[gtksourceview/wip/chergert/hoverers] wip on hover providers




commit 0e6f2842a6772a22e51f4f984d6e74f854b58d4c
Author: Christian Hergert <chergert redhat com>
Date:   Mon Mar 8 16:13:14 2021 -0800

    wip on hover providers

 gtksourceview/gtksource.h                     |   4 +
 gtksourceview/gtksourcehover-private.h        |  30 +++
 gtksourceview/gtksourcehover.c                | 126 +++++++++++
 gtksourceview/gtksourcehover.h                |  46 ++++
 gtksourceview/gtksourcehovercontext-private.h |  44 ++++
 gtksourceview/gtksourcehovercontext.c         | 305 ++++++++++++++++++++++++++
 gtksourceview/gtksourcehovercontext.h         |  51 +++++
 gtksourceview/gtksourcehoverdisplay.c         | 101 +++++++++
 gtksourceview/gtksourcehoverdisplay.h         |  53 +++++
 gtksourceview/gtksourcehoverprovider.c        | 102 +++++++++
 gtksourceview/gtksourcehoverprovider.h        |  70 ++++++
 gtksourceview/gtksourcetypes.h                |   4 +
 gtksourceview/meson.build                     |   8 +
 13 files changed, 944 insertions(+)
---
diff --git a/gtksourceview/gtksource.h b/gtksourceview/gtksource.h
index 31942337..45820372 100644
--- a/gtksourceview/gtksource.h
+++ b/gtksourceview/gtksource.h
@@ -34,6 +34,10 @@
 #include "gtksourcegutterrenderer.h"
 #include "gtksourcegutterrenderertext.h"
 #include "gtksourcegutterrendererpixbuf.h"
+#include "gtksourcehover.h"
+#include "gtksourcehovercontext.h"
+#include "gtksourcehoverdisplay.h"
+#include "gtksourcehoverprovider.h"
 #include "gtksourceinit.h"
 #include "gtksourcelanguage.h"
 #include "gtksourcelanguagemanager.h"
diff --git a/gtksourceview/gtksourcehover-private.h b/gtksourceview/gtksourcehover-private.h
new file mode 100644
index 00000000..ad13eddb
--- /dev/null
+++ b/gtksourceview/gtksourcehover-private.h
@@ -0,0 +1,30 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2021 Christian Hergert <chergert redhat com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#pragma once
+
+#include "gtksourcehover.h"
+
+G_BEGIN_DECLS
+
+GtkSourceHover *_gtk_source_hover_new (GtkSourceView *view);
+
+G_END_DECLS
diff --git a/gtksourceview/gtksourcehover.c b/gtksourceview/gtksourcehover.c
new file mode 100644
index 00000000..9cff9e16
--- /dev/null
+++ b/gtksourceview/gtksourcehover.c
@@ -0,0 +1,126 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2021 Christian Hergert <chergert redhat com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "config.h"
+
+#include "gtksourceassistant-private.h"
+#include "gtksourcehover-private.h"
+#include "gtksourcehovercontext.h"
+#include "gtksourcehoverprovider.h"
+#include "gtksourceview.h"
+
+struct _GtkSourceHover
+{
+  GObject             parent_instance;
+  GtkSourceView      *view;
+  GPtrArray          *providers;
+  GtkSourceAssistant *assistant;
+};
+
+G_DEFINE_TYPE (GtkSourceHover, gtk_source_hover, G_TYPE_OBJECT)
+
+static void
+gtk_source_hover_dispose (GObject *object)
+{
+       GtkSourceHover *self = (GtkSourceHover *)object;
+
+       self->view = NULL;
+
+       if (self->providers->len > 0)
+       {
+               g_ptr_array_remove_range (self->providers, 0, self->providers->len);
+       }
+
+       G_OBJECT_CLASS (gtk_source_hover_parent_class)->dispose (object);
+}
+
+static void
+gtk_source_hover_finalize (GObject *object)
+{
+       GtkSourceHover *self = (GtkSourceHover *)object;
+
+       g_clear_pointer (&self->providers, g_ptr_array_unref);
+
+       G_OBJECT_CLASS (gtk_source_hover_parent_class)->finalize (object);
+}
+
+static void
+gtk_source_hover_class_init (GtkSourceHoverClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->dispose = gtk_source_hover_dispose;
+       object_class->finalize = gtk_source_hover_finalize;
+}
+
+static void
+gtk_source_hover_init (GtkSourceHover *self)
+{
+       self->providers = g_ptr_array_new_with_free_func (g_object_unref);
+}
+
+GtkSourceHover *
+_gtk_source_hover_new (GtkSourceView *view)
+{
+       GtkSourceHover *self;
+
+       g_return_val_if_fail (GTK_SOURCE_IS_VIEW (view), NULL);
+
+       self = g_object_new (GTK_SOURCE_TYPE_HOVER, NULL);
+       self->view = view;
+
+       return self;
+}
+
+void
+gtk_source_hover_add_provider (GtkSourceHover         *self,
+                               GtkSourceHoverProvider *provider)
+{
+       g_return_if_fail (GTK_SOURCE_IS_HOVER (self));
+       g_return_if_fail (GTK_SOURCE_IS_HOVER_PROVIDER (provider));
+
+       for (guint i = 0; i < self->providers->len; i++)
+       {
+               if (g_ptr_array_index (self->providers, i) == (gpointer)provider)
+               {
+                       return;
+               }
+       }
+
+       g_ptr_array_add (self->providers, g_object_ref (provider));
+}
+
+void
+gtk_source_hover_remove_provider (GtkSourceHover         *self,
+                                  GtkSourceHoverProvider *provider)
+{
+       g_return_if_fail (GTK_SOURCE_IS_HOVER (self));
+       g_return_if_fail (GTK_SOURCE_IS_HOVER_PROVIDER (provider));
+
+       for (guint i = 0; i < self->providers->len; i++)
+       {
+               if (g_ptr_array_index (self->providers, i) == (gpointer)provider)
+               {
+                       g_ptr_array_remove_index (self->providers, i);
+                       return;
+               }
+       }
+}
diff --git a/gtksourceview/gtksourcehover.h b/gtksourceview/gtksourcehover.h
new file mode 100644
index 00000000..56d94b78
--- /dev/null
+++ b/gtksourceview/gtksourcehover.h
@@ -0,0 +1,46 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2021 Christian Hergert <chergert redhat com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#pragma once
+
+#if !defined (GTK_SOURCE_H_INSIDE) && !defined (GTK_SOURCE_COMPILATION)
+# error "Only <gtksourceview/gtksource.h> can be included directly."
+#endif
+
+#include <glib-object.h>
+
+#include "gtksourcetypes.h"
+
+G_BEGIN_DECLS
+
+#define GTK_SOURCE_TYPE_HOVER (gtk_source_hover_get_type())
+
+GTK_SOURCE_AVAILABLE_IN_5_0
+G_DECLARE_FINAL_TYPE (GtkSourceHover, gtk_source_hover, GTK_SOURCE, HOVER, GObject)
+
+GTK_SOURCE_AVAILABLE_IN_5_0
+void gtk_source_hover_add_provider    (GtkSourceHover         *self,
+                                       GtkSourceHoverProvider *provider);
+GTK_SOURCE_AVAILABLE_IN_5_0
+void gtk_source_hover_remove_provider (GtkSourceHover         *self,
+                                       GtkSourceHoverProvider *provider);
+
+G_END_DECLS
diff --git a/gtksourceview/gtksourcehovercontext-private.h b/gtksourceview/gtksourcehovercontext-private.h
new file mode 100644
index 00000000..3e19b69c
--- /dev/null
+++ b/gtksourceview/gtksourcehovercontext-private.h
@@ -0,0 +1,44 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2021 Christian Hergert <chergert redhat com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#pragma once
+
+#include "gtksourcehovercontext.h"
+
+G_BEGIN_DECLS
+
+GtkSourceHoverContext *_gtk_source_hover_context_new            (GtkSourceView           *view,
+                                                                 const GtkTextIter       *begin,
+                                                                 const GtkTextIter       *end,
+                                                                 const GtkTextIter       *location);
+void                  _gtk_source_hover_context_add_provider    (GtkSourceHoverContext   *self,
+                                                                 GtkSourceHoverProvider  *provider);
+void                  _gtk_source_hover_context_populate_async  (GtkSourceHoverContext   *self,
+                                                                 GtkSourceHoverDisplay   *display,
+                                                                 GCancellable            *cancellable,
+                                                                 GAsyncReadyCallback      callback,
+                                                                 gpointer                 user_data);
+gboolean              _gtk_source_hover_context_populate_finish (GtkSourceHoverContext   *self,
+                                                                 GAsyncResult            *result,
+                                                                 GError                 **error);
+
+
+G_END_DECLS
diff --git a/gtksourceview/gtksourcehovercontext.c b/gtksourceview/gtksourcehovercontext.c
new file mode 100644
index 00000000..97d5990b
--- /dev/null
+++ b/gtksourceview/gtksourcehovercontext.c
@@ -0,0 +1,305 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2021 Christian Hergert <chergert redhat com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "config.h"
+
+#include "gtksourcebuffer.h"
+#include "gtksourcehovercontext-private.h"
+#include "gtksourcehoverdisplay.h"
+#include "gtksourcehoverprovider.h"
+#include "gtksourceview.h"
+
+struct _GtkSourceHoverContext
+{
+       GObject          parent_instance;
+
+       GtkSourceView   *view;
+       GtkSourceBuffer *buffer;
+
+       GPtrArray       *providers;
+
+       GtkTextMark     *begin;
+       GtkTextMark     *end;
+       GtkTextMark     *location;
+};
+
+G_DEFINE_TYPE (GtkSourceHoverContext, gtk_source_hover_context, G_TYPE_OBJECT)
+
+typedef struct
+{
+       guint n_active;
+} Populate;
+
+static void
+gtk_source_hover_context_dispose (GObject *object)
+{
+       GtkSourceHoverContext *self = (GtkSourceHoverContext *)object;
+
+       if (self->buffer != NULL)
+       {
+               if (self->begin != NULL)
+                       gtk_text_buffer_delete_mark (GTK_TEXT_BUFFER (self->buffer), self->begin);
+
+               if (self->end != NULL)
+                       gtk_text_buffer_delete_mark (GTK_TEXT_BUFFER (self->buffer), self->end);
+
+               if (self->location != NULL)
+                       gtk_text_buffer_delete_mark (GTK_TEXT_BUFFER (self->buffer), self->location);
+       }
+
+       g_clear_object (&self->begin);
+       g_clear_object (&self->end);
+       g_clear_object (&self->location);
+
+       if (self->providers->len > 0)
+       {
+               g_ptr_array_remove_range (self->providers, 0, self->providers->len);
+       }
+
+       g_clear_weak_pointer (&self->buffer);
+       g_clear_weak_pointer (&self->view);
+
+       G_OBJECT_CLASS (gtk_source_hover_context_parent_class)->dispose (object);
+}
+
+static void
+gtk_source_hover_context_finalize (GObject *object)
+{
+       GtkSourceHoverContext *self = (GtkSourceHoverContext *)object;
+
+       g_clear_pointer (&self->providers, g_ptr_array_unref);
+
+       G_OBJECT_CLASS (gtk_source_hover_context_parent_class)->finalize (object);
+}
+
+static void
+gtk_source_hover_context_class_init (GtkSourceHoverContextClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->dispose = gtk_source_hover_context_dispose;
+       object_class->finalize = gtk_source_hover_context_finalize;
+}
+
+static void
+gtk_source_hover_context_init (GtkSourceHoverContext *self)
+{
+       self->providers = g_ptr_array_new_with_free_func (g_object_unref);
+}
+
+void
+_gtk_source_hover_context_add_provider (GtkSourceHoverContext  *self,
+                                        GtkSourceHoverProvider *provider)
+{
+       g_return_if_fail (GTK_SOURCE_IS_HOVER_CONTEXT (self));
+       g_return_if_fail (GTK_SOURCE_IS_HOVER_PROVIDER (provider));
+
+       for (guint i = 0; i < self->providers->len; i++)
+       {
+               if (g_ptr_array_index (self->providers, i) == (gpointer)provider)
+               {
+                       return;
+               }
+       }
+
+       g_ptr_array_add (self->providers, g_object_ref (provider));
+}
+
+/**
+ * gtk_source_hover_context_get_view:
+ *
+ * Returns: (transfer none): the #GtkSourceView that owns the context
+ */
+GtkSourceView *
+gtk_source_hover_context_get_view (GtkSourceHoverContext *self)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_HOVER_CONTEXT (self), NULL);
+
+       return self->view;
+}
+
+/**
+ * gtk_source_hover_context_get_buffer:
+ *
+ * A convenience function to get the buffer.
+ *
+ * Returns: (transfer none): The #GtkSourceBuffer for the view
+ */
+GtkSourceBuffer *
+gtk_source_hover_context_get_buffer (GtkSourceHoverContext *self)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_HOVER_CONTEXT (self), NULL);
+       g_return_val_if_fail (self->view != NULL, NULL);
+
+       return GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->view)));
+}
+
+GtkSourceHoverContext *
+_gtk_source_hover_context_new (GtkSourceView     *view,
+                              const GtkTextIter *begin,
+                              const GtkTextIter *end,
+                              const GtkTextIter *location)
+{
+       GtkSourceHoverContext *self;
+       GtkSourceBuffer *buffer;
+
+       g_return_val_if_fail (GTK_SOURCE_IS_VIEW (view), NULL);
+       g_return_val_if_fail (begin != NULL, NULL);
+       g_return_val_if_fail (end != NULL, NULL);
+       g_return_val_if_fail (location != NULL, NULL);
+
+       buffer = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
+       self = g_object_new (GTK_SOURCE_TYPE_VIEW, NULL);
+
+       g_set_weak_pointer (&self->view, view);
+       g_set_weak_pointer (&self->buffer, buffer);
+
+       return self;
+}
+
+static void
+gtk_source_hover_context_populate_cb (GObject      *object,
+                                      GAsyncResult *result,
+                                      gpointer      user_data)
+{
+       GtkSourceHoverProvider *provider = (GtkSourceHoverProvider *)object;
+       GTask *task = user_data;
+       Populate *state;
+       GError *error = NULL;
+
+       g_assert (GTK_SOURCE_IS_HOVER_PROVIDER (provider));
+       g_assert (G_IS_ASYNC_RESULT (result));
+       g_assert (G_IS_TASK (task));
+
+       state = g_task_get_task_data (task);
+
+       if (!gtk_source_hover_provider_populate_finish (provider, result, &error))
+       {
+               if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
+                   !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
+               {
+                       g_debug ("%s population failed", error->message);
+               }
+
+               g_clear_error (&error);
+       }
+
+       if (--state->n_active == 0)
+       {
+               g_task_return_boolean (task, TRUE);
+       }
+
+       g_object_unref (task);
+}
+
+void
+_gtk_source_hover_context_populate_async (GtkSourceHoverContext *self,
+                                          GtkSourceHoverDisplay *display,
+                                          GCancellable          *cancellable,
+                                          GAsyncReadyCallback    callback,
+                                          gpointer               user_data)
+{
+       Populate *state;
+       GTask *task;
+
+       g_return_if_fail (GTK_SOURCE_IS_HOVER_CONTEXT (self));
+       g_return_if_fail (GTK_SOURCE_IS_HOVER_DISPLAY (display));
+       g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+       state = g_new0 (Populate, 1);
+       state->n_active = self->providers->len;
+
+       task = g_task_new (self, cancellable, callback, user_data);
+       g_task_set_source_tag (task, _gtk_source_hover_context_populate_async);
+       g_task_set_task_data (task, state, g_free);
+
+       if (g_task_return_error_if_cancelled (task))
+       {
+               /* Do nothing */
+       }
+       else if (self->providers->len  == 0)
+       {
+               g_task_return_boolean (task, TRUE);
+       }
+       else
+       {
+               for (guint i = 0; i < self->providers->len; i++)
+               {
+                       GtkSourceHoverProvider *provider = g_ptr_array_index (self->providers, i);
+
+                       g_assert (GTK_SOURCE_IS_HOVER_PROVIDER (provider));
+
+                       gtk_source_hover_provider_populate_async (provider,
+                                                                 self,
+                                                                 display,
+                                                                 cancellable,
+                                                                 gtk_source_hover_context_populate_cb,
+                                                                 g_object_ref (task));
+               }
+       }
+
+       g_object_unref (task);
+}
+
+gboolean
+_gtk_source_hover_context_populate_finish (GtkSourceHoverContext  *self,
+                                           GAsyncResult           *result,
+                                           GError                **error)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_HOVER_CONTEXT (self), FALSE);
+       g_return_val_if_fail (G_IS_TASK (result), FALSE);
+
+       return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+gboolean
+gtk_source_hover_context_get_iter (GtkSourceHoverContext *self,
+                                   GtkTextIter           *iter)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_HOVER_CONTEXT (self), FALSE);
+       g_return_val_if_fail (iter != NULL, FALSE);
+
+       if (self->buffer == NULL)
+               return FALSE;
+
+       gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (self->buffer), iter, self->location);
+
+       return TRUE;
+}
+
+gboolean
+gtk_source_hover_context_get_bounds (GtkSourceHoverContext *self,
+                                     GtkTextIter           *begin,
+                                     GtkTextIter           *end)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_HOVER_CONTEXT (self), FALSE);
+
+       if (self->buffer == NULL)
+               return FALSE;
+
+       if (begin != NULL)
+               gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (self->buffer), begin, self->begin);
+
+       if (end != NULL)
+               gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (self->buffer), end, self->end);
+
+       return TRUE;
+}
diff --git a/gtksourceview/gtksourcehovercontext.h b/gtksourceview/gtksourcehovercontext.h
new file mode 100644
index 00000000..aee8f535
--- /dev/null
+++ b/gtksourceview/gtksourcehovercontext.h
@@ -0,0 +1,51 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2021 Christian Hergert <chergert redhat com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#pragma once
+
+#if !defined (GTK_SOURCE_H_INSIDE) && !defined (GTK_SOURCE_COMPILATION)
+# error "Only <gtksourceview/gtksource.h> can be included directly."
+#endif
+
+#include <gtk/gtk.h>
+
+#include "gtksourcetypes.h"
+
+G_BEGIN_DECLS
+
+#define GTK_SOURCE_TYPE_HOVER_CONTEXT (gtk_source_hover_context_get_type())
+
+GTK_SOURCE_AVAILABLE_IN_5_0
+G_DECLARE_FINAL_TYPE (GtkSourceHoverContext, gtk_source_hover_context, GTK_SOURCE, HOVER_CONTEXT, GObject)
+
+GTK_SOURCE_AVAILABLE_IN_5_0
+GtkSourceView   *gtk_source_hover_context_get_view   (GtkSourceHoverContext *self);
+GTK_SOURCE_AVAILABLE_IN_5_0
+GtkSourceBuffer *gtk_source_hover_context_get_buffer (GtkSourceHoverContext *self);
+GTK_SOURCE_AVAILABLE_IN_5_0
+gboolean         gtk_source_hover_context_get_iter   (GtkSourceHoverContext *self,
+                                                      GtkTextIter           *iter);
+GTK_SOURCE_AVAILABLE_IN_5_0
+gboolean         gtk_source_hover_context_get_bounds (GtkSourceHoverContext *self,
+                                                      GtkTextIter           *begin,
+                                                      GtkTextIter           *end);
+
+G_END_DECLS
diff --git a/gtksourceview/gtksourcehoverdisplay.c b/gtksourceview/gtksourcehoverdisplay.c
new file mode 100644
index 00000000..c48ac56e
--- /dev/null
+++ b/gtksourceview/gtksourcehoverdisplay.c
@@ -0,0 +1,101 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2021 Christian Hergert <chergert redhat com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "config.h"
+
+#include "gtksourcehoverdisplay.h"
+
+struct _GtkSourceHoverDisplay
+{
+       GtkWidget parent_instance;
+
+       GtkBox *vbox;
+};
+
+G_DEFINE_TYPE (GtkSourceHoverDisplay, gtk_source_hover_display, GTK_TYPE_WIDGET)
+
+static void
+gtk_source_hover_display_dispose (GObject *object)
+{
+       GtkSourceHoverDisplay *self = (GtkSourceHoverDisplay *)object;
+
+       g_clear_pointer ((GtkWidget **)&self->vbox, gtk_widget_unparent);
+
+       G_OBJECT_CLASS (gtk_source_hover_display_parent_class)->dispose (object);
+}
+
+static void
+gtk_source_hover_display_class_init (GtkSourceHoverDisplayClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+       GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+       object_class->dispose = gtk_source_hover_display_dispose;
+
+       gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
+}
+
+static void
+gtk_source_hover_display_init (GtkSourceHoverDisplay *self)
+{
+       self->vbox = g_object_new (GTK_TYPE_BOX, NULL);
+       gtk_widget_set_parent (GTK_WIDGET (self->vbox), GTK_WIDGET (self));
+}
+
+void
+gtk_source_hover_display_append (GtkSourceHoverDisplay *self,
+                                 GtkWidget             *child)
+{
+       g_return_if_fail (GTK_SOURCE_IS_HOVER_DISPLAY (self));
+       g_return_if_fail (GTK_IS_WIDGET (child));
+}
+
+void
+gtk_source_hover_display_prepend (GtkSourceHoverDisplay *self,
+                                  GtkWidget             *child)
+{
+       g_return_if_fail (GTK_SOURCE_IS_HOVER_DISPLAY (self));
+       g_return_if_fail (GTK_IS_WIDGET (child));
+}
+
+void
+gtk_source_hover_display_insert_after (GtkSourceHoverDisplay *self,
+                                       GtkWidget             *child,
+                                       GtkWidget             *sibling)
+{
+       g_return_if_fail (GTK_SOURCE_IS_HOVER_DISPLAY (self));
+       g_return_if_fail (GTK_IS_WIDGET (child));
+       g_return_if_fail (!sibling || GTK_IS_WIDGET (sibling));
+
+       if (sibling == NULL)
+       {
+               gtk_source_hover_display_append (self, child);
+       }
+}
+
+void
+gtk_source_hover_display_remove (GtkSourceHoverDisplay *self,
+                                 GtkWidget             *child)
+{
+       g_return_if_fail (GTK_SOURCE_IS_HOVER_DISPLAY (self));
+       g_return_if_fail (GTK_IS_WIDGET (child));
+       g_return_if_fail (gtk_widget_get_parent (child) == (GtkWidget *)self->vbox);
+}
diff --git a/gtksourceview/gtksourcehoverdisplay.h b/gtksourceview/gtksourcehoverdisplay.h
new file mode 100644
index 00000000..6a06b761
--- /dev/null
+++ b/gtksourceview/gtksourcehoverdisplay.h
@@ -0,0 +1,53 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2021 Christian Hergert <chergert redhat com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#pragma once
+
+#if !defined (GTK_SOURCE_H_INSIDE) && !defined (GTK_SOURCE_COMPILATION)
+# error "Only <gtksourceview/gtksource.h> can be included directly."
+#endif
+
+#include <gtk/gtk.h>
+
+#include "gtksourcetypes.h"
+
+G_BEGIN_DECLS
+
+#define GTK_SOURCE_TYPE_HOVER_DISPLAY (gtk_source_hover_display_get_type())
+
+GTK_SOURCE_AVAILABLE_IN_5_0
+G_DECLARE_FINAL_TYPE (GtkSourceHoverDisplay, gtk_source_hover_display, GTK_SOURCE, HOVER_DISPLAY, GtkWidget)
+
+GTK_SOURCE_AVAILABLE_IN_5_0
+void gtk_source_hover_display_append       (GtkSourceHoverDisplay *self,
+                                            GtkWidget             *child);
+GTK_SOURCE_AVAILABLE_IN_5_0
+void gtk_source_hover_display_prepend      (GtkSourceHoverDisplay *self,
+                                            GtkWidget             *child);
+GTK_SOURCE_AVAILABLE_IN_5_0
+void gtk_source_hover_display_insert_after (GtkSourceHoverDisplay *self,
+                                            GtkWidget             *child,
+                                            GtkWidget             *sibling);
+GTK_SOURCE_AVAILABLE_IN_5_0
+void gtk_source_hover_display_remove       (GtkSourceHoverDisplay *self,
+                                            GtkWidget             *child);
+
+G_END_DECLS
diff --git a/gtksourceview/gtksourcehoverprovider.c b/gtksourceview/gtksourcehoverprovider.c
new file mode 100644
index 00000000..fb25db59
--- /dev/null
+++ b/gtksourceview/gtksourcehoverprovider.c
@@ -0,0 +1,102 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2021 Christian Hergert <chergert redhat com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "config.h"
+
+#include "gtksourcehovercontext.h"
+#include "gtksourcehoverdisplay.h"
+#include "gtksourcehoverprovider.h"
+
+G_DEFINE_INTERFACE (GtkSourceHoverProvider, gtk_source_hover_provider, G_TYPE_OBJECT)
+
+static gboolean
+gtk_source_hover_provider_real_populate (GtkSourceHoverProvider  *provider,
+                                         GtkSourceHoverContext   *context,
+                                         GtkSourceHoverDisplay   *display,
+                                         GError                 **error)
+{
+       return TRUE;
+}
+
+static void
+gtk_source_hover_provider_real_populate_async (GtkSourceHoverProvider *provider,
+                                               GtkSourceHoverContext  *context,
+                                               GtkSourceHoverDisplay  *display,
+                                               GCancellable           *cancellable,
+                                               GAsyncReadyCallback     callback,
+                                               gpointer                user_data)
+{
+       GError *error = NULL;
+       GTask *task;
+
+       task = g_task_new (provider, cancellable, callback, user_data);
+       g_task_set_source_tag (task, gtk_source_hover_provider_real_populate_async);
+
+       if (!GTK_SOURCE_HOVER_PROVIDER_GET_IFACE (provider)->populate (provider, context, display, &error))
+               g_task_return_error (task, g_steal_pointer (&error));
+       else
+               g_task_return_boolean (task, TRUE);
+
+       g_object_unref (task);
+}
+
+static gboolean
+gtk_source_hover_provider_real_populate_finish (GtkSourceHoverProvider  *self,
+                                                GAsyncResult            *result,
+                                                GError                 **error)
+{
+       return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+static void
+gtk_source_hover_provider_default_init (GtkSourceHoverProviderInterface *iface)
+{
+       iface->populate_async = gtk_source_hover_provider_real_populate_async;
+       iface->populate_finish = gtk_source_hover_provider_real_populate_finish;
+       iface->populate = gtk_source_hover_provider_real_populate;
+}
+
+void
+gtk_source_hover_provider_populate_async (GtkSourceHoverProvider *provider,
+                                          GtkSourceHoverContext  *context,
+                                          GtkSourceHoverDisplay  *display,
+                                          GCancellable           *cancellable,
+                                          GAsyncReadyCallback     callback,
+                                          gpointer                user_data)
+{
+       g_return_if_fail (GTK_SOURCE_IS_HOVER_PROVIDER (provider));
+       g_return_if_fail (GTK_SOURCE_IS_HOVER_CONTEXT (context));
+       g_return_if_fail (GTK_SOURCE_IS_HOVER_DISPLAY (display));
+       g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+       GTK_SOURCE_HOVER_PROVIDER_GET_IFACE (provider)->populate_async (provider, context, display, 
cancellable, callback, user_data);
+}
+
+gboolean
+gtk_source_hover_provider_populate_finish (GtkSourceHoverProvider  *provider,
+                                           GAsyncResult            *result,
+                                           GError                 **error)
+{
+       g_return_val_if_fail (GTK_SOURCE_IS_HOVER_PROVIDER (provider), FALSE);
+       g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+       return GTK_SOURCE_HOVER_PROVIDER_GET_IFACE (provider)->populate_finish (provider, result, error);
+}
diff --git a/gtksourceview/gtksourcehoverprovider.h b/gtksourceview/gtksourcehoverprovider.h
new file mode 100644
index 00000000..c662c0a2
--- /dev/null
+++ b/gtksourceview/gtksourcehoverprovider.h
@@ -0,0 +1,70 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2021 Christian Hergert <chergert redhat com>
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#pragma once
+
+#if !defined (GTK_SOURCE_H_INSIDE) && !defined (GTK_SOURCE_COMPILATION)
+# error "Only <gtksourceview/gtksource.h> can be included directly."
+#endif
+
+#include <gio/gio.h>
+
+#include "gtksourcetypes.h"
+
+G_BEGIN_DECLS
+
+#define GTK_SOURCE_TYPE_HOVER_PROVIDER (gtk_source_hover_provider_get_type())
+
+GTK_SOURCE_AVAILABLE_IN_5_0
+G_DECLARE_INTERFACE (GtkSourceHoverProvider, gtk_source_hover_provider, GTK_SOURCE, HOVER_PROVIDER, GObject)
+
+struct _GtkSourceHoverProviderInterface
+{
+       GTypeInterface parent_iface;
+
+       gboolean (*populate)        (GtkSourceHoverProvider  *self,
+                                    GtkSourceHoverContext   *context,
+                                    GtkSourceHoverDisplay   *display,
+                                    GError                 **error);
+       void     (*populate_async)  (GtkSourceHoverProvider  *self,
+                                    GtkSourceHoverContext   *context,
+                                    GtkSourceHoverDisplay   *display,
+                                    GCancellable            *cancellable,
+                                    GAsyncReadyCallback      callback,
+                                    gpointer                 user_data);
+       gboolean (*populate_finish) (GtkSourceHoverProvider  *self,
+                                    GAsyncResult            *result,
+                                    GError                 **error);
+};
+
+GTK_SOURCE_AVAILABLE_IN_5_0
+void     gtk_source_hover_provider_populate_async  (GtkSourceHoverProvider  *self,
+                                                    GtkSourceHoverContext   *context,
+                                                    GtkSourceHoverDisplay   *display,
+                                                    GCancellable            *cancellable,
+                                                    GAsyncReadyCallback      callback,
+                                                    gpointer                 user_data);
+GTK_SOURCE_AVAILABLE_IN_5_0
+gboolean gtk_source_hover_provider_populate_finish (GtkSourceHoverProvider  *self,
+                                                    GAsyncResult                 *result,
+                                                    GError                      **error);
+
+G_END_DECLS
diff --git a/gtksourceview/gtksourcetypes.h b/gtksourceview/gtksourcetypes.h
index 85156f61..6f1530cc 100644
--- a/gtksourceview/gtksourcetypes.h
+++ b/gtksourceview/gtksourcetypes.h
@@ -50,6 +50,10 @@ typedef struct _GtkSourceGutterLines               GtkSourceGutterLines;
 typedef struct _GtkSourceGutterRenderer            GtkSourceGutterRenderer;
 typedef struct _GtkSourceGutterRendererPixbuf      GtkSourceGutterRendererPixbuf;
 typedef struct _GtkSourceGutterRendererText        GtkSourceGutterRendererText;
+typedef struct _GtkSourceHover                     GtkSourceHover;
+typedef struct _GtkSourceHoverContext              GtkSourceHoverContext;
+typedef struct _GtkSourceHoverDisplay              GtkSourceHoverDisplay;
+typedef struct _GtkSourceHoverProvider             GtkSourceHoverProvider;
 typedef struct _GtkSourceLanguage                  GtkSourceLanguage;
 typedef struct _GtkSourceLanguageManager           GtkSourceLanguageManager;
 typedef struct _GtkSourceMap                       GtkSourceMap;
diff --git a/gtksourceview/meson.build b/gtksourceview/meson.build
index e19c9dc0..e5558c06 100644
--- a/gtksourceview/meson.build
+++ b/gtksourceview/meson.build
@@ -21,6 +21,10 @@ core_public_h = files([
   'gtksourcegutterrenderer.h',
   'gtksourcegutterrendererpixbuf.h',
   'gtksourcegutterrenderertext.h',
+  'gtksourcehover.h',
+  'gtksourcehovercontext.h',
+  'gtksourcehoverprovider.h',
+  'gtksourcehoverdisplay.h',
   'gtksourceinit.h',
   'gtksourcelanguage.h',
   'gtksourcelanguagemanager.h',
@@ -64,6 +68,10 @@ core_public_c = files([
   'gtksourcegutterrenderer.c',
   'gtksourcegutterrendererpixbuf.c',
   'gtksourcegutterrenderertext.c',
+  'gtksourcehover.c',
+  'gtksourcehovercontext.c',
+  'gtksourcehoverdisplay.c',
+  'gtksourcehoverprovider.c',
   'gtksourceinit.c',
   'gtksourcelanguage.c',
   'gtksourcelanguagemanager.c',


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