system settings
git clone https://git.lucas.co/cce-system-interface.git
Clean up local font loading logic and delegate to cce-ui
src/main.rs | 134 +++-----------------------------------------------
src/pages/accounts.rs | 23 +++++++++
src/renderer.rs | 24 +++++----
3 files changed, 44 insertions(+), 137 deletions(-)
diff --git a/src/main.rs b/src/main.rs
index 7f7dbf8..b872e0e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,142 +1,21 @@
use cce_ui::widget::{hover_animation, Element};
-use glyphon::{Attrs, Buffer, FontSystem, Metrics};
+use glyphon::{Buffer, FontSystem};
use cce_settings::app::{AppAction, AppState};
use cce_settings::pages::{self, Page};
mod input_handler;
mod renderer;
-#[derive(Hash, PartialEq, Eq, Clone)]
-struct BufferCacheKey {
- text: String,
- size_milli: u32,
- font: Option<String>,
- sans_fallback: String,
- serif_fallback: String,
- mono_fallback: String,
-}
-
-std::thread_local! {
- static BUFFER_CACHE: std::cell::RefCell<std::collections::HashMap<BufferCacheKey, Buffer>> = std::cell::RefCell::new(std::collections::HashMap::new());
-}
-
-
-fn find_cased_family(fs: &FontSystem, name: &str) -> Option<String> {
- let lower_name = name.to_lowercase();
- for face in fs.db().faces() {
- for (family, _) in &face.families {
- if family.to_lowercase() == lower_name {
- return Some(family.clone());
- }
- }
- }
- None
-}
-
fn make_text_buffer_with_font(
fs: &mut FontSystem,
text: &str,
size: f32,
font: Option<&str>,
- sans_fallback: &str,
- serif_fallback: &str,
- mono_fallback: &str,
+ _sans_fallback: &str,
+ _serif_fallback: &str,
+ _mono_fallback: &str,
) -> Buffer {
- let scale = cce_ui::scale::scale_factor();
- let mut font_size = size;
- let mut family_name = Some("sans-serif".to_string());
-
- if let Some(font_str) = font {
- let (parsed_family, parsed_size) = cce_ui::layout::parse_font_string(font_str);
- if let Some(ps) = parsed_size {
- font_size = ps;
- }
- family_name = Some(parsed_family);
- }
-
- let physical_size = font_size * scale;
- let size_key = (physical_size * 1000.0).round() as u32;
-
- let key = BufferCacheKey {
- text: text.to_string(),
- size_milli: size_key,
- font: family_name.clone(),
- sans_fallback: sans_fallback.to_string(),
- serif_fallback: serif_fallback.to_string(),
- mono_fallback: mono_fallback.to_string(),
- };
-
- let cached = BUFFER_CACHE.with(|cache| {
- cache.borrow().get(&key).cloned()
- });
-
- if let Some(buf) = cached {
- return buf;
- }
-
- let metrics = Metrics::new(physical_size, physical_size * 1.0);
- let mut buf = Buffer::new(fs, metrics);
- let mut attrs = Attrs::new();
-
- let resolved_storage = family_name.as_deref().and_then(|font_name| match font_name {
- "monospace" if !mono_fallback.is_empty() => find_cased_family(fs, mono_fallback),
- "sans-serif" if !sans_fallback.is_empty() => find_cased_family(fs, sans_fallback),
- "serif" if !serif_fallback.is_empty() => find_cased_family(fs, serif_fallback),
- _ => None,
- });
-
- if let Some(font_name) = family_name.as_deref() {
- let family = match font_name {
- "monospace" => {
- if !mono_fallback.is_empty() {
- if let Some(ref cased) = resolved_storage {
- glyphon::Family::Name(cased)
- } else {
- glyphon::Family::Name(mono_fallback)
- }
- } else {
- glyphon::Family::Name(cce_ui::layout::get_system_monospace_font())
- }
- }
- "sans-serif" => {
- if !sans_fallback.is_empty() {
- if let Some(ref cased) = resolved_storage {
- glyphon::Family::Name(cased)
- } else {
- glyphon::Family::Name(sans_fallback)
- }
- } else {
- glyphon::Family::SansSerif
- }
- }
- "serif" => {
- if !serif_fallback.is_empty() {
- if let Some(ref cased) = resolved_storage {
- glyphon::Family::Name(cased)
- } else {
- glyphon::Family::Name(serif_fallback)
- }
- } else {
- glyphon::Family::Serif
- }
- }
- _ => glyphon::Family::Name(font_name),
- };
- attrs = attrs.family(family);
- }
-
- buf.set_text(fs, text, attrs, glyphon::Shaping::Advanced);
- buf.shape_until_scroll(fs, true);
-
- BUFFER_CACHE.with(|cache| {
- let mut cache = cache.borrow_mut();
- if cache.len() > 3000 {
- cache.clear();
- }
- cache.insert(key, buf.clone());
- });
-
- buf
+ cce_ui::backend::get_text_buffer(fs, text, size, font)
}
#[allow(dead_code)]
@@ -231,7 +110,8 @@ impl cce_ui::engine::Application for SystemInterface {
let pages_names = Page::ALL.iter().map(|p| p.label().to_string()).collect::<Vec<_>>();
let page_dropdown = cce_ui::widget::input::Dropdown::new(pages_names, initial_page_idx)
- .with_open_upward(true);
+ .with_open_upward(true)
+ .with_auto_width(true);
let sidebar_width = 0.0f32;
let switcher = cce_ui::widget::Switcher::new(sidebar_width, 0.0, 820.0 - sidebar_width, 680.0);
diff --git a/src/pages/accounts.rs b/src/pages/accounts.rs
index 31c0fa6..3cb7f55 100644
--- a/src/pages/accounts.rs
+++ b/src/pages/accounts.rs
@@ -878,3 +878,26 @@ impl crate::pages::AppPage for AccountsState {
}
}
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use cce_ui::layout::AdaptiveGrid;
+
+ #[test]
+ fn test_accounts_page_view() {
+ let mut state = AccountsState::default_mock();
+ state.loaded = true;
+ let mut layout = AdaptiveGrid::new(260.0, 20.0);
+ let pc = view(&mut state, 10.0, 20.0, 800.0, 600.0, &mut layout, &mut cce_ui::context::UiContext::new());
+ println!("PC BUTTONS COUNT: {}", pc.buttons.len());
+ for (i, (btn, _)) in pc.buttons.iter().enumerate() {
+ let base = btn.base().unwrap();
+ println!(
+ "Button {}: label={:?}, x={}, y={}, w={}, h={}, bg={:?}, hover_bg={:?}, label_color={:?}",
+ i, base.label, base.x, base.y, base.w, base.h, btn.bg, btn.hover_bg, btn.label_color
+ );
+ }
+ assert!(!pc.buttons.is_empty(), "Accounts page should have buttons");
+ }
+}
+
diff --git a/src/renderer.rs b/src/renderer.rs
index 5a79d9a..abf8542 100644
--- a/src/renderer.rs
+++ b/src/renderer.rs
@@ -89,8 +89,12 @@ impl SystemInterface {
// Position sidebar and switcher below the titlebar
let mut dummy_pc = PageContent::new();
- let dropdown_w = 180.0f32;
let dropdown_h = 18.0f32;
+ let size = self.page_dropdown.measure(
+ cce_ui::widget::LayoutConstraints::new(0.0, 500.0, dropdown_h, dropdown_h),
+ &self.ui_context,
+ );
+ let dropdown_w = size.width;
let dropdown_gap = (self.status_height - dropdown_h) / 2.0;
let dropdown_x = logical_sw - dropdown_w - dropdown_gap;
let dropdown_y = logical_sh - self.status_height + dropdown_gap;
@@ -355,15 +359,15 @@ impl SystemInterface {
});
let label = base.label.as_deref().unwrap_or("");
let label_size = 12.0;
- let buf = make_text_buffer_with_font(
- &mut self.font_system,
- label,
- label_size,
- None,
- &self.sans_serif_family,
- &self.serif_family,
- &self.monospace_family,
- );
+ let buf = make_text_buffer_with_font(
+ &mut self.font_system,
+ label,
+ label_size,
+ btn.widget_font().as_deref(),
+ &self.sans_serif_family,
+ &self.serif_family,
+ &self.monospace_family,
+ );
let tw = buf.layout_runs().next().map(|r| r.line_w).unwrap_or(0.0);
let lh = buf.metrics().line_height;
let mut left_align = btn.justify == cce_ui::widget::Justification::Left;