[gtksourceview/wip/chergert/gsv-gtk4] informative: add informative tooltip class
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/chergert/gsv-gtk4] informative: add informative tooltip class
- Date: Wed, 9 Sep 2020 21:36:41 +0000 (UTC)
commit 607ea0620b0ea7277c467d4d4c81b2853ad338db
Author: Christian Hergert <chergert redhat com>
Date: Wed Sep 9 12:47:46 2020 -0700
informative: add informative tooltip class
This can be used to display information with the sourceview, such as
tooltips related to cursor position.
gtksourceview/GtkSourceView.css | 52 +++++
gtksourceview/gtksourceinformative-private.h | 47 ++++
gtksourceview/gtksourceinformative.c | 316 +++++++++++++++++++++++++++
gtksourceview/gtksourceinformative.ui | 25 +++
gtksourceview/gtksourceview.gresource.xml | 1 +
gtksourceview/meson.build | 1 +
6 files changed, 442 insertions(+)
---
diff --git a/gtksourceview/GtkSourceView.css b/gtksourceview/GtkSourceView.css
index b3e1787d..ff49f32c 100644
--- a/gtksourceview/GtkSourceView.css
+++ b/gtksourceview/GtkSourceView.css
@@ -93,3 +93,55 @@ GtkSourceAssistant.completion box.details button.flat {
GtkSourceAssistant.completion-info {
padding: 6px;
}
+
+GtkSourceAssistant.informative label {
+ padding-right: 10px;
+}
+GtkSourceAssistant.informative image {
+ margin: 0 6px 0 0;
+ padding: 6px 10px 6px 9px;
+ border-top-left-radius: 7px;
+ border-bottom-left-radius: 7px;
+}
+
+GtkSourceAssistant.informative.warning {
+ background-color: @warning_color;
+ color: @theme_selected_fg_color;
+ border-color: shade(@warning_color, 0.8);
+ text-shadow: 0 1px shade(@warning_color, 0.8);
+ -gtk-icon-shadow: 0 1px shade(@warning_color, 0.8);
+}
+GtkSourceAssistant.informative.warning image {
+ background-color: shade(@warning_color, 0.8);
+}
+
+GtkSourceAssistant.informative.error {
+ background-color: @error_color;
+ color: @theme_selected_fg_color;
+ border-color: shade(@error_color, 0.8);
+ text-shadow: 0 1px shade(@error_color, 0.8);
+ -gtk-icon-shadow: 0 1px shade(@error_color, 0.8);
+}
+GtkSourceAssistant.informative.error image {
+ background-color: shade(@error_color, 0.8);
+}
+
+GtkSourceAssistant.informative.info {
+ background-color: @success_color;
+ color: @theme_selected_fg_color;
+ border-color: shade(@success_color, 0.8);
+ text-shadow: 0 1px shade(@success_color, 0.8);
+ -gtk-icon-shadow: 0 1px shade(@success_color, 0.8);
+}
+GtkSourceAssistant.informative.info image {
+ background-color: shade(@success_color, 0.8);
+}
+
+GtkSourceAssistant.informative.question {
+ background-color: @theme_bg_color;
+ color: @theme_fg_color;
+ border-color: @borders;
+}
+GtkSourceAssistant.informative.question image {
+ background-color: @borders;
+}
diff --git a/gtksourceview/gtksourceinformative-private.h b/gtksourceview/gtksourceinformative-private.h
new file mode 100644
index 00000000..ac72e25d
--- /dev/null
+++ b/gtksourceview/gtksourceinformative-private.h
@@ -0,0 +1,47 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2020 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 "gtksourceassistant-private.h"
+
+G_BEGIN_DECLS
+
+#define GTK_SOURCE_TYPE_INFORMATIVE (gtk_source_informative_get_type())
+
+G_DECLARE_DERIVABLE_TYPE (GtkSourceInformative, gtk_source_informative, GTK_SOURCE, INFORMATIVE,
GtkSourceAssistant)
+
+struct _GtkSourceInformativeClass
+{
+ GtkSourceAssistantClass parent_class;
+};
+
+const char *gtk_source_informative_get_message (GtkSourceInformative *self);
+void gtk_source_informative_set_message (GtkSourceInformative *self,
+ const char *message);
+void gtk_source_informative_set_message_type (GtkSourceInformative *self,
+ GtkMessageType message_type);
+GtkMessageType gtk_source_informative_get_message_type (GtkSourceInformative *self);
+const char *gtk_source_informative_get_icon_name (GtkSourceInformative *self);
+void gtk_source_informative_set_icon_name (GtkSourceInformative *self,
+ const char *icon_name);
+
+G_END_DECLS
diff --git a/gtksourceview/gtksourceinformative.c b/gtksourceview/gtksourceinformative.c
new file mode 100644
index 00000000..2201ef44
--- /dev/null
+++ b/gtksourceview/gtksourceinformative.c
@@ -0,0 +1,316 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2020 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 "gtksourceinformative-private.h"
+#include "gtksourceview.h"
+
+typedef struct
+{
+ GtkImage *icon;
+ GtkLabel *message;
+ GtkMessageType message_type;
+} GtkSourceInformativePrivate;
+
+enum {
+ PROP_0,
+ PROP_ICON_NAME,
+ PROP_MESSAGE,
+ PROP_MESSAGE_TYPE,
+ N_PROPS
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtkSourceInformative, gtk_source_informative, GTK_SOURCE_TYPE_ASSISTANT)
+
+static GParamSpec *properties [N_PROPS];
+
+const char *
+gtk_source_informative_get_message (GtkSourceInformative *self)
+{
+ GtkSourceInformativePrivate *priv = gtk_source_informative_get_instance_private (self);
+
+ g_return_val_if_fail (GTK_SOURCE_IS_INFORMATIVE (self), NULL);
+
+ return gtk_label_get_label (priv->message);
+}
+
+void
+gtk_source_informative_set_message (GtkSourceInformative *self,
+ const char *message)
+{
+ GtkSourceInformativePrivate *priv = gtk_source_informative_get_instance_private (self);
+
+ g_return_if_fail (GTK_SOURCE_IS_INFORMATIVE (self));
+
+ gtk_label_set_label (priv->message, message);
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_MESSAGE]);
+}
+
+GtkMessageType
+gtk_source_informative_get_message_type (GtkSourceInformative *self)
+{
+ GtkSourceInformativePrivate *priv = gtk_source_informative_get_instance_private (self);
+
+ g_return_val_if_fail (GTK_SOURCE_IS_INFORMATIVE (self), GTK_MESSAGE_OTHER);
+
+ return priv->message_type;
+}
+
+void
+gtk_source_informative_set_message_type (GtkSourceInformative *self,
+ GtkMessageType message_type)
+{
+ GtkSourceInformativePrivate *priv = gtk_source_informative_get_instance_private (self);
+
+ g_assert (GTK_SOURCE_IS_INFORMATIVE (self));
+
+ priv->message_type = message_type;
+
+ gtk_widget_remove_css_class (GTK_WIDGET (self), "error");
+ gtk_widget_remove_css_class (GTK_WIDGET (self), "info");
+ gtk_widget_remove_css_class (GTK_WIDGET (self), "question");
+ gtk_widget_remove_css_class (GTK_WIDGET (self), "warning");
+
+ switch (priv->message_type)
+ {
+ case GTK_MESSAGE_INFO:
+ gtk_widget_add_css_class (GTK_WIDGET (self), "info");
+ break;
+
+ case GTK_MESSAGE_WARNING:
+ gtk_widget_add_css_class (GTK_WIDGET (self), "warning");
+ break;
+
+ case GTK_MESSAGE_QUESTION:
+ gtk_widget_add_css_class (GTK_WIDGET (self), "question");
+ break;
+
+ case GTK_MESSAGE_ERROR:
+ gtk_widget_add_css_class (GTK_WIDGET (self), "error");
+ break;
+
+ case GTK_MESSAGE_OTHER:
+ default:
+ break;
+ }
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_MESSAGE_TYPE]);
+}
+
+const char *
+gtk_source_informative_get_icon_name (GtkSourceInformative *self)
+{
+ GtkSourceInformativePrivate *priv = gtk_source_informative_get_instance_private (self);
+
+ g_assert (GTK_SOURCE_IS_INFORMATIVE (self));
+
+ return gtk_image_get_icon_name (priv->icon);
+}
+
+void
+gtk_source_informative_set_icon_name (GtkSourceInformative *self,
+ const char *icon_name)
+{
+ GtkSourceInformativePrivate *priv = gtk_source_informative_get_instance_private (self);
+
+ g_assert (GTK_SOURCE_IS_INFORMATIVE (self));
+
+ gtk_image_set_from_icon_name (priv->icon, icon_name);
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_ICON_NAME]);
+}
+
+static void
+gtk_source_informative_get_offset (GtkSourceAssistant *assistant,
+ int *x_offset,
+ int *y_offset)
+{
+ GtkSourceInformative *self = GTK_SOURCE_INFORMATIVE (assistant);
+ GtkSourceInformativePrivate *priv = gtk_source_informative_get_instance_private (self);
+ GtkRequisition min;
+
+ GTK_SOURCE_ASSISTANT_CLASS (gtk_source_informative_parent_class)->get_offset (assistant, x_offset,
y_offset);
+
+ gtk_widget_get_preferred_size (GTK_WIDGET (priv->icon), &min, NULL);
+
+ *x_offset -= min.width;
+}
+
+static gboolean
+key_press_propagate_cb (GtkSourceInformative *self,
+ guint keyval,
+ guint keycode,
+ GdkModifierType modifiers,
+ GtkEventControllerKey *key)
+{
+ GtkWidget *parent;
+
+ g_assert (GTK_SOURCE_IS_INFORMATIVE (self));
+ g_assert (GTK_IS_EVENT_CONTROLLER_KEY (key));
+
+ parent = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_SOURCE_TYPE_VIEW);
+
+ if (GTK_SOURCE_IS_VIEW (parent))
+ {
+ return gtk_event_controller_key_forward (key, parent);
+ }
+
+ return GDK_EVENT_PROPAGATE;
+}
+
+static gboolean
+key_release_propagate_cb (GtkSourceInformative *self,
+ guint keyval,
+ guint keycode,
+ GdkModifierType modifiers,
+ GtkEventControllerKey *key)
+{
+ GtkWidget *parent;
+
+ g_assert (GTK_SOURCE_IS_INFORMATIVE (self));
+ g_assert (GTK_IS_EVENT_CONTROLLER_KEY (key));
+
+ parent = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_SOURCE_TYPE_VIEW);
+
+ if (GTK_SOURCE_IS_VIEW (parent))
+ {
+ return gtk_event_controller_key_forward (key, parent);
+ }
+
+ return GDK_EVENT_PROPAGATE;
+}
+
+static void
+gtk_source_informative_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkSourceInformative *self = GTK_SOURCE_INFORMATIVE (object);
+
+ switch (prop_id)
+ {
+ case PROP_ICON_NAME:
+ g_value_set_string (value, gtk_source_informative_get_icon_name (self));
+ break;
+
+ case PROP_MESSAGE:
+ g_value_set_string (value, gtk_source_informative_get_message (self));
+ break;
+
+ case PROP_MESSAGE_TYPE:
+ g_value_set_enum (value, gtk_source_informative_get_message_type (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gtk_source_informative_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkSourceInformative *self = GTK_SOURCE_INFORMATIVE (object);
+
+ switch (prop_id)
+ {
+ case PROP_ICON_NAME:
+ gtk_source_informative_set_icon_name (self, g_value_get_string (value));
+ break;
+
+ case PROP_MESSAGE:
+ gtk_source_informative_set_message (self, g_value_get_string (value));
+ break;
+
+ case PROP_MESSAGE_TYPE:
+ gtk_source_informative_set_message_type (self, g_value_get_enum (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gtk_source_informative_class_init (GtkSourceInformativeClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GtkSourceAssistantClass *assistant_class = GTK_SOURCE_ASSISTANT_CLASS (klass);
+
+ object_class->get_property = gtk_source_informative_get_property;
+ object_class->set_property = gtk_source_informative_set_property;
+
+ assistant_class->get_offset = gtk_source_informative_get_offset;
+
+ properties [PROP_ICON_NAME] =
+ g_param_spec_string ("icon-name",
+ "Icon Name",
+ "Icon Name",
+ NULL,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_MESSAGE] =
+ g_param_spec_string ("message",
+ "Message",
+ "The message for the popover",
+ NULL,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_MESSAGE_TYPE] =
+ g_param_spec_enum ("message-type",
+ "Message Type",
+ "The message type for the popover",
+ GTK_TYPE_MESSAGE_TYPE,
+ GTK_MESSAGE_INFO,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/gtksourceview/ui/gtksourceinformative.ui");
+ gtk_widget_class_bind_template_child_private (widget_class, GtkSourceInformative, icon);
+ gtk_widget_class_bind_template_child_private (widget_class, GtkSourceInformative, message);
+}
+
+static void
+gtk_source_informative_init (GtkSourceInformative *self)
+{
+ GtkEventController *key;
+
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ key = gtk_event_controller_key_new ();
+ gtk_event_controller_set_propagation_phase (key, GTK_PHASE_BUBBLE);
+ g_signal_connect_object (key,
+ "key-pressed",
+ G_CALLBACK (key_press_propagate_cb),
+ self,
+ G_CONNECT_SWAPPED);
+ g_signal_connect_object (key,
+ "key-released",
+ G_CALLBACK (key_release_propagate_cb),
+ self,
+ G_CONNECT_SWAPPED);
+ gtk_widget_add_controller (GTK_WIDGET (self), g_steal_pointer (&key));
+}
diff --git a/gtksourceview/gtksourceinformative.ui b/gtksourceview/gtksourceinformative.ui
new file mode 100644
index 00000000..f418cca0
--- /dev/null
+++ b/gtksourceview/gtksourceinformative.ui
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="GtkSourceInformative" parent="GtkSourceAssistant">
+ <property name="can-focus">false</property>
+ <style>
+ <class name="informative"/>
+ </style>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+ <property name="can-focus">false</property>
+ <child>
+ <object class="GtkImage" id="icon">
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="message">
+ <property name="hexpand">true</property>
+ <property name="xalign">0</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/gtksourceview/gtksourceview.gresource.xml b/gtksourceview/gtksourceview.gresource.xml
index 68256313..ccf6f5c1 100644
--- a/gtksourceview/gtksourceview.gresource.xml
+++ b/gtksourceview/gtksourceview.gresource.xml
@@ -6,6 +6,7 @@
<gresource prefix="/org/gnome/gtksourceview/ui">
<file preprocess="xml-stripblanks">gtksourcecompletionlist.ui</file>
<file preprocess="xml-stripblanks">gtksourcecompletionlistboxrow.ui</file>
+ <file preprocess="xml-stripblanks">gtksourceinformative.ui</file>
<file preprocess="xml-stripblanks">gtksourcestyleschemechooserwidget.ui</file>
</gresource>
</gresources>
diff --git a/gtksourceview/meson.build b/gtksourceview/meson.build
index 7e7fef3b..d7f923a0 100644
--- a/gtksourceview/meson.build
+++ b/gtksourceview/meson.build
@@ -107,6 +107,7 @@ core_private_c = files([
'gtksourceengine.c',
'gtksourcegutterrendererlines.c',
'gtksourcegutterrenderermarks.c',
+ 'gtksourceinformative.c',
'gtksourceiter.c',
'gtksourcelanguage-parser-2.c',
'gtksourcemarkssequence.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]