+ /** @param y y coordinate.
+ * @return Pair consisting of the child under y (or 0) and the (fractional) index of the child under y (or -1)
+ */
+ std::pair<T*, double> get_child_at_position (int y) const
+ {
+ T* before;
+ T* after;
+
+ std::pair<T*, double> r;
+
+ r.second = get_children_around_position (y, &before, &r.first, &after);
+
+ return r;
+ }
+
+ void set_spacing (int s) {
+ _internal_vbox.set_spacing (s);
+ }
+
+ void remove_placeholder ()
+ {
+ if (_placeholder) {
+ _internal_vbox.remove (*_placeholder);
+ _placeholder = 0;
+ }
+ }
+
+ /** Add a placeholder where a child would be put if it were added at the given y position.
+ * @param y y position within the DnDVBox.
+ * @return index of child that the placeholder represents, or -1 if it is at the end of all children.
+ */
+ int add_placeholder (double y)
+ {
+ return create_or_update_placeholder (get_child_at_position (y).second);
+ }
+
+ /** Children have been reordered by a drag */
+ sigc::signal<void> Reordered;
+
+ /** A button has been pressed over the widget */
+ sigc::signal<bool, GdkEventButton*, T*> ButtonPress;
+
+ /** A button has been release over the widget */
+ sigc::signal<bool, GdkEventButton*, T*> ButtonRelease;
+
+ /** A child has been dropped onto this DnDVBox from another one;
+ * Parameters are the source DnDVBox, our child which the other one was dropped on (or 0) and the DragContext.
+ */
+ sigc::signal<void, DnDVBox*, T*, Glib::RefPtr<Gdk::DragContext> const & > DropFromAnotherBox;
+ sigc::signal<void, Gtk::SelectionData const &, T*, Glib::RefPtr<Gdk::DragContext> const & > DropFromExternal;
+ sigc::signal<void> SelectionChanged;
+
+private:
+
+ /** @return the bottom y position of a child, pretending any placeholder
+ * is not there.
+ */
+ double bottom_of_child_ignoring_placeholder (T* child) const
+ {
+ Gtk::Allocation const a = child->widget().get_allocation ();
+ double bottom = a.get_y() + a.get_height();
+
+ if (_placeholder) {
+ Gtk::Allocation const b = _placeholder->get_allocation ();
+ if (b.get_y() < a.get_y()) {
+ bottom -= (b.get_height () + _internal_vbox.get_spacing ());
+ }
+ }
+
+ return bottom;
+ }
+