diff options
-rw-r--r-- | src/local/pager.nim | 88 | ||||
-rw-r--r-- | src/local/select.nim | 17 |
2 files changed, 60 insertions, 45 deletions
diff --git a/src/local/pager.nim b/src/local/pager.nim index b378bbba..349b9006 100644 --- a/src/local/pager.nim +++ b/src/local/pager.nim @@ -636,6 +636,7 @@ proc handleMouseInput(pager: Pager; input: MouseInput; container: Container) = container.setCursorXY(container.fromx + input.col, container.fromy + input.row) pager.openMenu(input.col, input.row) + pager.menu.unselect() of mibThumbInner: if input.t == mitPress: discard pager.evalAction("cmd.pager.prevBuffer", 0) @@ -646,54 +647,55 @@ proc handleMouseInput(pager: Pager; input: MouseInput; container: Container) = proc handleMouseInput(pager: Pager; input: MouseInput; select: Select) = let y = select.fromy + input.row - select.y - 1 # one off because of border - case input.button - of mibRight: - if (input.col, input.row) != pager.pressed: - # Prevent immediate movement/submission in case the menu appeared under - # the cursor. - select.setCursorY(y) - case input.t - of mitPress: - # Do not include borders, so that a double right click closes the - # menu again. - if input.row notin select.y + 1 ..< select.y + select.height - 1 or - input.col notin select.x + 1 ..< select.x + select.width - 1: - pager.blockTillRelease = true - select.cursorLeft() - of mitRelease: - if input.row in select.y + 1 ..< select.y + select.height - 1 and - input.col in select.x + 1 ..< select.x + select.width - 1 and - (input.col, input.row) != pager.pressed: - select.click() - # forget about where we started once btn3 is released - pager.pressed = (-1, -1) - of mitMove: discard - of mibLeft: - case input.t - of mitPress: - if input.row notin select.y ..< select.y + select.height or - input.col notin select.x ..< select.x + select.width: - # clicked outside the select - pager.blockTillRelease = true - select.cursorLeft() - of mitRelease: - let at = (input.col, input.row) - if at == pager.pressed and - (input.row in select.y + 1 ..< select.y + select.height - 1 and - input.col in select.x + 1 ..< select.x + select.width - 1 or - select.multiple and at == (select.x, select.y)): - # clicked inside the select + if input.button in {mibRight, mibLeft}: + # Note: "not inside and not outside" is a valid state, and it + # represents the mouse being above the border. + let inside = input.row in select.y + 1 ..< select.y + select.height - 1 and + input.col in select.x + 1 ..< select.x + select.width - 1 + let outside = input.row notin select.y ..< select.y + select.height or + input.col notin select.x ..< select.x + select.width + if input.button == mibRight: + if not inside: + select.unselect() + elif (input.col, input.row) != pager.pressed: + # Prevent immediate movement/submission in case the menu appeared under + # the cursor. select.setCursorY(y) - select.click() - of mitMove: discard - else: discard + case input.t + of mitPress: + # Do not include borders, so that a double right click closes the + # menu again. + if not inside: + pager.blockTillRelease = true + select.cursorLeft() + of mitRelease: + if inside and (input.col, input.row) != pager.pressed: + select.click() + elif outside: + select.cursorLeft() + # forget about where we started once btn3 is released + pager.pressed = (-1, -1) + of mitMove: discard + else: # mibLeft + case input.t + of mitPress: + if outside: # clicked outside the select + pager.blockTillRelease = true + select.cursorLeft() + of mitRelease: + let at = (input.col, input.row) + if at == pager.pressed and + (inside or select.multiple and at == (select.x, select.y)): + # clicked inside the select + select.setCursorY(y) + select.click() + of mitMove: discard proc handleMouseInput(pager: Pager; input: MouseInput) = if pager.blockTillRelease: - if input.t == mitRelease: - pager.blockTillRelease = false - else: + if input.t != mitRelease: return + pager.blockTillRelease = false if pager.menu != nil: pager.handleMouseInput(input, pager.menu) elif (let container = pager.container; container != nil): diff --git a/src/local/select.nim b/src/local/select.nim index b8e19d6c..f98fb944 100644 --- a/src/local/select.nim +++ b/src/local/select.nim @@ -27,6 +27,7 @@ type x*: int y*: int redraw*: bool + unselected*: bool bpos: seq[int] opaque: RootRef finishImpl: SelectFinish @@ -53,12 +54,17 @@ proc setCursorY*(select: Select; y: int) = if not select.multiple: y = max(y, 0) if select.options[max(y, 0)].nop: + if not select.unselected: + select.unselected = true + select.queueDraw() return if select.fromy > y: select.setFromY(y) if select.fromy + select.maxh <= y: select.setFromY(y - select.maxh + 1) select.cursory = y + if select.unselected: + select.unselected = false select.queueDraw() proc getCursorX*(select: Select): int = @@ -139,7 +145,8 @@ proc submit(select: Select) {.jsfunc.} = select.finishImpl(select.opaque, select, srSubmit) proc click*(select: Select) {.jsfunc.} = - if select.cursory >= 0 and select.cursory < select.options.len and + if select.unselected or + select.cursory >= 0 and select.cursory < select.options.len and select.options[select.cursory].nop: discard elif not select.multiple: @@ -233,6 +240,11 @@ proc popCursorPos*(select: Select; nojump = false) = if not nojump: select.queueDraw() +proc unselect*(select: Select) = + if not select.unselected: + select.unselected = true + select.queueDraw() + const HorizontalBar = "\u2500" const VerticalBar = "\u2502" const CornerTopLeft = "\u250C" @@ -325,7 +337,8 @@ proc drawSelect*(select: Select; display: var FixedGrid) = let dls = y * display.width if (select.multiple and k < select.selected.len and select.selected[k] == i or - not select.multiple and select.getCursorY() == y): + not select.multiple and select.getCursorY() == y and + not select.unselected): format.flags.incl(ffReverse) inc k else: |