diff --git a/src/app.rs b/src/app.rs index a41353c..5c6efd4 100644 --- a/src/app.rs +++ b/src/app.rs @@ -16,7 +16,7 @@ use crate::analytics; use crate::computed::{ComputedChannel, ComputedChannelLibrary, FormulaEditorState}; use crate::parsers::{Aim, EcuMaster, EcuType, Haltech, Link, Parseable, RomRaider, Speeduino}; use crate::state::{ - ActiveTool, CacheKey, LoadResult, LoadedFile, LoadingState, ScatterPlotConfig, + ActiveTool, CacheKey, FontScale, LoadResult, LoadedFile, LoadingState, ScatterPlotConfig, ScatterPlotState, SelectedChannel, Tab, ToastType, CHART_COLORS, COLORBLIND_COLORS, MAX_CHANNELS, }; @@ -74,6 +74,8 @@ pub struct UltraLogApp { // === Unit Preferences === /// User preferences for display units pub(crate) unit_preferences: UnitPreferences, + /// User preference for UI font size scaling + pub(crate) font_scale: FontScale, // === Custom Field Normalization === /// Custom user-defined field name mappings (source name -> normalized name) pub(crate) custom_normalizations: HashMap, @@ -151,6 +153,7 @@ impl Default for UltraLogApp { field_normalization: true, // Enabled by default for better readability initial_view_seconds: 60.0, // Start with 60 second view unit_preferences: UnitPreferences::default(), + font_scale: FontScale::default(), custom_normalizations: HashMap::new(), show_normalization_editor: false, norm_editor_extend_source: String::new(), @@ -230,6 +233,12 @@ impl UltraLogApp { palette[color_index % palette.len()] } + /// Get a scaled font size based on user's font scale preference + #[inline] + pub fn scaled_font(&self, base_size: f32) -> f32 { + (base_size * self.font_scale.multiplier()).round() + } + // ======================================================================== // File Loading // ======================================================================== diff --git a/src/state.rs b/src/state.rs index 9ecdd46..f9fdb23 100644 --- a/src/state.rs +++ b/src/state.rs @@ -195,6 +195,32 @@ impl ActiveTool { } } +/// Font scale preference for UI elements +#[derive(Clone, Copy, PartialEq, Eq, Default, Debug)] +pub enum FontScale { + /// Smaller fonts (0.85x) + Small, + /// Default size (1.0x) + #[default] + Medium, + /// Larger fonts (1.2x) + Large, + /// Extra large fonts (1.4x) + ExtraLarge, +} + +impl FontScale { + /// Get the multiplier for this font scale + pub fn multiplier(&self) -> f32 { + match self { + FontScale::Small => 0.85, + FontScale::Medium => 1.0, + FontScale::Large => 1.2, + FontScale::ExtraLarge => 1.4, + } + } +} + /// A selected point on a heatmap #[derive(Clone, Default)] pub struct SelectedHeatmapPoint { diff --git a/src/ui/channels.rs b/src/ui/channels.rs index f76d196..2fde154 100644 --- a/src/ui/channels.rs +++ b/src/ui/channels.rs @@ -9,7 +9,12 @@ use crate::state::MAX_CHANNELS; impl UltraLogApp { /// Render channel selection panel - fills available space pub fn render_channel_selection(&mut self, ui: &mut egui::Ui) { - ui.heading("Channels"); + // Pre-compute scaled font sizes + let font_14 = self.scaled_font(14.0); + let font_16 = self.scaled_font(16.0); + let font_18 = self.scaled_font(18.0); + + ui.label(egui::RichText::new("Channels").heading().size(font_18)); ui.separator(); // Get active tab info @@ -31,7 +36,7 @@ impl UltraLogApp { // Computed Channels button if ui - .button("+ Computed Channels") + .button(egui::RichText::new("+ Computed Channels").size(font_14)) .on_hover_text("Create virtual channels from mathematical formulas") .clicked() { @@ -44,7 +49,7 @@ impl UltraLogApp { let mut search_text = current_search; let mut search_changed = false; ui.horizontal(|ui| { - ui.label("Search:"); + ui.label(egui::RichText::new("Search:").size(font_14)); let response = ui .add(egui::TextEdit::singleline(&mut search_text).desired_width(f32::INFINITY)); search_changed = response.changed(); @@ -58,10 +63,13 @@ impl UltraLogApp { ui.add_space(5.0); // Channel count - ui.label(format!( - "Selected: {} / {} | Total: {}", - selected_count, MAX_CHANNELS, channel_count - )); + ui.label( + egui::RichText::new(format!( + "Selected: {} / {} | Total: {}", + selected_count, MAX_CHANNELS, channel_count + )) + .size(font_14), + ); ui.separator(); @@ -173,7 +181,8 @@ impl UltraLogApp { "📊 Channels with Data ({})", channels_with.len() )) - .strong(), + .strong() + .size(font_16), ) .default_open(true) .show(ui, |ui| { @@ -203,7 +212,8 @@ impl UltraLogApp { "📭 Empty Channels ({})", channels_without.len() )) - .color(egui::Color32::GRAY), + .color(egui::Color32::GRAY) + .size(font_16), ) .default_open(false) // Collapsed by default .show(ui, |ui| { @@ -234,7 +244,8 @@ impl UltraLogApp { ui.label( egui::RichText::new("Select a file to view channels") .italics() - .color(egui::Color32::GRAY), + .color(egui::Color32::GRAY) + .size(font_16), ); }); } @@ -242,7 +253,17 @@ impl UltraLogApp { /// Render selected channel cards pub fn render_selected_channels(&mut self, ui: &mut egui::Ui) { - ui.heading("Selected Channels"); + // Pre-compute scaled font sizes + let font_12 = self.scaled_font(12.0); + let font_14 = self.scaled_font(14.0); + let font_16 = self.scaled_font(16.0); + let font_18 = self.scaled_font(18.0); + + ui.label( + egui::RichText::new("Selected Channels") + .heading() + .size(font_18), + ); ui.separator(); let use_normalization = self.field_normalization; @@ -391,7 +412,8 @@ impl UltraLogApp { ui.label( egui::RichText::new(&card.display_name) .strong() - .color(card.color), + .color(card.color) + .size(font_14), ); let close_btn = ui.small_button("x"); if close_btn.clicked() { @@ -408,11 +430,12 @@ impl UltraLogApp { ui.label( egui::RichText::new("Min:") .color(egui::Color32::GRAY) - .small(), + .size(font_12), ); ui.label( egui::RichText::new(min_str) - .color(egui::Color32::LIGHT_GRAY), + .color(egui::Color32::LIGHT_GRAY) + .size(font_14), ); if let (Some(record), Some(time)) = (card.min_record, card.min_time) @@ -438,11 +461,12 @@ impl UltraLogApp { ui.label( egui::RichText::new("Max:") .color(egui::Color32::GRAY) - .small(), + .size(font_12), ); ui.label( egui::RichText::new(max_str) - .color(egui::Color32::LIGHT_GRAY), + .color(egui::Color32::LIGHT_GRAY) + .size(font_14), ); if let (Some(record), Some(time)) = (card.max_record, card.max_time) @@ -488,7 +512,8 @@ impl UltraLogApp { ui.label( egui::RichText::new("Click channels to add them to the chart") .italics() - .color(egui::Color32::GRAY), + .color(egui::Color32::GRAY) + .size(font_16), ); } } diff --git a/src/ui/chart.rs b/src/ui/chart.rs index 10c3527..7d98d20 100644 --- a/src/ui/chart.rs +++ b/src/ui/chart.rs @@ -17,7 +17,7 @@ impl UltraLogApp { ui.centered_and_justified(|ui| { ui.label( egui::RichText::new("Select channels to display chart") - .size(20.0) + .size(self.scaled_font(20.0)) .color(egui::Color32::GRAY), ); }); diff --git a/src/ui/histogram.rs b/src/ui/histogram.rs index b7a7a6b..a03a61b 100644 --- a/src/ui/histogram.rs +++ b/src/ui/histogram.rs @@ -90,7 +90,7 @@ impl UltraLogApp { ui.centered_and_justified(|ui| { ui.label( egui::RichText::new("Load a log file to use histogram") - .size(20.0) + .size(self.scaled_font(20.0)) .color(egui::Color32::GRAY), ); }); @@ -151,9 +151,13 @@ impl UltraLogApp { let mut new_mode: Option = None; let mut new_grid_size: Option = None; + // Pre-compute scaled font sizes + let font_14 = self.scaled_font(14.0); + let font_15 = self.scaled_font(15.0); + ui.horizontal(|ui| { // X Axis selector - ui.label(egui::RichText::new("X Axis:").size(15.0)); + ui.label(egui::RichText::new("X Axis:").size(font_15)); egui::ComboBox::from_id_salt("histogram_x") .selected_text( egui::RichText::new( @@ -161,7 +165,7 @@ impl UltraLogApp { .and_then(|i| channel_names.get(&i).map(|n| n.as_str())) .unwrap_or("Select..."), ) - .size(14.0), + .size(font_14), ) .width(160.0) .show_ui(ui, |ui| { @@ -169,7 +173,7 @@ impl UltraLogApp { if ui .selectable_label( current_x == Some(*idx), - egui::RichText::new(name).size(14.0), + egui::RichText::new(name).size(font_14), ) .clicked() { @@ -181,7 +185,7 @@ impl UltraLogApp { ui.add_space(16.0); // Y Axis selector - ui.label(egui::RichText::new("Y Axis:").size(15.0)); + ui.label(egui::RichText::new("Y Axis:").size(font_15)); egui::ComboBox::from_id_salt("histogram_y") .selected_text( egui::RichText::new( @@ -189,7 +193,7 @@ impl UltraLogApp { .and_then(|i| channel_names.get(&i).map(|n| n.as_str())) .unwrap_or("Select..."), ) - .size(14.0), + .size(font_14), ) .width(160.0) .show_ui(ui, |ui| { @@ -197,7 +201,7 @@ impl UltraLogApp { if ui .selectable_label( current_y == Some(*idx), - egui::RichText::new(name).size(14.0), + egui::RichText::new(name).size(font_14), ) .clicked() { @@ -211,7 +215,7 @@ impl UltraLogApp { // Z Axis selector (only enabled in AverageZ mode) let z_enabled = current_mode == HistogramMode::AverageZ; ui.add_enabled_ui(z_enabled, |ui| { - ui.label(egui::RichText::new("Z Axis:").size(15.0)); + ui.label(egui::RichText::new("Z Axis:").size(font_15)); egui::ComboBox::from_id_salt("histogram_z") .selected_text( egui::RichText::new( @@ -219,7 +223,7 @@ impl UltraLogApp { .and_then(|i| channel_names.get(&i).map(|n| n.as_str())) .unwrap_or("Select..."), ) - .size(14.0), + .size(font_14), ) .width(160.0) .show_ui(ui, |ui| { @@ -227,7 +231,7 @@ impl UltraLogApp { if ui .selectable_label( current_z == Some(*idx), - egui::RichText::new(name).size(14.0), + egui::RichText::new(name).size(font_14), ) .clicked() { @@ -240,9 +244,9 @@ impl UltraLogApp { ui.add_space(20.0); // Grid size selector - ui.label(egui::RichText::new("Grid:").size(15.0)); + ui.label(egui::RichText::new("Grid:").size(font_15)); egui::ComboBox::from_id_salt("histogram_grid_size") - .selected_text(egui::RichText::new(current_grid_size.name()).size(14.0)) + .selected_text(egui::RichText::new(current_grid_size.name()).size(font_14)) .width(80.0) .show_ui(ui, |ui| { let sizes = [ @@ -254,7 +258,7 @@ impl UltraLogApp { if ui .selectable_label( current_grid_size == size, - egui::RichText::new(size.name()).size(14.0), + egui::RichText::new(size.name()).size(font_14), ) .clicked() { @@ -266,11 +270,11 @@ impl UltraLogApp { ui.add_space(20.0); // Mode toggle - ui.label(egui::RichText::new("Mode:").size(15.0)); + ui.label(egui::RichText::new("Mode:").size(font_15)); if ui .selectable_label( current_mode == HistogramMode::AverageZ, - egui::RichText::new("Average Z").size(14.0), + egui::RichText::new("Average Z").size(font_14), ) .clicked() { @@ -279,7 +283,7 @@ impl UltraLogApp { if ui .selectable_label( current_mode == HistogramMode::HitCount, - egui::RichText::new("Hit Count").size(14.0), + egui::RichText::new("Hit Count").size(font_14), ) .clicked() { @@ -322,6 +326,12 @@ impl UltraLogApp { let mode = config.mode; let grid_size = config.grid_size.size(); + // Pre-compute scaled font sizes for use in closures + let font_10 = self.scaled_font(10.0); + let font_12 = self.scaled_font(12.0); + let font_13 = self.scaled_font(13.0); + let font_16 = self.scaled_font(16.0); + // Check valid axis selections let (x_idx, y_idx) = match (config.x_channel, config.y_channel) { (Some(x), Some(y)) => (x, y), @@ -332,7 +342,7 @@ impl UltraLogApp { rect.center(), egui::Align2::CENTER_CENTER, "Select X and Y axes", - egui::FontId::proportional(16.0), + egui::FontId::proportional(font_16), egui::Color32::GRAY, ); return; @@ -350,7 +360,7 @@ impl UltraLogApp { rect.center(), egui::Align2::CENTER_CENTER, "Select Z axis for Average mode", - egui::FontId::proportional(16.0), + egui::FontId::proportional(font_16), egui::Color32::GRAY, ); return; @@ -499,19 +509,20 @@ impl UltraLogApp { // Choose text color for AAA contrast compliance let text_color = get_aaa_text_color(color); - let font_size = if grid_size <= 16 { + let base_font_size = if grid_size <= 16 { 11.0 } else if grid_size <= 32 { 9.0 } else { 7.0 }; + let cell_font_size = self.scaled_font(base_font_size); painter.text( cell_rect.center(), egui::Align2::CENTER_CENTER, text, - egui::FontId::proportional(font_size), + egui::FontId::proportional(cell_font_size), text_color, ); } @@ -557,7 +568,7 @@ impl UltraLogApp { egui::pos2(plot_rect.left() - 8.0, y_pos), egui::Align2::RIGHT_CENTER, format!("{:.1}", value), - egui::FontId::proportional(10.0), + egui::FontId::proportional(font_10), text_color, ); } @@ -569,7 +580,7 @@ impl UltraLogApp { egui::pos2(y_title_x, y_title_y), egui::Align2::CENTER_CENTER, &y_channel_name, - egui::FontId::proportional(13.0), + egui::FontId::proportional(font_13), axis_title_color, ); @@ -582,7 +593,7 @@ impl UltraLogApp { egui::pos2(x_pos, plot_rect.bottom() + 5.0), egui::Align2::CENTER_TOP, format!("{:.0}", value), - egui::FontId::proportional(10.0), + egui::FontId::proportional(font_10), text_color, ); } @@ -594,7 +605,7 @@ impl UltraLogApp { egui::pos2(x_title_x, x_title_y), egui::Align2::CENTER_CENTER, &x_channel_name, - egui::FontId::proportional(13.0), + egui::FontId::proportional(font_13), axis_title_color, ); @@ -727,7 +738,7 @@ impl UltraLogApp { egui::pos2(plot_rect.right() - 10.0, plot_rect.top() + 15.0), egui::Align2::RIGHT_TOP, tooltip_text, - egui::FontId::proportional(12.0), + egui::FontId::proportional(font_12), egui::Color32::WHITE, ); } @@ -844,6 +855,8 @@ impl UltraLogApp { mode: HistogramMode, grid_size: usize, ) { + let font_13 = self.scaled_font(13.0); + ui.horizontal(|ui| { ui.add_space(4.0); @@ -860,7 +873,7 @@ impl UltraLogApp { }; ui.label( egui::RichText::new(label) - .size(13.0) + .size(font_13) .color(egui::Color32::WHITE), ); @@ -894,7 +907,7 @@ impl UltraLogApp { }; ui.label( egui::RichText::new(range_text) - .size(13.0) + .size(font_13) .color(egui::Color32::WHITE), ); }); @@ -911,13 +924,13 @@ impl UltraLogApp { ui.horizontal(|ui| { ui.label( egui::RichText::new(format!("Grid: {}x{}", grid_size, grid_size)) - .size(13.0) + .size(font_13) .color(egui::Color32::WHITE), ); ui.add_space(12.0); ui.label( egui::RichText::new(format!("Total Points: {}", total_points)) - .size(13.0) + .size(font_13) .color(egui::Color32::WHITE), ); }); @@ -933,13 +946,18 @@ impl UltraLogApp { let selected = &self.tabs[tab_idx].histogram_state.config.selected_cell; + // Pre-compute scaled font sizes + let font_12 = self.scaled_font(12.0); + let font_13 = self.scaled_font(13.0); + let font_14 = self.scaled_font(14.0); + ui.add_space(10.0); ui.separator(); ui.add_space(5.0); ui.label( egui::RichText::new("Cell Statistics") - .size(14.0) + .size(font_14) .strong() .color(egui::Color32::WHITE), ); @@ -956,7 +974,7 @@ impl UltraLogApp { ui.horizontal(|ui| { ui.label( egui::RichText::new(format!("Cell [{}, {}]", cell.x_bin, cell.y_bin)) - .size(13.0) + .size(font_13) .color(SELECTED_CELL_COLOR), ); }); @@ -985,7 +1003,7 @@ impl UltraLogApp { ui.horizontal(|ui| { ui.label( egui::RichText::new(format!("{}:", label)) - .size(12.0) + .size(font_12) .color(egui::Color32::from_rgb(180, 180, 180)), ); ui.with_layout( @@ -993,7 +1011,7 @@ impl UltraLogApp { |ui| { ui.label( egui::RichText::new(&value) - .size(12.0) + .size(font_12) .color(egui::Color32::WHITE), ); }, @@ -1010,7 +1028,7 @@ impl UltraLogApp { } else { ui.label( egui::RichText::new("Click a cell to view statistics") - .size(12.0) + .size(font_12) .italics() .color(egui::Color32::GRAY), ); diff --git a/src/ui/menu.rs b/src/ui/menu.rs index dd8e7f0..ab5bda3 100644 --- a/src/ui/menu.rs +++ b/src/ui/menu.rs @@ -4,7 +4,7 @@ use eframe::egui; use crate::analytics; use crate::app::UltraLogApp; -use crate::state::{ActiveTool, LoadingState}; +use crate::state::{ActiveTool, FontScale, LoadingState}; use crate::units::{ AccelerationUnit, DistanceUnit, FlowUnit, FuelEconomyUnit, PressureUnit, SpeedUnit, TemperatureUnit, VolumeUnit, @@ -13,11 +13,15 @@ use crate::units::{ impl UltraLogApp { /// Render the application menu bar pub fn render_menu_bar(&mut self, ui: &mut egui::Ui) { + // Pre-compute scaled font sizes for use in closures + let font_14 = self.scaled_font(14.0); + let font_15 = self.scaled_font(15.0); + egui::MenuBar::new().ui(ui, |ui| { // Increase font size for menu items ui.style_mut() .text_styles - .insert(egui::TextStyle::Button, egui::FontId::proportional(15.0)); + .insert(egui::TextStyle::Button, egui::FontId::proportional(font_15)); // File menu ui.menu_button("File", |ui| { @@ -26,10 +30,10 @@ impl UltraLogApp { // Increase font size for dropdown items ui.style_mut() .text_styles - .insert(egui::TextStyle::Button, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Button, egui::FontId::proportional(font_14)); ui.style_mut() .text_styles - .insert(egui::TextStyle::Body, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Body, egui::FontId::proportional(font_14)); let is_loading = matches!(self.loading_state, LoadingState::Loading(_)); @@ -68,7 +72,7 @@ impl UltraLogApp { // Increase font size for submenu items ui.style_mut() .text_styles - .insert(egui::TextStyle::Button, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Button, egui::FontId::proportional(font_14)); if self.active_tool == ActiveTool::Histogram && has_histogram_data { // Histogram export options @@ -98,10 +102,10 @@ impl UltraLogApp { // Increase font size for dropdown items ui.style_mut() .text_styles - .insert(egui::TextStyle::Button, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Button, egui::FontId::proportional(font_14)); ui.style_mut() .text_styles - .insert(egui::TextStyle::Body, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Body, egui::FontId::proportional(font_14)); // Cursor Tracking toggle if ui @@ -153,6 +157,44 @@ impl UltraLogApp { { ui.close(); } + + ui.separator(); + + // Font Size submenu + ui.menu_button("🔠 Font Size", |ui| { + ui.style_mut() + .text_styles + .insert(egui::TextStyle::Button, egui::FontId::proportional(font_14)); + + if ui + .radio_value(&mut self.font_scale, FontScale::Small, "Small (85%)") + .clicked() + { + ui.close(); + } + if ui + .radio_value(&mut self.font_scale, FontScale::Medium, "Medium (100%)") + .clicked() + { + ui.close(); + } + if ui + .radio_value(&mut self.font_scale, FontScale::Large, "Large (120%)") + .clicked() + { + ui.close(); + } + if ui + .radio_value( + &mut self.font_scale, + FontScale::ExtraLarge, + "Extra Large (140%)", + ) + .clicked() + { + ui.close(); + } + }); }); // Units menu @@ -162,17 +204,17 @@ impl UltraLogApp { // Increase font size for dropdown items ui.style_mut() .text_styles - .insert(egui::TextStyle::Button, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Button, egui::FontId::proportional(font_14)); ui.style_mut() .text_styles - .insert(egui::TextStyle::Body, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Body, egui::FontId::proportional(font_14)); // Temperature submenu ui.menu_button("°C Temperature", |ui| { // Increase font size for submenu items ui.style_mut() .text_styles - .insert(egui::TextStyle::Button, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Button, egui::FontId::proportional(font_14)); if ui .radio_value( &mut self.unit_preferences.temperature, @@ -210,7 +252,7 @@ impl UltraLogApp { // Increase font size for submenu items ui.style_mut() .text_styles - .insert(egui::TextStyle::Button, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Button, egui::FontId::proportional(font_14)); if ui .radio_value( &mut self.unit_preferences.pressure, @@ -248,7 +290,7 @@ impl UltraLogApp { // Increase font size for submenu items ui.style_mut() .text_styles - .insert(egui::TextStyle::Button, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Button, egui::FontId::proportional(font_14)); if ui .radio_value( &mut self.unit_preferences.speed, @@ -276,7 +318,7 @@ impl UltraLogApp { // Increase font size for submenu items ui.style_mut() .text_styles - .insert(egui::TextStyle::Button, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Button, egui::FontId::proportional(font_14)); if ui .radio_value( &mut self.unit_preferences.distance, @@ -306,7 +348,7 @@ impl UltraLogApp { // Increase font size for submenu items ui.style_mut() .text_styles - .insert(egui::TextStyle::Button, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Button, egui::FontId::proportional(font_14)); if ui .radio_value( &mut self.unit_preferences.fuel_economy, @@ -344,7 +386,7 @@ impl UltraLogApp { // Increase font size for submenu items ui.style_mut() .text_styles - .insert(egui::TextStyle::Button, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Button, egui::FontId::proportional(font_14)); if ui .radio_value( &mut self.unit_preferences.volume, @@ -372,7 +414,7 @@ impl UltraLogApp { // Increase font size for submenu items ui.style_mut() .text_styles - .insert(egui::TextStyle::Button, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Button, egui::FontId::proportional(font_14)); if ui .radio_value( &mut self.unit_preferences.flow, @@ -398,7 +440,7 @@ impl UltraLogApp { // Increase font size for submenu items ui.style_mut() .text_styles - .insert(egui::TextStyle::Button, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Button, egui::FontId::proportional(font_14)); if ui .radio_value( &mut self.unit_preferences.acceleration, @@ -429,10 +471,10 @@ impl UltraLogApp { // Increase font size for dropdown items ui.style_mut() .text_styles - .insert(egui::TextStyle::Button, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Button, egui::FontId::proportional(font_14)); ui.style_mut() .text_styles - .insert(egui::TextStyle::Body, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Body, egui::FontId::proportional(font_14)); if ui.button("ƒ(x) Computed Channels...").clicked() { self.show_computed_channels_manager = true; @@ -453,10 +495,10 @@ impl UltraLogApp { // Increase font size for dropdown items ui.style_mut() .text_styles - .insert(egui::TextStyle::Button, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Button, egui::FontId::proportional(font_14)); ui.style_mut() .text_styles - .insert(egui::TextStyle::Body, egui::FontId::proportional(14.0)); + .insert(egui::TextStyle::Body, egui::FontId::proportional(font_14)); if ui.button("📖 Documentation").clicked() { let _ = open::that("https://github.com/SomethingNew71/UltraLog/wiki"); diff --git a/src/ui/scatter_plot.rs b/src/ui/scatter_plot.rs index f06f3c4..0e425c2 100644 --- a/src/ui/scatter_plot.rs +++ b/src/ui/scatter_plot.rs @@ -45,7 +45,7 @@ impl UltraLogApp { ui.centered_and_justified(|ui| { ui.label( egui::RichText::new("Load a log file to use scatter plots") - .size(20.0) + .size(self.scaled_font(20.0)) .color(egui::Color32::GRAY), ); }); @@ -95,7 +95,7 @@ impl UltraLogApp { ui.horizontal(|ui| { ui.label( egui::RichText::new(&title) - .size(16.0) + .size(self.scaled_font(16.0)) .strong() .color(egui::Color32::WHITE), ); @@ -266,6 +266,11 @@ impl UltraLogApp { let file_idx = config.file_index.unwrap_or(self.tabs[tab_idx].file_index); + // Pre-compute scaled font sizes + let font_10 = self.scaled_font(10.0); + let font_11 = self.scaled_font(11.0); + let font_16 = self.scaled_font(16.0); + // Check if we have valid axis selections let (x_idx, y_idx) = match (config.x_channel, config.y_channel) { (Some(x), Some(y)) => (x, y), @@ -277,7 +282,7 @@ impl UltraLogApp { rect.center(), egui::Align2::CENTER_CENTER, "Select X and Y axes", - egui::FontId::proportional(16.0), + egui::FontId::proportional(font_16), egui::Color32::GRAY, ); return; @@ -396,7 +401,7 @@ impl UltraLogApp { egui::pos2(plot_rect.left() - 5.0, y_pos), egui::Align2::RIGHT_CENTER, format!("{:.1}", value), - egui::FontId::proportional(10.0), + egui::FontId::proportional(font_10), text_color, ); @@ -421,7 +426,7 @@ impl UltraLogApp { egui::pos2(x_pos, plot_rect.bottom() + 5.0), egui::Align2::CENTER_TOP, format!("{:.0}", value), - egui::FontId::proportional(10.0), + egui::FontId::proportional(font_10), text_color, ); @@ -510,7 +515,7 @@ impl UltraLogApp { egui::pos2(plot_rect.right() - 10.0, plot_rect.top() + 15.0), egui::Align2::RIGHT_TOP, tooltip_text, - egui::FontId::proportional(11.0), + egui::FontId::proportional(font_11), egui::Color32::WHITE, ); @@ -571,6 +576,10 @@ impl UltraLogApp { return; }; + // Pre-compute scaled font sizes + let font_10 = self.scaled_font(10.0); + let font_11 = self.scaled_font(11.0); + // First, gather the data we need (immutable borrow) let config = if is_left { &self.tabs[tab_idx].scatter_plot_state.left @@ -631,7 +640,7 @@ impl UltraLogApp { ui.horizontal(|ui| { ui.label( egui::RichText::new("Hits:") - .size(11.0) + .size(font_11) .color(egui::Color32::WHITE), ); @@ -660,7 +669,7 @@ impl UltraLogApp { ui.add_space(4.0); ui.label( egui::RichText::new(format!("0-{}", max_hits)) - .size(10.0) + .size(font_10) .color(egui::Color32::WHITE), ); }); @@ -697,7 +706,7 @@ impl UltraLogApp { selected.y_value, selected.hits )) - .size(11.0) + .size(font_11) .color(egui::Color32::WHITE), ); diff --git a/src/ui/sidebar.rs b/src/ui/sidebar.rs index dea7f2d..82a553a 100644 --- a/src/ui/sidebar.rs +++ b/src/ui/sidebar.rs @@ -66,7 +66,7 @@ impl UltraLogApp { "{} | {} channels | {} points", ecu_name, channel_count, data_count )) - .size(12.0) + .size(self.scaled_font(12.0)) .color(egui::Color32::GRAY), ); }); @@ -98,7 +98,7 @@ impl UltraLogApp { ui.label( egui::RichText::new("+ Add File") .color(egui::Color32::WHITE) - .size(14.0), + .size(self.scaled_font(14.0)), ); }); @@ -163,7 +163,7 @@ impl UltraLogApp { ui.label( egui::RichText::new("Select a file") .color(egui::Color32::WHITE) - .size(14.0), + .size(self.scaled_font(14.0)), ); }); @@ -186,14 +186,18 @@ impl UltraLogApp { ui.add_space(12.0); - ui.label(egui::RichText::new("or").color(text_gray).size(12.0)); + ui.label( + egui::RichText::new("or") + .color(text_gray) + .size(self.scaled_font(12.0)), + ); ui.add_space(8.0); ui.label( egui::RichText::new("Drop file here") .color(egui::Color32::LIGHT_GRAY) - .size(13.0), + .size(self.scaled_font(13.0)), ); ui.add_space(12.0); @@ -201,7 +205,7 @@ impl UltraLogApp { ui.label( egui::RichText::new("CSV • LOG • TXT • MLG") .color(text_gray) - .size(11.0), + .size(self.scaled_font(11.0)), ); }); }); @@ -209,6 +213,11 @@ impl UltraLogApp { /// Render view options at the bottom of the sidebar fn render_view_options(&mut self, ui: &mut egui::Ui) { + // Pre-compute scaled font sizes + let font_12 = self.scaled_font(12.0); + let font_14 = self.scaled_font(14.0); + let font_18 = self.scaled_font(18.0); + ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), |ui| { // Reverse order since we're bottom-up ui.add_space(10.0); @@ -232,16 +241,20 @@ impl UltraLogApp { .inner_margin(10.0) .show(ui, |ui| { // Cursor tracking checkbox - ui.checkbox(&mut self.cursor_tracking, "🎯 Cursor Tracking"); + ui.checkbox( + &mut self.cursor_tracking, + egui::RichText::new("🎯 Cursor Tracking").size(font_14), + ); ui.label( egui::RichText::new("Keep cursor centered while scrubbing") - .color(egui::Color32::GRAY), + .color(egui::Color32::GRAY) + .size(font_12), ); // Window size slider (only show when cursor tracking is enabled) if self.cursor_tracking { ui.add_space(8.0); - ui.label("View Window:"); + ui.label(egui::RichText::new("View Window:").size(font_14)); ui.add( egui::Slider::new(&mut self.view_window_seconds, 5.0..=120.0) .suffix("s") @@ -254,10 +267,14 @@ impl UltraLogApp { ui.add_space(4.0); // Color blind mode checkbox - ui.checkbox(&mut self.color_blind_mode, "👁 Color Blind Mode"); + ui.checkbox( + &mut self.color_blind_mode, + egui::RichText::new("👁 Color Blind Mode").size(font_14), + ); ui.label( egui::RichText::new("Use accessible color palette") - .color(egui::Color32::GRAY), + .color(egui::Color32::GRAY) + .size(font_12), ); ui.add_space(8.0); @@ -266,7 +283,10 @@ impl UltraLogApp { // Field normalization checkbox with right-aligned Edit button ui.horizontal(|ui| { - ui.checkbox(&mut self.field_normalization, "📝 Field Normalization"); + ui.checkbox( + &mut self.field_normalization, + egui::RichText::new("📝 Field Normalization").size(font_14), + ); ui.with_layout( egui::Layout::right_to_left(egui::Align::Center), |ui| { @@ -278,13 +298,14 @@ impl UltraLogApp { }); ui.label( egui::RichText::new("Standardize channel names across ECU types") - .color(egui::Color32::GRAY), + .color(egui::Color32::GRAY) + .size(font_12), ); }); ui.add_space(5.0); ui.separator(); - ui.heading("View Options"); + ui.label(egui::RichText::new("View Options").heading().size(font_18)); } }); } diff --git a/src/ui/tab_bar.rs b/src/ui/tab_bar.rs index a507880..98c27a3 100644 --- a/src/ui/tab_bar.rs +++ b/src/ui/tab_bar.rs @@ -63,9 +63,10 @@ impl UltraLogApp { .show(ui, |ui| { ui.horizontal(|ui| { // Tab name (clickable) + let font_13 = self.scaled_font(13.0); let label_response = ui.add( egui::Label::new( - egui::RichText::new(name).color(text_color).size(13.0), + egui::RichText::new(name).color(text_color).size(font_13), ) .sense(egui::Sense::click()), ); @@ -80,11 +81,12 @@ impl UltraLogApp { ui.add_space(4.0); // Close button + let font_14 = self.scaled_font(14.0); let close_btn = ui.add( egui::Label::new( egui::RichText::new("×") .color(egui::Color32::from_rgb(150, 150, 150)) - .size(14.0), + .size(font_14), ) .sense(egui::Sense::click()), ); diff --git a/src/ui/timeline.rs b/src/ui/timeline.rs index 03051ba..dae566e 100644 --- a/src/ui/timeline.rs +++ b/src/ui/timeline.rs @@ -8,6 +8,9 @@ use crate::app::UltraLogApp; impl UltraLogApp { /// Render the timeline scrubber bar pub fn render_timeline_scrubber(&mut self, ui: &mut egui::Ui) { + // Pre-compute scaled font size + let font_12 = self.scaled_font(12.0); + let Some((min_time, max_time)) = self.get_time_range() else { return; }; @@ -20,12 +23,15 @@ impl UltraLogApp { // Time labels row ui.horizontal(|ui| { ui.label( - egui::RichText::new(Self::format_time(min_time)).color(egui::Color32::LIGHT_GRAY), + egui::RichText::new(Self::format_time(min_time)) + .color(egui::Color32::LIGHT_GRAY) + .size(font_12), ); ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { ui.label( egui::RichText::new(Self::format_time(max_time)) - .color(egui::Color32::LIGHT_GRAY), + .color(egui::Color32::LIGHT_GRAY) + .size(font_12), ); }); }); @@ -63,19 +69,24 @@ impl UltraLogApp { /// Render the record/time indicator bar with playback controls pub fn render_record_indicator(&mut self, ui: &mut egui::Ui) { + // Pre-compute scaled font size + let font_14 = self.scaled_font(14.0); + ui.horizontal(|ui| { // Playback controls let button_size = egui::vec2(28.0, 28.0); // Play/Pause button let play_text = if self.is_playing { "⏸" } else { "▶" }; - let play_button = egui::Button::new(egui::RichText::new(play_text).size(16.0).color( - if self.is_playing { - egui::Color32::from_rgb(253, 193, 73) // Amber when playing - } else { - egui::Color32::from_rgb(144, 238, 144) // Light green when paused - }, - )) + let play_button = egui::Button::new( + egui::RichText::new(play_text) + .size(self.scaled_font(16.0)) + .color(if self.is_playing { + egui::Color32::from_rgb(253, 193, 73) // Amber when playing + } else { + egui::Color32::from_rgb(144, 238, 144) // Light green when paused + }), + ) .min_size(button_size); if ui.add(play_button).clicked() { @@ -99,7 +110,7 @@ impl UltraLogApp { // Stop button (resets to beginning) let stop_button = egui::Button::new( egui::RichText::new("⏹") - .size(16.0) + .size(self.scaled_font(16.0)) .color(egui::Color32::from_rgb(191, 78, 48)), // Rust orange ) .min_size(button_size); @@ -118,7 +129,11 @@ impl UltraLogApp { ui.separator(); // Playback speed selector - ui.label(egui::RichText::new("Speed:").color(egui::Color32::GRAY)); + ui.label( + egui::RichText::new("Speed:") + .color(egui::Color32::GRAY) + .size(font_14), + ); let speed_options = [0.25, 0.5, 1.0, 2.0, 4.0, 8.0]; egui::ComboBox::from_id_salt("playback_speed") @@ -137,7 +152,8 @@ impl UltraLogApp { ui.label( egui::RichText::new(format!("Time: {}", Self::format_time(time))) .strong() - .color(egui::Color32::from_rgb(0, 255, 255)), // Cyan to match cursor + .color(egui::Color32::from_rgb(0, 255, 255)) // Cyan to match cursor + .size(font_14), ); } @@ -155,7 +171,8 @@ impl UltraLogApp { record + 1, total_records )) - .color(egui::Color32::LIGHT_GRAY), + .color(egui::Color32::LIGHT_GRAY) + .size(font_14), ); } } diff --git a/src/ui/toast.rs b/src/ui/toast.rs index a52f0c3..c0472d9 100644 --- a/src/ui/toast.rs +++ b/src/ui/toast.rs @@ -44,7 +44,7 @@ impl UltraLogApp { text_color[1], text_color[2], )) - .size(14.0), + .size(self.scaled_font(14.0)), ); }); }); diff --git a/src/ui/tool_switcher.rs b/src/ui/tool_switcher.rs index 90493f7..b036b55 100644 --- a/src/ui/tool_switcher.rs +++ b/src/ui/tool_switcher.rs @@ -48,7 +48,7 @@ impl UltraLogApp { let response = ui.add( egui::Button::new( egui::RichText::new(tool.name()) - .size(14.0) + .size(self.scaled_font(14.0)) .color(text_color), ) .fill(button_fill) diff --git a/src/ui/update_dialog.rs b/src/ui/update_dialog.rs index 23ee10d..4d14faa 100644 --- a/src/ui/update_dialog.rs +++ b/src/ui/update_dialog.rs @@ -63,7 +63,7 @@ impl UltraLogApp { ui.label( egui::RichText::new("A new version is available!") - .size(18.0) + .size(self.scaled_font(18.0)) .strong(), ); @@ -133,7 +133,7 @@ impl UltraLogApp { ui.vertical_centered(|ui| { ui.add_space(20.0); - ui.label(egui::RichText::new("Downloading update...").size(16.0)); + ui.label(egui::RichText::new("Downloading update...").size(self.scaled_font(16.0))); ui.add_space(15.0); @@ -158,7 +158,7 @@ impl UltraLogApp { ui.label( egui::RichText::new("Download complete!") - .size(16.0) + .size(self.scaled_font(16.0)) .color(egui::Color32::LIGHT_GREEN), ); @@ -224,7 +224,7 @@ impl UltraLogApp { ui.label( egui::RichText::new("Update Error") - .size(16.0) + .size(self.scaled_font(16.0)) .color(egui::Color32::from_rgb(191, 78, 48)), );