merge: pop-os/iced a l'etat pinne par libcosmic 08a09e3df (epoch-1.9.0)
Some checks failed
Audit / vulnerabilities (push) Has been cancelled
Check / wasm (push) Has been cancelled
Check / widget (push) Has been cancelled
Document / all (push) Has been cancelled
Format / all (push) Has been cancelled
Lint / all (push) Has been cancelled
Test / all (macOS-latest, 1.88) (push) Has been cancelled
Test / all (macOS-latest, beta) (push) Has been cancelled
Test / all (macOS-latest, stable) (push) Has been cancelled
Test / all (ubuntu-latest, 1.88) (push) Has been cancelled
Test / all (ubuntu-latest, beta) (push) Has been cancelled
Test / all (ubuntu-latest, stable) (push) Has been cancelled
Test / all (windows-latest, 1.88) (push) Has been cancelled
Test / all (windows-latest, beta) (push) Has been cancelled
Test / all (windows-latest, stable) (push) Has been cancelled

# Conflicts:
#	Cargo.toml
This commit is contained in:
Lionel DARNIS 2026-09-24 20:45:11 +02:00
commit 24da1dc0e4
23 changed files with 1602 additions and 1231 deletions

View file

@ -267,6 +267,7 @@ struct State {
is_hovered: bool,
is_pressed: bool,
is_focused: bool,
needs_redraw: bool,
}
impl<'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer>
@ -368,6 +369,12 @@ where
viewport,
);
let state = tree.state.downcast_mut::<State>();
if state.needs_redraw {
state.needs_redraw = false;
shell.request_redraw();
}
if shell.is_event_captured() {
return;
}
@ -777,11 +784,11 @@ impl Default for Style {
///
/// impl Catalog for MyTheme {
/// type Class<'a> = ButtonClass;
///
///
/// fn default<'a>() -> Self::Class<'a> {
/// ButtonClass::default()
/// }
///
///
///
/// fn style(&self, class: &Self::Class<'_>, status: Status) -> Style {
/// let mut style = Style::default();
@ -1000,10 +1007,12 @@ impl operation::Focusable for State {
}
fn focus(&mut self) {
self.needs_redraw |= !self.is_focused;
self.is_focused = true;
}
fn unfocus(&mut self) {
self.needs_redraw |= self.is_focused;
self.is_focused = false;
}
}

View file

@ -247,64 +247,19 @@ where
self
}
/// Sets whether the user should be allowed to auto-scroll the [`Scrollable`]
/// with the middle mouse button.
/// Adds padding at the ends of the [`Scrollbar`]s of the [`Scrollable`].
///
/// By default, it is disabled.
pub fn auto_scroll(mut self, auto_scroll: bool) -> Self {
self.auto_scroll = auto_scroll;
self
}
/// Sets the scrollbar width of the [`Scrollbar`].
pub fn scrollbar_width(mut self, width: impl Into<Pixels>) -> Self {
let width = width.into().0.max(0.0);
/// The `padding` provided will be used as space at the top and bottom of a
/// vertical [`Scrollbar`], and at the left and right ends of a horizontal
/// [`Scrollbar`], when they are visible.
///
/// Unlike [`Self::spacing`], the padding does not affect the layout of the
/// [`Scrollable`].
pub fn padding(mut self, new_padding: impl Into<Pixels>) -> Self {
let padding = new_padding.into().0;
match &mut self.direction {
Direction::Horizontal(scrollbar)
| Direction::Vertical(scrollbar) => {
scrollbar.width = width;
}
Direction::Both {
horizontal,
vertical,
} => {
horizontal.width = width;
vertical.width = width;
}
}
self
}
/// Sets the scroller width of the [`Scrollbar`].
pub fn scroller_width(mut self, width: impl Into<Pixels>) -> Self {
let width = width.into().0.max(0.0);
match &mut self.direction {
Direction::Horizontal(scrollbar)
| Direction::Vertical(scrollbar) => {
scrollbar.scroller_width = width;
}
Direction::Both {
horizontal,
vertical,
} => {
horizontal.scroller_width = width;
vertical.scroller_width = width;
}
}
self
}
/// Sets the padding at the start and end of the [`Scrollbar`].
pub fn scrollbar_padding(mut self, padding: impl Into<Pixels>) -> Self {
let padding = padding.into().0.max(0.0);
match &mut self.direction {
Direction::Horizontal(scrollbar)
| Direction::Vertical(scrollbar) => {
Direction::Horizontal(scrollbar) | Direction::Vertical(scrollbar) => {
scrollbar.padding = padding;
}
Direction::Both {
@ -319,6 +274,15 @@ where
self
}
/// Sets whether the user should be allowed to auto-scroll the [`Scrollable`]
/// with the middle mouse button.
///
/// By default, it is disabled.
pub fn auto_scroll(mut self, auto_scroll: bool) -> Self {
self.auto_scroll = auto_scroll;
self
}
/// Sets the style of this [`Scrollable`].
#[must_use]
pub fn style(mut self, style: impl Fn(&Theme, Status) -> Style + 'a) -> Self
@ -503,9 +467,15 @@ impl Scrollbar {
self
}
/// Sets the padding at the start and end of the [`Scrollbar`].
/// Sets the padding of the [`Scrollbar`].
///
/// The padding is added at the top and bottom of the scrollbar (or at the
/// left and right ends for a horizontal [`Scrollbar`]) when it is visible.
///
/// Unlike [`Self::margin`] and [`Self::spacing`], the padding does not
/// affect the layout of the [`Scrollable`].
pub fn padding(mut self, padding: impl Into<Pixels>) -> Self {
self.padding = padding.into().0.max(0.0);
self.padding = padding.into().0;
self
}
}
@ -675,13 +645,7 @@ where
let translation =
state.translation(self.direction, bounds, content_bounds);
operation.scrollable(
Some(&self.id),
bounds,
content_bounds,
translation,
state,
);
operation.pre_operation(Some(&self.id));
operation.traverse(&mut |operation| {
self.content.as_widget_mut().operate(
@ -695,6 +659,14 @@ where
operation,
);
});
// XXX must be done after traversing to perform DFS
operation.scrollable(
Some(&self.id),
bounds,
content_bounds,
translation,
state,
);
}
fn update(
@ -2411,13 +2383,16 @@ impl Scrollbars {
let total_scrollbar_width =
width.max(scroller_width) + 2.0 * margin;
// The padding is purely visual: it shrinks the top and bottom of the
// scrollbar without affecting the layout
let scrollbar_height = (bounds.height - x_scrollbar_height - 2.0 * padding).max(0.0);
// Total bounds of the scrollbar + margin + scroller width
let total_scrollbar_bounds = Rectangle {
x: bounds.x + bounds.width - total_scrollbar_width,
y: bounds.y + padding,
width: total_scrollbar_width,
height: (bounds.height - x_scrollbar_height - 2.0 * padding)
.max(0.0),
height: scrollbar_height,
};
// Bounds of just the scrollbar
@ -2427,8 +2402,7 @@ impl Scrollbars {
- width / 2.0,
y: bounds.y + padding,
width,
height: (bounds.height - x_scrollbar_height - 2.0 * padding)
.max(0.0),
height: scrollbar_height,
};
let ratio = bounds.height / content_bounds.height;
@ -2485,12 +2459,15 @@ impl Scrollbars {
let total_scrollbar_height =
width.max(scroller_width) + 2.0 * margin;
// The padding is purely visual: it shrinks the left and right ends of
// the scrollbar without affecting the layout
let scrollbar_width = (bounds.width - scrollbar_y_width - 2.0 * padding).max(0.0);
// Total bounds of the scrollbar + margin + scroller width
let total_scrollbar_bounds = Rectangle {
x: bounds.x + padding,
y: bounds.y + bounds.height - total_scrollbar_height,
width: (bounds.width - scrollbar_y_width - 2.0 * padding)
.max(0.0),
width: scrollbar_width,
height: total_scrollbar_height,
};
@ -2500,8 +2477,7 @@ impl Scrollbars {
y: bounds.y + bounds.height
- total_scrollbar_height / 2.0
- width / 2.0,
width: (bounds.width - scrollbar_y_width - 2.0 * padding)
.max(0.0),
width: scrollbar_width,
height: width,
};

View file

@ -545,6 +545,7 @@ pub struct State<Highlighter: text::Highlighter> {
highlighter_settings: Highlighter::Settings,
highlighter_format_address: usize,
context_menu_position: Option<Point>,
clipboard_has_text: bool,
pending_edit: Option<Action>,
}
@ -632,6 +633,7 @@ where
highlighter_settings: self.highlighter_settings.clone(),
highlighter_format_address: self.highlighter_format as usize,
context_menu_position: None,
clipboard_has_text: false,
pending_edit: None,
})
}
@ -736,6 +738,8 @@ where
state.focus = Some(Focus::now());
}
state.context_menu_position = Some(pos);
state.clipboard_has_text =
widget::text::clipboard_has_text(clipboard);
shell.capture_event();
return;
}
@ -1649,6 +1653,16 @@ where
self.on_edit.is_some()
}
fn has_text(&self, _tree: &widget::Tree) -> bool {
!self.content.is_empty()
}
fn clipboard_has_text(&self, tree: &widget::Tree) -> bool {
tree.state
.downcast_ref::<State<Highlighter>>()
.clipboard_has_text
}
fn is_focused(&self, tree: &widget::Tree) -> bool {
tree.state.downcast_ref::<State<Highlighter>>().is_focused()
}