ui: Make toggle button group responsive (#36100)
This PR improves the toggle button group to be more responsive across different layouts. This is accomplished by ensuring each button takes up the same amount of space in the parent containers layout. Ideally, this should be done with grids instead of a flexbox container, as this would be much better suited for this purpose. Yet, since we lack support for this, we go with this route for now. | Before | After | | --- | --- | | <img width="1608" height="1094" alt="Bildschirmfoto 2025-08-13 um 11 24 26" src="https://github.com/user-attachments/assets/2a4b5a59-6483-4f79-8fcb-e26e22071795" /> | <img width="1608" height="1094" alt="Bildschirmfoto 2025-08-13 um 11 29 36" src="https://github.com/user-attachments/assets/e6402729-6a8f-4a44-b79e-a569406edfff" /> | Release Notes: - N/A
This commit is contained in:
parent
6307105976
commit
7f1a5c6ad7
10 changed files with 50 additions and 36 deletions
|
@ -3011,7 +3011,7 @@ impl EditorElement {
|
|||
.icon_color(Color::Custom(cx.theme().colors().editor_line_number))
|
||||
.selected_icon_color(Color::Custom(cx.theme().colors().editor_foreground))
|
||||
.icon_size(IconSize::Custom(rems(editor_font_size / window.rem_size())))
|
||||
.width(width.into())
|
||||
.width(width)
|
||||
.on_click(move |_, window, cx| {
|
||||
editor.update(cx, |editor, cx| {
|
||||
editor.expand_excerpt(excerpt_id, direction, window, cx);
|
||||
|
@ -3627,7 +3627,7 @@ impl EditorElement {
|
|||
ButtonLike::new("toggle-buffer-fold")
|
||||
.style(ui::ButtonStyle::Transparent)
|
||||
.height(px(28.).into())
|
||||
.width(px(28.).into())
|
||||
.width(px(28.))
|
||||
.children(toggle_chevron_icon)
|
||||
.tooltip({
|
||||
let focus_handle = focus_handle.clone();
|
||||
|
|
|
@ -58,7 +58,7 @@ fn render_theme_section(tab_index: &mut isize, cx: &mut App) -> impl IntoElement
|
|||
.tab_index(tab_index)
|
||||
.selected_index(theme_mode as usize)
|
||||
.style(ui::ToggleButtonGroupStyle::Outlined)
|
||||
.button_width(rems_from_px(64.)),
|
||||
.width(rems_from_px(3. * 64.)),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
|
@ -305,8 +305,8 @@ fn render_base_keymap_section(tab_index: &mut isize, cx: &mut App) -> impl IntoE
|
|||
.when_some(base_keymap, |this, base_keymap| {
|
||||
this.selected_index(base_keymap)
|
||||
})
|
||||
.full_width()
|
||||
.tab_index(tab_index)
|
||||
.button_width(rems_from_px(216.))
|
||||
.size(ui::ToggleButtonGroupSize::Medium)
|
||||
.style(ui::ToggleButtonGroupStyle::Outlined),
|
||||
);
|
||||
|
|
|
@ -706,7 +706,7 @@ fn render_popular_settings_section(
|
|||
})
|
||||
.tab_index(tab_index)
|
||||
.style(ToggleButtonGroupStyle::Outlined)
|
||||
.button_width(ui::rems_from_px(64.)),
|
||||
.width(ui::rems_from_px(3. * 64.)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -295,7 +295,7 @@ impl NotebookEditor {
|
|||
_cx: &mut Context<Self>,
|
||||
) -> IconButton {
|
||||
let id: ElementId = ElementId::Name(id.into());
|
||||
IconButton::new(id, icon).width(px(CONTROL_SIZE).into())
|
||||
IconButton::new(id, icon).width(px(CONTROL_SIZE))
|
||||
}
|
||||
|
||||
fn render_notebook_controls(
|
||||
|
|
|
@ -324,7 +324,7 @@ impl FixedWidth for Button {
|
|||
/// ```
|
||||
///
|
||||
/// This sets the button's width to be exactly 100 pixels.
|
||||
fn width(mut self, width: DefiniteLength) -> Self {
|
||||
fn width(mut self, width: impl Into<DefiniteLength>) -> Self {
|
||||
self.base = self.base.width(width);
|
||||
self
|
||||
}
|
||||
|
|
|
@ -499,8 +499,8 @@ impl Clickable for ButtonLike {
|
|||
}
|
||||
|
||||
impl FixedWidth for ButtonLike {
|
||||
fn width(mut self, width: DefiniteLength) -> Self {
|
||||
self.width = Some(width);
|
||||
fn width(mut self, width: impl Into<DefiniteLength>) -> Self {
|
||||
self.width = Some(width.into());
|
||||
self
|
||||
}
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ impl Clickable for IconButton {
|
|||
}
|
||||
|
||||
impl FixedWidth for IconButton {
|
||||
fn width(mut self, width: DefiniteLength) -> Self {
|
||||
fn width(mut self, width: impl Into<DefiniteLength>) -> Self {
|
||||
self.base = self.base.width(width);
|
||||
self
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ impl RenderOnce for IconButton {
|
|||
.map(|this| match self.shape {
|
||||
IconButtonShape::Square => {
|
||||
let size = self.icon_size.square(window, cx);
|
||||
this.width(size.into()).height(size.into())
|
||||
this.width(size).height(size.into())
|
||||
}
|
||||
IconButtonShape::Wide => this,
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use gpui::{AnyView, ClickEvent};
|
||||
use gpui::{AnyView, ClickEvent, relative};
|
||||
|
||||
use crate::{ButtonLike, ButtonLikeRounding, ElevationIndex, TintColor, Tooltip, prelude::*};
|
||||
|
||||
|
@ -73,8 +73,8 @@ impl SelectableButton for ToggleButton {
|
|||
}
|
||||
|
||||
impl FixedWidth for ToggleButton {
|
||||
fn width(mut self, width: DefiniteLength) -> Self {
|
||||
self.base.width = Some(width);
|
||||
fn width(mut self, width: impl Into<DefiniteLength>) -> Self {
|
||||
self.base.width = Some(width.into());
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -429,7 +429,7 @@ where
|
|||
rows: [[T; COLS]; ROWS],
|
||||
style: ToggleButtonGroupStyle,
|
||||
size: ToggleButtonGroupSize,
|
||||
button_width: Rems,
|
||||
group_width: Option<DefiniteLength>,
|
||||
selected_index: usize,
|
||||
tab_index: Option<isize>,
|
||||
}
|
||||
|
@ -441,7 +441,7 @@ impl<T: ButtonBuilder, const COLS: usize> ToggleButtonGroup<T, COLS> {
|
|||
rows: [buttons],
|
||||
style: ToggleButtonGroupStyle::Transparent,
|
||||
size: ToggleButtonGroupSize::Default,
|
||||
button_width: rems_from_px(100.),
|
||||
group_width: None,
|
||||
selected_index: 0,
|
||||
tab_index: None,
|
||||
}
|
||||
|
@ -455,7 +455,7 @@ impl<T: ButtonBuilder, const COLS: usize> ToggleButtonGroup<T, COLS, 2> {
|
|||
rows: [first_row, second_row],
|
||||
style: ToggleButtonGroupStyle::Transparent,
|
||||
size: ToggleButtonGroupSize::Default,
|
||||
button_width: rems_from_px(100.),
|
||||
group_width: None,
|
||||
selected_index: 0,
|
||||
tab_index: None,
|
||||
}
|
||||
|
@ -473,11 +473,6 @@ impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> ToggleButtonGroup<T
|
|||
self
|
||||
}
|
||||
|
||||
pub fn button_width(mut self, button_width: Rems) -> Self {
|
||||
self.button_width = button_width;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn selected_index(mut self, index: usize) -> Self {
|
||||
self.selected_index = index;
|
||||
self
|
||||
|
@ -491,6 +486,24 @@ impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> ToggleButtonGroup<T
|
|||
*tab_index += (COLS * ROWS) as isize;
|
||||
self
|
||||
}
|
||||
|
||||
const fn button_width() -> DefiniteLength {
|
||||
relative(1. / COLS as f32)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> FixedWidth
|
||||
for ToggleButtonGroup<T, COLS, ROWS>
|
||||
{
|
||||
fn width(mut self, width: impl Into<DefiniteLength>) -> Self {
|
||||
self.group_width = Some(width.into());
|
||||
self
|
||||
}
|
||||
|
||||
fn full_width(mut self) -> Self {
|
||||
self.group_width = Some(relative(1.));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> RenderOnce
|
||||
|
@ -511,6 +524,7 @@ impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> RenderOnce
|
|||
let entry_index = row_index * COLS + col_index;
|
||||
|
||||
ButtonLike::new((self.group_name, entry_index))
|
||||
.full_width()
|
||||
.rounding(None)
|
||||
.when_some(self.tab_index, |this, tab_index| {
|
||||
this.tab_index(tab_index + entry_index as isize)
|
||||
|
@ -527,7 +541,7 @@ impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> RenderOnce
|
|||
})
|
||||
.child(
|
||||
h_flex()
|
||||
.min_w(self.button_width)
|
||||
.w_full()
|
||||
.gap_1p5()
|
||||
.px_3()
|
||||
.py_1()
|
||||
|
@ -561,6 +575,13 @@ impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> RenderOnce
|
|||
let is_transparent = self.style == ToggleButtonGroupStyle::Transparent;
|
||||
|
||||
v_flex()
|
||||
.map(|this| {
|
||||
if let Some(width) = self.group_width {
|
||||
this.w(width)
|
||||
} else {
|
||||
this.w_full()
|
||||
}
|
||||
})
|
||||
.rounded_md()
|
||||
.overflow_hidden()
|
||||
.map(|this| {
|
||||
|
@ -583,6 +604,8 @@ impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> RenderOnce
|
|||
.when(is_outlined_or_filled && !last_item, |this| {
|
||||
this.border_r_1().border_color(border_color)
|
||||
})
|
||||
.w(Self::button_width())
|
||||
.overflow_hidden()
|
||||
.child(item)
|
||||
}))
|
||||
}))
|
||||
|
@ -630,7 +653,6 @@ impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> Component
|
|||
],
|
||||
)
|
||||
.selected_index(1)
|
||||
.button_width(rems_from_px(100.))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
|
@ -656,7 +678,6 @@ impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> Component
|
|||
],
|
||||
)
|
||||
.selected_index(1)
|
||||
.button_width(rems_from_px(100.))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
|
@ -675,7 +696,6 @@ impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> Component
|
|||
],
|
||||
)
|
||||
.selected_index(3)
|
||||
.button_width(rems_from_px(100.))
|
||||
.into_any_element(),
|
||||
),
|
||||
single_example(
|
||||
|
@ -718,7 +738,6 @@ impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> Component
|
|||
],
|
||||
)
|
||||
.selected_index(3)
|
||||
.button_width(rems_from_px(100.))
|
||||
.into_any_element(),
|
||||
),
|
||||
],
|
||||
|
@ -763,7 +782,6 @@ impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> Component
|
|||
],
|
||||
)
|
||||
.selected_index(1)
|
||||
.button_width(rems_from_px(100.))
|
||||
.style(ToggleButtonGroupStyle::Outlined)
|
||||
.into_any_element(),
|
||||
),
|
||||
|
@ -783,7 +801,6 @@ impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> Component
|
|||
],
|
||||
)
|
||||
.selected_index(3)
|
||||
.button_width(rems_from_px(100.))
|
||||
.style(ToggleButtonGroupStyle::Outlined)
|
||||
.into_any_element(),
|
||||
),
|
||||
|
@ -827,7 +844,6 @@ impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> Component
|
|||
],
|
||||
)
|
||||
.selected_index(3)
|
||||
.button_width(rems_from_px(100.))
|
||||
.style(ToggleButtonGroupStyle::Outlined)
|
||||
.into_any_element(),
|
||||
),
|
||||
|
@ -873,7 +889,6 @@ impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> Component
|
|||
],
|
||||
)
|
||||
.selected_index(1)
|
||||
.button_width(rems_from_px(100.))
|
||||
.style(ToggleButtonGroupStyle::Filled)
|
||||
.into_any_element(),
|
||||
),
|
||||
|
@ -893,7 +908,7 @@ impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> Component
|
|||
],
|
||||
)
|
||||
.selected_index(3)
|
||||
.button_width(rems_from_px(100.))
|
||||
.width(rems_from_px(100.))
|
||||
.style(ToggleButtonGroupStyle::Filled)
|
||||
.into_any_element(),
|
||||
),
|
||||
|
@ -937,7 +952,7 @@ impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> Component
|
|||
],
|
||||
)
|
||||
.selected_index(3)
|
||||
.button_width(rems_from_px(100.))
|
||||
.width(rems_from_px(100.))
|
||||
.style(ToggleButtonGroupStyle::Filled)
|
||||
.into_any_element(),
|
||||
),
|
||||
|
@ -957,7 +972,6 @@ impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> Component
|
|||
],
|
||||
)
|
||||
.selected_index(1)
|
||||
.button_width(rems_from_px(100.))
|
||||
.into_any_element(),
|
||||
)])
|
||||
.into_any_element(),
|
||||
|
|
|
@ -3,7 +3,7 @@ use gpui::DefiniteLength;
|
|||
/// A trait for elements that can have a fixed with. Enables the use of the `width` and `full_width` methods.
|
||||
pub trait FixedWidth {
|
||||
/// Sets the width of the element.
|
||||
fn width(self, width: DefiniteLength) -> Self;
|
||||
fn width(self, width: impl Into<DefiniteLength>) -> Self;
|
||||
|
||||
/// Sets the element's width to the full width of its container.
|
||||
fn full_width(self) -> Self;
|
||||
|
|
|
@ -216,7 +216,7 @@ impl QuickActionBar {
|
|||
.size(IconSize::XSmall)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.width(rems(1.).into())
|
||||
.width(rems(1.))
|
||||
.disabled(menu_state.popover_disabled),
|
||||
Tooltip::text("REPL Menu"),
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue