[gnome-builder] tree: add gb_tree_node_show_popover()
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] tree: add gb_tree_node_show_popover()
- Date: Sat, 11 Apr 2015 08:50:31 +0000 (UTC)
commit 7220a4bcfe518d273559d53fc65728b78a2ee42b
Author: Christian Hergert <christian hergert me>
Date: Sat Apr 11 01:48:37 2015 -0700
tree: add gb_tree_node_show_popover()
This helper will ensure that the GbTreeNode is visually onscreen before
displaying the popover, attached to the node.
src/tree/gb-tree-node.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++
src/tree/gb-tree-node.h | 2 +
2 files changed, 98 insertions(+), 0 deletions(-)
---
diff --git a/src/tree/gb-tree-node.c b/src/tree/gb-tree-node.c
index 1564c83..0dedc13 100644
--- a/src/tree/gb-tree-node.c
+++ b/src/tree/gb-tree-node.c
@@ -33,6 +33,12 @@ struct _GbTreeNodePrivate
guint use_markup : 1;
};
+typedef struct
+{
+ GbTreeNode *self;
+ GtkPopover *popover;
+} PopupRequest;
+
G_DEFINE_TYPE_WITH_PRIVATE (GbTreeNode, gb_tree_node, G_TYPE_INITIALLY_UNOWNED)
enum {
@@ -678,3 +684,93 @@ gb_tree_node_init (GbTreeNode *node)
{
node->priv = gb_tree_node_get_instance_private (node);
}
+
+static gboolean
+gb_tree_node_show_popover_timeout_cb (gpointer data)
+{
+ PopupRequest *popreq = data;
+ GdkRectangle rect;
+ GtkAllocation alloc;
+ GbTree *tree;
+
+ g_assert (popreq);
+ g_assert (GB_IS_TREE_NODE (popreq->self));
+ g_assert (GTK_IS_POPOVER (popreq->popover));
+
+ if (!(tree = gb_tree_node_get_tree (popreq->self)))
+ goto cleanup;
+
+ gb_tree_node_get_area (popreq->self, &rect);
+ gtk_widget_get_allocation (GTK_WIDGET (tree), &alloc);
+
+ if ((rect.x + rect.width) > (alloc.x + alloc.width))
+ rect.width = (alloc.x + alloc.width) - rect.x;
+
+ gtk_popover_set_relative_to (popreq->popover, GTK_WIDGET (tree));
+ gtk_popover_set_pointing_to (popreq->popover, &rect);
+ gtk_widget_show (GTK_WIDGET (popreq->popover));
+
+cleanup:
+ g_object_unref (popreq->self);
+ g_object_unref (popreq->popover);
+ g_free (popreq);
+}
+
+void
+gb_tree_node_show_popover (GbTreeNode *self,
+ GtkPopover *popover)
+{
+ GdkRectangle cell_area;
+ GdkRectangle visible_rect;
+ GbTree *tree;
+ PopupRequest *popreq;
+
+ g_return_if_fail (GB_IS_TREE_NODE (self));
+ g_return_if_fail (GTK_IS_POPOVER (popover));
+
+ tree = gb_tree_node_get_tree (self);
+ gtk_tree_view_get_visible_rect (GTK_TREE_VIEW (tree), &visible_rect);
+ gb_tree_node_get_area (self, &cell_area);
+ gtk_tree_view_convert_bin_window_to_tree_coords (GTK_TREE_VIEW (tree),
+ cell_area.x,
+ cell_area.y,
+ &cell_area.x,
+ &cell_area.y);
+
+ popreq = g_new0 (PopupRequest, 1);
+ popreq->self = g_object_ref (self);
+ popreq->popover = g_object_ref (popover);
+
+ /*
+ * If the node is not on screen, we need to animate until we get there.
+ */
+ if ((cell_area.y < visible_rect.y) ||
+ ((cell_area.y + cell_area.height) >
+ (visible_rect.y + visible_rect.height)))
+ {
+ GtkTreePath *path;
+
+ path = gb_tree_node_get_path (self);
+ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tree), path, NULL, FALSE, 0, 0);
+ gtk_tree_path_free (path);
+
+ /*
+ * FIXME: Time period comes from gtk animation duration.
+ * Not curently available in pubic API.
+ * We need to be greater than the max timeout it
+ * could take to move, since we must have it
+ * on screen by then.
+ *
+ * One alternative might be to check the result
+ * and if we are still not on screen, then just
+ * pin it to a row-height from the top or bottom.
+ */
+ g_timeout_add (300,
+ gb_tree_node_show_popover_timeout_cb,
+ popreq);
+ }
+ else
+ {
+ gb_tree_node_show_popover_timeout_cb (popreq);
+ }
+}
diff --git a/src/tree/gb-tree-node.h b/src/tree/gb-tree-node.h
index b6aae49..c0394d2 100644
--- a/src/tree/gb-tree-node.h
+++ b/src/tree/gb-tree-node.h
@@ -78,6 +78,8 @@ void gb_tree_node_get_area (GbTreeNode *node,
GdkRectangle *area);
void gb_tree_node_rebuild (GbTreeNode *node);
gboolean gb_tree_node_get_expanded (GbTreeNode *node);
+void gb_tree_node_show_popover (GbTreeNode *node,
+ GtkPopover *popover);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]