widgets(textinput): add inserSliceAtCursor and sliceToCursor
Add two helps methods to textinput: 1. inserSliceAtCursor allows inserting a slice of bytes at the cursor position. This allows a program to insert a string at the cursor position and allow the internal state of the textinput to properly track where the cursor should be 2. sliceToCursor: allow users to obtain an (allocated) slice of the content from the beginning of the input to the cursor position
This commit is contained in:
parent
da988cc8d9
commit
ea6a4a714b
1 changed files with 39 additions and 0 deletions
|
@ -70,6 +70,33 @@ pub fn update(self: *TextInput, event: Event) !void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// insert text at the cursor position
|
||||||
|
pub fn insertSliceAtCursor(self: *TextInput, data: []const u8) !void {
|
||||||
|
var iter = GraphemeIterator.init(data);
|
||||||
|
var byte_offset_to_cursor = self.byteOffsetToCursor();
|
||||||
|
while (iter.next()) |text| {
|
||||||
|
try self.buf.insertSliceBefore(byte_offset_to_cursor, text.slice(data));
|
||||||
|
byte_offset_to_cursor += text.len;
|
||||||
|
self.cursor_idx += 1;
|
||||||
|
self.grapheme_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sliceToCursor(self: *TextInput, buf: []u8) []const u8 {
|
||||||
|
const offset = self.byteOffsetToCursor();
|
||||||
|
assert(offset <= buf.len); // provided buf was too small
|
||||||
|
|
||||||
|
if (offset <= self.buf.items.len) {
|
||||||
|
@memcpy(buf[0..offset], self.buf.items[0..offset]);
|
||||||
|
} else {
|
||||||
|
@memcpy(buf[0..self.buf.items.len], self.buf.items);
|
||||||
|
const second_half = self.buf.secondHalf();
|
||||||
|
const copy_len = offset - self.buf.items.len;
|
||||||
|
@memcpy(buf[self.buf.items.len .. self.buf.items.len + copy_len], second_half[0..copy_len]);
|
||||||
|
}
|
||||||
|
return buf[0..offset];
|
||||||
|
}
|
||||||
|
|
||||||
pub fn draw(self: *TextInput, win: Window) void {
|
pub fn draw(self: *TextInput, win: Window) void {
|
||||||
if (self.cursor_idx > self.prev_cursor_idx and
|
if (self.cursor_idx > self.prev_cursor_idx and
|
||||||
self.prev_cursor_col > (win.width -| self.scroll_offset))
|
self.prev_cursor_col > (win.width -| self.scroll_offset))
|
||||||
|
@ -265,3 +292,15 @@ test "assertion" {
|
||||||
try input.update(.{ .key_press = astronaut_emoji });
|
try input.update(.{ .key_press = astronaut_emoji });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "sliceToCursor" {
|
||||||
|
var alloc = std.testing.allocator_instance;
|
||||||
|
var input = init(alloc.allocator());
|
||||||
|
try input.insertSliceAtCursor("hello, world");
|
||||||
|
input.cursor_idx = 2;
|
||||||
|
var buf: [32]u8 = undefined;
|
||||||
|
try std.testing.expectEqualStrings("he", input.sliceToCursor(&buf));
|
||||||
|
input.buf.moveGap(3);
|
||||||
|
input.cursor_idx = 5;
|
||||||
|
try std.testing.expectEqualStrings("hello", input.sliceToCursor(&buf));
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue