X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fgtkmm2ext%2Fpane.cc;h=aa8e7d142b74655eaa3f0922eacf17dfdd1fe0a8;hb=5700296cb66c1ebf16903b9baa8883395779a7fd;hp=5945ec40dca030accd0ad2c3c1c5c23355ef6765;hpb=067616a84f6ee6be2d2f77877fbf5f8bdc10775a;p=ardour.git diff --git a/libs/gtkmm2ext/pane.cc b/libs/gtkmm2ext/pane.cc index 5945ec40dc..aa8e7d142b 100644 --- a/libs/gtkmm2ext/pane.cc +++ b/libs/gtkmm2ext/pane.cc @@ -30,7 +30,7 @@ using namespace std; Pane::Pane (bool h) : horizontal (h) , did_move (false) - , divider_width (5) + , divider_width (2) { using namespace Gdk; @@ -40,7 +40,25 @@ Pane::Pane (bool h) if (horizontal) { drag_cursor = Cursor (SB_H_DOUBLE_ARROW); } else { - drag_cursor = Cursor (SB_H_DOUBLE_ARROW); + drag_cursor = Cursor (SB_V_DOUBLE_ARROW); + } +} + +Pane::~Pane () +{ + for (Children::iterator c = children.begin(); c != children.end(); ++c) { + c->w->unparent (); + } +} + +void +Pane::set_child_minsize (Gtk::Widget const& w, int32_t minsize) +{ + for (Children::iterator c = children.begin(); c != children.end(); ++c) { + if (c->w == &w) { + c->minsize = minsize; + break; + } } } @@ -75,7 +93,7 @@ Pane::on_size_request (GtkRequisition* req) for (Children::iterator child = children.begin(); child != children.end(); ++child) { GtkRequisition r; - (*child)->size_request (r); + child->w->size_request (r); if (horizontal) { largest.height = max (largest.height, r.height); @@ -100,6 +118,7 @@ void Pane::add_divider () { Divider* d = new Divider; + d->set_name (X_("Divider")); d->signal_button_press_event().connect (sigc::bind (sigc::mem_fun (*this, &Pane::handle_press_event), d), false); d->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &Pane::handle_release_event), d), false); d->signal_motion_notify_event().connect (sigc::bind (sigc::mem_fun (*this, &Pane::handle_motion_event), d), false); @@ -111,13 +130,22 @@ Pane::add_divider () dividers.push_back (d); } +void +Pane::handle_child_visibility () +{ + reallocate (get_allocation()); +} + void Pane::on_add (Widget* w) { - children.push_back (w); + children.push_back (Child (w, 0)); w->set_parent (*this); + w->signal_show().connect (sigc::mem_fun (*this, &Pane::handle_child_visibility)); + w->signal_hide().connect (sigc::mem_fun (*this, &Pane::handle_child_visibility)); + while (dividers.size() < (children.size() - 1)) { add_divider (); } @@ -126,8 +154,13 @@ Pane::on_add (Widget* w) void Pane::on_remove (Widget* w) { - w->unparent (); - children.remove (w); + for (Children::iterator c = children.begin(); c != children.end(); ++c) { + if (c->w == w) { + w->unparent (); + children.erase (c); + break; + } + } } void @@ -151,7 +184,7 @@ Pane::reallocate (Gtk::Allocation const & alloc) if (children.size() == 1) { /* only child gets the full allocation */ - children.front()->size_allocate (alloc); + children.front().w->size_allocate (alloc); return; } @@ -165,11 +198,30 @@ Pane::reallocate (Gtk::Allocation const & alloc) Children::iterator next; Dividers::iterator div; - for (child = children.begin(), div = dividers.begin(); child != children.end(); ) { + child = children.begin(); + + /* skip initial hidden children */ + + while (child != children.end()) { + if (child->w->is_visible()) { + break; + } + ++child; + } + + for (div = dividers.begin(); child != children.end(); ) { Gtk::Allocation child_alloc; + next = child; - ++next; + + /* Move on to next *visible* child */ + + while (++next != children.end()) { + if (next->w->is_visible()) { + break; + } + } child_alloc.set_x (xpos); child_alloc.set_y (ypos); @@ -183,7 +235,7 @@ Pane::reallocate (Gtk::Allocation const & alloc) } Gtk::Requisition cr; - (*child)->size_request (cr); + child->w->size_request (cr); if (horizontal) { child_alloc.set_width ((gint) floor (remaining * fract)); @@ -197,14 +249,23 @@ Pane::reallocate (Gtk::Allocation const & alloc) ypos += child_alloc.get_height (); } - (*child)->size_allocate (child_alloc); - ++child; + if (child->minsize) { + if (horizontal) { + child_alloc.set_width (max (child_alloc.get_width(), child->minsize)); + } else { + child_alloc.set_height (max (child_alloc.get_height(), child->minsize)); + } + } + + child->w->size_allocate (child_alloc); - if (child == children.end()) { + if (next == children.end()) { /* done, no more children, no need for a divider */ break; } + child = next; + /* add a divider between children */ Gtk::Allocation divider_allocation; @@ -225,6 +286,14 @@ Pane::reallocate (Gtk::Allocation const & alloc) } (*div)->size_allocate (divider_allocation); + (*div)->show (); + ++div; + } + + /* hide all remaining dividers */ + + while (div != dividers.end()) { + (*div)->hide (); ++div; } } @@ -237,9 +306,11 @@ Pane::on_expose_event (GdkEventExpose* ev) for (child = children.begin(), div = dividers.begin(); child != children.end(); ++child, ++div) { - propagate_expose (**child, ev); + if (child->w->is_visible()) { + propagate_expose (*(child->w), ev); + } - if (div != dividers.end()) { + if ((div != dividers.end()) && (*div)->is_visible()) { propagate_expose (**div, ev); } } @@ -262,7 +333,7 @@ Pane::handle_release_event (GdkEventButton* ev, Divider* d) d->dragging = false; if (did_move) { - children.front()->queue_resize (); + children.front().w->queue_resize (); did_move = false; } @@ -329,8 +400,6 @@ Pane::handle_motion_event (GdkEventMotion* ev, Divider* d) void Pane::set_divider (Dividers::size_type div, float fract) { - bool redraw = false; - Dividers::iterator d = dividers.begin(); while (div--) { @@ -343,12 +412,10 @@ Pane::set_divider (Dividers::size_type div, float fract) } } + fract = max (0.0f, min (1.0f, fract)); + if (fract != (*d)->fract) { (*d)->fract = fract; - redraw = true; - } - - if (redraw) { /* our size hasn't changed, but our internal allocations have */ reallocate (get_allocation()); queue_draw (); @@ -380,11 +447,11 @@ Pane::forall_vfunc (gboolean include_internals, GtkCallback callback, gpointer c * the iterators safe; */ - for (Children::iterator w = children.begin(); w != children.end(); ) { - Children::iterator next = w; + for (Children::iterator c = children.begin(); c != children.end(); ) { + Children::iterator next = c; ++next; - callback ((*w)->gobj(), callback_data); - w = next; + callback (c->w->gobj(), callback_data); + c = next; } if (include_internals) { @@ -436,5 +503,6 @@ Pane::handle_leave_event (GdkEventCrossing*, Divider* d) { d->get_window()->set_cursor (); d->set_state (Gtk::STATE_NORMAL); + d->queue_draw (); return true; }