Verified Commit 46eebb90 authored by Zander Brown's avatar Zander Brown 🇬🇧
Browse files

Apply CSS through a channel

This allows us to have (and reuse) a single provider
parent f2f2d5dd
use crate::config;
use crate::styles::generate;
use crate::utils::load_stylesheet;
use crate::styles::update_styles;
use crate::window::Window;
use gio::prelude::*;
use gtk::prelude::*;
use std::env;
pub enum Message {
ApplyStylesheet(String),
}
pub struct Application {
app: gtk::Application,
window: Window,
provider: gtk::CssProvider,
sender: glib::Sender<Message>,
}
impl Application {
pub fn new() -> Self {
let app = gtk::Application::new(Some(config::APP_ID), gio::ApplicationFlags::FLAGS_NONE).unwrap();
let window = Window::new();
let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
let window = Window::new(sender.clone());
glib::set_application_name(&format!("{}Colour Contrast", config::NAME_PREFIX));
glib::set_prgname(Some("colour-contrast"));
......@@ -23,7 +31,18 @@ impl Application {
let dialog: gtk::ShortcutsWindow = builder.get_object("shortcuts").unwrap();
window.widget.set_help_overlay(Some(&dialog));
let application = Self { app, window };
let provider = gtk::CssProvider::new();
let provider_for_cb = provider.clone();
receiver.attach(None, move |msg| {
match msg {
Message::ApplyStylesheet(text) => provider_for_cb.load_from_data(text.as_bytes()).expect("Huh?"),
}
glib::Continue(true)
});
let application = Self { app, window, provider, sender };
application.setup_gactions();
application.setup_signals();
......@@ -64,6 +83,8 @@ impl Application {
}
pub fn setup_css(&self) {
gtk::StyleContext::add_provider_for_screen(&gdk::Screen::get_default().unwrap(), &self.provider, 400);
let p = gtk::CssProvider::new();
gtk::CssProvider::load_from_resource(&p, "/org/gnome/design/ColourContrast/style.css");
gtk::StyleContext::add_provider_for_screen(&gdk::Screen::get_default().unwrap(), &p, 500);
......@@ -71,7 +92,7 @@ impl Application {
let bg_colour = self.window.state.borrow_mut().bg_colour.to_hex_string();
let fg_colour = self.window.state.borrow_mut().fg_colour.to_hex_string();
load_stylesheet(generate(fg_colour, bg_colour);
update_styles(&self.sender, fg_color, bg_color);
}
pub fn run(&self) {
......
......@@ -18,7 +18,6 @@ mod contrast_level;
mod contrast_preview;
mod static_resources;
mod styles;
mod utils;
mod window;
mod window_state;
......
......@@ -45,7 +45,7 @@ sources = files(
'contrast_preview.rs',
'main.rs',
'static_resources.rs',
'utils.rs',
'styles.rs',
'window.rs',
'window_state.rs',
)
......
use crate::application::Message;
use colorsys::Rgb;
use sass_rs::{compile_string, Options};
use std::str::FromStr;
pub fn generate(fg: &str, bg: &str) -> String {
pub fn update_styles(sender: &glib::Sender<Message>, fg: &str, bg: &str) {
let colours = format!(include_str!("Adwaita/_colors.scss"), fg = fg, bg = bg);
let colours_public = include_str!("Adwaita/_colors-public.scss");
......@@ -16,10 +17,11 @@ pub fn generate(fg: &str, bg: &str) -> String {
let scss = format!("$variant: '{}'; {} {} {} {}", variant, colours, drawing, common, colours_public);
match compile_string(&scss, Options::default()) {
Ok(styles) => styles,
Err(why) => {
error!("Couldn't parse the stylesheet: {}", why);
String::new()
Ok(styles) => {
if let Err(err) = sender.send(Message::ApplyStylesheet(styles)) {
error!("Can't update styles! {}", err);
}
}
Err(why) => error!("Couldn't parse the stylesheet: {}", why),
}
}
use gtk::CssProviderExt;
pub fn load_stylesheet(stylesheet: String) {
let provider = gtk::CssProvider::new();
match provider.load_from_data(stylesheet.as_bytes()) {
Ok(_) => {
gtk::StyleContext::add_provider_for_screen(&gdk::Screen::get_default().unwrap(), &provider, 400);
}
Err(_) => error!("Couldn't parse the stylesheet {}", stylesheet),
};
}
use crate::application::Message;
use crate::colour_entry::ColourEntry;
use crate::config::{APP_ID, PROFILE};
use crate::contrast_level::ContrastLevelBar;
......@@ -8,7 +9,7 @@ use gtk::prelude::{BoxExt, BuilderExtManual, ButtonExt, ContainerExt, EditableSi
use gtk::Inhibit;
use std::cell::RefCell;
use std::rc::Rc;
use crate::styles::generate;
use crate::styles::update_styles;
pub struct Window {
pub widget: gtk::ApplicationWindow,
......@@ -19,10 +20,11 @@ pub struct Window {
pub state: Rc<RefCell<WindowState>>,
levelbar: Rc<RefCell<ContrastLevelBar>>,
preview: Rc<RefCell<ContrastPreview>>,
sender: glib::Sender<Message>,
}
impl Window {
pub fn new() -> Self {
pub fn new(sender: glib::Sender<Message>) -> Self {
let settings = gio::Settings::new(APP_ID);
let builder = gtk::Builder::new_from_resource("/org/gnome/design/ColourContrast/window.ui");
let widget: gtk::ApplicationWindow = builder.get_object("window").unwrap();
......@@ -53,6 +55,7 @@ impl Window {
state,
levelbar,
preview,
sender,
};
window.init();
......@@ -112,13 +115,14 @@ impl Window {
reverse_btn.show();
let fg_entry = self.fg_entry.clone();
let bg_entry = self.bg_entry.clone();
let sender = self.sender.clone();
reverse_btn.connect_clicked(move |_| {
let fg_colour = fg_entry.get_text();
let bg_colour = bg_entry.get_text();
bg_entry.set_text(Some(fg_colour));
fg_entry.set_text(Some(bg_colour));
load_stylesheet(generate(fg_colour, bg_colour));
update_styles(&sender, fg_colour, bg_colour);
});
let entries_container = gtk::Box::new(gtk::Orientation::Horizontal, 0);
......
use crate::colour;
use crate::colour_entry::ColourEntry;
use crate::utils::load_stylesheet;
use colorsys::Rgb;
use gio::prelude::SettingsExt;
use gtk::prelude::GtkWindowExt;
......@@ -67,8 +66,6 @@ impl WindowState {
Some(colour) => match colour::parse(colour) {
Ok(rgb) => {
self.bg_colour = rgb.clone();
let stylesheet = format!("@define-color background_color {};", rgb.to_hex_string());
load_stylesheet(stylesheet);
self.contrast_level = colour::calc_contrast_level(&self.bg_colour, &self.fg_colour);
}
Err(_) => error!("Failed to parse colour {}", colour),
......@@ -83,8 +80,6 @@ impl WindowState {
Some(colour) => match colour::parse(colour) {
Ok(rgb) => {
self.fg_colour = rgb.clone();
let stylesheet = format!("@define-color foreground_color {};", rgb.to_hex_string());
load_stylesheet(stylesheet);
self.contrast_level = colour::calc_contrast_level(&self.bg_colour, &self.fg_colour);
}
Err(_) => error!("Failed to parse colour {}", colour),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment