Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions crates/app/src/host/common/colors.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
//! Shared color palettes, color pairs, and color serialization helpers.

use egui::{Color32, Stroke};
use serde::{Deserialize, Serialize};

const MAIN_ACCENT_BACKGROUND_DARK: Color32 = Color32::from_rgb(36, 44, 58);
const MAIN_ACCENT_BACKGROUND_LIGHT: Color32 = Color32::from_rgb(220, 228, 240);
Expand Down Expand Up @@ -103,6 +106,43 @@ impl ColorPair {
}
}

/// Color bytes stored for serialization in unpremultiplied sRGBA order.
pub type StoredRgba = [u8; 4];

/// Foreground/background color pair stored for serialization.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct StoredColorPair {
/// Foreground color.
pub fg: StoredRgba,
/// Background color.
pub bg: StoredRgba,
}

impl From<ColorPair> for StoredColorPair {
fn from(value: ColorPair) -> Self {
Self {
fg: color_to_rgba(value.fg),
bg: color_to_rgba(value.bg),
}
}
}

impl From<StoredColorPair> for ColorPair {
fn from(value: StoredColorPair) -> Self {
Self::new(color_from_rgba(value.fg), color_from_rgba(value.bg))
}
}

/// Converts an egui color into stored unpremultiplied sRGBA bytes.
pub fn color_to_rgba(color: Color32) -> StoredRgba {
color.to_srgba_unmultiplied()
}

/// Converts stored unpremultiplied sRGBA bytes into an egui color.
pub fn color_from_rgba([r, g, b, a]: StoredRgba) -> Color32 {
Color32::from_rgba_unmultiplied(r, g, b, a)
}

/// Foreground/background colors used for temporary search highlighting.
pub const TEMP_SEARCH_COLORS: ColorPair = ColorPair::new(
Color32::from_rgb(230, 234, 244),
Expand Down
40 changes: 4 additions & 36 deletions crates/app/src/host/service/presets_io/v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
//! Version 2 documents store named filter and search-value row snapshots,
//! including enabled state and colors.

use egui::Color32;
use processor::search::filter::SearchFilter;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use uuid::Uuid;

use crate::host::{
common::colors::ColorPair,
common::colors::{ColorPair, StoredColorPair, StoredRgba, color_from_rgba, color_to_rgba},
ui::registry::presets::{Preset, PresetFilterEntry, PresetSearchValueEntry},
};

Expand All @@ -19,8 +18,6 @@ use super::{
validate_search_value_entry,
};

type Rgba = [u8; 4];

/// Preset payload stored in the current preset document.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct DocumentPreset {
Expand All @@ -34,21 +31,15 @@ struct DocumentPreset {
struct DocumentFilterEntry {
filter: SearchFilter,
enabled: bool,
colors: DocumentColorPair,
colors: StoredColorPair,
}

/// Chart/search-value row payload stored in the current preset document.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct DocumentSearchValueEntry {
filter: SearchFilter,
enabled: bool,
color: Rgba,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct DocumentColorPair {
fg: Rgba,
bg: Rgba,
color: StoredRgba,
}

/// Versioned preset document stored on disk.
Expand Down Expand Up @@ -143,7 +134,7 @@ impl From<PresetFilterEntry> for DocumentFilterEntry {
Self {
filter: value.filter,
enabled: value.enabled,
colors: DocumentColorPair::from(value.colors),
colors: StoredColorPair::from(value.colors),
}
}
}
Expand All @@ -158,15 +149,6 @@ impl From<PresetSearchValueEntry> for DocumentSearchValueEntry {
}
}

impl From<ColorPair> for DocumentColorPair {
fn from(value: ColorPair) -> Self {
Self {
fg: color_to_rgba(value.fg),
bg: color_to_rgba(value.bg),
}
}
}

impl From<DocumentPreset> for Preset {
fn from(value: DocumentPreset) -> Self {
Self {
Expand Down Expand Up @@ -200,20 +182,6 @@ impl From<DocumentSearchValueEntry> for PresetSearchValueEntry {
}
}

impl From<DocumentColorPair> for ColorPair {
fn from(value: DocumentColorPair) -> Self {
Self::new(color_from_rgba(value.fg), color_from_rgba(value.bg))
}
}

fn color_to_rgba(color: Color32) -> Rgba {
color.to_srgba_unmultiplied()
}

fn color_from_rgba([r, g, b, a]: Rgba) -> Color32 {
Color32::from_rgba_unmultiplied(r, g, b, a)
}

#[cfg(test)]
mod tests {
use egui::Color32;
Expand Down
35 changes: 25 additions & 10 deletions crates/app/src/host/service/storage/recent/legacy/actions.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
//! Legacy recent-action source and parser conversion.
//!
//! Recent actions are converted into native recent-session snapshots first. Saved
//! filters/charts are attached later by matching these snapshots against legacy history
//! definitions. Keep the source identities conservative: file paths are normalized for
//! legacy case-insensitive matching, process cwd only tolerates trailing separators, and
//! no basename or extension-only fallback is used.

use std::{
ops::Not,
path::{Path, PathBuf},
};
use std::path::{Path, PathBuf};

use serde_json::{Map, Value, from_value};

Expand Down Expand Up @@ -318,7 +321,7 @@ fn parser_name_from_name(name: &str) -> Option<ParserNames> {
match name {
"Text" => Some(ParserNames::Text),
"Dlt" => Some(ParserNames::Dlt),
"SomeIp" => Some(ParserNames::SomeIP),
"SomeIp" | "SomeIP" => Some(ParserNames::SomeIP),
"Plugin" => Some(ParserNames::Plugins),
_ => None,
}
Expand Down Expand Up @@ -468,14 +471,26 @@ pub fn path_from_object(object: &Map<String, Value>) -> Option<PathBuf> {

/// Normalizes paths only for case-insensitive legacy matching.
pub fn normalize_path(path: &Path) -> String {
// Chipmunk 3 file descriptors stored lower-cased paths, so matching follows that.
path.to_string_lossy().to_lowercase()
}

fn path_to_match_string(path: &Path) -> Option<String> {
path.as_os_str()
.is_empty()
.not()
.then(|| path.to_string_lossy().into_owned())
/// Converts a process cwd path into the source matching identity.
pub fn path_to_match_string(path: &Path) -> Option<String> {
process_cwd_to_match_string(&path.to_string_lossy())
}

/// Converts a legacy process cwd string into the source matching identity.
pub fn process_cwd_to_match_string(path: &str) -> Option<String> {
// Chipmunk 3 can persist the same cwd with or without a trailing separator. This keeps
// exact cwd matching while avoiding that formatting-only mismatch.
if path.is_empty() {
return None;
}

let trimmed = path.trim_end_matches(['/', '\\']);
let normalized = if trimmed.is_empty() { path } else { trimmed };
Some(normalized.to_owned())
}

fn string_field<'a>(object: &'a Map<String, Value>, keys: &[&str]) -> Option<&'a str> {
Expand Down
Loading
Loading