Skip to content

Commit 14c35ea

Browse files
mike-wardclaude
andcommitted
show all 256 icons in showcase; fix input cursor on external text clear
- icons demo: display full icon catalog in 5-col grid with x-large size - category click clears search query - clamp cursor_pos to text length in insert/delete/render_cursor - render cursor at pos 0 when placeholder active Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1dc28a7 commit 14c35ea

3 files changed

Lines changed: 39 additions & 17 deletions

File tree

examples/showcase.v

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@ fn group_picker_item(label string, key string, app &ShowcaseApp) gui.View {
636636
mut app := w.state[ShowcaseApp]()
637637
app.selected_group = key
638638
app.show_docs = false
639+
app.nav_query = ''
639640
if key == 'data' {
640641
entries := filtered_entries(app)
641642
app.selected_component = preferred_component_for_group(key, entries)
@@ -4087,13 +4088,37 @@ Use `gui.icons_map` for programmatic access to all icon names.
40874088
Icons require `gui.theme().icon*` text styles for correct sizing.'
40884089

40894090
fn demo_icons() gui.View {
4090-
return gui.row(
4091-
content: [
4092-
gui.text(text: gui.icon_github_alt, text_style: gui.theme().icon2),
4093-
gui.text(text: gui.icon_twitter, text_style: gui.theme().icon2),
4094-
gui.text(text: gui.icon_bug, text_style: gui.theme().icon2),
4095-
gui.text(text: gui.icon_heart, text_style: gui.theme().icon2),
4096-
]
4091+
keys := gui.icons_map.keys()
4092+
mut rows := []gui.View{}
4093+
for i := 0; i < keys.len; i += 5 {
4094+
mut icons := []gui.View{}
4095+
end := if i + 5 < keys.len { i + 5 } else { keys.len }
4096+
for j := i; j < end; j++ {
4097+
key := keys[j]
4098+
icons << gui.column(
4099+
min_width: 100
4100+
h_align: .center
4101+
padding: gui.padding_small
4102+
content: [
4103+
gui.text(
4104+
text: gui.icons_map[key]
4105+
text_style: gui.theme().icon1
4106+
),
4107+
gui.text(
4108+
text: key.replace('icon_', '')
4109+
text_style: gui.theme().n5
4110+
),
4111+
]
4112+
)
4113+
}
4114+
rows << gui.row(
4115+
spacing: 0
4116+
content: icons
4117+
)
4118+
}
4119+
return gui.column(
4120+
spacing: gui.spacing_small
4121+
content: rows
40974122
)
40984123
}
40994124

render.v

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1268,7 +1268,11 @@ fn render_cursor(shape &Shape, clip DrawClip, mut window Window) {
12681268
if window.is_focus(shape.id_focus) && shape.shape_type == .text
12691269
&& window.view_state.input_cursor_on {
12701270
input_state := window.view_state.input_state.get(shape.id_focus) or { InputState{} }
1271-
cursor_pos := input_state.cursor_pos
1271+
cursor_pos := if shape.tc.text_is_placeholder {
1272+
0
1273+
} else {
1274+
int_min(input_state.cursor_pos, shape.tc.text.runes().len)
1275+
}
12721276

12731277
if cursor_pos >= 0 {
12741278
byte_idx := rune_to_byte_index(shape.tc.text, cursor_pos)

view_input.v

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ fn (cfg &InputCfg) delete(mut w Window, is_delete bool) ?string {
354354
}
355355
mut text := cfg.text.runes()
356356
input_state := w.view_state.input_state.get(cfg.id_focus) or { InputState{} }
357-
mut cursor_pos := input_state.cursor_pos
357+
mut cursor_pos := int_min(input_state.cursor_pos, text.len)
358358
if cursor_pos < 0 {
359359
cursor_pos = text.len
360360
}
@@ -373,10 +373,6 @@ fn (cfg &InputCfg) delete(mut w Window, is_delete bool) ?string {
373373
if cursor_pos == text.len && is_delete {
374374
return text.string()
375375
}
376-
if cursor_pos > text.len {
377-
log.error('cursor_pos out of range (delete)')
378-
return none
379-
}
380376
delete_pos := if is_delete { cursor_pos } else { cursor_pos - 1 }
381377
if delete_pos < 0 || delete_pos >= text.len {
382378
return none
@@ -416,7 +412,7 @@ fn (cfg &InputCfg) insert(s string, mut w Window) !string {
416412
}
417413
mut text := cfg.text.runes()
418414
input_state := w.view_state.input_state.get(cfg.id_focus) or { InputState{} }
419-
mut cursor_pos := input_state.cursor_pos
415+
mut cursor_pos := int_min(input_state.cursor_pos, text.len)
420416
if cursor_pos < 0 {
421417
text = arrays.append(cfg.text.runes(), insert_runes)
422418
cursor_pos = text.len
@@ -428,9 +424,6 @@ fn (cfg &InputCfg) insert(s string, mut w Window) !string {
428424
text = arrays.append(arrays.append(text[..beg], insert_runes), text[end..])
429425
cursor_pos = int_min(int(beg) + insert_runes.len, text.len)
430426
} else {
431-
if cursor_pos > text.len {
432-
return error('cursor_pos out of range (insert)')
433-
}
434427
text = arrays.append(arrays.append(text[..cursor_pos], insert_runes), text[cursor_pos..])
435428
cursor_pos = int_min(cursor_pos + insert_runes.len, text.len)
436429
}

0 commit comments

Comments
 (0)