GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
ci: clippy, warnings as errors; the crate clippy-clean
A clippy job runs `cargo clippy --all-targets --all-features -- -D warnings`.
Five lints are allowed as house style in Cargo.toml's [lints.clippy], each with
its reason (too_many_arguments, type_complexity, excessive_precision,
needless_range_loop, new_without_default); everything else clippy reported
(about 390) is fixed: its own suggestions applied, and by hand a key-text
block rewritten with Option combinators, matches! for two key sets, clamp,
an enumerate counter, a const assertion, pattern literals for redundant
guards, the copy button's identical pressed/hovered washes merged, and two
allows with their reasons (a Vec<Box<_>> whose boxes must not move; a picker
child try_wait has already reaped).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
.github/workflows/ci.yml | 19 ++
CLAUDE.md | 8 +-
Cargo.toml | 14 +
examples/carve_union_demo.rs | 2 +-
examples/frost_pair.rs | 2 +-
examples/grouped_recess_probe.rs | 2 +-
examples/probe/scene.rs | 2 +-
examples/probe3d/scene.rs | 2 +-
examples/trigger_near_roll_warning.rs | 2 +-
src/a11y.rs | 2 +-
src/backend/driver.rs | 29 +-
src/backend/menu_popup.rs | 2 +-
src/backend/tessellate.rs | 88 +++---
src/backend/text.rs | 4 +-
src/backend/text_input.rs | 5 +-
src/backend/touch.rs | 2 +-
src/backend/window_runner.rs | 24 +-
src/bin/cce-ramp.rs | 2 +-
src/bin/cce-relief.rs | 4 +-
src/color/mod.rs | 8 +-
src/compute.rs | 4 +-
src/config_style_tests.rs | 6 +-
src/context.rs | 16 +-
src/file_dialog.rs | 4 +-
src/layout/legacy.rs | 86 ++----
src/layout/mod.rs | 192 ++++++-------
src/layout/registry.rs | 3 -
src/lib.rs | 4 +-
src/main.rs | 2 +-
src/scene/heightfield.rs | 8 +-
src/scene/material.rs | 4 +-
src/scene/paint.rs | 4 +-
src/scene/tree.rs | 5 +-
src/vk/image.rs | 2 +-
src/vk/renderer.rs | 4 +-
src/widget/container/container_layout.rs | 5 +-
src/widget/container/menu.rs | 7 +-
src/widget/container/parameters_bg.rs | 156 +++++------
src/widget/container/spreadsheet.rs | 8 +-
src/widget/container/treelist.rs | 448 +++++++++++++++----------------
src/widget/core.rs | 36 +--
src/widget/display/float3.rs | 13 +-
src/widget/display/graph.rs | 4 +-
src/widget/display/label.rs | 2 +-
src/widget/display/serialize.rs | 10 +-
src/widget/doc_editor/mod.rs | 8 +-
src/widget/doc_editor/preview.rs | 2 +-
src/widget/input/button.rs | 12 +-
src/widget/input/button_strip.rs | 5 +-
src/widget/input/color_selector.rs | 6 +-
src/widget/input/dropdown.rs | 2 +-
src/widget/input/font_selector.rs | 2 +
src/widget/input/ramp.rs | 21 +-
src/widget/input/slider.rs | 4 +-
src/widget/input/spinbox.rs | 6 +-
src/widget/input/text_box.rs | 13 +-
src/widget/model.rs | 4 +-
57 files changed, 623 insertions(+), 718 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 9aad900..398e765 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -73,6 +73,25 @@ jobs:
exit 1
fi
+ # Clippy over every target and feature, warnings as errors. The few lints the
+ # crate allows are house style, listed with their reasons in Cargo.toml's
+ # [lints.clippy]; anything else is fixed. Linux only: src/web and src/mac are
+ # cfg'd out here, as in the test job.
+ clippy:
+ runs-on: ubuntu-24.04
+ timeout-minutes: 20
+ steps:
+ - uses: actions/checkout@v5
+ - name: Install system packages
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y --no-install-recommends pkg-config libwayland-dev libxkbcommon-dev
+ - uses: dtolnay/rust-toolchain@stable
+ with:
+ components: clippy
+ - uses: Swatinem/rust-cache@v2
+ - run: cargo clippy --all-targets --all-features -- -D warnings
+
# The browser half (src/web, the wasm examples) is cfg'd out of the Linux
# build above, so nothing else compiles it. scripts/check-wasm type-checks
# the library, its features and the four wasm examples.
diff --git a/CLAUDE.md b/CLAUDE.md
index 590c988..9e0bf9f 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -484,7 +484,7 @@ following the caret through every step, each `done`'s serial equal to the commit
Sway routes text-input focus only while an input method is bound, so with none (the
24-step harness) nothing changes: 0 px.
-CI (`.github/workflows/ci.yml`, every push and PR) has three jobs, warnings as errors in each:
+CI (`.github/workflows/ci.yml`, every push and PR) has four jobs, warnings as errors in each:
- **`test`** (Ubuntu 24.04) builds and tests with default and with all features. It installs
`libwayland-dev` and `libxkbcommon-dev` (the two native libraries the build links, through
@@ -495,6 +495,12 @@ CI (`.github/workflows/ci.yml`, every push and PR) has three jobs, warnings as e
tests needing a second face or a fallback glyph kept the workflow red from 2026-10-07 to
10-08). It also runs the path tracer's `#[ignore]`d GPU tests on lavapipe's compute tier
(`CCE_VK_RT=compute cargo test --lib vk::rt -- --ignored`).
+- **`clippy`** runs `cargo clippy --all-targets --all-features -- -D warnings` (since
+ 2026-10-08). Five lints are allowed as house style in `Cargo.toml`'s `[lints.clippy]`, each
+ with its reason (too many arguments, complex tuple types, precise colour constants, index
+ loops, `new` without `Default`); anything else clippy reports is fixed, not allowed —
+ locally, `cargo clippy -p cce-ui --all-features --all-targets -- -D warnings` is the check.
+ Linux only: `src/web` and `src/mac` are compiled out there.
- **`wasm`** runs `scripts/check-wasm`: the library, its features and the four wasm examples,
type-checked for the browser. Its `RUSTFLAGS` carries `--cfg=web_sys_unstable_apis` itself,
since an environment `RUSTFLAGS` replaces `.cargo/config.toml`'s. Its first run (2026-10-08)
diff --git a/Cargo.toml b/Cargo.toml
index 9b73d41..d0182de 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,6 +7,20 @@ edition = "2021"
name = "cce_ui"
path = "src/lib.rs"
+[lints.clippy]
+# House style, not defects (CI runs clippy with warnings as errors; anything not listed here
+# is fixed, not allowed):
+# - the paint and tessellation functions take geometry and colour piecewise;
+too_many_arguments = "allow"
+# - the legacy tuple views (`(f32, f32, f32, f32, [f32; 4])` quads and friends);
+type_complexity = "allow"
+# - colour and curve constants are written as their specs give them;
+excessive_precision = "allow"
+# - geometry loops index several arrays in step;
+needless_range_loop = "allow"
+# - a widget's `new` returns `Adapted<Self>`, which a `Default` would not.
+new_without_default = "allow"
+
[features]
# `widget::markdown` (MarkdownView): lays out vault notes for reading views
# and note cards. Brings in cce-vault and its Markdown parser, so only the
diff --git a/examples/carve_union_demo.rs b/examples/carve_union_demo.rs
index 833419d..9c0f77e 100644
--- a/examples/carve_union_demo.rs
+++ b/examples/carve_union_demo.rs
@@ -55,7 +55,7 @@ impl Application for DemoApp {
fn display_list(&mut self, size: LogicalSize, _scale: f64) -> Option<DisplayList> {
let mut pc = PaintCtx::new();
- let (w, h) = (size.width as f32, size.height as f32);
+ let (w, h) = (size.width, size.height);
pc.plate(
Rect { x: 0.0, y: 0.0, width: w, height: h },
(12.0, 12.0, 12.0, 12.0),
diff --git a/examples/frost_pair.rs b/examples/frost_pair.rs
index 15a8d92..0d60900 100644
--- a/examples/frost_pair.rs
+++ b/examples/frost_pair.rs
@@ -62,7 +62,7 @@ impl Application for FrostPair {
fn display_list(&mut self, size: LogicalSize, scale: f64) -> Option<DisplayList> {
cce_ui::scale::set_scale_factor(scale as f32);
- let (w, h) = (size.width as f32, size.height as f32);
+ let (w, h) = (size.width, size.height);
let mut pc = PaintCtx::new();
pc.plate_spec(&PlateSpec {
rect: Rect { x: 0.0, y: 0.0, width: w, height: h },
diff --git a/examples/grouped_recess_probe.rs b/examples/grouped_recess_probe.rs
index d24834c..84937c1 100644
--- a/examples/grouped_recess_probe.rs
+++ b/examples/grouped_recess_probe.rs
@@ -55,7 +55,7 @@ impl Application for ProbeApp {
fn display_list(&mut self, size: LogicalSize, _scale: f64) -> Option<DisplayList> {
let mut pc = PaintCtx::new();
- let (w, h) = (size.width as f32, size.height as f32);
+ let (w, h) = (size.width, size.height);
let half = (w - 30.0) * 0.5;
let bevel = cce_ui::layout::bevel_width();
for (i, x) in [10.0, 20.0 + half].into_iter().enumerate() {
diff --git a/examples/probe/scene.rs b/examples/probe/scene.rs
index 99a1e6c..dc54dc9 100644
--- a/examples/probe/scene.rs
+++ b/examples/probe/scene.rs
@@ -89,7 +89,7 @@ impl Application for ProbeApp {
depth: cce_ui::layout::bevel_width(),
});
let face = Some(Material::opaque([0.18, 0.22, 0.32, 1.0]));
- pc.control_plate(&ControlPlate::control(r(570.0, 60.0, 140.0, 36.0), 8.0, PlateStance::Raised, face.clone()));
+ pc.control_plate(&ControlPlate::control(r(570.0, 60.0, 140.0, 36.0), 8.0, PlateStance::Raised, face));
pc.control_plate(&ControlPlate::control(r(730.0, 60.0, 140.0, 36.0), 8.0, PlateStance::Raised, None));
pc.control_plate(&ControlPlate::control(r(890.0, 60.0, 140.0, 36.0), 8.0, PlateStance::Flush, None));
pc.control_plate(&ControlPlate::control(r(1050.0, 60.0, 140.0, 36.0), 8.0, PlateStance::Flat, face));
diff --git a/examples/probe3d/scene.rs b/examples/probe3d/scene.rs
index 7728c4c..dfac2dc 100644
--- a/examples/probe3d/scene.rs
+++ b/examples/probe3d/scene.rs
@@ -152,7 +152,7 @@ fn traced_scene() -> (Vec<RtTriangle>, Vec<RtMaterial>) {
let mut add = |verts: Vec<Vertex3D>, albedo: [f32; 3], emission: [f32; 3]| {
let m = mats.len() as u32;
mats.push(RtMaterial { albedo, emission });
- for t in verts.chunks_exact(3) {
+ for t in verts.as_chunks::<3>().0 {
tris.push(RtTriangle { p0: t[0].position, p1: t[1].position, p2: t[2].position, material: m });
}
};
diff --git a/examples/trigger_near_roll_warning.rs b/examples/trigger_near_roll_warning.rs
index e6c7f86..b361f4a 100644
--- a/examples/trigger_near_roll_warning.rs
+++ b/examples/trigger_near_roll_warning.rs
@@ -57,7 +57,7 @@ impl Application for TriggerApp {
fn display_list(&mut self, size: LogicalSize, _scale: f64) -> Option<DisplayList> {
let mut pc = PaintCtx::new();
- let (w, h) = (size.width as f32, size.height as f32);
+ let (w, h) = (size.width, size.height);
let roll = cce_ui::layout::bevel_width();
// 1. The window plate — opens the carve-grouping window.
diff --git a/src/a11y.rs b/src/a11y.rs
index 60c0df0..993026b 100644
--- a/src/a11y.rs
+++ b/src/a11y.rs
@@ -488,7 +488,7 @@ mod tests {
assert_eq!(key_for(&text, Action::Click), None);
}
- fn node<'a>(update: &'a TreeUpdate, id: NodeId) -> &'a Node {
+ fn node(update: &TreeUpdate, id: NodeId) -> &Node {
&update.nodes.iter().find(|(n, _)| *n == id).expect("node in the update").1
}
diff --git a/src/backend/driver.rs b/src/backend/driver.rs
index f71d1b2..6b239e5 100644
--- a/src/backend/driver.rs
+++ b/src/backend/driver.rs
@@ -33,18 +33,18 @@ pub const KEY_REPEAT_DELAY: std::time::Duration = std::time::Duration::from_mill
pub const KEY_REPEAT_INTERVAL: std::time::Duration = std::time::Duration::from_millis(50);
fn is_repeatable_key(key: &Key) -> bool {
- match key {
- Key::Named(NamedKey::Backspace) |
- Key::Named(NamedKey::Delete) |
- Key::Named(NamedKey::ArrowLeft) |
- Key::Named(NamedKey::ArrowRight) |
- Key::Named(NamedKey::ArrowUp) |
- Key::Named(NamedKey::ArrowDown) |
- Key::Named(NamedKey::Home) |
- Key::Named(NamedKey::End) |
- Key::Character(_) => true,
- _ => false,
- }
+ matches!(
+ key,
+ Key::Named(NamedKey::Backspace)
+ | Key::Named(NamedKey::Delete)
+ | Key::Named(NamedKey::ArrowLeft)
+ | Key::Named(NamedKey::ArrowRight)
+ | Key::Named(NamedKey::ArrowUp)
+ | Key::Named(NamedKey::ArrowDown)
+ | Key::Named(NamedKey::Home)
+ | Key::Named(NamedKey::End)
+ | Key::Character(_)
+ )
}
/// The modifier keys as the keyboard last reported them.
@@ -373,8 +373,7 @@ impl Driver {
let is_widget = t.app.ui_context().is_some_and(|ctx| ctx.is_widget_at(lx, ly));
if (!is_widget
&& t.app.csd_titlebar_move()
- && ly >= CSD_BORDER
- && ly < 32.0
+ && (CSD_BORDER..32.0).contains(&ly)
&& lx < site.size.width - 70.0)
|| t.app.is_movable_root_plate_at(lx, ly)
{
@@ -983,7 +982,7 @@ mod tests {
if state == ElementState::Pressed { self.press_msg } else { None }
}
fn handle_mouse_wheel(&mut self, delta: &MouseScrollDelta, _: LogicalPosition, _: &mut bool) {
- self.seen.push(Seen::Wheel(delta.clone()));
+ self.seen.push(Seen::Wheel(*delta));
}
fn handle_key_input(&mut self, event: &KeyEvent, _: &mut bool) -> Option<u32> {
self.seen.push(Seen::Key(event.logical_key.clone(), event.repeat));
diff --git a/src/backend/menu_popup.rs b/src/backend/menu_popup.rs
index 7b42bfb..c55ae73 100644
--- a/src/backend/menu_popup.rs
+++ b/src/backend/menu_popup.rs
@@ -99,7 +99,7 @@ fn popup_enabled() -> bool {
/// except in forced-scale mode, where the compositor believes scale 1 and
/// the app's logical px are `forced` of its own.
fn forced() -> f32 {
- crate::scale::forced_scale().map(|f| f as f32).unwrap_or(1.0)
+ crate::scale::forced_scale().unwrap_or(1.0)
}
impl<A: Application> EngineState<A> {
diff --git a/src/backend/tessellate.rs b/src/backend/tessellate.rs
index be38fa1..59196f7 100644
--- a/src/backend/tessellate.rs
+++ b/src/backend/tessellate.rs
@@ -1750,7 +1750,7 @@ pub fn tessellate_display_list(
}
// Contiguity: only the last feature-receiving plate (or
// one with no features yet) may take another.
- batches[*bi].plate.as_ref().map_or(false, |p| p.host[1] == 0.0)
+ batches[*bi].plate.as_ref().is_some_and(|p| p.host[1] == 0.0)
|| last_feature_plate == Some(*bi)
})
.map(|(_, &(bi, _))| bi)
@@ -2635,73 +2635,57 @@ pub fn extra_quad_vertices(
verts
}
-fn get_child_widget_for_quad<'a>(
- w: &'a dyn crate::widget::WidgetHost,
+fn get_child_widget_for_quad(
+ w: &dyn crate::widget::WidgetHost,
qx: f32, qy: f32, qw: f32, qh: f32,
-) -> &'a dyn crate::widget::WidgetHost {
+) -> &dyn crate::widget::WidgetHost {
if let Some(pbg) = w.as_any().downcast_ref::<crate::widget::ParametersBg>() {
- for s_opt in &pbg.sliders {
- if let Some(s) = s_opt {
- let (sx, sy, sww, shh) = s.rect();
- if qx >= sx - 0.1 && qx + qw <= sx + sww + 0.1 && qy >= sy - 0.1 && qy + qh <= sy + shh + 0.1 {
- return s;
- }
+ for s in pbg.sliders.iter().flatten() {
+ let (sx, sy, sww, shh) = s.rect();
+ if qx >= sx - 0.1 && qx + qw <= sx + sww + 0.1 && qy >= sy - 0.1 && qy + qh <= sy + shh + 0.1 {
+ return s;
}
}
- for f_opt in &pbg.float3s {
- if let Some(f) = f_opt {
- let (fx, fy, fww, fhh) = f.rect();
- if qx >= fx - 0.1 && qx + qw <= fx + fww + 0.1 && qy >= fy - 0.1 && qy + qh <= fy + fhh + 0.1 {
- return f;
- }
+ for f in pbg.float3s.iter().flatten() {
+ let (fx, fy, fww, fhh) = f.rect();
+ if qx >= fx - 0.1 && qx + qw <= fx + fww + 0.1 && qy >= fy - 0.1 && qy + qh <= fy + fhh + 0.1 {
+ return f;
}
}
- for sb_opt in &pbg.spinboxes {
- if let Some(sb) = sb_opt {
- let (sx, sy, sww, shh) = sb.rect();
- if qx >= sx - 0.1 && qx + qw <= sx + sww + 0.1 && qy >= sy - 0.1 && qy + qh <= sy + shh + 0.1 {
- return sb;
- }
+ for sb in pbg.spinboxes.iter().flatten() {
+ let (sx, sy, sww, shh) = sb.rect();
+ if qx >= sx - 0.1 && qx + qw <= sx + sww + 0.1 && qy >= sy - 0.1 && qy + qh <= sy + shh + 0.1 {
+ return sb;
}
}
- for btn_opt in &pbg.buttons {
- if let Some(btn) = btn_opt {
- let (bx, by, bww, bhh) = btn.rect();
- if qx >= bx - 0.1 && qx + qw <= bx + bww + 0.1 && qy >= by - 0.1 && qy + qh <= by + bhh + 0.1 {
- return btn;
- }
+ for btn in pbg.buttons.iter().flatten() {
+ let (bx, by, bww, bhh) = btn.rect();
+ if qx >= bx - 0.1 && qx + qw <= bx + bww + 0.1 && qy >= by - 0.1 && qy + qh <= by + bhh + 0.1 {
+ return btn;
}
}
- for ch_opt in &pbg.choices {
- if let Some(ch) = ch_opt {
- let (cx, cy, cww, chh) = ch.rect();
- if qx >= cx - 0.1 && qx + qw <= cx + cww + 0.1 && qy >= cy - 0.1 && qy + qh <= cy + chh + 0.1 {
- return ch;
- }
+ for ch in pbg.choices.iter().flatten() {
+ let (cx, cy, cww, chh) = ch.rect();
+ if qx >= cx - 0.1 && qx + qw <= cx + cww + 0.1 && qy >= cy - 0.1 && qy + qh <= cy + chh + 0.1 {
+ return ch;
}
}
- for t_opt in &pbg.texts {
- if let Some(t) = t_opt {
- let (tx, ty, tww, thh) = t.rect();
- if qx >= tx - 0.1 && qx + qw <= tx + tww + 0.1 && qy >= ty - 0.1 && qy + qh <= ty + thh + 0.1 {
- return t;
- }
+ for t in pbg.texts.iter().flatten() {
+ let (tx, ty, tww, thh) = t.rect();
+ if qx >= tx - 0.1 && qx + qw <= tx + tww + 0.1 && qy >= ty - 0.1 && qy + qh <= ty + thh + 0.1 {
+ return t;
}
}
- for cb_opt in &pbg.toggles {
- if let Some(cb) = cb_opt {
- let (cx, cy, cww, chh) = cb.rect();
- if qx >= cx - 0.1 && qx + qw <= cx + cww + 0.1 && qy >= cy - 0.1 && qy + qh <= cy + chh + 0.1 {
- return cb;
- }
+ for cb in pbg.toggles.iter().flatten() {
+ let (cx, cy, cww, chh) = cb.rect();
+ if qx >= cx - 0.1 && qx + qw <= cx + cww + 0.1 && qy >= cy - 0.1 && qy + qh <= cy + chh + 0.1 {
+ return cb;
}
}
- for c_opt in &pbg.colors {
- if let Some(c) = c_opt {
- let (cx, cy, cww, chh) = c.rect();
- if qx >= cx - 0.1 && qx + qw <= cx + cww + 0.1 && qy >= cy - 0.1 && qy + qh <= cy + chh + 0.1 {
- return c;
- }
+ for c in pbg.colors.iter().flatten() {
+ let (cx, cy, cww, chh) = c.rect();
+ if qx >= cx - 0.1 && qx + qw <= cx + cww + 0.1 && qy >= cy - 0.1 && qy + qh <= cy + chh + 0.1 {
+ return c;
}
}
}
diff --git a/src/backend/text.rs b/src/backend/text.rs
index cc78cad..4662862 100644
--- a/src/backend/text.rs
+++ b/src/backend/text.rs
@@ -288,7 +288,7 @@ fn replay_font_ops(fs: &mut FontSystem, ops: &[FontOp]) {
};
let synced = FONT_OPS_SYNCED.with(|m| m.borrow().get(&key).copied());
let (mut done, mut last) = match synced {
- Some((done, last)) if last.map_or(true, |(id, n)| is_alias(fs, id, n)) => (done, last),
+ Some((done, last)) if last.is_none_or(|(id, n)| is_alias(fs, id, n)) => (done, last),
_ => (0, None),
};
if done == ops.len() {
@@ -704,7 +704,7 @@ pub fn visual_run_order(runs: &[&str], rtl: bool) -> Vec<usize> {
.iter()
.map(|t| match unicode_bidi::get_base_direction(*t) {
unicode_bidi::Direction::Rtl => if base % 2 == 1 { base } else { base + 1 },
- unicode_bidi::Direction::Ltr => if base % 2 == 0 { base } else { base + 1 },
+ unicode_bidi::Direction::Ltr => if base.is_multiple_of(2) { base } else { base + 1 },
unicode_bidi::Direction::Mixed => base,
})
.collect();
diff --git a/src/backend/text_input.rs b/src/backend/text_input.rs
index aee6f07..69986f0 100644
--- a/src/backend/text_input.rs
+++ b/src/backend/text_input.rs
@@ -63,7 +63,7 @@ impl Batch {
/// hidden) as `Preedit`'s.
pub fn set_preedit(&mut self, text: Option<String>, begin: i32, end: i32) {
let text = text.unwrap_or_default();
- let cursor = (begin >= 0 && end >= 0).then(|| (begin as usize, end as usize));
+ let cursor = (begin >= 0 && end >= 0).then_some((begin as usize, end as usize));
self.preedit = (!text.is_empty()).then(|| Preedit::new(text, cursor));
}
@@ -184,8 +184,7 @@ mod tests {
#[test]
fn a_done_ends_the_composition_types_the_commit_and_starts_the_next() {
- let mut b = Batch::default();
- b.commit = Some("日本".into());
+ let mut b = Batch { commit: Some("日本".into()), ..Batch::default() };
b.set_preedit(Some("ご".into()), 3, 3);
assert_eq!(
b.apply_order(),
diff --git a/src/backend/touch.rs b/src/backend/touch.rs
index 78ba7b4..6087180 100644
--- a/src/backend/touch.rs
+++ b/src/backend/touch.rs
@@ -119,7 +119,7 @@ impl TouchTracker {
}
pub fn up(&mut self, id: i32) -> Vec<TouchAction> {
- if self.finger.map_or(true, |f| f.id != id) {
+ if self.finger.is_none_or(|f| f.id != id) {
return Vec::new();
}
let f = self.finger.take().unwrap();
diff --git a/src/backend/window_runner.rs b/src/backend/window_runner.rs
index c16a257..19e8709 100644
--- a/src/backend/window_runner.rs
+++ b/src/backend/window_runner.rs
@@ -250,7 +250,7 @@ impl<A: Application> EngineState<A> {
let surface_ptr = surface.id().as_ptr() as *mut std::ffi::c_void;
self.display_ptr = display_ptr as usize;
- let load_system_fonts = self.inner.as_ref().map_or(false, |a| a.load_system_fonts());
+ let load_system_fonts = self.inner.as_ref().is_some_and(|a| a.load_system_fonts());
// Corner radius 0: runner apps tessellate their own rounded corners.
let mut renderer = unsafe { VkRenderer::try_new(display_ptr, surface_ptr, pw, ph, 0.0) }?;
if self.inner.as_ref().is_some_and(|a| a.grid()) {
@@ -513,7 +513,7 @@ impl<A: Application> EngineState<A> {
// ~5s of continuous skipping at the 16ms loop cadence: nothing
// is presenting and nothing else will say so — this is the
// only witness to a wedged pending extent.
- if self.extent_gate_skips % 300 == 0 {
+ if self.extent_gate_skips.is_multiple_of(300) {
log::warn!(
"[window_runner] extent gate: pending {}x{} != expected {}x{} for {} consecutive renders; no frame is presenting",
e.width, e.height, epw, eph, self.extent_gate_skips,
@@ -892,7 +892,7 @@ impl<A: Application> CompositorHandler for EngineState<A> {
// not clobber the override.
return;
}
- if self.inner.as_ref().map_or(false, |a| a.grid()) {
+ if self.inner.as_ref().is_some_and(|a| a.grid()) {
// Grid surfaces stay at scale 1 — patch.scale is the sole
// resolution authority (see the pin at surface creation).
return;
@@ -1460,21 +1460,9 @@ fn xkb_logical_key(event: &smithay_client_toolkit::seat::keyboard::KeyEvent, ctr
// transformation (ctrl+j = "\n", ctrl+a = 0x01, ...); the keysym is
// untransformed, so prefer it there or ctrl+<letter> shortcuts can
// never match their letter.
- if ctrl {
- if let Some(ch) = event.keysym.key_char() {
- Key::Character(ch.to_string())
- } else if let Some(ref text) = event.utf8 {
- Key::Character(text.clone())
- } else {
- return None;
- }
- } else if let Some(ref text) = event.utf8 {
- Key::Character(text.clone())
- } else if let Some(ch) = event.keysym.key_char() {
- Key::Character(ch.to_string())
- } else {
- return None;
- }
+ let from_keysym = || event.keysym.key_char().map(|ch| ch.to_string());
+ let text = if ctrl { from_keysym().or_else(|| event.utf8.clone()) } else { event.utf8.clone().or_else(from_keysym) };
+ Key::Character(text?)
}
})
}
diff --git a/src/bin/cce-ramp.rs b/src/bin/cce-ramp.rs
index 1017f0e..595be7d 100644
--- a/src/bin/cce-ramp.rs
+++ b/src/bin/cce-ramp.rs
@@ -378,7 +378,7 @@ impl Application for RampPopup {
needs_rebuild: &mut bool,
) {
let ev = Event::MouseWheel {
- delta: delta.clone(),
+ delta: *delta,
x: pos.x,
y: pos.y,
local_x: pos.x,
diff --git a/src/bin/cce-relief.rs b/src/bin/cce-relief.rs
index 1ea8580..857f19d 100644
--- a/src/bin/cce-relief.rs
+++ b/src/bin/cce-relief.rs
@@ -1637,7 +1637,7 @@ impl Application for BevelPopup {
.and_then(|o| o.as_f64())
.map(|f| (f as f32).clamp(0.0, 1.0))
})
- .unwrap_or_else(|| cce_ui::color::root_plate_opacity());
+ .unwrap_or_else(cce_ui::color::root_plate_opacity);
Self {
profile_dropdown: Owned::new(Dropdown::new(
Shape::ALL.iter().map(|s| s.label().to_string()).collect(),
@@ -2028,7 +2028,7 @@ impl Application for BevelPopup {
needs_rebuild: &mut bool,
) {
let ev = Event::MouseWheel {
- delta: delta.clone(),
+ delta: *delta,
x: pos.x,
y: pos.y,
local_x: pos.x,
diff --git a/src/color/mod.rs b/src/color/mod.rs
index 3ebb2db..32b0ab2 100644
--- a/src/color/mod.rs
+++ b/src/color/mod.rs
@@ -1220,9 +1220,9 @@ pub fn control_label_focus_color() -> Option<[f32; 4]> {
pub fn control_label_color_for_state(hovered: bool, focused: bool) -> [u8; 3] {
let c = if focused {
- control_label_focus_color().unwrap_or_else(|| control_label_color())
+ control_label_focus_color().unwrap_or_else(control_label_color)
} else if hovered {
- control_label_hover_color().unwrap_or_else(|| control_label_color())
+ control_label_hover_color().unwrap_or_else(control_label_color)
} else {
control_label_color()
};
@@ -1252,9 +1252,9 @@ pub fn set_control_label_color_detached(color: [f32; 4]) {
pub fn control_label_color_detached_for_state(hovered: bool, focused: bool) -> [u8; 3] {
let c = if focused {
- control_label_focus_color().unwrap_or_else(|| control_label_color_detached())
+ control_label_focus_color().unwrap_or_else(control_label_color_detached)
} else if hovered {
- control_label_hover_color().unwrap_or_else(|| control_label_color_detached())
+ control_label_hover_color().unwrap_or_else(control_label_color_detached)
} else {
control_label_color_detached()
};
diff --git a/src/compute.rs b/src/compute.rs
index 3eff0b4..3c276ee 100644
--- a/src/compute.rs
+++ b/src/compute.rs
@@ -107,7 +107,7 @@ pub(crate) fn check_job(
if bindings.len() > MAX_BINDINGS {
return Err(format!("{} bindings; a job may carry at most {MAX_BINDINGS}", bindings.len()));
}
- if groups.iter().any(|&g| g == 0) {
+ if groups.contains(&0) {
return Err(format!("workgroup count {groups:?} has a zero"));
}
if passes == 0 {
@@ -148,7 +148,7 @@ pub(crate) fn slot_for(binding: usize, swapped: bool, ping_pong: Option<(usize,
/// from whichever buffer the LAST pass wrote, every other one from its own.
pub(crate) fn result_slot(binding: usize, passes: u32, ping_pong: Option<(usize, usize)>) -> usize {
match ping_pong {
- Some((a, b)) if binding == b && passes % 2 == 0 => a,
+ Some((a, b)) if binding == b && passes.is_multiple_of(2) => a,
_ => binding,
}
}
diff --git a/src/config_style_tests.rs b/src/config_style_tests.rs
index e2349ff..40453cb 100644
--- a/src/config_style_tests.rs
+++ b/src/config_style_tests.rs
@@ -28,7 +28,7 @@ fn test_plate_root_canonical_spelling() {
"##;
crate::color::reload_colors(content);
assert_eq!(crate::color::root_plate_corner_radius(), 17.0, "canonical read; legacy ignored");
- assert_eq!(crate::color::root_plate_menubar_blur(), true);
+ assert!(crate::color::root_plate_menubar_blur());
// A legacy-only spelling no longer feeds the getter: the value from
// the canonical load above stands.
@@ -75,14 +75,14 @@ fn test_root_plate_menubar_statusbar_styling() {
crate::color::reload_colors(content);
// Verify values are parsed correctly through the root_plate_* getters.
- assert_eq!(crate::color::root_plate_menubar_blur(), true);
+ assert!(crate::color::root_plate_menubar_blur());
let dd_color = crate::color::dropdown_background_color();
assert!((dd_color[0] - crate::color::srgb_to_linear(8.0 / 255.0)).abs() < 0.0001);
let placeholder_color = crate::color::textbox_placeholder_text_color();
assert_eq!(placeholder_color, [0x60, 0x60, 0x6a]);
- assert_eq!(crate::color::root_plate_statusbar_blur(), false);
+ assert!(!crate::color::root_plate_statusbar_blur());
// Colors are in sRGB converted to linear, let's verify text colors
let menubar_txt = crate::color::root_plate_menubar_text_color();
diff --git a/src/context.rs b/src/context.rs
index f7fe0d5..335567a 100644
--- a/src/context.rs
+++ b/src/context.rs
@@ -207,15 +207,15 @@ impl UiContext {
self.note_scroll_event();
}
if let Event::KeyInput(ref key_event) = event {
- let is_scroll_key = match &key_event.logical_key {
+ let is_scroll_key = matches!(
+ &key_event.logical_key,
Key::Named(NamedKey::PageUp)
- | Key::Named(NamedKey::PageDown)
- | Key::Named(NamedKey::Home)
- | Key::Named(NamedKey::End)
- | Key::Named(NamedKey::ArrowUp)
- | Key::Named(NamedKey::ArrowDown) => true,
- _ => false,
- };
+ | Key::Named(NamedKey::PageDown)
+ | Key::Named(NamedKey::Home)
+ | Key::Named(NamedKey::End)
+ | Key::Named(NamedKey::ArrowUp)
+ | Key::Named(NamedKey::ArrowDown)
+ );
if is_scroll_key {
let mut handled = false;
if let Some(focused) = self.focused_widget.and_then(|id| self.tree.get_ptr(id)) {
diff --git a/src/file_dialog.rs b/src/file_dialog.rs
index cfde95c..cc54ee8 100644
--- a/src/file_dialog.rs
+++ b/src/file_dialog.rs
@@ -4,7 +4,7 @@ use std::path::PathBuf;
pub fn pick_file(title: &str, filters: &[(&str, &[&str])]) -> Option<PathBuf> {
let mut dialog = rfd::FileDialog::new().set_title(title);
for (name, exts) in filters {
- dialog = dialog.add_filter(*name, *exts);
+ dialog = dialog.add_filter(*name, exts);
}
dialog.pick_file()
}
@@ -13,7 +13,7 @@ pub fn pick_file(title: &str, filters: &[(&str, &[&str])]) -> Option<PathBuf> {
pub fn save_file(title: &str, filters: &[(&str, &[&str])]) -> Option<PathBuf> {
let mut dialog = rfd::FileDialog::new().set_title(title);
for (name, exts) in filters {
- dialog = dialog.add_filter(*name, *exts);
+ dialog = dialog.add_filter(*name, exts);
}
dialog.save_file()
}
diff --git a/src/layout/legacy.rs b/src/layout/legacy.rs
index 3107722..5528c60 100644
--- a/src/layout/legacy.rs
+++ b/src/layout/legacy.rs
@@ -104,7 +104,7 @@ impl Column {
spacing: CONTROL_GAP,
};
f(&mut row);
- self.y = self.y + h;
+ self.y += h;
}
}
@@ -223,7 +223,7 @@ impl Section {
let max_cols = if is_child {
1
} else {
- ((usable_w + gap) / (min_col_width + gap)).floor().max(1.0).min(2.0) as usize
+ ((usable_w + gap) / (min_col_width + gap)).floor().clamp(1.0, 2.0) as usize
};
let content_start_y = top + pad + 19.0;
let grid = Grid::new(left + margin_x, content_start_y, usable_w, min_col_width, gap, max_cols);
@@ -315,15 +315,11 @@ impl Section {
let new_bottom = y + total_h;
self.content_y = new_bottom;
- for h in &mut self.grid.col_heights {
- *h = new_bottom;
- }
+ self.grid.col_heights.fill(new_bottom);
} else {
let max_h = self.grid.max_height();
if self.content_y > max_h {
- for h in &mut self.grid.col_heights {
- *h = self.content_y;
- }
+ self.grid.col_heights.fill(self.content_y);
}
let col = self.grid.next_column();
@@ -351,18 +347,14 @@ impl Section {
let y = max_h;
pc.rect([0.18, 0.18, 0.27, 1.0], x, y, self.cw - 2.0 * pad, 1.0);
self.content_y = max_h + 8.0;
- for h in &mut self.grid.col_heights {
- *h = self.content_y;
- }
+ self.grid.col_heights.fill(self.content_y);
}
pub fn rect(&mut self, pc: &mut dyn RenderTarget, color: [f32; 4], x_off: f32, w: f32, h: f32) {
let max_h = self.grid.max_height().max(self.content_y);
pc.rect(color, self.ax(x_off), max_h, w, h);
self.content_y = max_h + h;
- for col_h in &mut self.grid.col_heights {
- *col_h = self.content_y;
- }
+ self.grid.col_heights.fill(self.content_y);
}
pub fn row_layout(&self, count: usize, gap: f32) -> Vec<(f32, f32)> {
@@ -387,9 +379,7 @@ impl Section {
F: FnMut(usize, f32, f32),
{
let max_h = self.grid.max_height().max(self.content_y);
- for col_h in &mut self.grid.col_heights {
- *col_h = max_h;
- }
+ self.grid.col_heights.fill(max_h);
self.content_y = max_h;
let cols = self.row_layout(count, gap);
@@ -398,9 +388,7 @@ impl Section {
}
self.content_y += h;
- for col_h in &mut self.grid.col_heights {
- *col_h = self.content_y;
- }
+ self.grid.col_heights.fill(self.content_y);
}
pub fn finish(&mut self, pc: &mut dyn RenderTarget) -> f32 {
@@ -993,9 +981,7 @@ impl LayoutStrategy for AdaptiveGrid {
let y = grid.max_height();
let x = grid.left;
let allocated_w = grid.width;
- for col_h in &mut grid.col_heights {
- *col_h = y + wh + grid.gap;
- }
+ grid.col_heights.fill(y + wh + grid.gap);
(x, y, allocated_w, wh)
} else if num_cols_spanned == 1 {
let col = grid.next_column();
@@ -1407,7 +1393,7 @@ impl<'a, P: RenderTarget> SectionContext<'a, P> {
let max_cols = if is_child {
1
} else {
- ((usable_w + gap) / (min_col_width + gap)).floor().max(1.0).min(2.0) as usize
+ ((usable_w + gap) / (min_col_width + gap)).floor().clamp(1.0, 2.0) as usize
};
// Under relief styling the content stands off the well's top wall by
// the same inset it keeps from the side walls (`margin_x`, which is
@@ -1545,9 +1531,7 @@ impl<'a, P: RenderTarget> SectionContext<'a, P> {
self.pc.text_with_bounds(text, x, y, font_size, color, bounds);
let new_bottom = y + font_size + 4.0;
self.content_y = new_bottom;
- for h in &mut self.grid.col_heights {
- *h = new_bottom;
- }
+ self.grid.col_heights.fill(new_bottom);
}
pub fn widget<T: WidgetHost + 'static>(&mut self, w: &mut T, _x_off: f32, _ww: f32, mut wh: f32, ctx: &mut UiContext) {
@@ -1582,15 +1566,11 @@ impl<'a, P: RenderTarget> SectionContext<'a, P> {
let new_bottom = y + total_h;
self.content_y = new_bottom;
- for h in &mut self.grid.col_heights {
- *h = new_bottom;
- }
+ self.grid.col_heights.fill(new_bottom);
} else {
let max_h = self.grid.max_height();
if self.content_y > max_h {
- for h in &mut self.grid.col_heights {
- *h = self.content_y;
- }
+ self.grid.col_heights.fill(self.content_y);
}
let col = self.grid.next_column();
@@ -1624,18 +1604,14 @@ impl<'a, P: RenderTarget> SectionContext<'a, P> {
let y = max_h;
self.pc.rect([0.18, 0.18, 0.27, 1.0], x, y, self.cw - 2.0 * pad, 1.0);
self.content_y = max_h + 8.0;
- for h in &mut self.grid.col_heights {
- *h = self.content_y;
- }
+ self.grid.col_heights.fill(self.content_y);
}
pub fn rect(&mut self, color: [f32; 4], x_off: f32, w: f32, h: f32) {
let max_h = self.grid.max_height().max(self.content_y);
self.pc.rect(color, self.ax(x_off), max_h, w, h);
self.content_y = max_h + h;
- for col_h in &mut self.grid.col_heights {
- *col_h = self.content_y;
- }
+ self.grid.col_heights.fill(self.content_y);
}
pub fn row_layout(&self, count: usize, gap: f32) -> Vec<(f32, f32)> {
@@ -1703,9 +1679,7 @@ impl<'a, P: RenderTarget> SectionContext<'a, P> {
F: FnMut(usize, f32, f32),
{
let max_h = self.grid.max_height().max(self.content_y);
- for col_h in &mut self.grid.col_heights {
- *col_h = max_h;
- }
+ self.grid.col_heights.fill(max_h);
self.content_y = max_h;
let cols = self.row_layout(count, gap);
@@ -1714,9 +1688,7 @@ impl<'a, P: RenderTarget> SectionContext<'a, P> {
}
self.content_y += h;
- for col_h in &mut self.grid.col_heights {
- *col_h = self.content_y;
- }
+ self.grid.col_heights.fill(self.content_y);
}
pub fn vstack(&mut self, spacing: f32) -> VStack<'_, 'a, P> {
@@ -1761,9 +1733,7 @@ impl<'a, P: RenderTarget> SectionContext<'a, P> {
self.content_y = self.grid.max_height();
} else {
self.content_y = new_bottom;
- for h in &mut self.grid.col_heights {
- *h = new_bottom;
- }
+ self.grid.col_heights.fill(new_bottom);
}
}
@@ -1866,9 +1836,7 @@ impl<'b, 'a, P: RenderTarget> VStack<'b, 'a, P> {
let new_bottom = y + total_h;
self.context.content_y = new_bottom;
- for h in &mut self.context.grid.col_heights {
- *h = new_bottom;
- }
+ self.context.grid.col_heights.fill(new_bottom);
self.context.spacing(self.spacing);
}
@@ -1880,9 +1848,7 @@ impl<'b, 'a, P: RenderTarget> VStack<'b, 'a, P> {
F: FnMut(&mut SectionContext<'a, P>, usize, f32, f32),
{
let max_h = self.context.grid.max_height().max(self.context.content_y);
- for col_h in &mut self.context.grid.col_heights {
- *col_h = max_h;
- }
+ self.context.grid.col_heights.fill(max_h);
self.context.content_y = max_h;
let cols = self.context.row_layout_for(needs, gap);
@@ -1893,9 +1859,7 @@ impl<'b, 'a, P: RenderTarget> VStack<'b, 'a, P> {
let new_bottom = max_h + h;
self.context.content_y = new_bottom;
- for col_h in &mut self.context.grid.col_heights {
- *col_h = new_bottom;
- }
+ self.context.grid.col_heights.fill(new_bottom);
self.context.spacing(self.spacing);
}
@@ -1904,9 +1868,7 @@ impl<'b, 'a, P: RenderTarget> VStack<'b, 'a, P> {
F: FnMut(&mut SectionContext<'a, P>, usize, f32, f32),
{
let max_h = self.context.grid.max_height().max(self.context.content_y);
- for col_h in &mut self.context.grid.col_heights {
- *col_h = max_h;
- }
+ self.context.grid.col_heights.fill(max_h);
self.context.content_y = max_h;
let cols = self.context.row_layout(count, gap);
@@ -1917,9 +1879,7 @@ impl<'b, 'a, P: RenderTarget> VStack<'b, 'a, P> {
let new_bottom = max_h + h;
self.context.content_y = new_bottom;
- for col_h in &mut self.context.grid.col_heights {
- *col_h = new_bottom;
- }
+ self.context.grid.col_heights.fill(new_bottom);
self.context.spacing(self.spacing);
}
}
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 0749dee..90b8e10 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -213,7 +213,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("control_label_margin") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = CONTROL_LABEL_MARGIN.write() {
@@ -222,7 +222,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("nested_section_label_alignment") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<u8>() {
if let Ok(mut lock) = NESTED_SECTION_LABEL_ALIGNMENT.write() {
@@ -231,7 +231,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("nested_section_label_offset") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = NESTED_SECTION_LABEL_OFFSET.write() {
@@ -240,7 +240,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("plate_padding") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = PLATE_PADDING.write() {
@@ -249,7 +249,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("page_margin") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = PAGE_MARGIN.write() {
@@ -258,7 +258,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("grid_min_col_width") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = GRID_MIN_COL_WIDTH.write() {
@@ -267,7 +267,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("grid_gap") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = GRID_GAP.write() {
@@ -276,7 +276,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("column_gap") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = COLUMN_GAP.write() {
@@ -285,7 +285,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("control_panel_padding") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = CONTROL_PANEL_PADDING.write() {
@@ -294,7 +294,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("control_panel_gap") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = CONTROL_PANEL_GAP.write() {
@@ -303,7 +303,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("section_padding") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = SECTION_PADDING.write() {
@@ -312,7 +312,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("scrollbar_width") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = SCROLLBAR_WIDTH.write() {
@@ -321,7 +321,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("scrollbar_inset") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = SCROLLBAR_INSET.write() {
@@ -330,7 +330,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("tree_opacity") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = TREE_OPACITY.write() {
@@ -339,7 +339,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("tree_blur") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = TREE_BLUR.write() {
@@ -348,7 +348,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("spinbox_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = SPINBOX_HEIGHT.write() {
@@ -357,7 +357,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("spinbox_button_padding") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = SPINBOX_BUTTON_PADDING.write() {
@@ -366,7 +366,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("spinbox_corner_radius") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = SPINBOX_CORNER_RADIUS.write() {
@@ -375,7 +375,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("textbox_corner_radius") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = TEXTBOX_CORNER_RADIUS.write() {
@@ -384,7 +384,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("textbox_line_wrap") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
let wrap = val_str == "true" || val_str == "1" || val_str == "1.0";
if let Ok(mut lock) = TEXTBOX_LINE_WRAP.write() {
@@ -392,7 +392,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("touchpad_natural_scroll") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
let enabled = val_str == "true" || val_str == "1" || val_str == "1.0";
if let Ok(mut lock) = TOUCHPAD_NATURAL_SCROLL.write() {
@@ -400,7 +400,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("textbox_multiline_border_width") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = TEXTBOX_MULTILINE_BORDER_WIDTH.write() {
@@ -409,7 +409,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("list_corner_radius") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = LIST_CORNER_RADIUS.write() {
@@ -418,7 +418,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("tree_corner_radius") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = TREE_CORNER_RADIUS.write() {
@@ -427,7 +427,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("font_selector_corner_radius") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = FONT_SELECTOR_CORNER_RADIUS.write() {
@@ -436,7 +436,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("dropdown_corner_radius") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = DROPDOWN_CORNER_RADIUS.write() {
@@ -445,7 +445,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("toggle_corner_radius") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = TOGGLE_CORNER_RADIUS.write() {
@@ -454,7 +454,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("plate_corner_radius") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = PLATE_CORNER_RADIUS.write() {
@@ -463,7 +463,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("plate_opacity") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = PLATE_OPACITY.write() {
@@ -472,7 +472,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("page_opacity") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = PAGE_OPACITY.write() {
@@ -481,7 +481,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("layer_opacity") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = LAYER_OPACITY.write() {
@@ -493,7 +493,7 @@ pub fn reload_config() {
if let Some(rest) = trimmed.strip_prefix("toggle_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = TOGGLE_HEIGHT.write() {
@@ -502,7 +502,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("color_selector_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = COLOR_SELECTOR_HEIGHT.write() {
@@ -511,7 +511,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("font_selector_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = FONT_SELECTOR_HEIGHT.write() {
@@ -520,7 +520,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("color_selector_font") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=');
+ let rest = rest.trim_start_matches([' ', '=']);
let rest = rest.trim();
let val_str = if rest.starts_with('"') && rest.ends_with('"') && rest.len() >= 2 {
&rest[1..rest.len() - 1]
@@ -533,7 +533,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("menubar_font") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=');
+ let rest = rest.trim_start_matches([' ', '=']);
let rest = rest.trim();
let val_str = if rest.starts_with('"') && rest.ends_with('"') && rest.len() >= 2 {
&rest[1..rest.len() - 1]
@@ -553,7 +553,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("statusbar_font") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=');
+ let rest = rest.trim_start_matches([' ', '=']);
let rest = rest.trim();
let val_str = if rest.starts_with('"') && rest.ends_with('"') && rest.len() >= 2 {
&rest[1..rest.len() - 1]
@@ -573,7 +573,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("section_label_font") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=');
+ let rest = rest.trim_start_matches([' ', '=']);
let rest = mod_rest(rest);
let font = rest.trim().to_string();
if let Ok(mut lock) = SECTION_LABEL_FONT.write() {
@@ -581,7 +581,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("nested_section_label_font") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=');
+ let rest = rest.trim_start_matches([' ', '=']);
let rest = mod_rest(rest);
let font = rest.trim().to_string();
if let Ok(mut lock) = NESTED_SECTION_LABEL_FONT.write() {
@@ -589,7 +589,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("breadcrumb_font") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=');
+ let rest = rest.trim_start_matches([' ', '=']);
let rest = mod_rest(rest);
let font = rest.trim().to_string();
if let Ok(mut lock) = BREADCRUMB_FONT.write() {
@@ -597,7 +597,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("button_font") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=');
+ let rest = rest.trim_start_matches([' ', '=']);
let rest = mod_rest(rest);
let font = rest.trim().to_string();
if let Ok(mut lock) = BUTTON_FONT.write() {
@@ -605,7 +605,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("color_selector_preview_corner_radius") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = COLOR_SELECTOR_PREVIEW_CORNER_RADIUS.write() {
@@ -614,7 +614,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("color_selector_corner_radius") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = COLOR_SELECTOR_CORNER_RADIUS.write() {
@@ -623,7 +623,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("color_selector_preview_margin") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = COLOR_SELECTOR_PREVIEW_MARGIN.write() {
@@ -632,7 +632,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("paginator_tab_padding_x") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = PAGINATOR_TAB_PADDING_X.write() {
@@ -641,7 +641,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("button_padding") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = BUTTON_PADDING.write() {
@@ -649,7 +649,7 @@ pub fn reload_config() {
}
}
} else if let Some(rest) = trimmed.strip_prefix("paginator_tab_padding_y") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = BUTTON_PADDING.write() {
@@ -658,7 +658,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("button_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = BUTTON_HEIGHT.write() {
@@ -667,7 +667,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("button_strip_spacing") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = BUTTON_STRIP_SPACING.write() {
@@ -676,7 +676,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("textbox_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = TEXTBOX_HEIGHT.write() {
@@ -685,7 +685,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("dropdown_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = DROPDOWN_HEIGHT.write() {
@@ -694,7 +694,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("slider_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = SLIDER_HEIGHT.write() {
@@ -703,7 +703,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("rangeslider_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = RANGESLIDER_HEIGHT.write() {
@@ -712,7 +712,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("button_corner_radius") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = BUTTON_CORNER_RADIUS.write() {
@@ -721,7 +721,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("slider_corner_radius") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = SLIDER_CORNER_RADIUS.write() {
@@ -730,7 +730,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("rangeslider_corner_radius") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = RANGESLIDER_CORNER_RADIUS.write() {
@@ -739,7 +739,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("toggle_border_width") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = TOGGLE_BORDER_WIDTH.write() {
@@ -852,7 +852,7 @@ pub fn reload_config() {
}
}
if let Some(rest) = trimmed.strip_prefix("list_justification") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<u8>() {
if let Ok(mut lock) = LIST_JUSTIFICATION.write() {
@@ -1012,7 +1012,7 @@ pub fn nested_section_label_alignment() -> u8 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("nested_section_label_alignment") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<u8>() {
if let Ok(mut lock) = NESTED_SECTION_LABEL_ALIGNMENT.write() {
@@ -1042,7 +1042,7 @@ pub fn nested_section_label_offset() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("nested_section_label_offset") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = NESTED_SECTION_LABEL_OFFSET.write() {
@@ -1106,7 +1106,7 @@ pub fn grid_min_col_width() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("grid_min_col_width") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = GRID_MIN_COL_WIDTH.write() {
@@ -1136,7 +1136,7 @@ pub fn grid_gap() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("grid_gap") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = GRID_GAP.write() {
@@ -1237,7 +1237,7 @@ pub fn param_labels_inline() -> bool {
.read()
.unwrap()
.get_string("param_label_layout")
- .map_or(true, |v| v.trim() != "stacked")
+ .is_none_or(|v| v.trim() != "stacked")
}
pub fn section_padding() -> f32 {
@@ -1252,7 +1252,7 @@ pub fn section_padding() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("section_padding") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = SECTION_PADDING.write() {
@@ -1283,7 +1283,7 @@ pub fn spinbox_height() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("spinbox_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = SPINBOX_HEIGHT.write() {
@@ -1311,7 +1311,7 @@ pub fn toggle_height() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("toggle_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = TOGGLE_HEIGHT.write() {
@@ -1576,7 +1576,7 @@ mod ramp_sampling_tests {
assert!((sample_ramp_keys(&keys, true, 0.4) - 1.0).abs() < 1e-6);
for i in 0..=100 {
let v = sample_ramp_keys(&keys, true, i as f32 / 100.0);
- assert!(v <= 1.0 + 1e-6 && v >= 0.1 - 1e-6, "overshoot {v}");
+ assert!((0.1 - 1e-6..=1.0 + 1e-6).contains(&v), "overshoot {v}");
}
let near = sample_ramp_keys(&keys, true, 0.39);
assert!(near > 0.99, "flat at the extremum: {near}");
@@ -1795,7 +1795,7 @@ pub fn toggle_border_width() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("toggle_border_width") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = TOGGLE_BORDER_WIDTH.write() {
@@ -1869,7 +1869,7 @@ pub fn plate_opacity() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("plate_opacity") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = PLATE_OPACITY.write() {
@@ -1897,7 +1897,7 @@ pub fn page_opacity() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("page_opacity") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = PAGE_OPACITY.write() {
@@ -1925,7 +1925,7 @@ pub fn layer_opacity() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("layer_opacity") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = LAYER_OPACITY.write() {
@@ -1956,7 +1956,7 @@ pub fn color_selector_height() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("color_selector_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = COLOR_SELECTOR_HEIGHT.write() {
@@ -1984,7 +1984,7 @@ pub fn font_selector_height() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("font_selector_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = FONT_SELECTOR_HEIGHT.write() {
@@ -2013,7 +2013,7 @@ pub fn color_selector_font() -> String {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("color_selector_font") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=');
+ let rest = rest.trim_start_matches([' ', '=']);
let rest = rest.trim();
let val_str = if rest.starts_with('"') && rest.ends_with('"') && rest.len() >= 2 {
&rest[1..rest.len() - 1]
@@ -2508,7 +2508,7 @@ pub fn list_justification() -> u8 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("list_justification") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<u8>() {
if let Ok(mut lock) = LIST_JUSTIFICATION.write() {
@@ -2540,7 +2540,7 @@ pub fn section_label_font() -> String {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("section_label_font") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=');
+ let rest = rest.trim_start_matches([' ', '=']);
let rest = rest.trim();
let val_str = if rest.starts_with('"') && rest.ends_with('"') && rest.len() >= 2 {
&rest[1..rest.len() - 1]
@@ -2578,7 +2578,7 @@ pub fn nested_section_label_font() -> String {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("nested_section_label_font") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=');
+ let rest = rest.trim_start_matches([' ', '=']);
let rest = rest.trim();
let val_str = if rest.starts_with('"') && rest.ends_with('"') && rest.len() >= 2 {
&rest[1..rest.len() - 1]
@@ -2616,7 +2616,7 @@ pub fn breadcrumb_font() -> String {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("breadcrumb_font") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=');
+ let rest = rest.trim_start_matches([' ', '=']);
let rest = rest.trim();
let val_str = if rest.starts_with('"') && rest.ends_with('"') && rest.len() >= 2 {
&rest[1..rest.len() - 1]
@@ -2654,7 +2654,7 @@ pub fn button_font() -> String {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("button_font") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=');
+ let rest = rest.trim_start_matches([' ', '=']);
let rest = rest.trim();
let val_str = if rest.starts_with('"') && rest.ends_with('"') && rest.len() >= 2 {
&rest[1..rest.len() - 1]
@@ -2760,7 +2760,7 @@ pub fn spinbox_button_padding() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("spinbox_button_padding") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = SPINBOX_BUTTON_PADDING.write() {
@@ -2782,7 +2782,7 @@ pub fn scrollbar_width() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("scrollbar_width") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = SCROLLBAR_WIDTH.write() {
@@ -2824,7 +2824,7 @@ pub fn scrollbar_inset() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("scrollbar_inset") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = SCROLLBAR_INSET.write() {
@@ -2846,7 +2846,7 @@ pub fn tree_opacity() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("tree_opacity") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = TREE_OPACITY.write() {
@@ -2874,7 +2874,7 @@ pub fn tree_blur() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("tree_blur") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = TREE_BLUR.write() {
@@ -3198,7 +3198,7 @@ pub fn color_selector_preview_margin() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("color_selector_preview_margin") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = COLOR_SELECTOR_PREVIEW_MARGIN.write() {
@@ -3228,7 +3228,7 @@ pub fn paginator_tab_padding_x() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("paginator_tab_padding_x") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = PAGINATOR_TAB_PADDING_X.write() {
@@ -3257,7 +3257,7 @@ pub fn button_padding() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("button_padding") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = BUTTON_PADDING.write() {
@@ -3271,7 +3271,7 @@ pub fn button_padding() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("paginator_tab_padding_y") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = BUTTON_PADDING.write() {
@@ -3300,7 +3300,7 @@ pub fn button_height() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("button_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = BUTTON_HEIGHT.write() {
@@ -3322,7 +3322,7 @@ pub fn ramp_height() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("ramp_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = RAMP_HEIGHT.write() {
@@ -3356,7 +3356,7 @@ pub fn button_strip_spacing() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("button_strip_spacing") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = BUTTON_STRIP_SPACING.write() {
@@ -3392,7 +3392,7 @@ pub fn textbox_height() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("textbox_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = TEXTBOX_HEIGHT.write() {
@@ -3420,7 +3420,7 @@ pub fn dropdown_height() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("dropdown_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = DROPDOWN_HEIGHT.write() {
@@ -3448,7 +3448,7 @@ pub fn slider_height() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("slider_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = SLIDER_HEIGHT.write() {
@@ -3476,7 +3476,7 @@ pub fn progressbar_height() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("progressbar_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = PROGRESSBAR_HEIGHT.write() {
@@ -3504,7 +3504,7 @@ pub fn rangeslider_height() -> f32 {
for line in content.lines() {
let trimmed = line.trim();
if let Some(rest) = trimmed.strip_prefix("rangeslider_height") {
- let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+ let rest = rest.trim_start_matches([' ', '=', '"']);
let val_str = rest.trim_end_matches('"').trim();
if let Ok(val) = val_str.parse::<f32>() {
if let Ok(mut lock) = RANGESLIDER_HEIGHT.write() {
diff --git a/src/layout/registry.rs b/src/layout/registry.rs
index 2533539..f067856 100644
--- a/src/layout/registry.rs
+++ b/src/layout/registry.rs
@@ -118,7 +118,6 @@ impl StyleRegistry {
#[cfg(test)]
{
test_overlay::set_float(key, val);
- return;
}
#[cfg(not(test))]
self.load_float(key, val);
@@ -128,7 +127,6 @@ impl StyleRegistry {
#[cfg(test)]
{
test_overlay::set_len(key, len);
- return;
}
#[cfg(not(test))]
self.load_len(key, len);
@@ -138,7 +136,6 @@ impl StyleRegistry {
#[cfg(test)]
{
test_overlay::set_string(key, val);
- return;
}
#[cfg(not(test))]
self.load_string(key, val);
diff --git a/src/lib.rs b/src/lib.rs
index a211116..77f6309 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -156,7 +156,7 @@ pub fn icon_pixels(name: &str, px: u32, tint: Option<[u8; 3]>) -> Option<(Vec<u8
let data = std::fs::read(&path).ok()?;
let (mut rgba, w, h) = rasterize_svg(&data, px)?;
if let Some(rgb) = tint {
- for p in rgba.chunks_exact_mut(4) {
+ for p in rgba.as_chunks_mut::<4>().0 {
for (c, &t) in p[..3].iter_mut().zip(rgb.iter()) {
*c = ((*c as u16 * t as u16 + 127) / 255) as u8;
}
@@ -231,7 +231,7 @@ pub fn rasterize_svg(data: &[u8], px: u32) -> Option<(Vec<u8>, u32, u32)> {
);
// tiny-skia pixels are premultiplied; the upload path takes straight RGBA.
let mut rgba = pixmap.take();
- for p in rgba.chunks_exact_mut(4) {
+ for p in rgba.as_chunks_mut::<4>().0 {
let a = p[3] as f32 / 255.0;
if a > 0.0 {
p[0] = ((p[0] as f32 / a).min(255.0)) as u8;
diff --git a/src/main.rs b/src/main.rs
index 1f90b3d..e838868 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -620,7 +620,7 @@ impl Application for DemoApp {
needs_rebuild: &mut bool,
) {
let (px, py) = (pos.x, pos.y);
- let ev = Event::MouseWheel { delta: delta.clone(), x: px, y: py, local_x: px, local_y: py };
+ let ev = Event::MouseWheel { delta: *delta, x: px, y: py, local_x: px, local_y: py };
let mut changed = false;
// Wheel is hit-scoped per widget (the slider nudges its value under the
// cursor); roots that miss return false.
diff --git a/src/scene/heightfield.rs b/src/scene/heightfield.rs
index e4216b1..4a2a4bf 100644
--- a/src/scene/heightfield.rs
+++ b/src/scene/heightfield.rs
@@ -243,7 +243,7 @@ impl HeightField {
continue;
}
let shape = p.shape.clamp(2.0, 16.0);
- if profiles.as_ref().map_or(true, |(s, _)| (*s - shape).abs() > 1e-3) {
+ if profiles.as_ref().is_none_or(|(s, _)| (*s - shape).abs() > 1e-3) {
profiles = Some((shape, Profiles::build(shape)));
}
let prof = &profiles.as_ref().unwrap().1;
@@ -478,9 +478,9 @@ pub fn export_png(hf: &HeightField, path: &Path, mm_per_sample: Option<f32>) ->
let mut enc = png::Encoder::new(std::io::BufWriter::new(file), w as u32, h as u32);
enc.set_color(png::ColorType::Grayscale);
enc.set_depth(png::BitDepth::Sixteen);
- let mut writer = enc.write_header().map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
- writer.write_image_data(&bytes).map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
- writer.finish().map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
+ let mut writer = enc.write_header().map_err(std::io::Error::other)?;
+ writer.write_image_data(&bytes).map_err(std::io::Error::other)?;
+ writer.finish().map_err(std::io::Error::other)?;
let side = serde_json::json!({
"width": w,
"height": h,
diff --git a/src/scene/material.rs b/src/scene/material.rs
index 445d9b0..f41094f 100644
--- a/src/scene/material.rs
+++ b/src/scene/material.rs
@@ -735,8 +735,8 @@ mod tests {
assert!(retired("frost radius=(f64)3.0 compression=(f64)0.4 refraction=(f64)0.1").is_empty());
assert_eq!(load("frost backdrop_compression=(f64)0.2"), (true, frosted(0.4, 0.1, 3.0)), "the old knob name inside the block is ignored; unset knobs keep their last value");
assert_eq!(retired("frost backdrop_compression=(f64)0.2"), vec!["style.surface.plate.frost.backdrop_compression"]);
- assert_eq!(load("frost").0, true, "a bare `frost` is frosted");
- assert_eq!(load("frost (bool)false").0, false);
+ assert!(load("frost").0, "a bare `frost` is frosted");
+ assert!(!load("frost (bool)false").0);
// `from_style` is the RECIPE, `plate_blur` the switch: the retired
// keys flip neither — the switch stays off and the radius stays 3.
assert_eq!(load("blur (bool)true\n radius (f64)2.0"), (false, frosted(0.4, 0.1, 3.0)), "the retired spelling frosts nothing and moves nothing");
diff --git a/src/scene/paint.rs b/src/scene/paint.rs
index 3693a94..b2d2305 100644
--- a/src/scene/paint.rs
+++ b/src/scene/paint.rs
@@ -2040,7 +2040,7 @@ mod tests {
.items
.iter()
.find_map(|it| match &it.prim {
- Prim::Plate { radii, .. } => Some(radii.clone()),
+ Prim::Plate { radii, .. } => Some(*radii),
_ => None,
})
.expect("plate_spec emits a Prim::Plate");
@@ -2143,7 +2143,7 @@ mod tests {
ctx.rounded_rect(r(0.0, 0.0, 1.0, 1.0), 2.0, (true, false, true, false), [0.0; 4]);
ctx.border(r(0.0, 0.0, 10.0, 10.0), (2.0, 2.0, 2.0, 2.0), [0.1; 4], [0.9; 4], 1.5);
ctx.bevel(r(0.0, 0.0, 10.0, 10.0), (2.0, 2.0, 2.0, 2.0), &Material::opaque([0.3; 4]), 2.0);
- ctx.arc(5.0, 5.0, 4.0, 1.0, 0.0, 3.14, [0.0; 4]);
+ ctx.arc(5.0, 5.0, 4.0, 1.0, 0.0, std::f32::consts::PI, [0.0; 4]);
ctx.vector(0.0, 0.0, 10.0, 0.0, 1.0, [0.0; 4], Cap::Arrow);
ctx.circle(5.0, 5.0, 3.0, [0.0; 4]);
ctx.text("hi", 1.0, 2.0, 12.0, [255, 255, 255]);
diff --git a/src/scene/tree.rs b/src/scene/tree.rs
index 15702fc..9f150a9 100644
--- a/src/scene/tree.rs
+++ b/src/scene/tree.rs
@@ -268,6 +268,9 @@ mod tests {
/// Owns marker widgets and hands out stable raw pointers + ids for them.
struct Widgets {
+ // Boxed: each marker's address must not move as the Vec grows (the tree holds
+ // raw pointers to them).
+ #[allow(clippy::vec_box)]
boxes: Vec<Box<Marker>>,
}
impl Widgets {
@@ -276,7 +279,7 @@ mod tests {
}
/// Create a widget, returning `(WidgetId, *mut dyn WidgetHost)`.
fn make(&mut self, tag: u32) -> (WidgetId, *mut (dyn WidgetHost + 'static)) {
- let mut b = Box::new(Marker { base: crate::widget::Widget::new(), tag: tag });
+ let mut b = Box::new(Marker { base: crate::widget::Widget::new(), tag });
let ptr: *mut (dyn WidgetHost + 'static) = &mut *b;
self.boxes.push(b);
(WidgetId(tag as usize), ptr)
diff --git a/src/vk/image.rs b/src/vk/image.rs
index 74821f3..4c739ec 100644
--- a/src/vk/image.rs
+++ b/src/vk/image.rs
@@ -597,7 +597,7 @@ impl ImageStage {
let staging = self.staging_for(device, allocator, total);
let mapped = staging.allocation.as_mut().unwrap().mapped_slice_mut().unwrap();
for (item, &at) in run.iter().zip(&offsets) {
- mapped[at..at + item.pixels.len()].copy_from_slice(&item.pixels);
+ mapped[at..at + item.pixels.len()].copy_from_slice(item.pixels);
}
staging.buffer
};
diff --git a/src/vk/renderer.rs b/src/vk/renderer.rs
index cd68810..b534817 100644
--- a/src/vk/renderer.rs
+++ b/src/vk/renderer.rs
@@ -1133,9 +1133,7 @@ impl VkRenderer {
let data = window_info_data(self.extent, self.clip_corner_radius(), relief);
self.relief_uploaded = relief;
// Every pixel shades differently now: no image may be patched.
- for age in &mut self.image_ages {
- *age = ImageAge::Unknown;
- }
+ self.image_ages.fill(ImageAge::Unknown);
self.profile_gen = crate::layout::bevel_profile_generation();
self.roll_profile_gen = crate::layout::roll_profile_generation();
if let Some(allocation) = self.window_info.allocation.as_mut() {
diff --git a/src/widget/container/container_layout.rs b/src/widget/container/container_layout.rs
index 3dd3668..88ebe85 100644
--- a/src/widget/container/container_layout.rs
+++ b/src/widget/container/container_layout.rs
@@ -556,13 +556,12 @@ impl Packer {
let mut best_x = f32::MAX;
for (idx, &(rx, ry, rw, rh)) in self.free_rects.iter().enumerate() {
- if rw >= cw_clamped && rh >= ch {
- if ry < best_y || (ry == best_y && rx < best_x) {
+ if rw >= cw_clamped && rh >= ch
+ && (ry < best_y || (ry == best_y && rx < best_x)) {
best_y = ry;
best_x = rx;
best_idx = Some(idx);
}
- }
}
let chosen_idx = match best_idx {
diff --git a/src/widget/container/menu.rs b/src/widget/container/menu.rs
index 2e812ea..efa942b 100644
--- a/src/widget/container/menu.rs
+++ b/src/widget/container/menu.rs
@@ -247,7 +247,7 @@ impl MenuBar {
}
fn bg_color(&self) -> [f32; 4] {
- self.color.unwrap_or_else(|| colors::sidebar_bg_color())
+ self.color.unwrap_or_else(colors::sidebar_bg_color)
}
/// Position the embedded strip inside `rect` — the legacy `set_rect` body, minus the
@@ -953,8 +953,8 @@ impl Input for MenuBar {
}
if let Some((dx, dy, dw, dh)) = self.context_popover_rect(rect) {
- if px >= dx && px < dx + dw && py >= dy && py < dy + dh {
- if state == ElementState::Pressed {
+ if px >= dx && px < dx + dw && py >= dy && py < dy + dh
+ && state == ElementState::Pressed {
let di = ((py - dy) / DROPDOWN_ITEM_H) as usize;
if di < self.context_options.len() {
self.context_selected = di;
@@ -967,7 +967,6 @@ impl Input for MenuBar {
return true;
}
}
- }
}
if !self.context_options.is_empty() {
diff --git a/src/widget/container/parameters_bg.rs b/src/widget/container/parameters_bg.rs
index c7cd242..6ce9836 100644
--- a/src/widget/container/parameters_bg.rs
+++ b/src/widget/container/parameters_bg.rs
@@ -966,60 +966,44 @@ impl ParametersBg {
/// in the roster since the same day, having had no hover before.
fn hover_controls(&mut self, px: f32, py: f32, ui: &mut UiContext) -> bool {
let mut changed = false;
- for s_opt in &mut self.sliders {
- if let Some(s) = s_opt {
- if s.on_cursor_moved(px, py, ui) {
- changed = true;
- }
+ for s in self.sliders.iter_mut().flatten() {
+ if s.on_cursor_moved(px, py, ui) {
+ changed = true;
}
}
- for sb_opt in &mut self.spinboxes {
- if let Some(sb) = sb_opt {
- if sb.on_cursor_moved(px, py, ui) {
- changed = true;
- }
+ for sb in self.spinboxes.iter_mut().flatten() {
+ if sb.on_cursor_moved(px, py, ui) {
+ changed = true;
}
}
- for f_opt in &mut self.float3s {
- if let Some(f) = f_opt {
- if f.on_cursor_moved(px, py, ui) {
- changed = true;
- }
+ for f in self.float3s.iter_mut().flatten() {
+ if f.on_cursor_moved(px, py, ui) {
+ changed = true;
}
}
- for b_opt in &mut self.buttons {
- if let Some(b) = b_opt {
- if b.on_cursor_moved(px, py, ui) {
- changed = true;
- }
+ for b in self.buttons.iter_mut().flatten() {
+ if b.on_cursor_moved(px, py, ui) {
+ changed = true;
}
}
- for d_opt in &mut self.choices {
- if let Some(d) = d_opt {
- if d.on_cursor_moved(px, py, ui) {
- changed = true;
- }
+ for d in self.choices.iter_mut().flatten() {
+ if d.on_cursor_moved(px, py, ui) {
+ changed = true;
}
}
- for tb_opt in &mut self.texts {
- if let Some(tb) = tb_opt {
- if tb.on_cursor_moved(px, py, ui) {
- changed = true;
- }
+ for tb in self.texts.iter_mut().flatten() {
+ if tb.on_cursor_moved(px, py, ui) {
+ changed = true;
}
}
- for cb_opt in &mut self.toggles {
- if let Some(cb) = cb_opt {
- if cb.on_cursor_moved(px, py, ui) {
- changed = true;
- }
+ for cb in self.toggles.iter_mut().flatten() {
+ if cb.on_cursor_moved(px, py, ui) {
+ changed = true;
}
}
- for c_opt in &mut self.colors {
- if let Some(c) = c_opt {
- if c.on_cursor_moved(px, py, ui) {
- changed = true;
- }
+ for c in self.colors.iter_mut().flatten() {
+ if c.on_cursor_moved(px, py, ui) {
+ changed = true;
}
}
// Ramp rows: a move can drag a key — re-serialize the curve
@@ -1422,23 +1406,19 @@ impl ParametersBg {
/// ([`Paint::popover`]); the raw `children`'s popovers are the adapter's recursion.
/// The ramp rows' field dropdowns count too.
fn choices_popover_rect(&self) -> Option<(f32, f32, f32, f32)> {
- for d_opt in &self.choices {
- if let Some(d) = d_opt {
- if let Some(r) = d.popover_rect() {
- return Some(r);
- }
+ for d in self.choices.iter().flatten() {
+ if let Some(r) = d.popover_rect() {
+ return Some(r);
}
}
- for rp_opt in &self.ramps {
- if let Some(rp) = rp_opt {
- let ramp = rp.inner();
- if let Some(r) = ramp
- .preset_dropdown
- .popover_rect()
- .or_else(|| ramp.line_type_dropdown.popover_rect())
- {
- return Some(r);
- }
+ for rp in self.ramps.iter().flatten() {
+ let ramp = rp.inner();
+ if let Some(r) = ramp
+ .preset_dropdown
+ .popover_rect()
+ .or_else(|| ramp.line_type_dropdown.popover_rect())
+ {
+ return Some(r);
}
}
None
@@ -2206,7 +2186,7 @@ impl Paint for ParametersBg {
// section's well spans many rows, so it never qualifies.
let hover_rect = self.hover_row.and_then(|i| self.get_param_rects().get(i).copied()).filter(|r| r.3 > 0.0);
let hovered = |x: f32, y: f32, w: f32, h: f32| {
- hover_rect.map_or(false, |(rx, ry, rw, rh)| {
+ hover_rect.is_some_and(|(rx, ry, rw, rh)| {
x >= rx - 0.5 && y >= ry - 0.5 && x + w <= rx + rw + 0.5 && y + h <= ry + rh + 0.5
})
};
@@ -2327,16 +2307,12 @@ impl Paint for ParametersBg {
/// The dropdown rows' popovers; the raw children's are the adapter's recursion.
fn draw_popover(&self, _rect: Rect, pc: &mut dyn crate::layout::RenderTarget) {
- for d_opt in &self.choices {
- if let Some(d) = d_opt {
- d.render_popover(pc);
- }
+ for d in self.choices.iter().flatten() {
+ d.render_popover(pc);
}
- for rp_opt in &self.ramps {
- if let Some(rp) = rp_opt {
- rp.inner().preset_dropdown.render_popover(pc);
- rp.inner().line_type_dropdown.render_popover(pc);
- }
+ for rp in self.ramps.iter().flatten() {
+ rp.inner().preset_dropdown.render_popover(pc);
+ rp.inner().line_type_dropdown.render_popover(pc);
}
}
}
@@ -2503,18 +2479,14 @@ impl Input for ParametersBg {
// in the host tree), and without it every params-pane dropdown opened
// at zero drawn extent: logically open, invisible, reporting a sliver
// popover rect — and the next click toggled it closed again.
- for c_opt in &mut self.choices {
- if let Some(d) = c_opt {
- if d.tick(dt, &mut dummy) {
- changed = true;
- }
+ for d in self.choices.iter_mut().flatten() {
+ if d.tick(dt, &mut dummy) {
+ changed = true;
}
}
- for cb_opt in &mut self.toggles {
- if let Some(cb) = cb_opt {
- if cb.tick(dt, &mut dummy) {
- changed = true;
- }
+ for cb in self.toggles.iter_mut().flatten() {
+ if cb.tick(dt, &mut dummy) {
+ changed = true;
}
}
// Slider rows tick their wheel-glide inertia — fold a coasting value
@@ -2706,13 +2678,12 @@ impl Input for ParametersBg {
}
return true;
}
- } else if state == ElementState::Released {
- if self.scrollbar_dragging {
+ } else if state == ElementState::Released
+ && self.scrollbar_dragging {
self.scrollbar_dragging = false;
self.activity.bump();
return true;
}
- }
}
// A press on a section's title box collapses/expands it. Checked before the
@@ -2793,14 +2764,12 @@ impl Input for ParametersBg {
}
if let Some(rp) = rp_opt {
let ramp = rp.inner();
- if ramp.preset_dropdown.popover_rect().is_some()
- || ramp.line_type_dropdown.popover_rect().is_some()
- {
- if rp.mouse_input(button, state, px, py, ui) {
+ if (ramp.preset_dropdown.popover_rect().is_some()
+ || ramp.line_type_dropdown.popover_rect().is_some())
+ && rp.mouse_input(button, state, px, py, ui) {
self.display_params[i].1 = rp.inner().spec_string();
return true;
}
- }
}
}
@@ -3456,8 +3425,8 @@ impl Input for ParametersBg {
}
}
}
- } else if p.2.starts_with("spinbox") {
- if owner == Some(i) {
+ } else if p.2.starts_with("spinbox")
+ && owner == Some(i) {
if let Some(sb) = &mut self.spinboxes[i] {
// The widget's own wheel arm: one step per
// notch, fractions carried between events.
@@ -3474,7 +3443,6 @@ impl Input for ParametersBg {
}
}
}
- }
}
// The legacy tail's `self.hit_test(px, py, ctx)`: occlusion via the adapter's
@@ -3485,7 +3453,7 @@ impl Input for ParametersBg {
&& px <= self.rect.x + self.rect.width
&& py >= self.rect.y
&& py <= self.rect.y + self.rect.height;
- let in_popover = self.own_popover_rect().map_or(false, |(rx, ry, rw, rh)| {
+ let in_popover = self.own_popover_rect().is_some_and(|(rx, ry, rw, rh)| {
px >= rx && px <= rx + rw && py >= ry && py <= ry + rh
});
if in_rect || in_popover {
@@ -3619,7 +3587,7 @@ fn parse_spinbox_range(ptype: &str) -> (i32, i32, i32) {
fn parse_vec_value(val_str: &str, min: f32, max: f32, n: usize) -> Vec<f32> {
let mut out = vec![0.5; n];
let parts: Vec<&str> = val_str
- .split(|c| c == ':' || c == ',' || c == ' ')
+ .split([':', ',', ' '])
.filter(|s| !s.is_empty())
.collect();
for i in 0..n {
@@ -3907,8 +3875,7 @@ fn apply_code_action(
fn get_cursor_line_col(buffer: &str, cursor_idx: usize) -> (usize, usize) {
let mut cur_line = 0;
let mut cur_col = 0;
- let mut count = 0;
- for c in buffer.chars() {
+ for (count, c) in buffer.chars().enumerate() {
if count == cursor_idx {
return (cur_line, cur_col);
}
@@ -3918,7 +3885,6 @@ fn get_cursor_line_col(buffer: &str, cursor_idx: usize) -> (usize, usize) {
} else {
cur_col += 1;
}
- count += 1;
}
(cur_line, cur_col)
}
@@ -4641,7 +4607,7 @@ mod tests {
// Every corner hands off to a straight run — no arc dangles. (Within a stroke width:
// runs and arcs are anchored on opposite ink sides at the concave corner.)
- let ends: Vec<(f32, f32)> = runs.iter().flat_map(|r| run_ends(r)).collect();
+ let ends: Vec<(f32, f32)> = runs.iter().flat_map(run_ends).collect();
for arc in &arcs {
for (ax, ay) in arc_ends(arc) {
let nearest = ends
@@ -4714,7 +4680,7 @@ mod tests {
// Section to section stays far wider, so the blocks still read apart.
assert_eq!(title_top(2) - content_bottom(1), SECTION_GAP, "section -> next section");
- assert!(SECTION_GAP > 2.0 * CHANNEL, "sections separate wider than any channel");
+ const { assert!(SECTION_GAP > 2.0 * CHANNEL, "sections separate wider than any channel") };
}
#[test]
@@ -4825,7 +4791,7 @@ mod tests {
ParamController::set_display_params(&mut *p, &rows);
WidgetHost::set_rect(&mut p, 0.0, 0.0, 300.0, 200.0);
let hovered = |p: &Adapted<ParametersBg>| -> Vec<usize> {
- p.sliders.iter().enumerate().filter(|(_, s)| s.as_ref().map_or(false, |s| s.inner().hovered())).map(|(i, _)| i).collect()
+ p.sliders.iter().enumerate().filter(|(_, s)| s.as_ref().is_some_and(|s| s.inner().hovered())).map(|(i, _)| i).collect()
};
assert!(hovered(&p).is_empty());
@@ -4922,7 +4888,7 @@ mod tests {
_ => None,
};
let at_rest = prims(&p, &ctx);
- assert!(at_rest.iter().all(|pr| carve(pr).map_or(true, |(_, t)| t.is_none())), "nothing is tinted at rest");
+ assert!(at_rest.iter().all(|pr| carve(pr).is_none_or(|(_, t)| t.is_none())), "nothing is tinted at rest");
assert_eq!(label_of(&p, "Count"), ParametersBg::LABEL);
let (x, y, w, h) = p.get_param_rects()[1];
diff --git a/src/widget/container/spreadsheet.rs b/src/widget/container/spreadsheet.rs
index d92bc6e..9546557 100644
--- a/src/widget/container/spreadsheet.rs
+++ b/src/widget/container/spreadsheet.rs
@@ -1134,7 +1134,7 @@ mod tests {
fn a_half_scrolled_row_draws_its_text_cut_at_the_body() {
let rect = Rect { x: 0.0, y: 0.0, width: 200.0, height: 124.0 };
let mut s = filled(20);
- (*s).scroll_y = ROW_H * 0.5;
+ s.scroll_y = ROW_H * 0.5;
let mut pc = crate::scene::paint::PaintCtx::new();
Paint::paint(&*s, rect, &mut pc);
let items = pc.finish().items;
@@ -1215,7 +1215,7 @@ mod tests {
let rect = Rect { x: 0.0, y: 0.0, width: 200.0, height: 124.0 };
let mut s = wide(6);
assert_eq!((*s).header_col_at(10.0, 5.0, rect), Some(0));
- (*s).scroll_x = (*s).col_edges()[1];
+ s.scroll_x = (*s).col_edges()[1];
assert_eq!((*s).header_col_at(10.0, 5.0, rect), Some(1));
}
@@ -1243,8 +1243,8 @@ mod tests {
}
let rect = Rect { x: 0.0, y: 0.0, width: 200.0, height: 124.0 };
let max = (*s).hgeom(rect).unwrap().max_scroll;
- assert!((*s).scroll_x >= 0.0 && (*s).scroll_x <= max, "h-scroll stays clamped");
- assert!((*s).scroll_x > 0.0, "negative dx scrolled the columns (ScrollRegion sign convention)");
+ assert!(s.scroll_x >= 0.0 && s.scroll_x <= max, "h-scroll stays clamped");
+ assert!(s.scroll_x > 0.0, "negative dx scrolled the columns (ScrollRegion sign convention)");
// A pane whose columns fit ignores horizontal wheels.
let mut fits = wide(2);
diff --git a/src/widget/container/treelist.rs b/src/widget/container/treelist.rs
index cdff52a..ecdfdaa 100644
--- a/src/widget/container/treelist.rs
+++ b/src/widget/container/treelist.rs
@@ -529,8 +529,8 @@ impl TreeList {
}
}
- if button == MouseButton::Right && state == ElementState::Pressed && !covered {
- if px >= list_left && px <= list_left + list_width && py >= list_top && py <= list_bottom {
+ if button == MouseButton::Right && state == ElementState::Pressed && !covered
+ && px >= list_left && px <= list_left + list_width && py >= list_top && py <= list_bottom {
// SAFETY: `host` is this widget's own adapter, live while its event is routed.
if let Some(h) = host { unsafe { ui.set_focused_ptr(h) }; }
let relative_y = py - list_top + self.scroll_box.scroll_y;
@@ -579,7 +579,6 @@ impl TreeList {
}
}
}
- }
changed
}
@@ -592,11 +591,10 @@ impl TreeList {
if self.add_key_btn.on_cursor_moved(px, py, ui) {
changed = true;
}
- if self.add_key_popover_open {
- if self.add_key_popover_box.on_cursor_moved(px, py, ui) {
+ if self.add_key_popover_open
+ && self.add_key_popover_box.on_cursor_moved(px, py, ui) {
changed = true;
}
- }
let list_left = self.scroll_box.base.x;
let list_width = self.scroll_box.base.w;
@@ -623,16 +621,14 @@ impl TreeList {
}
fn key_body(&mut self, event: &KeyEvent, ui: &mut UiContext) -> bool {
- if self.editing_key_idx.is_some() {
- if self.edit_box.keyboard_input(event, ui) {
+ if self.editing_key_idx.is_some()
+ && self.edit_box.keyboard_input(event, ui) {
return true;
}
- }
- if self.add_key_popover_open {
- if self.add_key_popover_box.keyboard_input(event, ui) {
+ if self.add_key_popover_open
+ && self.add_key_popover_box.keyboard_input(event, ui) {
return true;
}
- }
if self.search_box.keyboard_input(event, ui) {
return true;
}
@@ -884,7 +880,7 @@ impl Paint for TreeList {
let grid_size = 8.0;
quads.push((preview_x, preview_draw_y, 16.0, preview_draw_h, 0.0, [1.0, 1.0, 1.0, 1.0], (false, false, false, false)));
let cols = (16.0f32 / grid_size).ceil() as i32;
- let rows = (preview_draw_h as f32 / grid_size).ceil() as i32;
+ let rows = (preview_draw_h / grid_size).ceil() as i32;
for r in 0..rows {
for c in 0..cols {
if (r + c) % 2 == 1 {
@@ -1209,7 +1205,7 @@ impl Input for TreeList {
self.move_body(px, py, ui)
}
Event::MouseWheel { delta, x, y, .. } => {
- let (delta, px, py) = (delta.clone(), *x, *y);
+ let (delta, px, py) = (*delta, *x, *y);
let Some(ui) = ectx.ui.as_deref_mut() else { return false; };
self.scroll_box.mouse_wheel(&delta, px, py, ui)
}
@@ -1391,6 +1387,216 @@ fn parse_hex_f32(s: &str) -> Option<[f32; 4]> {
unsafe impl Send for TreeList {}
unsafe impl Sync for TreeList {}
+impl TreeList {
+ /// Row/header labels plus each label's column clip: the x where its
+ /// column ends (None = only the shared list/header bounds apply). Key and
+ /// Type cells clip at their separators so text can't bleed into the next
+ /// column; sections span the whole row.
+ /// The section-row chevron (cce-icons), cached per size by `upload_icon`;
+ /// `None` when the icon set is missing (the slot is left empty).
+ fn chevron_icon(collapsed: bool) -> Option<(u32, u32, u32)> {
+ crate::upload_icon(if collapsed { "chevron-right" } else { "chevron-down" }, 32)
+ }
+
+ pub(crate) fn own_labels(&self) -> Vec<(TextLabel, Option<f32>)> {
+ let f32_to_rgb = |c: [f32; 4]| -> [u8; 3] {
+ [
+ (crate::color::linear_to_srgb(c[0]) * 255.0).round() as u8,
+ (crate::color::linear_to_srgb(c[1]) * 255.0).round() as u8,
+ (crate::color::linear_to_srgb(c[2]) * 255.0).round() as u8,
+ ]
+ };
+
+ let (_, tree_font_size) = crate::layout::tree_font_parsed();
+ let header_font_size = (tree_font_size - 1.0).max(8.0);
+
+ let mut labels = Vec::new();
+ let list_left = self.scroll_box.base.x;
+ let list_top = self.scroll_box.viewport_y;
+ let list_bottom = self.scroll_box.viewport_y + self.scroll_box.viewport_h;
+
+ let search_margin_y = 6.0;
+ let search_h = 26.0;
+ let offset_y = search_h + 2.0 * search_margin_y;
+
+ labels.push((TextLabel {
+ text: "Key".to_string(),
+ x: list_left + 8.0,
+ y: self.base.y + offset_y + 6.0,
+ font_size: header_font_size,
+ color: [200, 200, 210],
+ }, None));
+ labels.push((TextLabel {
+ text: "Type".to_string(),
+ x: list_left + 180.0 + 8.0,
+ y: self.base.y + offset_y + 6.0,
+ font_size: header_font_size,
+ color: [200, 200, 210],
+ }, None));
+ labels.push((TextLabel {
+ text: "Value".to_string(),
+ x: list_left + 235.0 + 8.0,
+ y: self.base.y + offset_y + 6.0,
+ font_size: header_font_size,
+ color: [200, 200, 210],
+ }, None));
+
+ for (i, item) in self.items.iter().enumerate() {
+ let row_y = list_top + i as f32 * self.item_height - self.scroll_box.scroll_y;
+ if row_y + self.item_height < list_top || row_y > list_bottom {
+ continue;
+ }
+
+ match item {
+ TreeElement::Section { name, indent, .. } => {
+ if self.editing_key_idx != Some(i) {
+ let sx = list_left + 8.0 + *indent as f32 * 12.0;
+ // The chevron glyph (cce-icons) stands in the slot
+ // this leaves open — paint() draws it. A machine
+ // without the icon set shows the slot empty: no
+ // symbol is drawn as a character.
+ let (text, tx) = (name.clone(), sx + tree_font_size + 6.0);
+ labels.push((TextLabel {
+ text,
+ x: tx,
+ y: row_y + 6.0,
+ font_size: tree_font_size,
+ color: f32_to_rgb(crate::color::tree_section_text_color()),
+ }, None));
+ }
+ }
+ TreeElement::Leaf { name, indent, val, original_idx, .. } => {
+ // A unit-suffixed string (`"2mm"`, what `(mm)2.0` reads
+ // as) shows as the length it is — `2 mm` — not a quoted
+ // string; its unit is its type below.
+ let len = val.as_str().and_then(crate::units::Len::parse);
+ let val_str = match len {
+ Some(l) => format!("{} {}", crate::units::fmt_num(l.value), l.unit.suffix()),
+ None => serde_json::to_string(val).unwrap_or_default(),
+ };
+ // Generous shaping cap only — the column bounds clip the
+ // visible text at the list edge. (char-based: the old
+ // byte slice could panic on multibyte text.)
+ let display_val = if val_str.chars().count() > 120 {
+ let cut: String = val_str.chars().take(117).collect();
+ format!("{}...", cut)
+ } else {
+ val_str
+ };
+
+ let color = if Some(*original_idx) == self.selected_key_idx {
+ f32_to_rgb(crate::color::tree_leaf_text_selected_color())
+ } else {
+ f32_to_rgb(crate::color::tree_leaf_text_color())
+ };
+
+ if self.editing_key_idx != Some(i) {
+ labels.push((TextLabel {
+ text: name.clone(),
+ x: list_left + 8.0 + *indent as f32 * 12.0,
+ y: row_y + 6.0,
+ font_size: tree_font_size,
+ color,
+ }, Some(list_left + 178.0)));
+ }
+
+ let val_ty = match val {
+ serde_json::Value::Bool(_) => Some("bool"),
+ serde_json::Value::Number(num) => {
+ if num.is_f64() {
+ Some("f64")
+ } else {
+ Some("i64")
+ }
+ }
+ serde_json::Value::String(s) => {
+ if s.starts_with('#') {
+ let s_clean = s.trim_start_matches('#');
+ if s_clean.len() == 8 {
+ Some("rgba")
+ } else {
+ Some("rgb")
+ }
+ } else if name == "key" || name == "keybind" || name == "shortcut" || name == "open_search" || name == "close_search" || name == "delete" || name.ends_with("_key") || name.ends_with(".key") || name.ends_with(".keybind") || name.ends_with(".shortcut") || name.ends_with(".open_search") || name.ends_with(".close_search") || name.ends_with("_delete") || name.ends_with(".delete") {
+ Some("keybind")
+ } else if name == "font" || name.ends_with("_font") || name.ends_with(".font") {
+ Some("font")
+ } else { len.map(|l| l.unit.suffix()) }
+ }
+ _ => None,
+ };
+ let mut display_ty = val_ty.map(|s| s.to_string());
+ if let Some(Some(ref anno)) = self.annotations.get(*original_idx) {
+ if anno.starts_with("menu:") {
+ display_ty = Some("menu".to_string());
+ } else if anno == "button" || anno.starts_with("button:") {
+ display_ty = Some("button".to_string());
+ } else {
+ display_ty = Some(anno.clone());
+ }
+ } else if display_ty.is_none() {
+ if let serde_json::Value::String(_) = val {
+ display_ty = Some("string".to_string());
+ }
+ }
+
+ if let Some(ty) = display_ty {
+ let ty_text = format!("({})", ty);
+ labels.push((TextLabel {
+ text: ty_text,
+ x: list_left + 190.0,
+ y: row_y + 6.0,
+ font_size: tree_font_size,
+ color: f32_to_rgb(crate::color::tree_type_text_color()),
+ }, Some(list_left + 233.0)));
+ }
+
+ if Some(*original_idx) != self.selected_key_idx {
+ let mut is_button = false;
+ if let Some(Some(ref anno)) = self.annotations.get(*original_idx) {
+ if anno == "button" || anno.starts_with("button:") {
+ is_button = true;
+ }
+ }
+
+ let is_color = if let serde_json::Value::String(s) = val {
+ s.starts_with('#')
+ } else {
+ false
+ };
+
+ let label_x = if is_color {
+ list_left + 267.0
+ } else {
+ list_left + 245.0
+ };
+
+ if is_button {
+ labels.push((TextLabel {
+ text: display_val,
+ x: list_left + 245.0 + 8.0,
+ y: row_y + 6.0,
+ font_size: tree_font_size,
+ color: [240, 240, 245],
+ }, None));
+ } else {
+ labels.push((TextLabel {
+ text: display_val,
+ x: label_x,
+ y: row_y + 6.0,
+ font_size: tree_font_size,
+ color: f32_to_rgb(crate::color::tree_value_text_color()),
+ }, None));
+ }
+ }
+ }
+ }
+ }
+ labels
+ }
+
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -1607,217 +1813,3 @@ mod tests {
assert_eq!(req, Some(("style.control.dropdown.color".to_string(), "style.control.dropdown.bg_color".to_string())));
}
}
-
-impl TreeList {
- /// Row/header labels plus each label's column clip: the x where its
- /// column ends (None = only the shared list/header bounds apply). Key and
- /// Type cells clip at their separators so text can't bleed into the next
- /// column; sections span the whole row.
- /// The section-row chevron (cce-icons), cached per size by `upload_icon`;
- /// `None` when the icon set is missing (the slot is left empty).
- fn chevron_icon(collapsed: bool) -> Option<(u32, u32, u32)> {
- crate::upload_icon(if collapsed { "chevron-right" } else { "chevron-down" }, 32)
- }
-
- pub(crate) fn own_labels(&self) -> Vec<(TextLabel, Option<f32>)> {
- let f32_to_rgb = |c: [f32; 4]| -> [u8; 3] {
- [
- (crate::color::linear_to_srgb(c[0]) * 255.0).round() as u8,
- (crate::color::linear_to_srgb(c[1]) * 255.0).round() as u8,
- (crate::color::linear_to_srgb(c[2]) * 255.0).round() as u8,
- ]
- };
-
- let (_, tree_font_size) = crate::layout::tree_font_parsed();
- let header_font_size = (tree_font_size - 1.0).max(8.0);
-
- let mut labels = Vec::new();
- let list_left = self.scroll_box.base.x;
- let list_top = self.scroll_box.viewport_y;
- let list_bottom = self.scroll_box.viewport_y + self.scroll_box.viewport_h;
-
- let search_margin_y = 6.0;
- let search_h = 26.0;
- let offset_y = search_h + 2.0 * search_margin_y;
-
- labels.push((TextLabel {
- text: "Key".to_string(),
- x: list_left + 8.0,
- y: self.base.y + offset_y + 6.0,
- font_size: header_font_size,
- color: [200, 200, 210],
- }, None));
- labels.push((TextLabel {
- text: "Type".to_string(),
- x: list_left + 180.0 + 8.0,
- y: self.base.y + offset_y + 6.0,
- font_size: header_font_size,
- color: [200, 200, 210],
- }, None));
- labels.push((TextLabel {
- text: "Value".to_string(),
- x: list_left + 235.0 + 8.0,
- y: self.base.y + offset_y + 6.0,
- font_size: header_font_size,
- color: [200, 200, 210],
- }, None));
-
- for (i, item) in self.items.iter().enumerate() {
- let row_y = list_top + i as f32 * self.item_height - self.scroll_box.scroll_y;
- if row_y + self.item_height < list_top || row_y > list_bottom {
- continue;
- }
-
- match item {
- TreeElement::Section { name, indent, .. } => {
- if self.editing_key_idx != Some(i) {
- let sx = list_left + 8.0 + *indent as f32 * 12.0;
- // The chevron glyph (cce-icons) stands in the slot
- // this leaves open — paint() draws it. A machine
- // without the icon set shows the slot empty: no
- // symbol is drawn as a character.
- let (text, tx) = (name.clone(), sx + tree_font_size + 6.0);
- labels.push((TextLabel {
- text,
- x: tx,
- y: row_y + 6.0,
- font_size: tree_font_size,
- color: f32_to_rgb(crate::color::tree_section_text_color()),
- }, None));
- }
- }
- TreeElement::Leaf { name, indent, val, original_idx, .. } => {
- // A unit-suffixed string (`"2mm"`, what `(mm)2.0` reads
- // as) shows as the length it is — `2 mm` — not a quoted
- // string; its unit is its type below.
- let len = val.as_str().and_then(crate::units::Len::parse);
- let val_str = match len {
- Some(l) => format!("{} {}", crate::units::fmt_num(l.value), l.unit.suffix()),
- None => serde_json::to_string(val).unwrap_or_default(),
- };
- // Generous shaping cap only — the column bounds clip the
- // visible text at the list edge. (char-based: the old
- // byte slice could panic on multibyte text.)
- let display_val = if val_str.chars().count() > 120 {
- let cut: String = val_str.chars().take(117).collect();
- format!("{}...", cut)
- } else {
- val_str
- };
-
- let color = if Some(*original_idx) == self.selected_key_idx {
- f32_to_rgb(crate::color::tree_leaf_text_selected_color())
- } else {
- f32_to_rgb(crate::color::tree_leaf_text_color())
- };
-
- if self.editing_key_idx != Some(i) {
- labels.push((TextLabel {
- text: name.clone(),
- x: list_left + 8.0 + *indent as f32 * 12.0,
- y: row_y + 6.0,
- font_size: tree_font_size,
- color,
- }, Some(list_left + 178.0)));
- }
-
- let val_ty = match val {
- serde_json::Value::Bool(_) => Some("bool"),
- serde_json::Value::Number(num) => {
- if num.is_f64() {
- Some("f64")
- } else {
- Some("i64")
- }
- }
- serde_json::Value::String(s) => {
- if s.starts_with('#') {
- let s_clean = s.trim_start_matches('#');
- if s_clean.len() == 8 {
- Some("rgba")
- } else {
- Some("rgb")
- }
- } else if name == "key" || name == "keybind" || name == "shortcut" || name == "open_search" || name == "close_search" || name == "delete" || name.ends_with("_key") || name.ends_with(".key") || name.ends_with(".keybind") || name.ends_with(".shortcut") || name.ends_with(".open_search") || name.ends_with(".close_search") || name.ends_with("_delete") || name.ends_with(".delete") {
- Some("keybind")
- } else if name == "font" || name.ends_with("_font") || name.ends_with(".font") {
- Some("font")
- } else if let Some(l) = len {
- Some(l.unit.suffix())
- } else {
- None
- }
- }
- _ => None,
- };
- let mut display_ty = val_ty.map(|s| s.to_string());
- if let Some(Some(ref anno)) = self.annotations.get(*original_idx) {
- if anno.starts_with("menu:") {
- display_ty = Some("menu".to_string());
- } else if anno == "button" || anno.starts_with("button:") {
- display_ty = Some("button".to_string());
- } else {
- display_ty = Some(anno.clone());
- }
- } else if display_ty.is_none() {
- if let serde_json::Value::String(_) = val {
- display_ty = Some("string".to_string());
- }
- }
-
- if let Some(ty) = display_ty {
- let ty_text = format!("({})", ty);
- labels.push((TextLabel {
- text: ty_text,
- x: list_left + 190.0,
- y: row_y + 6.0,
- font_size: tree_font_size,
- color: f32_to_rgb(crate::color::tree_type_text_color()),
- }, Some(list_left + 233.0)));
- }
-
- if Some(*original_idx) != self.selected_key_idx {
- let mut is_button = false;
- if let Some(Some(ref anno)) = self.annotations.get(*original_idx) {
- if anno == "button" || anno.starts_with("button:") {
- is_button = true;
- }
- }
-
- let is_color = if let serde_json::Value::String(s) = val {
- s.starts_with('#')
- } else {
- false
- };
-
- let label_x = if is_color {
- list_left + 267.0
- } else {
- list_left + 245.0
- };
-
- if is_button {
- labels.push((TextLabel {
- text: display_val,
- x: list_left + 245.0 + 8.0,
- y: row_y + 6.0,
- font_size: tree_font_size,
- color: [240, 240, 245],
- }, None));
- } else {
- labels.push((TextLabel {
- text: display_val,
- x: label_x,
- y: row_y + 6.0,
- font_size: tree_font_size,
- color: f32_to_rgb(crate::color::tree_value_text_color()),
- }, None));
- }
- }
- }
- }
- }
- labels
- }
-
-}
diff --git a/src/widget/core.rs b/src/widget/core.rs
index bc805e2..537bf25 100644
--- a/src/widget/core.rs
+++ b/src/widget/core.rs
@@ -9,7 +9,7 @@ pub mod focus {
// previous holder (`unfocus`) resolves through the caller's generational tree, so a
// stale id is skipped instead of dereferencing freed memory (the 6w settings UAF class).
thread_local! {
- static FOCUSED_WIDGET: Cell<Option<WidgetId>> = Cell::new(None);
+ static FOCUSED_WIDGET: Cell<Option<WidgetId>> = const { Cell::new(None) };
}
/// Resolve `id` in `ctx`'s tree (when a ctx is in reach) and call `unfocus()` on it.
@@ -137,7 +137,7 @@ pub mod hover_animation {
thread_local! {
pub static HOVER_STATE: RefCell<HoverState> = RefCell::new(HoverState::new());
- pub static CURSOR_POS: RefCell<(f32, f32)> = RefCell::new((0.0, 0.0));
+ pub static CURSOR_POS: RefCell<(f32, f32)> = const { RefCell::new((0.0, 0.0)) };
}
pub fn set_cursor_pos(x: f32, y: f32) {
@@ -326,33 +326,25 @@ pub mod clipboard {
}
pub fn read() -> Option<String> {
- match std::process::Command::new("wl-paste")
+ if let Ok(output) = std::process::Command::new("wl-paste")
.arg("-n")
- .output()
- {
- Ok(output) => {
- if output.status.success() {
- if let Ok(text) = String::from_utf8(output.stdout) {
- return Some(text);
- }
+ .output() {
+ if output.status.success() {
+ if let Ok(text) = String::from_utf8(output.stdout) {
+ return Some(text);
}
}
- Err(_) => {}
}
- match std::process::Command::new("xclip")
+ if let Ok(output) = std::process::Command::new("xclip")
.arg("-selection")
.arg("clipboard")
.arg("-o")
- .output()
- {
- Ok(output) => {
- if output.status.success() {
- if let Ok(text) = String::from_utf8(output.stdout) {
- return Some(text);
- }
+ .output() {
+ if output.status.success() {
+ if let Ok(text) = String::from_utf8(output.stdout) {
+ return Some(text);
}
}
- Err(_) => {}
}
None
}
@@ -1348,10 +1340,10 @@ pub mod context_menu {
}
}
self.hide();
- return true;
+ true
} else {
self.hide();
- return true;
+ true
}
}
diff --git a/src/widget/display/float3.rs b/src/widget/display/float3.rs
index 1ce130d..34a77a1 100644
--- a/src/widget/display/float3.rs
+++ b/src/widget/display/float3.rs
@@ -149,6 +149,7 @@ impl Float3 {
}
/// And back: a direction of the view's, in the vector's space.
+ #[allow(clippy::wrong_self_convention)] // a transform's inverse, beside `to_view`
fn from_view(&self, p: [f32; 3]) -> [f32; 3] {
[0, 1, 2].map(|k| self.view[0][k] * p[0] + self.view[1][k] * p[1] + self.view[2][k] * p[2])
}
@@ -619,8 +620,8 @@ impl Adapted<Float3> {
}
impl Layout for Float3 {
- /// The Slider convention: the label eats into the assigned rect, the host sizes the row
- /// for it ([`Float3::preferred_height`]).
+ // The Slider convention: the label eats into the assigned rect, the host sizes the row
+ // for it ([`Float3::preferred_height`]).
/// The three rows alone: the adapter adds the detached-label strip itself
/// (`Adapted::preferred_height`), as it does for every non-inflating widget.
@@ -1002,7 +1003,7 @@ mod tests {
let mut pc = PaintCtx::new();
f.paint_ball(&mut pc);
pc.finish().items.into_iter().find_map(|i| match i.prim {
- crate::scene::paint::Prim::Vector { x2, y2, thickness, .. } if thickness == 2.0 => Some((x2, y2)),
+ crate::scene::paint::Prim::Vector { x2, y2, thickness: 2.0, .. } => Some((x2, y2)),
_ => None,
}).expect("the vector's stroke")
};
@@ -1036,8 +1037,8 @@ mod tests {
// The rings are circles of latitude about the vector: every point
// on one is the same angle from it, whichever way it points.
- for dir in [[0.0, 0.0, 1.0], [0.3, 0.5, 0.4], [0.0, 1.0, 0.0], [-1.0, 0.0, 0.0]] {
- let l = (dir[0] * dir[0] + dir[1] * dir[1] + dir[2] * dir[2] as f32).sqrt();
+ for dir in [[0.0f32, 0.0, 1.0], [0.3, 0.5, 0.4], [0.0, 1.0, 0.0], [-1.0, 0.0, 0.0]] {
+ let l = (dir[0] * dir[0] + dir[1] * dir[1] + dir[2] * dir[2]).sqrt();
let d = dir.map(|c: f32| c / l);
for degrees in RING_ANGLES {
let ring = Float3::ring(dir, degrees, 24);
@@ -1067,7 +1068,7 @@ mod tests {
.items
.into_iter()
.filter_map(|i| match i.prim {
- crate::scene::paint::Prim::Vector { x1, y1, thickness, .. } if thickness == 1.0 => Some((x1, y1)),
+ crate::scene::paint::Prim::Vector { x1, y1, thickness: 1.0, .. } => Some((x1, y1)),
_ => None,
})
.collect()
diff --git a/src/widget/display/graph.rs b/src/widget/display/graph.rs
index 7af03f9..1810af6 100644
--- a/src/widget/display/graph.rs
+++ b/src/widget/display/graph.rs
@@ -621,7 +621,7 @@ impl Graph {
pub fn zoom_by_factor(&mut self, factor: f32) {
let new_w = self.node_w * factor;
- if new_w >= 40.0 && new_w <= 400.0 {
+ if (40.0..=400.0).contains(&new_w) {
self.scale_by(factor);
}
}
@@ -1224,7 +1224,7 @@ impl Input for Graph {
}
Event::MouseWheel { delta, x: px, y: py, .. } => {
let _ = (px, py); // hit-gated by the adapter
- let ctrl = ectx.ui.as_deref().map_or(false, |ui| ui.ctrl_pressed);
+ let ctrl = ectx.ui.as_deref().is_some_and(|ui| ui.ctrl_pressed);
if ctrl {
match delta {
MouseScrollDelta::LineDelta(_x, y) => {
diff --git a/src/widget/display/label.rs b/src/widget/display/label.rs
index 2121aa4..4e5d41e 100644
--- a/src/widget/display/label.rs
+++ b/src/widget/display/label.rs
@@ -171,7 +171,7 @@ impl StyledLabel {
let mut buffer = crate::backend::text::get_text_buffer(fs, &final_text, size, Some(family));
if is_vert {
let bar_thickness = crate::backend::text::vertical_text().unwrap_or(24) as f32;
- buffer.set_size(fs, Some(bar_thickness * scale as f32), None);
+ buffer.set_size(fs, Some(bar_thickness * scale), None);
for line in &mut buffer.lines {
line.set_align(Some(cosmic_text::Align::Center));
}
diff --git a/src/widget/display/serialize.rs b/src/widget/display/serialize.rs
index 0bb0a33..aa4280a 100644
--- a/src/widget/display/serialize.rs
+++ b/src/widget/display/serialize.rs
@@ -11,11 +11,11 @@ fn serialize_single_widget(w: &dyn WidgetHost, json: &mut String) {
let a = w.as_any();
let value = a
.downcast_ref::<Checkbox>()
- .map(|x| Input::value(x))
- .or_else(|| a.downcast_ref::<Dropdown>().map(|x| Input::value(x)))
- .or_else(|| a.downcast_ref::<Slider>().map(|x| Input::value(x)))
- .or_else(|| a.downcast_ref::<RangeSlider>().map(|x| Input::value(x)))
- .or_else(|| a.downcast_ref::<Spinbox>().map(|x| Input::value(x)))
+ .map(Input::value)
+ .or_else(|| a.downcast_ref::<Dropdown>().map(Input::value))
+ .or_else(|| a.downcast_ref::<Slider>().map(Input::value))
+ .or_else(|| a.downcast_ref::<RangeSlider>().map(Input::value))
+ .or_else(|| a.downcast_ref::<Spinbox>().map(Input::value))
.unwrap_or(0);
let type_name = w.type_name();
diff --git a/src/widget/doc_editor/mod.rs b/src/widget/doc_editor/mod.rs
index 30ee935..5d3538a 100644
--- a/src/widget/doc_editor/mod.rs
+++ b/src/widget/doc_editor/mod.rs
@@ -168,9 +168,7 @@ impl DocEditor {
/// Drop every layout (fonts or the theme changed).
pub fn invalidate(&mut self) {
- for l in &mut self.layouts {
- *l = None;
- }
+ self.layouts.fill(None);
self.tops_dirty = true;
}
@@ -244,9 +242,7 @@ impl DocEditor {
}
}
} else {
- for l in &mut self.layouts {
- *l = None;
- }
+ self.layouts.fill(None);
}
self.ctx = ctx;
let props = preview::properties(self.buf.lines(), &self.ctx);
diff --git a/src/widget/doc_editor/preview.rs b/src/widget/doc_editor/preview.rs
index a453cab..eb7ed30 100644
--- a/src/widget/doc_editor/preview.rs
+++ b/src/widget/doc_editor/preview.rs
@@ -1010,6 +1010,6 @@ mod tests {
Context::Normal
]
);
- assert_eq!(style_line("let x;", Context::Code, false).segs[0].look.mono, true);
+ assert!(style_line("let x;", Context::Code, false).segs[0].look.mono);
}
}
diff --git a/src/widget/input/button.rs b/src/widget/input/button.rs
index dcdbdf1..50b17bc 100644
--- a/src/widget/input/button.rs
+++ b/src/widget/input/button.rs
@@ -453,14 +453,14 @@ impl Paint for Button {
}
}
ButtonKind::CopyIcon => {
+ // Pressed and hovered wear the same wash.
+ let lit = self.pressed || self.hovered;
if self.selected {
- if self.pressed { [0.30, 0.52, 0.78, 0.5] }
- else if self.hovered { [0.30, 0.52, 0.78, 0.5] }
- else { [0.20, 0.40, 0.65, 0.2] }
+ if lit { [0.30, 0.52, 0.78, 0.5] } else { [0.20, 0.40, 0.65, 0.2] }
+ } else if lit {
+ [0.20, 0.20, 0.25, 0.25]
} else {
- if self.pressed { [0.20, 0.20, 0.25, 0.25] }
- else if self.hovered { [0.20, 0.20, 0.25, 0.25] }
- else { [0.0, 0.0, 0.0, 0.0] }
+ [0.0, 0.0, 0.0, 0.0]
}
}
}
diff --git a/src/widget/input/button_strip.rs b/src/widget/input/button_strip.rs
index a85d17e..1064d74 100644
--- a/src/widget/input/button_strip.rs
+++ b/src/widget/input/button_strip.rs
@@ -432,8 +432,8 @@ impl crate::widget::Paint for ButtonStrip {
);
}
- if self.vertical {
- if i < self.tab_text_quads.len() {
+ if self.vertical
+ && i < self.tab_text_quads.len() {
let min_y = self.y;
let max_y = self.y + self.h;
let has_icon = self.icon_of(i).is_some();
@@ -458,7 +458,6 @@ impl crate::widget::Paint for ButtonStrip {
}
}
}
- }
}
// Own labels (horizontal button text).
diff --git a/src/widget/input/color_selector.rs b/src/widget/input/color_selector.rs
index e96b03f..12a55b6 100644
--- a/src/widget/input/color_selector.rs
+++ b/src/widget/input/color_selector.rs
@@ -745,10 +745,8 @@ impl Input for ColorSelector {
for ch in text.chars() {
match ch {
'#' => {
- if state.buffer.is_empty() {
- state.insert_text("#");
- handled = true;
- } else if state.cursor_idx == 0 && !state.buffer.starts_with('#') {
+ // A "#" only leads the value.
+ if state.buffer.is_empty() || (state.cursor_idx == 0 && !state.buffer.starts_with('#')) {
state.insert_text("#");
handled = true;
}
diff --git a/src/widget/input/dropdown.rs b/src/widget/input/dropdown.rs
index 4ecbad8..260508e 100644
--- a/src/widget/input/dropdown.rs
+++ b/src/widget/input/dropdown.rs
@@ -580,7 +580,7 @@ impl Dropdown {
content.y + content.height
};
- let is_ramp = self.parent_snapshot.map_or(false, |s| s.is_ramp);
+ let is_ramp = self.parent_snapshot.is_some_and(|s| s.is_ramp);
if is_ramp {
if let Some(snap) = self.parent_snapshot {
diff --git a/src/widget/input/font_selector.rs b/src/widget/input/font_selector.rs
index b5c6fa1..7ef6423 100644
--- a/src/widget/input/font_selector.rs
+++ b/src/widget/input/font_selector.rs
@@ -236,6 +236,8 @@ impl Input for FontSelector {
true
}
+ // `try_wait` has reaped the picker by the time its handle is dropped unread.
+ #[allow(clippy::zombie_processes)]
fn tick(&mut self, _dt: f32, _rect: Rect) -> bool {
let mut child_guard = self.child.lock().unwrap();
if let Some(ref mut child) = *child_guard {
diff --git a/src/widget/input/ramp.rs b/src/widget/input/ramp.rs
index 36db72e..f137029 100644
--- a/src/widget/input/ramp.rs
+++ b/src/widget/input/ramp.rs
@@ -541,8 +541,8 @@ impl Input for ColorRamp {
self.r_slider.mouse_input(button, state, px, py_event, ui);
self.g_slider.mouse_input(button, state, px, py_event, ui);
self.b_slider.mouse_input(button, state, px, py_event, ui);
- if self.del_button.mouse_input(button, state, px, py_event, ui) {
- if self.del_button.take_click() {
+ if self.del_button.mouse_input(button, state, px, py_event, ui)
+ && self.del_button.take_click() {
if let Some(idx) = self.selected_key_idx {
if self.keys.len() > 2 {
self.keys.remove(idx);
@@ -552,7 +552,6 @@ impl Input for ColorRamp {
}
}
}
- }
return true;
}
}
@@ -608,7 +607,7 @@ impl Input for ColorRamp {
// Wheel forwarding (6bd self-routing): with the field widgets no longer
// tree-linked, the sliders' wheel rides this arm — and the key color syncs
// immediately (the old descent path left it stale until the next hover flip).
- let (delta, px, py) = (delta.clone(), *x, *y);
+ let (delta, px, py) = (*delta, *x, *y);
let Some(ui) = ectx.ui.as_deref_mut() else { return false; };
if self.selected_key_idx.is_none() {
return false;
@@ -1346,11 +1345,8 @@ impl Input for Ramp {
/// The open dropdown popover extends the hit area (the 5p Dropdown pattern).
fn hit(&self, rect: Rect, x: f32, y: f32) -> bool {
- if let Some((px, py, pw, ph)) = {
- self.preset_dropdown.popover_rect()
- .or_else(|| self.line_type_dropdown.popover_rect())
-
- } {
+ let popover = self.preset_dropdown.popover_rect().or_else(|| self.line_type_dropdown.popover_rect());
+ if let Some((px, py, pw, ph)) = popover {
if x >= px && x <= px + pw && y >= py && y <= py + ph {
return true;
}
@@ -1526,8 +1522,8 @@ impl Input for Ramp {
self.is_dragging_key = false;
if self.selected_key_idx.is_some() {
self.key_pad.mouse_input(button, state, px, py_event, ui);
- if self.del_button.mouse_input(button, state, px, py_event, ui) {
- if self.del_button.take_click() {
+ if self.del_button.mouse_input(button, state, px, py_event, ui)
+ && self.del_button.take_click() {
if let Some(idx) = self.selected_key_idx {
if self.keys.len() > 2 {
self.keys.remove(idx);
@@ -1538,7 +1534,6 @@ impl Input for Ramp {
}
}
}
- }
return true;
}
}
@@ -1591,7 +1586,7 @@ impl Input for Ramp {
Event::MouseWheel { delta, x, y, .. } => {
// Wheel forwarding (6bd self-routing): dropdowns first (mirroring the press
// order, incl. the preset drain), then the value slider with the key sync.
- let (delta, px, py) = (delta.clone(), *x, *y);
+ let (delta, px, py) = (*delta, *x, *y);
let Some(ui) = ectx.ui.as_deref_mut() else { return false; };
if self.preset_dropdown.mouse_wheel(&delta, px, py, ui) {
if self.preset_dropdown.take_change() {
diff --git a/src/widget/input/slider.rs b/src/widget/input/slider.rs
index 7ed9f06..e552c1d 100644
--- a/src/widget/input/slider.rs
+++ b/src/widget/input/slider.rs
@@ -838,7 +838,7 @@ pub fn paint_band_shape_colored(ctx: &mut PaintCtx, track_x: f32, track_w: f32,
pub(crate) fn detached_strip(label: &Option<String>) -> f32 {
// An EMPTY label is no label: `Adapted::clear_label` syncs one to take a
// label off a widget that stores whatever it is handed.
- if label.as_deref().map_or(false, |l| !l.is_empty()) { crate::layout::control_label_strip() } else { 0.0 }
+ if label.as_deref().is_some_and(|l| !l.is_empty()) { crate::layout::control_label_strip() } else { 0.0 }
}
impl Layout for RangeSlider {
@@ -870,7 +870,7 @@ impl Paint for RangeSlider {
// is the highlight — the colour rides the swell's own bell, so it
// blooms over that end and fades back to the band along its flanks.
let base = if self.active_thumb.is_some() { colors::rangeslider_thumb_drag() } else { colors::rangeslider_thumb() };
- let focus_center = self.focused.then(|| if matches!(self.focus_end, ActiveThumb::Low) { lo } else { hi });
+ let focus_center = self.focused.then_some(if matches!(self.focus_end, ActiveThumb::Low) { lo } else { hi });
let hl = crate::color::highlight_primary_color();
let bulge_w = crate::layout::slider_bulge_width().max(2.0);
let color_at = |px: f32| -> [f32; 4] {
diff --git a/src/widget/input/spinbox.rs b/src/widget/input/spinbox.rs
index 817a4fe..987aaf6 100644
--- a/src/widget/input/spinbox.rs
+++ b/src/widget/input/spinbox.rs
@@ -50,9 +50,9 @@ pub struct SpinRelief {
pub rect: Rect,
pub radius: f32,
pub depth: f32,
- /// Where the -/+ run begins (an x), and the engraved seam dividing - from
- /// + as `(top, bottom, width, host)` — `None` when the button zone has no
- /// area, and the field is the well alone.
+ /// Where the -/+ run begins (an x), and the engraved seam dividing the minus from the
+ /// plus as `(top, bottom, width, host)` — `None` when the button zone has no area, and
+ /// the field is the well alone.
pub run: Option<(f32, ((f32, f32), (f32, f32), f32, Rect))>,
}
diff --git a/src/widget/input/text_box.rs b/src/widget/input/text_box.rs
index 66b3c34..fd9f5e4 100644
--- a/src/widget/input/text_box.rs
+++ b/src/widget/input/text_box.rs
@@ -587,7 +587,7 @@ impl TextBox {
for (i, &(l, c)) in index_map.iter().enumerate() {
if l == line {
- let dist = (c as isize - target_col as isize).abs() as usize;
+ let dist = (c as isize - target_col as isize).unsigned_abs();
if dist < best_dist {
best_dist = dist;
best_idx = i;
@@ -1255,7 +1255,7 @@ impl TextBox {
Key::Named(NamedKey::Backspace) => Some(2),
Key::Named(NamedKey::Delete) => Some(3),
Key::Character(_) if !control => {
- let ws = event.text.as_deref().map_or(false, |t| t.chars().all(char::is_whitespace));
+ let ws = event.text.as_deref().is_some_and(|t| t.chars().all(char::is_whitespace));
Some(if ws { 4 } else { 1 })
}
_ => None,
@@ -1325,8 +1325,8 @@ impl TextBox {
}
MouseScrollDelta::PixelDelta(pos) => {
if !self.multiline {
- let scroll_val = if pos.y != 0.0 { -pos.y as f32 } else { if natural { -pos.x as f32 } else { pos.x as f32 } };
- scroll_val
+
+ if pos.y != 0.0 { -pos.y as f32 } else { if natural { -pos.x as f32 } else { pos.x as f32 } }
} else {
if natural { -pos.x as f32 } else { pos.x as f32 }
}
@@ -1464,11 +1464,10 @@ impl TextBox {
caret = Some([cursor_x, cursor_y, 1.5, caret_h]);
let clipped_y = cursor_y.max(view_top);
let clipped_bottom = (cursor_y + caret_h).min(view_bottom);
- if cursor_x >= x + pad && cursor_x <= x + w - pad {
- if clipped_y < clipped_bottom {
+ if cursor_x >= x + pad && cursor_x <= x + w - pad
+ && clipped_y < clipped_bottom {
out.push((cursor_x, clipped_y, 1.5, clipped_bottom - clipped_y, cursor_color));
}
- }
}
} else {
let caret_h = self.font_size * 1.15;
diff --git a/src/widget/model.rs b/src/widget/model.rs
index 1be8af0..0a1d361 100644
--- a/src/widget/model.rs
+++ b/src/widget/model.rs
@@ -131,7 +131,7 @@ pub trait Layout {
}
/// Republish value-embedded legacy children into the ctx registry (Paginator's ButtonStrip
- /// + Pages). Legacy value-owning containers re-registered their children on EVERY `tick` and
+ /// and Pages). Legacy value-owning containers re-registered their children on EVERY `tick` and
/// `layout` because the children's addresses move with the owning struct (host struct moves,
/// `Vec` reallocation) — and the registration is load-bearing: the spatial grid is rebuilt
/// from registered widgets, and it is the registered ButtonStrip (whose
@@ -359,7 +359,7 @@ impl EventCtx<'_> {
/// `focus::clear_if_matches(self)` — MenuBar releases focus when its dropdowns close).
pub fn release_focus(&mut self) {
if let Some(ptr) = self.self_ptr {
- unsafe { crate::widget::focus::clear_if_matches(&mut *ptr) };
+ unsafe { crate::widget::focus::clear_if_matches(&*ptr) };
}
}