X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fardour_button.cc;h=98c54e409f2ab9311303e0e5445168679dde483f;hb=d4f91010c37a3ce185bb3c8bcf6453503eccd2b2;hp=922ba84d2c08ae82739395e7af749440c9bcc899;hpb=3921e33c2a6c5ae5d745a8313ad9981b55a5aa5c;p=ardour.git diff --git a/gtk2_ardour/ardour_button.cc b/gtk2_ardour/ardour_button.cc index 922ba84d2c..98c54e409f 100644 --- a/gtk2_ardour/ardour_button.cc +++ b/gtk2_ardour/ardour_button.cc @@ -44,7 +44,6 @@ #define BASELINESTRETCH (1.25) #define TRACKHEADERBTNW (3.10) -using namespace Gdk; using namespace Gtk; using namespace Glib; using namespace PBD; @@ -59,8 +58,11 @@ ArdourButton::Element ArdourButton::just_led_default_elements = ArdourButton::El ArdourButton::ArdourButton (Element e) : _sizing_text("") + , _markup (false) , _elements (e) , _icon (Gtkmm2ext::ArdourIcon::NoIcon) + , _icon_render_cb (0) + , _icon_render_cb_data (0) , _tweaks (Tweaks (0)) , _char_pixel_width (0) , _char_pixel_height (0) @@ -68,7 +70,7 @@ ArdourButton::ArdourButton (Element e) , _text_width (0) , _text_height (0) , _diameter (0) - , _corner_radius (2.5) + , _corner_radius (3.5) , _corner_mask (0xf) , _angle(0) , _xalign(.5) @@ -104,7 +106,9 @@ ArdourButton::ArdourButton (Element e) ArdourButton::ArdourButton (const std::string& str, Element e) : _sizing_text("") + , _markup (false) , _elements (e) + , _icon (Gtkmm2ext::ArdourIcon::NoIcon) , _tweaks (Tweaks (0)) , _char_pixel_width (0) , _char_pixel_height (0) @@ -112,7 +116,7 @@ ArdourButton::ArdourButton (const std::string& str, Element e) , _text_width (0) , _text_height (0) , _diameter (0) - , _corner_radius (2.5) + , _corner_radius (3.5) , _corner_mask (0xf) , _angle(0) , _xalign(.5) @@ -172,22 +176,39 @@ ArdourButton::set_layout_font (const Pango::FontDescription& fd) if (_layout) { _layout->set_font_description (fd); queue_resize (); + _char_pixel_width = 0; + _char_pixel_height = 0; + } +} + +void +ArdourButton::set_text_internal () { + assert (_layout); + if (_markup) { + _layout->set_markup (_text); + } else { + _layout->set_text (_text); } } void -ArdourButton::set_text (const std::string& str) +ArdourButton::set_text (const std::string& str, bool markup) { - if (_text == str) { + if (!(_elements & Text)) { + return; + } + if (_text == str && _markup == markup) { return; } + _text = str; + _markup = markup; if (!is_realized()) { return; } ensure_layout (); if (_layout && _layout->get_text() != _text) { - _layout->set_text (_text); + set_text_internal (); /* on_size_request() will fill in _text_width/height * so queue it even if _sizing_text != "" */ queue_resize (); @@ -234,8 +255,10 @@ ArdourButton::set_alignment (const float xa, const float ya) * ARDOUR_UI_UTILS::render_vector_icon() */ void -ArdourButton::render (cairo_t* cr, cairo_rectangle_t *) +ArdourButton::render (Cairo::RefPtr const& ctx, cairo_rectangle_t*) { + cairo_t* cr = ctx->cobj(); + uint32_t text_color; uint32_t led_color; @@ -348,9 +371,22 @@ ArdourButton::render (cairo_t* cr, cairo_rectangle_t *) gdk_cairo_set_source_pixbuf (cr, _pixbuf->gobj(), x, y); cairo_fill (cr); } - else /* VectorIcons are exclusive to Pixbuf Icons */ - if (_elements & VectorIcon) { - Gtkmm2ext::ArdourIcon::render (cr, _icon, get_width(), get_height(), active_state(), text_color); + else /* VectorIcon, IconRenderCallback are exclusive to Pixbuf Icons */ + if (_elements & (VectorIcon | IconRenderCallback)) { + int vw = get_width(); + int vh = get_height(); + if (_elements & Menu) { + vw -= _diameter + 4; + } + if (_elements & VectorIcon) { + Gtkmm2ext::ArdourIcon::render (cr, _icon, vw, vh, active_state(), text_color); + } else { + cairo_save (cr); + rounded_function (cr, 0, 0, get_width(), get_height(), corner_radius + 1.5); + cairo_clip (cr); + _icon_render_cb (cr, vw, vh, text_color, _icon_render_cb_data); + cairo_restore (cr); + } } const int text_margin = char_pixel_width(); @@ -403,10 +439,19 @@ ArdourButton::render (cairo_t* cr, cairo_rectangle_t *) ww = get_width(); wh = get_height(); - cairo_save (cr); - cairo_rotate(cr, _angle * M_PI / 180.0); + cairo_matrix_t m1; + cairo_get_matrix (cr, &m1); + cairo_matrix_t m2 = m1; + m2.x0 = 0; + m2.y0 = 0; + cairo_set_matrix (cr, &m2); + + if (_angle) { + cairo_rotate(cr, _angle * M_PI / 180.0); + } + cairo_device_to_user(cr, &ww, &wh); - xa = (ww - _text_width) * _xalign; + xa = text_margin + (ww - _text_width - 2 * text_margin) * _xalign; ya = (wh - _text_height) * _yalign; /* quick hack for left/bottom alignment at -90deg @@ -415,10 +460,9 @@ ArdourButton::render (cairo_t* cr, cairo_rectangle_t *) */ if (_xalign < 0) xa = ceil(.5 + (ww * fabs(_xalign) + text_margin)); - cairo_move_to (cr, xa, ya); + cairo_move_to (cr, xa + m1.x0, ya + m1.y0); pango_cairo_update_layout(cr, _layout->gobj()); pango_cairo_show_layout (cr, _layout->gobj()); - cairo_restore (cr); } cairo_restore (cr); } @@ -547,9 +591,9 @@ ArdourButton::on_realize() ensure_layout (); if (_layout) { if (_layout->get_text() != _text) { - _layout->set_text (_text); + set_text_internal (); + queue_resize (); } - queue_resize (); } } @@ -570,7 +614,8 @@ ArdourButton::on_size_request (Gtk::Requisition* req) if (_elements & Text) { ensure_layout(); - _layout->set_text (_text); + set_text_internal (); + /* render() needs the size of the displayed text */ _layout->get_pixel_size (_text_width, _text_height); @@ -580,7 +625,7 @@ ArdourButton::on_size_request (Gtk::Requisition* req) * of text. */ - } else { //if (!_text.empty() || !_sizing_text.empty()) { + } else /*if (!_text.empty() || !_sizing_text.empty()) */ { req->height = std::max(req->height, (int) ceil(char_pixel_height() * BASELINESTRETCH + 1.0)); req->width += rint(1.75 * char_pixel_width()); // padding @@ -595,7 +640,7 @@ ArdourButton::on_size_request (Gtk::Requisition* req) req->width += sizing_text_width; if (!_sizing_text.empty()) { - _layout->set_text (_text); /* restore display text */ + set_text_internal (); /* restore display text */ } } @@ -627,7 +672,7 @@ ArdourButton::on_size_request (Gtk::Requisition* req) req->width += _diameter + 4; } - if (_elements & VectorIcon) { + if (_elements & (VectorIcon | IconRenderCallback)) { assert(!(_elements & Text)); const int wh = std::max (6., std::max (rint (TRACKHEADERBTNW * char_avg_pixel_width()), ceil (char_pixel_height() * BASELINESTRETCH + 1.))); req->width += wh; @@ -649,7 +694,7 @@ ArdourButton::on_size_request (Gtk::Requisition* req) req->width = req->height; if (req->height < req->width) req->height = req->width; - } else if (_sizing_text.empty() && _text_width > 0 && !(_elements & (Menu | Indicator))) { + } else if (_sizing_text.empty() && _text_width > 0 && !(_elements & Menu)) { // properly centered text for those elements that are centered // (no sub-pixel offset) if ((req->width - _text_width) & 1) { ++req->width; } @@ -1016,6 +1061,7 @@ ArdourButton::setup_led_rect () void ArdourButton::set_image (const RefPtr& img) { + _elements = (ArdourButton::Element) (_elements & ~ArdourButton::Text); _pixbuf = img; if (is_realized()) { queue_resize (); @@ -1062,7 +1108,21 @@ ArdourButton::on_focus_out_event (GdkEventFocus* ev) bool ArdourButton::on_key_release_event (GdkEventKey *ev) { - if (_focused && + if (_act_on_release && _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_key_press_event (GdkEventKey *ev) { + if (!_act_on_release && _focused && (ev->keyval == GDK_space || ev->keyval == GDK_Return)) { signal_clicked(); @@ -1189,7 +1249,7 @@ ArdourButton::recalc_char_pixel_geometry () // NB. this is not static, since the geometry is different // depending on the font used. int w, h; - std::string x = _("ABCDEFGHIJLKMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); + std::string x = _("@ABCDEFGHIJLKMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); _layout->set_text (x); _layout->get_pixel_size (w, h); _char_pixel_height = std::max(4, h); @@ -1198,7 +1258,7 @@ ArdourButton::recalc_char_pixel_geometry () 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); + set_text_internal (); /* restore display text */ } void @@ -1236,7 +1296,24 @@ void ArdourButton::set_icon (Gtkmm2ext::ArdourIcon::Icon i) { _icon = i; - _elements = (ArdourButton::Element) ((_elements | ArdourButton::VectorIcon) & ~ArdourButton::Text); + _icon_render_cb = 0; + _icon_render_cb_data = 0; + _elements = (ArdourButton::Element) ((_elements | VectorIcon) & ~(ArdourButton::Text | IconRenderCallback)); + CairoWidget::set_dirty (); +} + +void +ArdourButton::set_icon (rendercallback_t cb, void* d) +{ + if (!cb) { + _elements = (ArdourButton::Element) ((_elements | ArdourButton::Text) & ~(IconRenderCallback | VectorIcon)); + _icon_render_cb = 0; + _icon_render_cb_data = 0; + } else { + _elements = (ArdourButton::Element) ((_elements | IconRenderCallback) & ~(ArdourButton::Text | VectorIcon)); + _icon_render_cb = cb; + _icon_render_cb_data = d; + } CairoWidget::set_dirty (); }