Skip to content

Commit

Permalink
add Target assignments to widgets
Browse files Browse the repository at this point in the history
This allows to define widgets inside the main UI in the
natural order.
Widgets that are referenced from other widgets can do so
by Target pointers.

This is an example implementation for mjl-/duit#9
  • Loading branch information
ktye committed Jun 1, 2018
1 parent d12294d commit 164b760
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 11 deletions.
9 changes: 5 additions & 4 deletions examples/alert/alert.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,17 @@ func main() {
dui, err := duit.NewDUI("ex/alert", &duit.DUIOpts{Dimensions: "400x300"})
check(err, "new dui")

field := &duit.Field{
Text: "type an alert message here",
}
var field *duit.Field

dui.Top.UI = &duit.Box{
Padding: duit.SpaceXY(6, 4),
Margin: image.Pt(6, 4),
Valign: duit.ValignMiddle,
Kids: duit.NewKids(
field,
&duit.Field{
Target: &field,
Text: "type an alert message here",
},
&duit.Button{
Text: "click me to create an alert",
Click: func() (e duit.Event) {
Expand Down
5 changes: 3 additions & 2 deletions examples/basic/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ func main() {

// assign some UIs to variables, so we can reference
// and modify them in the button click handler.
status := &duit.Label{Text: "status: not logged in yet"}
var status *duit.Label

username := &duit.Field{}
password := &duit.Field{Password: true}
login := &duit.Button{
Expand Down Expand Up @@ -57,7 +58,7 @@ func main() {
Margin: image.Pt(6, 4), // space between kids in this box
// duit.NewKids is a convenience function turning UIs into Kids
Kids: duit.NewKids(
status,
&duit.Label{Target: &status, Text: "status: not logged in yet"},
&duit.Grid{
Columns: 2,
Padding: []duit.Space{
Expand Down
6 changes: 4 additions & 2 deletions examples/demo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func main() {
}

count := 0
counter := &duit.Label{Text: fmt.Sprintf("%d", count)}
var counter *duit.Label
tick := make(chan struct{}, 0)
go func() {
for {
Expand All @@ -39,6 +39,8 @@ func main() {
}
}()

// We cannot define the RadiobuttonGroup inside the main UI.
// It cannot be assigned to a Target, as it is just a slice.
radio1 := &duit.Radiobutton{
Selected: true,
Value: 1,
Expand Down Expand Up @@ -116,7 +118,7 @@ func main() {
Margin: image.Pt(6, 4),
Kids: duit.NewKids(
&duit.Label{Text: "counter:"},
counter,
&duit.Label{Target: &counter, Text: fmt.Sprintf("%d", count)},
&duit.Button{
Text: "button1",
Colorset: &dui.Primary,
Expand Down
5 changes: 5 additions & 0 deletions field.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

// Field is a single line text field. The cursor is always visible, and determines which part of the text is shown.
type Field struct {
Target **Field `json:"-"` // Reference to itself.
Text string // Current text.
Placeholder string // Text displayed in lighter color as example.
Disabled bool // If disabled, mouse and key input have no effect.
Expand Down Expand Up @@ -80,6 +81,10 @@ func (ui *Field) removeSelection() {
func (ui *Field) Layout(dui *DUI, self *Kid, sizeAvail image.Point, force bool) {
dui.debugLayout(self)

if ui.Target != nil {
*ui.Target = ui
}

ui.size = image.Point{sizeAvail.X, ui.font(dui).Height + 2*ui.space(dui).Y}
self.R = rect(ui.size)
return
Expand Down
11 changes: 8 additions & 3 deletions label.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import (
// cmd-c, copy text
// \n, like button1 click, calls the Click function
type Label struct {
Text string // Text to draw, wrapped at glyph boundary.
Font *draw.Font `json:"-"` // For drawing text.
Click func() (e Event) `json:"-"` // Called on button1 click.
Target **Label `json:"-"`
Text string // Text to draw, wrapped at glyph boundary.
Font *draw.Font `json:"-"` // For drawing text.
Click func() (e Event) `json:"-"` // Called on button1 click.

lines []string
size image.Point
Expand All @@ -30,6 +31,10 @@ func (ui *Label) font(dui *DUI) *draw.Font {
func (ui *Label) Layout(dui *DUI, self *Kid, sizeAvail image.Point, force bool) {
dui.debugLayout(self)

if ui.Target != nil {
*ui.Target = ui
}

font := ui.font(dui)
ui.lines = []string{}
s := 0
Expand Down
5 changes: 5 additions & 0 deletions radiobutton.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

// Radiobutton is typically part of a group of radiobuttons, with exactly one of them selected. Labels are not part of the radiobutton itself.
type Radiobutton struct {
Target **Radiobutton `json:"-"`
Selected bool
Disabled bool // If set, cannot be selected.
Group RadiobuttonGroup // Other radiobuttons as part of this group. If a radiobutton is selected, others in the group are unselected.
Expand Down Expand Up @@ -54,6 +55,10 @@ func (ui *Radiobutton) innerDim(dui *DUI) int {
func (ui *Radiobutton) Layout(dui *DUI, self *Kid, sizeAvail image.Point, force bool) {
dui.debugLayout(self)

if ui.Target != nil {
*ui.Target = ui
}

hit := image.Point{0, 1}
size := pt(2*BorderSize + 7*dui.Display.DefaultFont.Height/10).Add(hit)
self.R = rect(size)
Expand Down

0 comments on commit 164b760

Please sign in to comment.