3636 onMousePressed, onMouseMoved, onMouseReleased, onMouseWheel
3737 pressButton
3838 refresh, refreshRecursively, refreshAll
39+ scrollTo, scrollIntoView
3940 setActive
4041 setFocus, blurFocus
4142 showMenu, showContextMenu, showContextMenuWithInput, hideContextMenu
@@ -197,6 +198,7 @@ export State :: struct {
197198 refresh :: _refresh,
198199 refreshAll :: _refreshAll,
199200 refreshRecursively :: _refreshRecursively,
201+ scrollIntoView :: _scrollIntoView,
200202 scrollTo :: _scrollTo,
201203 setActive :: _setActive,
202204 setFocus :: _setFocus,
@@ -234,6 +236,7 @@ local _pressButton :: pressButton
234236local _refresh :: refresh
235237local _refreshAll :: refreshAll
236238local _refreshRecursively :: refreshRecursively
239+ local _scrollIntoView :: scrollIntoView
237240local _scrollTo :: scrollTo
238241local _setActive :: setActive
239242local _setFocus :: setFocus
@@ -424,6 +427,7 @@ export Buttons :: struct {
424427 align = Alignment.CENTER,
425428 vertical = false,
426429 allowFocus = false,
430+ selectMultiple = false, -- Used if Buttons.allowFocus is set.
427431 buttonMinHeight = 0,
428432
429433 buttonWidth: float, -- Round when necessary!
@@ -588,20 +592,35 @@ export onKeyPressed :: (state:State, key:LK.KeyConstant, scancode:LK.Scancode, i
588592 if found triggerDoublePressEvent(state, buttons, buttons.buttons[i].name, i) -- @Cleanup: Rename double-press events to something better, or use the submit event.
589593
590594 } elseif key == "down" or key == "up" {
591- if buttons.buttons {
592- local dir = (key == "down") ? 1 : -1
593- local found, i = indexWith(buttons.buttons, "selected", true)
595+ if not buttons.buttons return true
594596
595- i = found
596- ? ((i-1+dir) % #buttons.buttons + 1)
597- : (dir < 0 ? #buttons.buttons : 1)
597+ local dir = (key == "down") ? 1 : -1
598+ local found, i = indexWith(buttons.buttons, "selected", true)
598599
599- for buttons.buttons it.selected = (itIndex == i)
600+ i = found
601+ ? ((i-1+dir) % #buttons.buttons + 1)
602+ : (dir < 0 ? #buttons.buttons : 1)
600603
601- -- @Incomplete: Scroll button into view if we're in a scrollable.
602- triggerBeginEvent (state, buttons, buttons.buttons[i].name, i)
603- triggerActionEvent(state, buttons, buttons.buttons[i].name, i, .KEYBOARD, alsoEnd=true)
604- }
604+ for buttons.buttons it.selected = (itIndex == i)
605+ state.scrollIntoView!(buttons, i)
606+
607+ triggerBeginEvent (state, buttons, buttons.buttons[i].name, i)
608+ triggerActionEvent(state, buttons, buttons.buttons[i].name, i, .KEYBOARD, alsoEnd=true)
609+
610+ } elseif key == "pageup" or key == "pagedown" {
611+ -- @Incomplete
612+
613+ } elseif key == "end" or key == "home" {
614+ local iTarget = (key == "end") ? #buttons.buttons : 1
615+ local found, i = indexWith(buttons.buttons, "selected", true)
616+
617+ if found and i == iTarget return true
618+
619+ for buttons.buttons it.selected = (itIndex == iTarget)
620+ state.scrollIntoView!(buttons, iTarget)
621+
622+ triggerBeginEvent (state, buttons, buttons.buttons[i].name, i)
623+ triggerActionEvent(state, buttons, buttons.buttons[i].name, i, .KEYBOARD, alsoEnd=true)
605624 }
606625 }
607626
@@ -761,14 +780,25 @@ export onMousePressed :: (state:State, mx,my:int, mbutton:int, presses:int) -> (
761780 local buttons = cast(Buttons) el
762781 local slider = cast(Slider) el
763782
783+ local mayDoublePress = (presses % 2 == 0)
784+
764785 if el.type == Buttons and buttons.allowFocus {
765- for buttons.buttons it.selected = (itIndex == state.hoveredSubid)
786+ if buttons.selectMultiple and LK.isDown(lctrl,rctrl) {
787+ local button = buttons.buttons[state.hoveredSubid]
788+ button.selected = not button.selected
789+ mayDoublePress = false
790+ -- @Incomplete: Maybe don't trigger action event like normal when deselecting?
791+ } else {
792+ for buttons.buttons {
793+ it.selected = (itIndex == state.hoveredSubid)
794+ }
795+ }
766796 }
767797
768798 -- Buttons which allow double press.
769799 if el.type == Buttons and (buttons.style == .CONTEXT_MENU or buttons.style == .LIST) {
770800 local handled = false
771- if presses % 2 == 0 {
801+ if mayDoublePress {
772802 handled = triggerDoublePressEvent(state, buttons, buttons.buttons[state.hoveredSubid].name, state.hoveredSubid)
773803 }
774804 if not handled {
@@ -777,7 +807,7 @@ export onMousePressed :: (state:State, mx,my:int, mbutton:int, presses:int) -> (
777807 }
778808
779809 -- Double press on sliders.
780- } elseif el.type == Slider and presses % 2 == 0 and triggerDoublePressEvent(state, slider, "", 0) {
810+ } elseif el.type == Slider and mayDoublePress and triggerDoublePressEvent(state, slider, "", 0) {
781811 -- void
782812
783813 -- Press that activates.
@@ -3272,7 +3302,8 @@ export setFocus :: (state:State, name:string) {
32723302 state.setFocus!(input)
32733303}
32743304export setFocus :: (state:State, widget:Widget) {
3275- if state.focusId == widget.id return
3305+ if not state.isElementVisible!(widget) return
3306+ if state.focusId == widget.id return
32763307
32773308 state.blurFocus!(abort=false)
32783309 state.focusId = widget.id
@@ -3753,6 +3784,12 @@ export scrollTo :: (state:State, scrollable:Scrollable, scroll:int, limit=false)
37533784
37543785
37553786
3787+ export scrollIntoView :: (state:State, el:Element, subid:int) {
3788+ -- @Incomplete
3789+ }
3790+
3791+
3792+
37563793export getButtonLayout :: (state:State, buttons:Buttons, i:int) -> (x,y,w,h:int) {
37573794 updateLayoutIfNeeded(state)
37583795
0 commit comments