+}
+
+void
+ArdourButton::on_style_changed (const RefPtr<Gtk::Style>&)
+{
+ _update_colors = true;
+ CairoWidget::set_dirty ();
+}
+
+void
+ArdourButton::on_name_changed ()
+{
+ _char_pixel_width = 0;
+ _char_pixel_height = 0;
+ _diameter = 0;
+ _update_colors = true;
+ if (is_realized()) {
+ queue_resize ();
+ }
+}
+
+void
+ArdourButton::setup_led_rect ()
+{
+ if (!(_elements & Indicator)) {
+ delete _led_rect;
+ _led_rect = 0;
+ return;
+ }
+
+ if (!_led_rect) {
+ _led_rect = new cairo_rectangle_t;
+ }
+
+ if (_elements & Text) {
+ if (_led_left) {
+ _led_rect->x = char_pixel_width();
+ } else {
+ _led_rect->x = get_width() - char_pixel_width() + _diameter;
+ }
+ } else {
+ /* centered */
+ _led_rect->x = .5 * get_width() - _diameter;
+ }
+
+ _led_rect->y = .5 * (get_height() - _diameter);
+ _led_rect->width = _diameter;
+ _led_rect->height = _diameter;
+}
+
+void
+ArdourButton::set_image (const RefPtr<Gdk::Pixbuf>& img)
+{
+ _pixbuf = img;
+ if (is_realized()) {
+ queue_resize ();
+ }
+}
+
+void
+ArdourButton::set_active_state (Gtkmm2ext::ActiveState s)
+{
+ bool changed = (_active_state != s);
+ CairoWidget::set_active_state (s);
+ if (changed) {
+ _update_colors = true;
+ CairoWidget::set_dirty ();
+ }
+}
+
+void
+ArdourButton::set_visual_state (Gtkmm2ext::VisualState s)
+{
+ bool changed = (_visual_state != s);
+ CairoWidget::set_visual_state (s);
+ if (changed) {
+ _update_colors = true;
+ CairoWidget::set_dirty ();
+ }
+}
+
+bool
+ArdourButton::on_focus_in_event (GdkEventFocus* ev)
+{
+ _focused = true;
+ CairoWidget::set_dirty ();
+ return CairoWidget::on_focus_in_event (ev);
+}
+
+bool
+ArdourButton::on_focus_out_event (GdkEventFocus* ev)
+{
+ _focused = false;
+ CairoWidget::set_dirty ();
+ return CairoWidget::on_focus_out_event (ev);
+}
+
+bool
+ArdourButton::on_key_release_event (GdkEventKey *ev) {
+ if (_focused &&
+ (ev->keyval == GDK_space || ev->keyval == GDK_Return))
+ {
+ signal_clicked();
+ if (_action) {
+ _action->activate ();
+ }
+ return true;
+ }
+ return CairoWidget::on_key_release_event (ev);
+}
+
+bool
+ArdourButton::on_enter_notify_event (GdkEventCrossing* ev)
+{
+ _hovering = (_elements & Inactive) ? false : true;
+
+ if (ARDOUR::Config->get_widget_prelight()) {
+ CairoWidget::set_dirty ();
+ }
+
+ return CairoWidget::on_enter_notify_event (ev);
+}
+
+bool
+ArdourButton::on_leave_notify_event (GdkEventCrossing* ev)
+{
+ _hovering = false;
+
+ if (ARDOUR::Config->get_widget_prelight()) {
+ CairoWidget::set_dirty ();
+ }
+
+ return CairoWidget::on_leave_notify_event (ev);
+}
+
+void
+ArdourButton::set_tweaks (Tweaks t)
+{
+ if (_tweaks != t) {
+ _tweaks = t;
+ if (is_realized()) {
+ queue_resize ();
+ }
+ }
+}
+
+void
+ArdourButton::action_sensitivity_changed ()
+{
+ if (_action->property_sensitive ()) {
+ set_visual_state (Gtkmm2ext::VisualState (visual_state() & ~Gtkmm2ext::Insensitive));
+ } else {
+ set_visual_state (Gtkmm2ext::VisualState (visual_state() | Gtkmm2ext::Insensitive));
+ }
+}
+
+void
+ArdourButton::set_layout_ellisize_width (int w)
+{
+ if (_layout_ellipsize_width == w) {
+ return;
+ }
+ _layout_ellipsize_width = w;
+ if (!_layout) {
+ return;
+ }
+ if (_layout_ellipsize_width > 0) {
+ _layout->set_width (_layout_ellipsize_width);
+ }
+}
+
+void
+ArdourButton::set_text_ellipsize (Pango::EllipsizeMode e)
+{
+ if (_ellipsis == e) {
+ return;
+ }
+ _ellipsis = e;
+ if (!_layout) {
+ return;
+ }
+ _layout->set_ellipsize(_ellipsis);
+ if (_layout_ellipsize_width > 0) {
+ _layout->set_width (_layout_ellipsize_width);
+ }
+ if (is_realized ()) {
+ queue_resize ();
+ }
+}
+
+void
+ArdourButton::ensure_layout ()
+{
+ if (!_layout) {
+ ensure_style ();
+ _layout = Pango::Layout::create (get_pango_context());
+ _layout->set_ellipsize(_ellipsis);
+ if (_layout_ellipsize_width > 0) {
+ _layout->set_width (_layout_ellipsize_width);
+ }
+ }
+}
+
+void
+ArdourButton::recalc_char_pixel_geometry ()
+{
+ if (_char_pixel_height > 0 && _char_pixel_width > 0) {
+ return;
+ }
+ ensure_layout();
+ // NB. this is not static, since the geometry is different
+ // depending on the font used.
+ int w, h;
+ std::string x = _("ABCDEFGHIJLKMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
+ _layout->set_text (x);
+ _layout->get_pixel_size (w, h);
+ _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_avg_pixel_width = w / (float)gx.size();
+ _char_pixel_width = std::max(4, (int) ceil (_char_avg_pixel_width));
+ _layout->set_text (_text);
+}
+
+void
+ArdourButton::action_visibility_changed ()
+{
+ if (_action->property_visible ()) {
+ show ();
+ } else {
+ hide ();
+ }
+}
+
+void
+ArdourButton::action_tooltip_changed ()
+{
+ string str = _action->property_tooltip().get_value();
+ ARDOUR_UI::instance()->set_tip (*this, str);
+}
+
+void
+ArdourButton::set_elements (Element e)
+{
+ _elements = e;
+ CairoWidget::set_dirty ();
+}
+
+void
+ArdourButton::add_elements (Element e)
+{
+ _elements = (ArdourButton::Element) (_elements | e);
+ CairoWidget::set_dirty ();
+}