X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fardour_button.cc;h=a4f346a040ad2dd63ce23399931fbb4357bfe094;hb=ca6ee56347ede03d87c1b3bdbdec52458fd25662;hp=f2c107d859134b8ae09a8b2fc3af70817793a996;hpb=dfecb069466876d03cf8583e331dc4ba2ee3a59d;p=ardour.git diff --git a/gtk2_ardour/ardour_button.cc b/gtk2_ardour/ardour_button.cc index f2c107d859..a4f346a040 100644 --- a/gtk2_ardour/ardour_button.cc +++ b/gtk2_ardour/ardour_button.cc @@ -24,6 +24,7 @@ #include #include "pbd/compose.h" +#include "pbd/controllable.h" #include "pbd/error.h" #include "pbd/stacktrace.h" @@ -31,22 +32,23 @@ #include "gtkmm2ext/rgb_macros.h" #include "gtkmm2ext/gui_thread.h" -#include "ardour/rc_configuration.h" // for widget prelight preference - #include "canvas/utils.h" +#include "canvas/colors.h" #include "ardour_button.h" -#include "ardour_ui.h" -#include "global_signals.h" +#include "tooltips.h" +#include "ui_config.h" #include "i18n.h" #define BASELINESTRETCH (1.25) +#define TRACKHEADERBTNW (3.10) using namespace Gdk; using namespace Gtk; using namespace Glib; using namespace PBD; +using namespace ARDOUR_UI_UTILS; using std::max; using std::min; using namespace std; @@ -57,9 +59,11 @@ ArdourButton::Element ArdourButton::just_led_default_elements = ArdourButton::El ArdourButton::ArdourButton (Element e) : _elements (e) + , _icon (Gtkmm2ext::ArdourIcon::NoIcon) , _tweaks (Tweaks (0)) , _char_pixel_width (0) , _char_pixel_height (0) + , _char_avg_pixel_width (0) , _text_width (0) , _text_height (0) , _diameter (0) @@ -74,6 +78,8 @@ ArdourButton::ArdourButton (Element e) , text_inactive_color(0) , led_active_color(0) , led_inactive_color(0) + , led_custom_color (0) + , use_custom_led_color (false) , convex_pattern (0) , concave_pattern (0) , led_inset_pattern (0) @@ -90,7 +96,7 @@ ArdourButton::ArdourButton (Element e) , _update_colors (true) , _pattern_height (0) { - ARDOUR_UI_UTILS::ColorsChanged.connect (sigc::mem_fun (*this, &ArdourButton::color_handler)); + UIConfiguration::instance().ColorsChanged.connect (sigc::mem_fun (*this, &ArdourButton::color_handler)); } ArdourButton::ArdourButton (const std::string& str, Element e) @@ -110,6 +116,8 @@ ArdourButton::ArdourButton (const std::string& str, Element e) , text_inactive_color(0) , led_active_color(0) , led_inactive_color(0) + , led_custom_color (0) + , use_custom_led_color (false) , convex_pattern (0) , concave_pattern (0) , led_inset_pattern (0) @@ -120,8 +128,15 @@ ArdourButton::ArdourButton (const std::string& str, Element e) , _hovering (false) , _focused (false) , _fixed_colors_set (false) + , _fallthrough_to_parent (false) + , _layout_ellipsize_width (-1) + , _ellipsis (Pango::ELLIPSIZE_NONE) + , _update_colors (true) + , _pattern_height (0) { set_text (str); + UIConfiguration::instance().ColorsChanged.connect (sigc::mem_fun (*this, &ArdourButton::color_handler)); + UIConfiguration::instance().DPIReset.connect (sigc::mem_fun (*this, &ArdourButton::on_name_changed)); } ArdourButton::~ArdourButton() @@ -141,6 +156,16 @@ ArdourButton::~ArdourButton() } } +void +ArdourButton::set_layout_font (const Pango::FontDescription& fd) +{ + ensure_layout (); + if (_layout) { + _layout->set_font_description (fd); + queue_resize (); + } +} + void ArdourButton::set_text (const std::string& str) { @@ -168,12 +193,24 @@ ArdourButton::set_alignment (const float xa, const float ya) _yalign = ya; } + +/* TODO make this a dedicated function elsewhere. + * + * Option 1: + * virtual ArdourButton::render_vector_icon() + * ArdourIconButton::render_vector_icon + * + * Option 2: + * ARDOUR_UI_UTILS::render_vector_icon() + */ void ArdourButton::render (cairo_t* cr, cairo_rectangle_t *) { uint32_t text_color; uint32_t led_color; + const float corner_radius = std::max(2.f, _corner_radius * UIConfiguration::instance().get_ui_scale()); + if (_update_colors) { set_colors (); } @@ -189,6 +226,10 @@ ArdourButton::render (cairo_t* cr, cairo_rectangle_t *) led_color = led_inactive_color; } + if (use_custom_led_color) { + led_color = led_custom_color; + } + void (*rounded_function)(cairo_t*, double, double, double, double, double); switch (_corner_mask) { @@ -210,14 +251,14 @@ ArdourButton::render (cairo_t* cr, cairo_rectangle_t *) // draw edge (filling a rect underneath, rather than stroking a border on top, allows the corners to be lighter-weight. if ((_elements & (Body|Edge)) == (Body|Edge)) { - rounded_function (cr, 0, 0, get_width(), get_height(), _corner_radius + 1.5); + rounded_function (cr, 0, 0, get_width(), get_height(), corner_radius + 1.5); cairo_set_source_rgba (cr, 0, 0, 0, 1); cairo_fill(cr); } // background fill if ((_elements & Body)==Body) { - rounded_function (cr, 1, 1, get_width() - 2, get_height() - 2, _corner_radius); + rounded_function (cr, 1, 1, get_width() - 2, get_height() - 2, corner_radius); if (active_state() == Gtkmm2ext::ImplicitActive && !((_elements & Indicator)==Indicator)) { ArdourCanvas::set_source_rgba (cr, fill_inactive_color); cairo_fill (cr); @@ -236,7 +277,7 @@ ArdourButton::render (cairo_t* cr, cairo_rectangle_t *) if ((_elements & Body)==Body) { if (active_state() == Gtkmm2ext::ImplicitActive && !((_elements & Indicator)==Indicator)) { cairo_set_line_width (cr, 2.0); - rounded_function (cr, 2, 2, get_width() - 4, get_height() - 4, _corner_radius-0.5); + rounded_function (cr, 2, 2, get_width() - 4, get_height() - 4, corner_radius-0.5); ArdourCanvas::set_source_rgba (cr, fill_active_color); cairo_stroke (cr); } @@ -244,14 +285,14 @@ ArdourButton::render (cairo_t* cr, cairo_rectangle_t *) //show the "convex" or "concave" gradient if (!_flat_buttons) { - if ( active_state() == Gtkmm2ext::ExplicitActive && !((_elements & Indicator)==Indicator) ) { + if ( active_state() == Gtkmm2ext::ExplicitActive && ( !((_elements & Indicator)==Indicator) || use_custom_led_color) ) { //concave cairo_set_source (cr, concave_pattern); - Gtkmm2ext::rounded_rectangle (cr, 1, 1, get_width() - 2, get_height() - 2, _corner_radius); + Gtkmm2ext::rounded_rectangle (cr, 1, 1, get_width() - 2, get_height() - 2, corner_radius); cairo_fill (cr); } else { cairo_set_source (cr, convex_pattern); - Gtkmm2ext::rounded_rectangle (cr, 1, 1, get_width() - 2, get_height() - 2, _corner_radius); + Gtkmm2ext::rounded_rectangle (cr, 1, 1, get_width() - 2, get_height() - 2, corner_radius); cairo_fill (cr); } } @@ -260,7 +301,14 @@ ArdourButton::render (cairo_t* cr, cairo_rectangle_t *) if (_pixbuf) { double x = rint((get_width() - _pixbuf->get_width()) * .5); const double y = rint((get_height() - _pixbuf->get_height()) * .5); - +#if 0 // DEBUG style (print on hover) + if (_hovering || (_elements & Inactive)) { + printf("%s: p:%dx%d (%dx%d)\n", + get_name().c_str(), + _pixbuf->get_width(), _pixbuf->get_height(), + get_width(), get_height()); + } +#endif if (_elements & Menu) { //if this is a DropDown with an icon, then we need to //move the icon left slightly to accomomodate the arrow @@ -270,109 +318,28 @@ ArdourButton::render (cairo_t* cr, cairo_rectangle_t *) gdk_cairo_set_source_pixbuf (cr, _pixbuf->gobj(), x, y); cairo_fill (cr); } - else // rec-en is exclusive to pixbuf (tape machine mode, rec-en) - if ((_elements & (RecButton|RecTapeMode)) == (RecButton|RecTapeMode)) { - const double x = get_width() * .5; - const double y = get_height() * .5; - const double r = std::min(10., std::min(x, y) * .6); // TODO we need a better way to limit max. radius. - const double slit = .11 * M_PI; - cairo_save(cr); - cairo_translate(cr, x, y); - - cairo_arc (cr, 0, 0, r, 0, 2 * M_PI); - if (active_state() == Gtkmm2ext::ExplicitActive) - cairo_set_source_rgba (cr, .95, .1, .1, 1.); - else - cairo_set_source_rgba (cr, .95, .44, .44, 1.); // #f46f6f - cairo_fill_preserve(cr); - cairo_set_source_rgba (cr, .0, .0, .0, .5); - cairo_set_line_width(cr, 1); - cairo_stroke(cr); - - cairo_save(cr); - cairo_set_source_rgba (cr, .15, .07, .07, 1.0); - - cairo_rotate (cr, -.5 * M_PI); - cairo_move_to(cr, 0, 0); - cairo_arc (cr, 0, 0, r *.85, -slit, slit); - cairo_line_to(cr, 0, 0); - cairo_close_path(cr); - - cairo_fill(cr); - cairo_rotate (cr, 2. * M_PI / 3.); - - cairo_move_to(cr, 0, 0); - cairo_arc (cr, 0, 0, r *.85, -slit, slit); - cairo_line_to(cr, 0, 0); - cairo_close_path(cr); - cairo_fill(cr); - - cairo_rotate (cr, 2. * M_PI / 3.); - cairo_move_to(cr, 0, 0); - cairo_arc (cr, 0, 0, r *.85, -slit, slit); - cairo_line_to(cr, 0, 0); - cairo_close_path(cr); - cairo_fill(cr); - - cairo_restore(cr); - - cairo_arc (cr, 0, 0, r * .3, 0, 2 * M_PI); - if (active_state() == Gtkmm2ext::ExplicitActive) - cairo_set_source_rgba (cr, .95, .1, .1, 1.); - else - cairo_set_source_rgba (cr, .95, .44, .44, 1.); // #f46f6f - cairo_fill(cr); - cairo_set_source_rgba (cr, .0, .0, .0, 1.0); - cairo_arc (cr, 0, 0, r *.15, 0, 2 * M_PI); // hole in the middle - cairo_fill(cr); - - cairo_restore(cr); - } - else if (_elements & RecButton) { - const double x = get_width() * .5; - const double y = get_height() * .5; - const double r = std::min(10., std::min(x, y) * .55); // TODO we need a better way to limit max. radius. - cairo_arc (cr, x, y, r, 0, 2 * M_PI); - if (active_state() == Gtkmm2ext::ExplicitActive) - cairo_set_source_rgba (cr, .95, .1, .1, 1.); - else - cairo_set_source_rgba (cr, .95, .44, .44, 1.); // #f46f6f - cairo_fill_preserve(cr); - cairo_set_source_rgba (cr, .0, .0, .0, .8); - cairo_set_line_width(cr, 1); - cairo_stroke(cr); - } - else if (_elements & CloseCross) { - const double x = get_width() * .5; - const double y = get_height() * .5; - const double o = .5 + std::min(x, y) * .4; - ArdourCanvas::set_source_rgba (cr, text_color); - cairo_set_line_width(cr, 1); - cairo_move_to(cr, x-o, y-o); - cairo_line_to(cr, x+o, y+o); - cairo_move_to(cr, x+o, y-o); - cairo_line_to(cr, x-o, y+o); - cairo_stroke(cr); + else /* VectorIcons are exclusive to Pixbuf Icons */ + if (_elements & VectorIcon) { + Gtkmm2ext::ArdourIcon::render (cr, _icon, get_width(), get_height(), active_state(), text_color); } const int text_margin = char_pixel_width(); - // Text, if any if (!_pixbuf && ((_elements & Text)==Text) && !_text.empty()) { assert(_layout); #if 0 // DEBUG style (print on hover) - if (_hovering) { + if (_hovering || (_elements & Inactive)) { bool layout_font = true; Pango::FontDescription fd = _layout->get_font_description(); if (fd.gobj() == NULL) { layout_font = false; fd = get_pango_context()->get_font_description(); } - printf("%s: f:%dx%d bh:%.0f tw:%d (%dx%d) %s\"%s\"\n", + printf("%s: f:%dx%d aw:%.3f bh:%.0f t:%dx%d (%dx%d) %s\"%s\"\n", get_name().c_str(), - char_pixel_width(), char_pixel_height(), - ceil(_text_height * BASELINESTRETCH), - _text_width, + char_pixel_width(), char_pixel_height(), char_avg_pixel_width(), + ceil(char_pixel_height() * BASELINESTRETCH), + _text_width, _text_height, get_width(), get_height(), layout_font ? "L:" : "W:", fd.to_string().c_str()); @@ -474,29 +441,30 @@ ArdourButton::render (cairo_t* cr, cairo_rectangle_t *) //black ring cairo_set_source_rgb (cr, 0, 0, 0); - cairo_arc (cr, 0, 0, _diameter * .5 - 1, 0, 2 * M_PI); + cairo_arc (cr, 0, 0, _diameter * .5 - 1 * UIConfiguration::instance().get_ui_scale(), 0, 2 * M_PI); cairo_fill(cr); //led color ArdourCanvas::set_source_rgba (cr, led_color); - cairo_arc (cr, 0, 0, _diameter * .5 - 3, 0, 2 * M_PI); + cairo_arc (cr, 0, 0, _diameter * .5 - 3 * UIConfiguration::instance().get_ui_scale(), 0, 2 * M_PI); cairo_fill(cr); cairo_restore (cr); } - // a transparent gray layer to indicate insensitivity + // a transparent overlay to indicate insensitivity if ((visual_state() & Gtkmm2ext::Insensitive)) { - rounded_function (cr, 1, 1, get_width() - 2, get_height() - 2, _corner_radius); - cairo_set_source_rgba (cr, 0.505, 0.517, 0.525, 0.6); + rounded_function (cr, 0, 0, get_width(), get_height(), corner_radius); + uint32_t ins_color = UIConfiguration::instance().color ("gtk_background"); + ArdourCanvas::set_source_rgb_a (cr, ins_color, 0.6); cairo_fill (cr); } // if requested, show hovering - if (ARDOUR::Config->get_widget_prelight() + if (UIConfiguration::instance().get_widget_prelight() && !((visual_state() & Gtkmm2ext::Insensitive))) { if (_hovering) { - rounded_function (cr, 1, 1, get_width() - 2, get_height() - 2, _corner_radius); + rounded_function (cr, 1, 1, get_width() - 2, get_height() - 2, corner_radius); cairo_set_source_rgba (cr, 0.905, 0.917, 0.925, 0.2); cairo_fill (cr); } @@ -504,7 +472,7 @@ ArdourButton::render (cairo_t* cr, cairo_rectangle_t *) //user is currently pressing the button. dark outline helps to indicate this if (_grabbed && !(_elements & (Inactive|Menu))) { - rounded_function (cr, 1, 1, get_width() - 2, get_height() - 2, _corner_radius); + rounded_function (cr, 1, 1, get_width() - 2, get_height() - 2, corner_radius); cairo_set_line_width(cr, 2); cairo_set_source_rgba (cr, 0.1, 0.1, 0.1, .5); cairo_stroke (cr); @@ -514,7 +482,7 @@ ArdourButton::render (cairo_t* cr, cairo_rectangle_t *) if (visual_state() & Gtkmm2ext::Selected) { cairo_set_line_width(cr, 1); cairo_set_source_rgba (cr, 1, 0, 0, 0.8); - rounded_function (cr, 0.5, 0.5, get_width() - 1, get_height() - 1, _corner_radius); + rounded_function (cr, 0.5, 0.5, get_width() - 1, get_height() - 1, corner_radius); cairo_stroke (cr); } @@ -524,7 +492,7 @@ ArdourButton::render (cairo_t* cr, cairo_rectangle_t *) // (the editor is always the first receiver for KeyDown). // It's needed for eg. the engine-dialog at startup or after closing a sesion. if (_focused) { - rounded_function (cr, 1.5, 1.5, get_width() - 3, get_height() - 3, _corner_radius); + rounded_function (cr, 1.5, 1.5, get_width() - 3, get_height() - 3, corner_radius); cairo_set_source_rgba (cr, 0.905, 0.917, 0.925, 0.8); double dashes = 1; cairo_set_dash (cr, &dashes, 1, 0); @@ -549,6 +517,7 @@ ArdourButton::on_realize() ensure_layout (); if (_layout && _layout->get_text() != _text) { _layout->set_text (_text); + queue_resize (); } } @@ -559,7 +528,7 @@ ArdourButton::on_size_request (Gtk::Requisition* req) CairoWidget::on_size_request (req); if (_diameter == 0) { - const float newdia = rint (ARDOUR::Config->get_font_scale () / 1024. / 7.5); // 11px with 80% font-scaling + const float newdia = rintf (11.f * UIConfiguration::instance().get_ui_scale()); if (_diameter != newdia) { _pattern_height = 0; _diameter = newdia; @@ -567,13 +536,11 @@ ArdourButton::on_size_request (Gtk::Requisition* req) } if ((_elements & Text) && !_text.empty()) { - int ignored; - _text_height = char_pixel_height (); // if _layout does not exist, char_pixel_height() creates it, - _layout->get_pixel_size (_text_width, ignored); - req->width += rint(1.6 * char_pixel_width()); // padding + req->height = std::max(req->height, (int) ceil(char_pixel_height() * BASELINESTRETCH + 1.0)); + _layout->get_pixel_size (_text_width, _text_height); + req->width += rint(1.75 * char_pixel_width()); // padding req->width += _text_width; - req->height = std::max(req->height, (int) ceil(_text_height * BASELINESTRETCH + 1.0)); } else { _text_width = 0; _text_height = 0; @@ -593,25 +560,37 @@ ArdourButton::on_size_request (Gtk::Requisition* req) req->width += _diameter + 4; } - if (_elements & (RecButton | CloseCross)) { + if (_elements & VectorIcon) { assert(!(_elements & Text)); - const int wh = std::max(char_pixel_width(), char_pixel_height()) * BASELINESTRETCH; + const int wh = std::max (6., std::max (rint (TRACKHEADERBTNW * char_avg_pixel_width()), ceil (char_pixel_height() * BASELINESTRETCH + 1.))); req->width += wh; - req->height = std::max(req->height, (int) wh); + req->height = std::max(req->height, wh); } - if (_tweaks & Square) { - // squared buttons are also grouped, we cannot align all texts - // -> skip proper center adjustment + /* Tweaks to mess the nice stuff above up again. */ + if (_tweaks & TrackHeader) { + // forget everything above and just use a fixed square [em] size + // "TrackHeader Buttons" are single letter (usually uppercase) + // a SizeGroup is much less efficient (lots of gtk work under the hood for each track) + const int wh = std::max (rint (TRACKHEADERBTNW * char_avg_pixel_width()), ceil (char_pixel_height() * BASELINESTRETCH + 1.)); + req->width = wh; + req->height = wh; + } + else if (_tweaks & Square) { + // currerntly unused (again) if (req->width < req->height) req->width = req->height; if (req->height < req->width) req->height = req->width; } else if (_text_width > 0 && !(_elements & (Menu | Indicator))) { // properly centered text for those elements that are centered + // (no sub-pixel offset) if ((req->width - _text_width) & 1) { ++req->width; } if ((req->height - _text_height) & 1) { ++req->height; } } +#if 0 + printf("REQ: %s: %dx%d\n", get_name().c_str(), req->width, req->height); +#endif } /** @@ -626,15 +605,33 @@ ArdourButton::set_colors () return; } std::string name = get_name(); + bool failed = false; - fill_active_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1: fill active", name)); - fill_inactive_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1: fill", name)); + fill_active_color = UIConfiguration::instance().color (string_compose ("%1: fill active", name), &failed); + if (failed) { + fill_active_color = UIConfiguration::instance().color ("generic button: fill active"); + } + fill_inactive_color = UIConfiguration::instance().color (string_compose ("%1: fill", name), &failed); + if (failed) { + fill_inactive_color = UIConfiguration::instance().color ("generic button: fill"); + } + + text_active_color = ArdourCanvas::contrasting_text_color (fill_active_color); + text_inactive_color = ArdourCanvas::contrasting_text_color (fill_inactive_color); + + led_active_color = UIConfiguration::instance().color (string_compose ("%1: led active", name), &failed); + if (failed) { + led_active_color = UIConfiguration::instance().color ("generic button: led active"); + } + + /* The inactive color for the LED is just a fairly dark version of the + * active color. + */ - text_active_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1: text active", name)); - text_inactive_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1: text", name)); + ArdourCanvas::HSV inactive (led_active_color); + inactive.v = 0.35; - led_active_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1: led active", name)); - led_inactive_color = ARDOUR_UI::config()->color_by_name (string_compose ("%1: led", name)); + led_inactive_color = inactive.color (); } /** @@ -680,9 +677,7 @@ void ArdourButton::set_fixed_colors (const uint32_t color_active, const uint32_t RGBA_TO_UINT( 0, 0, 0, 255); /* use black */ /* XXX what about led colors ? */ - - /* trigger a "style-changed" message */ - on_name_changed(); + CairoWidget::set_dirty (); } void @@ -729,7 +724,9 @@ ArdourButton::set_led_left (bool yn) bool ArdourButton::on_button_press_event (GdkEventButton *ev) { - if ((_elements & Indicator) && _led_rect && _distinct_led_click) { + focus_handler (); + + if (ev->button == 1 && (_elements & Indicator) && _led_rect && _distinct_led_click) { if (ev->x >= _led_rect->x && ev->x < _led_rect->x + _led_rect->width && ev->y >= _led_rect->y && ev->y < _led_rect->y + _led_rect->height) { return true; @@ -743,7 +740,7 @@ ArdourButton::on_button_press_event (GdkEventButton *ev) _grabbed = true; CairoWidget::set_dirty (); - if (!_act_on_release) { + if (ev->button == 1 && !_act_on_release) { if (_action) { _action->activate (); return true; @@ -759,10 +756,10 @@ ArdourButton::on_button_press_event (GdkEventButton *ev) bool ArdourButton::on_button_release_event (GdkEventButton *ev) { - if (_hovering && (_elements & Indicator) && _led_rect && _distinct_led_click) { + if (ev->button == 1 && _hovering && (_elements & Indicator) && _led_rect && _distinct_led_click) { if (ev->x >= _led_rect->x && ev->x < _led_rect->x + _led_rect->width && ev->y >= _led_rect->y && ev->y < _led_rect->y + _led_rect->height) { - signal_led_clicked(); /* EMIT SIGNAL */ + signal_led_clicked(ev); /* EMIT SIGNAL */ return true; } } @@ -770,7 +767,7 @@ ArdourButton::on_button_release_event (GdkEventButton *ev) _grabbed = false; CairoWidget::set_dirty (); - if (_hovering) { + if (ev->button == 1 && _hovering) { signal_clicked (); if (_act_on_release) { if (_action) { @@ -805,7 +802,6 @@ ArdourButton::on_size_allocate (Allocation& alloc) { CairoWidget::on_size_allocate (alloc); setup_led_rect (); - _update_colors = true; } void @@ -878,7 +874,8 @@ ArdourButton::action_toggled () void ArdourButton::on_style_changed (const RefPtr&) { - on_name_changed(); + _update_colors = true; + CairoWidget::set_dirty (); } void @@ -902,7 +899,9 @@ ArdourButton::setup_led_rect () return; } - _led_rect = new cairo_rectangle_t; + if (!_led_rect) { + _led_rect = new cairo_rectangle_t; + } if (_elements & Text) { if (_led_left) { @@ -970,7 +969,7 @@ ArdourButton::on_focus_out_event (GdkEventFocus* ev) bool ArdourButton::on_key_release_event (GdkEventKey *ev) { if (_focused && - (ev->keyval == GDK_KEY_space || ev->keyval == GDK_Return)) + (ev->keyval == GDK_space || ev->keyval == GDK_Return)) { signal_clicked(); if (_action) { @@ -986,7 +985,7 @@ ArdourButton::on_enter_notify_event (GdkEventCrossing* ev) { _hovering = (_elements & Inactive) ? false : true; - if (ARDOUR::Config->get_widget_prelight()) { + if (UIConfiguration::instance().get_widget_prelight()) { CairoWidget::set_dirty (); } @@ -998,7 +997,7 @@ ArdourButton::on_leave_notify_event (GdkEventCrossing* ev) { _hovering = false; - if (ARDOUR::Config->get_widget_prelight()) { + if (UIConfiguration::instance().get_widget_prelight()) { CairoWidget::set_dirty (); } @@ -1010,7 +1009,9 @@ ArdourButton::set_tweaks (Tweaks t) { if (_tweaks != t) { _tweaks = t; - CairoWidget::set_dirty (); + if (is_realized()) { + queue_resize (); + } } } @@ -1025,7 +1026,7 @@ ArdourButton::action_sensitivity_changed () } void -ArdourButton::set_layout_ellisize_width (int w) +ArdourButton::set_layout_ellipsize_width (int w) { if (_layout_ellipsize_width == w) { return; @@ -1034,8 +1035,11 @@ ArdourButton::set_layout_ellisize_width (int w) if (!_layout) { return; } - if (_layout_ellipsize_width > 0) { - _layout->set_width (_layout_ellipsize_width); + if (_layout_ellipsize_width > 3 * PANGO_SCALE) { + _layout->set_width (_layout_ellipsize_width - 3 * PANGO_SCALE); + } + if (is_realized ()) { + queue_resize (); } } @@ -1050,8 +1054,10 @@ ArdourButton::set_text_ellipsize (Pango::EllipsizeMode e) return; } _layout->set_ellipsize(_ellipsis); - if (is_realized () && _layout_ellipsize_width > 0) { - _layout->set_width (_layout_ellipsize_width); + if (_layout_ellipsize_width > 3 * PANGO_SCALE) { + _layout->set_width (_layout_ellipsize_width - 3 * PANGO_SCALE); + } + if (is_realized ()) { queue_resize (); } } @@ -1063,8 +1069,8 @@ ArdourButton::ensure_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); + if (_layout_ellipsize_width > 3 * PANGO_SCALE) { + _layout->set_width (_layout_ellipsize_width - 3* PANGO_SCALE); } } } @@ -1086,7 +1092,8 @@ ArdourButton::recalc_char_pixel_geometry () // 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()); + _char_avg_pixel_width = w / (float)gx.size(); + _char_pixel_width = std::max(4, (int) ceil (_char_avg_pixel_width)); _layout->set_text (_text); } @@ -1104,7 +1111,7 @@ void ArdourButton::action_tooltip_changed () { string str = _action->property_tooltip().get_value(); - ARDOUR_UI::instance()->set_tip (*this, str); + set_tooltip (*this, str); } void @@ -1120,3 +1127,23 @@ ArdourButton::add_elements (Element e) _elements = (ArdourButton::Element) (_elements | e); CairoWidget::set_dirty (); } + +void +ArdourButton::set_icon (Gtkmm2ext::ArdourIcon::Icon i) +{ + _icon = i; + _elements = (ArdourButton::Element) ((_elements | ArdourButton::VectorIcon) & ~ArdourButton::Text); + CairoWidget::set_dirty (); +} + +void +ArdourButton::set_custom_led_color (uint32_t c, bool useit) +{ + if (led_custom_color == c && use_custom_led_color == useit) { + return; + } + + led_custom_color = c; + use_custom_led_color = useit; + CairoWidget::set_dirty (); +}