sysd-manager 2.18.0

Application to empower user to manage their <b>systemd units</b> via Graphical User Interface. Not only are you able to make changes to the enablement and running status of each of the units, but you will also be able to view and modify their unit files and check the journal logs.
use std::sync::{LazyLock, RwLock};

use gtk::{
    ffi::GTK_STYLE_PROVIDER_PRIORITY_APPLICATION,
    gdk,
    pango::{self, FontDescription},
    prelude::WidgetExt,
};
use tracing::{debug, info, warn};

pub static FONT_CONTEXT: LazyLock<FontContext> = LazyLock::new(FontContext::default);

#[derive(Default, Debug)]
pub struct FontContext {
    //font_family: RwLock<String>,
    //font_size: RwLock<i32>,
    font_description: RwLock<FontDescription>,
}

impl FontContext {
    pub fn set_font_description(&self, font_description: FontDescription) {
        let mut font_description_w = self.font_description.write().expect("supposed to write");
        *font_description_w = font_description;
    }

    pub fn font_description(&self) -> FontDescription {
        let font_description = self.font_description.read().expect("supposed to read");
        font_description.clone()
    }
}

pub fn is_default_font(family: &str, size: u32) -> bool {
    family.is_empty() && size == 0
}

pub fn create_provider(font_description: &Option<&FontDescription>) -> Option<gtk::CssProvider> {
    let Some(font_description) = font_description else {
        info!("set font default");

        //gtk::style_context_remove_provider_for_display(&text_view.display(), &provider);
        return None;
    };

    let family = font_description.family();
    let size = font_description.size() / pango::SCALE;

    info!("set font {:?}", font_description.to_string());
    debug!(
        "set familly {:?} gravity {:?} weight {:?} size {} variations {:?} stretch {:?}",
        font_description.family(),
        font_description.gravity(),
        font_description.weight(),
        font_description.size(),
        font_description.variations(),
        font_description.stretch(),
    );

    let provider = gtk::CssProvider::new();

    let mut css = String::with_capacity(100);

    css.push_str("textview {");
    css.push_str("font-size: ");
    css.push_str(&size.to_string());
    css.push_str("px;\n");

    if let Some(family) = family {
        css.push_str("font-family: ");
        css.push('"');
        css.push_str(family.as_str());
        css.push_str("\";\n");
    }
    css.push('}');

    provider.load_from_string(&css);

    Some(provider)
}

pub fn set_text_view_font(
    old_provider: Option<&gtk::CssProvider>,
    new_provider: Option<&gtk::CssProvider>,
    text_view: &gtk::TextView,
) {
    set_text_view_font_display(old_provider, new_provider, &text_view.display())
}

pub fn set_text_view_font_display(
    old_provider: Option<&gtk::CssProvider>,
    new_provider: Option<&gtk::CssProvider>,
    display: &gdk::Display,
) {
    if let Some(old_provider) = old_provider {
        info!("rem old font provider");
        let provider = gtk::CssProvider::new();
        let css = String::from("textview {}");
        provider.load_from_string(&css);

        gtk::style_context_remove_provider_for_display(display, old_provider);
    };

    if let Some(new_provider) = new_provider {
        info!("add new font provider");
        gtk::style_context_add_provider_for_display(
            display,
            new_provider,
            GTK_STYLE_PROVIDER_PRIORITY_APPLICATION as u32,
        );
    }
}

pub fn set_font_context(text_view: &gtk::TextView) {
    let context = text_view.pango_context();
    let font_description = context.font_description();
    if let Some(font_description) = font_description {
        info!("Font description {font_description}");
        FONT_CONTEXT.set_font_description(font_description);
    } else {
        warn!("NO FONT Description")
    }
}