Compare commits

1 Commits

Author SHA1 Message Date
ee0616885f single line textedit 2025-11-22 22:04:46 -05:00
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 msg_area = texts.scroll().masked().background(rect(Color::SKY));
let add_text = text("add")
.editable()
.editable(false)
.text_align(Align::LEFT)
.size(30)
.attr::<Selectable>(())
.id_on(Submit, move |id, client: &mut Client, _| {
let content = client.ui.text(id).take();
let text = text(content)
.editable()
.editable(false)
.size(30)
.text_align(Align::LEFT)
.wrap(true)

View File

@@ -1,12 +1,12 @@
use crate::prelude::*;
use cosmic_text::{Attrs, Family, Metrics};
use std::marker::{PhantomData, Sized};
use std::marker::Sized;
pub struct TextBuilder<O = TextOutput, H: WidgetOption = ()> {
pub content: String,
pub attrs: TextAttrs,
pub hint: H,
_pd: PhantomData<O>,
pub output: O,
}
impl<O, H: WidgetOption> TextBuilder<O, H> {
@@ -35,12 +35,12 @@ impl<O, H: WidgetOption> TextBuilder<O, H> {
self.attrs.wrap = wrap;
self
}
pub fn editable(self) -> TextBuilder<TextEditOutput, H> {
pub fn editable(self, single_line: bool) -> TextBuilder<TextEditOutput, H> {
TextBuilder {
content: self.content,
attrs: self.attrs,
hint: self.hint,
_pd: PhantomData,
output: TextEditOutput { single_line },
}
}
}
@@ -51,7 +51,7 @@ impl<O> TextBuilder<O> {
content: self.content,
attrs: self.attrs,
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 {
type Output = TextEdit;
@@ -92,7 +94,10 @@ impl TextBuilderOutput for TextEditOutput {
builder.attrs.font_size,
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;
text.buf
.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(),
attrs: TextAttrs::default(),
hint: (),
_pd: PhantomData,
output: TextOutput,
}
}

View File

@@ -13,15 +13,17 @@ pub struct TextEdit {
selection: TextSelection,
history: Vec<(String, TextSelection)>,
double_hit: Option<Cursor>,
pub single_line: bool,
}
impl TextEdit {
pub fn new(view: TextView) -> Self {
pub fn new(view: TextView, single_line: bool) -> Self {
Self {
view,
selection: Default::default(),
history: Default::default(),
double_hit: None,
single_line,
}
}
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) {
let text = self.string(text);
self.text
.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();
}
@@ -236,13 +239,23 @@ impl<'a> TextEditCtx<'a> {
}
pub fn replace(&mut self, len: usize, text: &str) {
let text = self.string(text);
for _ in 0..len {
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) {
let text = self.string(text);
let mut lines = text.split('\n');
let Some(first) = lines.next() else {
return;
@@ -303,6 +316,9 @@ impl<'a> TextEditCtx<'a> {
}
pub fn newline(&mut self) {
if self.text.single_line {
return;
}
self.clear_span();
if let TextSelection::Pos(cursor) = &mut self.text.selection {
let lines = &mut self.text.view.buf.lines;