[gtksourceview/wip/chergert/hoverers: 10/10] wip on hover providers
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/chergert/hoverers: 10/10] wip on hover providers
- Date: Tue, 9 Mar 2021 02:58:02 +0000 (UTC)
commit 4d5e18cb03728e4e03b83c771d53fd25fbe90323
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 | 236 ++++++++++++++++++++
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/gtksourceview.c | 33 +++
gtksourceview/gtksourceview.h | 2 +
gtksourceview/meson.build | 8 +
15 files changed, 1089 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..9b8b6e79
--- /dev/null
+++ b/gtksourceview/gtksourcehover.c
@@ -0,0 +1,236 @@
+/*
+ * 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 "gtksourcesignalgroup-private.h"
+#include "gtksourceview.h"
+
+struct _GtkSourceHover
+{
+ GObject parent_instance;
+
+ GtkSourceView *view;
+ GtkSourceAssistant *assistant;
+
+ GPtrArray *providers;
+
+ guint delay_display_source;
+ guint dismiss_source;
+};
+
+G_DEFINE_TYPE (GtkSourceHover, gtk_source_hover, G_TYPE_OBJECT)
+
+static gboolean
+on_key_pressed_cb (GtkSourceHover *hover,
+ guint keyval,
+ guint keycode,
+ GdkModifierType state,
+ GtkEventControllerKey *controller)
+{
+ g_assert (GTK_SOURCE_IS_HOVER (hover));
+ g_assert (GTK_IS_EVENT_CONTROLLER_KEY (controller));
+
+ return GDK_EVENT_PROPAGATE;
+}
+
+static void
+on_focus_enter_cb (GtkSourceHover *hover,
+ GtkEventControllerFocus *controller)
+{
+ g_assert (GTK_SOURCE_IS_HOVER (hover));
+ g_assert (GTK_IS_EVENT_CONTROLLER_FOCUS (controller));
+
+}
+
+static void
+on_focus_leave_cb (GtkSourceHover *hover,
+ GtkEventControllerFocus *controller)
+{
+ g_assert (GTK_SOURCE_IS_HOVER (hover));
+ g_assert (GTK_IS_EVENT_CONTROLLER_FOCUS (controller));
+
+}
+
+static void
+on_motion_cb (GtkSourceHover *hover,
+ double x,
+ double y,
+ GtkEventControllerMotion *controller)
+{
+ g_assert (GTK_SOURCE_IS_HOVER (hover));
+ g_assert (GTK_IS_EVENT_CONTROLLER_MOTION (controller));
+
+}
+
+static gboolean
+on_scroll_cb (GtkSourceHover *hover,
+ double dx,
+ double dy,
+ GtkEventControllerScroll *controller)
+{
+ g_assert (GTK_SOURCE_IS_HOVER (hover));
+ g_assert (GTK_IS_EVENT_CONTROLLER_SCROLL (controller));
+
+ return GDK_EVENT_PROPAGATE;
+}
+
+static void
+gtk_source_hover_dispose (GObject *object)
+{
+ GtkSourceHover *self = (GtkSourceHover *)object;
+
+ g_clear_pointer (&self->assistant, _gtk_source_assistant_destroy);
+
+ g_clear_weak_pointer (&self->view);
+
+ g_clear_handle_id (&self->delay_display_source, g_source_remove);
+ g_clear_handle_id (&self->dismiss_source, g_source_remove);
+
+ 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_assert (self->delay_display_source == 0);
+ g_assert (self->dismiss_source == 0);
+
+ 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;
+ GtkEventController *focus;
+ GtkEventController *key;
+ GtkEventController *motion;
+ GtkEventController *scroll;
+
+ g_return_val_if_fail (GTK_SOURCE_IS_VIEW (view), NULL);
+
+ self = g_object_new (GTK_SOURCE_TYPE_HOVER, NULL);
+
+ g_set_weak_pointer (&self->view, view);
+
+ key = gtk_event_controller_key_new ();
+ g_signal_connect_object (key,
+ "key-pressed",
+ G_CALLBACK (on_key_pressed_cb),
+ self,
+ G_CONNECT_SWAPPED);
+ gtk_widget_add_controller (GTK_WIDGET (self), key);
+
+ focus = gtk_event_controller_focus_new ();
+ g_signal_connect_object (focus,
+ "enter",
+ G_CALLBACK (on_focus_enter_cb),
+ self,
+ G_CONNECT_SWAPPED);
+ g_signal_connect_object (focus,
+ "leave",
+ G_CALLBACK (on_focus_leave_cb),
+ self,
+ G_CONNECT_SWAPPED);
+ gtk_widget_add_controller (GTK_WIDGET (self), focus);
+
+ motion = gtk_event_controller_motion_new ();
+ g_signal_connect_object (motion,
+ "motion",
+ G_CALLBACK (on_motion_cb),
+ self,
+ G_CONNECT_SWAPPED);
+ gtk_widget_add_controller (GTK_WIDGET (self), motion);
+
+ scroll = gtk_event_controller_scroll_new (GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES);
+ g_signal_connect_object (scroll,
+ "scroll",
+ G_CALLBACK (on_scroll_cb),
+ self,
+ G_CONNECT_SWAPPED);
+ gtk_widget_add_controller (GTK_WIDGET (self), scroll);
+
+ 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/gtksourceview.c b/gtksourceview/gtksourceview.c
index e4292dd2..e2abe64b 100644
--- a/gtksourceview/gtksourceview.c
+++ b/gtksourceview/gtksourceview.c
@@ -39,6 +39,7 @@
#include "gtksourcegutter-private.h"
#include "gtksourcegutterrendererlines-private.h"
#include "gtksourcegutterrenderermarks-private.h"
+#include "gtksourcehover-private.h"
#include "gtksource-enumtypes.h"
#include "gtksourcemark.h"
#include "gtksourcemarkattributes.h"
@@ -189,6 +190,7 @@ typedef struct
GdkRGBA right_margin_overlay_color;
GtkSourceCompletion *completion;
+ GtkSourceHover *hover;
guint right_margin_pos;
gint cached_right_margin_pos;
@@ -1455,6 +1457,12 @@ gtk_source_view_dispose (GObject *object)
g_clear_object (&priv->completion);
}
+ if (priv->hover != NULL)
+ {
+ g_object_run_dispose (G_OBJECT (priv->hover));
+ g_clear_object (&priv->hover);
+ }
+
g_clear_object (&priv->style_scheme);
g_clear_object (&priv->space_drawer);
@@ -4805,6 +4813,31 @@ gtk_source_view_get_completion (GtkSourceView *view)
return priv->completion;
}
+/**
+ * gtk_source_view_get_hover:
+ * @view: a #GtkSourceView.
+ *
+ * Gets the #GtkSourceHover associated with @view. The returned object is
+ * guaranteed to be the same for the lifetime of @view. Each #GtkSourceView
+ * object has a different #GtkSourceHover.
+ *
+ * Returns: (transfer none): a #GtkSourceHover associated with @view.
+ */
+GtkSourceHover *
+gtk_source_view_get_hover (GtkSourceView *view)
+{
+ GtkSourceViewPrivate *priv = gtk_source_view_get_instance_private (view);
+
+ g_return_val_if_fail (GTK_SOURCE_IS_VIEW (view), NULL);
+
+ if (priv->hover == NULL)
+ {
+ priv->hover = _gtk_source_hover_new (view);
+ }
+
+ return priv->hover;
+}
+
/**
* gtk_source_view_get_gutter:
* @view: a #GtkSourceView.
diff --git a/gtksourceview/gtksourceview.h b/gtksourceview/gtksourceview.h
index 4b448722..ab154a39 100644
--- a/gtksourceview/gtksourceview.h
+++ b/gtksourceview/gtksourceview.h
@@ -195,6 +195,8 @@ guint gtk_source_view_get_visual_column
const GtkTextIter
*iter);
GTK_SOURCE_AVAILABLE_IN_ALL
GtkSourceCompletion *gtk_source_view_get_completion (GtkSourceView
*view);
+GTK_SOURCE_AVAILABLE_IN_5_0
+GtkSourceHover *gtk_source_view_get_hover (GtkSourceView
*view);
GTK_SOURCE_AVAILABLE_IN_ALL
GtkSourceGutter *gtk_source_view_get_gutter (GtkSourceView
*view,
GtkTextWindowType
window_type);
diff --git a/gtksourceview/meson.build b/gtksourceview/meson.build
index df97aba8..b3982261 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]