dynamically resize text in the big clock, first version
authorPaul Davis <paul@linuxaudiosystems.com>
Fri, 15 Jan 2010 14:42:19 +0000 (14:42 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Fri, 15 Jan 2010 14:42:19 +0000 (14:42 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@6494 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/ardour_ui.cc
gtk2_ardour/ardour_ui.h
gtk2_ardour/ardour_ui_ed.cc
gtk2_ardour/audio_clock.cc
gtk2_ardour/audio_clock.h
libs/gtkmm2ext/utils.cc

index 8ab4cf65777fcd50d8baf86294b38d56aa050041..3bbd748277d767388d8995f585338b53c441c0a5 100644 (file)
@@ -197,6 +197,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
        engine = 0;
        _session_is_new = false;
        big_clock_window = 0;
+       big_clock_height = 0;
+       big_clock_resize_in_progress = false;
        session_selector_window = 0;
        last_key_press_time = 0;
        _will_create_new_session_automatically = false;
index 9cf245fbeb991dee1fee987a87b7becb5991bc63..bb8db0ef5a54a900a705be1936aba80ba829ca6e 100644 (file)
@@ -313,6 +313,11 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
 
        AudioClock   big_clock;
        Gtk::Window* big_clock_window;
+       void big_clock_size_allocate (Gtk::Allocation&);
+       bool idle_big_clock_text_resizer (int width, int height);
+       void big_clock_realized ();
+       bool big_clock_resize_in_progress;
+       int  big_clock_height;
 
        void float_big_clock (Gtk::Window* parent);
        bool main_window_state_event_handler (GdkEventWindowState*, bool window_was_editor);
index 6a8f68cf6f8761261204700913f7e8d75d4d8f40..d9a6958e70dabcc671e37d008e3770e1015f4187 100644 (file)
@@ -536,13 +536,22 @@ ARDOUR_UI::setup_clock ()
 
        big_clock_window->set_title (_("Big Clock"));
        big_clock_window->set_type_hint (Gdk::WINDOW_TYPE_HINT_UTILITY);
-       big_clock_window->signal_realize().connect (sigc::bind (sigc::ptr_fun (set_decoration), big_clock_window,  (Gdk::DECOR_BORDER|Gdk::DECOR_RESIZEH)));
+       big_clock_window->signal_realize().connect (sigc::mem_fun (*this, &ARDOUR_UI::big_clock_realized));
        big_clock_window->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleBigClock")));
        big_clock_window->signal_key_press_event().connect (sigc::bind (sigc::ptr_fun (relay_key_press), big_clock_window), false);
+       big_clock_window->signal_size_allocate().connect (sigc::mem_fun (*this, &ARDOUR_UI::big_clock_size_allocate));
 
        manage_window (*big_clock_window);
 }
 
+void
+ARDOUR_UI::big_clock_realized ()
+{
+       set_decoration (big_clock_window, (Gdk::DECOR_BORDER|Gdk::DECOR_RESIZEH));
+       int x, y, w, d;
+       big_clock_window->get_window()->get_geometry (x, y, w, big_clock_height, d);
+}
+
 void
 ARDOUR_UI::float_big_clock (Gtk::Window* parent)
 {
@@ -555,3 +564,111 @@ ARDOUR_UI::float_big_clock (Gtk::Window* parent)
        }
 }
 
+void
+ARDOUR_UI::big_clock_size_allocate (Gtk::Allocation& allocation)
+{
+       if (!big_clock_resize_in_progress) {
+               Glib::signal_idle().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::idle_big_clock_text_resizer), 0, 0));
+               big_clock_resize_in_progress = true;
+       }
+
+       big_clock_window->set_size_request (allocation.get_width() - 2, allocation.get_height() - 1);
+}
+
+bool
+ARDOUR_UI::idle_big_clock_text_resizer (int win_w, int win_h)
+{
+       extern void get_pixel_size (Glib::RefPtr<Pango::Layout> layout, int& width, int& height);
+       Glib::RefPtr<Gdk::Window> win = big_clock_window->get_window();
+       assert (win);
+
+       big_clock_resize_in_progress = false;
+
+       Pango::FontDescription fd (big_clock.get_style()->get_font());
+       string family = fd.get_family();
+       int size = fd.get_size ();
+       int original_size;
+       bool absolute = fd.get_size_is_absolute ();
+       int stepsize;
+
+       if (!absolute) {
+               size /= PANGO_SCALE;
+       }
+
+       original_size = size;
+
+       int x, y, winw, winh, d;
+       int w, h;
+       int slop;
+       int limit;
+
+       win->get_geometry (x, y, winw, winh, d);
+
+       Glib::RefPtr<Pango::Layout> layout = big_clock.create_pango_layout ("0");
+       get_pixel_size (layout, w, h);
+
+       /* we want about 10% of the font height as padding, and we'll allow 10% of slop
+          in the accuracy of the fit.
+       */
+
+       slop = 10;
+       limit = winh - (h/4);
+
+       if (h < limit && limit - h < slop) {
+               /* current font is smaller than the window height but not by too much */
+               return false;
+       }
+
+       stepsize = 16;
+       if (h > limit) {
+               /* font is too big, lets get smaller */
+               size -= stepsize;
+       } else {
+               /* font is too big, lets get bigger */
+               size += stepsize;
+       }
+
+       while (1) {
+               
+               char buf[family.length()+16];
+               snprintf (buf, family.length()+16, "%s %d", family.c_str(), size);
+               Pango::FontDescription fd (buf);
+               layout->set_font_description (fd);
+               get_pixel_size (layout, w, h);
+
+               if (abs (h - limit) < slop) {
+                       if (size != original_size) {
+                               
+                               /* use the size from the last loop */
+                               
+                               Glib::RefPtr<Gtk::RcStyle> rcstyle = big_clock.get_modifier_style ();
+                               rcstyle->set_font (fd);
+                               big_clock.modify_style (rcstyle);
+                       }
+                       break;
+               }
+               
+               if (h > limit) {
+                       
+                       /* too big, stepsize should be smaller */
+
+                       if (size < 2) {
+                               break;
+                       }
+                       size -= stepsize;
+
+               } else if (h < limit) {
+
+                       /* too small (but not small enough): step size should be bigger */
+                       
+                       if (size > 720) {
+                               break;
+                       }
+                       size += stepsize;
+               }
+
+               stepsize /= 2;
+       }
+
+       return false;
+}
index 86497709c633abc1c636a50291a9056158c72525..bdf0ceda33fafa4f948ca0045a39371761b85460 100644 (file)
@@ -2044,30 +2044,30 @@ AudioClock::set_mode (Mode m)
 void
 AudioClock::set_size_requests ()
 {
-       /* note that in some fonts, "88" is narrower than "00", hence the 2 pixel padding */
+       /* note that in some fonts, "88" is narrower than "00" */
 
        switch (_mode) {
        case Timecode:
-               Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-00", 5, 5);
-               Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "00", 5, 5);
-               Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "00", 5, 5);
-               Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "00", 5, 5);
+               Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-88", 5, 5);
+               Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "88", 5, 5);
+               Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "88", 5, 5);
+               Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "88", 5, 5);
                break;
 
        case BBT:
-               Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-000", 5, 5);
-               Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "00", 5, 5);
-               Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "0000", 5, 5);
+               Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-888", 5, 5);
+               Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "88", 5, 5);
+               Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "8888", 5, 5);
                break;
 
        case MinSec:
-               Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "00", 5, 5);
-               Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "00", 5, 5);
-               Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "00.000", 5, 5);
+               Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "88", 5, 5);
+               Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "88", 5, 5);
+               Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "88.888", 5, 5);
                break;
 
        case Frames:
-               Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "0000000000", 5, 5);
+               Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "8888888888", 5, 5);
                break;
 
        case Off:
@@ -2082,3 +2082,47 @@ AudioClock::set_bbt_reference (nframes64_t pos)
 {
        bbt_reference_time = pos;
 }
+
+void
+AudioClock::on_style_changed (const Glib::RefPtr<Style>& old_style)
+{
+       HBox::on_style_changed (old_style);
+
+       /* propagate style changes to all component widgets that should inherit the main one */
+
+       Glib::RefPtr<RcStyle> rcstyle = get_modifier_style();
+
+       clock_base.modify_style (rcstyle);
+       audio_frames_label.modify_style (rcstyle);
+       hours_label.modify_style (rcstyle);
+       minutes_label.modify_style (rcstyle);
+       seconds_label.modify_style (rcstyle);
+       frames_label.modify_style (rcstyle);
+       bars_label.modify_style (rcstyle);
+       beats_label.modify_style (rcstyle);
+       ticks_label.modify_style (rcstyle);
+       ms_hours_label.modify_style (rcstyle);
+       ms_minutes_label.modify_style (rcstyle);
+       ms_seconds_label.modify_style (rcstyle);
+       hours_ebox.modify_style (rcstyle);
+       minutes_ebox.modify_style (rcstyle);
+       seconds_ebox.modify_style (rcstyle);
+       frames_ebox.modify_style (rcstyle);
+       audio_frames_ebox.modify_style (rcstyle);
+       bars_ebox.modify_style (rcstyle);
+       beats_ebox.modify_style (rcstyle);
+       ticks_ebox.modify_style (rcstyle);
+       ms_hours_ebox.modify_style (rcstyle);
+       ms_minutes_ebox.modify_style (rcstyle);
+       ms_seconds_ebox.modify_style (rcstyle);
+
+       colon1.modify_style (rcstyle);
+       colon2.modify_style (rcstyle);
+       colon3.modify_style (rcstyle);
+       colon4.modify_style (rcstyle);
+       colon5.modify_style (rcstyle);
+       b1.modify_style (rcstyle);
+       b2.modify_style (rcstyle);
+
+       set_size_requests ();
+}
index 1a15cecd7b15d24811193acada6f2698db5c5be8..b9fc740543ef04427a9f6a159410d022db8f764c 100644 (file)
@@ -216,6 +216,7 @@ class AudioClock : public Gtk::HBox, public ARDOUR::SessionHandlePtr
        static const uint32_t field_length[(int)AudioFrames+1];
        static bool _has_focus;
 
+       void on_style_changed (const Glib::RefPtr<Gtk::Style>&);
 };
 
 #endif /* __audio_clock_h__ */
index 400899cb674044171c39489a35d1d2f27b4a28e6..d558ce809955db8cc50e863a83787e389dcd71c5 100644 (file)
@@ -45,6 +45,14 @@ Gtkmm2ext::get_ink_pixel_size (Glib::RefPtr<Pango::Layout> layout,
        height = (ink_rect.get_height() + PANGO_SCALE / 2) / PANGO_SCALE;
 }
 
+void
+get_pixel_size (Glib::RefPtr<Pango::Layout> layout,
+                              int& width,
+                              int& height)
+{
+       layout->get_pixel_size (width, height);
+}
+
 void
 Gtkmm2ext::set_size_request_to_display_given_text (Gtk::Widget &w, const gchar *text,
                                                   gint hpadding, gint vpadding)
@@ -53,7 +61,7 @@ Gtkmm2ext::set_size_request_to_display_given_text (Gtk::Widget &w, const gchar *
        int width, height;
        w.ensure_style ();
        
-       get_ink_pixel_size (w.create_pango_layout (text), width, height);
+       get_pixel_size (w.create_pango_layout (text), width, height);
        w.set_size_request(width + hpadding, height + vpadding);
 }
 
@@ -69,7 +77,7 @@ Gtkmm2ext::set_size_request_to_display_given_text (Gtk::Widget &w,
        w.ensure_style ();
        
        for (vector<string>::const_iterator i = strings.begin(); i != strings.end(); ++i) {
-               get_ink_pixel_size (w.create_pango_layout (*i), width, height);
+               get_pixel_size (w.create_pango_layout (*i), width, height);
                width_max = max(width_max,width);
                height_max = max(height_max, height);
        }