make more InputState properties private
This commit is contained in:
@@ -191,7 +191,7 @@ struct InputStateSnapshot {
|
|||||||
marked_range: Option<Range<usize>>,
|
marked_range: Option<Range<usize>>,
|
||||||
cursor_position: usize,
|
cursor_position: usize,
|
||||||
logical_lines: Vec<InputLogicalLine>,
|
logical_lines: Vec<InputLogicalLine>,
|
||||||
scroll_offset: Pixels,
|
scroll_distance: Pixels,
|
||||||
line_height: Pixels,
|
line_height: Pixels,
|
||||||
}
|
}
|
||||||
impl InputStateSnapshot {
|
impl InputStateSnapshot {
|
||||||
@@ -201,7 +201,7 @@ impl InputStateSnapshot {
|
|||||||
let marked_range = input_state.marked_range().cloned();
|
let marked_range = input_state.marked_range().cloned();
|
||||||
let cursor_position = input_state.cursor_position();
|
let cursor_position = input_state.cursor_position();
|
||||||
let logical_lines = input_state.logical_lines.clone();
|
let logical_lines = input_state.logical_lines.clone();
|
||||||
let scroll_offset = input_state.scroll_offset;
|
let scroll_distance = input_state.distance_from_top();
|
||||||
let line_height = input_state.line_height();
|
let line_height = input_state.line_height();
|
||||||
let layout_axis = input_state.layout_style().axis();
|
let layout_axis = input_state.layout_style().axis();
|
||||||
let should_center_placeholder = matches!(
|
let should_center_placeholder = matches!(
|
||||||
@@ -216,7 +216,7 @@ impl InputStateSnapshot {
|
|||||||
marked_range,
|
marked_range,
|
||||||
cursor_position,
|
cursor_position,
|
||||||
logical_lines,
|
logical_lines,
|
||||||
scroll_offset,
|
scroll_distance,
|
||||||
line_height,
|
line_height,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,6 +241,7 @@ impl<'app> PaintContext<'app> {
|
|||||||
) {
|
) {
|
||||||
let axis = self.snapshot.layout_axis;
|
let axis = self.snapshot.layout_axis;
|
||||||
let bounds = self.bounds;
|
let bounds = self.bounds;
|
||||||
|
let scroll_distance = self.snapshot.scroll_distance;
|
||||||
window.on_mouse_event({
|
window.on_mouse_event({
|
||||||
let input = entity.clone();
|
let input = entity.clone();
|
||||||
move |event: &MouseDownEvent, phase, window, cx| {
|
move |event: &MouseDownEvent, phase, window, cx| {
|
||||||
@@ -257,7 +258,7 @@ impl<'app> PaintContext<'app> {
|
|||||||
input.update(cx, |input, cx| {
|
input.update(cx, |input, cx| {
|
||||||
// Converts a screen position to a position relative to the text area origin, adjusted for scroll offset.
|
// Converts a screen position to a position relative to the text area origin, adjusted for scroll offset.
|
||||||
let text_position = (event.position - bounds.origin)
|
let text_position = (event.position - bounds.origin)
|
||||||
.apply_along(axis, |pos| pos + input.scroll_offset);
|
.apply_along(axis, |pos| pos + scroll_distance);
|
||||||
input.on_mouse_down(
|
input.on_mouse_down(
|
||||||
text_position,
|
text_position,
|
||||||
event.click_count,
|
event.click_count,
|
||||||
@@ -293,7 +294,7 @@ impl<'app> PaintContext<'app> {
|
|||||||
input.update(cx, |input, cx| {
|
input.update(cx, |input, cx| {
|
||||||
// Converts a screen position to a position relative to the text area origin, adjusted for scroll offset.
|
// Converts a screen position to a position relative to the text area origin, adjusted for scroll offset.
|
||||||
let text_position = (event.position - bounds.origin)
|
let text_position = (event.position - bounds.origin)
|
||||||
.apply_along(axis, |pos| pos + input.scroll_offset);
|
.apply_along(axis, |pos| pos + scroll_distance);
|
||||||
input.on_mouse_move(text_position, cx);
|
input.on_mouse_move(text_position, cx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -330,7 +331,7 @@ impl<'app> PaintContext<'app> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
input.scroll_offset = (input.scroll_offset - delta).clamp(px(0.), max_scroll);
|
input.apply_scroll_delta(delta, max_scroll);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -372,7 +373,7 @@ impl<'app> PaintContext<'app> {
|
|||||||
fn paint_selection(&self, window: &mut Window) {
|
fn paint_selection(&self, window: &mut Window) {
|
||||||
let one_line = self.snapshot.logical_lines.len() == 1;
|
let one_line = self.snapshot.logical_lines.len() == 1;
|
||||||
for line in &self.snapshot.logical_lines {
|
for line in &self.snapshot.logical_lines {
|
||||||
let line_y = line.y_offset - self.snapshot.scroll_offset;
|
let line_y = line.y_offset - self.snapshot.scroll_distance;
|
||||||
|
|
||||||
if !one_line {
|
if !one_line {
|
||||||
if !self.is_line_visible(line) {
|
if !self.is_line_visible(line) {
|
||||||
@@ -442,7 +443,7 @@ impl<'app> PaintContext<'app> {
|
|||||||
|
|
||||||
fn paint_text(&self, window: &mut Window, cx: &mut App) {
|
fn paint_text(&self, window: &mut Window, cx: &mut App) {
|
||||||
for line_layout in &self.snapshot.logical_lines {
|
for line_layout in &self.snapshot.logical_lines {
|
||||||
let line_y = line_layout.y_offset - self.snapshot.scroll_offset;
|
let line_y = line_layout.y_offset - self.snapshot.scroll_distance;
|
||||||
|
|
||||||
if !self.is_line_visible(line_layout) {
|
if !self.is_line_visible(line_layout) {
|
||||||
continue;
|
continue;
|
||||||
@@ -499,7 +500,7 @@ impl<'app> PaintContext<'app> {
|
|||||||
|
|
||||||
fn find_cursor_position_in_layouts(&self) -> Point<Pixels> {
|
fn find_cursor_position_in_layouts(&self) -> Point<Pixels> {
|
||||||
for line in &self.snapshot.logical_lines {
|
for line in &self.snapshot.logical_lines {
|
||||||
let line_y = line.y_offset - self.snapshot.scroll_offset;
|
let line_y = line.y_offset - self.snapshot.scroll_distance;
|
||||||
|
|
||||||
if !self.is_line_visible(line) {
|
if !self.is_line_visible(line) {
|
||||||
continue;
|
continue;
|
||||||
@@ -544,7 +545,7 @@ impl<'app> PaintContext<'app> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_line_visible(&self, line: &InputLogicalLine) -> bool {
|
fn is_line_visible(&self, line: &InputLogicalLine) -> bool {
|
||||||
let line_y = line.y_offset - self.snapshot.scroll_offset;
|
let line_y = line.y_offset - self.snapshot.scroll_distance;
|
||||||
let line_bottom = line_y + self.snapshot.line_height * line.visual_line_count as f32;
|
let line_bottom = line_y + self.snapshot.line_height * line.visual_line_count as f32;
|
||||||
line_bottom >= px(0.) && line_y <= self.bounds.size.height
|
line_bottom >= px(0.) && line_y <= self.bounds.size.height
|
||||||
}
|
}
|
||||||
@@ -565,7 +566,7 @@ impl<'app> PaintContext<'app> {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let line_y = line.y_offset - self.snapshot.scroll_offset;
|
let line_y = line.y_offset - self.snapshot.scroll_distance;
|
||||||
|
|
||||||
let line_start = line.text_range.start;
|
let line_start = line.text_range.start;
|
||||||
let line_end = line.text_range.end;
|
let line_end = line.text_range.end;
|
||||||
|
|||||||
@@ -44,15 +44,15 @@ pub struct InputState {
|
|||||||
cached_utf16_len: Option<usize>,
|
cached_utf16_len: Option<usize>,
|
||||||
|
|
||||||
/// The style of layout (single or multiline).
|
/// The style of layout (single or multiline).
|
||||||
pub(super) layout_style: InputLayoutStyle,
|
layout_style: InputLayoutStyle,
|
||||||
/// The utf-8 character range that is currently selected by the user.
|
/// The utf-8 character range that is currently selected by the user.
|
||||||
/// NOTE: because each input has its own selection state, its trivial for users to have multiple selections active across multiple inputs at the same time.
|
/// NOTE: because each input has its own selection state, its trivial for users to have multiple selections active across multiple inputs at the same time.
|
||||||
/// This could be considered undesirable behavior, and doing so would prompt the question of should there be a mechanism to clear selection when focus is lost.
|
/// This could be considered undesirable behavior, and doing so would prompt the question of should there be a mechanism to clear selection when focus is lost.
|
||||||
pub(super) selected_range: Range<usize>,
|
selected_range: Range<usize>,
|
||||||
/// The direction of the selection_range. Forward means providing in iteration order along `content`. Back means reverse iteration order.
|
/// The direction of the selection_range. Forward means providing in iteration order along `content`. Back means reverse iteration order.
|
||||||
pub(super) selection_direction: NavigationDirection,
|
selection_direction: NavigationDirection,
|
||||||
/// The utf-8 character range of `content` that is currently marked/highlighted.
|
/// The utf-8 character range of `content` that is currently marked/highlighted.
|
||||||
pub(super) marked_range: Option<Range<usize>>,
|
marked_range: Option<Range<usize>>,
|
||||||
|
|
||||||
// refreshed each update by the element, for conveinent access in mutations and painting
|
// refreshed each update by the element, for conveinent access in mutations and painting
|
||||||
pub(super) layout_data: InputLayoutData,
|
pub(super) layout_data: InputLayoutData,
|
||||||
@@ -68,7 +68,7 @@ pub struct InputState {
|
|||||||
/// The number of times the user has clicked `last_click_position`. Used to determine which click behavior to trigger, depending on single, double, or triple clicks.
|
/// The number of times the user has clicked `last_click_position`. Used to determine which click behavior to trigger, depending on single, double, or triple clicks.
|
||||||
click_count: usize,
|
click_count: usize,
|
||||||
/// The distance in pixels from the start of the text a user has scrolled along the layout_style axis (singleline is horizontal, multiline is vertical).
|
/// The distance in pixels from the start of the text a user has scrolled along the layout_style axis (singleline is horizontal, multiline is vertical).
|
||||||
pub(super) scroll_offset: Pixels,
|
scroll_distance: Pixels,
|
||||||
|
|
||||||
/// The maximum duration between changes to `content` that can be grouped together as a single entry in the history log.
|
/// The maximum duration between changes to `content` that can be grouped together as a single entry in the history log.
|
||||||
history_grouping_interval: Duration,
|
history_grouping_interval: Duration,
|
||||||
@@ -163,7 +163,7 @@ impl InputState {
|
|||||||
is_selecting: false,
|
is_selecting: false,
|
||||||
last_click_position: None,
|
last_click_position: None,
|
||||||
click_count: 0,
|
click_count: 0,
|
||||||
scroll_offset: px(0.),
|
scroll_distance: px(0.),
|
||||||
|
|
||||||
history_grouping_interval: super::DEFAULT_GROUP_INTERVAL,
|
history_grouping_interval: super::DEFAULT_GROUP_INTERVAL,
|
||||||
history_undo_stack: Vec::new(),
|
history_undo_stack: Vec::new(),
|
||||||
@@ -232,6 +232,10 @@ impl InputState {
|
|||||||
&self.selected_range
|
&self.selected_range
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn selection_direction(&self) -> NavigationDirection {
|
||||||
|
self.selection_direction
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the selection range directly.
|
/// Sets the selection range directly.
|
||||||
pub fn set_selected_range(&mut self, range: Range<usize>) {
|
pub fn set_selected_range(&mut self, range: Range<usize>) {
|
||||||
let range = range.start.min(self.content.len())..range.end.min(self.content.len());
|
let range = range.start.min(self.content.len())..range.end.min(self.content.len());
|
||||||
@@ -254,7 +258,7 @@ impl InputState {
|
|||||||
|
|
||||||
/// Returns true if the scroll position is at the top.
|
/// Returns true if the scroll position is at the top.
|
||||||
pub fn at_top(&self) -> bool {
|
pub fn at_top(&self) -> bool {
|
||||||
self.scroll_offset <= px(0.)
|
self.scroll_distance <= px(0.)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the scroll position is at the bottom.
|
/// Returns true if the scroll position is at the bottom.
|
||||||
@@ -266,7 +270,7 @@ impl InputState {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.scroll_offset + visible_height >= content_height
|
self.scroll_distance + visible_height >= content_height
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the scroll progress as a value from 0.0 (top) to 1.0 (bottom).
|
/// Returns the scroll progress as a value from 0.0 (top) to 1.0 (bottom).
|
||||||
@@ -279,12 +283,12 @@ impl InputState {
|
|||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
(self.scroll_offset / max_scroll).clamp(0.0, 1.0)
|
(self.scroll_distance / max_scroll).clamp(0.0, 1.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns how far the content is scrolled from the top in pixels.
|
/// Returns how far the content is scrolled from the top in pixels.
|
||||||
pub fn distance_from_top(&self) -> Pixels {
|
pub fn distance_from_top(&self) -> Pixels {
|
||||||
self.scroll_offset.max(px(0.))
|
self.scroll_distance.max(px(0.))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns how far the content is from the bottom in pixels.
|
/// Returns how far the content is from the bottom in pixels.
|
||||||
@@ -297,7 +301,7 @@ impl InputState {
|
|||||||
return px(0.);
|
return px(0.);
|
||||||
}
|
}
|
||||||
|
|
||||||
(max_scroll - self.scroll_offset).max(px(0.))
|
(max_scroll - self.scroll_distance).max(px(0.))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Configures how long the input will wait between user-input changes to create new logs in the history for undo/redo.
|
/// Configures how long the input will wait between user-input changes to create new logs in the history for undo/redo.
|
||||||
@@ -347,7 +351,7 @@ impl InputState {
|
|||||||
self.cached_utf16_len = Some(cached_len - removed_utf16_len + added_utf16_len);
|
self.cached_utf16_len = Some(cached_len - removed_utf16_len + added_utf16_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.replace_range(range.clone(), &text_to_insert);
|
self.replace_text_at_range(range.clone(), &text_to_insert);
|
||||||
|
|
||||||
self.selected_range =
|
self.selected_range =
|
||||||
range.start + text_to_insert.len()..range.start + text_to_insert.len();
|
range.start + text_to_insert.len()..range.start + text_to_insert.len();
|
||||||
@@ -834,8 +838,12 @@ impl InputState {
|
|||||||
self.layout_data.line_height
|
self.layout_data.line_height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn set_marked_range(&mut self, range: Option<Range<usize>>) {
|
||||||
|
self.marked_range = range;
|
||||||
|
}
|
||||||
|
|
||||||
/// Replaces the provided utf-8 character range with the provided text
|
/// Replaces the provided utf-8 character range with the provided text
|
||||||
pub(super) fn replace_range(&mut self, range: Range<usize>, text: &str) {
|
pub(super) fn replace_text_at_range(&mut self, range: Range<usize>, text: &str) {
|
||||||
self.content.replace_range(range, &text);
|
self.content.replace_range(range, &text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -944,6 +952,10 @@ impl InputState {
|
|||||||
self.content.len()
|
self.content.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn apply_scroll_delta(&mut self, delta: Pixels, max: Pixels) {
|
||||||
|
self.scroll_distance = (self.scroll_distance - delta).clamp(px(0.), max);
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn scroll_to_cursor(&mut self) {
|
pub(super) fn scroll_to_cursor(&mut self) {
|
||||||
if self.logical_lines.is_empty() {
|
if self.logical_lines.is_empty() {
|
||||||
return;
|
return;
|
||||||
@@ -971,19 +983,20 @@ impl InputState {
|
|||||||
px(0.)
|
px(0.)
|
||||||
};
|
};
|
||||||
|
|
||||||
let visible_left = self.scroll_offset;
|
let visible_left = self.scroll_distance;
|
||||||
let visible_right = self.scroll_offset + self.layout_data.available_size.width;
|
let visible_right = self.scroll_distance + self.layout_data.available_size.width;
|
||||||
|
|
||||||
// Add some padding so cursor isn't right at the edge
|
// Add some padding so cursor isn't right at the edge
|
||||||
let padding = px(2.0);
|
let padding = px(2.0);
|
||||||
|
|
||||||
if cursor_x < visible_left + padding {
|
if cursor_x < visible_left + padding {
|
||||||
self.scroll_offset = (cursor_x - padding).max(px(0.));
|
self.scroll_distance = (cursor_x - padding).max(px(0.));
|
||||||
} else if cursor_x > visible_right - padding {
|
} else if cursor_x > visible_right - padding {
|
||||||
self.scroll_offset = cursor_x - self.layout_data.available_size.width + padding;
|
self.scroll_distance =
|
||||||
|
cursor_x - self.layout_data.available_size.width + padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.scroll_offset = self.scroll_offset.max(px(0.));
|
self.scroll_distance = self.scroll_distance.max(px(0.));
|
||||||
}
|
}
|
||||||
InputLayoutStyle::MultiLine => {
|
InputLayoutStyle::MultiLine => {
|
||||||
if self.layout_data.available_size.height <= px(0.) {
|
if self.layout_data.available_size.height <= px(0.) {
|
||||||
@@ -1015,18 +1028,18 @@ impl InputState {
|
|||||||
line.y_offset
|
line.y_offset
|
||||||
};
|
};
|
||||||
|
|
||||||
let visible_top = self.scroll_offset;
|
let visible_top = self.scroll_distance;
|
||||||
let visible_bottom =
|
let visible_bottom =
|
||||||
self.scroll_offset + self.layout_data.available_size.height;
|
self.scroll_distance + self.layout_data.available_size.height;
|
||||||
|
|
||||||
if cursor_visual_y < visible_top {
|
if cursor_visual_y < visible_top {
|
||||||
self.scroll_offset = cursor_visual_y;
|
self.scroll_distance = cursor_visual_y;
|
||||||
} else if cursor_visual_y + line_height > visible_bottom {
|
} else if cursor_visual_y + line_height > visible_bottom {
|
||||||
self.scroll_offset = (cursor_visual_y + line_height)
|
self.scroll_distance = (cursor_visual_y + line_height)
|
||||||
- self.layout_data.available_size.height;
|
- self.layout_data.available_size.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.scroll_offset = self.scroll_offset.max(px(0.));
|
self.scroll_distance = self.scroll_distance.max(px(0.));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ impl EntityInputHandler for super::InputState {
|
|||||||
_cx: &mut Context<Self>,
|
_cx: &mut Context<Self>,
|
||||||
) -> Option<UTF16Selection> {
|
) -> Option<UTF16Selection> {
|
||||||
Some(UTF16Selection {
|
Some(UTF16Selection {
|
||||||
range: self.utf_range_8to16(&self.selected_range),
|
range: self.utf_range_8to16(self.selected_range()),
|
||||||
reversed: self.selection_direction == NavigationDirection::Back,
|
reversed: self.selection_direction() == NavigationDirection::Back,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,13 +38,13 @@ impl EntityInputHandler for super::InputState {
|
|||||||
_window: &mut Window,
|
_window: &mut Window,
|
||||||
_cx: &mut Context<Self>,
|
_cx: &mut Context<Self>,
|
||||||
) -> Option<Range<usize>> {
|
) -> Option<Range<usize>> {
|
||||||
self.marked_range
|
self.marked_range()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|range| self.utf_range_8to16(range))
|
.map(|range| self.utf_range_8to16(range))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unmark_text(&mut self, _window: &mut Window, _cx: &mut Context<Self>) {
|
fn unmark_text(&mut self, _window: &mut Window, _cx: &mut Context<Self>) {
|
||||||
self.marked_range = None;
|
self.set_marked_range(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace_text_in_range(
|
fn replace_text_in_range(
|
||||||
@@ -57,21 +57,21 @@ impl EntityInputHandler for super::InputState {
|
|||||||
let range = range_utf16
|
let range = range_utf16
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|range_utf16| self.utf_range_16to8(range_utf16))
|
.map(|range_utf16| self.utf_range_16to8(range_utf16))
|
||||||
.or(self.marked_range.clone())
|
.or(self.marked_range().cloned())
|
||||||
.unwrap_or(self.selected_range.clone());
|
.unwrap_or(self.selected_range().clone());
|
||||||
let range = range.start.min(self.content().len())..range.end.min(self.content().len());
|
let range = range.start.min(self.content().len())..range.end.min(self.content().len());
|
||||||
|
|
||||||
let text_to_insert = self.layout_style.sanitize_content(new_text);
|
let text_to_insert = self.layout_style().sanitize_content(new_text);
|
||||||
|
|
||||||
// Record patch for undo before modifying content
|
// Record patch for undo before modifying content
|
||||||
self.push_undo_patch(range.clone(), text_to_insert.len());
|
self.push_undo_patch(range.clone(), text_to_insert.len());
|
||||||
self.push_undo_patch(range.clone(), text_to_insert.len());
|
|
||||||
self.update_utf16_len(range.clone(), &text_to_insert);
|
|
||||||
self.replace_range(range.clone(), &text_to_insert);
|
|
||||||
|
|
||||||
self.selected_range =
|
self.update_utf16_len(range.clone(), &text_to_insert);
|
||||||
range.start + text_to_insert.len()..range.start + text_to_insert.len();
|
self.replace_text_at_range(range.clone(), &text_to_insert);
|
||||||
self.marked_range.take();
|
self.set_selected_range(
|
||||||
|
range.start + text_to_insert.len()..range.start + text_to_insert.len(),
|
||||||
|
);
|
||||||
|
self.set_marked_range(None);
|
||||||
self.layout_data.dirty = true;
|
self.layout_data.dirty = true;
|
||||||
|
|
||||||
self.pause_cursor_blink(cx);
|
self.pause_cursor_blink(cx);
|
||||||
@@ -90,28 +90,27 @@ impl EntityInputHandler for super::InputState {
|
|||||||
let range = range_utf16
|
let range = range_utf16
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|range_utf16| self.utf_range_16to8(range_utf16))
|
.map(|range_utf16| self.utf_range_16to8(range_utf16))
|
||||||
.or(self.marked_range.clone())
|
.or(self.marked_range().cloned())
|
||||||
.unwrap_or(self.selected_range.clone());
|
.unwrap_or(self.selected_range().clone());
|
||||||
let range = range.start.min(self.content().len())..range.end.min(self.content().len());
|
let range = range.start.min(self.content().len())..range.end.min(self.content().len());
|
||||||
|
|
||||||
let text_to_insert = self.layout_style.sanitize_content(new_text);
|
let text_to_insert = self.layout_style().sanitize_content(new_text);
|
||||||
|
|
||||||
self.update_utf16_len(range.clone(), &text_to_insert);
|
self.update_utf16_len(range.clone(), &text_to_insert);
|
||||||
self.replace_range(range.clone(), &text_to_insert);
|
self.replace_text_at_range(range.clone(), &text_to_insert);
|
||||||
|
self.set_marked_range(match text_to_insert.is_empty() {
|
||||||
if !text_to_insert.is_empty() {
|
true => None,
|
||||||
self.marked_range = Some(range.start..range.start + text_to_insert.len());
|
false => Some(range.start..range.start + text_to_insert.len()),
|
||||||
} else {
|
});
|
||||||
self.marked_range = None;
|
self.set_selected_range({
|
||||||
}
|
let new_range = new_selected_range_utf16.as_ref();
|
||||||
|
let new_range = new_range.map(|range_utf16| self.utf_range_16to8(range_utf16));
|
||||||
self.selected_range = new_selected_range_utf16
|
let new_range = new_range
|
||||||
.as_ref()
|
.map(|new_range| new_range.start + range.start..new_range.end + range.start);
|
||||||
.map(|range_utf16| self.utf_range_16to8(range_utf16))
|
new_range.unwrap_or_else(|| {
|
||||||
.map(|new_range| new_range.start + range.start..new_range.end + range.start)
|
|
||||||
.unwrap_or_else(|| {
|
|
||||||
range.start + text_to_insert.len()..range.start + text_to_insert.len()
|
range.start + text_to_insert.len()..range.start + text_to_insert.len()
|
||||||
});
|
})
|
||||||
|
});
|
||||||
|
|
||||||
self.layout_data.dirty = true;
|
self.layout_data.dirty = true;
|
||||||
cx.emit(InputStateEvent::TextChanged);
|
cx.emit(InputStateEvent::TextChanged);
|
||||||
|
|||||||
Reference in New Issue
Block a user