From 3450d6db9bfbc18dae8409594c3f47ae573dd534 Mon Sep 17 00:00:00 2001 From: Shaun Reed Date: Sat, 21 Feb 2026 21:10:12 -0500 Subject: [PATCH] WIP --- libclide/src/lib.rs | 1 + libclide/src/theme.rs | 5 +++ libclide/src/theme/colors.rs | 52 ++++++++++++++++++++++++++++++ src/gui/colors.rs | 62 ++++++++++++++++++------------------ src/tui/component.rs | 5 +-- 5 files changed, 92 insertions(+), 33 deletions(-) create mode 100644 libclide/src/theme.rs create mode 100644 libclide/src/theme/colors.rs diff --git a/libclide/src/lib.rs b/libclide/src/lib.rs index 950c8f3..baf3411 100644 --- a/libclide/src/lib.rs +++ b/libclide/src/lib.rs @@ -3,3 +3,4 @@ // SPDX-License-Identifier: GNU General Public License v3.0 or later pub mod fs; +pub mod theme; diff --git a/libclide/src/theme.rs b/libclide/src/theme.rs new file mode 100644 index 0000000..645977c --- /dev/null +++ b/libclide/src/theme.rs @@ -0,0 +1,5 @@ +// SPDX-FileCopyrightText: 2026, Shaun Reed +// +// SPDX-License-Identifier: GNU General Public License v3.0 or later + +pub mod colors; diff --git a/libclide/src/theme/colors.rs b/libclide/src/theme/colors.rs new file mode 100644 index 0000000..69bbaf0 --- /dev/null +++ b/libclide/src/theme/colors.rs @@ -0,0 +1,52 @@ +// SPDX-FileCopyrightText: 2026, Shaun Reed +// +// SPDX-License-Identifier: GNU General Public License v3.0 or later + +pub struct Colors {} + +impl Colors { + pub const HOVERED: &str = "#303234"; + pub const UNHOVERED: &str = "#3c3f41"; + pub const PRESSED: &str = "#4b4f51"; + pub const MENUBAR: &str = "#262626"; + pub const MENUBAR_BORDER: &str = "#575757"; + pub const SCROLLBAR: &str = "#4b4f51"; + pub const SCROLLBAR_ACTIVE: &str = "#4b4f51"; + pub const SCROLLBAR_GUTTER: &str = "#3b3b3b"; + pub const LINENUMBER: &str = "#94989b"; + pub const ACTIVE: &str = "#a9acb0"; + pub const INACTIVE: &str = "#FFF"; + pub const EDITOR_BACKGROUND: &str = "#1E1F22"; + pub const EDITOR_TEXT: &str = "#acaea3"; + pub const EDITOR_HIGHLIGHTED_TEXT: &str = "#ccced3"; + pub const EDITOR_HIGHLIGHT: &str = "#ccced3"; + pub const GUTTER: &str = "#1e1f22"; + pub const EXPLORER_HOVERED: &str = "#4c5053"; + pub const EXPLORER_TEXT: &str = "#FFF"; + pub const EXPLORER_TEXT_SELECTED: &str = "#262626"; + pub const EXPLORER_BACKGROUND: &str = "#1E1F22"; + pub const EXPLORER_FOLDER: &str = "#54585b"; + pub const EXPLORER_FOLDER_OPEN: &str = "#393B40"; + pub const TERMINAL_BACKGROUND: &str = "#111111"; + pub const INFO_LOG: &str = "#C4FFFF"; + pub const DEBUG_LOG: &str = "#9148AF"; + pub const WARN_LOG: &str = "#C4A958"; + pub const ERROR_LOG: &str = "#ff5555"; + pub const TRACE_LOG: &str = "#ffaa00"; + + pub fn css_to_u32(css: &str) -> Result { + let hex = css.trim_start_matches('#'); + // Expand shorthand #RGB to #RRGGBB + let hex_full = match hex.len() { + 3 => hex.chars() + .map(|c| std::iter::repeat(c).take(2).collect::()) + .collect::(), + 6 => hex.to_string(), + _ => return Err(format!("Invalid hex color length: {}", hex)), + }; + // Parse the hex string as u32, masking to ensure the top byte is 0x00. + u32::from_str_radix(&hex_full, 16) + .map(|rgb| rgb & 0x00FF_FFFF) + .map_err(|e| format!("Failed to parse hex: {}", e)) + } +} diff --git a/src/gui/colors.rs b/src/gui/colors.rs index 9fb5ab3..8500527 100644 --- a/src/gui/colors.rs +++ b/src/gui/colors.rs @@ -2,8 +2,10 @@ // // SPDX-License-Identifier: GNU General Public License v3.0 or later -#[cxx_qt::bridge] +use cxx_qt_lib::QColor; +use libclide::theme::colors::Colors; +#[cxx_qt::bridge] pub mod qobject { unsafe extern "C++" { include!("cxx-qt-lib/qcolor.h"); @@ -46,8 +48,6 @@ pub mod qobject { } } -use cxx_qt_lib::QColor; - pub struct RustColorsImpl { hovered: QColor, unhovered: QColor, @@ -82,34 +82,34 @@ pub struct RustColorsImpl { impl Default for RustColorsImpl { fn default() -> Self { Self { - hovered: QColor::try_from("#303234").unwrap(), - unhovered: QColor::try_from("#3c3f41").unwrap(), - pressed: QColor::try_from("#4b4f51").unwrap(), - menubar: QColor::try_from("#262626").unwrap(), - menubar_border: QColor::try_from("#575757").unwrap(), - scrollbar: QColor::try_from("#4b4f51").unwrap(), - scrollbar_active: QColor::try_from("#4b4f51").unwrap(), - scrollbar_gutter: QColor::try_from("#3b3b3b").unwrap(), - linenumber: QColor::try_from("#94989b").unwrap(), - active: QColor::try_from("#a9acb0").unwrap(), - inactive: QColor::try_from("#FFF").unwrap(), - editor_background: QColor::try_from("#1E1F22").unwrap(), - editor_text: QColor::try_from("#acaea3").unwrap(), - editor_highlighted_text: QColor::try_from("#ccced3").unwrap(), - editor_highlight: QColor::try_from("#ccced3").unwrap(), - gutter: QColor::try_from("#1e1f22").unwrap(), - explorer_hovered: QColor::try_from("#4c5053").unwrap(), - explorer_text: QColor::try_from("#FFF").unwrap(), - explorer_text_selected: QColor::try_from("#262626").unwrap(), - explorer_background: QColor::try_from("#1E1F22").unwrap(), - explorer_folder: QColor::try_from("#54585b").unwrap(), - explorer_folder_open: QColor::try_from("#393B40").unwrap(), - terminal_background: QColor::try_from("#111111").unwrap(), - info_log: QColor::try_from("#C4FFFF").unwrap(), - debug_log: QColor::try_from("#9148AF").unwrap(), - warn_log: QColor::try_from("#C4A958").unwrap(), - error_log: QColor::try_from("#ff5555").unwrap(), - trace_log: QColor::try_from("#ffaa00").unwrap(), + hovered: QColor::try_from(Colors::HOVERED).unwrap(), + unhovered: QColor::try_from(Colors::UNHOVERED).unwrap(), + pressed: QColor::try_from(Colors::PRESSED).unwrap(), + menubar: QColor::try_from(Colors::MENUBAR).unwrap(), + menubar_border: QColor::try_from(Colors::MENUBAR_BORDER).unwrap(), + scrollbar: QColor::try_from(Colors::SCROLLBAR).unwrap(), + scrollbar_active: QColor::try_from(Colors::SCROLLBAR_ACTIVE).unwrap(), + scrollbar_gutter: QColor::try_from(Colors::SCROLLBAR_GUTTER).unwrap(), + linenumber: QColor::try_from(Colors::LINENUMBER).unwrap(), + active: QColor::try_from(Colors::ACTIVE).unwrap(), + inactive: QColor::try_from(Colors::INACTIVE).unwrap(), + editor_background: QColor::try_from(Colors::EDITOR_BACKGROUND).unwrap(), + editor_text: QColor::try_from(Colors::EDITOR_TEXT).unwrap(), + editor_highlighted_text: QColor::try_from(Colors::EDITOR_HIGHLIGHTED_TEXT).unwrap(), + editor_highlight: QColor::try_from(Colors::EDITOR_HIGHLIGHT).unwrap(), + gutter: QColor::try_from(Colors::GUTTER).unwrap(), + explorer_hovered: QColor::try_from(Colors::EXPLORER_HOVERED).unwrap(), + explorer_text: QColor::try_from(Colors::EXPLORER_TEXT).unwrap(), + explorer_text_selected: QColor::try_from(Colors::EXPLORER_TEXT_SELECTED).unwrap(), + explorer_background: QColor::try_from(Colors::EXPLORER_BACKGROUND).unwrap(), + explorer_folder: QColor::try_from(Colors::EXPLORER_FOLDER).unwrap(), + explorer_folder_open: QColor::try_from(Colors::EXPLORER_FOLDER_OPEN).unwrap(), + terminal_background: QColor::try_from(Colors::TERMINAL_BACKGROUND).unwrap(), + info_log: QColor::try_from(Colors::INFO_LOG).unwrap(), + debug_log: QColor::try_from(Colors::DEBUG_LOG).unwrap(), + warn_log: QColor::try_from(Colors::WARN_LOG).unwrap(), + error_log: QColor::try_from(Colors::ERROR_LOG).unwrap(), + trace_log: QColor::try_from(Colors::TRACE_LOG).unwrap(), } } } diff --git a/src/tui/component.rs b/src/tui/component.rs index 27b3999..6d9d655 100644 --- a/src/tui/component.rs +++ b/src/tui/component.rs @@ -7,6 +7,7 @@ use crate::tui::component::Focus::Inactive; use Focus::Active; use anyhow::Result; +use libclide::theme::colors::Colors; use log::trace; use ratatui::crossterm::event::{Event, KeyEvent, MouseEvent}; use ratatui::style::Color; @@ -98,8 +99,8 @@ pub enum Focus { impl Focus { pub(crate) fn get_active_color(&self) -> Color { match self { - Active => Color::LightYellow, - Inactive => Color::White, + Active => Color::from_u32(Colors::css_to_u32(Colors::ACTIVE)?), + Inactive => Color::from_u32(Colors::css_to_u32(Colors::INACTIVE)?), } } }