segmented_button: honour WindowControlsPosition for the tab close button
The close button of closable tabs was pinned to the trailing edge, so enabling macOS-style window controls left the window buttons on the left and the tab crosses on the right. Read crate::config::window_controls_position() and, when Start, place the close button before the tab contents and shift them accordingly. The hit-test, the text width and the drawn icon all derive from the same position so they stay in sync. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
28f7ab4651
commit
5392d9d5ae
1 changed files with 41 additions and 15 deletions
|
|
@ -9,7 +9,7 @@ use crate::widget::menu::{
|
|||
self, CloseCondition, ItemHeight, ItemWidth, MenuBarState, PathHighlight, menu_roots_children,
|
||||
menu_roots_diff,
|
||||
};
|
||||
use crate::widget::{Icon, icon};
|
||||
use crate::widget::{Icon, WindowControlsPosition, icon};
|
||||
use crate::{Element, Renderer};
|
||||
use derive_setters::Setters;
|
||||
use iced::clipboard::dnd::{
|
||||
|
|
@ -1608,8 +1608,11 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
let close_button_bounds =
|
||||
close_bounds(bounds, f32::from(self.close_icon.size));
|
||||
let close_button_bounds = close_bounds(
|
||||
bounds,
|
||||
f32::from(self.close_icon.size),
|
||||
crate::config::window_controls_position(),
|
||||
);
|
||||
let over_close_button = self.model.items[key].closable
|
||||
&& cursor_position.is_over(close_button_bounds);
|
||||
|
||||
|
|
@ -2420,6 +2423,25 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
// Whether to show the close button on this tab.
|
||||
let show_close_button =
|
||||
(key_is_active || !self.show_close_icon_on_hover || key_is_hovered)
|
||||
&& self.model.is_closable(key);
|
||||
|
||||
// Width of the icon used by the close button, which we will subtract from the text bounds.
|
||||
let close_icon_width = if show_close_button {
|
||||
f32::from(self.close_icon.size)
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
|
||||
// With macOS-style controls the close button precedes the contents, so
|
||||
// shift them right to make room for it.
|
||||
let close_position = crate::config::window_controls_position();
|
||||
if show_close_button && close_position == WindowControlsPosition::Start {
|
||||
bounds.x += close_icon_width + f32::from(self.button_spacing);
|
||||
}
|
||||
|
||||
// Draw the image beside the text.
|
||||
if let Some(icon) = self.model.icon(key) {
|
||||
let mut image_bounds = bounds;
|
||||
|
|
@ -2477,21 +2499,17 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
// Whether to show the close button on this tab.
|
||||
let show_close_button =
|
||||
(key_is_active || !self.show_close_icon_on_hover || key_is_hovered)
|
||||
&& self.model.is_closable(key);
|
||||
|
||||
// Width of the icon used by the close button, which we will subtract from the text bounds.
|
||||
let close_icon_width = if show_close_button {
|
||||
f32::from(self.close_icon.size)
|
||||
// Room reserved after the contents: only needed when the close button
|
||||
// trails them, since a leading one is already counted in `bounds.x`.
|
||||
let trailing_close_width = if close_position == WindowControlsPosition::End {
|
||||
close_icon_width
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
|
||||
bounds.width = original_bounds.width
|
||||
- (bounds.x - original_bounds.x)
|
||||
- close_icon_width
|
||||
- trailing_close_width
|
||||
- f32::from(self.button_padding[2]);
|
||||
|
||||
bounds.y = center_y;
|
||||
|
|
@ -2517,7 +2535,8 @@ where
|
|||
|
||||
// Draw a close button if set.
|
||||
if show_close_button {
|
||||
let close_button_bounds = close_bounds(original_bounds, close_icon_width);
|
||||
let close_button_bounds =
|
||||
close_bounds(original_bounds, close_icon_width, close_position);
|
||||
|
||||
draw_icon::<Message>(
|
||||
renderer,
|
||||
|
|
@ -3070,9 +3089,16 @@ impl From<Id> for widget::Id {
|
|||
}
|
||||
|
||||
/// Calculates the bounds of the close button within the area of an item.
|
||||
fn close_bounds(area: Rectangle<f32>, icon_size: f32) -> Rectangle<f32> {
|
||||
fn close_bounds(
|
||||
area: Rectangle<f32>,
|
||||
icon_size: f32,
|
||||
position: WindowControlsPosition,
|
||||
) -> Rectangle<f32> {
|
||||
Rectangle {
|
||||
x: area.x + area.width - icon_size - 8.0,
|
||||
x: match position {
|
||||
WindowControlsPosition::Start => area.x + 8.0,
|
||||
WindowControlsPosition::End => area.x + area.width - icon_size - 8.0,
|
||||
},
|
||||
y: area.center_y() - (icon_size / 2.0),
|
||||
width: icon_size,
|
||||
height: icon_size,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue