From 2f2a90ba85c36a0935840654fd45d9a8a9798610 Mon Sep 17 00:00:00 2001 From: hhvn Date: Wed, 21 Feb 2024 18:21:18 +0000 Subject: Make bar part of main --- bar.go | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 bar.go (limited to 'bar.go') diff --git a/bar.go b/bar.go new file mode 100644 index 0000000..6c3c981 --- /dev/null +++ b/bar.go @@ -0,0 +1,201 @@ +package main + +import ( + "image" + "errors" + "image/color" + + "hhvn.uk/hbspbar/config" + "hhvn.uk/hbspbar/status" + "hhvn.uk/hbspbar/bspc" + "hhvn.uk/hbspbar/drw" +) + +var bars map[int]*bar = make(map[int]*bar) + +type bar struct { + id int + w *drw.Window + i *image.RGBA +} + +var ( + ErrNoState = errors.New("attempted to create a bar with uninitialized state") + ErrNoSuchBar = errors.New("attempted to destroy non-existant bar") +) + +func (b *bar) init(id int, state *bspc.State) error { + b.id = id + b.i = nil + + mon, err := b.getmon(state) + if err != nil { return err } + + go mon.TopPadding(config.H) + + geom := mon.Rectangle + + b.w, err = drw.WindowCreate(geom.X, geom.Y, geom.Width, config.H) + if err != nil { return err } + + rect := image.Rect(0, 0, int(mon.Rectangle.Width), int(config.H)) + b.i = image.NewRGBA(rect) + + return nil +} + +func (b *bar) destroy(state *bspc.State) { + mon, _ := b.getmon(state) + if (mon != nil) { + mon.TopPadding(0) + } +} + +func (b bar) getmon(state *bspc.State) (*bspc.Monitor, error) { + return state.GetMon(b.id) +} + +func (b *bar) drawText(x int, col color.Color, text string) (int, error) { + return drw.DrawText(b.i, x, col, text) +} + +func (b *bar) drawRect(x, y, w, h int, c color.Color, fill bool) { + drw.DrawRect(b.i, x, y, w, h, c, fill) +} + +func (b bar) draw(state *bspc.State, blocks []*status.Block) error { + var bg color.Color + var filled bool + + if blocks == nil { + return nil + } + + mon, err := b.getmon(state) + if err != nil { + return err + } + + // Dimensions of drawing space + cx := 0 + w := int(mon.Rectangle.Width) + h := int(config.H) + + + // Draw background + b.drawRect(0, 0, w, h, config.Bg, true) + + // Monitor + montext := mon.Name + monw := 6 + drw.TextWidth(montext) + 8 + + if mon.Focused { + bg = config.Sel + } else { + bg = config.UnselMon + } + + b.drawRect(cx, 0, monw, h, bg, true) + b.drawText(cx + 6, config.Fg, montext) + cx += monw + + // Desktops + boxw := 4 + ds := len(mon.Desktops) + dw := 4 + (4 + boxw + 2 + 3) * ds + 5 + + for i := 0; i < ds; i++ { + dw += drw.TextWidth(mon.Desktops[i].Name) + } + + cx += 4 + for i := 0; i < ds; i++ { + d := mon.Desktops[i] + + cx += 5 + + if d.Focused { + bg = config.Sel + } else { + bg = config.FgDark + } + + filled = d.Root != nil + + b.drawRect(cx, 3, boxw, h - 7, bg, filled) + cx += boxw + 2 + ax, _ := b.drawText(cx, config.Fg, d.Name) + cx += ax + 2 + } + + cx = int(mon.Rectangle.Width) + for _, s := range blocks { + if s != nil { + cx -= s.W + cx -= config.StatusPad + } + } + + b.drawRect(cx, 0, int(mon.Rectangle.Width) - cx, int(config.H), + config.Status, true) + + cx += config.StatusPad / 2 + + for _, s := range blocks { + if s != nil { + drw.AddImg(b.i, cx, s.W, s.I) + + cx += s.W + config.StatusPad + } + } + + b.w.Paint(b.i) + + return nil +} + +func Create(state *bspc.State, id int) (error) { + var b bar + + if state == nil { + return ErrNoState + } + + if _, ok := bars[id]; ok { + // Already created, whatever. + return nil + } + + if err := b.init(id, state); err != nil { + return err + } + + bars[b.id] = &b + return nil +} + +func Redraw(state *bspc.State, blocks []*status.Block) { + for _, b := range bars { + b.draw(state, blocks) + } +} + +func Destroy(state *bspc.State, id int) error { + b, ok := bars[id] + if !ok { + return ErrNoSuchBar + } + + b.destroy(state) + delete(bars, id) + + return nil +} + +func Cleanup(state *bspc.State) { + if state != nil { + for _, b := range bars { + b.destroy(finalstate) + } + } +} -- cgit v1.2.3