diff --git a/absolute_layout.go b/absolute_layout.go index 730477a..08d00b3 100644 --- a/absolute_layout.go +++ b/absolute_layout.go @@ -135,12 +135,16 @@ func (w *AbsoluteLayout) Draw(screen tcell.Screen) { } p := w.GetPos() for _, wd := range w.widgets { - o := wd.GetPos() - wd.SetPos(p.Add(o)) - wd.Draw(screen) - wd.SetPos(o) + wd.DrawOffset(p, screen) } } + +func (w *AbsoluteLayout) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) +} func (w *AbsoluteLayout) Active() bool { return w.active } func (w *AbsoluteLayout) SetActive(a bool) { w.active = a } func (w *AbsoluteLayout) Visible() bool { return w.visible } diff --git a/alert.go b/alert.go index b4f5a3f..99093b1 100644 --- a/alert.go +++ b/alert.go @@ -39,7 +39,7 @@ type Alert struct { visible bool tabbable bool - layout *AbsoluteLayout + layout *LinearLayout title string message *Text btnOk, btnCancel *Button @@ -59,19 +59,25 @@ func (w *Alert) Init(id string, style tcell.Style) { w.id = id w.style = style - w.layout = NewAbsoluteLayout("alertlayout", tcell.StyleDefault) + w.layout = NewLinearLayout("alertlayout", tcell.StyleDefault) w.message = NewText(fmt.Sprintf("%s-text", id), style) - w.layout.AddAnchored(w.message, Coord{X: 0, Y: 0}, AnchorC) + w.layout.Add(w.message) + + btnLayout := NewLinearLayout("alertbtn-layout", tcell.StyleDefault) + btnLayout.SetOrientation(LinLayH) + + w.btnCancel = NewButton(fmt.Sprintf("%s-cancel", id), style) + w.btnCancel.SetLabel("Cancel") + w.layout.Add(w.btnCancel) + btnLayout.Add(w.btnCancel) w.btnOk = NewButton(fmt.Sprintf("%s-select", id), style) w.btnOk.SetLabel("Ok") w.btnOk.SetActive(true) - w.layout.AddAnchored(w.btnOk, Coord{X: -2, Y: 0}, AnchorBR) + btnLayout.Add(w.btnOk) - w.btnCancel = NewButton(fmt.Sprintf("%s-cancel", id), style) - w.btnCancel.SetLabel("Cancel") - w.layout.AddAnchored(w.btnCancel, Coord{X: 2, Y: 0}, AnchorBL) + w.layout.Add(btnLayout) w.keyMap = NewKeyMap(map[tcell.Key]func(ev *tcell.EventKey) bool{ tcell.KeyTab: w.SelectNext, @@ -130,11 +136,16 @@ func (w *Alert) Draw(screen tcell.Screen) { } wh.TitledBorderFilled(w.x, w.y, w.x+w.w, w.y+w.h, w.title, wh.BRD_SIMPLE, w.style, screen) - w.layout.Draw(screen) - // w.message.Draw(screen) - // w.btnOk.Draw(screen) - // w.btnCancel.Draw(screen) + w.layout.DrawOffset(w.GetPos(), screen) } + +func (w *Alert) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) +} + func (w *Alert) Active() bool { return w.active } func (w *Alert) SetActive(a bool) { w.active = a } func (w *Alert) Visible() bool { return w.visible } diff --git a/bordered_widget.go b/bordered_widget.go index ec29013..e8c722b 100644 --- a/bordered_widget.go +++ b/bordered_widget.go @@ -92,7 +92,14 @@ func (w *BorderedWidget) Draw(screen tcell.Screen) { h.BorderFilled(w.x, w.y, w.x+w.w, w.y+w.h, w.border, w.style, screen) } w.widget.SetPos(Coord{X: w.x + 1, Y: w.y + 1}) - w.widget.Draw(screen) + w.widget.DrawOffset(w.GetPos(), screen) +} + +func (w *BorderedWidget) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) } func (w *BorderedWidget) Active() bool { return w.active } func (w *BorderedWidget) SetActive(a bool) { w.active = a } diff --git a/button.go b/button.go index 882a222..c16c145 100644 --- a/button.go +++ b/button.go @@ -112,6 +112,13 @@ func (w *Button) Draw(screen tcell.Screen) { h.DrawText(w.x, w.y+1, fmt.Sprintf("│%s│", h.Center(lbl, w.w-2)), dStyle, screen) h.DrawText(w.x, w.y+2, fmt.Sprintf("╰%s╯", strings.Repeat("─", w.w-2)), dStyle, screen) } + +func (w *Button) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) +} func (w *Button) Active() bool { return w.active } func (w *Button) SetActive(a bool) { w.active = a } func (w *Button) Visible() bool { return w.visible } diff --git a/chat.go b/chat.go index 15a5a7c..fdf3ac9 100644 --- a/chat.go +++ b/chat.go @@ -150,6 +150,13 @@ func (w *Chat) Draw(screen tcell.Screen) { // x += len(post) - 1 } +func (w *Chat) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) +} + func (w *Chat) Active() bool { return w.active } func (w *Chat) SetActive(a bool) { w.active = a } func (w *Chat) Visible() bool { return w.visible } diff --git a/checkbox.go b/checkbox.go index 2d83043..7d67ec7 100644 --- a/checkbox.go +++ b/checkbox.go @@ -91,6 +91,13 @@ func (w *Checkbox) Draw(screen tcell.Screen) { } h.DrawText(w.x, w.y, fmt.Sprintf("[%s] %s", string(w.state), w.label), dStyle, screen) } + +func (w *Checkbox) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) +} func (w *Checkbox) Active() bool { return w.active } func (w *Checkbox) SetActive(a bool) { w.active = a } func (w *Checkbox) Visible() bool { return w.visible } diff --git a/cli.go b/cli.go index 4f02f13..35088d6 100644 --- a/cli.go +++ b/cli.go @@ -154,6 +154,13 @@ func (w *Cli) Draw(screen tcell.Screen) { // x += len(post) - 1 } +func (w *Cli) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) +} + func (w *Cli) Active() bool { return w.active } func (w *Cli) SetActive(a bool) { w.active = a } func (w *Cli) Visible() bool { return w.visible } diff --git a/field.go b/field.go index bc08045..8cc019a 100644 --- a/field.go +++ b/field.go @@ -131,6 +131,13 @@ func (w *Field) Draw(screen tcell.Screen) { x += 1 h.DrawText(x, w.y, post, useStyle, screen) } + +func (w *Field) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) +} func (w *Field) Active() bool { return w.active } func (w *Field) SetActive(a bool) { w.active = a } func (w *Field) Visible() bool { return w.visible } diff --git a/filepicker.go b/filepicker.go index 67c29df..4062dfa 100644 --- a/filepicker.go +++ b/filepicker.go @@ -99,8 +99,16 @@ func (w *FilePicker) Draw(screen tcell.Screen) { wh.TitledBorderFilled(w.x, w.y, w.x+w.w, w.y+w.h, w.title, wh.BRD_SIMPLE, ds, screen) // TODO: Draw the file picker wh.DrawText(w.x+1, w.y+1, "TODO: Draw Filepicker", ds, screen) - w.btnSelect.Draw(screen) - w.btnCancel.Draw(screen) + c := w.GetPos() + w.btnSelect.DrawOffset(c, screen) + w.btnCancel.DrawOffset(c, screen) +} + +func (w *FilePicker) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) } func (w *FilePicker) Active() bool { return w.active } func (w *FilePicker) SetActive(a bool) { w.active = a } diff --git a/linear_layout.go b/linear_layout.go index 8c1d63c..beee673 100644 --- a/linear_layout.go +++ b/linear_layout.go @@ -119,13 +119,17 @@ func (w *LinearLayout) Draw(screen tcell.Screen) { } p := w.GetPos() for _, wd := range w.widgets { - o := wd.GetPos() - wd.SetPos(p.Add(o)) - wd.Draw(screen) - wd.SetPos(o) + wd.DrawOffset(p, screen) } } +func (w *LinearLayout) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) +} + func (w *LinearLayout) Active() bool { return w.active } func (w *LinearLayout) SetActive(a bool) { w.active = a } func (w *LinearLayout) Visible() bool { return w.visible } @@ -197,7 +201,9 @@ func (w *LinearLayout) MinH() int { } return minH } -func (w *LinearLayout) Append(n Widget) { w.widgets = append(w.widgets, n) } + +func (w *LinearLayout) SetOrientation(o LinearLayoutOrient) { w.orientation = o } +func (w *LinearLayout) Add(n Widget) { w.widgets = append(w.widgets, n) } func (w *LinearLayout) Delete(n Widget) { for i := 0; i < len(w.widgets); i++ { if w.widgets[i] == n { diff --git a/list.go b/list.go index 1a1df42..93b11d1 100644 --- a/list.go +++ b/list.go @@ -130,6 +130,13 @@ func (w *List) Draw(screen tcell.Screen) { y += 1 } } + +func (w *List) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) +} func (w *List) Active() bool { return w.active } func (w *List) SetActive(a bool) { w.active = a } func (w *List) Visible() bool { return w.visible } diff --git a/menu.go b/menu.go index 7d0153f..ab79e70 100644 --- a/menu.go +++ b/menu.go @@ -104,6 +104,13 @@ func (w *Menu) Draw(screen tcell.Screen) { } } +func (w *Menu) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) +} + func (w *Menu) drawHMenu(screen tcell.Screen) { st := w.style if w.active { @@ -116,6 +123,7 @@ func (w *Menu) drawHMenu(screen tcell.Screen) { } x += 2 if w.expanded || (w.active && !w.manualExpand) { + // TODO: Use DrawOffset? for i := range w.items { w.items[i].SetActive(w.active && w.cursor == i) w.items[i].SetPos(Coord{X: x, Y: y}) @@ -138,6 +146,7 @@ func (w *Menu) drawVMenu(screen tcell.Screen) { } h.DrawText(w.x, w.y, w.label, st, screen) if w.expanded || (w.active && !w.manualExpand) { + // TODO: Use DrawOffset? for i := range w.items { w.items[i].SetActive(w.active && w.cursor == i) w.items[i].SetSize(Coord{X: wW, Y: wH}) diff --git a/menu_item.go b/menu_item.go index d5ad664..dca2e77 100644 --- a/menu_item.go +++ b/menu_item.go @@ -108,12 +108,20 @@ func (w *MenuItem) Draw(screen tcell.Screen) { } x += 1 for i := range w.items { + // TODO: Use DrawOffset w.items[i].SetPos(Coord{X: x, Y: y}) w.items[i].Draw(screen) y++ } } } + +func (w *MenuItem) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) +} func (w *MenuItem) Active() bool { return w.active } func (w *MenuItem) SetActive(a bool) { w.active = a diff --git a/prompt.go b/prompt.go index a38cac2..53f1d7e 100644 --- a/prompt.go +++ b/prompt.go @@ -89,9 +89,17 @@ func (w *Prompt) Draw(screen tcell.Screen) { dS = dS.Dim(true) } wh.TitledBorderFilled(w.x, w.y, w.x+w.w, w.y+w.h, w.title, wh.BRD_SIMPLE, w.style, screen) - w.message.Draw(screen) - w.btnOk.Draw(screen) - w.btnCancel.Draw(screen) + p := w.GetPos() + w.message.DrawOffset(p, screen) + w.btnOk.DrawOffset(p, screen) + w.btnCancel.DrawOffset(p, screen) +} + +func (w *Prompt) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) } func (w *Prompt) Active() bool { return w.active } func (w *Prompt) SetActive(a bool) { w.active = a } diff --git a/relative_layout.go b/relative_layout.go index a01e311..205ad76 100644 --- a/relative_layout.go +++ b/relative_layout.go @@ -95,6 +95,13 @@ func (w *RelativeLayout) Draw(screen tcell.Screen) { } */ } + +func (w *RelativeLayout) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) +} func (w *RelativeLayout) Active() bool { return w.active } func (w *RelativeLayout) SetActive(a bool) { w.active = a } func (w *RelativeLayout) Visible() bool { return w.visible } @@ -140,10 +147,10 @@ func (w *RelativeLayout) MinH() int { } func (w *RelativeLayout) Add(n Widget, relTo Widget, relation RelativeRelation) { - w.widgetRelations[n] = widgetRelation{ + w.widgetRelations[n] = append(w.widgetRelations[n], widgetRelation{ relation: relation, relTo: relTo, - } + }) } func (w *RelativeLayout) AddRelation(n Widget, relation RelativeRelation, relTo Widget) { diff --git a/searcher.go b/searcher.go index eaf8da5..80a228b 100644 --- a/searcher.go +++ b/searcher.go @@ -176,7 +176,7 @@ func (w *Searcher) Draw(screen tcell.Screen) { } else { h.BorderFilled(w.x, w.y, w.x+w.w, w.y+w.h, h.BRD_CSIMPLE, dStyle, screen) } - w.search.Draw(screen) + w.search.DrawOffset(w.GetPos(), screen) x, y := w.x+1, w.y+2 var stIdx int if w.cursor > w.h/2 { @@ -199,6 +199,13 @@ func (w *Searcher) Draw(screen tcell.Screen) { } } } + +func (w *Searcher) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) +} func (w *Searcher) Active() bool { return w.active } func (w *Searcher) SetActive(a bool) { w.active = a diff --git a/table.go b/table.go index 0cadcbb..e31dd08 100644 --- a/table.go +++ b/table.go @@ -141,6 +141,13 @@ func (w *Table) Draw(screen tcell.Screen) { y++ } } + +func (w *Table) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) +} func (w *Table) Active() bool { return w.active } func (w *Table) SetActive(a bool) { w.active = a } func (w *Table) Visible() bool { return w.visible } diff --git a/text.go b/text.go index b7b3bd7..544f26a 100644 --- a/text.go +++ b/text.go @@ -72,6 +72,13 @@ func (w *Text) Draw(screen tcell.Screen) { y++ } } + +func (w *Text) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) +} func (w *Text) Active() bool { return false } func (w *Text) SetActive(a bool) {} func (w *Text) Visible() bool { return w.visible } diff --git a/timefield.go b/timefield.go index 5041d8b..368130c 100644 --- a/timefield.go +++ b/timefield.go @@ -153,6 +153,13 @@ func (w *TimeField) Draw(screen tcell.Screen) { } } +func (w *TimeField) DrawOffset(c Coord, screen tcell.Screen) { + p := w.GetPos() + w.SetPos(p.Add(c)) + w.Draw(screen) + w.SetPos(p) +} + func (w *TimeField) Active() bool { return w.active } func (w *TimeField) SetActive(a bool) { w.active = a } func (w *TimeField) Visible() bool { return w.visible } diff --git a/widget.go b/widget.go index c10331a..5f93f34 100644 --- a/widget.go +++ b/widget.go @@ -32,6 +32,7 @@ type Widget interface { HandleKey(*tcell.EventKey) bool HandleTime(*tcell.EventTime) Draw(tcell.Screen) + DrawOffset(Coord, tcell.Screen) Active() bool SetActive(bool) Visible() bool