Compare commits
3 Commits
bf3ade840b
...
14a9da0553
| Author | SHA1 | Date | |
|---|---|---|---|
| 14a9da0553 | |||
| 8e08f67627 | |||
| 84b3bf9078 |
@@ -46,8 +46,9 @@ impl Widget for TextEdit {
|
||||
fn draw(&mut self, painter: &mut Painter) {
|
||||
let base = painter.layer;
|
||||
painter.child_layer();
|
||||
let region = self.view.draw(painter);
|
||||
self.view.draw(painter);
|
||||
painter.layer = base;
|
||||
let region = self.region();
|
||||
|
||||
let size = vec2(1, self.attrs.line_height);
|
||||
match self.selection {
|
||||
@@ -62,7 +63,8 @@ impl Widget for TextEdit {
|
||||
}
|
||||
TextSelection::Span { start, end } => {
|
||||
let (start, end) = sort_cursors(start, end);
|
||||
for (top_left, width) in iter_layout_lines(start, end, &self.buf) {
|
||||
for (l, x, width) in iter_layout_lines(start, end, &self.buf) {
|
||||
let top_left = vec2(x, self.attrs.line_height * l as f32);
|
||||
painter.primitive_within(
|
||||
RectPrimitive::color(Color::SKY),
|
||||
size.with_x(width)
|
||||
@@ -97,34 +99,34 @@ fn iter_layout_lines(
|
||||
start: Cursor,
|
||||
end: Cursor,
|
||||
buf: &TextBuffer,
|
||||
) -> impl Iterator<Item = (Vec2, f32)> {
|
||||
) -> impl Iterator<Item = (usize, f32, f32)> {
|
||||
gen move {
|
||||
let mut iter = buf.layout_runs();
|
||||
for line in iter.by_ref() {
|
||||
let mut iter = buf.layout_runs().enumerate();
|
||||
for (i, line) in iter.by_ref() {
|
||||
if line.line_i == start.line
|
||||
&& let Some(start_x) = index_x(&line, start.index)
|
||||
{
|
||||
if start.line == end.line
|
||||
&& let Some(end_x) = index_x(&line, end.index)
|
||||
{
|
||||
yield (vec2(start_x, line.line_top), end_x - start_x);
|
||||
yield (i, start_x, end_x - start_x);
|
||||
return;
|
||||
}
|
||||
yield (vec2(start_x, line.line_top), line.line_w - start_x);
|
||||
yield (i, start_x, line.line_w - start_x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for line in iter {
|
||||
for (i, line) in iter {
|
||||
if line.line_i > end.line {
|
||||
return;
|
||||
}
|
||||
if line.line_i == end.line
|
||||
&& let Some(end_x) = index_x(&line, end.index)
|
||||
{
|
||||
yield (vec2(0.0, line.line_top), end_x);
|
||||
yield (i, 0.0, end_x);
|
||||
return;
|
||||
}
|
||||
yield (vec2(0.0, line.line_top), line.line_w);
|
||||
yield (i, 0.0, line.line_w);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -200,18 +202,35 @@ impl<'a> TextEditCtx<'a> {
|
||||
self.text.selection.clear();
|
||||
}
|
||||
|
||||
pub fn motion(&mut self, motion: Motion) {
|
||||
pub fn motion(&mut self, motion: Motion, select: bool) {
|
||||
if let TextSelection::Pos(cursor) = self.text.selection
|
||||
&& let Some(cursor) = self.buf_motion(cursor, motion)
|
||||
&& let Some(new) = self.buf_motion(cursor, motion)
|
||||
{
|
||||
self.text.selection = TextSelection::Pos(cursor);
|
||||
if select {
|
||||
self.text.selection = TextSelection::Span {
|
||||
start: cursor,
|
||||
end: new,
|
||||
};
|
||||
} else {
|
||||
self.text.selection = TextSelection::Pos(new);
|
||||
}
|
||||
} else if let TextSelection::Span { start, end } = self.text.selection {
|
||||
let (start, end) = sort_cursors(start, end);
|
||||
let sel = &mut self.text.selection;
|
||||
match motion {
|
||||
Motion::Left | Motion::LeftWord => *sel = TextSelection::Pos(start),
|
||||
Motion::Right | Motion::RightWord => *sel = TextSelection::Pos(end),
|
||||
_ => (),
|
||||
if select {
|
||||
if let Some(cursor) = self.buf_motion(end, motion) {
|
||||
self.text.selection = TextSelection::Span { start, end: cursor };
|
||||
}
|
||||
} else {
|
||||
let (start, end) = sort_cursors(start, end);
|
||||
let sel = &mut self.text.selection;
|
||||
match motion {
|
||||
Motion::Left | Motion::LeftWord => *sel = TextSelection::Pos(start),
|
||||
Motion::Right | Motion::RightWord => *sel = TextSelection::Pos(end),
|
||||
_ => {
|
||||
if let Some(cursor) = self.buf_motion(end, motion) {
|
||||
self.text.selection = TextSelection::Pos(cursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -277,7 +296,7 @@ impl<'a> TextEditCtx<'a> {
|
||||
edit_line(line, line_text);
|
||||
if mov {
|
||||
for _ in 0..text.chars().count() {
|
||||
self.motion(Motion::Right);
|
||||
self.motion(Motion::Right, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -300,7 +319,7 @@ impl<'a> TextEditCtx<'a> {
|
||||
&& let TextSelection::Pos(cursor) = &mut self.text.selection
|
||||
&& (cursor.index != 0 || cursor.line != 0)
|
||||
{
|
||||
self.motion(if word { Motion::LeftWord } else { Motion::Left });
|
||||
self.motion(if word { Motion::LeftWord } else { Motion::Left }, false);
|
||||
self.delete(word);
|
||||
}
|
||||
}
|
||||
@@ -442,20 +461,20 @@ impl<'a> TextEditCtx<'a> {
|
||||
}
|
||||
NamedKey::ArrowRight => {
|
||||
if modifiers.control {
|
||||
self.motion(Motion::RightWord)
|
||||
self.motion(Motion::RightWord, modifiers.shift)
|
||||
} else {
|
||||
self.motion(Motion::Right)
|
||||
self.motion(Motion::Right, modifiers.shift)
|
||||
}
|
||||
}
|
||||
NamedKey::ArrowLeft => {
|
||||
if modifiers.control {
|
||||
self.motion(Motion::LeftWord)
|
||||
self.motion(Motion::LeftWord, modifiers.shift)
|
||||
} else {
|
||||
self.motion(Motion::Left)
|
||||
self.motion(Motion::Left, modifiers.shift)
|
||||
}
|
||||
}
|
||||
NamedKey::ArrowUp => self.motion(Motion::Up),
|
||||
NamedKey::ArrowDown => self.motion(Motion::Down),
|
||||
NamedKey::ArrowUp => self.motion(Motion::Up, modifiers.shift),
|
||||
NamedKey::ArrowDown => self.motion(Motion::Down, modifiers.shift),
|
||||
NamedKey::Escape => {
|
||||
self.deselect();
|
||||
return TextInputResult::Unfocus;
|
||||
@@ -472,6 +491,13 @@ impl<'a> TextEditCtx<'a> {
|
||||
return TextInputResult::Copy(content);
|
||||
}
|
||||
}
|
||||
"x" => {
|
||||
if let TextSelection::Span { start, end } = self.text.selection {
|
||||
let content = self.text.select_content(start, end);
|
||||
self.clear_span();
|
||||
return TextInputResult::Copy(content);
|
||||
}
|
||||
}
|
||||
"a" => {
|
||||
if !self.text.buf.lines[0].text().is_empty()
|
||||
|| self.text.buf.lines.len() > 1
|
||||
|
||||
@@ -35,6 +35,8 @@ impl TextView {
|
||||
}
|
||||
}
|
||||
|
||||
/// region where the text should be draw
|
||||
/// does not include extra height or width from weird unicode
|
||||
pub fn region(&self) -> UiRegion {
|
||||
self.tex()
|
||||
.map(|t| t.size)
|
||||
|
||||
Reference in New Issue
Block a user