Allow multiple sizing texts for ArdourButton/Dropdown

A widget's style (font) is only set after the widget has been
packed and inherits relevant information from the top-level window.

`set_size_request_to_display_given_text()` produces incorrect
results when it is called for widgets without a top-level
(here ARDOUR_UI::setup_windows() _main_window.add(), changes the
font from "Sans 11" to "Sans 9" for ArdourDropdowns).

`set_size_request_to_display_given_text()` must subscribe to
`signal_style_changed()`, however in case of ArdourButton UI-scaling
of elements also needs to be taken into account. It is preferable
to allow for multiple sizing-texts directly.
This commit is contained in:
Robin Gareus 2022-09-20 02:35:26 +02:00
parent d1bf8428fc
commit 8508b3dba4
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
2 changed files with 33 additions and 23 deletions

View File

@ -55,8 +55,7 @@ ArdourButton::Element ArdourButton::led_default_elements = ArdourButton::Element
ArdourButton::Element ArdourButton::just_led_default_elements = ArdourButton::Element (ArdourButton::Edge|ArdourButton::Body|ArdourButton::Indicator);
ArdourButton::ArdourButton (Element e, bool toggle)
: _sizing_text("")
, _markup (false)
: _markup (false)
, _elements (e)
, _icon (ArdourIcon::NoIcon)
, _icon_render_cb (0)
@ -105,8 +104,7 @@ ArdourButton::ArdourButton (Element e, bool toggle)
}
ArdourButton::ArdourButton (const std::string& str, Element e, bool toggle)
: _sizing_text("")
, _markup (false)
: _markup (false)
, _elements (e)
, _icon (ArdourIcon::NoIcon)
, _tweaks (Tweaks (0))
@ -214,7 +212,7 @@ ArdourButton::set_text (const std::string& str, bool markup)
set_text_internal ();
/* on_size_request() will fill in _text_width/height
* so queue it even if _sizing_text != "" */
if (_sizing_text.empty ()) {
if (_sizing_texts.empty ()) {
queue_resize ();
} else {
_layout->get_pixel_size (_text_width, _text_height);
@ -224,12 +222,20 @@ ArdourButton::set_text (const std::string& str, bool markup)
}
void
ArdourButton::set_sizing_text (const std::string& str)
ArdourButton::set_sizing_text (std::string const& str)
{
if (_sizing_text == str) {
if (_sizing_texts.size () == 1 && _sizing_texts.front() == str) {
return;
}
_sizing_text = str;
_sizing_texts.clear ();
_sizing_texts.push_back (str);
queue_resize ();
}
void
ArdourButton::set_sizing_texts (std::vector<std::string> const& s)
{
_sizing_texts = s;
queue_resize ();
}
@ -677,28 +683,32 @@ ArdourButton::on_size_request (Gtk::Requisition* req)
* of text.
*/
} else if (_layout_ellipsize_width > 0 && _sizing_text.empty()) {
} else if (_layout_ellipsize_width > 0 && _sizing_texts.empty()) {
req->height = std::max(req->height, (int) ceil(char_pixel_height() * BASELINESTRETCH + 1.0));
req->width += _layout_ellipsize_width / PANGO_SCALE;
} else /*if (!_text.empty() || !_sizing_text.empty()) */ {
} else /*if (!_text.empty() || !_sizing_texts.empty()) */ {
req->height = std::max(req->height, (int) ceil(char_pixel_height() * BASELINESTRETCH + 1.0));
req->width += rint(1.75 * char_pixel_width()); // padding
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()) {
set_text_internal (); /* restore display text */
for (auto const& txt : _sizing_texts) {
_layout->set_text (txt); /* use sizing text */
int w, h;
_layout->get_pixel_size (w, h);
sizing_text_width = max(sizing_text_width, w);
sizing_text_width = max(sizing_text_width, h);
}
if (!_sizing_texts.empty()) {
set_text_internal (); /* restore display text */
} else {
_layout->get_pixel_size (sizing_text_width, sizing_text_height);
}
req->width += sizing_text_width;
}
/* XXX hack (surprise). Deal with two common rotation angles */
@ -750,7 +760,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)) {
} else if (_sizing_texts.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; }

View File

@ -106,8 +106,8 @@ class LIBWIDGETS_API ArdourButton : public CairoWidget , public Gtkmm2ext::Activ
/* 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;}
void set_sizing_text (std::string const&);
void set_sizing_texts (std::vector<std::string> const&);
sigc::signal<void, GdkEventButton*> signal_led_clicked;
sigc::signal<void> signal_clicked;
@ -156,7 +156,7 @@ class LIBWIDGETS_API ArdourButton : public CairoWidget , public Gtkmm2ext::Activ
Glib::RefPtr<Pango::Layout> _layout;
Glib::RefPtr<Gdk::Pixbuf> _pixbuf;
std::string _text;
std::string _sizing_text;
std::vector<std::string> _sizing_texts;
bool _markup;
Element _elements;
ArdourIcon::Icon _icon;