Skip to content

Commit 1089208

Browse files
committed
Make use of content-area-relative mouse events everywhere
1 parent c60dc9d commit 1089208

File tree

5 files changed

+136
-70
lines changed

5 files changed

+136
-70
lines changed

lib/Terminal/Widgets/Input/Menu.rakumod

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,17 @@ class Terminal::Widgets::Input::Menu
136136
#| Handle mouse events
137137
multi method handle-event(Terminal::Widgets::Events::MouseEvent:D
138138
$event where !*.mouse.pressed, AtTarget) {
139-
# Always focus on click, but only allow selection if enabled
139+
# Take focus even if clicked on framing instead of content area
140140
self.toplevel.focus-on(self);
141-
self.select($.top-item + $event.relative-to(self)[1]) if $.enabled;
141+
142+
# Only allow selection if enabled and within content area
143+
if $.enabled {
144+
my ($x, $y, $w, $h) = $event.relative-to-content-area(self);
145+
self.select($.top-item + $y) if 0 <= $x < $w && 0 <= $y < $h;
146+
}
147+
148+
# Refresh even if outside content area because of focus state change
149+
self.full-refresh;
142150
}
143151

144152
#| Handle LayoutBuilt event by updating hint and scrolling

lib/Terminal/Widgets/Input/Text.rakumod

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,21 @@ class Terminal::Widgets::Input::Text
231231
#| Handle mouse events
232232
multi method handle-event(Terminal::Widgets::Events::MouseEvent:D
233233
$event where !*.mouse.pressed, AtTarget) {
234+
# Take focus even if clicked on framing instead of content area
234235
self.toplevel.focus-on(self);
235-
# XXXX: Move cursor if enabled? What about scroll?
236+
237+
# Only allow other interaction if enabled and within content area
238+
if $.enabled {
239+
my ($x, $y, $w, $h) = $event.relative-to-content-area(self);
240+
241+
if 0 <= $x < $w && 0 <= $y < $h {
242+
# XXXX: Move cursor if enabled? What about scroll?
243+
# XXXX: Support for selection/copy to clipboard?
244+
}
245+
}
246+
247+
# Refresh even if outside content area because of focus state change
248+
self.full-refresh;
236249
}
237250

238251
#| Abort entry in progress

lib/Terminal/Widgets/RichText.rakumod

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,27 @@ class Terminal::Widgets::RichText
5252

5353
multi method handle-event(Terminal::Widgets::Events::MouseEvent:D
5454
$event where !*.mouse.pressed, AtTarget) {
55+
# Take focus even if clicked on framing instead of content area
5556
self.toplevel.focus-on(self);
5657

57-
my ($x, $y) = $event.relative-to(self);
58-
my $clicked-display-line = $!first-display-line + $y;
59-
my $line-index = @!dl-l[min($clicked-display-line, @!dl-l.end)];
60-
$!cursor-y = $line-index;
61-
my $rel-y = $y - @!l-dl[$line-index];
62-
$x = self!display-pos-to-line-pos(@!lines[$line-index], self.x-scroll + $x, $rel-y);
63-
$!cursor-x = min(self!chars-in-line(@!lines[$line-index]) - 1, $x);
58+
# If enabled and within content area, move cursor and process click
59+
if $.enabled {
60+
my ($x, $y, $w, $h) = $event.relative-to-content-area(self);
61+
62+
if 0 <= $x < $w && 0 <= $y < $h {
63+
my $clicked-display-line = $!first-display-line + $y;
64+
my $line-index = @!dl-l[$clicked-display-line min @!dl-l.end];
65+
$!cursor-y = $line-index;
66+
my $rel-y = $y - @!l-dl[$line-index];
67+
68+
$x = self!display-pos-to-line-pos(@!lines[$line-index],
69+
self.x-scroll + $x, $rel-y);
70+
$!cursor-x = $x min self!chars-in-line(@!lines[$line-index]) - 1;
71+
$_($line-index, $x, 0) with &!process-click;
72+
}
73+
}
74+
75+
# Refresh even if outside content area because of focus state change
6476
self.full-refresh;
65-
&!process-click($line-index, $x, 0) with &!process-click;
6677
}
6778
}

lib/Terminal/Widgets/ScrollBar.rakumod

Lines changed: 66 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -142,33 +142,44 @@ class Terminal::Widgets::HScrollBar
142142
# XXXX: Handle drag events
143143
multi method handle-event(Terminal::Widgets::Events::MouseEvent:D
144144
$event where !*.mouse.pressed, AtTarget) {
145-
# Determine relative click location and bounds
146-
my $layout = $.layout.computed;
147-
my $x = 0 max $event.relative-to(self)[0] - $layout.left-correction;
148-
my $end = 0 max $.w - 1 - $layout.right-correction;
149-
150-
# Handle end arrows if any
151-
if $.show-end-arrows {
152-
if $x == 0 {
153-
self.arrow-left-scroll;
154-
$.scroll-target.refresh-for-scroll;
155-
return;
156-
}
157-
elsif $x == $end {
158-
self.arrow-right-scroll;
145+
# Take focus even if clicked on framing instead of content area
146+
self.toplevel.focus-on(self);
147+
148+
# If enabled and within content area, process click
149+
if $.enabled {
150+
my ($x, $y, $w, $h) = $event.relative-to-content-area(self);
151+
152+
if 0 <= $x < $w && 0 <= $y < $h {
153+
my $end = $w - 1;
154+
155+
# Handle end arrows if any
156+
if $.show-end-arrows {
157+
if $x == 0 {
158+
self.arrow-left-scroll;
159+
$.scroll-target.refresh-for-scroll;
160+
return;
161+
}
162+
elsif $x == $end {
163+
self.arrow-right-scroll;
164+
$.scroll-target.refresh-for-scroll;
165+
return;
166+
}
167+
else {
168+
$end -= 2;
169+
$x--;
170+
}
171+
}
172+
173+
# Handle bar events
174+
my $scroll = floor($.scroll-target.x-max * $x / ($end max 1));
175+
$.scroll-target.set-x-scroll($scroll);
159176
$.scroll-target.refresh-for-scroll;
160177
return;
161178
}
162-
else {
163-
$end -= 2;
164-
$x--;
165-
}
166179
}
167180

168-
# Handle bar events
169-
my $scroll = floor($.scroll-target.x-max * $x / ($end max 1));
170-
$.scroll-target.set-x-scroll($scroll);
171-
$.scroll-target.refresh-for-scroll;
181+
# Refresh even if outside content area because of focus state change
182+
self.full-refresh;
172183
}
173184
}
174185

@@ -260,32 +271,43 @@ class Terminal::Widgets::VScrollBar
260271
# XXXX: Handle drag events
261272
multi method handle-event(Terminal::Widgets::Events::MouseEvent:D
262273
$event where !*.mouse.pressed, AtTarget) {
263-
# Determine relative click location and bounds
264-
my $layout = $.layout.computed;
265-
my $y = 0 max $event.relative-to(self)[1] - $layout.top-correction;
266-
my $end = 0 max $.h - 1 - $layout.bottom-correction;
267-
268-
# Handle end arrows if any
269-
if $.show-end-arrows {
270-
if $y == 0 {
271-
self.arrow-up-scroll;
272-
$.scroll-target.refresh-for-scroll;
273-
return;
274-
}
275-
elsif $y == $end {
276-
self.arrow-down-scroll;
274+
# Take focus even if clicked on framing instead of content area
275+
self.toplevel.focus-on(self);
276+
277+
# If enabled and within content area, process click
278+
if $.enabled {
279+
my ($x, $y, $w, $h) = $event.relative-to-content-area(self);
280+
281+
if 0 <= $x < $w && 0 <= $y < $h {
282+
my $end = $h - 1;
283+
284+
# Handle end arrows if any
285+
if $.show-end-arrows {
286+
if $y == 0 {
287+
self.arrow-up-scroll;
288+
$.scroll-target.refresh-for-scroll;
289+
return;
290+
}
291+
elsif $y == $end {
292+
self.arrow-down-scroll;
293+
$.scroll-target.refresh-for-scroll;
294+
return;
295+
}
296+
else {
297+
$end -= 2;
298+
$y--;
299+
}
300+
}
301+
302+
# Handle bar events
303+
my $scroll = floor($.scroll-target.y-max * $y / ($end max 1));
304+
$.scroll-target.set-y-scroll($scroll);
277305
$.scroll-target.refresh-for-scroll;
278306
return;
279307
}
280-
else {
281-
$end -= 2;
282-
$y--;
283-
}
284308
}
285309

286-
# Handle bar events
287-
my $scroll = floor($.scroll-target.y-max * $y / ($end max 1));
288-
$.scroll-target.set-y-scroll($scroll);
289-
$.scroll-target.refresh-for-scroll;
310+
# Refresh even if outside content area because of focus state change
311+
self.full-refresh;
290312
}
291313
}

lib/Terminal/Widgets/TreeView.rakumod

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -368,23 +368,35 @@ class Terminal::Widgets::TreeView
368368

369369
multi method handle-event(Terminal::Widgets::Events::MouseEvent:D
370370
$event where !*.mouse.pressed, AtTarget) {
371+
# Take focus even if clicked on framing instead of content area
371372
self.toplevel.focus-on(self);
372373

373-
my ($x, $y) = $event.relative-to(self);
374-
my $clicked-display-line = $!first-display-line + $y;
375-
my $line-index = @!dl-l[min($clicked-display-line, @!dl-l.end)];
376-
$!cursor-y = $line-index;
377-
my $dn = self!line-to-dn: $line-index;
378-
my $rel-y = $y - @!l-dl[$line-index];
379-
$x = self!display-pos-to-line-pos(@!lines[$line-index], self.x-scroll + $x, $rel-y);
380-
$!cursor-x = min(self!chars-in-line(@!lines[$line-index]) - 1, $x);
381-
self.full-refresh;
382-
my $prefix-len = duospace-width(self!dn-get-prefix($dn));
383-
if $!cursor-x < $prefix-len {
384-
self!toggle-expand-dn($dn);
385-
}
386-
else {
387-
&!process-click($dn.orig-node, $!cursor-x - $prefix-len, 0) with &!process-click;
374+
# If enabled and within content area, move cursor and process click
375+
if $.enabled {
376+
my ($x, $y, $w, $h) = $event.relative-to-content-area(self);
377+
378+
if 0 <= $x < $w && 0 <= $y < $h {
379+
my $clicked-display-line = $!first-display-line + $y;
380+
my $line-index = @!dl-l[$clicked-display-line min @!dl-l.end];
381+
$!cursor-y = $line-index;
382+
my $dn = self!line-to-dn: $line-index;
383+
my $rel-y = $y - @!l-dl[$line-index];
384+
385+
$x = self!display-pos-to-line-pos(@!lines[$line-index],
386+
self.x-scroll + $x, $rel-y);
387+
$!cursor-x = $x min self!chars-in-line(@!lines[$line-index]) - 1;
388+
389+
my $prefix-len = duospace-width(self!dn-get-prefix($dn));
390+
if $!cursor-x < $prefix-len {
391+
self!toggle-expand-dn($dn);
392+
}
393+
else {
394+
$_($dn.orig-node, $!cursor-x - $prefix-len, 0) with &!process-click;
395+
}
396+
}
388397
}
398+
399+
# Refresh even if outside content area because of focus state change
400+
self.full-refresh;
389401
}
390402
}

0 commit comments

Comments
 (0)