window.rs 5.85 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
7
use crate::libhandy::HeaderBarExt;
use crate::window_state::WindowState;
8
use gettextrs::gettext;
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
    pub state: Rc<RefCell<WindowState>>,
23
24
    pub levelbar: Rc<RefCell<ContrastLevelBar>>,
    pub 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/Contrast/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
37
        let bg_entry = ColourEntry::new(gettext("Background Colour"));
        let fg_entry = ColourEntry::new(gettext("Foreground Colour"));
38

39
40
        let reverse_btn = gtk::Button::new();

41
        let state = Rc::new(RefCell::new(WindowState::init(settings)));
42

43
44
        let levelbar = Rc::new(RefCell::new(ContrastLevelBar::new()));
        let preview = Rc::new(RefCell::new(ContrastPreview::new()));
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
45

Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
46
47
48
49
        if PROFILE == "Devel" {
            widget.get_style_context().add_class("devel");
        }

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

Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
63
        window.init();
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
64
        window.setup_widgets();
65
        window.setup_signals();
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
66
67
68
        window
    }

Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
69
70
    pub fn init(&self) {
        self.widget.get_style_context().add_class("main-window");
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
71
        // setup app menu
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
72
        let menu_builder = gtk::Builder::new_from_resource("/org/gnome/design/Contrast/menu.ui");
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
73
74
75
        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
76
77

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

Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
83
        self.widget.show();
Bilal Elmoussaoui's avatar
Init  
Bilal Elmoussaoui committed
84
    }
85
86
    fn setup_signals(&self) {
        let state = self.state.clone();
87
88
89
90
91
92
93
94
95
96
        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));

97
            sender.send(Message::ColorChanged).ok(); // never fails
98
        };
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
99

100
101
        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
102

103
        let state = self.state.clone();
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
104
105
        let fg_entry = self.fg_entry.clone();
        let bg_entry = self.bg_entry.clone();
Zander Brown's avatar
Zander Brown committed
106
        let sender = self.sender.clone();
107
108
109
        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
110
111
            let fg_colour = fg_entry.get_text();
            let bg_colour = bg_entry.get_text();
112
113
114
115
116
            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);

117
118
            state.borrow_mut().set_bg_colour(Some(&fg_colour));
            state.borrow_mut().set_fg_colour(Some(&bg_colour));
Zander Brown's avatar
Zander Brown committed
119

120
            sender.send(Message::ColorChanged).ok(); // never fails
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
121
        });
122
123
124
125
126
    }

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

130
131
132
        self.fg_entry.entry.get_style_context().add_class("fg-entry");
        self.bg_entry.entry.get_style_context().add_class("bg-entry");

133
134
135
136
137
        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
138

Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
139
        let entries_container = gtk::Box::new(gtk::Orientation::Horizontal, 0);
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
140
        entries_container.pack_start(&self.bg_entry.widget, false, false, 6);
141
        entries_container.pack_start(&self.reverse_btn, false, false, 6);
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
142
143
144
        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
145
        self.headerbar.set_custom_title(Some(&entries_container));
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
146

147
148
        container.pack_start(&self.preview.borrow().widget, true, true, 18);
        container.pack_start(&self.levelbar.borrow().widget, false, false, 18);
Bilal Elmoussaoui's avatar
Bilal Elmoussaoui committed
149
150

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