1
0
mirror of https://github.com/mum4k/termdash.git synced 2025-04-27 13:48:49 +08:00

Adding options for global keyboard.

This commit is contained in:
Jakub Sobon 2019-02-22 01:07:53 -05:00
parent 8b3f1a146f
commit a16d908b5e
No known key found for this signature in database
GPG Key ID: F2451A77FB05D3B7
3 changed files with 72 additions and 20 deletions

View File

@ -28,8 +28,8 @@ import (
)
// CallbackFn is the function called when the button is pressed.
// The callback function must be non-blocking, ideally just storing a value and
// returning, since event processing blocks the redraws.
// The callback function must be light-weight, ideally just storing a value and
// returning, since more button presses might occur.
//
// The callback function must be thread-safe as the mouse or keyboard events
// that press the button are processed in a separate goroutine.
@ -100,10 +100,12 @@ func (*Button) Mouse(m *terminalapi.Mouse) error {
func (b *Button) Options() widgetapi.Options {
// No need to lock, as the height and width get fixed when New is called.
// TODO calculate width and set MaximumSize too.
height := b.opts.height + 1 // One for the shadow.
return widgetapi.Options{
MinimumSize: image.Point{b.opts.width, height},
WantKeyboard: true,
MaximumSize: image.Point{b.opts.width, height},
WantKeyboard: b.opts.keyScope,
WantMouse: true,
}
}

View File

@ -22,6 +22,7 @@ import (
"github.com/kylelemons/godebug/pretty"
"github.com/mum4k/termdash/canvas"
"github.com/mum4k/termdash/keyboard"
"github.com/mum4k/termdash/terminal/faketerm"
"github.com/mum4k/termdash/terminalapi"
"github.com/mum4k/termdash/widgetapi"
@ -150,18 +151,56 @@ func TestMouse(t *testing.T) {
}
func TestOptions(t *testing.T) {
ct := &callbackTracker{}
b, err := New("text", ct.callback)
if err != nil {
t.Fatalf("New => unexpected error: %v", err)
tests := []struct {
desc string
opts []Option
want widgetapi.Options
}{
{
desc: "doesn't want keyboard by default",
want: widgetapi.Options{
MinimumSize: image.Point{6, 3},
WantKeyboard: widgetapi.KeyScopeNone,
WantMouse: true,
},
},
{
desc: "registers for focused keyboard events",
opts: []Option{
Key(keyboard.KeyEnter),
},
want: widgetapi.Options{
MinimumSize: image.Point{6, 3},
WantKeyboard: widgetapi.KeyScopeFocused,
WantMouse: true,
},
},
{
desc: "registers for global keyboard events",
opts: []Option{
GlobalKey(keyboard.KeyEnter),
},
want: widgetapi.Options{
MinimumSize: image.Point{6, 3},
WantKeyboard: widgetapi.KeyScopeFocused,
WantMouse: true,
},
},
}
got := b.Options()
want := widgetapi.Options{
MinimumSize: image.Point{6, 3},
WantKeyboard: true,
WantMouse: true,
}
if diff := pretty.Compare(want, got); diff != "" {
t.Errorf("Options => unexpected diff (-want, +got):\n%s", diff)
for _, tc := range tests {
t.Run(tc.desc, func(t *testing.T) {
ct := &callbackTracker{}
b, err := New("text", ct.callback, tc.opts...)
if err != nil {
t.Fatalf("New => unexpected error: %v", err)
}
got := b.Options()
if diff := pretty.Compare(tc.want, got); diff != "" {
t.Errorf("Options => unexpected diff (-want, +got):\n%s", diff)
}
})
}
}

View File

@ -21,6 +21,7 @@ import (
"github.com/mum4k/termdash/cell"
"github.com/mum4k/termdash/keyboard"
"github.com/mum4k/termdash/widgetapi"
)
// Option is used to provide options.
@ -45,6 +46,7 @@ type options struct {
height int
width int
key keyboard.Key
keyScope widgetapi.KeyScope
}
// validate validates the provided options.
@ -103,7 +105,7 @@ func ShadowColor(c cell.Color) Option {
}
// DefaultHeight is the default for the Height option.
const DefaultHeight = 2
const DefaultHeight = 3
// Height sets the height of the button in cells.
// Must be a positive non-zero integer.
@ -123,13 +125,22 @@ func Width(cells int) Option {
})
}
// DefaultKey is the default value for the Key option.
const DefaultKey = keyboard.KeyEnter
// Key configures the keyboard key that presses the button.
// Defaults to DefaultKey.
// The widget responds to this key only if its container if focused.
// When not provided, the widget ignores all keyboard events.
func Key(k keyboard.Key) Option {
return option(func(opts *options) {
opts.key = k
opts.keyScope = widgetapi.KeyScopeFocused
})
}
// GlobalKey is like Key, but makes the widget respond to the key even if its
// container isn't focused.
// When not provided, the widget ignores all keyboard events.
func GlobalKey(k keyboard.Key) Option {
return option(func(opts *options) {
opts.key = k
opts.keyScope = widgetapi.KeyScopeFocused
})
}