Update vulnerable dependencies and migrate to Iced 0.14.

This commit is contained in:
2026-08-09 17:16:26 +02:00
parent c757314c91
commit 520e1d86ea
38 changed files with 1105 additions and 1237 deletions

View File

@@ -1229,7 +1229,7 @@ impl BdsApp {
let init_task = Task::batch([
init_task,
Task::done(Message::InitMenuBar),
window::get_oldest().map(Message::MainWindowLoaded),
window::oldest().map(Message::MainWindowLoaded),
]);
registry.set_enabled(MenuAction::Save, false);
registry.set_enabled(MenuAction::PublishSelected, false);
@@ -1459,8 +1459,12 @@ impl BdsApp {
pub fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::KeyboardNavigation(navigation) => match navigation {
crate::components::keyboard::Navigation::Next => iced::widget::focus_next(),
crate::components::keyboard::Navigation::Previous => iced::widget::focus_previous(),
crate::components::keyboard::Navigation::Next => {
iced::widget::operation::focus_next()
}
crate::components::keyboard::Navigation::Previous => {
iced::widget::operation::focus_previous()
}
},
Message::WindowCloseRequested => {
self.persist_project_ui_state();
@@ -2639,7 +2643,7 @@ impl BdsApp {
} else if let Some(anchor) = url.strip_prefix("https://ruds.invalid/document#") {
if let Some(offset) = self.documentation_state(kind).parsed.anchors.get(anchor)
{
return iced::widget::scrollable::snap_to(
return iced::widget::operation::snap_to(
crate::views::documentation::scroll_id(kind),
iced::widget::scrollable::RelativeOffset { x: 0.0, y: *offset },
);
@@ -10102,7 +10106,7 @@ impl BdsApp {
}
let Some(window_id) = self.main_window_id else {
return window::get_oldest().map(Message::MainWindowLoaded);
return window::oldest().map(Message::MainWindowLoaded);
};
if let Some(preview) = &mut self.embedded_style_preview
&& should_start_embedded_preview_creation(
@@ -10157,7 +10161,7 @@ impl BdsApp {
}
let Some(window_id) = self.main_window_id else {
return window::get_oldest().map(Message::MainWindowLoaded);
return window::oldest().map(Message::MainWindowLoaded);
};
if let Some(preview) = &mut self.embedded_preview
@@ -14551,7 +14555,7 @@ mod tests {
app.settings_state
.as_ref()
.map(|state| state.project_description.text()),
Some("Description from project.json\n".to_string())
Some("Description from project.json".to_string())
);
}

View File

@@ -39,6 +39,7 @@ pub fn app_theme() -> Theme {
text: Color::from_rgb8(0xCC, 0xCC, 0xCC),
primary: PRIMARY_BG,
success: Color::from_rgb8(0x2E, 0x7D, 0x32),
warning: Color::from_rgb8(0xC9, 0x8A, 0x20),
danger: DANGER_BG,
},
)
@@ -67,12 +68,12 @@ pub fn compact_scrollbar() -> scrollable::Scrollbar {
}
/// Muted overlay-like scrollbar chrome that gains contrast only while interacting.
pub fn scrollable_style(_theme: &Theme, status: scrollable::Status) -> scrollable::Style {
pub fn scrollable_style(theme: &Theme, status: scrollable::Status) -> scrollable::Style {
let rail = |opacity| scrollable::Rail {
background: None,
border: Border::default(),
scroller: scrollable::Scroller {
color: Color::from_rgba(0.72, 0.74, 0.80, opacity),
background: Background::Color(Color::from_rgba(0.72, 0.74, 0.80, opacity)),
border: Border {
radius: 999.0.into(),
..Border::default()
@@ -80,10 +81,11 @@ pub fn scrollable_style(_theme: &Theme, status: scrollable::Status) -> scrollabl
},
};
let (horizontal_opacity, vertical_opacity) = match status {
scrollable::Status::Active => (0.24, 0.24),
scrollable::Status::Active { .. } => (0.24, 0.24),
scrollable::Status::Hovered {
is_horizontal_scrollbar_hovered,
is_vertical_scrollbar_hovered,
..
} => (
if is_horizontal_scrollbar_hovered {
0.55
@@ -99,6 +101,7 @@ pub fn scrollable_style(_theme: &Theme, status: scrollable::Status) -> scrollabl
scrollable::Status::Dragged {
is_horizontal_scrollbar_dragged,
is_vertical_scrollbar_dragged,
..
} => (
if is_horizontal_scrollbar_dragged {
0.75
@@ -117,12 +120,13 @@ pub fn scrollable_style(_theme: &Theme, status: scrollable::Status) -> scrollabl
vertical_rail: rail(vertical_opacity),
horizontal_rail: rail(horizontal_opacity),
gap: None,
auto_scroll: scrollable::default(theme, status).auto_scroll,
}
}
pub fn field_style(_theme: &Theme, status: text_input::Status) -> text_input::Style {
let border_color = match status {
text_input::Status::Focused => FOCUS_COLOR,
text_input::Status::Focused { .. } => FOCUS_COLOR,
text_input::Status::Hovered => Color::from_rgb8(0x5A, 0x5A, 0x5A),
_ => BORDER_COLOR,
};
@@ -143,7 +147,7 @@ pub fn field_style(_theme: &Theme, status: text_input::Status) -> text_input::St
/// Multi-line editor style matching the standard form fields.
pub fn text_editor_style(_theme: &Theme, status: text_editor::Status) -> text_editor::Style {
let border_color = match status {
text_editor::Status::Focused => FOCUS_COLOR,
text_editor::Status::Focused { .. } => FOCUS_COLOR,
text_editor::Status::Hovered => Color::from_rgb8(0x5A, 0x5A, 0x5A),
_ => BORDER_COLOR,
};
@@ -154,7 +158,6 @@ pub fn text_editor_style(_theme: &Theme, status: text_editor::Status) -> text_ed
width: 1.0,
radius: 6.0.into(),
},
icon: SECTION_COLOR,
placeholder: Color::from_rgb8(0x7D, 0x7D, 0x7D),
value: Color::from_rgb8(0xE4, 0xE4, 0xE4),
selection: Color::from_rgba8(0x26, 0x4F, 0x78, 0.8),
@@ -163,7 +166,7 @@ pub fn text_editor_style(_theme: &Theme, status: text_editor::Status) -> text_ed
pub(crate) fn select_style(_theme: &Theme, status: pick_list::Status) -> pick_list::Style {
let border_color = match status {
pick_list::Status::Hovered | pick_list::Status::Opened => FOCUS_COLOR,
pick_list::Status::Hovered | pick_list::Status::Opened { .. } => FOCUS_COLOR,
pick_list::Status::Active => BORDER_COLOR,
};
pick_list::Style {
@@ -265,7 +268,8 @@ pub fn labeled_checkbox<'a, Message: Clone + 'a>(
on_toggle: impl Fn(bool) -> Message + 'a,
) -> Element<'a, Message> {
keyboard::focusable(
checkbox(label, is_checked)
checkbox(is_checked)
.label(label.to_string())
.on_toggle(on_toggle)
.size(16)
.text_size(14),
@@ -476,7 +480,7 @@ mod tests {
);
assert_ne!(
field_style(&theme, text_input::Status::Active).border.color,
field_style(&theme, text_input::Status::Focused)
field_style(&theme, text_input::Status::Focused { is_hovered: false })
.border
.color
);
@@ -484,7 +488,7 @@ mod tests {
text_editor_style(&theme, text_editor::Status::Active)
.border
.color,
text_editor_style(&theme, text_editor::Status::Focused)
text_editor_style(&theme, text_editor::Status::Focused { is_hovered: false },)
.border
.color
);
@@ -511,16 +515,30 @@ mod tests {
.scroller_width(3)
);
let theme = app_theme();
let active = scrollable_style(&theme, scrollable::Status::Active);
let active = scrollable_style(
&theme,
scrollable::Status::Active {
is_horizontal_scrollbar_disabled: false,
is_vertical_scrollbar_disabled: false,
},
);
let hovered = scrollable_style(
&theme,
scrollable::Status::Hovered {
is_horizontal_scrollbar_hovered: false,
is_vertical_scrollbar_hovered: true,
is_horizontal_scrollbar_disabled: false,
is_vertical_scrollbar_disabled: false,
},
);
assert!(active.vertical_rail.background.is_none());
assert!(active.vertical_rail.scroller.color.a < 0.5);
assert!(hovered.vertical_rail.scroller.color.a > active.vertical_rail.scroller.color.a);
let Background::Color(active_color) = active.vertical_rail.scroller.background else {
panic!("scrollbar scroller must use a solid color");
};
let Background::Color(hovered_color) = hovered.vertical_rail.scroller.background else {
panic!("scrollbar scroller must use a solid color");
};
assert!(active_color.a < 0.5);
assert!(hovered_color.a > active_color.a);
}
}

View File

@@ -70,9 +70,9 @@ mod tests {
..State::default()
};
let mut inventory = AccessKeyInventory::default();
inventory.custom(&mut visible, None);
inventory.custom(&mut offscreen, None);
inventory.custom(&mut disabled, None);
inventory.custom(None, Rectangle::default(), &mut visible);
inventory.custom(None, Rectangle::default(), &mut offscreen);
inventory.custom(None, Rectangle::default(), &mut disabled);
assert_eq!(inventory.control_count, 1);
assert_eq!(inventory.generic_count, 1);
}
@@ -115,8 +115,8 @@ mod tests {
count: 0,
exact: None,
};
prefix.custom(&mut first, None);
prefix.custom(&mut second, None);
prefix.custom(None, Rectangle::default(), &mut first);
prefix.custom(None, Rectangle::default(), &mut second);
assert_eq!(prefix.count, 2);
assert_eq!(prefix.exact, None);
@@ -125,8 +125,8 @@ mod tests {
count: 0,
exact: None,
};
complete.custom(&mut first, None);
complete.custom(&mut second, None);
complete.custom(None, Rectangle::default(), &mut first);
complete.custom(None, Rectangle::default(), &mut second);
assert_eq!(complete.count, 1);
assert_eq!(complete.exact.as_deref(), Some("AA"));
}
@@ -280,13 +280,6 @@ impl Focusable for State {
}
}
fn visit_children(
operation: &mut dyn Operation,
operate_on_children: &mut dyn FnMut(&mut dyn Operation),
) {
operate_on_children(operation);
}
#[derive(Default)]
struct AccessKeyInventory {
generic_count: usize,
@@ -295,16 +288,11 @@ struct AccessKeyInventory {
}
impl Operation for AccessKeyInventory {
fn container(
&mut self,
_id: Option<&Id>,
_bounds: Rectangle,
operate_on_children: &mut dyn FnMut(&mut dyn Operation),
) {
visit_children(self, operate_on_children);
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation)) {
operate(self);
}
fn custom(&mut self, state: &mut dyn Any, _id: Option<&Id>) {
fn custom(&mut self, _id: Option<&Id>, _bounds: Rectangle, state: &mut dyn Any) {
let Some(state) = state.downcast_ref::<State>() else {
return;
};
@@ -327,16 +315,11 @@ struct AssignAccessKeys {
}
impl Operation for AssignAccessKeys {
fn container(
&mut self,
_id: Option<&Id>,
_bounds: Rectangle,
operate_on_children: &mut dyn FnMut(&mut dyn Operation),
) {
visit_children(self, operate_on_children);
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation)) {
operate(self);
}
fn custom(&mut self, state: &mut dyn Any, _id: Option<&Id>) {
fn custom(&mut self, _id: Option<&Id>, _bounds: Rectangle, state: &mut dyn Any) {
let Some(state) = state.downcast_mut::<State>() else {
return;
};
@@ -359,16 +342,11 @@ struct SetAccessPrefix<'a> {
}
impl Operation for SetAccessPrefix<'_> {
fn container(
&mut self,
_id: Option<&Id>,
_bounds: Rectangle,
operate_on_children: &mut dyn FnMut(&mut dyn Operation),
) {
visit_children(self, operate_on_children);
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation)) {
operate(self);
}
fn custom(&mut self, state: &mut dyn Any, _id: Option<&Id>) {
fn custom(&mut self, _id: Option<&Id>, _bounds: Rectangle, state: &mut dyn Any) {
if let Some(state) = state.downcast_mut::<State>()
&& state.access_mode
{
@@ -381,16 +359,11 @@ impl Operation for SetAccessPrefix<'_> {
struct CancelAccessKeys;
impl Operation for CancelAccessKeys {
fn container(
&mut self,
_id: Option<&Id>,
_bounds: Rectangle,
operate_on_children: &mut dyn FnMut(&mut dyn Operation),
) {
visit_children(self, operate_on_children);
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation)) {
operate(self);
}
fn custom(&mut self, state: &mut dyn Any, _id: Option<&Id>) {
fn custom(&mut self, _id: Option<&Id>, _bounds: Rectangle, state: &mut dyn Any) {
if let Some(state) = state.downcast_mut::<State>() {
state.access_mode = false;
state.prefix.clear();
@@ -405,16 +378,11 @@ struct AccessKeyMatches<'a> {
}
impl Operation for AccessKeyMatches<'_> {
fn container(
&mut self,
_id: Option<&Id>,
_bounds: Rectangle,
operate_on_children: &mut dyn FnMut(&mut dyn Operation),
) {
visit_children(self, operate_on_children);
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation)) {
operate(self);
}
fn custom(&mut self, state: &mut dyn Any, _id: Option<&Id>) {
fn custom(&mut self, _id: Option<&Id>, _bounds: Rectangle, state: &mut dyn Any) {
let Some(state) = state.downcast_ref::<State>() else {
return;
};
@@ -439,16 +407,11 @@ struct FocusAccessKey<'a> {
}
impl Operation for FocusAccessKey<'_> {
fn container(
&mut self,
_id: Option<&Id>,
_bounds: Rectangle,
operate_on_children: &mut dyn FnMut(&mut dyn Operation),
) {
visit_children(self, operate_on_children);
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation)) {
operate(self);
}
fn custom(&mut self, state: &mut dyn Any, _id: Option<&Id>) {
fn custom(&mut self, _id: Option<&Id>, _bounds: Rectangle, state: &mut dyn Any) {
let Some(state) = state.downcast_mut::<State>() else {
self.next_is_target = false;
return;
@@ -457,7 +420,7 @@ impl Operation for FocusAccessKey<'_> {
state.pending_activation = self.next_is_target;
}
fn focusable(&mut self, state: &mut dyn Focusable, _id: Option<&Id>) {
fn focusable(&mut self, _id: Option<&Id>, _bounds: Rectangle, state: &mut dyn Focusable) {
if self.next_is_target {
state.focus();
} else {
@@ -474,20 +437,15 @@ struct FocusedEditable {
}
impl Operation for FocusedEditable {
fn container(
&mut self,
_id: Option<&Id>,
_bounds: Rectangle,
operate_on_children: &mut dyn FnMut(&mut dyn Operation),
) {
visit_children(self, operate_on_children);
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation)) {
operate(self);
}
fn custom(&mut self, state: &mut dyn Any, _id: Option<&Id>) {
fn custom(&mut self, _id: Option<&Id>, _bounds: Rectangle, state: &mut dyn Any) {
self.next_is_control = state.is::<State>();
}
fn focusable(&mut self, state: &mut dyn Focusable, _id: Option<&Id>) {
fn focusable(&mut self, _id: Option<&Id>, _bounds: Rectangle, state: &mut dyn Focusable) {
self.found |= state.is_focused() && !self.next_is_control;
self.next_is_control = false;
}
@@ -535,9 +493,9 @@ impl<'a, Message> FocusableControl<'a, Message> {
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)),
Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)),
] {
let _ = self.content.as_widget_mut().on_event(
self.content.as_widget_mut().update(
&mut tree.children[0],
event,
&event,
layout,
cursor,
renderer,
@@ -574,18 +532,18 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for FocusableControl<'_, Me
}
fn layout(
&self,
&mut self,
tree: &mut Tree,
renderer: &iced::Renderer,
limits: &layout::Limits,
) -> layout::Node {
self.content
.as_widget()
.as_widget_mut()
.layout(&mut tree.children[0], renderer, limits)
}
fn operate(
&self,
&mut self,
tree: &mut Tree,
layout: Layout<'_>,
renderer: &iced::Renderer,
@@ -594,30 +552,34 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for FocusableControl<'_, Me
let state = tree.state.downcast_mut::<State>();
state.enabled = self.enabled;
state.direct_key = self.hotkey;
operation.custom(state, None);
operation.custom(None, layout.bounds(), state);
if self.enabled {
operation.focusable(state, None);
operation.focusable(None, layout.bounds(), state);
} else {
state.unfocus();
}
operation.container(None, layout.bounds(), &mut |operation| {
self.content
.as_widget()
.operate(&mut tree.children[0], layout, renderer, operation);
operation.container(None, layout.bounds());
operation.traverse(&mut |operation| {
self.content.as_widget_mut().operate(
&mut tree.children[0],
layout,
renderer,
operation,
);
});
}
fn on_event(
fn update(
&mut self,
tree: &mut Tree,
event: Event,
event: &Event,
layout: Layout<'_>,
cursor: mouse::Cursor,
renderer: &iced::Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
viewport: &Rectangle,
) -> event::Status {
) {
let pending_activation = {
let state = tree.state.downcast_mut::<State>();
let pending = state.pending_activation;
@@ -626,11 +588,12 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for FocusableControl<'_, Me
};
if pending_activation && self.enabled {
self.activate(tree, layout, renderer, clipboard, shell, viewport);
return event::Status::Captured;
shell.capture_event();
return;
}
let child_status = self.content.as_widget_mut().on_event(
self.content.as_widget_mut().update(
&mut tree.children[0],
event.clone(),
event,
layout,
cursor,
renderer,
@@ -639,8 +602,8 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for FocusableControl<'_, Me
viewport,
);
let state = tree.state.downcast_mut::<State>();
if child_status == event::Status::Captured || !self.enabled {
return child_status;
if shell.is_event_captured() || !self.enabled {
return;
}
let activate = state.focused
&& matches!(
@@ -652,9 +615,7 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for FocusableControl<'_, Me
);
if activate {
self.activate(tree, layout, renderer, clipboard, shell, viewport);
event::Status::Captured
} else {
child_status
shell.capture_event();
}
}
@@ -743,8 +704,8 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for FocusableControl<'_, Me
size: Pixels(9.0),
line_height: text::LineHeight::Relative(1.0),
bounds: badge.size(),
horizontal_alignment: alignment::Horizontal::Center,
vertical_alignment: alignment::Vertical::Center,
align_x: alignment::Horizontal::Center.into(),
align_y: alignment::Vertical::Center,
shaping: text::Shaping::Advanced,
wrapping: text::Wrapping::None,
},
@@ -758,13 +719,18 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for FocusableControl<'_, Me
fn overlay<'b>(
&'b mut self,
tree: &'b mut Tree,
layout: Layout<'_>,
layout: Layout<'b>,
renderer: &iced::Renderer,
viewport: &Rectangle,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, iced::Renderer>> {
self.content
.as_widget_mut()
.overlay(&mut tree.children[0], layout, renderer, translation)
self.content.as_widget_mut().overlay(
&mut tree.children[0],
layout,
renderer,
viewport,
translation,
)
}
}
@@ -802,18 +768,18 @@ impl<'a, Message> AccessKeyScope<'a, Message> {
}
fn operate(
&self,
&mut self,
tree: &mut Tree,
layout: Layout<'_>,
renderer: &iced::Renderer,
operation: &mut dyn Operation,
) {
self.content
.as_widget()
.as_widget_mut()
.operate(&mut tree.children[0], layout, renderer, operation);
}
fn begin(&self, tree: &mut Tree, layout: Layout<'_>, renderer: &iced::Renderer) -> bool {
fn begin(&mut self, tree: &mut Tree, layout: Layout<'_>, renderer: &iced::Renderer) -> bool {
let mut focused_editable = FocusedEditable::default();
self.operate(tree, layout, renderer, &mut focused_editable);
if focused_editable.found {
@@ -834,7 +800,7 @@ impl<'a, Message> AccessKeyScope<'a, Message> {
true
}
fn cancel(&self, tree: &mut Tree, layout: Layout<'_>, renderer: &iced::Renderer) {
fn cancel(&mut self, tree: &mut Tree, layout: Layout<'_>, renderer: &iced::Renderer) {
self.operate(tree, layout, renderer, &mut CancelAccessKeys);
}
}
@@ -861,41 +827,45 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for AccessKeyScope<'_, Mess
}
fn layout(
&self,
&mut self,
tree: &mut Tree,
renderer: &iced::Renderer,
limits: &layout::Limits,
) -> layout::Node {
self.content
.as_widget()
.as_widget_mut()
.layout(&mut tree.children[0], renderer, limits)
}
fn operate(
&self,
&mut self,
tree: &mut Tree,
layout: Layout<'_>,
renderer: &iced::Renderer,
operation: &mut dyn Operation,
) {
operation.container(None, layout.bounds(), &mut |operation| {
self.content
.as_widget()
.operate(&mut tree.children[0], layout, renderer, operation);
operation.container(None, layout.bounds());
operation.traverse(&mut |operation| {
self.content.as_widget_mut().operate(
&mut tree.children[0],
layout,
renderer,
operation,
);
});
}
fn on_event(
fn update(
&mut self,
tree: &mut Tree,
event: Event,
event: &Event,
layout: Layout<'_>,
cursor: mouse::Cursor,
renderer: &iced::Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
viewport: &Rectangle,
) -> event::Status {
) {
let modifier_update = match &event {
Event::Keyboard(keyboard::Event::ModifiersChanged(modifiers))
| Event::Keyboard(keyboard::Event::KeyPressed { modifiers, .. })
@@ -939,7 +909,8 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for AccessKeyScope<'_, Mess
state.active = false;
state.prefix.clear();
state.cancelled_until_modifiers_release = true;
return event::Status::Captured;
shell.capture_event();
return;
}
if let Event::Keyboard(keyboard::Event::KeyPressed { key, modifiers, .. }) = &event
@@ -955,12 +926,13 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for AccessKeyScope<'_, Mess
)
};
if cancelled {
return event::Status::Captured;
shell.capture_event();
return;
}
if !active {
active = self.begin(tree, layout, renderer);
if !active {
return self.content.as_widget_mut().on_event(
self.content.as_widget_mut().update(
&mut tree.children[0],
event,
layout,
@@ -970,6 +942,7 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for AccessKeyScope<'_, Mess
shell,
viewport,
);
return;
}
let state = tree.state.downcast_mut::<AccessKeyScopeState>();
state.active = true;
@@ -987,7 +960,8 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for AccessKeyScope<'_, Mess
let exact = matches.exact.take();
drop(matches);
if count == 0 {
return event::Status::Captured;
shell.capture_event();
return;
}
self.operate(
@@ -1008,7 +982,7 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for AccessKeyScope<'_, Mess
next_is_target: false,
},
);
let _ = self.content.as_widget_mut().on_event(
self.content.as_widget_mut().update(
&mut tree.children[0],
event,
layout,
@@ -1024,7 +998,8 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for AccessKeyScope<'_, Mess
state.prefix.clear();
state.cancelled_until_modifiers_release = true;
}
return event::Status::Captured;
shell.capture_event();
return;
}
if matches!(event, Event::Mouse(mouse::Event::ButtonPressed(_)))
@@ -1036,7 +1011,7 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for AccessKeyScope<'_, Mess
state.prefix.clear();
}
self.content.as_widget_mut().on_event(
self.content.as_widget_mut().update(
&mut tree.children[0],
event,
layout,
@@ -1045,7 +1020,7 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for AccessKeyScope<'_, Mess
clipboard,
shell,
viewport,
)
);
}
fn mouse_interaction(
@@ -1089,13 +1064,18 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for AccessKeyScope<'_, Mess
fn overlay<'b>(
&'b mut self,
tree: &'b mut Tree,
layout: Layout<'_>,
layout: Layout<'b>,
renderer: &iced::Renderer,
viewport: &Rectangle,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, iced::Renderer>> {
self.content
.as_widget_mut()
.overlay(&mut tree.children[0], layout, renderer, translation)
self.content.as_widget_mut().overlay(
&mut tree.children[0],
layout,
renderer,
viewport,
translation,
)
}
}
@@ -1130,18 +1110,18 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for SuspendedKeyboard<'_, M
}
fn layout(
&self,
&mut self,
tree: &mut Tree,
renderer: &iced::Renderer,
limits: &layout::Limits,
) -> layout::Node {
self.content
.as_widget()
.as_widget_mut()
.layout(&mut tree.children[0], renderer, limits)
}
fn operate(
&self,
&mut self,
_tree: &mut Tree,
_layout: Layout<'_>,
_renderer: &iced::Renderer,
@@ -1149,21 +1129,21 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for SuspendedKeyboard<'_, M
) {
}
fn on_event(
fn update(
&mut self,
tree: &mut Tree,
event: Event,
event: &Event,
layout: Layout<'_>,
cursor: mouse::Cursor,
renderer: &iced::Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
viewport: &Rectangle,
) -> event::Status {
) {
if matches!(event, Event::Keyboard(_)) {
event::Status::Captured
shell.capture_event();
} else {
self.content.as_widget_mut().on_event(
self.content.as_widget_mut().update(
&mut tree.children[0],
event,
layout,
@@ -1172,7 +1152,7 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for SuspendedKeyboard<'_, M
clipboard,
shell,
viewport,
)
);
}
}
@@ -1217,13 +1197,18 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for SuspendedKeyboard<'_, M
fn overlay<'b>(
&'b mut self,
tree: &'b mut Tree,
layout: Layout<'_>,
layout: Layout<'b>,
renderer: &iced::Renderer,
viewport: &Rectangle,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, iced::Renderer>> {
self.content
.as_widget_mut()
.overlay(&mut tree.children[0], layout, renderer, translation)
self.content.as_widget_mut().overlay(
&mut tree.children[0],
layout,
renderer,
viewport,
translation,
)
}
}

View File

@@ -6,7 +6,6 @@ use iced::advanced::overlay;
use iced::advanced::renderer;
use iced::advanced::widget::{Operation, Tree, tree};
use iced::advanced::{Clipboard, Layout, Shell, Widget};
use iced::event;
use iced::keyboard::{self, Key, Location, Modifiers, key};
use iced::mouse;
use iced::{Element, Event, Length, Rectangle, Size, Vector};
@@ -103,9 +102,12 @@ fn command_events(command: EditCommand) -> [Event; 4] {
location: Location::Standard,
modifiers,
text: None,
repeat: false,
}),
Event::Keyboard(keyboard::Event::KeyReleased {
key,
key: key.clone(),
modified_key: Key::Character(modified_character.into()),
physical_key: key::Physical::Code(physical_key),
location: Location::Standard,
modifiers,
}),
@@ -139,68 +141,63 @@ where
}
fn layout(
&self,
&mut self,
tree: &mut Tree,
renderer: &Renderer,
limits: &layout::Limits,
) -> layout::Node {
self.content
.as_widget()
.as_widget_mut()
.layout(&mut tree.children[0], renderer, limits)
}
fn operate(
&self,
&mut self,
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn Operation,
) {
self.content
.as_widget()
.as_widget_mut()
.operate(&mut tree.children[0], layout, renderer, operation);
}
fn on_event(
fn update(
&mut self,
tree: &mut Tree,
event: Event,
event: &Event,
layout: Layout<'_>,
cursor: mouse::Cursor,
renderer: &Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
viewport: &Rectangle,
) -> event::Status {
let mut status = event::Status::Ignored;
) {
if matches!(
event,
Event::Window(iced::window::Event::RedrawRequested(_))
) {
while let Some(command) = pop_command(&self.commands) {
for command_event in command_events(command) {
if self.content.as_widget_mut().on_event(
self.content.as_widget_mut().update(
&mut tree.children[0],
command_event,
&command_event,
layout,
cursor,
renderer,
clipboard,
shell,
viewport,
) == event::Status::Captured
{
status = event::Status::Captured;
}
);
}
}
}
if let Some(sync_event) = modifier_sync_event(&event) {
let _ = self.content.as_widget_mut().on_event(
if let Some(sync_event) = modifier_sync_event(event) {
self.content.as_widget_mut().update(
&mut tree.children[0],
sync_event,
&sync_event,
layout,
cursor,
renderer,
@@ -210,7 +207,7 @@ where
);
}
if self.content.as_widget_mut().on_event(
self.content.as_widget_mut().update(
&mut tree.children[0],
event,
layout,
@@ -219,12 +216,7 @@ where
clipboard,
shell,
viewport,
) == event::Status::Captured
{
event::Status::Captured
} else {
status
}
);
}
fn mouse_interaction(
@@ -268,13 +260,18 @@ where
fn overlay<'b>(
&'b mut self,
tree: &'b mut Tree,
layout: Layout<'_>,
layout: Layout<'b>,
renderer: &Renderer,
viewport: &Rectangle,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
self.content
.as_widget_mut()
.overlay(&mut tree.children[0], layout, renderer, translation)
self.content.as_widget_mut().overlay(
&mut tree.children[0],
layout,
renderer,
viewport,
translation,
)
}
}
@@ -311,6 +308,7 @@ mod tests {
location: Location::Standard,
modifiers,
text: Some("v".into()),
repeat: false,
});
assert_eq!(

View File

@@ -3,7 +3,6 @@ use iced::advanced::overlay;
use iced::advanced::renderer;
use iced::advanced::widget::{Operation, Tree};
use iced::advanced::{Clipboard, Layout, Shell, Widget};
use iced::event;
use iced::keyboard::{self, Key, key};
use iced::mouse;
use iced::{Element, Event, Length, Point, Rectangle, Size, Vector};
@@ -84,40 +83,40 @@ where
}
fn layout(
&self,
&mut self,
tree: &mut Tree,
renderer: &Renderer,
limits: &layout::Limits,
) -> layout::Node {
self.trigger
.as_widget()
.as_widget_mut()
.layout(&mut tree.children[0], renderer, limits)
}
fn operate(
&self,
&mut self,
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn Operation,
) {
self.trigger
.as_widget()
.as_widget_mut()
.operate(&mut tree.children[0], layout, renderer, operation);
}
fn on_event(
fn update(
&mut self,
tree: &mut Tree,
event: Event,
event: &Event,
layout: Layout<'_>,
cursor: mouse::Cursor,
renderer: &Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
viewport: &Rectangle,
) -> event::Status {
self.trigger.as_widget_mut().on_event(
) {
self.trigger.as_widget_mut().update(
&mut tree.children[0],
event,
layout,
@@ -126,7 +125,7 @@ where
clipboard,
shell,
viewport,
)
);
}
fn mouse_interaction(
@@ -170,8 +169,9 @@ where
fn overlay<'b>(
&'b mut self,
tree: &'b mut Tree,
layout: Layout<'_>,
layout: Layout<'b>,
renderer: &Renderer,
viewport: &Rectangle,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
let (trigger_tree, popup_tree) = tree.children.split_at_mut(1);
@@ -179,6 +179,7 @@ where
&mut trigger_tree[0],
layout,
renderer,
viewport,
translation,
);
let popup_overlay = self.is_open.then(|| {
@@ -233,7 +234,7 @@ where
Renderer: renderer::Renderer,
{
fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
let popup = self.popup.as_widget().layout(
let popup = self.popup.as_widget_mut().layout(
self.state,
renderer,
&layout::Limits::new(Size::ZERO, bounds),
@@ -264,12 +265,12 @@ where
style,
layout.children().next().expect("popover child layout"),
cursor,
&Rectangle::with_size(Size::INFINITY),
&Rectangle::INFINITE,
);
}
fn operate(&mut self, layout: Layout<'_>, renderer: &Renderer, operation: &mut dyn Operation) {
self.popup.as_widget().operate(
self.popup.as_widget_mut().operate(
self.state,
layout.children().next().expect("popover child layout"),
renderer,
@@ -277,28 +278,28 @@ where
);
}
fn on_event(
fn update(
&mut self,
event: Event,
event: &Event,
layout: Layout<'_>,
cursor: mouse::Cursor,
renderer: &Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
) -> event::Status {
) {
let popup_layout = layout.children().next().expect("popover child layout");
let status = self.popup.as_widget_mut().on_event(
self.popup.as_widget_mut().update(
self.state,
event.clone(),
event,
popup_layout,
cursor,
renderer,
clipboard,
shell,
&Rectangle::with_size(Size::INFINITY),
&Rectangle::INFINITE,
);
if status == event::Status::Captured {
return status;
if shell.is_event_captured() {
return;
}
let escape = matches!(
@@ -315,9 +316,7 @@ where
) && !cursor.is_over(layout.bounds());
if escape || outside_press {
shell.publish(self.on_dismiss.clone());
event::Status::Captured
} else {
status
shell.capture_event();
}
}
@@ -325,27 +324,27 @@ where
&self,
layout: Layout<'_>,
cursor: mouse::Cursor,
viewport: &Rectangle,
renderer: &Renderer,
) -> mouse::Interaction {
self.popup.as_widget().mouse_interaction(
self.state,
layout.children().next().expect("popover child layout"),
cursor,
viewport,
&Rectangle::INFINITE,
renderer,
)
}
fn overlay<'b>(
&'b mut self,
layout: Layout<'_>,
layout: Layout<'b>,
renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
self.popup.as_widget_mut().overlay(
self.state,
layout.children().next().expect("popover child layout"),
renderer,
&Rectangle::INFINITE,
Vector::ZERO,
)
}

View File

@@ -7,7 +7,6 @@ use iced::advanced::layout::{self, Node};
use iced::advanced::renderer;
use iced::advanced::widget::Tree;
use iced::advanced::{Clipboard, Layout, Shell, Widget};
use iced::event;
use iced::mouse;
use iced::{Element, Event, Length, Rectangle, Size, Task, window};
use wry::dpi::{LogicalPosition, LogicalSize};
@@ -120,7 +119,7 @@ impl WebViewController {
let transparent = self.config.transparent;
let devtools = self.config.devtools;
window::run_with_handle(window_id, move |handle| {
window::run(window_id, move |handle| {
build_webview(id, handle, content, transparent, devtools)
})
.map(on_result)
@@ -165,11 +164,12 @@ impl WebViewController {
fn build_webview(
id: u64,
handle: window::raw_window_handle::WindowHandle<'_>,
handle: &dyn window::Window,
content: Content,
transparent: bool,
devtools: bool,
) -> Result<(), String> {
let handle = handle.window_handle().map_err(|error| error.to_string())?;
let mut builder = WebViewBuilder::new()
.with_transparent(transparent)
.with_devtools(devtools)
@@ -251,7 +251,7 @@ where
Size::new(self.width, self.height)
}
fn layout(&self, _tree: &mut Tree, _renderer: &Renderer, limits: &layout::Limits) -> Node {
fn layout(&mut self, _tree: &mut Tree, _renderer: &Renderer, limits: &layout::Limits) -> Node {
Node::new(limits.resolve(self.width, self.height, Size::ZERO))
}
@@ -267,19 +267,19 @@ where
) {
}
fn on_event(
fn update(
&mut self,
tree: &mut Tree,
event: Event,
event: &Event,
layout: Layout<'_>,
cursor: mouse::Cursor,
_renderer: &Renderer,
_clipboard: &mut dyn Clipboard,
_shell: &mut Shell<'_, Message>,
_viewport: &Rectangle,
) -> event::Status {
) {
let Some(tx) = &self.bounds_tx else {
return event::Status::Ignored;
return;
};
let state = tree.state.downcast_mut::<PlaceholderState>();
@@ -295,8 +295,6 @@ where
{
tx.refocus_parent();
}
event::Status::Ignored
}
}

View File

@@ -27,14 +27,19 @@ fn main() -> anyhow::Result<()> {
iced::window::icon::from_file_data(include_bytes!("../assets/app-icons/bds.png"), None)
.expect("bundled application icon must be valid");
iced::application("bDS", BdsApp::update, BdsApp::view)
iced::application(BdsApp::new, BdsApp::update, BdsApp::view)
.title("bDS")
.subscription(BdsApp::subscription)
.theme(|_| inputs::app_theme())
.theme(app_theme)
.window(desktop_window_settings(Some(icon)))
.run_with(BdsApp::new)?;
.run()?;
Ok(())
}
fn app_theme(_: &BdsApp) -> iced::Theme {
inputs::app_theme()
}
fn desktop_window_settings(icon: Option<iced::window::Icon>) -> iced::window::Settings {
iced::window::Settings {
size: iced::Size::new(1200.0, 800.0),

View File

@@ -1,8 +1,6 @@
use std::collections::HashMap;
use iced::widget::{
Column, column, container, horizontal_space, mouse_area, row, scrollable, text,
};
use iced::widget::{Column, column, container, mouse_area, row, scrollable, space, text};
use iced::{
Alignment, Background, Border, Color, Element, Length, Shadow, Subscription, Theme, Vector,
};
@@ -633,7 +631,7 @@ fn window_menu_popup<'a>(
let shortcut = shortcut_hint(action).unwrap_or_default();
let content = row![
text(translate(locale, action.i18n_key())).size(12),
horizontal_space(),
space::horizontal(),
text(shortcut)
.size(11)
.color(Color::from_rgb8(0x9D, 0xA5, 0xB4)),
@@ -653,7 +651,7 @@ fn window_menu_popup<'a>(
}
Separator => {
entries = entries.push(
container(horizontal_space())
container(space::horizontal())
.height(Length::Fixed(1.0))
.width(Length::Fill)
.style(|_| iced::widget::container::Style {

View File

@@ -142,7 +142,7 @@ pub fn view(
// Active indicator: 2px left border (like bDS/VS Code)
let btn_row: Element<'static, Message> = if is_active {
let indicator = container(Space::new(0, 0))
let indicator = container(Space::new())
.width(Length::Fixed(2.0))
.height(Length::Fixed(48.0))
.style(|_theme: &Theme| container::Style {
@@ -151,7 +151,7 @@ pub fn view(
});
iced::widget::row![indicator, btn].into()
} else {
let spacer = Space::with_width(2.0);
let spacer = Space::new().width(2.0);
iced::widget::row![spacer, btn].into()
};
@@ -182,7 +182,7 @@ pub fn view(
let bottom = Column::with_children(bottom_items).spacing(0);
container(
column![top, Space::with_height(Length::Fill), bottom,]
column![top, Space::new().height(Length::Fill), bottom,]
.width(Length::Fixed(50.0))
.height(Length::Fill)
.padding([4, 0]),

View File

@@ -60,7 +60,7 @@ fn surface_view<'a>(
&format!("chat.surface.type.{}", surface.kind.as_str()),
)
});
let mut header = row![text(title).size(14), Space::with_width(Length::Fill),]
let mut header = row![text(title).size(14), Space::new().width(Length::Fill),]
.spacing(8)
.align_y(Alignment::Center);
if has_title {
@@ -196,7 +196,8 @@ fn form<'a>(
let key = field.key.clone();
let control: Element<'a, Message> = match field.input_type {
FormInputType::Checkbox => keyboard::focusable(
checkbox(label, field.value.as_bool().unwrap_or(false))
checkbox(field.value.as_bool().unwrap_or(false))
.label(label.to_string())
.on_toggle(move |value| Message::ChatSurfaceFieldChanged {
surface_id: surface_id.clone(),
field: key.clone(),
@@ -355,7 +356,7 @@ fn mindmap<'a>(surface: &'a InlineSurface, locale: UiLocale) -> Element<'a, Mess
rows.into_iter()
.map(|(depth, label)| {
row![
Space::with_width(Length::Fixed(depth as f32 * 18.0)),
Space::new().width(Length::Fixed(depth as f32 * 18.0)),
text(if depth == 0 { "" } else { "" })
.size(11)
.color(inputs::SECTION_COLOR),

View File

@@ -390,7 +390,7 @@ pub fn view<'a>(
text(t(locale, "chat.input.hint"))
.size(11)
.color(inputs::SECTION_COLOR),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
send_button,
]
.align_y(Alignment::Center),
@@ -442,8 +442,9 @@ fn message_view<'a>(
let body: Element<'a, Message> = if let Some(items) = rendered_markdown {
markdown::view(
items,
markdown::Settings::default(),
markdown::Style::from_palette(crate::components::inputs::app_theme().palette()),
markdown::Settings::with_style(markdown::Style::from_palette(
crate::components::inputs::app_theme().palette(),
)),
)
.map(|url| Message::ChatLinkClicked(url.to_string()))
} else {
@@ -500,8 +501,9 @@ fn tool_markers_view<'a>(
fn assistant_card<'a>(items: &'a [markdown::Item], label: String) -> Element<'a, Message> {
let body = markdown::view(
items,
markdown::Settings::default(),
markdown::Style::from_palette(crate::components::inputs::app_theme().palette()),
markdown::Settings::with_style(markdown::Style::from_palette(
crate::components::inputs::app_theme().palette(),
)),
)
.map(|url| Message::ChatLinkClicked(url.to_string()));
inputs::card(column![text(label).size(11).color(inputs::SECTION_COLOR), body,].spacing(6))

View File

@@ -147,29 +147,30 @@ pub fn view<'a>(state: &'a DashboardState, locale: UiLocale) -> Element<'a, Mess
]
.spacing(16);
let mut content = column![header, project_label, Space::with_height(16), counts_row].spacing(8);
let mut content =
column![header, project_label, Space::new().height(16), counts_row].spacing(8);
if !state.timeline.is_empty() {
content = content
.push(Space::with_height(20))
.push(Space::new().height(20))
.push(inputs::section_header(&t(locale, "dashboard.timeline")))
.push(timeline_chart(&state.timeline, locale));
}
if !state.tag_cloud.is_empty() {
content = content
.push(Space::with_height(20))
.push(Space::new().height(20))
.push(inputs::section_header(&t(locale, "dashboard.tags")))
.push(tag_cloud(&state.tag_cloud, locale));
}
if !state.category_cloud.is_empty() {
content = content
.push(Space::with_height(20))
.push(Space::new().height(20))
.push(inputs::section_header(&t(locale, "dashboard.categories")))
.push(category_cloud(&state.category_cloud, locale));
}
if !state.recent_posts.is_empty() {
content = content
.push(Space::with_height(20))
.push(Space::new().height(20))
.push(inputs::section_header(&t(locale, "dashboard.recentPosts")))
.push(recent_posts(&state.recent_posts, locale));
}
@@ -238,7 +239,7 @@ fn timeline_chart<'a>(
container(
column![
text(month.count.to_string()).size(12).color(Color::WHITE),
container(Space::with_height(height))
container(Space::new().height(height))
.width(Length::Fill)
.style(|_: &Theme| container::Style {
background: Some(Background::Color(Color::from_rgb(0.25, 0.48, 0.80))),

View File

@@ -137,8 +137,8 @@ impl DocumentationState {
}
}
pub fn scroll_id(kind: DocumentationKind) -> scrollable::Id {
scrollable::Id::new(match kind {
pub fn scroll_id(kind: DocumentationKind) -> iced::widget::Id {
iced::widget::Id::new(match kind {
DocumentationKind::Guide => "user-documentation",
DocumentationKind::Api => "api-documentation",
DocumentationKind::Cli => "cli-documentation",
@@ -200,8 +200,10 @@ pub fn view(state: &DocumentationState, locale: UiLocale) -> Element<'_, Message
content = content.push(match block {
DocumentBlock::Markdown(items) => markdown::view(
items,
markdown::Settings::with_text_size(14),
markdown::Style::from_palette(inputs::app_theme().palette()),
markdown::Settings::with_text_size(
14,
markdown::Style::from_palette(inputs::app_theme().palette()),
),
)
.map({
let kind = state.kind;

View File

@@ -122,7 +122,8 @@ pub fn view(state: &DuplicatesState, locale: UiLocale) -> Element<'_, Message> {
pairs = pairs.push(inputs::card(
row![
keyboard::focusable(
checkbox("", checked)
checkbox(checked)
.label("")
.on_toggle({
let a = pair.post_id_a.clone();
let b = pair.post_id_b.clone();
@@ -148,7 +149,7 @@ pub fn view(state: &DuplicatesState, locale: UiLocale) -> Element<'_, Message> {
.on_press(Message::DuplicatesOpenPost(pair.post_id_b.clone()))
.padding([5, 8])
.style(inputs::disclosure_button),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
text(badge).size(12).color(if pair.exact_match {
Color::from_rgb(0.96, 0.68, 0.28)
} else {

View File

@@ -310,7 +310,7 @@ fn status_button(file: &GitFileStatus) -> Element<'static, Message> {
keyboard::button(
row![
text(path.clone()).size(11),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
text(file.kind.code()).size(11),
]
.spacing(6),
@@ -364,7 +364,7 @@ fn sync_legend_item(status: SyncStatus, locale: UiLocale) -> Element<'static, Me
fn sync_status_dot(status: SyncStatus) -> Element<'static, Message> {
let color = sync_status_color(status);
container(Space::new(8, 8))
container(Space::new().width(8).height(8))
.style(move |_: &iced::Theme| container::Style {
background: Some(Background::Color(color)),
border: iced::Border {

View File

@@ -385,7 +385,7 @@ fn progress_view<'a>(state: &ImportEditorState, locale: UiLocale) -> Element<'a,
column![
row![
text(phase).size(13),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
text(format!("{current} / {total}"))
.size(12)
.color(inputs::LABEL_COLOR),
@@ -778,7 +778,7 @@ fn macro_rows<'a>(report: &'a ImportReport, locale: UiLocale) -> Element<'a, Mes
column![
row![
text(format!("[[{}]]", usage.name)).size(13),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
text(tw(
locale,
"import.macroUses",

View File

@@ -314,7 +314,7 @@ pub fn view<'a>(
// Translation flags bar
let flags = state.translation_flags();
let flags_bar: Element<'a, Message> = if flags.is_empty() {
Space::new(0, 0).into()
Space::new().into()
} else {
let flag_buttons: Vec<Element<'a, Message>> = flags
.iter()
@@ -430,7 +430,7 @@ pub fn view<'a>(
text(t(locale, "editor.linkedPosts"))
.size(12)
.color(Color::from_rgb(0.55, 0.58, 0.65)),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
keyboard::button(text(t(locale, "editor.linkToPost")).size(12))
.on_press(Message::MediaEditor(MediaEditorMsg::TogglePostPicker))
.style(inputs::secondary_button)
@@ -484,7 +484,7 @@ pub fn view<'a>(
})
.into()
} else {
Space::new(0, 0).into()
Space::new().into()
};
let linked_posts_list: Element<'a, Message> = if state.linked_posts.is_empty() {
@@ -503,7 +503,7 @@ pub fn view<'a>(
post.post_id.clone()
)))
.padding([4, 0]),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
keyboard::button(text(t(locale, "editor.unlinkMedia")).size(11))
.on_press(Message::MediaEditor(MediaEditorMsg::UnlinkPost(
post.post_id.clone()
@@ -522,7 +522,7 @@ pub fn view<'a>(
// Footer
let footer = row![
inputs::date_label(&t(locale, "editor.createdAt"), state.created_at),
Space::with_width(Length::Fixed(24.0)),
Space::new().width(Length::Fixed(24.0)),
inputs::date_label(&t(locale, "editor.updatedAt"), state.updated_at),
]
.padding(8);

View File

@@ -869,10 +869,10 @@ fn tree_item<'a>(
.style(secondary_button)
.into()
} else {
Space::new(Length::Fixed(28.0), 0).into()
Space::new().width(Length::Fixed(28.0)).into()
};
let drag: Element<'_, Message> = if item.id == HOME_ID {
Space::new(Length::Fixed(24.0), 0).into()
Space::new().width(Length::Fixed(24.0)).into()
} else {
tooltip(
mouse_area(text("").width(Length::Fixed(24.0)))
@@ -893,7 +893,7 @@ fn tree_item<'a>(
row![
kind_icon(&item.kind),
text(label).size(14),
Space::new(Length::Fill, 0),
Space::new().width(Length::Fill),
text(kind_label(locale, &item.kind))
.size(11)
.color(Color::from_rgb8(0x9D, 0xA5, 0xB4))
@@ -913,7 +913,7 @@ fn tree_item<'a>(
..button::Style::default()
});
let row_content = row![
Space::new(Length::Fixed(depth as f32 * 22.0), 0),
Space::new().width(Length::Fixed(depth as f32 * 22.0)),
toggle,
drag,
label_button
@@ -985,8 +985,8 @@ fn tree_item<'a>(
fn drop_indicator(depth: usize) -> Element<'static, Message> {
row![
Space::new(Length::Fixed(depth as f32 * 22.0 + 60.0), 0),
container(Space::new(Length::Fill, Length::Fixed(2.0))).style(|_theme| {
Space::new().width(Length::Fixed(depth as f32 * 22.0 + 60.0)),
container(Space::new().width(Length::Fill).height(Length::Fixed(2.0))).style(|_theme| {
container::Style {
background: Some(Background::Color(Color::from_rgb8(0x00, 0x7F, 0xD4))),
..container::Style::default()
@@ -1069,7 +1069,7 @@ fn draft_editor<'a>(
);
}
container(row![
Space::new(Length::Fixed(depth as f32 * 22.0 + 60.0), 0),
Space::new().width(Length::Fixed(depth as f32 * 22.0 + 60.0)),
editor.width(Length::Fill)
])
.padding([8, 8])

View File

@@ -32,7 +32,7 @@ pub fn view<'a>(state: &'a MetadataDiffState, locale: UiLocale) -> Element<'a, M
.size(24)
.shaping(Shaping::Advanced)
.color(Color::from_rgb(0.88, 0.88, 0.92)),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
run,
]
.align_y(iced::Alignment::Center),
@@ -113,7 +113,7 @@ pub fn view<'a>(state: &'a MetadataDiffState, locale: UiLocale) -> Element<'a, M
&[("reason", &orphan.reason), ("path", &orphan.file_path)],
))
.size(12),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
]
.align_y(iced::Alignment::Center);
if orphan.reason == "file_without_db_entry" {

View File

@@ -254,7 +254,7 @@ pub fn view(
.size(12)
.shaping(Shaping::Advanced)
.color(Color::from_rgb(0.70, 0.70, 0.75)),
Space::with_height(8.0),
Space::new().height(8.0),
text(t(locale, "remoteConnection.target"))
.size(12)
.color(Color::from_rgb(0.80, 0.80, 0.85)),
@@ -271,7 +271,7 @@ pub fn view(
}
if !projects.is_empty() {
content = content.push(Space::with_height(6.0));
content = content.push(Space::new().height(6.0));
content = content.push(
text(t(locale, "remoteConnection.projects"))
.size(13)
@@ -286,7 +286,7 @@ pub fn view(
row![
text(marker).size(12),
text(project.name.clone()).size(13),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
text(project.description.unwrap_or_default())
.size(11)
.color(Color::from_rgb(0.65, 0.65, 0.70)),
@@ -337,8 +337,8 @@ pub fn view(
button
}
};
content = content.push(Space::with_height(8.0)).push(
row![cancel, Space::with_width(Length::Fill), action].align_y(Alignment::Center),
content = content.push(Space::new().height(8.0)).push(
row![cancel, Space::new().width(Length::Fill), action].align_y(Alignment::Center),
);
container(content.padding(20))
.width(Length::Fixed(500.0))
@@ -371,8 +371,8 @@ pub fn view(
.color(Color::from_rgb(0.70, 0.70, 0.75));
let mut content_col = column![
row![warning_icon, Space::with_width(8.0), title].align_y(Alignment::Center),
Space::with_height(12.0),
row![warning_icon, Space::new().width(8.0), title].align_y(Alignment::Center),
Space::new().height(12.0),
entity_label,
warning_text,
]
@@ -380,7 +380,7 @@ pub fn view(
// Reference section
if !references.is_empty() {
content_col = content_col.push(Space::with_height(8.0));
content_col = content_col.push(Space::new().height(8.0));
for r in references {
content_col = content_col.push(
text(format!("\u{2022} {r}"))
@@ -401,7 +401,7 @@ pub fn view(
.on_press(Message::DismissModal)
.padding([6, 16])
.style(cancel_button_style),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
keyboard::button(
text(t(locale, "modal.confirmDelete.delete"))
.size(13)
@@ -412,7 +412,7 @@ pub fn view(
.style(danger_button_style),
];
content_col = content_col.push(Space::with_height(16.0));
content_col = content_col.push(Space::new().height(16.0));
content_col = content_col.push(buttons);
container(content_col.padding(20))
@@ -446,7 +446,7 @@ pub fn view(
.on_press(Message::DismissModal)
.padding([6, 16])
.style(cancel_button_style),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
keyboard::button(
text(t(locale, "modal.confirm.confirm"))
.size(13)
@@ -459,9 +459,9 @@ pub fn view(
let content_col = column![
title,
Space::with_height(12.0),
Space::new().height(12.0),
msg,
Space::with_height(16.0),
Space::new().height(16.0),
buttons,
]
.spacing(4);
@@ -478,7 +478,7 @@ pub fn view(
.on_press(Message::DismissModal)
.padding([6, 16])
.style(cancel_button_style),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
keyboard::button(text(t(locale, "searchIndexRepair.rebuildNow")).size(13))
.on_press(Message::ConfirmModal(ConfirmAction::RebuildSearchIndex))
.padding([6, 16])
@@ -489,12 +489,12 @@ pub fn view(
.size(16)
.shaping(Shaping::Advanced)
.color(Color::WHITE),
Space::with_height(12.0),
Space::new().height(12.0),
text(t(locale, "searchIndexRepair.message"))
.size(13)
.shaping(Shaping::Advanced)
.color(Color::from_rgb(0.80, 0.80, 0.85)),
Space::with_height(16.0),
Space::new().height(16.0),
buttons,
];
container(content.padding(20))
@@ -566,22 +566,22 @@ pub fn view(
.size(16)
.shaping(Shaping::Advanced)
.color(Color::WHITE),
Space::with_height(12.0),
Space::new().height(12.0),
text(t(locale, "searchIndexRepair.rebuildingMessage"))
.size(13)
.shaping(Shaping::Advanced)
.color(Color::from_rgb(0.80, 0.80, 0.85)),
];
content = if cancellation_requested {
content.push(Space::with_height(16.0)).push(
content.push(Space::new().height(16.0)).push(
text(t(locale, "tasks.status.cancelling"))
.size(13)
.shaping(Shaping::Advanced)
.color(Color::from_rgb(0.80, 0.80, 0.85)),
)
} else {
content.push(Space::with_height(16.0)).push(row![
Space::with_width(Length::Fill),
content.push(Space::new().height(16.0)).push(row![
Space::new().width(Length::Fill),
keyboard::button(text(t(locale, "tasks.cancelTask")).size(13))
.on_press(Message::CancelTask(
crate::state::navigation::TaskSource::Local,
@@ -654,7 +654,7 @@ pub fn view(
let internal_content: Element<'static, Message> = if results.is_empty() {
column![
search_input,
Space::with_height(12.0),
Space::new().height(12.0),
text(t(locale, "modal.postInsertLink.emptyState"))
.size(12)
.shaping(Shaping::Advanced)
@@ -663,7 +663,7 @@ pub fn view(
.spacing(4)
.into()
} else {
let mut column = column![search_input, Space::with_height(12.0)];
let mut column = column![search_input, Space::new().height(12.0)];
for link in results {
column = column.push(
keyboard::button(
@@ -746,9 +746,9 @@ pub fn view(
.padding([6, 10])
.width(Length::Fill)
.style(inputs::field_style),
Space::with_height(12.0),
Space::new().height(12.0),
row![
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
keyboard::button(text(t(locale, "modal.postInsertLink.insert")))
.on_press(Message::PostEditor(
PostEditorMsg::PostInsertLinkExternalInsert
@@ -788,7 +788,7 @@ pub fn view(
if active_tab == PostInsertLinkTab::Internal {
create_post_btn
} else {
Space::with_width(0.0).into()
Space::new().width(0.0).into()
};
let buttons = row![
@@ -796,20 +796,20 @@ pub fn view(
.on_press(Message::DismissModal)
.padding([6, 16])
.style(cancel_button_style),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
trailing_button,
]
.spacing(8);
let content = column![
tabs,
Space::with_height(12.0),
Space::new().height(12.0),
if active_tab == PostInsertLinkTab::Internal {
internal_content
} else {
external_content
},
Space::with_height(16.0),
Space::new().height(16.0),
buttons,
]
.spacing(4);
@@ -896,7 +896,7 @@ pub fn view(
},
..container::Style::default()
}),
Space::with_height(8.0),
Space::new().height(8.0),
media_title,
media_name,
]
@@ -939,7 +939,7 @@ pub fn view(
let media_list_col: Element<'static, Message> = if media_list.is_empty() {
column![
search_input,
Space::with_height(12.0),
Space::new().height(12.0),
text(t(locale, "modal.postInsertLink.emptyState"))
.size(12)
.shaping(Shaping::Advanced)
@@ -950,7 +950,7 @@ pub fn view(
} else {
column![
search_input,
Space::with_height(16.0),
Space::new().height(16.0),
container(grid).width(Length::Fill).center_x(Length::Fill),
]
.spacing(8)
@@ -971,9 +971,9 @@ pub fn view(
let content = column![
title,
Space::with_height(12.0),
Space::new().height(12.0),
media_list_col,
Space::with_height(16.0),
Space::new().height(16.0),
buttons,
]
.spacing(4)
@@ -1039,7 +1039,7 @@ pub fn view(
},
..container::Style::default()
}),
Space::with_height(8.0),
Space::new().height(8.0),
media_title,
]
.spacing(4)
@@ -1110,16 +1110,16 @@ pub fn view(
.on_press(Message::PostEditor(PostEditorMsg::PostGalleryPrevious))
.padding([6, 12])
.style(cancel_button_style),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
text(format!("{} / {}", index + 1, image_media.len()))
.size(12)
.shaping(Shaping::Advanced),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
keyboard::button(text(">"))
.on_press(Message::PostEditor(PostEditorMsg::PostGalleryNext))
.padding([6, 12])
.style(cancel_button_style),
Space::with_width(12.0),
Space::new().width(12.0),
keyboard::button(text(t(locale, "modal.postGallery.backToGrid")))
.on_press(Message::PostEditor(
PostEditorMsg::PostGalleryCloseLightbox
@@ -1132,10 +1132,10 @@ pub fn view(
.spacing(12)
.into()
} else {
Space::with_height(0.0).into()
Space::new().height(0.0).into()
}
} else {
Space::with_height(0.0).into()
Space::new().height(0.0).into()
};
let content = column![
@@ -1144,7 +1144,7 @@ pub fn view(
} else {
container(grid).center_x(Length::Fill).into()
},
Space::with_height(16.0),
Space::new().height(16.0),
close_button,
]
.spacing(4);
@@ -1167,7 +1167,8 @@ pub fn view(
.enumerate()
.map(|(index, field)| {
let toggle = keyboard::focusable(
checkbox(field.label.clone(), field.accepted)
checkbox(field.accepted)
.label(field.label.clone())
.on_toggle_maybe((!field.locked).then_some(move |value| {
Message::ToggleAiSuggestionField(index, value)
}))
@@ -1217,7 +1218,7 @@ pub fn view(
.on_press(Message::DismissModal)
.padding([6, 16])
.style(cancel_button_style),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
keyboard::button(text(t(locale, "modal.aiSuggestions.applySelected")).size(13))
.on_press(Message::ApplyAiSuggestions(target, fields))
.padding([6, 16])
@@ -1226,12 +1227,12 @@ pub fn view(
let content = column![
title,
Space::with_height(12.0),
Space::new().height(12.0),
scrollable(column(rows).spacing(8))
.direction(scrollable::Direction::Vertical(inputs::compact_scrollbar()))
.style(inputs::scrollable_style)
.height(Length::Fixed(320.0)),
Space::with_height(16.0),
Space::new().height(16.0),
buttons,
]
.spacing(4);
@@ -1283,7 +1284,7 @@ pub fn view(
.size(13)
.shaping(Shaping::Advanced)
.color(Color::WHITE),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
text(status)
.size(11)
.color(Color::from_rgb(0.60, 0.60, 0.68)),
@@ -1301,9 +1302,9 @@ pub fn view(
let content = column![
title,
subtitle,
Space::with_height(12.0),
Space::new().height(12.0),
column(rows).spacing(6),
Space::with_height(16.0),
Space::new().height(16.0),
keyboard::button(text(t(locale, "common.cancel")).size(13))
.on_press(Message::DismissModal)
.padding([6, 16])

View File

@@ -40,7 +40,7 @@ fn task_row(
weight: iced::font::Weight::Semibold,
..Font::DEFAULT
}),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
text(status)
.size(10)
.shaping(Shaping::Advanced)
@@ -67,7 +67,7 @@ fn task_row(
rows.push(
row![
progress_bar(0.0..=1.0, progress.clamp(0.0, 1.0))
.height(Length::Fixed(6.0))
.girth(Length::Fixed(6.0))
.style(task_progress_style),
text(format!("{:.0}%", progress * 100.0))
.size(10)
@@ -81,7 +81,7 @@ fn task_row(
if snapshot.is_cancellable {
rows.push(
row![
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
keyboard::button(text(t(locale, "tasks.cancelTask")).size(10))
.on_press(Message::CancelTask(snapshot.source, snapshot.id))
.padding([3, 8])
@@ -102,7 +102,7 @@ fn task_row(
.into();
if is_group_child {
row![Space::with_width(Length::Fixed(16.0)), card]
row![Space::new().width(Length::Fixed(16.0)), card]
.width(Length::Fill)
.into()
} else {
@@ -334,7 +334,7 @@ pub fn view(
tab_row.push(git_log_btn.into());
}
tab_row.push(Space::with_width(Length::Fill).into());
tab_row.push(Space::new().width(Length::Fill).into());
tab_row.push(close_btn.into());
let tab_header = iced::widget::Row::with_children(tab_row)
@@ -477,7 +477,7 @@ pub fn view(
}
}
items.push(Space::with_height(8.0).into());
items.push(Space::new().height(8.0).into());
items.push(
text(t(locale, "editor.backlinks"))
.size(12)
@@ -530,7 +530,7 @@ pub fn view(
row![
text(short).size(11).font(iced::Font::MONOSPACE),
text(subject.clone()).size(11),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
text(commit.date.clone().unwrap_or_default()).size(10),
]
.spacing(8),

View File

@@ -748,7 +748,7 @@ pub fn view<'a>(
&state.tags_input,
);
let semantic_tags: Element<'a, Message> = if semantic_suggestions.is_empty() {
Space::new(0, 0).into()
Space::new().into()
} else {
let mut chips = row![
text(t(locale, "editor.semanticTagSuggestions"))
@@ -776,7 +776,7 @@ pub fn view<'a>(
let matching_tags: Element<'a, Message> = if state.tags_input.trim().is_empty()
|| (matching_suggestions.is_empty() && !query_addable)
{
Space::new(0, 0).into()
Space::new().into()
} else {
let mut chips = row![
text(t(locale, "editor.matchingTags"))
@@ -822,7 +822,7 @@ pub fn view<'a>(
// Post links sections
let outlinks_section: Element<'a, Message> = if state.outlinks.is_empty() {
Space::new(0, 0).into()
Space::new().into()
} else {
let mut items: Vec<Element<'a, Message>> = vec![
text(t(locale, "editor.outlinks"))
@@ -844,7 +844,7 @@ pub fn view<'a>(
};
let backlinks_section: Element<'a, Message> = if state.backlinks.is_empty() {
Space::new(0, 0).into()
Space::new().into()
} else {
let mut items: Vec<Element<'a, Message>> = vec![
text(t(locale, "editor.backlinks"))
@@ -880,7 +880,7 @@ pub fn view<'a>(
.size(12)
.color(inputs::LABEL_COLOR)
.shaping(Shaping::Advanced),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
link_existing_button,
]
.align_y(iced::Alignment::Center)
@@ -977,7 +977,7 @@ pub fn view<'a>(
)
.into()
} else {
Space::new(0, 0).into()
Space::new().into()
};
// ── Collapsible Excerpt Section ──
@@ -1008,7 +1008,7 @@ pub fn view<'a>(
))
.into()
} else {
Space::new(0, 0).into()
Space::new().into()
};
// ── Content section (fills remaining space) ──
@@ -1034,7 +1034,7 @@ pub fn view<'a>(
vec![
row![
content_label,
Space::with_width(Length::Fixed(12.0)),
Space::new().width(Length::Fixed(12.0)),
mode_toggle
]
.align_y(iced::Alignment::Center)
@@ -1052,7 +1052,7 @@ pub fn view<'a>(
.style(inputs::secondary_button)
.into()
} else {
Space::new(0, 0).into()
Space::new().into()
},
if show_content_actions {
keyboard::button(
@@ -1065,7 +1065,7 @@ pub fn view<'a>(
.style(inputs::secondary_button)
.into()
} else {
Space::new(0, 0).into()
Space::new().into()
},
if show_content_actions {
keyboard::button(
@@ -1078,7 +1078,7 @@ pub fn view<'a>(
.style(inputs::secondary_button)
.into()
} else {
Space::new(0, 0).into()
Space::new().into()
},
],
);
@@ -1108,19 +1108,19 @@ pub fn view<'a>(
// ── Footer ──
let published_gap: Element<'a, Message> = if state.published_at.is_some() {
Space::with_width(Length::Fixed(24.0)).into()
Space::new().width(Length::Fixed(24.0)).into()
} else {
Space::new(0, 0).into()
Space::new().into()
};
let published_label: Element<'a, Message> = if let Some(published_at) = state.published_at {
inputs::date_label(&t(locale, "editor.publishedAt"), published_at)
} else {
Space::new(0, 0).into()
Space::new().into()
};
let footer = row![
inputs::date_label(&t(locale, "editor.createdAt"), state.created_at),
Space::with_width(Length::Fixed(24.0)),
Space::new().width(Length::Fixed(24.0)),
inputs::date_label(&t(locale, "editor.updatedAt"), state.updated_at),
published_gap,
published_label,

View File

@@ -134,7 +134,7 @@ pub fn view(
.spacing(6)
} else {
row![
Space::with_width(Length::Fixed(14.0)),
Space::new().width(Length::Fixed(14.0)),
text(name)
.size(12)
.shaping(Shaping::Advanced)
@@ -161,7 +161,7 @@ pub fn view(
// Separator
items.push(
container(Space::new(Length::Fill, Length::Fixed(1.0)))
container(Space::new().width(Length::Fill).height(Length::Fixed(1.0)))
.style(|_theme: &Theme| container::Style {
background: Some(Background::Color(Color::from_rgb(0.30, 0.30, 0.35))),
..container::Style::default()

View File

@@ -243,13 +243,13 @@ pub fn view<'a>(state: &'a ScriptEditorState, locale: UiLocale) -> Element<'a, M
.padding(8)
.into()
} else {
Space::new(0, 0).into()
Space::new().into()
};
// Footer
let footer = row![
inputs::date_label(&t(locale, "editor.createdAt"), state.created_at),
Space::with_width(Length::Fixed(24.0)),
Space::new().width(Length::Fixed(24.0)),
inputs::date_label(&t(locale, "editor.updatedAt"), state.updated_at),
]
.padding(8);

View File

@@ -936,7 +936,8 @@ fn section_mcp<'a>(state: &'a SettingsViewState, locale: UiLocale) -> Element<'a
};
let server = column![
keyboard::focusable(
iced::widget::checkbox(t(locale, "settings.mcpEnable"), state.mcp_enabled)
iced::widget::checkbox(state.mcp_enabled)
.label(t(locale, "settings.mcpEnable"))
.on_toggle(|value| Message::Settings(SettingsMsg::McpEnabledChanged(value))),
true,
),
@@ -1003,10 +1004,12 @@ fn section_mcp<'a>(state: &'a SettingsViewState, locale: UiLocale) -> Element<'a
let configured = agent.configured;
column![
keyboard::focusable(
iced::widget::checkbox(agent.label.clone(), configured).on_toggle({
let agent = agent.agent;
move |_| Message::Settings(SettingsMsg::McpAgentToggled(agent))
}),
iced::widget::checkbox(configured)
.label(agent.label.clone())
.on_toggle({
let agent = agent.agent;
move |_| Message::Settings(SettingsMsg::McpAgentToggled(agent))
}),
true,
),
text(agent.config_path.clone())

View File

@@ -516,7 +516,7 @@ fn post_filter_panel(
Message::SetPostStatusFilter,
locale,
));
sections.push(Space::with_height(4.0).into());
sections.push(Space::new().height(4.0).into());
if !filter.available_languages.is_empty() {
let languages = filter
@@ -531,7 +531,7 @@ fn post_filter_panel(
Message::SetPostLanguageFilter,
locale,
));
sections.push(Space::with_height(4.0).into());
sections.push(Space::new().height(4.0).into());
}
// Calendar archive
@@ -544,7 +544,7 @@ fn post_filter_panel(
Message::SetPostCalendarMonth,
locale,
));
sections.push(Space::with_height(4.0).into());
sections.push(Space::new().height(4.0).into());
}
// Tag chips
@@ -556,7 +556,7 @@ fn post_filter_panel(
Message::TogglePostTagFilter,
locale,
));
sections.push(Space::with_height(4.0).into());
sections.push(Space::new().height(4.0).into());
}
// Category chips (not shown for Pages since Pages IS a category filter)
@@ -568,7 +568,7 @@ fn post_filter_panel(
Message::TogglePostCategoryFilter,
locale,
));
sections.push(Space::with_height(4.0).into());
sections.push(Space::new().height(4.0).into());
}
sections.push(
@@ -596,7 +596,7 @@ fn post_filter_panel(
.spacing(2)
.into(),
);
sections.push(Space::with_height(4.0).into());
sections.push(Space::new().height(4.0).into());
// Clear all filters button
if filter.has_active_filters() {
@@ -631,7 +631,7 @@ fn media_filter_panel(filter: &MediaFilter, locale: UiLocale) -> Element<'static
Message::SetMediaCalendarMonth,
locale,
));
sections.push(Space::with_height(4.0).into());
sections.push(Space::new().height(4.0).into());
}
if !filter.available_tags.is_empty() {
@@ -642,7 +642,7 @@ fn media_filter_panel(filter: &MediaFilter, locale: UiLocale) -> Element<'static
Message::ToggleMediaTagFilter,
locale,
));
sections.push(Space::with_height(4.0).into());
sections.push(Space::new().height(4.0).into());
}
if filter.has_active_filters() {
@@ -712,7 +712,7 @@ pub fn view(
let header_row: Element<'static, Message> = if let Some(action) = create_action {
row![
header,
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
keyboard::button(
text(t(locale, "common.add"))
.size(11)
@@ -764,9 +764,9 @@ pub fn view(
// Filter panel (collapsible)
if filter.filter_panel_visible {
top_items.push(Space::with_height(4.0).into());
top_items.push(Space::new().height(4.0).into());
top_items.push(post_filter_panel(filter, is_pages, locale));
top_items.push(Space::with_height(4.0).into());
top_items.push(Space::new().height(4.0).into());
}
// Post list
@@ -848,7 +848,7 @@ pub fn view(
for p in &drafts {
top_items.push(make_post_item(p));
}
top_items.push(Space::with_height(6.0).into());
top_items.push(Space::new().height(6.0).into());
}
// Published section
@@ -861,7 +861,7 @@ pub fn view(
for p in &published {
top_items.push(make_post_item(p));
}
top_items.push(Space::with_height(6.0).into());
top_items.push(Space::new().height(6.0).into());
}
// Archived section
@@ -914,9 +914,9 @@ pub fn view(
// Filter panel (collapsible)
if filter.filter_panel_visible {
top_items.push(Space::with_height(4.0).into());
top_items.push(Space::new().height(4.0).into());
top_items.push(media_filter_panel(filter, locale));
top_items.push(Space::with_height(4.0).into());
top_items.push(Space::new().height(4.0).into());
}
if media.is_empty() {
@@ -1308,7 +1308,7 @@ pub fn view(
SidebarView::Git => crate::views::git::sidebar_view(git_state, offline_mode, locale),
};
let content = column![header_row, Space::with_height(8.0), body,]
let content = column![header_row, Space::new().height(8.0), body,]
.spacing(4)
.padding(12);

View File

@@ -176,7 +176,7 @@ pub fn view(
.color(label_color)
.into()
} else {
Space::with_width(0).into()
Space::new().width(0).into()
};
let left = row![project_trigger, task_indicator]
@@ -199,7 +199,7 @@ pub fn view(
.color(color)
.into()
} else {
Space::with_width(0).into()
Space::new().width(0).into()
};
// Post + media counts
@@ -226,7 +226,7 @@ pub fn view(
)
});
let chat_tokens_el: Element<'static, Message> = chat_token_label.map_or_else(
|| Space::with_width(0).into(),
|| Space::new().width(0).into(),
|label| {
text(label)
.size(11)
@@ -282,7 +282,7 @@ pub fn view(
.align_y(Alignment::Center);
container(
row![left, Space::with_width(Length::Fill), right,]
row![left, Space::new().width(Length::Fill), right,]
.align_y(Alignment::Center)
.padding([0, 8]),
)

View File

@@ -204,7 +204,7 @@ fn theme_accent_background(theme: &StyleTheme) -> Background {
}
fn swatch(background: Background, width_portion: u16) -> Element<'static, Message> {
container(Space::new(Length::Fill, Length::Fill))
container(Space::new().width(Length::Fill).height(Length::Fill))
.width(Length::FillPortion(width_portion))
.height(Length::Fixed(30.0))
.style(move |_: &Theme| container::Style {
@@ -270,7 +270,7 @@ pub fn view<'a>(
.map(|theme| theme_button(theme, &state.selected_theme))
.collect::<Vec<_>>();
while children.len() < 4 {
children.push(Space::with_width(Length::FillPortion(1)).into());
children.push(Space::new().width(Length::FillPortion(1)).into());
}
iced::widget::Row::with_children(children)
.spacing(8)

View File

@@ -125,7 +125,7 @@ fn build_tooltip_text(tab: &Tab, locale: UiLocale) -> String {
pub fn view(tabs: &[Tab], active_tab: Option<&str>, locale: UiLocale) -> Element<'static, Message> {
// Per tabs.allium: "Hidden when no tabs exist."
if tabs.is_empty() {
return Space::with_height(0).into();
return Space::new().height(0).into();
}
let tab_buttons: Vec<Element<'static, Message>> = tabs

View File

@@ -250,12 +250,14 @@ fn view_categories<'a>(state: &'a SettingsViewState, locale: UiLocale) -> Elemen
let name = category.name.clone();
cells.push(
container(keyboard::focusable(
checkbox("", category.render_in_lists).on_toggle(move |value| {
Message::Settings(SettingsMsg::CategoryRenderInListsChanged(
name.clone(),
value,
))
}),
checkbox(category.render_in_lists)
.label("")
.on_toggle(move |value| {
Message::Settings(SettingsMsg::CategoryRenderInListsChanged(
name.clone(),
value,
))
}),
true,
))
.width(Length::Fixed(TOGGLE_WIDTH))
@@ -264,9 +266,14 @@ fn view_categories<'a>(state: &'a SettingsViewState, locale: UiLocale) -> Elemen
let name = category.name.clone();
cells.push(
container(keyboard::focusable(
checkbox("", category.show_title).on_toggle(move |value| {
Message::Settings(SettingsMsg::CategoryShowTitleChanged(name.clone(), value))
}),
checkbox(category.show_title)
.label("")
.on_toggle(move |value| {
Message::Settings(SettingsMsg::CategoryShowTitleChanged(
name.clone(),
value,
))
}),
true,
))
.width(Length::Fixed(TOGGLE_WIDTH))
@@ -587,19 +594,21 @@ fn view_manage<'a>(state: &'a TagsViewState, locale: UiLocale) -> Element<'a, Me
.unwrap_or(0);
keyboard::button(
row![
container(Space::new(12, 12)).style(move |_: &Theme| container::Style {
background: Some(Background::Color(color)),
border: iced::Border {
radius: 6.0.into(),
..iced::Border::default()
},
..container::Style::default()
container(Space::new().width(12).height(12)).style(move |_: &Theme| {
container::Style {
background: Some(Background::Color(color)),
border: iced::Border {
radius: 6.0.into(),
..iced::Border::default()
},
..container::Style::default()
}
}),
text(&tag.name).size(14),
text(format!("({count})"))
.size(12)
.color(Color::from_rgb(0.55, 0.58, 0.65)),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
]
.spacing(8)
.align_y(Alignment::Center),
@@ -748,7 +757,7 @@ fn view_merge<'a>(state: &'a TagsViewState, locale: UiLocale) -> Element<'a, Mes
|choice| Message::Tags(TagsMsg::SetMergeTarget(choice)),
),
if merge_preview.is_empty() {
Element::from(Space::new(0, 0))
Element::from(Space::new())
} else {
container(
text(tw(locale, "tags.mergePreview", &[("tags", &merge_preview)])).size(12),
@@ -831,7 +840,7 @@ fn color_swatches<'a>(locale: UiLocale, create_mode: bool) -> Element<'a, Messag
} else {
TagsMsg::EditTagColor((*hex).to_string())
};
keyboard::button(Space::new(18, 18))
keyboard::button(Space::new().width(18).height(18))
.on_press(Message::Tags(msg))
.padding(0)
.style(move |_theme: &Theme, _status| button::Style {

View File

@@ -207,13 +207,13 @@ pub fn view<'a>(state: &'a TemplateEditorState, locale: UiLocale) -> Element<'a,
.padding(8)
.into()
} else {
Space::new(0, 0).into()
Space::new().into()
};
// Footer
let footer = row![
inputs::date_label(&t(locale, "editor.createdAt"), state.created_at),
Space::with_width(Length::Fixed(24.0)),
Space::new().width(Length::Fixed(24.0)),
inputs::date_label(&t(locale, "editor.updatedAt"), state.updated_at),
]
.padding(8);

View File

@@ -75,7 +75,7 @@ pub fn view(toasts: &[Toast]) -> Option<Element<'static, Message>> {
.size(12)
.shaping(Shaping::Advanced)
.color(Color::WHITE),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
dismiss,
]
.spacing(8)

View File

@@ -30,7 +30,7 @@ pub fn view<'a>(state: &'a TranslationValidationState, locale: UiLocale) -> Elem
.size(24)
.shaping(Shaping::Advanced)
.color(Color::from_rgb(0.88, 0.88, 0.92)),
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
run,
]
.align_y(iced::Alignment::Center),
@@ -77,7 +77,7 @@ fn issue_section<'a>(
locale: UiLocale,
) -> Element<'a, Message> {
if issues.is_empty() {
return Space::new(0, 0).into();
return Space::new().into();
}
let rows = issues.iter().fold(column!().spacing(6), |column, issue| {
let location = issue.file_path.as_deref().unwrap_or(issue.post_id.as_str());

View File

@@ -60,7 +60,7 @@ fn drag_handle_style(_theme: &Theme) -> container::Style {
/// Horizontal line separator (full width).
fn separator_h<'a>() -> Element<'a, Message> {
container(Space::new(0, 0))
container(Space::new())
.width(Length::Fill)
.height(Length::Fixed(1.0))
.style(|_theme: &Theme| container::Style {
@@ -245,7 +245,7 @@ pub fn view<'a>(
));
// Resize drag handle: 4px wide strip between sidebar and content
let handle = container(Space::new(0, 0))
let handle = container(Space::new())
.width(Length::Fixed(4.0))
.height(Length::Fill)
.style(drag_handle_style);
@@ -325,9 +325,9 @@ pub fn view<'a>(
Some(
container(
container(row![
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
dropdown_menu,
Space::with_width(Length::Fixed(40.0)),
Space::new().width(Length::Fixed(40.0)),
])
.width(Length::Fill)
.align_y(Alignment::End)
@@ -350,9 +350,9 @@ pub fn view<'a>(
Some(
container(
container(row![
Space::with_width(Length::Fixed(8.0)),
Space::new().width(Length::Fixed(8.0)),
dropdown,
Space::with_width(Length::Fill),
Space::new().width(Length::Fill),
])
.width(Length::Fill)
.align_y(Alignment::End)