Skip to content

Commit

Permalink
make dragvalue textedit style consistent with button (#2649)
Browse files Browse the repository at this point in the history
* make dragvalue textedit style consistent with button

* fix comments &  fix wrong interactive cursor pos

* * apply button_padding to textedit
* support vertical align
* add same min size as button to avoid unintented height shrink
  • Loading branch information
lictex authored Feb 7, 2023
1 parent b52cd20 commit 8bc88c9
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 10 deletions.
8 changes: 6 additions & 2 deletions crates/egui/src/widgets/drag_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,14 +461,18 @@ impl<'a> Widget for DragValue<'a> {
// some clones below are redundant if AccessKit is disabled
#[allow(clippy::redundant_clone)]
let mut response = if is_kb_editing {
let button_width = ui.spacing().interact_size.x;
let mut value_text = ui
.memory_mut(|mem| mem.drag_value.edit_string.take())
.unwrap_or_else(|| value_text.clone());
let response = ui.add(
TextEdit::singleline(&mut value_text)
.clip_text(false)
.horizontal_align(ui.layout().horizontal_align())
.vertical_align(ui.layout().vertical_align())
.margin(ui.spacing().button_padding)
.min_size(ui.spacing().interact_size)
.id(id)
.desired_width(button_width)
.desired_width(ui.spacing().interact_size.x)
.font(text_style),
);
let parsed_value = match custom_parser {
Expand Down
64 changes: 56 additions & 8 deletions crates/egui/src/widgets/text_edit/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ pub struct TextEdit<'t> {
desired_height_rows: usize,
lock_focus: bool,
cursor_at_end: bool,
min_size: Vec2,
align: Align2,
clip_text: bool,
}

impl<'t> WidgetWithState for TextEdit<'t> {
Expand All @@ -89,6 +92,7 @@ impl<'t> TextEdit<'t> {
Self {
desired_height_rows: 1,
multiline: false,
clip_text: true,
..Self::multiline(text)
}
}
Expand All @@ -112,6 +116,9 @@ impl<'t> TextEdit<'t> {
desired_height_rows: 4,
lock_focus: false,
cursor_at_end: true,
min_size: Vec2::ZERO,
align: Align2::LEFT_TOP,
clip_text: false,
}
}

Expand Down Expand Up @@ -269,6 +276,37 @@ impl<'t> TextEdit<'t> {
self.cursor_at_end = b;
self
}

/// When `true` (default), overflowing text will be clipped.
///
/// When `false`, widget width will expand to make all text visible.
///
/// This only works for singleline [`TextEdit`].
pub fn clip_text(mut self, b: bool) -> Self {
// always show everything in multiline
if !self.multiline {
self.clip_text = b;
}
self
}

/// Set the horizontal align of the inner text.
pub fn horizontal_align(mut self, align: Align) -> Self {
self.align.0[0] = align;
self
}

/// Set the vertical align of the inner text.
pub fn vertical_align(mut self, align: Align) -> Self {
self.align.0[1] = align;
self
}

/// Set the minimum size of the [`TextEdit`].
pub fn min_size(mut self, min_size: Vec2) -> Self {
self.min_size = min_size;
self
}
}

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -364,13 +402,16 @@ impl<'t> TextEdit<'t> {
layouter,
password,
frame: _,
margin: _,
margin,
multiline,
interactive,
desired_width,
desired_height_rows,
lock_focus,
cursor_at_end,
min_size,
align,
clip_text,
} = self;

let text_color = text_color
Expand All @@ -389,7 +430,7 @@ impl<'t> TextEdit<'t> {
available_width
} else {
desired_width.min(available_width)
};
} - margin.x * 2.0;

let font_id_clone = font_id.clone();
let mut default_layouter = move |ui: &Ui, text: &str, wrap_width: f32| {
Expand All @@ -406,13 +447,14 @@ impl<'t> TextEdit<'t> {

let mut galley = layouter(ui, text.as_str(), wrap_width);

let desired_width = if multiline {
galley.size().x.max(wrap_width) // always show everything in multiline
let desired_width = if clip_text {
wrap_width // visual clipping with scroll in singleline input.
} else {
wrap_width // visual clipping with scroll in singleline input. TODO(emilk): opt-in/out?
galley.size().x.max(wrap_width)
};
let desired_height = (desired_height_rows.at_least(1) as f32) * row_height;
let desired_size = vec2(desired_width, galley.size().y.max(desired_height));
let desired_size = vec2(desired_width, galley.size().y.max(desired_height))
.at_least(min_size - margin * 2.0);

let (auto_id, rect) = ui.allocate_space(desired_size);

Expand Down Expand Up @@ -547,10 +589,14 @@ impl<'t> TextEdit<'t> {
cursor_range = Some(new_cursor_range);
}

let mut text_draw_pos = response.rect.min;
let mut text_draw_pos = align
.align_size_within_rect(galley.size(), response.rect)
.intersect(response.rect) // limit pos to the response rect area
.min;
let align_offset = response.rect.left() - text_draw_pos.x;

// Visual clipping for singleline text editor with text larger than width
if !multiline {
if clip_text && align_offset == 0.0 {
let cursor_pos = match (cursor_range, ui.memory(|mem| mem.has_focus(id))) {
(Some(cursor_range), true) => galley.pos_from_cursor(&cursor_range.primary).min.x,
_ => 0.0,
Expand All @@ -573,6 +619,8 @@ impl<'t> TextEdit<'t> {

state.singleline_offset = offset_x;
text_draw_pos -= vec2(offset_x, 0.0);
} else {
state.singleline_offset = align_offset;
}

let selection_changed = if let (Some(cursor_range), Some(prev_cursor_range)) =
Expand Down

0 comments on commit 8bc88c9

Please sign in to comment.