From b87b4825af184dea29e121472a107c4de931fdcc Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Sun, 13 Jun 2021 19:59:22 -0700 Subject: [PATCH] Checkbox updates, SelectBox images --- checkbox.go | 11 ++++++++++- frame_pack.go | 30 ++++++++++++++++++++++++++++++ image.go | 5 +++-- selectbox.go | 50 +++++++++++++++++++++++++++++++++++++++----------- 4 files changed, 82 insertions(+), 14 deletions(-) diff --git a/checkbox.go b/checkbox.go index 464af4c..31d2d60 100644 --- a/checkbox.go +++ b/checkbox.go @@ -21,6 +21,10 @@ func NewRadiobox(name string, stringVar *string, value string, child Widget) *Ch func makeCheckbox(name string, boolVar *bool, stringVar *string, value string, child Widget) *Checkbox { // Our custom checkbutton widget. mark := NewFrame(name + "_mark") + mark.Configure(Config{ + Width: 6, + Height: 6, + }) w := &Checkbox{ child: child, @@ -33,7 +37,7 @@ func makeCheckbox(name string, boolVar *bool, stringVar *string, value string, c w.Frame.Setup() // Forward clicks on the child widget to the CheckButton. - for _, e := range []Event{MouseOver, MouseOut, MouseUp, MouseDown} { + for _, e := range []Event{MouseOver, MouseOut, MouseUp, MouseDown, Click} { func(e Event) { w.child.Handle(e, func(ed EventData) error { return w.button.Event(e, ed) @@ -56,6 +60,11 @@ func (w *Checkbox) Child() Widget { return w.child } +// Pass event handlers on to descendents. +func (w *Checkbox) Handle(e Event, fn func(EventData) error) { + w.button.Handle(e, fn) +} + // Supervise the checkbutton inside the widget. func (w *Checkbox) Supervise(s *Supervisor) { s.Add(w.button) diff --git a/frame_pack.go b/frame_pack.go index 8021bee..9c6ed06 100644 --- a/frame_pack.go +++ b/frame_pack.go @@ -1,6 +1,8 @@ package ui import ( + "fmt" + "git.kirsle.net/go/render" ) @@ -56,6 +58,34 @@ func (w *Frame) Pack(child Widget, config ...Pack) { w.Add(child) } +// Unpack removes the widget from the packed lists. +func (w *Frame) Unpack(child Widget) bool { + var any = false + for side, widgets := range w.packs { + var ( + replace = []packedWidget{} + found = false + ) + + fmt.Printf("unpack:%s side:%s\n", child, side) + + for _, widget := range widgets { + if widget.widget == child { + fmt.Printf("found!\n") + found = true + any = true + continue + } + replace = append(replace, widget) + } + + if found { + w.packs[side] = replace + } + } + return any +} + // computePacked processes all the Pack layout widgets in the Frame. func (w *Frame) computePacked(e render.Engine) { var ( diff --git a/image.go b/image.go index 700613c..5116025 100644 --- a/image.go +++ b/image.go @@ -54,8 +54,8 @@ func ImageFromImage(e render.Engine, im image.Image) (*Image, error) { } return &Image{ - Type: PNG, - Image: im, + Type: PNG, + Image: im, texture: tex, }, nil } @@ -64,6 +64,7 @@ func ImageFromImage(e render.Engine, im image.Image) (*Image, error) { func ImageFromTexture(tex render.Texturer) *Image { return &Image{ texture: tex, + Image: tex.Image(), } } diff --git a/selectbox.go b/selectbox.go index ef5bab1..7b47814 100644 --- a/selectbox.go +++ b/selectbox.go @@ -11,19 +11,20 @@ import ( type SelectBox struct { MenuButton - name string + name string // Configurables after SelectBox creation. AlwaysChange bool // always call the Change event, even if selection not changed. - + // Child widgets specific to the SelectBox. - frame *Frame - label *Label - arrow *Image + frame *Frame + label *Label + arrow *Image + showImage *Image // User override show image // Data storage. textVariable string - values []SelectValue + values []SelectValue } // SelectValue holds a mapping between a text label for a SelectBox and @@ -40,9 +41,9 @@ type SelectValue struct { // all be ignored, as SelectBox will handle the values internally. func NewSelectBox(name string, withLabel Label) *SelectBox { w := &SelectBox{ - name: name, + name: name, textVariable: "Choose one", - values: []SelectValue{}, + values: []SelectValue{}, } // Ensure the label has no text of its own. @@ -63,9 +64,9 @@ func NewSelectBox(name string, withLabel Label) *SelectBox { // Configure the button's appearance. w.Button.Configure(Config{ - BorderSize: 2, + BorderSize: 2, BorderStyle: BorderSunken, - Background: render.White, + Background: render.White, }) // Set sensible default padding on the label. @@ -82,6 +83,34 @@ func NewSelectBox(name string, withLabel Label) *SelectBox { return w } +// SetImage sets the selectbox button to show the image instead of its +// normal text label. If the image corresponds with an option in the selectbox, +// it is up to the caller to call SetImage on change and set the right image here. +// +// Provide a nil value to remove the image and show the text labels instead. +func (w *SelectBox) SetImage(img *Image) { + // Get rid of the current image. + if w.showImage != nil { + w.showImage.Hide() + w.frame.Unpack(w.showImage) + } + + // Are we getting a new one? + if img != nil { + w.label.Hide() + w.frame.Pack(img, Pack{ + Side: W, + }) + } else { + w.label.Show() + } + + w.showImage = img + if w.showImage != nil { + w.showImage.Show() + } +} + // AddItem adds a new option to the SelectBox's menu. // The label is the text value to display. // The value is the underlying value (string or int) for the TextVariable or IntVariable. @@ -197,4 +226,3 @@ func (w *SelectBox) setup() { return nil }) } -