mirror of
https://github.com/mum4k/termdash.git
synced 2025-04-25 13:48:50 +08:00
Allow button to specify multiple trigger keys.
This commit is contained in:
parent
891a672716
commit
3a0d044a4d
@ -159,7 +159,7 @@ func (b *Button) keyActivated(k *terminalapi.Keyboard) bool {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
|
||||
if k.Key == b.opts.key {
|
||||
if b.opts.keys[k.Key] {
|
||||
b.state = button.Down
|
||||
now := time.Now().UTC()
|
||||
b.keyTriggerTime = &now
|
||||
@ -220,7 +220,7 @@ func (b *Button) Options() widgetapi.Options {
|
||||
return widgetapi.Options{
|
||||
MinimumSize: image.Point{width, height},
|
||||
MaximumSize: image.Point{width, height},
|
||||
WantKeyboard: widgetapi.KeyScopeGlobal,
|
||||
WantKeyboard: b.opts.keyScope,
|
||||
WantMouse: widgetapi.MouseScopeGlobal,
|
||||
}
|
||||
}
|
||||
|
@ -243,6 +243,105 @@ func TestButton(t *testing.T) {
|
||||
count: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "draws button in down state due to a keyboard event when multiple keys are specified",
|
||||
callback: &callbackTracker{},
|
||||
text: "hello",
|
||||
opts: []Option{
|
||||
Keys(keyboard.KeyEnter, keyboard.KeyTab),
|
||||
},
|
||||
canvas: image.Rect(0, 0, 8, 4),
|
||||
events: []terminalapi.Event{
|
||||
&terminalapi.Keyboard{Key: keyboard.KeyTab},
|
||||
},
|
||||
want: func(size image.Point) *faketerm.Terminal {
|
||||
ft := faketerm.MustNew(size)
|
||||
cvs := testcanvas.MustNew(ft.Area())
|
||||
|
||||
// Button.
|
||||
testcanvas.MustSetAreaCells(cvs, image.Rect(1, 1, 8, 4), 'x', cell.BgColor(cell.ColorNumber(117)))
|
||||
|
||||
// Text.
|
||||
testdraw.MustText(cvs, "hello", image.Point{2, 2},
|
||||
draw.TextCellOpts(
|
||||
cell.FgColor(cell.ColorBlack),
|
||||
cell.BgColor(cell.ColorNumber(117))),
|
||||
)
|
||||
|
||||
testcanvas.MustApply(cvs, ft)
|
||||
return ft
|
||||
},
|
||||
wantCallback: &callbackTracker{
|
||||
called: true,
|
||||
count: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "draws button in down state due to a keyboard event when single global key is specified",
|
||||
callback: &callbackTracker{},
|
||||
text: "hello",
|
||||
opts: []Option{
|
||||
GlobalKey(keyboard.KeyTab),
|
||||
},
|
||||
canvas: image.Rect(0, 0, 8, 4),
|
||||
events: []terminalapi.Event{
|
||||
&terminalapi.Keyboard{Key: keyboard.KeyTab},
|
||||
},
|
||||
want: func(size image.Point) *faketerm.Terminal {
|
||||
ft := faketerm.MustNew(size)
|
||||
cvs := testcanvas.MustNew(ft.Area())
|
||||
|
||||
// Button.
|
||||
testcanvas.MustSetAreaCells(cvs, image.Rect(1, 1, 8, 4), 'x', cell.BgColor(cell.ColorNumber(117)))
|
||||
|
||||
// Text.
|
||||
testdraw.MustText(cvs, "hello", image.Point{2, 2},
|
||||
draw.TextCellOpts(
|
||||
cell.FgColor(cell.ColorBlack),
|
||||
cell.BgColor(cell.ColorNumber(117))),
|
||||
)
|
||||
|
||||
testcanvas.MustApply(cvs, ft)
|
||||
return ft
|
||||
},
|
||||
wantCallback: &callbackTracker{
|
||||
called: true,
|
||||
count: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "draws button in down state due to a keyboard event when multiple global keys are specified",
|
||||
callback: &callbackTracker{},
|
||||
text: "hello",
|
||||
opts: []Option{
|
||||
GlobalKeys(keyboard.KeyEnter, keyboard.KeyTab),
|
||||
},
|
||||
canvas: image.Rect(0, 0, 8, 4),
|
||||
events: []terminalapi.Event{
|
||||
&terminalapi.Keyboard{Key: keyboard.KeyTab},
|
||||
},
|
||||
want: func(size image.Point) *faketerm.Terminal {
|
||||
ft := faketerm.MustNew(size)
|
||||
cvs := testcanvas.MustNew(ft.Area())
|
||||
|
||||
// Button.
|
||||
testcanvas.MustSetAreaCells(cvs, image.Rect(1, 1, 8, 4), 'x', cell.BgColor(cell.ColorNumber(117)))
|
||||
|
||||
// Text.
|
||||
testdraw.MustText(cvs, "hello", image.Point{2, 2},
|
||||
draw.TextCellOpts(
|
||||
cell.FgColor(cell.ColorBlack),
|
||||
cell.BgColor(cell.ColorNumber(117))),
|
||||
)
|
||||
|
||||
testcanvas.MustApply(cvs, ft)
|
||||
return ft
|
||||
},
|
||||
wantCallback: &callbackTracker{
|
||||
called: true,
|
||||
count: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "keyboard event ignored when no key specified",
|
||||
callback: &callbackTracker{},
|
||||
@ -814,6 +913,19 @@ func TestOptions(t *testing.T) {
|
||||
WantMouse: widgetapi.MouseScopeGlobal,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "registers for focused keyboard events when multiple keys are specified",
|
||||
text: "hello",
|
||||
opts: []Option{
|
||||
Keys(keyboard.KeyEnter, keyboard.KeyTab),
|
||||
},
|
||||
want: widgetapi.Options{
|
||||
MinimumSize: image.Point{8, 4},
|
||||
MaximumSize: image.Point{8, 4},
|
||||
WantKeyboard: widgetapi.KeyScopeFocused,
|
||||
WantMouse: widgetapi.MouseScopeGlobal,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "registers for global keyboard events",
|
||||
text: "hello",
|
||||
@ -827,6 +939,19 @@ func TestOptions(t *testing.T) {
|
||||
WantMouse: widgetapi.MouseScopeGlobal,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "registers for global keyboard events when multiple keys are specified",
|
||||
text: "hello",
|
||||
opts: []Option{
|
||||
GlobalKeys(keyboard.KeyEnter, keyboard.KeyTab),
|
||||
},
|
||||
want: widgetapi.Options{
|
||||
MinimumSize: image.Point{8, 4},
|
||||
MaximumSize: image.Point{8, 4},
|
||||
WantKeyboard: widgetapi.KeyScopeGlobal,
|
||||
WantMouse: widgetapi.MouseScopeGlobal,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
|
@ -47,7 +47,8 @@ type options struct {
|
||||
shadowColor cell.Color
|
||||
height int
|
||||
width int
|
||||
keyScopes []*keyScope
|
||||
keys map[keyboard.Key]bool
|
||||
keyScope widgetapi.KeyScope
|
||||
keyUpDelay time.Duration
|
||||
}
|
||||
|
||||
@ -80,6 +81,7 @@ func newOptions(text string) *options {
|
||||
height: DefaultHeight,
|
||||
width: widthFor(text),
|
||||
keyUpDelay: DefaultKeyUpDelay,
|
||||
keys: map[keyboard.Key]bool{},
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,31 +136,53 @@ func WidthFor(text string) Option {
|
||||
})
|
||||
}
|
||||
|
||||
// Key configures the keyboard keys that press the button.
|
||||
// Can be specified multiple times to provide multiple keys.
|
||||
// Key configures the keyboard key that presses the button.
|
||||
// The widget responds to this key only if its container is focused.
|
||||
// When not provided, the widget ignores all keyboard events.
|
||||
//
|
||||
// Clears all keys set previously.
|
||||
// Mutually exclusive with GlobalKey() and GlobalKeys().
|
||||
func Key(k keyboard.Key) Option {
|
||||
return option(func(opts *options) {
|
||||
ks := &keyScope{
|
||||
key: k,
|
||||
scope: widgetapi.KeyScopeFocused,
|
||||
}
|
||||
opts.keyScopes = append(opts.keyScopes, ks)
|
||||
opts.keys = map[keyboard.Key]bool{}
|
||||
opts.keys[k] = true
|
||||
opts.keyScope = widgetapi.KeyScopeFocused
|
||||
})
|
||||
}
|
||||
|
||||
// GlobalKey is like Key, but makes the widget respond to the keys even if its
|
||||
// GlobalKey is like Key, but makes the widget respond to the key even if its
|
||||
// container isn't focused.
|
||||
// Can be specified multiple times to provide multiple keys.
|
||||
// When not provided, the widget ignores all keyboard events.
|
||||
//
|
||||
// Clears all keys set previously.
|
||||
// Mutually exclusive with Key() and Keys().
|
||||
func GlobalKey(k keyboard.Key) Option {
|
||||
return option(func(opts *options) {
|
||||
ks := &keyScope{
|
||||
key: k,
|
||||
scope: widgetapi.KeyScopeGlobal,
|
||||
opts.keys = map[keyboard.Key]bool{}
|
||||
opts.keys[k] = true
|
||||
opts.keyScope = widgetapi.KeyScopeGlobal
|
||||
})
|
||||
}
|
||||
|
||||
// Keys is like Key, but allows to configure multiple keys.
|
||||
func Keys(keys ...keyboard.Key) Option {
|
||||
return option(func(opts *options) {
|
||||
opts.keys = map[keyboard.Key]bool{}
|
||||
for _, k := range keys {
|
||||
opts.keys[k] = true
|
||||
}
|
||||
opts.keyScopes = append(opts.keyScopes, ks)
|
||||
opts.keyScope = widgetapi.KeyScopeFocused
|
||||
})
|
||||
}
|
||||
|
||||
// GlobalKeys is like GlobalKey, but allows to configure multiple keys.
|
||||
func GlobalKeys(keys ...keyboard.Key) Option {
|
||||
return option(func(opts *options) {
|
||||
opts.keys = map[keyboard.Key]bool{}
|
||||
for _, k := range keys {
|
||||
opts.keys[k] = true
|
||||
}
|
||||
opts.keyScope = widgetapi.KeyScopeGlobal
|
||||
})
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user