merge with master.
[ardour.git] / gtk2_ardour / big_clock_window.cc
1 /*
2     Copyright (C) 20002-2013 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <algorithm>
21 #include <string>
22 #include <vector>
23
24 #include "ardour_ui.h"
25 #include "audio_clock.h"
26 #include "big_clock_window.h"
27 #include "public_editor.h"
28 #include "utils.h"
29
30 #include "i18n.h"
31
32 using std::min;
33 using std::string;
34 using namespace ARDOUR_UI_UTILS;
35
36 BigClockWindow::BigClockWindow (AudioClock& c) 
37         : ArdourWindow (_("Big Clock"))
38         , clock (c)
39         , resize_in_progress (false)
40         , original_height (0)
41         , original_width (0)
42         , original_font_size (0)
43 {
44         ARDOUR_UI::Clock.connect (sigc::mem_fun (clock, &AudioClock::set));
45
46         clock.set_corner_radius (0.0);
47         clock.mode_changed.connect (sigc::mem_fun (*this, &BigClockWindow::reset_aspect_ratio));
48
49         set_keep_above (true);
50         set_border_width (0);
51         add (clock);
52         clock.show_all ();
53 }
54
55 void
56 BigClockWindow::on_unmap ()
57 {
58         ArdourWindow::on_unmap ();
59
60         PublicEditor::instance().reset_focus ();
61 }
62
63 bool
64 BigClockWindow::on_key_press_event (GdkEventKey* ev)
65 {
66         return relay_key_press (ev, this);
67 }
68
69 void
70 BigClockWindow::on_realize ()
71 {
72         int x, y, w, d, h;
73
74         ArdourWindow::on_realize ();
75
76         get_window()->set_decorations (Gdk::DECOR_BORDER|Gdk::DECOR_RESIZEH);
77         get_window()->get_geometry (x, y, w, h, d);
78
79         reset_aspect_ratio ();
80
81         original_height = h;
82         original_width = w;
83
84         Pango::FontDescription fd (clock.get_style()->get_font());
85         original_font_size = fd.get_size ();
86
87         if (!fd.get_size_is_absolute ()) {
88                 original_font_size /= PANGO_SCALE;
89         }
90 }
91
92 void
93 BigClockWindow::on_size_allocate (Gtk::Allocation& alloc)
94 {
95         ArdourWindow::on_size_allocate (alloc);
96
97         if (!resize_in_progress) {
98                 Glib::signal_idle().connect (sigc::bind (sigc::mem_fun (*this, &BigClockWindow::text_resizer), 0, 0));
99                 resize_in_progress = true;
100         }
101 }
102
103 void
104 BigClockWindow::reset_aspect_ratio ()
105 {
106         Gtk::Requisition req;
107
108         clock.size_request (req);
109
110         float aspect = req.width/(float)req.height;
111         Gdk::Geometry geom;
112
113         geom.min_aspect = aspect;
114         geom.max_aspect = aspect;
115         
116         set_geometry_hints (clock, geom, Gdk::HINT_ASPECT);
117 }
118
119 bool
120 BigClockWindow::text_resizer (int, int)
121 {
122         resize_in_progress = false;
123
124         Glib::RefPtr<Gdk::Window> win = get_window();
125         Pango::FontDescription fd (clock.get_style()->get_font());
126         int current_size = fd.get_size ();
127         int x, y, w, h, d;
128
129         if (!fd.get_size_is_absolute ()) {
130                 current_size /= PANGO_SCALE;
131         }
132
133         win->get_geometry (x, y, w, h, d);
134
135         double scale  = min (((double) w / (double) original_width),
136                              ((double) h / (double) original_height));
137
138         int size = (int) lrintf (original_font_size * scale);
139
140         if (size != current_size) {
141
142                 string family = fd.get_family();
143                 std::vector<char> buf(family.length()+16);
144                 snprintf (&buf[0], family.length()+16, "%s %d", family.c_str(), size);
145
146                 try {
147                         Pango::FontDescription fd (&buf[0]);
148                         Glib::RefPtr<Gtk::RcStyle> rcstyle = clock.get_modifier_style ();
149                         rcstyle->set_font (fd);
150                         clock.modify_style (rcstyle);
151                 }
152
153                 catch (...) {
154                         /* oh well, do nothing */
155                 }
156         }
157
158         return false;
159 }
160