#include "gtkframe.h"
#include "gtktreemodelsort.h"
#include "gtktooltip.h"
+#include "gtkscrollable.h"
#include "gtkprivate.h"
+#include "gtkwidgetprivate.h"
#define GTK_TREE_VIEW_PRIORITY_VALIDATE (GDK_PRIORITY_REDRAW + 5)
#define GTK_TREE_VIEW_PRIORITY_SCROLL_SYNC (GTK_TREE_VIEW_PRIORITY_VALIDATE + 2)
PROP_MODEL,
PROP_HADJUSTMENT,
PROP_VADJUSTMENT,
+ PROP_HSCROLL_POLICY,
+ PROP_VSCROLL_POLICY,
PROP_HEADERS_VISIBLE,
PROP_HEADERS_CLICKABLE,
PROP_EXPANDER_COLUMN,
static void gtk_tree_view_realize (GtkWidget *widget);
static void gtk_tree_view_unrealize (GtkWidget *widget);
static void gtk_tree_view_map (GtkWidget *widget);
+static void gtk_tree_view_get_preferred_width (GtkWidget *widget,
+ gint *minimum,
+ gint *natural);
+static void gtk_tree_view_get_preferred_height (GtkWidget *widget,
+ gint *minimum,
+ gint *natural);
static void gtk_tree_view_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static void gtk_tree_view_size_allocate (GtkWidget *widget,
guint time);
/* tree_model signals */
-static void gtk_tree_view_set_adjustments (GtkTreeView *tree_view,
- GtkAdjustment *hadj,
- GtkAdjustment *vadj);
+static void gtk_tree_view_set_hadjustment (GtkTreeView *tree_view,
+ GtkAdjustment *adjustment);
+static void gtk_tree_view_set_vadjustment (GtkTreeView *tree_view,
+ GtkAdjustment *adjustment);
static gboolean gtk_tree_view_real_move_cursor (GtkTreeView *tree_view,
GtkMovementStep step,
gint count);
G_DEFINE_TYPE_WITH_CODE (GtkTreeView, gtk_tree_view, GTK_TYPE_CONTAINER,
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
- gtk_tree_view_buildable_init))
+ gtk_tree_view_buildable_init)
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
static void
gtk_tree_view_class_init (GtkTreeViewClass *class)
widget_class->map = gtk_tree_view_map;
widget_class->realize = gtk_tree_view_realize;
widget_class->unrealize = gtk_tree_view_unrealize;
- widget_class->size_request = gtk_tree_view_size_request;
+ widget_class->get_preferred_width = gtk_tree_view_get_preferred_width;
+ widget_class->get_preferred_height = gtk_tree_view_get_preferred_height;
widget_class->size_allocate = gtk_tree_view_size_allocate;
widget_class->button_press_event = gtk_tree_view_button_press;
widget_class->button_release_event = gtk_tree_view_button_release;
container_class->forall = gtk_tree_view_forall;
container_class->set_focus_child = gtk_tree_view_set_focus_child;
- class->set_scroll_adjustments = gtk_tree_view_set_adjustments;
class->move_cursor = gtk_tree_view_real_move_cursor;
class->select_all = gtk_tree_view_real_select_all;
class->unselect_all = gtk_tree_view_real_unselect_all;
GTK_TYPE_TREE_MODEL,
GTK_PARAM_READWRITE));
- g_object_class_install_property (o_class,
- PROP_HADJUSTMENT,
- g_param_spec_object ("hadjustment",
- P_("Horizontal Adjustment"),
- P_("Horizontal Adjustment for the widget"),
- GTK_TYPE_ADJUSTMENT,
- GTK_PARAM_READWRITE));
-
- g_object_class_install_property (o_class,
- PROP_VADJUSTMENT,
- g_param_spec_object ("vadjustment",
- P_("Vertical Adjustment"),
- P_("Vertical Adjustment for the widget"),
- GTK_TYPE_ADJUSTMENT,
- GTK_PARAM_READWRITE));
+ g_object_class_override_property (o_class, PROP_HADJUSTMENT, "hadjustment");
+ g_object_class_override_property (o_class, PROP_VADJUSTMENT, "vadjustment");
+ g_object_class_override_property (o_class, PROP_HSCROLL_POLICY, "hscroll-policy");
+ g_object_class_override_property (o_class, PROP_VSCROLL_POLICY, "vscroll-policy");
g_object_class_install_property (o_class,
PROP_HEADERS_VISIBLE,
GTK_PARAM_READABLE));
/* Signals */
- /**
- * GtkTreeView::set-scroll-adjustments
- * @horizontal: the horizontal #GtkAdjustment
- * @vertical: the vertical #GtkAdjustment
- *
- * Set the scroll adjustments for the tree view. Usually scrolled containers
- * like #GtkScrolledWindow will emit this signal to connect two instances
- * of #GtkScrollbar to the scroll directions of the #GtkTreeView.
- */
- widget_class->set_scroll_adjustments_signal =
- g_signal_new (I_("set-scroll-adjustments"),
- G_TYPE_FROM_CLASS (o_class),
- G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET (GtkTreeViewClass, set_scroll_adjustments),
- NULL, NULL,
- _gtk_marshal_VOID__OBJECT_OBJECT,
- G_TYPE_NONE, 2,
- GTK_TYPE_ADJUSTMENT,
- GTK_TYPE_ADJUSTMENT);
-
/**
* GtkTreeView::row-activated:
* @tree_view: the object on which the signal is emitted
tree_view->priv->fixed_height = -1;
tree_view->priv->fixed_height_mode = FALSE;
tree_view->priv->fixed_height_check = 0;
- gtk_tree_view_set_adjustments (tree_view, NULL, NULL);
tree_view->priv->selection = _gtk_tree_selection_new_with_tree_view (tree_view);
tree_view->priv->enable_search = TRUE;
tree_view->priv->search_column = -1;
tree_view->priv->event_last_x = -10000;
tree_view->priv->event_last_y = -10000;
+
+ gtk_tree_view_set_vadjustment (tree_view, NULL);
+ gtk_tree_view_set_hadjustment (tree_view, NULL);
}
\f
case PROP_VADJUSTMENT:
gtk_tree_view_set_vadjustment (tree_view, g_value_get_object (value));
break;
+ case PROP_HSCROLL_POLICY:
+ tree_view->priv->hscroll_policy = g_value_get_enum (value);
+ gtk_widget_queue_resize (GTK_WIDGET (tree_view));
+ break;
+ case PROP_VSCROLL_POLICY:
+ tree_view->priv->vscroll_policy = g_value_get_enum (value);
+ gtk_widget_queue_resize (GTK_WIDGET (tree_view));
+ break;
case PROP_HEADERS_VISIBLE:
gtk_tree_view_set_headers_visible (tree_view, g_value_get_boolean (value));
break;
case PROP_VADJUSTMENT:
g_value_set_object (value, tree_view->priv->vadjustment);
break;
+ case PROP_HSCROLL_POLICY:
+ g_value_set_enum (value, tree_view->priv->hscroll_policy);
+ break;
+ case PROP_VSCROLL_POLICY:
+ g_value_set_enum (value, tree_view->priv->vscroll_policy);
+ break;
case PROP_HEADERS_VISIBLE:
g_value_set_boolean (value, gtk_tree_view_get_headers_visible (tree_view));
break;
requisition->height = tree_view->priv->height + TREE_VIEW_HEADER_HEIGHT (tree_view);
tmp_list = tree_view->priv->children;
+}
- while (tmp_list)
- {
- GtkTreeViewChild *child = tmp_list->data;
- GtkRequisition child_requisition;
+static void
+gtk_tree_view_get_preferred_width (GtkWidget *widget,
+ gint *minimum,
+ gint *natural)
+{
+ GtkRequisition requisition;
- tmp_list = tmp_list->next;
+ gtk_tree_view_size_request (widget, &requisition);
- if (gtk_widget_get_visible (child->widget))
- gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
- }
+ *minimum = *natural = requisition.width;
+}
+
+static void
+gtk_tree_view_get_preferred_height (GtkWidget *widget,
+ gint *minimum,
+ gint *natural)
+{
+ GtkRequisition requisition;
+
+ gtk_tree_view_size_request (widget, &requisition);
+
+ *minimum = *natural = requisition.height;
}
static int
if (validated_area)
{
GtkRequisition requisition;
+
/* We temporarily guess a size, under the assumption that it will be the
* same when we get our next size_allocate. If we don't do this, we'll be
* in an inconsistent state when we call top_row_to_dy. */
- gtk_widget_get_preferred_size (GTK_WIDGET (tree_view),
- &requisition, NULL);
+ /* FIXME: This is called from size_request, for some reason it is not infinitely
+ * recursing, we cannot call gtk_widget_get_preferred_size() here because that's
+ * not allowed (from inside ->get_preferred_width/height() implementations, one
+ * should call the vfuncs directly). However what is desired here is the full
+ * size including any margins and limited by any alignment (i.e. after
+ * GtkWidget:adjust_size_request() is called).
+ *
+ * Currently bypassing this but the real solution is to not update the scroll adjustments
+ * untill we've recieved an allocation (never update scroll adjustments from size-requests).
+ */
+ gtk_tree_view_size_request (GTK_WIDGET (tree_view), &requisition);
+
tree_view->priv->hadjustment->upper = MAX (tree_view->priv->hadjustment->upper, (gfloat)requisition.width);
tree_view->priv->vadjustment->upper = MAX (tree_view->priv->vadjustment->upper, (gfloat)requisition.height);
gtk_adjustment_changed (tree_view->priv->hadjustment);
/* Case 2. We don't have focus at all. */
if (!gtk_widget_has_focus (widget))
{
- if (!gtk_tree_view_header_focus (tree_view, direction, FALSE))
- gtk_widget_grab_focus (widget);
+ gtk_widget_grab_focus (widget);
return TRUE;
}
GTK_CONTAINER_CLASS (gtk_tree_view_parent_class)->set_focus_child (container, child);
}
-static void
-gtk_tree_view_set_adjustments (GtkTreeView *tree_view,
- GtkAdjustment *hadj,
- GtkAdjustment *vadj)
-{
- gboolean need_adjust = FALSE;
-
- g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
-
- if (hadj)
- g_return_if_fail (GTK_IS_ADJUSTMENT (hadj));
- else
- hadj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
- if (vadj)
- g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
- else
- vadj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
-
- if (tree_view->priv->hadjustment && (tree_view->priv->hadjustment != hadj))
- {
- g_signal_handlers_disconnect_by_func (tree_view->priv->hadjustment,
- gtk_tree_view_adjustment_changed,
- tree_view);
- g_object_unref (tree_view->priv->hadjustment);
- }
-
- if (tree_view->priv->vadjustment && (tree_view->priv->vadjustment != vadj))
- {
- g_signal_handlers_disconnect_by_func (tree_view->priv->vadjustment,
- gtk_tree_view_adjustment_changed,
- tree_view);
- g_object_unref (tree_view->priv->vadjustment);
- }
-
- if (tree_view->priv->hadjustment != hadj)
- {
- tree_view->priv->hadjustment = hadj;
- g_object_ref_sink (tree_view->priv->hadjustment);
-
- g_signal_connect (tree_view->priv->hadjustment, "value-changed",
- G_CALLBACK (gtk_tree_view_adjustment_changed),
- tree_view);
- need_adjust = TRUE;
- }
-
- if (tree_view->priv->vadjustment != vadj)
- {
- tree_view->priv->vadjustment = vadj;
- g_object_ref_sink (tree_view->priv->vadjustment);
-
- g_signal_connect (tree_view->priv->vadjustment, "value-changed",
- G_CALLBACK (gtk_tree_view_adjustment_changed),
- tree_view);
- need_adjust = TRUE;
- }
-
- if (need_adjust)
- gtk_tree_view_adjustment_changed (NULL, tree_view);
-}
-
-
static gboolean
gtk_tree_view_real_move_cursor (GtkTreeView *tree_view,
GtkMovementStep step,
send_event = gdk_event_new (GDK_LEAVE_NOTIFY);
send_event->crossing.send_event = TRUE;
- send_event->crossing.window = g_object_ref (GTK_BUTTON (column->button)->event_window);
+ send_event->crossing.window = g_object_ref (gtk_button_get_event_window (GTK_BUTTON (column->button)));
send_event->crossing.subwindow = NULL;
send_event->crossing.detail = GDK_NOTIFY_ANCESTOR;
send_event->crossing.time = GDK_CURRENT_TIME;
gtk_widget_show (frame);
gtk_container_add (GTK_CONTAINER (tree_view->priv->search_window), frame);
- vbox = gtk_vbox_new (FALSE, 0);
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_show (vbox);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 3);
*
* Return value: (transfer none): A #GtkAdjustment object, or %NULL
* if none is currently being used.
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_get_hadjustment()
**/
GtkAdjustment *
gtk_tree_view_get_hadjustment (GtkTreeView *tree_view)
{
g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL);
- if (tree_view->priv->hadjustment == NULL)
- gtk_tree_view_set_hadjustment (tree_view, NULL);
-
return tree_view->priv->hadjustment;
}
* @adjustment: (allow-none): The #GtkAdjustment to set, or %NULL
*
* Sets the #GtkAdjustment for the current horizontal aspect.
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_set_hadjustment()
**/
void
gtk_tree_view_set_hadjustment (GtkTreeView *tree_view,
- GtkAdjustment *adjustment)
+ GtkAdjustment *adjustment)
{
+ GtkTreeViewPrivate *priv = tree_view->priv;
+
g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+ g_return_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment));
+
+ if (adjustment && priv->hadjustment == adjustment)
+ return;
+
+ if (priv->hadjustment != NULL)
+ {
+ g_signal_handlers_disconnect_by_func (priv->hadjustment,
+ gtk_tree_view_adjustment_changed,
+ tree_view);
+ g_object_unref (priv->hadjustment);
+ }
+
+ if (adjustment == NULL)
+ adjustment = gtk_adjustment_new (0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0);
- gtk_tree_view_set_adjustments (tree_view,
- adjustment,
- tree_view->priv->vadjustment);
+ g_signal_connect (adjustment, "value-changed",
+ G_CALLBACK (gtk_tree_view_adjustment_changed), tree_view);
+ priv->hadjustment = g_object_ref_sink (adjustment);
+ /* FIXME: Adjustment should probably be populated here with fresh values, but
+ * internal details are too complicated for me to decipher right now.
+ */
+ gtk_tree_view_adjustment_changed (NULL, tree_view);
g_object_notify (G_OBJECT (tree_view), "hadjustment");
}
*
* Return value: (transfer none): A #GtkAdjustment object, or %NULL
* if none is currently being used.
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_get_vadjustment()
**/
GtkAdjustment *
gtk_tree_view_get_vadjustment (GtkTreeView *tree_view)
{
g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL);
- if (tree_view->priv->vadjustment == NULL)
- gtk_tree_view_set_vadjustment (tree_view, NULL);
-
return tree_view->priv->vadjustment;
}
* @adjustment: (allow-none): The #GtkAdjustment to set, or %NULL
*
* Sets the #GtkAdjustment for the current vertical aspect.
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_set_vadjustment()
**/
void
gtk_tree_view_set_vadjustment (GtkTreeView *tree_view,
- GtkAdjustment *adjustment)
+ GtkAdjustment *adjustment)
{
+ GtkTreeViewPrivate *priv = tree_view->priv;
+
g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+ g_return_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment));
- gtk_tree_view_set_adjustments (tree_view,
- tree_view->priv->hadjustment,
- adjustment);
+ if (adjustment && priv->vadjustment == adjustment)
+ return;
+ if (priv->vadjustment != NULL)
+ {
+ g_signal_handlers_disconnect_by_func (priv->vadjustment,
+ gtk_tree_view_adjustment_changed,
+ tree_view);
+ g_object_unref (priv->vadjustment);
+ }
+
+ if (adjustment == NULL)
+ adjustment = gtk_adjustment_new (0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0);
+
+ g_signal_connect (adjustment, "value-changed",
+ G_CALLBACK (gtk_tree_view_adjustment_changed), tree_view);
+ priv->vadjustment = g_object_ref_sink (adjustment);
+ /* FIXME: Adjustment should probably be populated here with fresh values, but
+ * internal details are too complicated for me to decipher right now.
+ */
+ gtk_tree_view_adjustment_changed (NULL, tree_view);
g_object_notify (G_OBJECT (tree_view), "vadjustment");
}