1 #include "main_window.hpp"
2 #include "canvas/canvas_gl.hpp"
3 #include "util/gtk_util.hpp"
4 #include <iostream>
5 
6 namespace horizon {
7 
MainWindow(BaseObjectType * cobject,const Glib::RefPtr<Gtk::Builder> & x)8 MainWindow::MainWindow(BaseObjectType *cobject, const Glib::RefPtr<Gtk::Builder> &x)
9     : Gtk::ApplicationWindow(cobject), builder(x)
10 {
11     GET_WIDGET(tool_hint_label);
12     GET_WIDGET(left_panel);
13     GET_WIDGET(grid_box_square);
14     GET_WIDGET(grid_box_rect);
15     GET_WIDGET(grid_box_stack);
16     GET_WIDGET(grid_mul_label);
17     GET_WIDGET(cursor_label);
18     GET_WIDGET(selection_mode_label);
19     GET_WIDGET(property_viewport);
20     GET_WIDGET(tool_bar);
21     GET_WIDGET(tool_bar_name_label);
22     GET_WIDGET(tool_bar_stack);
23     GET_WIDGET(tool_bar_tip_label);
24     GET_WIDGET(tool_bar_flash_label);
25     GET_WIDGET(selection_label);
26     GET_WIDGET(header);
27     GET_WIDGET(property_scrolled_window);
28     GET_WIDGET(property_throttled_revealer);
29     GET_WIDGET(hud);
30     GET_WIDGET(hud_label);
31     GET_WIDGET(nonmodal_rev);
32     GET_WIDGET(nonmodal_button);
33     GET_WIDGET(nonmodal_close_button);
34     GET_WIDGET(nonmodal_label);
35     GET_WIDGET(nonmodal_label2);
36     GET_WIDGET(view_hints_label);
37 
38     GET_WIDGET(search_revealer);
39     GET_WIDGET(search_entry);
40     GET_WIDGET(search_previous_button);
41     GET_WIDGET(search_next_button);
42     GET_WIDGET(search_status_label);
43     GET_WIDGET(search_types_box);
44     GET_WIDGET(search_expander);
45     GET_WIDGET(search_exact_cb);
46     GET_WIDGET(action_bar_revealer);
47     GET_WIDGET(action_bar_box);
48     GET_WIDGET(view_options_button);
49     search_revealer->set_reveal_child(false);
50 
51     GET_WIDGET(grid_options_button);
52     GET_WIDGET(grid_options_revealer);
53     GET_WIDGET(grid_square_button);
54     GET_WIDGET(grid_rect_button);
55     GET_WIDGET(grid_grid);
56     GET_WIDGET(grid_window_button);
57     GET_WIDGET(grid_reset_origin_button);
58     GET_WIDGET(tool_bar_action_tip_label);
59     GET_WIDGET(tool_bar_actions_box);
60 
61     GET_WIDGET(version_info_bar);
62     GET_WIDGET(version_label);
63 
64     GET_WIDGET(key_hint_box);
65     GET_WIDGET(key_hint_revealer);
66     key_hint_size_group = Gtk::SizeGroup::create(Gtk::SIZE_GROUP_HORIZONTAL);
67 
68     set_version_info("");
69 
70     grid_options_button->signal_clicked().connect([this] {
71         const auto a = grid_options_button->get_active();
72         grid_options_revealer->set_reveal_child(a);
73         if (a) {
74             grid_options_button->set_image_from_icon_name("pan-down-symbolic", Gtk::ICON_SIZE_BUTTON);
75         }
76         else {
77             grid_options_button->set_image_from_icon_name("pan-end-symbolic", Gtk::ICON_SIZE_BUTTON);
78         }
79     });
80 
81     grid_square_button->signal_toggled().connect([this] {
82         if (grid_square_button->get_active()) {
83             grid_box_stack->set_visible_child("square");
84         }
85         else {
86             grid_box_stack->set_visible_child("rect");
87         }
88     });
89 
90 
91     nonmodal_close_button->signal_clicked().connect([this] { nonmodal_rev->set_reveal_child(false); });
92     nonmodal_button->signal_clicked().connect([this] {
93         nonmodal_rev->set_reveal_child(false);
94         if (nonmodal_fn) {
95             nonmodal_fn();
96         }
97     });
98 
99     label_set_tnum(cursor_label);
100     label_set_tnum(tool_bar_tip_label);
101     label_set_tnum(grid_mul_label);
102     label_set_tnum(search_status_label);
103     label_set_tnum(view_hints_label);
104     {
105         auto attributes_list = pango_attr_list_new();
106         auto attribute_font_features = pango_attr_font_features_new("tnum 1");
107         pango_attr_list_insert(attributes_list, attribute_font_features);
108         auto attribute_italic = pango_attr_style_new(PANGO_STYLE_ITALIC);
109         pango_attr_list_insert(attributes_list, attribute_italic);
110         gtk_label_set_attributes(tool_bar_action_tip_label->gobj(), attributes_list);
111         pango_attr_list_unref(attributes_list);
112     }
113 
114     GET_WIDGET(gl_container);
115     canvas = Gtk::manage(new CanvasGL());
116     gl_container->add(*canvas);
117     canvas->show();
118 
119     tool_bar_set_visible(false);
120     hud->set_reveal_child(false);
121     set_use_action_bar(false);
122 }
123 
tool_bar_set_visible(bool v)124 void MainWindow::tool_bar_set_visible(bool v)
125 {
126     if (v == false && tip_timeout_connection) { // hide and tip is still shown
127         tool_bar_queue_close = true;
128     }
129     else {
130         tool_bar->set_reveal_child(v);
131         if (v) {
132             tool_bar_queue_close = false;
133         }
134     }
135 }
136 
tool_bar_set_tool_name(const std::string & s)137 void MainWindow::tool_bar_set_tool_name(const std::string &s)
138 {
139     tool_bar_name_label->set_text(s);
140 }
141 
tool_bar_set_tool_tip(const std::string & s)142 void MainWindow::tool_bar_set_tool_tip(const std::string &s)
143 {
144     if (tool_bar_use_actions) {
145         tool_bar_action_tip_label->set_markup(s);
146     }
147     else {
148         tool_bar_tip_label->set_markup(s);
149     }
150 }
151 
tool_bar_flash(const std::string & s)152 void MainWindow::tool_bar_flash(const std::string &s)
153 {
154     tool_bar_flash_label->set_markup(s);
155     tool_bar_stack->set_visible_child("flash");
156     tip_timeout_connection.disconnect();
157     tip_timeout_connection = Glib::signal_timeout().connect(
158             [this] {
159                 if (tool_bar_use_actions)
160                     tool_bar_stack->set_visible_child("action");
161 
162                 else
163                     tool_bar_stack->set_visible_child("tip");
164                 if (tool_bar_queue_close)
165                     tool_bar->set_reveal_child(false);
166                 tool_bar_queue_close = false;
167                 return false;
168             },
169             2000);
170 }
171 
hud_update(const std::string & s)172 void MainWindow::hud_update(const std::string &s)
173 {
174     hud_timeout_connection.disconnect();
175     if (s.size()) {
176         hud_label->set_markup(s);
177         hud->set_reveal_child(true);
178     }
179     else {
180         hud_timeout_connection = Glib::signal_timeout().connect(
181                 [this] {
182                     hud->set_reveal_child(false);
183                     return false;
184                 },
185                 250);
186     }
187 }
188 
hud_hide()189 void MainWindow::hud_hide()
190 {
191     hud->set_reveal_child(false);
192 }
193 
show_nonmodal(const std::string & la,const std::string & button,std::function<void (void)> fn,const std::string & la2)194 void MainWindow::show_nonmodal(const std::string &la, const std::string &button, std::function<void(void)> fn,
195                                const std::string &la2)
196 {
197     nonmodal_label->set_markup(la);
198     nonmodal_label2->set_markup(la2);
199     nonmodal_label2->set_visible(la2.size());
200     nonmodal_button->set_label(button);
201     nonmodal_fn = fn;
202     nonmodal_rev->set_reveal_child(true);
203 }
204 
set_view_hints_label(const std::vector<std::string> & s)205 void MainWindow::set_view_hints_label(const std::vector<std::string> &s)
206 {
207     if (s.size()) {
208         std::string label_text;
209         std::string tooltip_text;
210         for (const auto &it : s) {
211             if (label_text.size())
212                 label_text += ", ";
213             if (tooltip_text.size())
214                 tooltip_text += "\n";
215             label_text += it;
216             tooltip_text += it;
217         }
218         view_hints_label->set_markup("<b>" + Glib::Markup::escape_text(label_text) + "</b>");
219         view_hints_label->set_tooltip_text(tooltip_text);
220     }
221     else {
222         view_hints_label->set_text("View & Selection");
223         view_hints_label->set_has_tooltip(false);
224     }
225 }
226 
set_use_action_bar(bool u)227 void MainWindow::set_use_action_bar(bool u)
228 {
229     action_bar_revealer->set_visible(u);
230     hud->set_margin_start(u ? 100 : 20);
231 }
232 
disable_grid_options()233 void MainWindow::disable_grid_options()
234 {
235     grid_options_button->set_active(false);
236     grid_options_button->set_visible(false);
237     grid_options_revealer->set_visible(false);
238 }
239 
tool_bar_set_use_actions(bool use_actions)240 void MainWindow::tool_bar_set_use_actions(bool use_actions)
241 {
242     tool_bar_use_actions = use_actions;
243     if (!tip_timeout_connection.connected()) {
244         if (use_actions)
245             tool_bar_stack->set_visible_child("action");
246 
247         else
248             tool_bar_stack->set_visible_child("tip");
249     }
250 }
251 
tool_bar_clear_actions()252 void MainWindow::tool_bar_clear_actions()
253 {
254     for (auto ch : tool_bar_actions_box->get_children())
255         delete ch;
256 }
257 
tool_bar_append_action(Gtk::Widget & w)258 void MainWindow::tool_bar_append_action(Gtk::Widget &w)
259 {
260     w.show();
261     tool_bar_actions_box->pack_start(w, false, false, 0);
262 }
263 
set_version_info(const std::string & s)264 void MainWindow::set_version_info(const std::string &s)
265 {
266     if (s.size()) {
267         info_bar_show(version_info_bar);
268         version_label->set_markup(s);
269     }
270     else {
271         info_bar_hide(version_info_bar);
272     }
273 }
274 
update_key_hint_position()275 void MainWindow::update_key_hint_position()
276 {
277     int dest_x, dest_y;
278     if (tool_hint_label->translate_coordinates(*gl_container, 0, 0, dest_x, dest_y)) {
279         key_hint_revealer->set_margin_start(dest_x - 5); // compensate for various borders and margins
280     }
281 }
282 
key_hint_set_visible(bool show)283 void MainWindow::key_hint_set_visible(bool show)
284 {
285     key_hint_connection.disconnect();
286     if (show) {
287         if (!key_hint_revealer->get_reveal_child()) {
288             update_key_hint_position();
289             key_hint_connection = Glib::signal_timeout().connect(
290                     [this] {
291                         key_hint_revealer->set_reveal_child(true);
292                         return false;
293                     },
294                     500);
295         }
296     }
297     else {
298         key_hint_revealer->set_reveal_child(false);
299     }
300 }
301 
create()302 MainWindow *MainWindow::create()
303 {
304     MainWindow *w;
305     Glib::RefPtr<Gtk::Builder> x = Gtk::Builder::create();
306     x->add_from_resource("/org/horizon-eda/horizon/imp/window.ui");
307     x->get_widget_derived("mainWindow", w);
308     return w;
309 }
310 } // namespace horizon
311