13
0

ArdourButton: add text for measuring decoupled from display text

In the normal course of events, an ArdourButton requests just enough
space to display its elements. In particular the size will change when
the text does. Yet, in several cases it is better to avoid layout jittering; until now ArdourButton users manually set a static size on the button at creation time.

Introduce new API to set the text used for measuring the button size
separately from the text that will be displayed. In most cases this
enables the callers to replace

    set_size_request_to_display_given_text(button, text, w, h);

where w and h were hard-coded to cater for other button elements, by

    button.set_sizing_text(text);

which will make ArdourButton correctly compute the size request in all
cases with its real elements and padding. ArdourButton users can call

    button.set_sizing_text("");

to get the size request depend on displayed text (which is the default).
This commit is contained in:
Julien "_FrnchFrgg_" RIVAUD 2016-08-20 15:46:41 +02:00
parent 23ccf48c28
commit f108bf1373
2 changed files with 50 additions and 14 deletions

View File

@ -95,6 +95,7 @@ ArdourButton::ArdourButton (Element e)
, _ellipsis (Pango::ELLIPSIZE_NONE)
, _update_colors (true)
, _pattern_height (0)
, _sizing_text("")
{
UIConfiguration::instance().ColorsChanged.connect (sigc::mem_fun (*this, &ArdourButton::color_handler));
/* This is not provided by gtkmm */
@ -138,6 +139,7 @@ ArdourButton::ArdourButton (const std::string& str, Element e)
, _ellipsis (Pango::ELLIPSIZE_NONE)
, _update_colors (true)
, _pattern_height (0)
, _sizing_text("")
{
set_text (str);
UIConfiguration::instance().ColorsChanged.connect (sigc::mem_fun (*this, &ArdourButton::color_handler));
@ -186,6 +188,24 @@ ArdourButton::set_text (const std::string& str)
ensure_layout ();
if (_layout && _layout->get_text() != _text) {
_layout->set_text (_text);
/* on_size_request() will fill in _text_width/height
* so queue it even if _sizing_text != "" */
queue_resize ();
}
}
void
ArdourButton::set_sizing_text (const std::string& str)
{
if (_sizing_text == str) {
return;
}
_sizing_text = str;
if (!is_realized()) {
return;
}
ensure_layout ();
if (_layout) {
queue_resize ();
}
}
@ -525,8 +545,10 @@ ArdourButton::on_realize()
{
CairoWidget::on_realize ();
ensure_layout ();
if (_layout && _layout->get_text() != _text) {
_layout->set_text (_text);
if (_layout) {
if (_layout->get_text() != _text) {
_layout->set_text (_text);
}
queue_resize ();
}
}
@ -547,27 +569,34 @@ ArdourButton::on_size_request (Gtk::Requisition* req)
if (_elements & Text) {
ensure_layout();
_layout->set_text (_text);
/* render() needs the size of the displayed text */
_layout->get_pixel_size (_text_width, _text_height);
if (_tweaks & OccasionalText) {
/* size should not change based on presence or absence
* of text.
*/
if (!_text.empty()) {
ensure_layout ();
_layout->set_text (_text);
_layout->get_pixel_size (_text_width, _text_height);
}
} else if (!_text.empty()) {
//if _layout does not exist, char_pixel_height() creates it,
} else { //if (!_text.empty() || !_sizing_text.empty()) {
req->height = std::max(req->height, (int) ceil(char_pixel_height() * BASELINESTRETCH + 1.0));
assert (_layout);
_layout->get_pixel_size (_text_width, _text_height);
req->width += rint(1.75 * char_pixel_width()); // padding
req->width += _text_width;
if (!_sizing_text.empty()) {
_layout->set_text (_sizing_text); /* use sizing text */
}
int sizing_text_width = 0, sizing_text_height = 0;
_layout->get_pixel_size (sizing_text_width, sizing_text_height);
req->width += sizing_text_width;
if (!_sizing_text.empty()) {
_layout->set_text (_text); /* restore display text */
}
}
/* XXX hack (surprise). Deal with two common rotation angles */

View File

@ -91,6 +91,12 @@ class ArdourButton : public CairoWidget , public Gtkmm2ext::Activatable
void set_layout_font (const Pango::FontDescription&);
void set_text_ellipsize (Pango::EllipsizeMode);
/* Sets the text used for size request computation. Pass an
* empty string to return to the default behavior which uses
* the currently displayed text for measurement. */
void set_sizing_text (const std::string&);
const std::string& get_sizing_text () {return _sizing_text;}
sigc::signal<void, GdkEventButton*> signal_led_clicked;
sigc::signal<void> signal_clicked;
@ -136,6 +142,7 @@ class ArdourButton : public CairoWidget , public Gtkmm2ext::Activatable
Glib::RefPtr<Pango::Layout> _layout;
Glib::RefPtr<Gdk::Pixbuf> _pixbuf;
std::string _text;
std::string _sizing_text;
Element _elements;
Gtkmm2ext::ArdourIcon::Icon _icon;
Tweaks _tweaks;