File: checkbox.go

package info (click to toggle)
golang-github-gcla-gowid 1.4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 1,456 kB
  • sloc: makefile: 4
file content (144 lines) | stat: -rw-r--r-- 3,801 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Copyright 2019-2022 Graham Clark. All rights reserved.  Use of this source
// code is governed by the MIT license that can be found in the LICENSE
// file.

// Package checkbox provides a widget which can be checked or unchecked.
package checkbox

import (
	"fmt"

	"github.com/gcla/gowid"
	"github.com/gcla/gowid/gwutil"
	"github.com/gcla/gowid/widgets/button"
)

//======================================================================

type IChecked interface {
	button.IDecoratedAround
	button.IDecoratedMiddle
	IsChecked() bool
}

type IWidget interface {
	gowid.IWidget
	IChecked
}

//======================================================================

type Decoration struct {
	button.Decoration
	Middle string
}

func (b *Decoration) MiddleDec() string {
	return b.Middle
}

func (w *Decoration) SetMiddleDec(dec string, app gowid.IApp) {
	w.Middle = dec
}

//======================================================================

type Widget struct {
	checked   bool
	Callbacks *gowid.Callbacks
	gowid.ClickCallbacks
	Decoration
	gowid.AddressProvidesID
	gowid.IsSelectable
}

func New(isChecked bool) *Widget {
	cb := gowid.NewCallbacks()
	res := &Widget{
		checked:        isChecked,
		Callbacks:      cb,
		ClickCallbacks: gowid.ClickCallbacks{CB: &cb},
		Decoration:     Decoration{button.Decoration{"[", "]"}, "X"},
	}
	var _ gowid.IWidget = res
	return res
}

func NewDecorated(isChecked bool, decoration Decoration) *Widget {
	cb := gowid.NewCallbacks()
	res := &Widget{
		checked:        isChecked,
		Callbacks:      cb,
		ClickCallbacks: gowid.ClickCallbacks{CB: &cb},
		Decoration:     decoration,
	}
	var _ gowid.IWidget = res
	return res
}

func (w *Widget) String() string {
	return fmt.Sprintf("checkbox[%s]", gwutil.If(w.IsChecked(), "X", " ").(string))
}

func (w *Widget) IsChecked() bool {
	return w.checked
}

func (w *Widget) SetChecked(app gowid.IApp, val bool) {
	w.setChecked(app, val)
}

func (w *Widget) setChecked(app gowid.IApp, val bool) {
	w.checked = val
	gowid.RunWidgetCallbacks(*w.CB, gowid.ClickCB{}, app, w)
}

func (w *Widget) Click(app gowid.IApp) {
	if app.GetMouseState().NoButtonClicked() || app.GetMouseState().LeftIsClicked() {
		w.setChecked(app, !w.IsChecked())
	}
}

func (w *Widget) RenderSize(size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.IRenderBox {
	return gowid.RenderBox{C: len(w.LeftDec()) + len(w.MiddleDec()) + len(w.RightDec()), R: 1}
}

func (w *Widget) Render(size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.ICanvas {

	if _, ok := size.(gowid.IRenderFixed); !ok {
		panic(gowid.WidgetSizeError{Widget: w, Size: size, Required: "gowid.IRenderFixed"})
	}

	return Render(w, size, focus, app)
}

func (w *Widget) UserInput(ev interface{}, size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) bool {
	if _, ok := size.(gowid.IRenderFixed); !ok {
		panic(gowid.WidgetSizeError{Widget: w, Size: size, Required: "gowid.IRenderFixed"})
	}
	return button.UserInput(w, ev, size, focus, app)
}

//======================================================================

func Render(w IChecked, size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) gowid.ICanvas {
	line := make([]gowid.Cell, 0)
	line = append(line, gowid.CellsFromString(w.LeftDec())...)
	if w.IsChecked() {
		line = append(line, gowid.CellsFromString(w.MiddleDec())...)
	} else {
		line = append(line, gowid.CellsFromString(gwutil.StringOfLength(' ', len(w.MiddleDec())))...)
	}
	line = append(line, gowid.CellsFromString(w.RightDec())...)

	res := gowid.NewCanvasWithLines([][]gowid.Cell{line})
	res.SetCursorCoords(len(w.LeftDec())+(len(w.MiddleDec())/2), 0)

	return res
}

//======================================================================
// Local Variables:
// mode: Go
// fill-column: 110
// End: