/* * Copyright (C) 2020 Robin Gareus * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include "gtkmm2ext/colors.h" #include "gtkmm2ext/utils.h" #include "widgets/frame.h" #include "widgets/ui_config.h" using namespace std; using namespace Gtk; using namespace ArdourWidgets; Frame::Frame (Orientation orientation, bool boxy) : _orientation (orientation) , _w (0) , _current_parent (0) , _border (0) , _padding (4) , _label_pad_w (5) , _label_pad_h (2) , _label_left (12) , _text_width (0) , _text_height (0) , _alloc_x0 (0) , _alloc_y0 (0) , _boxy (boxy) , _draw (true) { set_name ("Frame"); ensure_style (); _min_size.width = _min_size.height = 0; _layout = Pango::Layout::create (get_pango_context ()); /* provide bg color for cairo child widgets */ g_object_set_data (G_OBJECT (gobj ()), "has_cairo_widget_background_info", (void*)0xfeedface); UIConfigurationBase::instance().DPIReset.connect (sigc::mem_fun (*this, &Frame::on_name_changed)); } Frame::~Frame () { if (_parent_style_change) { _parent_style_change.disconnect (); } if (_w) { _w->unparent (); } } void Frame::on_add (Widget* w) { if (_w || !w) { return; } Bin::on_add (w); _w = w; queue_resize (); } void Frame::on_remove (Gtk::Widget* w) { Bin::on_remove (w); assert (_w == w); _w = 0; } void Frame::on_size_request (GtkRequisition* r) { Bin::on_size_request (r); _border = get_border_width (); _layout->set_markup (_label_text); if (!_layout->get_text ().empty ()) { _layout->get_pixel_size (_text_width, _text_height); } else { _text_width = _text_height = 0; } if (_w) { *r = _w->size_request (); } else { r->width = 0; r->height = 0; } if (_text_width > 0) { if (_orientation == Horizontal) { r->width = max (r->width, _text_width + _label_pad_w * 2 + _label_left); r->width += 2 * (_padding + _border); r->height += 2 * (_padding + _border + _label_pad_h) + _text_height; } else { r->height = max (r->height, _text_width + _label_pad_w * 2 + _label_left); r->width += 2 * (_padding + _border + _label_pad_h) + _text_height; r->height += 2 * (_padding + _border); } } else { r->height += 2 * (_padding + _border); r->width += 2 * (_padding + _border); } _min_size = *r; } void Frame::on_size_allocate (Allocation& alloc) { Bin::on_size_allocate (alloc); _alloc_x0 = alloc.get_x (); _alloc_y0 = alloc.get_y (); Allocation child_alloc; if (alloc.get_width () < _min_size.width || alloc.get_height () < _min_size.height) { #if 0 printf ("Frame::on_size_allocate %dx%d < %dx%d\n", alloc.get_width (), alloc.get_height (), _min_size.width, _min_size.height); #endif return; } int pb_l, pb_t; if (_orientation == Horizontal) { pb_l = _padding + _border; pb_t = _padding + _border + (_text_width > 0 ? _label_pad_h : 0); child_alloc.set_x (alloc.get_x () + pb_l); child_alloc.set_y (alloc.get_y () + pb_t + _text_height); child_alloc.set_width (alloc.get_width () - pb_l * 2); child_alloc.set_height (alloc.get_height () - pb_t * 2 - _text_height); } else { pb_l = _padding + _border + (_text_width > 0 ? _label_pad_h : 0);; pb_t = _padding + _border; child_alloc.set_x (alloc.get_x () + pb_l + _text_height); child_alloc.set_y (alloc.get_y () + pb_t); child_alloc.set_width (alloc.get_width () - pb_l * 2 - _text_height); child_alloc.set_height (alloc.get_height () - pb_t * 2); } if (child_alloc.get_width () < 1 || child_alloc.get_height () < 1) { return; } if (_w) { _w->size_allocate (child_alloc); } } void Frame::on_style_changed (const Glib::RefPtr& style) { Bin::on_style_changed (style); Glib::RefPtr const& new_style = get_style (); if (_layout && (_layout->get_font_description ().gobj () == 0 || _layout->get_font_description () != new_style->get_font ())) { _layout->set_font_description (new_style->get_font ()); queue_resize (); } else if (get_realized ()) { queue_resize (); } } void Frame::on_name_changed () { ensure_style (); queue_resize (); queue_draw (); } Glib::RefPtr