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

1422
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -61,21 +61,21 @@ url = "2.5"
fastembed = { version = "5.17.3", default-features = false, features = ["hf-hub-rustls-tls", "ort-download-binaries-rustls-tls"] } fastembed = { version = "5.17.3", default-features = false, features = ["hf-hub-rustls-tls", "ort-download-binaries-rustls-tls"] }
usearch = "2.26" usearch = "2.26"
ort = { version = "=2.0.0-rc.12", default-features = false, features = ["std", "api-24", "coreml", "directml"] } ort = { version = "=2.0.0-rc.12", default-features = false, features = ["std", "api-24", "coreml", "directml"] }
russh = "0.62.2" russh = "0.62.5"
ratatui = "0.30.2" ratatui = "0.30.2"
ratatui-image = { version = "11.0.6", default-features = false, features = ["crossterm", "image-defaults"] } ratatui-image = { version = "11.0.6", default-features = false, features = ["crossterm", "image-defaults"] }
tui-markdown = { version = "0.3.8", default-features = false } tui-markdown = { version = "0.3.8", default-features = false }
# UI framework # UI framework
iced = { version = "0.13", features = ["wgpu", "advanced", "canvas", "image", "svg", "tokio", "markdown"] } iced = { version = "0.14", features = ["wgpu", "advanced", "canvas", "image", "svg", "tokio", "markdown"] }
# Editor widget # Editor widget
cosmic-text = "0.12" cosmic-text = "0.15"
ropey = "1" ropey = "1"
syntect = { version = "5", default-features = false, features = ["default-fancy"] } syntect = { version = "5", default-features = false, features = ["default-fancy"] }
# Platform integration (cross-platform) # Platform integration (cross-platform)
muda = "0.15" muda = "0.19.3"
rfd = "0.15" rfd = "0.15"
# Internal crates # Internal crates

View File

@@ -7,7 +7,6 @@ use iced::advanced::renderer;
use iced::advanced::text; use iced::advanced::text;
use iced::advanced::widget::{self, Widget}; use iced::advanced::widget::{self, Widget};
use iced::advanced::{Clipboard, Shell}; use iced::advanced::{Clipboard, Shell};
use iced::event::Status;
use iced::keyboard; use iced::keyboard;
use iced::mouse; use iced::mouse;
use iced::{Color, Element, Event, Length, Pixels, Point, Rectangle, Shadow, Size, Theme, Vector}; use iced::{Color, Element, Event, Length, Pixels, Point, Rectangle, Shadow, Size, Theme, Vector};
@@ -54,8 +53,9 @@ pub fn mono_metrics() -> &'static MonoMetrics {
buffer.set_text( buffer.set_text(
&mut font_system, &mut font_system,
"M", "M",
Attrs::new().family(Family::Monospace), &Attrs::new().family(Family::Monospace),
Shaping::Advanced, Shaping::Advanced,
None,
); );
buffer.shape_until_scroll(&mut font_system, false); buffer.shape_until_scroll(&mut font_system, false);
@@ -313,7 +313,7 @@ where
} }
fn layout( fn layout(
&self, &mut self,
_tree: &mut widget::Tree, _tree: &mut widget::Tree,
_renderer: &Renderer, _renderer: &Renderer,
limits: &layout::Limits, limits: &layout::Limits,
@@ -350,6 +350,7 @@ where
offset: Vector::new(0.0, 3.0), offset: Vector::new(0.0, 3.0),
blur_radius: 14.0, blur_radius: 14.0,
}, },
snap: true,
}, },
theme.palette().background, theme.palette().background,
); );
@@ -365,6 +366,7 @@ where
}, },
border: iced::Border::default(), border: iced::Border::default(),
shadow: iced::Shadow::default(), shadow: iced::Shadow::default(),
snap: true,
}, },
Color::from_rgb8(0x2B, 0x2B, 0x2B), Color::from_rgb8(0x2B, 0x2B, 0x2B),
); );
@@ -465,6 +467,7 @@ where
}, },
border: iced::Border::default(), border: iced::Border::default(),
shadow: iced::Shadow::default(), shadow: iced::Shadow::default(),
snap: true,
}, },
SELECTION_BG, SELECTION_BG,
); );
@@ -489,8 +492,8 @@ where
metrics.line_height, metrics.line_height,
)), )),
font, font,
horizontal_alignment: iced::alignment::Horizontal::Right, align_x: iced::alignment::Horizontal::Right.into(),
vertical_alignment: iced::alignment::Vertical::Top, align_y: iced::alignment::Vertical::Top,
shaping: iced::widget::text::Shaping::Basic, shaping: iced::widget::text::Shaping::Basic,
wrapping: iced::widget::text::Wrapping::None, wrapping: iced::widget::text::Wrapping::None,
}, },
@@ -546,8 +549,8 @@ where
metrics.line_height, metrics.line_height,
)), )),
font, font,
horizontal_alignment: iced::alignment::Horizontal::Left, align_x: iced::alignment::Horizontal::Left.into(),
vertical_alignment: iced::alignment::Vertical::Top, align_y: iced::alignment::Vertical::Top,
shaping: iced::widget::text::Shaping::Advanced, shaping: iced::widget::text::Shaping::Advanced,
wrapping: iced::widget::text::Wrapping::None, wrapping: iced::widget::text::Wrapping::None,
}, },
@@ -577,8 +580,8 @@ where
metrics.line_height, metrics.line_height,
)), )),
font, font,
horizontal_alignment: iced::alignment::Horizontal::Left, align_x: iced::alignment::Horizontal::Left.into(),
vertical_alignment: iced::alignment::Vertical::Top, align_y: iced::alignment::Vertical::Top,
shaping: iced::widget::text::Shaping::Advanced, shaping: iced::widget::text::Shaping::Advanced,
wrapping: iced::widget::text::Wrapping::None, wrapping: iced::widget::text::Wrapping::None,
}, },
@@ -603,6 +606,7 @@ where
}, },
border: iced::Border::default(), border: iced::Border::default(),
shadow: iced::Shadow::default(), shadow: iced::Shadow::default(),
snap: true,
}, },
CURSOR_COLOR, CURSOR_COLOR,
); );
@@ -622,6 +626,7 @@ where
}, },
border: iced::Border::default(), border: iced::Border::default(),
shadow: iced::Shadow::default(), shadow: iced::Shadow::default(),
snap: true,
}, },
CURSOR_COLOR, CURSOR_COLOR,
); );
@@ -656,6 +661,7 @@ where
}, },
border: iced::Border::default(), border: iced::Border::default(),
shadow: iced::Shadow::default(), shadow: iced::Shadow::default(),
snap: true,
}, },
SCROLLBAR_TRACK, SCROLLBAR_TRACK,
); );
@@ -674,6 +680,7 @@ where
..iced::Border::default() ..iced::Border::default()
}, },
shadow: iced::Shadow::default(), shadow: iced::Shadow::default(),
snap: true,
}, },
if is_hover { if is_hover {
SCROLLBAR_THUMB_HOVER SCROLLBAR_THUMB_HOVER
@@ -684,17 +691,17 @@ where
} }
} }
fn on_event( fn update(
&mut self, &mut self,
tree: &mut widget::Tree, tree: &mut widget::Tree,
event: Event, event: &Event,
layout: Layout<'_>, layout: Layout<'_>,
cursor: mouse::Cursor, cursor: mouse::Cursor,
_renderer: &Renderer, _renderer: &Renderer,
clipboard: &mut dyn Clipboard, clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>, shell: &mut Shell<'_, Message>,
_viewport: &Rectangle, _viewport: &Rectangle,
) -> Status { ) {
let state = tree.state.downcast_mut::<EditorState>(); let state = tree.state.downcast_mut::<EditorState>();
let bounds = layout.bounds(); let bounds = layout.bounds();
let metrics = mono_metrics(); let metrics = mono_metrics();
@@ -734,11 +741,13 @@ where
let new_scroll = (ratio * max_scroll as f32).round() as usize; let new_scroll = (ratio * max_scroll as f32).round() as usize;
self.buffer.borrow_mut().set_scroll(new_scroll, max_scroll); self.buffer.borrow_mut().set_scroll(new_scroll, max_scroll);
} }
return Status::Captured; shell.capture_event();
return;
} }
Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) => { Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) => {
state.scrollbar_drag = None; state.scrollbar_drag = None;
return Status::Captured; shell.capture_event();
return;
} }
_ => {} _ => {}
} }
@@ -771,7 +780,8 @@ where
state.scrollbar_drag = Some(thumb_height / 2.0); state.scrollbar_drag = Some(thumb_height / 2.0);
} }
state.is_focused = true; state.is_focused = true;
return Status::Captured; shell.capture_event();
return;
} }
} }
@@ -811,7 +821,8 @@ where
state.last_click_col = col; state.last_click_col = col;
} }
} }
return Status::Captured; shell.capture_event();
return;
} else { } else {
state.is_focused = false; state.is_focused = false;
} }
@@ -859,7 +870,8 @@ where
buf.set_selection(anchor_line, anchor_col, clamped_line, clamped_col); buf.set_selection(anchor_line, anchor_col, clamped_line, clamped_col);
buf.set_cursor(clamped_line, clamped_col); buf.set_cursor(clamped_line, clamped_col);
} }
return Status::Captured; shell.capture_event();
return;
} }
} }
Event::Mouse(mouse::Event::WheelScrolled { delta }) if cursor.is_over(bounds) => { Event::Mouse(mouse::Event::WheelScrolled { delta }) if cursor.is_over(bounds) => {
@@ -872,7 +884,8 @@ where
let total = total_visual_lines(&buf, cpl); let total = total_visual_lines(&buf, cpl);
let max_scroll = total.saturating_sub(vis); let max_scroll = total.saturating_sub(vis);
buf.scroll_by_clamped(lines, max_scroll); buf.scroll_by_clamped(lines, max_scroll);
return Status::Captured; shell.capture_event();
return;
} }
Event::Keyboard(keyboard::Event::KeyPressed { Event::Keyboard(keyboard::Event::KeyPressed {
key, key,
@@ -900,7 +913,7 @@ where
match key { match key {
// Cmd+Z = undo, Cmd+Shift+Z = redo // Cmd+Z = undo, Cmd+Shift+Z = redo
keyboard::Key::Character(ref c) if is_cmd && c.as_str() == "z" => { keyboard::Key::Character(c) if is_cmd && c.as_str() == "z" => {
{ {
let mut buf = self.buffer.borrow_mut(); let mut buf = self.buffer.borrow_mut();
if is_shift { if is_shift {
@@ -913,7 +926,7 @@ where
self.emit_change(shell); self.emit_change(shell);
} }
// Cmd+Y = redo (Windows convention) // Cmd+Y = redo (Windows convention)
keyboard::Key::Character(ref c) if is_cmd && c.as_str() == "y" => { keyboard::Key::Character(c) if is_cmd && c.as_str() == "y" => {
{ {
let mut buf = self.buffer.borrow_mut(); let mut buf = self.buffer.borrow_mut();
buf.redo(); buf.redo();
@@ -922,18 +935,18 @@ where
self.emit_change(shell); self.emit_change(shell);
} }
// Cmd+A = select all // Cmd+A = select all
keyboard::Key::Character(ref c) if is_cmd && c.as_str() == "a" => { keyboard::Key::Character(c) if is_cmd && c.as_str() == "a" => {
self.buffer.borrow_mut().select_all(); self.buffer.borrow_mut().select_all();
} }
// Cmd+C = copy // Cmd+C = copy
keyboard::Key::Character(ref c) if is_cmd && c.as_str() == "c" => { keyboard::Key::Character(c) if is_cmd && c.as_str() == "c" => {
let text = self.buffer.borrow().selected_text(); let text = self.buffer.borrow().selected_text();
if !text.is_empty() { if !text.is_empty() {
clipboard.write(iced::advanced::clipboard::Kind::Standard, text); clipboard.write(iced::advanced::clipboard::Kind::Standard, text);
} }
} }
// Cmd+X = cut // Cmd+X = cut
keyboard::Key::Character(ref c) if is_cmd && c.as_str() == "x" => { keyboard::Key::Character(c) if is_cmd && c.as_str() == "x" => {
let text = self.buffer.borrow().selected_text(); let text = self.buffer.borrow().selected_text();
if !text.is_empty() { if !text.is_empty() {
clipboard.write(iced::advanced::clipboard::Kind::Standard, text); clipboard.write(iced::advanced::clipboard::Kind::Standard, text);
@@ -942,7 +955,7 @@ where
} }
} }
// Cmd+V = paste // Cmd+V = paste
keyboard::Key::Character(ref c) if is_cmd && c.as_str() == "v" => { keyboard::Key::Character(c) if is_cmd && c.as_str() == "v" => {
if let Some(text) = if let Some(text) =
clipboard.read(iced::advanced::clipboard::Kind::Standard) clipboard.read(iced::advanced::clipboard::Kind::Standard)
{ {
@@ -954,7 +967,7 @@ where
} }
} }
// Cmd+S = save // Cmd+S = save
keyboard::Key::Character(ref c) if is_cmd && c.as_str() == "s" => { keyboard::Key::Character(c) if is_cmd && c.as_str() == "s" => {
if let Some(ref on_change) = self.on_change { if let Some(ref on_change) = self.on_change {
shell.publish((on_change)(EditorMessage::SaveRequested)); shell.publish((on_change)(EditorMessage::SaveRequested));
} }
@@ -1083,13 +1096,13 @@ where
} }
self.emit_change(shell); self.emit_change(shell);
} }
_ => return Status::Ignored, _ => return,
} }
return Status::Captured; shell.capture_event();
return;
} }
_ => {} _ => {}
} }
Status::Ignored
} }
} }

View File

@@ -21,7 +21,7 @@ anyhow = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }
uuid = { workspace = true } uuid = { workspace = true }
futures = { workspace = true } futures = { workspace = true }
wry = "0.55.1" wry = "0.56.0"
[target.'cfg(target_os = "macos")'.dependencies] [target.'cfg(target_os = "macos")'.dependencies]
objc2 = "0.6" objc2 = "0.6"

View File

@@ -1229,7 +1229,7 @@ impl BdsApp {
let init_task = Task::batch([ let init_task = Task::batch([
init_task, init_task,
Task::done(Message::InitMenuBar), 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::Save, false);
registry.set_enabled(MenuAction::PublishSelected, false); registry.set_enabled(MenuAction::PublishSelected, false);
@@ -1459,8 +1459,12 @@ impl BdsApp {
pub fn update(&mut self, message: Message) -> Task<Message> { pub fn update(&mut self, message: Message) -> Task<Message> {
match message { match message {
Message::KeyboardNavigation(navigation) => match navigation { Message::KeyboardNavigation(navigation) => match navigation {
crate::components::keyboard::Navigation::Next => iced::widget::focus_next(), crate::components::keyboard::Navigation::Next => {
crate::components::keyboard::Navigation::Previous => iced::widget::focus_previous(), iced::widget::operation::focus_next()
}
crate::components::keyboard::Navigation::Previous => {
iced::widget::operation::focus_previous()
}
}, },
Message::WindowCloseRequested => { Message::WindowCloseRequested => {
self.persist_project_ui_state(); self.persist_project_ui_state();
@@ -2639,7 +2643,7 @@ impl BdsApp {
} else if let Some(anchor) = url.strip_prefix("https://ruds.invalid/document#") { } else if let Some(anchor) = url.strip_prefix("https://ruds.invalid/document#") {
if let Some(offset) = self.documentation_state(kind).parsed.anchors.get(anchor) 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), crate::views::documentation::scroll_id(kind),
iced::widget::scrollable::RelativeOffset { x: 0.0, y: *offset }, iced::widget::scrollable::RelativeOffset { x: 0.0, y: *offset },
); );
@@ -10102,7 +10106,7 @@ impl BdsApp {
} }
let Some(window_id) = self.main_window_id else { 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 if let Some(preview) = &mut self.embedded_style_preview
&& should_start_embedded_preview_creation( && should_start_embedded_preview_creation(
@@ -10157,7 +10161,7 @@ impl BdsApp {
} }
let Some(window_id) = self.main_window_id else { 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 if let Some(preview) = &mut self.embedded_preview
@@ -14551,7 +14555,7 @@ mod tests {
app.settings_state app.settings_state
.as_ref() .as_ref()
.map(|state| state.project_description.text()), .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), text: Color::from_rgb8(0xCC, 0xCC, 0xCC),
primary: PRIMARY_BG, primary: PRIMARY_BG,
success: Color::from_rgb8(0x2E, 0x7D, 0x32), success: Color::from_rgb8(0x2E, 0x7D, 0x32),
warning: Color::from_rgb8(0xC9, 0x8A, 0x20),
danger: DANGER_BG, danger: DANGER_BG,
}, },
) )
@@ -67,12 +68,12 @@ pub fn compact_scrollbar() -> scrollable::Scrollbar {
} }
/// Muted overlay-like scrollbar chrome that gains contrast only while interacting. /// 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 { let rail = |opacity| scrollable::Rail {
background: None, background: None,
border: Border::default(), border: Border::default(),
scroller: scrollable::Scroller { 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 { border: Border {
radius: 999.0.into(), radius: 999.0.into(),
..Border::default() ..Border::default()
@@ -80,10 +81,11 @@ pub fn scrollable_style(_theme: &Theme, status: scrollable::Status) -> scrollabl
}, },
}; };
let (horizontal_opacity, vertical_opacity) = match status { let (horizontal_opacity, vertical_opacity) = match status {
scrollable::Status::Active => (0.24, 0.24), scrollable::Status::Active { .. } => (0.24, 0.24),
scrollable::Status::Hovered { scrollable::Status::Hovered {
is_horizontal_scrollbar_hovered, is_horizontal_scrollbar_hovered,
is_vertical_scrollbar_hovered, is_vertical_scrollbar_hovered,
..
} => ( } => (
if is_horizontal_scrollbar_hovered { if is_horizontal_scrollbar_hovered {
0.55 0.55
@@ -99,6 +101,7 @@ pub fn scrollable_style(_theme: &Theme, status: scrollable::Status) -> scrollabl
scrollable::Status::Dragged { scrollable::Status::Dragged {
is_horizontal_scrollbar_dragged, is_horizontal_scrollbar_dragged,
is_vertical_scrollbar_dragged, is_vertical_scrollbar_dragged,
..
} => ( } => (
if is_horizontal_scrollbar_dragged { if is_horizontal_scrollbar_dragged {
0.75 0.75
@@ -117,12 +120,13 @@ pub fn scrollable_style(_theme: &Theme, status: scrollable::Status) -> scrollabl
vertical_rail: rail(vertical_opacity), vertical_rail: rail(vertical_opacity),
horizontal_rail: rail(horizontal_opacity), horizontal_rail: rail(horizontal_opacity),
gap: None, gap: None,
auto_scroll: scrollable::default(theme, status).auto_scroll,
} }
} }
pub fn field_style(_theme: &Theme, status: text_input::Status) -> text_input::Style { pub fn field_style(_theme: &Theme, status: text_input::Status) -> text_input::Style {
let border_color = match status { 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), text_input::Status::Hovered => Color::from_rgb8(0x5A, 0x5A, 0x5A),
_ => BORDER_COLOR, _ => 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. /// Multi-line editor style matching the standard form fields.
pub fn text_editor_style(_theme: &Theme, status: text_editor::Status) -> text_editor::Style { pub fn text_editor_style(_theme: &Theme, status: text_editor::Status) -> text_editor::Style {
let border_color = match status { 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), text_editor::Status::Hovered => Color::from_rgb8(0x5A, 0x5A, 0x5A),
_ => BORDER_COLOR, _ => BORDER_COLOR,
}; };
@@ -154,7 +158,6 @@ pub fn text_editor_style(_theme: &Theme, status: text_editor::Status) -> text_ed
width: 1.0, width: 1.0,
radius: 6.0.into(), radius: 6.0.into(),
}, },
icon: SECTION_COLOR,
placeholder: Color::from_rgb8(0x7D, 0x7D, 0x7D), placeholder: Color::from_rgb8(0x7D, 0x7D, 0x7D),
value: Color::from_rgb8(0xE4, 0xE4, 0xE4), value: Color::from_rgb8(0xE4, 0xE4, 0xE4),
selection: Color::from_rgba8(0x26, 0x4F, 0x78, 0.8), 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 { pub(crate) fn select_style(_theme: &Theme, status: pick_list::Status) -> pick_list::Style {
let border_color = match status { 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::Status::Active => BORDER_COLOR,
}; };
pick_list::Style { pick_list::Style {
@@ -265,7 +268,8 @@ pub fn labeled_checkbox<'a, Message: Clone + 'a>(
on_toggle: impl Fn(bool) -> Message + 'a, on_toggle: impl Fn(bool) -> Message + 'a,
) -> Element<'a, Message> { ) -> Element<'a, Message> {
keyboard::focusable( keyboard::focusable(
checkbox(label, is_checked) checkbox(is_checked)
.label(label.to_string())
.on_toggle(on_toggle) .on_toggle(on_toggle)
.size(16) .size(16)
.text_size(14), .text_size(14),
@@ -476,7 +480,7 @@ mod tests {
); );
assert_ne!( assert_ne!(
field_style(&theme, text_input::Status::Active).border.color, 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 .border
.color .color
); );
@@ -484,7 +488,7 @@ mod tests {
text_editor_style(&theme, text_editor::Status::Active) text_editor_style(&theme, text_editor::Status::Active)
.border .border
.color, .color,
text_editor_style(&theme, text_editor::Status::Focused) text_editor_style(&theme, text_editor::Status::Focused { is_hovered: false },)
.border .border
.color .color
); );
@@ -511,16 +515,30 @@ mod tests {
.scroller_width(3) .scroller_width(3)
); );
let theme = app_theme(); 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( let hovered = scrollable_style(
&theme, &theme,
scrollable::Status::Hovered { scrollable::Status::Hovered {
is_horizontal_scrollbar_hovered: false, is_horizontal_scrollbar_hovered: false,
is_vertical_scrollbar_hovered: true, 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.background.is_none());
assert!(active.vertical_rail.scroller.color.a < 0.5); let Background::Color(active_color) = active.vertical_rail.scroller.background else {
assert!(hovered.vertical_rail.scroller.color.a > active.vertical_rail.scroller.color.a); 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() ..State::default()
}; };
let mut inventory = AccessKeyInventory::default(); let mut inventory = AccessKeyInventory::default();
inventory.custom(&mut visible, None); inventory.custom(None, Rectangle::default(), &mut visible);
inventory.custom(&mut offscreen, None); inventory.custom(None, Rectangle::default(), &mut offscreen);
inventory.custom(&mut disabled, None); inventory.custom(None, Rectangle::default(), &mut disabled);
assert_eq!(inventory.control_count, 1); assert_eq!(inventory.control_count, 1);
assert_eq!(inventory.generic_count, 1); assert_eq!(inventory.generic_count, 1);
} }
@@ -115,8 +115,8 @@ mod tests {
count: 0, count: 0,
exact: None, exact: None,
}; };
prefix.custom(&mut first, None); prefix.custom(None, Rectangle::default(), &mut first);
prefix.custom(&mut second, None); prefix.custom(None, Rectangle::default(), &mut second);
assert_eq!(prefix.count, 2); assert_eq!(prefix.count, 2);
assert_eq!(prefix.exact, None); assert_eq!(prefix.exact, None);
@@ -125,8 +125,8 @@ mod tests {
count: 0, count: 0,
exact: None, exact: None,
}; };
complete.custom(&mut first, None); complete.custom(None, Rectangle::default(), &mut first);
complete.custom(&mut second, None); complete.custom(None, Rectangle::default(), &mut second);
assert_eq!(complete.count, 1); assert_eq!(complete.count, 1);
assert_eq!(complete.exact.as_deref(), Some("AA")); 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)] #[derive(Default)]
struct AccessKeyInventory { struct AccessKeyInventory {
generic_count: usize, generic_count: usize,
@@ -295,16 +288,11 @@ struct AccessKeyInventory {
} }
impl Operation for AccessKeyInventory { impl Operation for AccessKeyInventory {
fn container( fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation)) {
&mut self, operate(self);
_id: Option<&Id>,
_bounds: Rectangle,
operate_on_children: &mut dyn FnMut(&mut dyn Operation),
) {
visit_children(self, operate_on_children);
} }
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 { let Some(state) = state.downcast_ref::<State>() else {
return; return;
}; };
@@ -327,16 +315,11 @@ struct AssignAccessKeys {
} }
impl Operation for AssignAccessKeys { impl Operation for AssignAccessKeys {
fn container( fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation)) {
&mut self, operate(self);
_id: Option<&Id>,
_bounds: Rectangle,
operate_on_children: &mut dyn FnMut(&mut dyn Operation),
) {
visit_children(self, operate_on_children);
} }
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 { let Some(state) = state.downcast_mut::<State>() else {
return; return;
}; };
@@ -359,16 +342,11 @@ struct SetAccessPrefix<'a> {
} }
impl Operation for SetAccessPrefix<'_> { impl Operation for SetAccessPrefix<'_> {
fn container( fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation)) {
&mut self, operate(self);
_id: Option<&Id>,
_bounds: Rectangle,
operate_on_children: &mut dyn FnMut(&mut dyn Operation),
) {
visit_children(self, operate_on_children);
} }
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>() if let Some(state) = state.downcast_mut::<State>()
&& state.access_mode && state.access_mode
{ {
@@ -381,16 +359,11 @@ impl Operation for SetAccessPrefix<'_> {
struct CancelAccessKeys; struct CancelAccessKeys;
impl Operation for CancelAccessKeys { impl Operation for CancelAccessKeys {
fn container( fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation)) {
&mut self, operate(self);
_id: Option<&Id>,
_bounds: Rectangle,
operate_on_children: &mut dyn FnMut(&mut dyn Operation),
) {
visit_children(self, operate_on_children);
} }
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>() { if let Some(state) = state.downcast_mut::<State>() {
state.access_mode = false; state.access_mode = false;
state.prefix.clear(); state.prefix.clear();
@@ -405,16 +378,11 @@ struct AccessKeyMatches<'a> {
} }
impl Operation for AccessKeyMatches<'_> { impl Operation for AccessKeyMatches<'_> {
fn container( fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation)) {
&mut self, operate(self);
_id: Option<&Id>,
_bounds: Rectangle,
operate_on_children: &mut dyn FnMut(&mut dyn Operation),
) {
visit_children(self, operate_on_children);
} }
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 { let Some(state) = state.downcast_ref::<State>() else {
return; return;
}; };
@@ -439,16 +407,11 @@ struct FocusAccessKey<'a> {
} }
impl Operation for FocusAccessKey<'_> { impl Operation for FocusAccessKey<'_> {
fn container( fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation)) {
&mut self, operate(self);
_id: Option<&Id>,
_bounds: Rectangle,
operate_on_children: &mut dyn FnMut(&mut dyn Operation),
) {
visit_children(self, operate_on_children);
} }
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 { let Some(state) = state.downcast_mut::<State>() else {
self.next_is_target = false; self.next_is_target = false;
return; return;
@@ -457,7 +420,7 @@ impl Operation for FocusAccessKey<'_> {
state.pending_activation = self.next_is_target; 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 { if self.next_is_target {
state.focus(); state.focus();
} else { } else {
@@ -474,20 +437,15 @@ struct FocusedEditable {
} }
impl Operation for FocusedEditable { impl Operation for FocusedEditable {
fn container( fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation)) {
&mut self, operate(self);
_id: Option<&Id>,
_bounds: Rectangle,
operate_on_children: &mut dyn FnMut(&mut dyn Operation),
) {
visit_children(self, operate_on_children);
} }
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>(); 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.found |= state.is_focused() && !self.next_is_control;
self.next_is_control = false; 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::ButtonPressed(mouse::Button::Left)),
Event::Mouse(mouse::Event::ButtonReleased(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], &mut tree.children[0],
event, &event,
layout, layout,
cursor, cursor,
renderer, renderer,
@@ -574,18 +532,18 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for FocusableControl<'_, Me
} }
fn layout( fn layout(
&self, &mut self,
tree: &mut Tree, tree: &mut Tree,
renderer: &iced::Renderer, renderer: &iced::Renderer,
limits: &layout::Limits, limits: &layout::Limits,
) -> layout::Node { ) -> layout::Node {
self.content self.content
.as_widget() .as_widget_mut()
.layout(&mut tree.children[0], renderer, limits) .layout(&mut tree.children[0], renderer, limits)
} }
fn operate( fn operate(
&self, &mut self,
tree: &mut Tree, tree: &mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &iced::Renderer, renderer: &iced::Renderer,
@@ -594,30 +552,34 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for FocusableControl<'_, Me
let state = tree.state.downcast_mut::<State>(); let state = tree.state.downcast_mut::<State>();
state.enabled = self.enabled; state.enabled = self.enabled;
state.direct_key = self.hotkey; state.direct_key = self.hotkey;
operation.custom(state, None); operation.custom(None, layout.bounds(), state);
if self.enabled { if self.enabled {
operation.focusable(state, None); operation.focusable(None, layout.bounds(), state);
} else { } else {
state.unfocus(); state.unfocus();
} }
operation.container(None, layout.bounds(), &mut |operation| { operation.container(None, layout.bounds());
self.content operation.traverse(&mut |operation| {
.as_widget() self.content.as_widget_mut().operate(
.operate(&mut tree.children[0], layout, renderer, operation); &mut tree.children[0],
layout,
renderer,
operation,
);
}); });
} }
fn on_event( fn update(
&mut self, &mut self,
tree: &mut Tree, tree: &mut Tree,
event: Event, event: &Event,
layout: Layout<'_>, layout: Layout<'_>,
cursor: mouse::Cursor, cursor: mouse::Cursor,
renderer: &iced::Renderer, renderer: &iced::Renderer,
clipboard: &mut dyn Clipboard, clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>, shell: &mut Shell<'_, Message>,
viewport: &Rectangle, viewport: &Rectangle,
) -> event::Status { ) {
let pending_activation = { let pending_activation = {
let state = tree.state.downcast_mut::<State>(); let state = tree.state.downcast_mut::<State>();
let pending = state.pending_activation; let pending = state.pending_activation;
@@ -626,11 +588,12 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for FocusableControl<'_, Me
}; };
if pending_activation && self.enabled { if pending_activation && self.enabled {
self.activate(tree, layout, renderer, clipboard, shell, viewport); 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], &mut tree.children[0],
event.clone(), event,
layout, layout,
cursor, cursor,
renderer, renderer,
@@ -639,8 +602,8 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for FocusableControl<'_, Me
viewport, viewport,
); );
let state = tree.state.downcast_mut::<State>(); let state = tree.state.downcast_mut::<State>();
if child_status == event::Status::Captured || !self.enabled { if shell.is_event_captured() || !self.enabled {
return child_status; return;
} }
let activate = state.focused let activate = state.focused
&& matches!( && matches!(
@@ -652,9 +615,7 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for FocusableControl<'_, Me
); );
if activate { if activate {
self.activate(tree, layout, renderer, clipboard, shell, viewport); self.activate(tree, layout, renderer, clipboard, shell, viewport);
event::Status::Captured shell.capture_event();
} else {
child_status
} }
} }
@@ -743,8 +704,8 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for FocusableControl<'_, Me
size: Pixels(9.0), size: Pixels(9.0),
line_height: text::LineHeight::Relative(1.0), line_height: text::LineHeight::Relative(1.0),
bounds: badge.size(), bounds: badge.size(),
horizontal_alignment: alignment::Horizontal::Center, align_x: alignment::Horizontal::Center.into(),
vertical_alignment: alignment::Vertical::Center, align_y: alignment::Vertical::Center,
shaping: text::Shaping::Advanced, shaping: text::Shaping::Advanced,
wrapping: text::Wrapping::None, wrapping: text::Wrapping::None,
}, },
@@ -758,13 +719,18 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for FocusableControl<'_, Me
fn overlay<'b>( fn overlay<'b>(
&'b mut self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'b>,
renderer: &iced::Renderer, renderer: &iced::Renderer,
viewport: &Rectangle,
translation: Vector, translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, iced::Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, iced::Renderer>> {
self.content self.content.as_widget_mut().overlay(
.as_widget_mut() &mut tree.children[0],
.overlay(&mut tree.children[0], layout, renderer, translation) layout,
renderer,
viewport,
translation,
)
} }
} }
@@ -802,18 +768,18 @@ impl<'a, Message> AccessKeyScope<'a, Message> {
} }
fn operate( fn operate(
&self, &mut self,
tree: &mut Tree, tree: &mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &iced::Renderer, renderer: &iced::Renderer,
operation: &mut dyn Operation, operation: &mut dyn Operation,
) { ) {
self.content self.content
.as_widget() .as_widget_mut()
.operate(&mut tree.children[0], layout, renderer, operation); .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(); let mut focused_editable = FocusedEditable::default();
self.operate(tree, layout, renderer, &mut focused_editable); self.operate(tree, layout, renderer, &mut focused_editable);
if focused_editable.found { if focused_editable.found {
@@ -834,7 +800,7 @@ impl<'a, Message> AccessKeyScope<'a, Message> {
true 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); self.operate(tree, layout, renderer, &mut CancelAccessKeys);
} }
} }
@@ -861,41 +827,45 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for AccessKeyScope<'_, Mess
} }
fn layout( fn layout(
&self, &mut self,
tree: &mut Tree, tree: &mut Tree,
renderer: &iced::Renderer, renderer: &iced::Renderer,
limits: &layout::Limits, limits: &layout::Limits,
) -> layout::Node { ) -> layout::Node {
self.content self.content
.as_widget() .as_widget_mut()
.layout(&mut tree.children[0], renderer, limits) .layout(&mut tree.children[0], renderer, limits)
} }
fn operate( fn operate(
&self, &mut self,
tree: &mut Tree, tree: &mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &iced::Renderer, renderer: &iced::Renderer,
operation: &mut dyn Operation, operation: &mut dyn Operation,
) { ) {
operation.container(None, layout.bounds(), &mut |operation| { operation.container(None, layout.bounds());
self.content operation.traverse(&mut |operation| {
.as_widget() self.content.as_widget_mut().operate(
.operate(&mut tree.children[0], layout, renderer, operation); &mut tree.children[0],
layout,
renderer,
operation,
);
}); });
} }
fn on_event( fn update(
&mut self, &mut self,
tree: &mut Tree, tree: &mut Tree,
event: Event, event: &Event,
layout: Layout<'_>, layout: Layout<'_>,
cursor: mouse::Cursor, cursor: mouse::Cursor,
renderer: &iced::Renderer, renderer: &iced::Renderer,
clipboard: &mut dyn Clipboard, clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>, shell: &mut Shell<'_, Message>,
viewport: &Rectangle, viewport: &Rectangle,
) -> event::Status { ) {
let modifier_update = match &event { let modifier_update = match &event {
Event::Keyboard(keyboard::Event::ModifiersChanged(modifiers)) Event::Keyboard(keyboard::Event::ModifiersChanged(modifiers))
| Event::Keyboard(keyboard::Event::KeyPressed { 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.active = false;
state.prefix.clear(); state.prefix.clear();
state.cancelled_until_modifiers_release = true; state.cancelled_until_modifiers_release = true;
return event::Status::Captured; shell.capture_event();
return;
} }
if let Event::Keyboard(keyboard::Event::KeyPressed { key, modifiers, .. }) = &event 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 { if cancelled {
return event::Status::Captured; shell.capture_event();
return;
} }
if !active { if !active {
active = self.begin(tree, layout, renderer); active = self.begin(tree, layout, renderer);
if !active { if !active {
return self.content.as_widget_mut().on_event( self.content.as_widget_mut().update(
&mut tree.children[0], &mut tree.children[0],
event, event,
layout, layout,
@@ -970,6 +942,7 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for AccessKeyScope<'_, Mess
shell, shell,
viewport, viewport,
); );
return;
} }
let state = tree.state.downcast_mut::<AccessKeyScopeState>(); let state = tree.state.downcast_mut::<AccessKeyScopeState>();
state.active = true; state.active = true;
@@ -987,7 +960,8 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for AccessKeyScope<'_, Mess
let exact = matches.exact.take(); let exact = matches.exact.take();
drop(matches); drop(matches);
if count == 0 { if count == 0 {
return event::Status::Captured; shell.capture_event();
return;
} }
self.operate( self.operate(
@@ -1008,7 +982,7 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for AccessKeyScope<'_, Mess
next_is_target: false, next_is_target: false,
}, },
); );
let _ = self.content.as_widget_mut().on_event( self.content.as_widget_mut().update(
&mut tree.children[0], &mut tree.children[0],
event, event,
layout, layout,
@@ -1024,7 +998,8 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for AccessKeyScope<'_, Mess
state.prefix.clear(); state.prefix.clear();
state.cancelled_until_modifiers_release = true; state.cancelled_until_modifiers_release = true;
} }
return event::Status::Captured; shell.capture_event();
return;
} }
if matches!(event, Event::Mouse(mouse::Event::ButtonPressed(_))) 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(); state.prefix.clear();
} }
self.content.as_widget_mut().on_event( self.content.as_widget_mut().update(
&mut tree.children[0], &mut tree.children[0],
event, event,
layout, layout,
@@ -1045,7 +1020,7 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for AccessKeyScope<'_, Mess
clipboard, clipboard,
shell, shell,
viewport, viewport,
) );
} }
fn mouse_interaction( fn mouse_interaction(
@@ -1089,13 +1064,18 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for AccessKeyScope<'_, Mess
fn overlay<'b>( fn overlay<'b>(
&'b mut self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'b>,
renderer: &iced::Renderer, renderer: &iced::Renderer,
viewport: &Rectangle,
translation: Vector, translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, iced::Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, iced::Renderer>> {
self.content self.content.as_widget_mut().overlay(
.as_widget_mut() &mut tree.children[0],
.overlay(&mut tree.children[0], layout, renderer, translation) layout,
renderer,
viewport,
translation,
)
} }
} }
@@ -1130,18 +1110,18 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for SuspendedKeyboard<'_, M
} }
fn layout( fn layout(
&self, &mut self,
tree: &mut Tree, tree: &mut Tree,
renderer: &iced::Renderer, renderer: &iced::Renderer,
limits: &layout::Limits, limits: &layout::Limits,
) -> layout::Node { ) -> layout::Node {
self.content self.content
.as_widget() .as_widget_mut()
.layout(&mut tree.children[0], renderer, limits) .layout(&mut tree.children[0], renderer, limits)
} }
fn operate( fn operate(
&self, &mut self,
_tree: &mut Tree, _tree: &mut Tree,
_layout: Layout<'_>, _layout: Layout<'_>,
_renderer: &iced::Renderer, _renderer: &iced::Renderer,
@@ -1149,21 +1129,21 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for SuspendedKeyboard<'_, M
) { ) {
} }
fn on_event( fn update(
&mut self, &mut self,
tree: &mut Tree, tree: &mut Tree,
event: Event, event: &Event,
layout: Layout<'_>, layout: Layout<'_>,
cursor: mouse::Cursor, cursor: mouse::Cursor,
renderer: &iced::Renderer, renderer: &iced::Renderer,
clipboard: &mut dyn Clipboard, clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>, shell: &mut Shell<'_, Message>,
viewport: &Rectangle, viewport: &Rectangle,
) -> event::Status { ) {
if matches!(event, Event::Keyboard(_)) { if matches!(event, Event::Keyboard(_)) {
event::Status::Captured shell.capture_event();
} else { } else {
self.content.as_widget_mut().on_event( self.content.as_widget_mut().update(
&mut tree.children[0], &mut tree.children[0],
event, event,
layout, layout,
@@ -1172,7 +1152,7 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for SuspendedKeyboard<'_, M
clipboard, clipboard,
shell, shell,
viewport, viewport,
) );
} }
} }
@@ -1217,13 +1197,18 @@ impl<Message> Widget<Message, Theme, iced::Renderer> for SuspendedKeyboard<'_, M
fn overlay<'b>( fn overlay<'b>(
&'b mut self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'b>,
renderer: &iced::Renderer, renderer: &iced::Renderer,
viewport: &Rectangle,
translation: Vector, translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, iced::Renderer>> { ) -> Option<overlay::Element<'b, Message, Theme, iced::Renderer>> {
self.content self.content.as_widget_mut().overlay(
.as_widget_mut() &mut tree.children[0],
.overlay(&mut tree.children[0], layout, renderer, translation) layout,
renderer,
viewport,
translation,
)
} }
} }

View File

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

View File

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

View File

@@ -7,7 +7,6 @@ use iced::advanced::layout::{self, Node};
use iced::advanced::renderer; use iced::advanced::renderer;
use iced::advanced::widget::Tree; use iced::advanced::widget::Tree;
use iced::advanced::{Clipboard, Layout, Shell, Widget}; use iced::advanced::{Clipboard, Layout, Shell, Widget};
use iced::event;
use iced::mouse; use iced::mouse;
use iced::{Element, Event, Length, Rectangle, Size, Task, window}; use iced::{Element, Event, Length, Rectangle, Size, Task, window};
use wry::dpi::{LogicalPosition, LogicalSize}; use wry::dpi::{LogicalPosition, LogicalSize};
@@ -120,7 +119,7 @@ impl WebViewController {
let transparent = self.config.transparent; let transparent = self.config.transparent;
let devtools = self.config.devtools; 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) build_webview(id, handle, content, transparent, devtools)
}) })
.map(on_result) .map(on_result)
@@ -165,11 +164,12 @@ impl WebViewController {
fn build_webview( fn build_webview(
id: u64, id: u64,
handle: window::raw_window_handle::WindowHandle<'_>, handle: &dyn window::Window,
content: Content, content: Content,
transparent: bool, transparent: bool,
devtools: bool, devtools: bool,
) -> Result<(), String> { ) -> Result<(), String> {
let handle = handle.window_handle().map_err(|error| error.to_string())?;
let mut builder = WebViewBuilder::new() let mut builder = WebViewBuilder::new()
.with_transparent(transparent) .with_transparent(transparent)
.with_devtools(devtools) .with_devtools(devtools)
@@ -251,7 +251,7 @@ where
Size::new(self.width, self.height) 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)) Node::new(limits.resolve(self.width, self.height, Size::ZERO))
} }
@@ -267,19 +267,19 @@ where
) { ) {
} }
fn on_event( fn update(
&mut self, &mut self,
tree: &mut Tree, tree: &mut Tree,
event: Event, event: &Event,
layout: Layout<'_>, layout: Layout<'_>,
cursor: mouse::Cursor, cursor: mouse::Cursor,
_renderer: &Renderer, _renderer: &Renderer,
_clipboard: &mut dyn Clipboard, _clipboard: &mut dyn Clipboard,
_shell: &mut Shell<'_, Message>, _shell: &mut Shell<'_, Message>,
_viewport: &Rectangle, _viewport: &Rectangle,
) -> event::Status { ) {
let Some(tx) = &self.bounds_tx else { let Some(tx) = &self.bounds_tx else {
return event::Status::Ignored; return;
}; };
let state = tree.state.downcast_mut::<PlaceholderState>(); let state = tree.state.downcast_mut::<PlaceholderState>();
@@ -295,8 +295,6 @@ where
{ {
tx.refocus_parent(); 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) iced::window::icon::from_file_data(include_bytes!("../assets/app-icons/bds.png"), None)
.expect("bundled application icon must be valid"); .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) .subscription(BdsApp::subscription)
.theme(|_| inputs::app_theme()) .theme(app_theme)
.window(desktop_window_settings(Some(icon))) .window(desktop_window_settings(Some(icon)))
.run_with(BdsApp::new)?; .run()?;
Ok(()) Ok(())
} }
fn app_theme(_: &BdsApp) -> iced::Theme {
inputs::app_theme()
}
fn desktop_window_settings(icon: Option<iced::window::Icon>) -> iced::window::Settings { fn desktop_window_settings(icon: Option<iced::window::Icon>) -> iced::window::Settings {
iced::window::Settings { iced::window::Settings {
size: iced::Size::new(1200.0, 800.0), size: iced::Size::new(1200.0, 800.0),

View File

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

View File

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

View File

@@ -60,7 +60,7 @@ fn surface_view<'a>(
&format!("chat.surface.type.{}", surface.kind.as_str()), &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) .spacing(8)
.align_y(Alignment::Center); .align_y(Alignment::Center);
if has_title { if has_title {
@@ -196,7 +196,8 @@ fn form<'a>(
let key = field.key.clone(); let key = field.key.clone();
let control: Element<'a, Message> = match field.input_type { let control: Element<'a, Message> = match field.input_type {
FormInputType::Checkbox => keyboard::focusable( 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 { .on_toggle(move |value| Message::ChatSurfaceFieldChanged {
surface_id: surface_id.clone(), surface_id: surface_id.clone(),
field: key.clone(), field: key.clone(),
@@ -355,7 +356,7 @@ fn mindmap<'a>(surface: &'a InlineSurface, locale: UiLocale) -> Element<'a, Mess
rows.into_iter() rows.into_iter()
.map(|(depth, label)| { .map(|(depth, label)| {
row![ 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 { "" }) text(if depth == 0 { "" } else { "" })
.size(11) .size(11)
.color(inputs::SECTION_COLOR), .color(inputs::SECTION_COLOR),

View File

@@ -390,7 +390,7 @@ pub fn view<'a>(
text(t(locale, "chat.input.hint")) text(t(locale, "chat.input.hint"))
.size(11) .size(11)
.color(inputs::SECTION_COLOR), .color(inputs::SECTION_COLOR),
Space::with_width(Length::Fill), Space::new().width(Length::Fill),
send_button, send_button,
] ]
.align_y(Alignment::Center), .align_y(Alignment::Center),
@@ -442,8 +442,9 @@ fn message_view<'a>(
let body: Element<'a, Message> = if let Some(items) = rendered_markdown { let body: Element<'a, Message> = if let Some(items) = rendered_markdown {
markdown::view( markdown::view(
items, items,
markdown::Settings::default(), markdown::Settings::with_style(markdown::Style::from_palette(
markdown::Style::from_palette(crate::components::inputs::app_theme().palette()), crate::components::inputs::app_theme().palette(),
)),
) )
.map(|url| Message::ChatLinkClicked(url.to_string())) .map(|url| Message::ChatLinkClicked(url.to_string()))
} else { } else {
@@ -500,8 +501,9 @@ fn tool_markers_view<'a>(
fn assistant_card<'a>(items: &'a [markdown::Item], label: String) -> Element<'a, Message> { fn assistant_card<'a>(items: &'a [markdown::Item], label: String) -> Element<'a, Message> {
let body = markdown::view( let body = markdown::view(
items, items,
markdown::Settings::default(), markdown::Settings::with_style(markdown::Style::from_palette(
markdown::Style::from_palette(crate::components::inputs::app_theme().palette()), crate::components::inputs::app_theme().palette(),
)),
) )
.map(|url| Message::ChatLinkClicked(url.to_string())); .map(|url| Message::ChatLinkClicked(url.to_string()));
inputs::card(column![text(label).size(11).color(inputs::SECTION_COLOR), body,].spacing(6)) 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); .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() { if !state.timeline.is_empty() {
content = content content = content
.push(Space::with_height(20)) .push(Space::new().height(20))
.push(inputs::section_header(&t(locale, "dashboard.timeline"))) .push(inputs::section_header(&t(locale, "dashboard.timeline")))
.push(timeline_chart(&state.timeline, locale)); .push(timeline_chart(&state.timeline, locale));
} }
if !state.tag_cloud.is_empty() { if !state.tag_cloud.is_empty() {
content = content content = content
.push(Space::with_height(20)) .push(Space::new().height(20))
.push(inputs::section_header(&t(locale, "dashboard.tags"))) .push(inputs::section_header(&t(locale, "dashboard.tags")))
.push(tag_cloud(&state.tag_cloud, locale)); .push(tag_cloud(&state.tag_cloud, locale));
} }
if !state.category_cloud.is_empty() { if !state.category_cloud.is_empty() {
content = content content = content
.push(Space::with_height(20)) .push(Space::new().height(20))
.push(inputs::section_header(&t(locale, "dashboard.categories"))) .push(inputs::section_header(&t(locale, "dashboard.categories")))
.push(category_cloud(&state.category_cloud, locale)); .push(category_cloud(&state.category_cloud, locale));
} }
if !state.recent_posts.is_empty() { if !state.recent_posts.is_empty() {
content = content content = content
.push(Space::with_height(20)) .push(Space::new().height(20))
.push(inputs::section_header(&t(locale, "dashboard.recentPosts"))) .push(inputs::section_header(&t(locale, "dashboard.recentPosts")))
.push(recent_posts(&state.recent_posts, locale)); .push(recent_posts(&state.recent_posts, locale));
} }
@@ -238,7 +239,7 @@ fn timeline_chart<'a>(
container( container(
column![ column![
text(month.count.to_string()).size(12).color(Color::WHITE), text(month.count.to_string()).size(12).color(Color::WHITE),
container(Space::with_height(height)) container(Space::new().height(height))
.width(Length::Fill) .width(Length::Fill)
.style(|_: &Theme| container::Style { .style(|_: &Theme| container::Style {
background: Some(Background::Color(Color::from_rgb(0.25, 0.48, 0.80))), 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 { pub fn scroll_id(kind: DocumentationKind) -> iced::widget::Id {
scrollable::Id::new(match kind { iced::widget::Id::new(match kind {
DocumentationKind::Guide => "user-documentation", DocumentationKind::Guide => "user-documentation",
DocumentationKind::Api => "api-documentation", DocumentationKind::Api => "api-documentation",
DocumentationKind::Cli => "cli-documentation", DocumentationKind::Cli => "cli-documentation",
@@ -200,8 +200,10 @@ pub fn view(state: &DocumentationState, locale: UiLocale) -> Element<'_, Message
content = content.push(match block { content = content.push(match block {
DocumentBlock::Markdown(items) => markdown::view( DocumentBlock::Markdown(items) => markdown::view(
items, items,
markdown::Settings::with_text_size(14), markdown::Settings::with_text_size(
14,
markdown::Style::from_palette(inputs::app_theme().palette()), markdown::Style::from_palette(inputs::app_theme().palette()),
),
) )
.map({ .map({
let kind = state.kind; let kind = state.kind;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -176,7 +176,7 @@ pub fn view(
.color(label_color) .color(label_color)
.into() .into()
} else { } else {
Space::with_width(0).into() Space::new().width(0).into()
}; };
let left = row![project_trigger, task_indicator] let left = row![project_trigger, task_indicator]
@@ -199,7 +199,7 @@ pub fn view(
.color(color) .color(color)
.into() .into()
} else { } else {
Space::with_width(0).into() Space::new().width(0).into()
}; };
// Post + media counts // Post + media counts
@@ -226,7 +226,7 @@ pub fn view(
) )
}); });
let chat_tokens_el: Element<'static, Message> = chat_token_label.map_or_else( let chat_tokens_el: Element<'static, Message> = chat_token_label.map_or_else(
|| Space::with_width(0).into(), || Space::new().width(0).into(),
|label| { |label| {
text(label) text(label)
.size(11) .size(11)
@@ -282,7 +282,7 @@ pub fn view(
.align_y(Alignment::Center); .align_y(Alignment::Center);
container( container(
row![left, Space::with_width(Length::Fill), right,] row![left, Space::new().width(Length::Fill), right,]
.align_y(Alignment::Center) .align_y(Alignment::Center)
.padding([0, 8]), .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> { 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)) .width(Length::FillPortion(width_portion))
.height(Length::Fixed(30.0)) .height(Length::Fixed(30.0))
.style(move |_: &Theme| container::Style { .style(move |_: &Theme| container::Style {
@@ -270,7 +270,7 @@ pub fn view<'a>(
.map(|theme| theme_button(theme, &state.selected_theme)) .map(|theme| theme_button(theme, &state.selected_theme))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
while children.len() < 4 { 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) iced::widget::Row::with_children(children)
.spacing(8) .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> { pub fn view(tabs: &[Tab], active_tab: Option<&str>, locale: UiLocale) -> Element<'static, Message> {
// Per tabs.allium: "Hidden when no tabs exist." // Per tabs.allium: "Hidden when no tabs exist."
if tabs.is_empty() { if tabs.is_empty() {
return Space::with_height(0).into(); return Space::new().height(0).into();
} }
let tab_buttons: Vec<Element<'static, Message>> = tabs let tab_buttons: Vec<Element<'static, Message>> = tabs

View File

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

View File

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

View File

@@ -30,7 +30,7 @@ pub fn view<'a>(state: &'a TranslationValidationState, locale: UiLocale) -> Elem
.size(24) .size(24)
.shaping(Shaping::Advanced) .shaping(Shaping::Advanced)
.color(Color::from_rgb(0.88, 0.88, 0.92)), .color(Color::from_rgb(0.88, 0.88, 0.92)),
Space::with_width(Length::Fill), Space::new().width(Length::Fill),
run, run,
] ]
.align_y(iced::Alignment::Center), .align_y(iced::Alignment::Center),
@@ -77,7 +77,7 @@ fn issue_section<'a>(
locale: UiLocale, locale: UiLocale,
) -> Element<'a, Message> { ) -> Element<'a, Message> {
if issues.is_empty() { 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 rows = issues.iter().fold(column!().spacing(6), |column, issue| {
let location = issue.file_path.as_deref().unwrap_or(issue.post_id.as_str()); 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). /// Horizontal line separator (full width).
fn separator_h<'a>() -> Element<'a, Message> { fn separator_h<'a>() -> Element<'a, Message> {
container(Space::new(0, 0)) container(Space::new())
.width(Length::Fill) .width(Length::Fill)
.height(Length::Fixed(1.0)) .height(Length::Fixed(1.0))
.style(|_theme: &Theme| container::Style { .style(|_theme: &Theme| container::Style {
@@ -245,7 +245,7 @@ pub fn view<'a>(
)); ));
// Resize drag handle: 4px wide strip between sidebar and content // 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)) .width(Length::Fixed(4.0))
.height(Length::Fill) .height(Length::Fill)
.style(drag_handle_style); .style(drag_handle_style);
@@ -325,9 +325,9 @@ pub fn view<'a>(
Some( Some(
container( container(
container(row![ container(row![
Space::with_width(Length::Fill), Space::new().width(Length::Fill),
dropdown_menu, dropdown_menu,
Space::with_width(Length::Fixed(40.0)), Space::new().width(Length::Fixed(40.0)),
]) ])
.width(Length::Fill) .width(Length::Fill)
.align_y(Alignment::End) .align_y(Alignment::End)
@@ -350,9 +350,9 @@ pub fn view<'a>(
Some( Some(
container( container(
container(row![ container(row![
Space::with_width(Length::Fixed(8.0)), Space::new().width(Length::Fixed(8.0)),
dropdown, dropdown,
Space::with_width(Length::Fill), Space::new().width(Length::Fill),
]) ])
.width(Length::Fill) .width(Length::Fill)
.align_y(Alignment::End) .align_y(Alignment::End)