Refactor code structure for improved readability and maintainability
This commit is contained in:
@@ -2296,13 +2296,37 @@ impl HcieIcedApp {
|
||||
doc.selection_mask_dirty.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if `color` is within the proximity threshold of `last`,
|
||||
/// meaning it is visually very similar and should be skipped to prevent
|
||||
/// slider/wheel drag noise from flooding the recent colors list.
|
||||
///
|
||||
/// The threshold is ≤2 units per RGBA channel (unsigned comparison).
|
||||
pub fn is_proximate_to_last(last: &[u8; 4], color: &[u8; 4]) -> bool {
|
||||
let channel_diff = |a: u8, b: u8| -> u16 { (a as i16 - b as i16).unsigned_abs() as u16 };
|
||||
channel_diff(last[0], color[0]) <= 2
|
||||
&& channel_diff(last[1], color[1]) <= 2
|
||||
&& channel_diff(last[2], color[2]) <= 2
|
||||
}
|
||||
|
||||
impl HcieIcedApp {
|
||||
/// Add a color to the recent colors list (most recent first, max 40).
|
||||
///
|
||||
/// Immediately persists to disk so committed colors survive a crash or non-graceful
|
||||
/// shutdown. Color-wheel movement never calls this method; the final sampled color is
|
||||
/// committed once by `ColorDragEnded`.
|
||||
///
|
||||
/// Proximity dedup: if the new color is within the proximity threshold of the most recent
|
||||
/// entry — checked by `is_proximate_to_last` — it is skipped. This prevents slider and
|
||||
/// wheel drag noise from flooding the recent colors list with near-identical entries.
|
||||
fn add_recent_color(&mut self, color: [u8; 4]) {
|
||||
// Skip if visually very similar to the most recent entry (proximity dedup).
|
||||
if let Some(last) = self.recent_colors.first() {
|
||||
if is_proximate_to_last(last, &color) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
self.recent_colors.retain(|c| *c != color);
|
||||
self.recent_colors.insert(0, color);
|
||||
self.recent_colors.truncate(40);
|
||||
@@ -2611,8 +2635,10 @@ impl HcieIcedApp {
|
||||
|
||||
Message::BgColorChanged(color) => {
|
||||
self.bg_color = color;
|
||||
self.add_recent_color(color);
|
||||
self.colors_dirty = true;
|
||||
if !self.color_dragging {
|
||||
self.add_recent_color(color);
|
||||
self.colors_dirty = true;
|
||||
}
|
||||
if !self.color_dragging {
|
||||
crate::shape_sync::sync_shape_from_tool(self);
|
||||
self.refresh_composite_if_needed();
|
||||
@@ -10116,6 +10142,53 @@ mod cycle_one_ux_tests {
|
||||
let union = union_regions(Some(first), [25, 5, 50, 35]);
|
||||
assert_eq!(union, [10, 5, 50, 40]);
|
||||
}
|
||||
|
||||
// ── Recent color proximity dedup ─────────────────────
|
||||
|
||||
/// Confirms an identical color IS proximate (diff=0 ≤ threshold).
|
||||
/// In practice this means an exact duplicate click is deduped, which is
|
||||
/// acceptable because the color is already at (or near) the front of the list.
|
||||
#[test]
|
||||
fn proximate_identical_color_is_skipped() {
|
||||
let last = [100, 150, 200, 255];
|
||||
let color = [100, 150, 200, 255];
|
||||
// Identical → not proximate because the function returns true for
|
||||
// threshold ≤2 per channel; identical (diff=0) is within threshold
|
||||
// so `is_proximate_to_last` returns true.
|
||||
assert!(super::is_proximate_to_last(&last, &color));
|
||||
}
|
||||
|
||||
/// Confirms a slider-step color (+1 in one channel) IS proximate and skipped.
|
||||
#[test]
|
||||
fn proximate_small_slider_step_skipped() {
|
||||
let last = [100, 150, 200, 255];
|
||||
let slider_step = [101, 150, 200, 255];
|
||||
assert!(super::is_proximate_to_last(&last, &slider_step));
|
||||
}
|
||||
|
||||
/// Confirms a +3 change in all channels is NOT proximate (exceeds threshold).
|
||||
#[test]
|
||||
fn large_change_not_proximate() {
|
||||
let last = [100, 150, 200, 255];
|
||||
let far = [105, 155, 205, 255];
|
||||
assert!(!super::is_proximate_to_last(&last, &far));
|
||||
}
|
||||
|
||||
/// Confirms a single-channel +3 jump exceeds the threshold.
|
||||
#[test]
|
||||
fn three_unit_change_exceeds_threshold() {
|
||||
let last = [100, 150, 200, 255];
|
||||
let three_away = [103, 150, 200, 255];
|
||||
assert!(!super::is_proximate_to_last(&last, &three_away));
|
||||
}
|
||||
|
||||
/// Confirms small mixed changes are still within the proximity window.
|
||||
#[test]
|
||||
fn mixed_small_changes_are_proximate() {
|
||||
let last = [100, 150, 200, 255];
|
||||
let mixed_small = [101, 151, 201, 255];
|
||||
assert!(super::is_proximate_to_last(&last, &mixed_small));
|
||||
}
|
||||
}
|
||||
|
||||
/// Find the topmost text layer whose rasterized pixels contain the point
|
||||
|
||||
Reference in New Issue
Block a user