DrawOffset

This commit is contained in:
2025-08-06 20:55:44 -05:00
parent 81c7ec8324
commit 7c96fbb187
20 changed files with 168 additions and 29 deletions

View File

@@ -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 }

View File

@@ -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 }

View File

@@ -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 }

View File

@@ -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 }

View File

@@ -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 }

View File

@@ -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 }

7
cli.go
View File

@@ -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 }

View File

@@ -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 }

View File

@@ -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 }

View File

@@ -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 {

View File

@@ -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 }

View File

@@ -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})

View File

@@ -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

View File

@@ -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 }

View File

@@ -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) {

View File

@@ -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

View File

@@ -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 }

View File

@@ -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 }

View File

@@ -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 }

View File

@@ -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