single line textedit

This commit is contained in:
2025-11-22 22:04:46 -05:00
parent 14a9da0553
commit ee0616885f
3 changed files with 34 additions and 13 deletions

View File

@@ -168,14 +168,14 @@ impl Client {
let texts = Span::empty(Dir::DOWN).gap(10).add_static(&mut ui); let texts = Span::empty(Dir::DOWN).gap(10).add_static(&mut ui);
let msg_area = texts.scroll().masked().background(rect(Color::SKY)); let msg_area = texts.scroll().masked().background(rect(Color::SKY));
let add_text = text("add") let add_text = text("add")
.editable() .editable(false)
.text_align(Align::LEFT) .text_align(Align::LEFT)
.size(30) .size(30)
.attr::<Selectable>(()) .attr::<Selectable>(())
.id_on(Submit, move |id, client: &mut Client, _| { .id_on(Submit, move |id, client: &mut Client, _| {
let content = client.ui.text(id).take(); let content = client.ui.text(id).take();
let text = text(content) let text = text(content)
.editable() .editable(false)
.size(30) .size(30)
.text_align(Align::LEFT) .text_align(Align::LEFT)
.wrap(true) .wrap(true)

View File

@@ -1,12 +1,12 @@
use crate::prelude::*; use crate::prelude::*;
use cosmic_text::{Attrs, Family, Metrics}; use cosmic_text::{Attrs, Family, Metrics};
use std::marker::{PhantomData, Sized}; use std::marker::Sized;
pub struct TextBuilder<O = TextOutput, H: WidgetOption = ()> { pub struct TextBuilder<O = TextOutput, H: WidgetOption = ()> {
pub content: String, pub content: String,
pub attrs: TextAttrs, pub attrs: TextAttrs,
pub hint: H, pub hint: H,
_pd: PhantomData<O>, pub output: O,
} }
impl<O, H: WidgetOption> TextBuilder<O, H> { impl<O, H: WidgetOption> TextBuilder<O, H> {
@@ -35,12 +35,12 @@ impl<O, H: WidgetOption> TextBuilder<O, H> {
self.attrs.wrap = wrap; self.attrs.wrap = wrap;
self self
} }
pub fn editable(self) -> TextBuilder<TextEditOutput, H> { pub fn editable(self, single_line: bool) -> TextBuilder<TextEditOutput, H> {
TextBuilder { TextBuilder {
content: self.content, content: self.content,
attrs: self.attrs, attrs: self.attrs,
hint: self.hint, hint: self.hint,
_pd: PhantomData, output: TextEditOutput { single_line },
} }
} }
} }
@@ -51,7 +51,7 @@ impl<O> TextBuilder<O> {
content: self.content, content: self.content,
attrs: self.attrs, attrs: self.attrs,
hint: move |ui: &mut Ui| Some(hint.add(ui).any()), hint: move |ui: &mut Ui| Some(hint.add(ui).any()),
_pd: PhantomData, output: self.output,
} }
} }
} }
@@ -83,7 +83,9 @@ impl TextBuilderOutput for TextOutput {
} }
} }
pub struct TextEditOutput; pub struct TextEditOutput {
single_line: bool,
}
impl TextBuilderOutput for TextEditOutput { impl TextBuilderOutput for TextEditOutput {
type Output = TextEdit; type Output = TextEdit;
@@ -92,7 +94,10 @@ impl TextBuilderOutput for TextEditOutput {
builder.attrs.font_size, builder.attrs.font_size,
builder.attrs.line_height, builder.attrs.line_height,
)); ));
let mut text = TextEdit::new(TextView::new(buf, builder.attrs, builder.hint.get(ui))); let mut text = TextEdit::new(
TextView::new(buf, builder.attrs, builder.hint.get(ui)),
builder.output.single_line,
);
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);
@@ -114,6 +119,6 @@ pub fn text(content: impl Into<String>) -> TextBuilder {
content: content.into(), content: content.into(),
attrs: TextAttrs::default(), attrs: TextAttrs::default(),
hint: (), hint: (),
_pd: PhantomData, output: TextOutput,
} }
} }

View File

@@ -13,15 +13,17 @@ pub struct TextEdit {
selection: TextSelection, selection: TextSelection,
history: Vec<(String, TextSelection)>, history: Vec<(String, TextSelection)>,
double_hit: Option<Cursor>, double_hit: Option<Cursor>,
pub single_line: bool,
} }
impl TextEdit { impl TextEdit {
pub fn new(view: TextView) -> Self { pub fn new(view: TextView, single_line: bool) -> Self {
Self { Self {
view, view,
selection: Default::default(), selection: Default::default(),
history: Default::default(), history: Default::default(),
double_hit: None, double_hit: None,
single_line,
} }
} }
pub fn select_content(&self, start: Cursor, end: Cursor) -> String { pub fn select_content(&self, start: Cursor, end: Cursor) -> String {
@@ -196,9 +198,10 @@ impl<'a> TextEditCtx<'a> {
} }
pub fn set(&mut self, text: &str) { pub fn set(&mut self, text: &str) {
let text = self.string(text);
self.text self.text
.buf .buf
.set_text(self.font_system, text, &Attrs::new(), SHAPING, None); .set_text(self.font_system, &text, &Attrs::new(), SHAPING, None);
self.text.selection.clear(); self.text.selection.clear();
} }
@@ -236,13 +239,23 @@ impl<'a> TextEditCtx<'a> {
} }
pub fn replace(&mut self, len: usize, text: &str) { pub fn replace(&mut self, len: usize, text: &str) {
let text = self.string(text);
for _ in 0..len { for _ in 0..len {
self.delete(false); self.delete(false);
} }
self.insert_inner(text, false); self.insert_inner(&text, false);
}
fn string(&self, text: &str) -> String {
if self.text.single_line {
text.replace('\n', "")
} else {
text.to_string()
}
} }
pub fn insert(&mut self, text: &str) { pub fn insert(&mut self, text: &str) {
let text = self.string(text);
let mut lines = text.split('\n'); let mut lines = text.split('\n');
let Some(first) = lines.next() else { let Some(first) = lines.next() else {
return; return;
@@ -303,6 +316,9 @@ impl<'a> TextEditCtx<'a> {
} }
pub fn newline(&mut self) { pub fn newline(&mut self) {
if self.text.single_line {
return;
}
self.clear_span(); self.clear_span();
if let TextSelection::Pos(cursor) = &mut self.text.selection { if let TextSelection::Pos(cursor) = &mut self.text.selection {
let lines = &mut self.text.view.buf.lines; let lines = &mut self.text.view.buf.lines;