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:
parent
23ccf48c28
commit
f108bf1373
@ -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 */
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user