Skip to content

Commit e8a5139

Browse files
committed
Refactor hover handling, scroll logic, and input layout for improved clarity and consistency
- Enhanced `on_hover` behavior in `view_scrollbar.v` to update cursor and mark events as handled. - Simplified scroll container lookups using `find_layout_by_id_scroll` in `xtra_text_cursor.v`. - Improved `layout_hover` in `layout.v` to handle hover events with early termination when processed. - Refactored input layout in `view_input.v` for better readability and organization.
1 parent e0c41ac commit e8a5139

File tree

5 files changed

+106
-78
lines changed

5 files changed

+106
-78
lines changed

layout.v

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -748,19 +748,22 @@ fn layout_amend(mut layout Layout, mut w Window) {
748748
// layout_hover is a convenience callback for clients to do hover things.
749749
// Originally, it was done in layout_amend but it's a fair bit of boiler
750750
// plate that this callback encapsulates.
751-
fn layout_hover(mut layout Layout, mut w Window) {
751+
fn layout_hover(mut layout Layout, mut w Window) bool {
752752
if w.mouse_is_locked() {
753-
return
753+
return false
754754
}
755755
for mut child in layout.children {
756-
layout_hover(mut child, mut w)
756+
is_handled := layout_hover(mut child, mut w)
757+
if is_handled {
758+
return true
759+
}
757760
}
758761
if layout.shape.on_hover != unsafe { nil } {
759762
if layout.shape.disabled {
760-
return
763+
return false
761764
}
762765
if w.dialog_cfg.visible && !layout_in_dialog_layout(layout) {
763-
return
766+
return false
764767
}
765768
ctx := w.context()
766769
if layout.shape.point_in_shape(ctx.mouse_pos_x, ctx.mouse_pos_y) {
@@ -786,6 +789,8 @@ fn layout_hover(mut layout Layout, mut w Window) {
786789
window_height: ctx.height
787790
}
788791
layout.shape.on_hover(mut layout, mut ev, mut w)
792+
return ev.is_handled
789793
}
790794
}
795+
return false
791796
}

render.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ fn render_text(mut shape Shape, clip DrawClip, mut window Window) {
325325
window.renderers << DrawText{
326326
x: x
327327
y: y
328-
text: lnl.clone()
328+
text: lnl
329329
cfg: text_cfg
330330
}
331331

view_input.v

Lines changed: 61 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -151,62 +151,68 @@ pub fn input(cfg InputCfg) View {
151151
mode := if cfg.mode == .single_line { TextMode.single_line } else { TextMode.wrap_keep_spaces }
152152

153153
return row(
154-
name: 'input border'
155-
id: cfg.id
156-
id_focus: cfg.id_focus
157-
id_scroll: cfg.id_scroll
158-
scrollbar_cfg_x: cfg.scrollbar_cfg_x
159-
scrollbar_cfg_y: cfg.scrollbar_cfg_y
160-
tooltip: cfg.tooltip
161-
width: cfg.width
162-
height: cfg.height
163-
min_width: cfg.min_width
164-
max_width: cfg.max_width
165-
min_height: cfg.min_height
166-
max_height: cfg.max_height
167-
disabled: cfg.disabled
168-
color: cfg.color_border
169-
invisible: cfg.invisible
170-
fill: cfg.fill_border
171-
padding: cfg.padding_border
172-
radius: cfg.radius_border
173-
sizing: cfg.sizing
174-
on_char: cfg.on_char
175-
on_hover: cfg.hover
176-
amend_layout: cfg.amend_layout
177-
content: [
178-
row(
179-
name: 'input interior'
180-
color: cfg.color
181-
clip: true
182-
fill: cfg.fill
183-
padding: cfg.padding
184-
radius: cfg.radius
185-
sizing: fill_fill
186-
spacing: spacing_small
187-
on_click: cfg.on_click_interior
188-
content: [
189-
text(
190-
id_focus: cfg.id_focus
191-
text: txt
192-
text_style: txt_style
193-
mode: mode
194-
is_password: cfg.is_password
195-
placeholder_active: placeholder_active
196-
),
197-
rectangle(
198-
color: color_transparent
199-
sizing: fill_fit
200-
),
154+
name: 'input border'
155+
id: cfg.id
156+
id_focus: cfg.id_focus
157+
tooltip: cfg.tooltip
158+
width: cfg.width
159+
height: cfg.height
160+
min_width: cfg.min_width
161+
max_width: cfg.max_width
162+
min_height: cfg.min_height
163+
max_height: cfg.max_height
164+
disabled: cfg.disabled
165+
clip: true
166+
color: cfg.color_border
167+
invisible: cfg.invisible
168+
fill: cfg.fill_border
169+
padding: cfg.padding_border
170+
radius: cfg.radius_border
171+
sizing: cfg.sizing
172+
on_char: cfg.on_char
173+
on_hover: cfg.hover
174+
amend_layout: cfg.amend_layout
175+
content: [
176+
column(
177+
name: 'input interior'
178+
id_scroll: cfg.id_scroll
179+
scrollbar_cfg_x: cfg.scrollbar_cfg_x
180+
scrollbar_cfg_y: cfg.scrollbar_cfg_y
181+
color: cfg.color
182+
fill: cfg.fill
183+
padding: cfg.padding
184+
radius: cfg.radius
185+
sizing: fill_fill
186+
spacing: spacing_small
187+
content: [
201188
row(
202-
name: 'input icon'
203189
padding: padding_none
204-
on_click: cfg.on_click_icon
205-
on_hover: cfg.hover_icon
190+
sizing: fill_fill
191+
on_click: cfg.on_click_interior
206192
content: [
207193
text(
208-
text: cfg.icon
209-
text_style: cfg.icon_style
194+
id_focus: cfg.id_focus
195+
text: txt
196+
text_style: txt_style
197+
mode: mode
198+
is_password: cfg.is_password
199+
placeholder_active: placeholder_active
200+
),
201+
rectangle(
202+
color: color_transparent
203+
sizing: fill_fit
204+
),
205+
row(
206+
name: 'input icon'
207+
padding: padding_none
208+
on_click: cfg.on_click_icon
209+
on_hover: cfg.hover_icon
210+
content: [
211+
text(
212+
text: cfg.icon
213+
text_style: cfg.icon_style
214+
),
215+
]
210216
),
211217
]
212218
),
@@ -226,7 +232,9 @@ fn (_ &InputCfg) on_click_interior(layout &Layout, mut e Event, mut w Window) {
226232
if ly.shape.id_focus > 0 {
227233
w.set_id_focus(ly.shape.id_focus)
228234
}
229-
ly.shape.on_click(ly, mut e, mut w)
235+
if layout.shape.on_click != unsafe { nil } {
236+
ly.shape.on_click(ly, mut e, mut w)
237+
}
230238
}
231239

232240
// on_char handles keyboard and character input for the input field.

view_scrollbar.v

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,11 +281,13 @@ fn (cfg &ScrollbarCfg) amend_layout(mut layout Layout, mut w Window) {
281281
// on_hover handles the mouse hover event on the scrollbar.
282282
// It changes the thumb's color to a hover state if it's not transparent
283283
// or if the overflow mode is set to `on_hover`.
284-
fn (cfg &ScrollbarCfg) on_hover(mut layout Layout, mut _ Event, mut w Window) {
284+
fn (cfg &ScrollbarCfg) on_hover(mut layout Layout, mut e Event, mut w Window) {
285285
// on hover dim color of thumb
286286
thumb := 0
287287
if layout.children[thumb].shape.color != color_transparent || cfg.overflow == .on_hover {
288288
layout.children[thumb].shape.color = gui_theme.color_active
289+
w.set_mouse_cursor_arrow()
290+
e.is_handled = true
289291
}
290292
}
291293

xtra_text_cursor.v

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -447,12 +447,7 @@ fn (tv &TextView) auto_scroll_cursor(id_focus u32, id_scroll_container u32, mut
447447

448448
// Decide how fast the scroll animation should be based on the distance
449449
// the mouse is outside the scroll container view.
450-
//
451-
// Find the scroll container
452-
scroll_container := w.layout.find_layout(fn [id_scroll_container] (ly Layout) bool {
453-
return ly.shape.id_scroll == id_scroll_container
454-
}) or { return }
455-
450+
scroll_container := find_layout_by_id_scroll(w.layout, id_scroll_container) or { return }
456451
evs := event_relative_to(scroll_container.shape, e)
457452

458453
distance := match evs.mouse_y < 0 {
@@ -477,18 +472,8 @@ fn (tv &TextView) auto_scroll_cursor(id_focus u32, id_scroll_container u32, mut
477472
// Returns -1 if the scroll container cannot be found.
478473
fn cursor_pos_to_scroll_y(cursor_pos int, shape &Shape, mut w Window) f32 {
479474
id_scroll_container := shape.id_scroll_container
480-
481-
// Find the scroll container and calculate height. (need to start at the root layout)
482-
scroll_container := w.layout.find_layout(fn [id_scroll_container] (ly Layout) bool {
483-
return ly.shape.id_scroll == id_scroll_container
484-
}) or { return -1 }
485-
486-
// Determine the height of the scrollable region
487-
mut padding_height := scroll_container.shape.padding.height()
488-
if scroll_container.children.len > 0 {
489-
padding_height += scroll_container.children[0].shape.padding.height()
490-
}
491-
scroll_view_height := scroll_container.shape.height - padding_height
475+
scroll_container := find_layout_by_id_scroll(w.layout, id_scroll_container) or { return -1 }
476+
scroll_view_height := scroll_container.shape.height - scroll_container.shape.padding.height()
492477

493478
// Find the index of the line where the cursor is located.
494479
mut line_idx := 0
@@ -523,6 +508,34 @@ fn cursor_pos_to_scroll_y(cursor_pos int, shape &Shape, mut w Window) f32 {
523508
return scroll_offset_y
524509
}
525510

511+
fn cursor_pos_to_scroll_x(cursor_pos int, shape &Shape, mut w Window) f32 {
512+
return 0
513+
}
514+
515+
// id_scroll_container := shape.id_scroll_container
516+
// scroll_container := find_scroll_container(id_scroll_container, w) or { return -1 }
517+
//
518+
// // Determine the width of the scrollable region
519+
// mut padding_width := scroll_container.shape.padding.width()
520+
// if scroll_container.children.len > 0 {
521+
// padding_width += scroll_container.children[0].shape.padding.width()
522+
// }
523+
// // scroll_view_width := scroll_container.shape.width - padding_width
524+
//
525+
// // Find the index of the line where the cursor is located.
526+
// mut line_idx := 0
527+
// mut total_len := 0
528+
// for i, line in shape.text_lines {
529+
// line_idx = i
530+
// total_len += utf8_str_visible_length(line)
531+
// if total_len > cursor_pos {
532+
// break
533+
// }
534+
// }
535+
//
536+
// width := utf8_str_visible_length(shape.text.lines[line_idx][..total_len - cursor_pos])
537+
// }
538+
526539
// mouse_cursor_pos determines the character index (cursor position) within
527540
// the entire text based on the mouse coordinates.
528541
// It handles multiline text by calculating the line index first, then

0 commit comments

Comments
 (0)