5bar5/bar.go

153 lines
3.2 KiB
Go
Raw Permalink Normal View History

2017-07-11 01:17:27 +00:00
package main
import (
2017-07-12 16:21:51 +00:00
"fmt"
2017-07-11 01:17:27 +00:00
"image"
"log"
2017-07-11 01:17:27 +00:00
"github.com/BurntSushi/xgb/xproto"
"github.com/BurntSushi/xgbutil/xgraphics"
"github.com/BurntSushi/xgbutil/xwindow"
2021-05-04 14:48:49 +00:00
"github.com/elliotchance/orderedmap"
2018-12-24 19:16:42 +00:00
"golang.org/x/image/font"
"golang.org/x/image/math/fixed"
2017-07-11 01:17:27 +00:00
)
// Bar is a struct with information about the bar.
type Bar struct {
// Bar window, and bar image.
2017-07-11 01:17:27 +00:00
win *xwindow.Window
img *xgraphics.Image
2017-07-11 15:25:19 +00:00
// The width and height of the bar.
w, h int
// This is a sum of all of the block widths, used to draw a block to the
// right of the last block.
2017-07-11 15:25:19 +00:00
xsum int
// Text drawer.
drawer *font.Drawer
2021-05-04 14:48:49 +00:00
// A map that stores the various blocks.
blocks *orderedmap.OrderedMap
// A map that stores the various popups.
popups *orderedmap.OrderedMap
// Store is an interface to store variables and objects to be used by other
// blocks or popups.
store map[string]interface{}
2017-07-11 01:17:27 +00:00
// A channel where the block should be send to to once its ready to be
// redrawn.
2017-07-13 18:51:08 +00:00
redraw chan *Block
2017-07-11 01:17:27 +00:00
}
func initBar(x, y, w, h int) (*Bar, error) {
2017-07-11 01:17:27 +00:00
bar := new(Bar)
var err error
// Create a window for the bar. This window listens to button press events
// in order to respond to them.
bar.win, err = xwindow.Generate(X)
2017-07-11 01:17:27 +00:00
if err != nil {
return nil, err
}
bar.win.Create(X.RootWin(), x, y, w, h, xproto.CwBackPixel|xproto.
CwEventMask, 0x000000, xproto.EventMaskButtonPress)
// EWMH stuff to make the window behave like an actual bar.
2019-01-15 20:05:07 +00:00
if err := initEWMH(bar.win.Id); err != nil {
2017-07-12 16:21:51 +00:00
return nil, err
}
// Map window.
2017-07-11 01:17:27 +00:00
bar.win.Map()
2017-07-13 19:22:19 +00:00
// XXX: Moving the window is again a hack to keep OpenBox happy.
2017-07-12 16:21:51 +00:00
bar.win.Move(x, y)
2017-07-11 01:17:27 +00:00
2017-07-13 19:22:19 +00:00
// Create the bar image.
bar.img = xgraphics.New(X, image.Rect(0, 0, w, h))
if err := bar.img.XSurfaceSet(bar.win.Id); err != nil {
return nil, err
}
bar.img.XDraw()
2017-07-11 01:17:27 +00:00
2021-05-04 14:48:49 +00:00
// Set bar width and height.
bar.w = w
bar.h = h
2021-05-04 14:48:49 +00:00
// Set bar font face.
bar.drawer = &font.Drawer{
Dst: bar.img,
Face: face,
}
2021-05-04 14:48:49 +00:00
// Creat blocks and popups map.
bar.blocks = orderedmap.NewOrderedMap()
bar.popups = orderedmap.NewOrderedMap()
2021-05-04 14:48:49 +00:00
// Create store map.
bar.store = make(map[string]interface{})
2021-05-04 14:48:49 +00:00
// Create redraw channel.
bar.redraw = make(chan *Block)
2017-07-13 18:51:08 +00:00
return bar, nil
2017-07-11 01:17:27 +00:00
}
func (bar *Bar) draw(block *Block) error {
// Calculate the required x coordinate for the different aligments.
2017-07-11 01:17:27 +00:00
var x int
2021-05-04 14:48:49 +00:00
tw := bar.drawer.MeasureString(block.txt).Round()
2017-07-11 01:17:27 +00:00
switch block.align {
case 'l':
x = block.x
2017-07-11 01:17:27 +00:00
case 'c':
x = block.x + ((block.w / 2) - (tw / 2))
2017-07-11 01:17:27 +00:00
case 'r':
x = (block.x + block.w) - tw
case 'a':
x = (bar.w / 2) - (tw / 2)
2017-07-12 16:21:51 +00:00
default:
return fmt.Errorf("draw %#U: Not a valid aligment rune", block.align)
2017-07-11 01:17:27 +00:00
}
x += block.xoff
2021-05-04 14:48:49 +00:00
x += 2
2017-07-11 01:17:27 +00:00
// Color the background.
2017-07-12 16:21:51 +00:00
block.img.For(func(cx, cy int) xgraphics.BGRA {
// XXX: Hack for music block.
2017-07-13 18:51:08 +00:00
if block.w == 660 {
2017-07-12 16:21:51 +00:00
if cx < x+block.xoff {
2021-05-04 14:48:49 +00:00
return xgraphics.BGRA{B: 103, G: 89, R: 68, A: 0xFF}
2017-07-12 16:21:51 +00:00
}
}
2021-05-04 14:48:49 +00:00
return block.bg
2017-07-12 16:21:51 +00:00
})
2021-05-04 14:48:49 +00:00
// Set foreground color.
bar.drawer.Src = image.NewUniform(block.fg)
2017-07-11 01:17:27 +00:00
// Draw the text.
bar.drawer.Dot = fixed.P(x, 18)
bar.drawer.DrawString(block.txt)
2017-07-11 01:17:27 +00:00
2018-12-24 19:16:42 +00:00
// Redraw the bar.
2017-07-11 01:17:27 +00:00
block.img.XDraw()
bar.img.XPaint(bar.win.Id)
2017-07-13 18:51:08 +00:00
return nil
2017-07-11 01:17:27 +00:00
}
2018-12-26 20:24:04 +00:00
func (bar *Bar) listen() {
for {
if err := bar.draw(<-bar.redraw); err != nil {
log.Fatalln(err)
2018-12-26 20:24:04 +00:00
}
}
}