ArdourButton: prepare for [em] based padding
authorRobin Gareus <robin@gareus.org>
Tue, 2 Sep 2014 17:23:18 +0000 (19:23 +0200)
committerRobin Gareus <robin@gareus.org>
Tue, 2 Sep 2014 17:23:18 +0000 (19:23 +0200)
gtk2_ardour/ardour_button.cc
gtk2_ardour/ardour_button.h

index f45c1855b70cf25a42bf2437da26add076cba4c7..6208deda2a33c0649ae433f79b0ec95f065611ee 100644 (file)
@@ -58,6 +58,8 @@ ArdourButton::Element ArdourButton::just_led_default_elements = ArdourButton::El
 ArdourButton::ArdourButton (Element e)
        : _elements (e)
        , _tweaks (Tweaks (0))
+       , _char_pixel_width (0)
+       , _char_pixel_height (0)
        , _text_width (0)
        , _text_height (0)
        , _diameter (11.0)
@@ -494,12 +496,7 @@ ArdourButton::on_size_request (Gtk::Requisition* req)
                //calc our real width for our string (but ignore the height, because that results in inconsistent button heights)
                int ignored;
                _layout->get_pixel_size (_text_width, ignored);
-
-               //calc the height using some text with both ascenders and descenders
-               std::string t = _layout->get_text();
-               _layout->set_text ("WjgO");  //what we put here probably doesn't matter, as long as its the same for everyone
-               _layout->get_pixel_size (ignored, _text_height);
-               _layout->set_text (t);
+               _text_height = char_pixel_height ();
 
                if (_text_width + _diameter < 75) {
                        xpad = 7;
@@ -803,13 +800,14 @@ ArdourButton::action_toggled ()
 void
 ArdourButton::on_style_changed (const RefPtr<Gtk::Style>&)
 {
-       set_colors ();
-       build_patterns ();
+       on_name_changed();
 }
 
 void
 ArdourButton::on_name_changed ()
 {
+       _char_pixel_width = 0;
+       _char_pixel_height = 0;
        set_colors ();
        build_patterns ();
 }
@@ -953,6 +951,29 @@ ArdourButton::action_sensitivity_changed ()
        
 }
 
+void
+ArdourButton::recalc_char_pixel_geometry ()
+{
+       if (_char_pixel_height > 0 && _char_pixel_width > 0) {
+               return;
+       }
+       if (!_layout) {
+               _layout = Pango::Layout::create (get_pango_context());
+       }
+       // NB. this is not static, since the geometry is different
+       // depending on the font used.
+       int w, h;
+       std::string t = _layout->get_text();
+       std::string x = _("ABCDEFGHIJLKMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
+       _layout->set_text (x);
+       _layout->get_pixel_size (w, h);
+       _layout->set_text (t);
+       _char_pixel_height = std::max(4, h);
+       // number of actual chars in the string (not bytes)
+       // Glib to the rescue.
+       Glib::ustring gx(x);
+       _char_pixel_width = std::max(4, w / (int)gx.size());
+}
 
 void
 ArdourButton::action_visibility_changed ()
index 75e3a9cd90f50717230e5971a78a979edd3b1834..0c61a6f101bcc429b3951a9c9bcab95b34d8d6b5 100644 (file)
@@ -101,6 +101,9 @@ class ArdourButton : public CairoWidget , public Gtkmm2ext::Activatable
 
        void set_fallthrough_to_parent(bool fall) { _fallthrough_to_parent = fall; }
 
+       unsigned int char_pixel_width() { if (_char_pixel_width < 1) recalc_char_pixel_geometry() ; return _char_pixel_width; }
+       unsigned int char_pixel_height() { if (_char_pixel_height < 1) recalc_char_pixel_geometry() ; return _char_pixel_height; }
+
   protected:
        void render (cairo_t *, cairo_rectangle_t *);
        void on_size_request (Gtk::Requisition* req);
@@ -124,6 +127,10 @@ class ArdourButton : public CairoWidget , public Gtkmm2ext::Activatable
        Tweaks                      _tweaks;
        BindingProxy                binding_proxy;
 
+       void recalc_char_pixel_geometry ();
+       unsigned int _char_pixel_width;
+       unsigned int _char_pixel_height;
+
        int   _text_width;
        int   _text_height;
        float _diameter;