window.rs 5.87 KB
Newer Older
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
1
use super::application::Action;
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
2
use super::colour;
3
4
5
6
use super::colour_entry::ColourEntry;
use super::config::{APP_ID, PROFILE};
use super::contrast_level::ContrastLevelBar;
use super::contrast_preview::ContrastPreview;
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
7
use super::utils;
8
9
use super::window_state::WindowState;

10
use gettextrs::gettext;
11
use glib::ObjectExt;
12
use gtk::prelude::*;
13
use libhandy::HeaderBarExt;
14
use std::{cell::RefCell, rc::Rc};
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
15
16
17

pub struct Window {
    pub widget: gtk::ApplicationWindow,
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
18
    builder: gtk::Builder,
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
19
20
    fg_entry: ColourEntry,
    bg_entry: ColourEntry,
21
    reverse_btn: gtk::Button,
22
    pub state: Rc<RefCell<WindowState>>,
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
23
24
    pub levelbar: RefCell<ContrastLevelBar>,
    pub preview: RefCell<ContrastPreview>,
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
25
    sender: glib::Sender<Action>,
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
26
27
28
}

impl Window {
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
29
    pub fn new(sender: glib::Sender<Action>) -> Rc<Self> {
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
30
        let settings = gio::Settings::new(APP_ID);
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
31
        let builder = gtk::Builder::new_from_resource("/org/gnome/design/Contrast/window.ui");
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
32
        get_widget!(builder, gtk::ApplicationWindow, window_widget);
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
33

34
35
        let bg_entry = ColourEntry::new(gettext("Background Colour"));
        let fg_entry = ColourEntry::new(gettext("Foreground Colour"));
36

37
38
        let reverse_btn = gtk::Button::new();

39
        let state = Rc::new(RefCell::new(WindowState::init(settings)));
40

Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
41
42
        let levelbar = RefCell::new(ContrastLevelBar::new());
        let preview = RefCell::new(ContrastPreview::new());
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
43

Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
44
45
46
        let window = Rc::new(Window {
            widget: window_widget,
            builder,
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
47
48
            fg_entry,
            bg_entry,
49
            reverse_btn,
50
51
52
            state,
            levelbar,
            preview,
Zander Brown's avatar
Zander Brown committed
53
            sender,
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
54
        });
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
55

Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
56
        window.setup_widgets();
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
57
        window.setup_signals(window.clone());
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
58
59
60
        window
    }

Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
61
62
63
64
65
66
67
    fn colour_changed(&self, bg_colour: String, fg_colour: String) {
        let bg_rgba = self.state.borrow_mut().set_bg_colour(Some(&bg_colour));
        let fg_rgba = self.state.borrow_mut().set_fg_colour(Some(&fg_colour));
        let contrast_level = colour::calc_contrast_level(&bg_rgba, &fg_rgba);

        self.levelbar.borrow_mut().set_contrast_level(contrast_level);
        self.preview.borrow_mut().set_contrast_level(contrast_level);
68

Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
69
70
71
72
73
74
        utils::compile_styles(&self.sender, fg_rgba, bg_rgba);
    }

    fn setup_signals(&self, window: Rc<Self>) {
        // save window state on delete event
        self.widget.connect_delete_event(clone!(@strong self.state as state => move |window, _| {
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
75
76
77
            if let Err(err) = state.borrow_mut().dump(&window) {
                warn!("Failed to save window state {}", err);
            }
78
            gtk::Inhibit(false)
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
79
        }));
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
80

Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
81
82
83
        let on_entry_changed = clone!(
                    @strong self.fg_entry as fg_entry,@strong self.bg_entry as bg_entry,
                    @weak window => move |_entry: &gtk::Entry| {
84
85
86
            let fg_colour = fg_entry.get_text();
            let bg_colour = bg_entry.get_text();

Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
87
88
            window.colour_changed(bg_colour, fg_colour);
        });
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
89

90
        let bg_handle = self.bg_entry.entry.connect_changed(on_entry_changed.clone());
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
91
        let fg_handle = self.fg_entry.entry.connect_changed(on_entry_changed);
92
93

        let actions = gio::SimpleActionGroup::new();
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
        utils::action(
            &actions,
            "reverse-colors",
            None,
            clone!(@strong self.fg_entry as fg_entry, @strong self.bg_entry as bg_entry => move |_, _| {
                fg_entry.entry.block_signal(&fg_handle);
                bg_entry.entry.block_signal(&bg_handle);
                let fg_colour = fg_entry.get_text();
                let bg_colour = bg_entry.get_text();
                fg_entry.set_text(Some(bg_colour.clone()));
                bg_entry.set_text(Some(fg_colour.clone()));

                fg_entry.entry.unblock_signal(&fg_handle);
                bg_entry.entry.unblock_signal(&bg_handle);

                window.colour_changed(fg_colour, bg_colour);
            }),
        );
112
        self.widget.insert_action_group("window", Some(&actions));
113
114
115
    }

    fn setup_widgets(&self) {
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
116
117
118
119
120
121
122
        if PROFILE == "Devel" {
            self.widget.get_style_context().add_class("devel");
        }
        let builder = gtk::Builder::new_from_resource("/org/gnome/design/Contrast/shortcuts.ui");
        get_widget!(builder, gtk::ShortcutsWindow, shortcuts_dialog);
        self.widget.set_help_overlay(Some(&shortcuts_dialog));

123
124
        let container = gtk::Box::new(gtk::Orientation::Vertical, 0);
        container.get_style_context().add_class("main-container");
125
        container.set_valign(gtk::Align::Center);
126

127
128
129
        self.fg_entry.entry.get_style_context().add_class("fg-entry");
        self.bg_entry.entry.get_style_context().add_class("bg-entry");

130
        self.reverse_btn.set_halign(gtk::Align::Center);
131
        self.reverse_btn.set_action_name(Some("window.reverse-colors"));
132
133
        let reverse_img = gtk::Image::new_from_icon_name(Some("network-transmit-receive-symbolic"), gtk::IconSize::Button);
        self.reverse_btn.set_image(Some(&reverse_img));
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
134

Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
135
        let entries_container = gtk::Box::new(gtk::Orientation::Horizontal, 0);
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
136
        entries_container.pack_start(&self.bg_entry.widget, false, false, 6);
137
        entries_container.pack_start(&self.reverse_btn, false, false, 6);
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
138
139
        entries_container.pack_start(&self.fg_entry.widget, false, false, 6);
        entries_container.set_halign(gtk::Align::Center);
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
140
141
142

        get_widget!(self.builder, libhandy::HeaderBar, headerbar);
        headerbar.set_custom_title(Some(&entries_container));
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
143

144
145
        container.pack_start(&self.preview.borrow().widget, true, true, 12);
        container.pack_start(&self.levelbar.borrow().widget, true, true, 12);
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
146
147

        self.widget.add(&container);
148
149
        // Restore state
        self.state.borrow_mut().load_into(&self.widget, &self.bg_entry, &self.fg_entry);
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
150
151
        self.colour_changed(self.bg_entry.get_text(), self.fg_entry.get_text());
        self.widget.show_all();
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
152
    }
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
153
}