diff --git a/wdgt_linear_layout.go b/wdgt_linear_layout.go index 64ad495..241e11c 100644 --- a/wdgt_linear_layout.go +++ b/wdgt_linear_layout.go @@ -50,10 +50,11 @@ type LinearLayout struct { // fields stacked bool - active bool - visible bool - tabbable bool - disableTab bool + active bool + visible bool + tabbable bool + disableTab bool + insetBorder bool logger func(string, ...any) } @@ -93,24 +94,19 @@ func (w *LinearLayout) HandleKey(ev *tcell.EventKey) bool { if !w.active || w.disableTab { return false } - active := w.findActive() if active != nil { if active.HandleKey(ev) { - w.Log("%s.HandleKey %s <- Consumed by %s", w.Id(), ev.Name(), active.Id()) return true } - w.Log("%s.HandleKey Not handled by active (%s)", w.Id(), active.Id()) } if ev.Key() == tcell.KeyTab { - w.Log("%s-> Activating Next (current: %s)", w.Id(), w.findActive().Id()) - ret := w.activateNext() - if ret { - w.Log("%s<- Activated: %s", w.Id(), w.findActive().Id()) - } else { - w.Log("%s<- Nothing Activated", w.Id()) + if active == nil && len(w.widgets) > 0 { + // No widget is active + w.widgets[0].SetActive(true) + return true } - return ret + return w.activateNext() } return false @@ -128,13 +124,25 @@ func (w *LinearLayout) Draw(screen tcell.Screen) { return } pos := w.GetPos() + if w.insetBorder { + wh.Border(pos.X, pos.Y, pos.X+w.w, pos.Y+w.h, wh.BRD_CSIMPLE, w.style, screen) + } + for _, wd := range w.widgets { pos.DrawOffset(wd, screen) } } -func (w *LinearLayout) Active() bool { return w.active } -func (w *LinearLayout) SetActive(a bool) { w.active = a } +func (w *LinearLayout) Active() bool { return w.active } +func (w *LinearLayout) SetActive(a bool) { + w.active = a + if w.active { + act := w.findActiveOrFirst() + if act != nil { + act.SetActive(true) + } + } +} func (w *LinearLayout) Visible() bool { return w.visible } func (w *LinearLayout) SetVisible(a bool) { w.visible = a } func (w *LinearLayout) Focusable() bool { return true } @@ -217,6 +225,13 @@ func (w *LinearLayout) findActive() Widget { return w.widgets[i] } } + return nil +} + +func (w *LinearLayout) findActiveOrFirst() Widget { + if act := w.findActive(); act != nil { + return act + } // Didn't find one, return the first if len(w.widgets) > 0 { return w.widgets[0] @@ -227,7 +242,7 @@ func (w *LinearLayout) findActive() Widget { func (w *LinearLayout) activateNext() bool { var found bool for i := range w.widgets { - if found { + if found && w.widgets[i].Tabbable() { w.Log("%s.activeNext Setting Next Active: %s", w.Id(), w.widgets[i].Id()) w.widgets[i].SetActive(true) return true @@ -537,6 +552,8 @@ func (w *LinearLayout) getWeightedW(wd Widget) int { func (w *LinearLayout) SetStacked(s bool) { w.stacked = s } +func (w *LinearLayout) SetBordered(b bool) { w.insetBorder = b } + func (w *LinearLayout) SetLogger(l func(string, ...any)) { w.logger = l } func (w *LinearLayout) Log(txt string, args ...any) { if w.logger != nil { diff --git a/wdgt_list.go b/wdgt_list.go index 94b758b..91e250b 100644 --- a/wdgt_list.go +++ b/wdgt_list.go @@ -205,6 +205,7 @@ func (w *List) MoveDown(ev *tcell.EventKey) bool { } func (w *List) SetTitle(ttl string) { w.title = ttl } func (w *List) SetList(l []string) { w.list = l } +func (w *List) Clear() { w.list = []string{} } func (w *List) Add(l string) { w.list = append(w.list, l) } func (w *List) Remove(l string) { var idx int diff --git a/wdgt_menu.go b/wdgt_menu.go index 9255ca1..23ce659 100644 --- a/wdgt_menu.go +++ b/wdgt_menu.go @@ -97,7 +97,10 @@ func (w *Menu) HandleKey(ev *tcell.EventKey) bool { if !w.active { return false } else if w.items[w.cursor].HandleKey(ev) { - // See if the active menuitem consumes this event + // Active menuitem consumes this event + if ev.Key() == tcell.KeyEnter { + w.SetActive(false) + } return true } else if ok := w.keyMap.Handle(ev); ok { // Otherwise see if we handle it diff --git a/wdgt_menu_item.go b/wdgt_menu_item.go index a5256fd..2c632ff 100644 --- a/wdgt_menu_item.go +++ b/wdgt_menu_item.go @@ -80,9 +80,6 @@ func (w *MenuItem) Init(id string, style tcell.Style) { func (w *MenuItem) Id() string { return w.id } func (w *MenuItem) HandleResize(ev *tcell.EventResize) { w.w, w.h = ev.Size() - - // w.w = wh.Min(w.w, w.WantW()) - // w.h = wh.Min(w.h, w.WantH()) // TODO: Trickle-down HandleResize } diff --git a/wdgt_searcher.go b/wdgt_searcher.go index 918558f..541f473 100644 --- a/wdgt_searcher.go +++ b/wdgt_searcher.go @@ -85,7 +85,6 @@ func (w *Searcher) Init(id string, style tcell.Style) { func (w *Searcher) Id() string { return w.id } func (w *Searcher) HandleResize(ev *tcell.EventResize) { w.w, w.h = ev.Size() - w.Log("Searcher<%s>.HandleResize: %d,%d", w.Id(), w.w, w.h) // Remove 2 from each for borders aW, aH := w.w-2, w.h-2 if !w.disableBorder { @@ -187,7 +186,6 @@ func (w *Searcher) Draw(screen tcell.Screen) { if !w.disableBorder { if len(w.title) > 0 { wh.TitledBorderFilled(w.x, w.y, w.x+w.w, w.y+w.h-1, w.title, wh.BRD_CSIMPLE, dStyle, screen) - // w.Log("Searcher<%s> Bounds: %d,%d -> %d,%d", w.Id(), w.x, w.y, w.x+w.w, w.y+w.h) } else { wh.BorderFilled(w.x, w.y, w.x+w.w, w.y+w.h, wh.BRD_CSIMPLE, dStyle, screen) } @@ -269,6 +267,8 @@ func (w *Searcher) SetHideOnSelect(t bool) { w.hideOnSelect = t } func (w *Searcher) SetTitle(ttl string) { w.title = ttl } func (w *Searcher) SetData(data []string) { // w.data = data + w.Log("%s: Setting Searcher (filtered)Data (%d length)", w.Id(), len(data)) + w.data = data w.filteredData = data w.updateFilter() } @@ -277,6 +277,7 @@ func (w *Searcher) updateFilter() { var selVal string data := []string{} copy(data, w.filteredData) + w.Log("%s: Setting Searcher Data (%d length)", w.Id(), len(data)) if len(data) > 0 && len(data) > w.cursor { selVal = data[w.cursor] } diff --git a/wdgt_top_menu_layout.go b/wdgt_top_menu_layout.go index b42abfa..794a335 100644 --- a/wdgt_top_menu_layout.go +++ b/wdgt_top_menu_layout.go @@ -101,7 +101,9 @@ func (w *TopMenuLayout) HandleKey(ev *tcell.EventKey) bool { // If we're here, that means the menu isn't active, but we are. So the // widget should be. w.widget.SetActive(true) - return w.widget.HandleKey(ev) + ret := w.widget.HandleKey(ev) + w.widget.SetActive(true) + return ret } return false }