triple click to select line + fix highlighting
This commit is contained in:
@@ -92,11 +92,7 @@ impl TextBuilderOutput for TextEditOutput {
|
|||||||
builder.attrs.font_size,
|
builder.attrs.font_size,
|
||||||
builder.attrs.line_height,
|
builder.attrs.line_height,
|
||||||
));
|
));
|
||||||
let mut text = TextEdit {
|
let mut text = TextEdit::new(TextView::new(buf, builder.attrs, builder.hint.get(ui)));
|
||||||
view: TextView::new(buf, builder.attrs, builder.hint.get(ui)),
|
|
||||||
selection: Default::default(),
|
|
||||||
history: Default::default(),
|
|
||||||
};
|
|
||||||
let font_system = &mut ui.data.text.font_system;
|
let font_system = &mut ui.data.text.font_system;
|
||||||
text.buf
|
text.buf
|
||||||
.set_text(font_system, &builder.content, &Attrs::new(), SHAPING, None);
|
.set_text(font_system, &builder.content, &Attrs::new(), SHAPING, None);
|
||||||
|
|||||||
@@ -9,12 +9,21 @@ use winit::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub struct TextEdit {
|
pub struct TextEdit {
|
||||||
pub(super) view: TextView,
|
view: TextView,
|
||||||
pub(super) selection: TextSelection,
|
selection: TextSelection,
|
||||||
pub(super) history: Vec<(String, TextSelection)>,
|
history: Vec<(String, TextSelection)>,
|
||||||
|
double_hit: Option<Cursor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextEdit {
|
impl TextEdit {
|
||||||
|
pub fn new(view: TextView) -> Self {
|
||||||
|
Self {
|
||||||
|
view,
|
||||||
|
selection: Default::default(),
|
||||||
|
history: Default::default(),
|
||||||
|
double_hit: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn select_content(&self, start: Cursor, end: Cursor) -> String {
|
pub fn select_content(&self, start: Cursor, end: Cursor) -> String {
|
||||||
let (start, end) = sort_cursors(start, end);
|
let (start, end) = sort_cursors(start, end);
|
||||||
let mut iter = self.buf.lines.iter().skip(start.line);
|
let mut iter = self.buf.lines.iter().skip(start.line);
|
||||||
@@ -106,6 +115,9 @@ fn iter_layout_lines(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for line in iter {
|
for line in iter {
|
||||||
|
if line.line_i > end.line {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if line.line_i == end.line
|
if line.line_i == end.line
|
||||||
&& let Some(end_x) = index_x(&line, end.index)
|
&& let Some(end_x) = index_x(&line, end.index)
|
||||||
{
|
{
|
||||||
@@ -339,6 +351,14 @@ impl<'a> TextEditCtx<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn select_line_at(&mut self, cursor: Cursor) {
|
||||||
|
let end = self.text.buf.lines[cursor.line].text().len();
|
||||||
|
self.text.selection = TextSelection::Span {
|
||||||
|
start: Cursor::new(cursor.line, 0),
|
||||||
|
end: Cursor::new(cursor.line, end),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn select(&mut self, pos: Vec2, size: Vec2, drag: bool, recent: bool) {
|
pub fn select(&mut self, pos: Vec2, size: Vec2, drag: bool, recent: bool) {
|
||||||
let pos = pos - self.text.region().top_left().to_abs(size);
|
let pos = pos - self.text.region().top_left().to_abs(size);
|
||||||
let hit = self.text.buf.hit(pos.x, pos.y);
|
let hit = self.text.buf.hit(pos.x, pos.y);
|
||||||
@@ -354,6 +374,7 @@ impl<'a> TextEditCtx<'a> {
|
|||||||
(None, true) => (),
|
(None, true) => (),
|
||||||
(Some(hit), false) => {
|
(Some(hit), false) => {
|
||||||
if recent && hit == *pos {
|
if recent && hit == *pos {
|
||||||
|
self.text.double_hit = Some(hit);
|
||||||
return self.select_word_at(hit);
|
return self.select_word_at(hit);
|
||||||
} else {
|
} else {
|
||||||
*pos = hit
|
*pos = hit
|
||||||
@@ -364,7 +385,16 @@ impl<'a> TextEditCtx<'a> {
|
|||||||
TextSelection::Span { start, end } => match (hit, drag) {
|
TextSelection::Span { start, end } => match (hit, drag) {
|
||||||
(None, false) => *sel = TextSelection::None,
|
(None, false) => *sel = TextSelection::None,
|
||||||
(None, true) => *sel = TextSelection::Pos(*start),
|
(None, true) => *sel = TextSelection::Pos(*start),
|
||||||
(Some(hit), false) => *sel = TextSelection::Pos(hit),
|
(Some(hit), false) => {
|
||||||
|
if recent
|
||||||
|
&& let Some(double) = self.text.double_hit
|
||||||
|
&& double == hit
|
||||||
|
{
|
||||||
|
return self.select_line_at(hit);
|
||||||
|
} else {
|
||||||
|
*sel = TextSelection::Pos(hit)
|
||||||
|
}
|
||||||
|
}
|
||||||
(Some(hit), true) => *end = hit,
|
(Some(hit), true) => *end = hit,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user