window.rs 6.49 KB
Newer Older
Zander Brown's avatar
Zander Brown committed
1
use crate::application::Message;
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
2
use crate::colour_entry::ColourEntry;
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
3
use crate::config::{APP_ID, PROFILE};
4
use crate::contrast_level::ContrastLevelBar;
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
5
use crate::contrast_preview::ContrastPreview;
6
use crate::libhandy::HeaderBarExt;
7
use crate::styles::update_styles;
8
use crate::window_state::WindowState;
9
10
use glib::ObjectExt;
use gtk::prelude::{BoxExt, BuilderExtManual, ButtonExt, ContainerExt, EditableSignals, MenuButtonExt, StyleContextExt, WidgetExt};
11
12
13
use gtk::Inhibit;
use std::cell::RefCell;
use std::rc::Rc;
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
14
15
16
17

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

impl Window {
Zander Brown's avatar
Zander Brown committed
29
    pub fn new(sender: glib::Sender<Message>) -> 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/ColourContrast/window.ui");
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
32
        let widget: gtk::ApplicationWindow = builder.get_object("window").unwrap();
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
33
        let headerbar: libhandy::HeaderBar = builder.get_object("headerbar").unwrap();
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
34
35
        let appmenu_button: gtk::MenuButton = builder.get_object("appmenu_button").unwrap();

36
        let bg_entry = ColourEntry::new("Background Colour".to_string());
37
        bg_entry.entry.set_name("bg");
38
        let fg_entry = ColourEntry::new("Foreground Colour".to_string());
39
40
        fg_entry.entry.set_name("fg");

41
42
        let reverse_btn = gtk::Button::new();

43
44
45
46
47
        let state = Rc::new(RefCell::new(WindowState::init(settings)));
        let levelbar = Rc::new(RefCell::new(ContrastLevelBar::new()));
        levelbar.borrow_mut().set_contrast_level(state.borrow_mut().contrast_level);
        let preview = Rc::new(RefCell::new(ContrastPreview::new()));
        preview.borrow_mut().set_contrast_level(state.borrow_mut().contrast_level);
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
48

Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
49
50
51
52
        if PROFILE == "Devel" {
            widget.get_style_context().add_class("devel");
        }

Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
53
54
55
56
57
        let window = Window {
            widget,
            appmenu_button,
            fg_entry,
            bg_entry,
58
            reverse_btn,
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
59
            headerbar,
60
61
62
            state,
            levelbar,
            preview,
Zander Brown's avatar
Zander Brown committed
63
            sender,
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
64
        };
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
65

Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
66
        window.init();
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
67
        window.setup_widgets();
68
        window.setup_signals();
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
69
70
71
        window
    }

Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
72
73
    pub fn init(&self) {
        self.widget.get_style_context().add_class("main-window");
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
74
        // setup app menu
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
75
        let menu_builder = gtk::Builder::new_from_resource("/org/gnome/design/ColourContrast/menu.ui");
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
76
77
78
        let popover_menu: gio::MenuModel = menu_builder.get_object("popover_menu").unwrap();
        self.appmenu_button.set_menu_model(Some(&popover_menu));
        // save window state on delete event
79
80

        let state = self.state.clone();
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
81
        self.widget.connect_delete_event(move |window, _| {
82
            state.borrow_mut().dump(&window);
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
83
84
85
            Inhibit(false)
        });

Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
86
        self.widget.show();
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
87
    }
88
89
90
91
    fn setup_signals(&self) {
        let state = self.state.clone();
        let level_bar = self.levelbar.clone();
        let preview = self.preview.clone();
92
93
94
95
96
97
98
99
100
101
        let fg_entry = self.fg_entry.clone();
        let bg_entry = self.bg_entry.clone();
        let sender = self.sender.clone();
        let on_entry_changed = move |_entry: &gtk::Entry| {
            let fg_colour = fg_entry.get_text();
            let bg_colour = bg_entry.get_text();

            state.borrow_mut().set_bg_colour(Some(&bg_colour));
            state.borrow_mut().set_fg_colour(Some(&fg_colour));

102
103
104
105
            let contarst_level = state.borrow_mut().contrast_level;
            level_bar.borrow_mut().set_contrast_level(contarst_level);
            preview.borrow_mut().set_contrast_level(contarst_level);

106
107
            update_styles(&sender, fg_colour, bg_colour);
        };
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
108

109
110
        let bg_handle = self.bg_entry.entry.connect_changed(on_entry_changed.clone());
        let fg_handle = self.fg_entry.entry.connect_changed(on_entry_changed.clone());
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
111

112
113
114
        let state = self.state.clone();
        let level_bar = self.levelbar.clone();
        let preview = self.preview.clone();
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
115
116
        let fg_entry = self.fg_entry.clone();
        let bg_entry = self.bg_entry.clone();
Zander Brown's avatar
Zander Brown committed
117
        let sender = self.sender.clone();
118
119
120
        self.reverse_btn.connect_clicked(move |_| {
            fg_entry.entry.block_signal(&fg_handle);
            bg_entry.entry.block_signal(&bg_handle);
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
121
122
            let fg_colour = fg_entry.get_text();
            let bg_colour = bg_entry.get_text();
123
124
125
126
127
128
129
130
131
132
133
            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);

            state.borrow_mut().set_bg_colour(Some(&bg_colour));
            state.borrow_mut().set_fg_colour(Some(&fg_colour));

            let contarst_level = state.borrow_mut().contrast_level;
            level_bar.borrow_mut().set_contrast_level(contarst_level);
            preview.borrow_mut().set_contrast_level(contarst_level);
Zander Brown's avatar
Zander Brown committed
134

Zander Brown's avatar
Zander Brown committed
135
            update_styles(&sender, fg_colour, bg_colour);
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
136
        });
137
138
139
140
141
142
143
144
145
146
147
148
    }

    fn setup_widgets(&self) {
        let container = gtk::Box::new(gtk::Orientation::Vertical, 0);
        container.get_style_context().add_class("main-container");
        container.show();

        self.reverse_btn.set_halign(gtk::Align::Center);
        let reverse_img = gtk::Image::new_from_icon_name(Some("network-transmit-receive-symbolic"), gtk::IconSize::Button);
        reverse_img.show();
        self.reverse_btn.set_image(Some(&reverse_img));
        self.reverse_btn.show();
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
149

Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
150
        let entries_container = gtk::Box::new(gtk::Orientation::Horizontal, 0);
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
151
        entries_container.pack_start(&self.bg_entry.widget, false, false, 6);
152
        entries_container.pack_start(&self.reverse_btn, false, false, 6);
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
153
154
155
        entries_container.pack_start(&self.fg_entry.widget, false, false, 6);
        entries_container.set_halign(gtk::Align::Center);
        entries_container.show();
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
156
        self.headerbar.set_custom_title(Some(&entries_container));
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
157

158
159
        container.pack_start(&self.preview.borrow_mut().widget, true, true, 0);
        container.pack_start(&self.levelbar.borrow_mut().widget, false, false, 0);
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
160
161

        self.widget.add(&container);
162
163
        // Restore state
        self.state.borrow_mut().load_into(&self.widget, &self.bg_entry, &self.fg_entry);
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
164
    }
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
165
}