Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support mouse selection and delete key on textbox #206

Merged
merged 2 commits into from
Nov 28, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 67 additions & 23 deletions src/views/text_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,31 @@ impl TextInput {
)
}

fn get_box_position(&self, pos_x: f64, pos_y: f64, cx: &mut EventCx) -> usize {
// Already focused - move cursor to click pos
let layout = cx.get_layout(self.id()).unwrap();
let style = cx.app_state.get_builtin_style(self.id());

let padding_left = match style.padding_left() {
PxPct::Px(padding) => padding as f32,
PxPct::Pct(pct) => pct as f32 * layout.size.width,
};
let padding_top = match style.padding_top() {
PxPct::Px(padding) => padding as f32,
PxPct::Pct(pct) => pct as f32 * layout.size.width,
};
self.text_buf
.as_ref()
.unwrap()
.hit_point(Point::new(
pos_x + self.clip_start_x - padding_left as f64,
// TODO: prevent cursor incorrectly going to end of buffer when clicking
// slightly below the text
pos_y - padding_top as f64,
))
.index
}

fn get_selection_rect(&self, node_layout: &Layout, left_padding: f64) -> Rect {
let selection = if let Some(curr_selection) = &self.selection {
curr_selection
Expand Down Expand Up @@ -374,6 +399,20 @@ impl TextInput {
tmp.size()
}

fn update_selection(&mut self, selection_start: usize, selection_stop: usize) {
if selection_stop < selection_start {
self.selection = Some(Range {
start: selection_stop,
end: selection_start,
});
} else {
self.selection = Some(Range {
start: selection_start,
end: selection_stop,
});
}
}

fn update_text_layout(&mut self) {
let mut text_layout = TextLayout::new();
let attrs_list = self.get_text_attrs();
Expand Down Expand Up @@ -605,6 +644,15 @@ impl TextInput {
}
}
Key::Named(NamedKey::Delete) => {
let selection = self.selection.clone();
if let Some(selection) = selection {
self.cursor_glyph_idx = selection.start;
self.buffer
.update(|buf| replace_range(buf, selection, None));
self.selection = None;
return true;
}

let prev_cursor_idx = self.cursor_glyph_idx;

if event.modifiers.contains(ModifiersState::CONTROL) {
Expand Down Expand Up @@ -808,32 +856,28 @@ impl View for TextInput {
// Just gained focus - move cursor to buff end
self.cursor_glyph_idx = self.buffer.with_untracked(|buff| buff.len());
} else {
// Already focused - move cursor to click pos
let layout = cx.get_layout(self.id()).unwrap();
let style = cx.app_state.get_builtin_style(self.id());

let padding_left = match style.padding_left() {
PxPct::Px(padding) => padding as f32,
PxPct::Pct(pct) => pct as f32 * layout.size.width,
};
let padding_top = match style.padding_top() {
PxPct::Px(padding) => padding as f32,
PxPct::Pct(pct) => pct as f32 * layout.size.width,
};
self.cursor_glyph_idx = self
.text_buf
.as_ref()
.unwrap()
.hit_point(Point::new(
event.pos.x + self.clip_start_x - padding_left as f64,
// TODO: prevent cursor incorrectly going to end of buffer when clicking
// slightly below the text
event.pos.y - padding_top as f64,
))
.index;
cx.update_active(self.id());
cx.app_state_mut().request_layout(self.id());
self.selection = None;
self.cursor_glyph_idx = self.get_box_position(event.pos.x, event.pos.y, cx);
}
true
}
Event::PointerUp(event) => {
cx.app_state_mut().request_layout(self.id());
if self.selection.is_some() {
self.cursor_glyph_idx = self.get_box_position(event.pos.x, event.pos.y, cx);
}
true
}
Event::PointerMove(event) => {
cx.app_state_mut().request_layout(self.id());
if cx.is_active(self.id()) {
let selection_stop = self.get_box_position(event.pos.x, event.pos.y, cx);
self.update_selection(self.cursor_glyph_idx, selection_stop);
}
false
}
Event::KeyDown(event) => self.handle_key_down(cx, event),
_ => false,
};
Expand Down