[gnome-builder] documentation-card: card showing relevant information about a library function



commit acf564fc6050c44fbe8d8f8408fe840be9eeab65
Author: Lucie Dvorakova <luci_dvorak me com>
Date:   Tue Aug 29 21:20:00 2017 +0000

    documentation-card: card showing relevant information about a library function
    
    https://bugzilla.gnome.org/show_bug.cgi?id=785854

 libide/documentation/ide-documentation-proposal.c  |   14 ++--
 libide/documentation/ide-documentation.c           |    6 +-
 .../devhelp/gbp-devhelp-documentation-provider.c   |    2 +-
 .../gbp-documentation-card-view-addin.c            |   96 +++++++++++++++++---
 .../documentation-card/gbp-documentation-card.c    |   64 ++++++--------
 .../documentation-card/gbp-documentation-card.h    |    5 +-
 6 files changed, 124 insertions(+), 63 deletions(-)
---
diff --git a/libide/documentation/ide-documentation-proposal.c 
b/libide/documentation/ide-documentation-proposal.c
index 04c9373..8b74c79 100644
--- a/libide/documentation/ide-documentation-proposal.c
+++ b/libide/documentation/ide-documentation-proposal.c
@@ -103,16 +103,16 @@ ide_documentation_proposal_set_text (IdeDocumentationProposal *self,
   g_return_if_fail (IDE_IS_DOCUMENTATION_PROPOSAL (self));
 
     if (g_strcmp0 (priv->text, text) != 0)
-    {
-      g_free (priv->text);
-      priv->text = g_strdup (text);
-      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_TEXT]);
-    }
+      {
+        g_free (priv->text);
+        priv->text = g_strdup (text);
+        g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_TEXT]);
+      }
 }
 
 void
-ide_documentation_proposal_set_uri  (IdeDocumentationProposal *self,
-                                     const gchar              *uri)
+ide_documentation_proposal_set_uri (IdeDocumentationProposal *self,
+                                    const gchar              *uri)
 {
   IdeDocumentationProposalPrivate *priv = ide_documentation_proposal_get_instance_private (self);
 
diff --git a/libide/documentation/ide-documentation.c b/libide/documentation/ide-documentation.c
index 97dea06..2798f91 100644
--- a/libide/documentation/ide-documentation.c
+++ b/libide/documentation/ide-documentation.c
@@ -97,9 +97,9 @@ ide_documentation_init (IdeDocumentation *self)
  * Returns: (transfer full): An #IdeDocumentationInfo
  */
 IdeDocumentationInfo *
-ide_documentation_get_info    (IdeDocumentation        *self,
-                               const gchar             *input,
-                               IdeDocumentationContext  context)
+ide_documentation_get_info (IdeDocumentation        *self,
+                            const gchar             *input,
+                            IdeDocumentationContext  context)
 {
   IdeDocumentationInfo *info;
 
diff --git a/plugins/devhelp/gbp-devhelp-documentation-provider.c 
b/plugins/devhelp/gbp-devhelp-documentation-provider.c
index aa420e3..90568d0 100644
--- a/plugins/devhelp/gbp-devhelp-documentation-provider.c
+++ b/plugins/devhelp/gbp-devhelp-documentation-provider.c
@@ -248,7 +248,7 @@ gbp_devhelp_documentation_provider_get_info (IdeDocumentationProvider *provider,
   if (parse_succ)
     {
       if (G_UNLIKELY (self->proposal == NULL))
-          return;
+        return;
 
       ide_documentation_info_take_proposal (info, g_steal_pointer (&self->proposal));
     }
diff --git a/plugins/documentation-card/gbp-documentation-card-view-addin.c 
b/plugins/documentation-card/gbp-documentation-card-view-addin.c
index aea5400..c8449cc 100644
--- a/plugins/documentation-card/gbp-documentation-card-view-addin.c
+++ b/plugins/documentation-card/gbp-documentation-card-view-addin.c
@@ -46,6 +46,64 @@ static void iface_init (IdeEditorViewAddinInterface *iface);
 G_DEFINE_TYPE_EXTENDED (GbpDocumentationCardViewAddin, gbp_documentation_card_view_addin, G_TYPE_OBJECT, 0,
                         G_IMPLEMENT_INTERFACE (IDE_TYPE_EDITOR_VIEW_ADDIN, iface_init))
 
+static void
+documentation_requested_cb (GbpDocumentationCardViewAddin *self,
+                            const gchar                   *word,
+                            IdeSourceView                 *source_view)
+{
+  IdeBuffer *buffer;
+  GtkSourceLanguage *lang;
+  IdeContext *context;
+  IdeDocumentation *doc;
+  IdeDocumentationContext doc_context;
+  g_autoptr(IdeDocumentationInfo) info = NULL;
+  GtkTextIter begin;
+  GtkTextIter end;
+  GdkRectangle begin_location;
+  GdkRectangle end_location;
+  gint x1, x2;
+  gint y1, y2;
+
+  g_assert (GBP_IS_DOCUMENTATION_CARD_VIEW_ADDIN (self));
+  g_assert (IDE_IS_SOURCE_VIEW (source_view));
+
+  buffer = ide_editor_view_get_buffer (self->editor_view);
+  if (buffer == NULL)
+    return;
+
+  context = ide_buffer_get_context (buffer);
+  doc = ide_context_get_documentation (context);
+
+  gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (buffer), &begin, &end);
+  gtk_text_view_get_iter_location (GTK_TEXT_VIEW (source_view), &begin, &begin_location);
+  gtk_text_view_get_iter_location (GTK_TEXT_VIEW (source_view), &end, &end_location);
+  gtk_text_view_buffer_to_window_coords (GTK_TEXT_VIEW (source_view), GTK_TEXT_WINDOW_WIDGET,
+                                         begin_location.x, begin_location.y, &x1, &y1);
+  gtk_text_view_buffer_to_window_coords (GTK_TEXT_VIEW (source_view), GTK_TEXT_WINDOW_WIDGET,
+                                         end_location.x, end_location.y, &x2, &y2);
+
+  lang = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (buffer));
+  if (lang == NULL)
+    return;
+
+  if (ide_str_equal0 (gtk_source_language_get_id (lang), "c"))
+    doc_context = IDE_DOCUMENTATION_CONTEXT_CARD_C;
+
+  if (g_strcmp0 (word, self->previous_text) != 0)
+    {
+      info = ide_documentation_get_info (doc, word, doc_context);
+      if (ide_documentation_info_get_size (info) == 0)
+        return;
+
+      gbp_documentation_card_set_info (self->popover, info);
+      g_free (self->previous_text);
+      self->previous_text = g_strdup (word);
+    }
+
+  gtk_popover_set_modal (GTK_POPOVER (self->popover), TRUE);
+  gbp_documentation_card_popup (self->popover, (x1 + x2) / 2, y1);
+}
+
 static gboolean
 within_space (GbpDocumentationCardViewAddin *self,
               guint                          x,
@@ -67,7 +125,7 @@ unichar_issymbol (gunichar ch)
 static gboolean
 search_document_cb (gpointer data)
 {
-  GbpDocumentationCardViewAddin *self = GBP_DOCUMENTATION_CARD_VIEW_ADDIN  (data);
+  GbpDocumentationCardViewAddin *self = GBP_DOCUMENTATION_CARD_VIEW_ADDIN (data);
   IdeBuffer *buffer;
   IdeSourceView *source_view;
   GtkSourceLanguage *lang;
@@ -85,6 +143,7 @@ search_document_cb (gpointer data)
   g_autoptr(IdeDocumentationInfo) info = NULL;
   g_autofree gchar *selected_text = NULL;
   gint x, y;
+  gint buf_x, buf_y;
 
   self->timeout_id = 0;
 
@@ -96,7 +155,7 @@ search_document_cb (gpointer data)
     {
       if (self->poped_up)
         self->poped_up = FALSE;
-      gbp_documentation_card_popdown (self->popover);
+      gtk_popover_popdown (GTK_POPOVER (self->popover));
       return G_SOURCE_REMOVE;
     }
 
@@ -107,7 +166,7 @@ search_document_cb (gpointer data)
       if (within_space (self, x, y))
         return G_SOURCE_REMOVE;
       self->poped_up = FALSE;
-      gbp_documentation_card_popdown (self->popover);
+      gtk_popover_popdown (GTK_POPOVER (self->popover));
       return G_SOURCE_REMOVE;
     }
 
@@ -129,14 +188,14 @@ search_document_cb (gpointer data)
   if (lang == NULL)
     return G_SOURCE_REMOVE;
 
-  if (ide_str_equal0 (gtk_source_language_get_id(lang), "c"))
+  if (ide_str_equal0 (gtk_source_language_get_id (lang), "c"))
     doc_context = IDE_DOCUMENTATION_CONTEXT_CARD_C;
   else
     return G_SOURCE_REMOVE;
 
-  gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (source_view), GTK_TEXT_WINDOW_WIDGET, x, y, &x, &y);
-  gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (source_view), &end, x, y);
-  gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (source_view), &begin, x, y);
+  gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (source_view), GTK_TEXT_WINDOW_WIDGET, x, y, &buf_x, 
&buf_y);
+  gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (source_view), &end, buf_x, buf_y);
+  gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (source_view), &begin, buf_x, buf_y);
 
   while (unichar_issymbol (gtk_text_iter_get_char (&begin)))
     if (!gtk_text_iter_backward_char (&begin))
@@ -160,7 +219,7 @@ search_document_cb (gpointer data)
       self->previous_text = g_steal_pointer (&selected_text);
     }
 
-  gbp_documentation_card_popup (self->popover);
+  gbp_documentation_card_popup (self->popover, x, y);
   self->poped_up = TRUE;
 
   return G_SOURCE_REMOVE;
@@ -171,7 +230,7 @@ search_document_cb (gpointer data)
 static gboolean
 motion_notify_event_cb (gpointer data)
 {
-  GbpDocumentationCardViewAddin *self = GBP_DOCUMENTATION_CARD_VIEW_ADDIN  (data);
+  GbpDocumentationCardViewAddin *self = GBP_DOCUMENTATION_CARD_VIEW_ADDIN (data);
 
   ide_clear_source (&self->timeout_id);
 
@@ -208,6 +267,7 @@ gbp_documentation_card_view_addin_load (IdeEditorViewAddin *addin,
                     "destroy",
                     G_CALLBACK (gtk_widget_destroyed),
                     &self->popover);
+
   self->motion_handler_id =
     g_signal_connect_object (view,
                             "motion-notify-event",
@@ -215,6 +275,11 @@ gbp_documentation_card_view_addin_load (IdeEditorViewAddin *addin,
                             self,
                             G_CONNECT_SWAPPED);
 
+  g_signal_connect_object (ide_editor_view_get_view (view),
+                           "documentation-requested",
+                           G_CALLBACK (documentation_requested_cb),
+                           addin,
+                           G_CONNECT_SWAPPED);
 }
 
 static void
@@ -222,21 +287,26 @@ gbp_documentation_card_view_addin_unload (IdeEditorViewAddin *addin,
                                           IdeEditorView      *view)
 {
   GbpDocumentationCardViewAddin *self;
+  IdeSourceView *source_view;
 
   g_assert (GBP_IS_DOCUMENTATION_CARD_VIEW_ADDIN (addin));
   g_assert (IDE_IS_EDITOR_VIEW (view));
 
   self = GBP_DOCUMENTATION_CARD_VIEW_ADDIN (addin);
+  source_view = ide_editor_view_get_view (view);
 
   ide_clear_source (&self->timeout_id);
   ide_clear_signal_handler (self->editor_view, &self->motion_handler_id);
-  g_clear_pointer (&self->previous_text, g_free);
-
-  if (self->popover != NULL)
-    gtk_widget_destroy (GTK_WIDGET (self->popover));
 
+  g_free (self->previous_text);
+  gtk_widget_destroy (GTK_WIDGET (self->popover));
+  self->popover = NULL;
   self->editor_view = NULL;
 
+  if (source_view != NULL)
+    g_signal_handlers_disconnect_by_func (source_view,
+                                          G_CALLBACK (documentation_requested_cb),
+                                          addin);
 }
 
 static void
diff --git a/plugins/documentation-card/gbp-documentation-card.c 
b/plugins/documentation-card/gbp-documentation-card.c
index 231bbc4..750bdc7 100644
--- a/plugins/documentation-card/gbp-documentation-card.c
+++ b/plugins/documentation-card/gbp-documentation-card.c
@@ -43,30 +43,6 @@ struct _GbpDocumentationCard
 
 G_DEFINE_TYPE (GbpDocumentationCard, gbp_documentation_card, GTK_TYPE_POPOVER)
 
-static gboolean
-card_popup (GbpDocumentationCard *self)
-{
-  GdkRectangle rec = {1, 1, 1, 1};
-
-  gdk_window_get_device_position (self->window, self->pointer, &rec.x, &rec.y, NULL);
-  gtk_popover_set_pointing_to (GTK_POPOVER (self), &rec);
-  gtk_popover_popup (GTK_POPOVER (self));
-
-  return FALSE;
-}
-
-static gboolean
-card_popdown (GbpDocumentationCard *self)
-{
-  gtk_popover_popdown (GTK_POPOVER (self));
-  gtk_popover_set_modal (GTK_POPOVER (self), FALSE);
-
-  gtk_widget_set_visible (GTK_WIDGET (self->text), FALSE);
-  gtk_widget_set_visible (GTK_WIDGET (self->button), TRUE);
-
-  return FALSE;
-}
-
 static void
 gbp_documentation_card__button_clicked (GbpDocumentationCard *self,
                                         GtkButton            *button)
@@ -82,16 +58,31 @@ gbp_documentation_card__button_clicked (GbpDocumentationCard *self,
 
 }
 
+void
+gbp_documentation_card_closed (GtkPopover *popover)
+{
+  GbpDocumentationCard *self = (GbpDocumentationCard *)popover;
+
+  g_assert (GBP_IS_DOCUMENTATION_CARD (self));
+
+  gtk_popover_set_modal (popover, FALSE);
+
+  gtk_widget_set_visible (GTK_WIDGET (self->text), FALSE);
+  gtk_widget_set_visible (GTK_WIDGET (self->button), TRUE);
+}
+
 static void
 gbp_documentation_card_class_init (GbpDocumentationCardClass *klass)
 {
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+  GtkPopoverClass *popover_class = GTK_POPOVER_CLASS (klass);
 
   gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/builder/plugins/documentation-card/gbp-documentation-card.ui");
   gtk_widget_class_bind_template_child (widget_class, GbpDocumentationCard, button);
   gtk_widget_class_bind_template_child (widget_class, GbpDocumentationCard, header);
   gtk_widget_class_bind_template_child (widget_class, GbpDocumentationCard, text);
 
+  popover_class->closed = gbp_documentation_card_closed;
 }
 
 static void
@@ -123,24 +114,23 @@ gbp_documentation_card_set_info (GbpDocumentationCard *self,
 }
 
 void
-gbp_documentation_card_popup (GbpDocumentationCard *self)
+gbp_documentation_card_popup (GbpDocumentationCard *self,
+                              gint x,
+                              gint y)
 {
-  GdkDisplay *display;
+  GdkRectangle rec;
 
   g_return_if_fail (GBP_IS_DOCUMENTATION_CARD (self));
 
-  self->window = gtk_widget_get_parent_window (gtk_popover_get_relative_to (GTK_POPOVER (self)));
-  display = gdk_window_get_display (self->window);
-  self->pointer = gdk_seat_get_pointer (gdk_display_get_default_seat (display));
+  if (x < 0 || y < 0)
+    return;
 
-  card_popup (self);
-}
+  rec.x = x;
+  rec.y = y;
+  rec.width = 1;
+  rec.height = 1;
 
-void
-gbp_documentation_card_popdown (GbpDocumentationCard *self)
-{
-  g_return_if_fail (GBP_IS_DOCUMENTATION_CARD (self));
-
-  card_popdown (self);
+  gtk_popover_set_pointing_to (GTK_POPOVER (self), &rec);
+  gtk_popover_popup (GTK_POPOVER (self));
 }
 
diff --git a/plugins/documentation-card/gbp-documentation-card.h 
b/plugins/documentation-card/gbp-documentation-card.h
index 7b462a5..658b5b1 100644
--- a/plugins/documentation-card/gbp-documentation-card.h
+++ b/plugins/documentation-card/gbp-documentation-card.h
@@ -29,8 +29,9 @@ G_DECLARE_FINAL_TYPE (GbpDocumentationCard, gbp_documentation_card, GBP, DOCUMEN
 
 void gbp_documentation_card_set_info (GbpDocumentationCard *self,
                                       IdeDocumentationInfo *info);
-void gbp_documentation_card_popup    (GbpDocumentationCard *self);
-void gbp_documentation_card_popdown  (GbpDocumentationCard *self);
+void gbp_documentation_card_popup    (GbpDocumentationCard *self,
+                                      gint x,
+                                      gint y);
 G_END_DECLS
 
 #endif /* GB_DOCUMENTATION_CARD_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]