[gnome-builder] greeter: add IdeGreeterRow
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] greeter: add IdeGreeterRow
- Date: Tue, 22 Jan 2019 02:36:46 +0000 (UTC)
commit e2e970e173a0a6e9d96bff7059dc2fe570a2c001
Author: Christian Hergert <chergert redhat com>
Date: Mon Jan 21 16:15:30 2019 -0800
greeter: add IdeGreeterRow
This base class can be used to create a common form of greeter row between
different sections in the greeter workspace.
src/libide/greeter/ide-greeter-row.c | 389 ++++++++++++++++++++++++
src/libide/greeter/ide-greeter-row.h | 60 ++++
src/libide/greeter/ide-greeter-row.ui | 65 ++++
src/libide/greeter/libide-greeter.gresource.xml | 1 +
src/libide/greeter/libide-greeter.h | 1 +
src/libide/greeter/meson.build | 2 +
6 files changed, 518 insertions(+)
---
diff --git a/src/libide/greeter/ide-greeter-row.c b/src/libide/greeter/ide-greeter-row.c
new file mode 100644
index 000000000..d0bca4695
--- /dev/null
+++ b/src/libide/greeter/ide-greeter-row.c
@@ -0,0 +1,389 @@
+/* ide-greeter-row.c
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "ide-greeter-row"
+
+#include "config.h"
+
+#include <stdlib.h>
+
+#include "ide-greeter-row.h"
+
+typedef struct
+{
+ IdeProjectInfo *project_info;
+
+ /* Template Widgets */
+ GtkCheckButton *check_button;
+ GtkLabel *title;
+ GtkLabel *subtitle;
+ GtkImage *image;
+ GtkBox *tags;
+} IdeGreeterRowPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (IdeGreeterRow, ide_greeter_row, GTK_TYPE_LIST_BOX_ROW)
+
+enum {
+ PROP_0,
+ PROP_PROJECT_INFO,
+ PROP_SELECTED,
+ N_PROPS
+};
+
+enum {
+ TAG_NONE,
+ TAG_BUILD_SYSTEM,
+ TAG_LANGUAGE,
+};
+
+static GParamSpec *properties [N_PROPS];
+static GHashTable *icon_name_map;
+
+/**
+ * ide_greeter_row_new:
+ *
+ * Create a new #IdeGreeterRow.
+ *
+ * Returns: (transfer full): a newly created #IdeGreeterRow
+ */
+IdeGreeterRow *
+ide_greeter_row_new (void)
+{
+ return g_object_new (IDE_TYPE_GREETER_ROW, NULL);
+}
+
+static void
+ide_greeter_row_finalize (GObject *object)
+{
+ IdeGreeterRow *self = (IdeGreeterRow *)object;
+ IdeGreeterRowPrivate *priv = ide_greeter_row_get_instance_private (self);
+
+ g_clear_object (&priv->project_info);
+
+ G_OBJECT_CLASS (ide_greeter_row_parent_class)->finalize (object);
+}
+
+static void
+ide_greeter_row_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdeGreeterRow *self = IDE_GREETER_ROW (object);
+ IdeGreeterRowPrivate *priv = ide_greeter_row_get_instance_private (self);
+
+ switch (prop_id)
+ {
+ case PROP_PROJECT_INFO:
+ g_value_set_object (value, ide_greeter_row_get_project_info (self));
+ break;
+
+ case PROP_SELECTED:
+ g_value_set_boolean (value,
+ gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->check_button)));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_greeter_row_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdeGreeterRow *self = IDE_GREETER_ROW (object);
+ IdeGreeterRowPrivate *priv = ide_greeter_row_get_instance_private (self);
+
+ switch (prop_id)
+ {
+ case PROP_PROJECT_INFO:
+ ide_greeter_row_set_project_info (self, g_value_get_object (value));
+ break;
+
+ case PROP_SELECTED:
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->check_button),
+ g_value_get_boolean (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_greeter_row_class_init (IdeGreeterRowClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = ide_greeter_row_finalize;
+ object_class->get_property = ide_greeter_row_get_property;
+ object_class->set_property = ide_greeter_row_set_property;
+
+ /**
+ * IdeGreeterRow:project-info:
+ *
+ * The "project-info" property contains information about the project
+ * to be displayed.
+ *
+ * Since: 3.32
+ */
+ properties [PROP_PROJECT_INFO] =
+ g_param_spec_object ("project-info",
+ "Project Info",
+ "Project Info",
+ IDE_TYPE_PROJECT_INFO,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_SELECTED] =
+ g_param_spec_boolean ("selected",
+ "Selected",
+ "If the row is selected",
+ FALSE,
+ (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/builder/ui/ide-greeter-row.ui");
+ gtk_widget_class_bind_template_child_private (widget_class, IdeGreeterRow, check_button);
+ gtk_widget_class_bind_template_child_private (widget_class, IdeGreeterRow, image);
+ gtk_widget_class_bind_template_child_private (widget_class, IdeGreeterRow, subtitle);
+ gtk_widget_class_bind_template_child_private (widget_class, IdeGreeterRow, tags);
+ gtk_widget_class_bind_template_child_private (widget_class, IdeGreeterRow, title);
+
+#define ADD(a,b) g_hash_table_insert(icon_name_map, (gpointer)a, (gpointer)b)
+ icon_name_map = g_hash_table_new (g_str_hash, g_str_equal);
+ ADD ("python", "text-x-python-symbolic");
+ ADD ("c", "text-x-csrc-symbolic");
+ ADD ("c++", "text-x-cpp-symbolic");
+ ADD ("css", "text-x-css-symbolic");
+ ADD ("html", "text-x-html-symbolic");
+ ADD ("ruby", "text-x-ruby-symbolic");
+ ADD ("rust", "text-x-rust-symbolic");
+ ADD ("javascript", "text-x-javascript-symbolic");
+ ADD ("vala", "text-x-vala-symbolic");
+ ADD ("xml", "text-x-xml-symbolic");
+#undef ADD
+}
+
+static void
+ide_greeter_row_init (IdeGreeterRow *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+static void
+ide_greeter_row_clear (IdeGreeterRow *self)
+{
+ IdeGreeterRowPrivate *priv = ide_greeter_row_get_instance_private (self);
+
+ g_assert (IDE_IS_GREETER_ROW (self));
+
+ g_object_set (priv->image, "icon-name", NULL, NULL);
+ gtk_label_set_label (priv->title, NULL);
+ gtk_label_set_label (priv->subtitle, NULL);
+ gtk_container_foreach (GTK_CONTAINER (priv->tags),
+ (GtkCallback)gtk_widget_destroy,
+ NULL);
+}
+
+/**
+ * ide_greeter_row_get_project_info:
+ * @self: an #IdeGreeterRow
+ *
+ * Gets the #IdeGreeterRow:project-info property.
+ *
+ * Returns: (transfer none) (nullable): an #IdeProjectInfo or %NULL
+ *
+ * Since: 3.32
+ */
+IdeProjectInfo *
+ide_greeter_row_get_project_info (IdeGreeterRow *self)
+{
+ IdeGreeterRowPrivate *priv = ide_greeter_row_get_instance_private (self);
+
+ g_return_val_if_fail (IDE_IS_GREETER_ROW (self), NULL);
+
+ return priv->project_info;
+}
+
+static const gchar *
+get_language_icon_name (const gchar *language)
+{
+ g_autofree gchar *lower = NULL;
+
+ if (language == NULL)
+ return NULL;
+
+ lower = g_utf8_strdown (language, -1);
+
+ return g_hash_table_lookup (icon_name_map, lower);
+}
+
+static void
+ide_greeter_row_add_tag (IdeGreeterRow *self,
+ const gchar *name,
+ gint kind)
+{
+ IdeGreeterRowPrivate *priv = ide_greeter_row_get_instance_private (self);
+ const gchar *icon_name = NULL;
+ GtkBox *box;
+ GtkImage *image;
+ GtkLabel *label;
+ gboolean skip_label = FALSE;
+
+ g_assert (IDE_IS_GREETER_ROW (self));
+ g_assert (name != NULL);
+
+ box = g_object_new (GTK_TYPE_BOX,
+ "orientation", GTK_ORIENTATION_HORIZONTAL,
+ "spacing", 3,
+ "visible", TRUE,
+ NULL);
+
+
+ if (kind == TAG_BUILD_SYSTEM)
+ icon_name = "builder-build-symbolic";
+
+ if (kind == TAG_LANGUAGE)
+ {
+ if ((icon_name = get_language_icon_name (name)))
+ skip_label = TRUE;
+ }
+
+ if (icon_name != NULL)
+ {
+ image = g_object_new (GTK_TYPE_IMAGE,
+ "icon-name", icon_name,
+ "valign", GTK_ALIGN_BASELINE,
+ "visible", TRUE,
+ NULL);
+ dzl_gtk_widget_add_style_class (GTK_WIDGET (image), "dim-label");
+ gtk_container_add (GTK_CONTAINER (box), GTK_WIDGET (image));
+ }
+
+ if (!skip_label)
+ {
+ label = g_object_new (GTK_TYPE_LABEL,
+ "label", name,
+ "valign", GTK_ALIGN_BASELINE,
+ "visible", TRUE,
+ NULL);
+ dzl_gtk_widget_add_style_class (GTK_WIDGET (label), "dim-label");
+ gtk_container_add (GTK_CONTAINER (box), GTK_WIDGET (label));
+ }
+
+ gtk_container_add (GTK_CONTAINER (priv->tags), GTK_WIDGET (box));
+}
+
+static gint
+compare_language (gconstpointer a,
+ gconstpointer b)
+{
+ return g_strcmp0 (*(gchar **)a, *(gchar **)b);
+}
+
+void
+ide_greeter_row_set_project_info (IdeGreeterRow *self,
+ IdeProjectInfo *project_info)
+{
+ IdeGreeterRowPrivate *priv = ide_greeter_row_get_instance_private (self);
+
+ g_return_if_fail (IDE_IS_GREETER_ROW (self));
+ g_return_if_fail (!project_info || IDE_IS_PROJECT_INFO (project_info));
+
+ if (g_set_object (&priv->project_info, project_info))
+ {
+ ide_greeter_row_clear (self);
+
+ if (project_info != NULL)
+ {
+ g_autofree gchar *collapsed = NULL;
+ g_auto(GStrv) languages = g_strdupv ((gchar **)ide_project_info_get_languages (project_info));
+ const gchar *name = ide_project_info_get_name (project_info);
+ const gchar *build_system = ide_project_info_get_build_system_name (project_info);
+ GFile *directory = ide_project_info_get_directory (project_info);
+ const gchar *desc = ide_project_info_get_description (project_info);
+
+ if (!ide_str_empty0 (desc))
+ gtk_widget_set_tooltip_text (GTK_WIDGET (self), desc);
+
+ if ((collapsed = ide_path_collapse (g_file_peek_path (directory))))
+ desc = collapsed;
+
+ gtk_label_set_label (priv->title, name);
+ gtk_label_set_label (priv->subtitle, desc);
+
+ if (build_system != NULL)
+ ide_greeter_row_add_tag (self, build_system, TAG_BUILD_SYSTEM);
+
+ if (languages != NULL)
+ {
+ qsort (languages, g_strv_length (languages), sizeof (gchar*), compare_language);
+ for (guint i = 0; languages[i] != NULL; i++)
+ ide_greeter_row_add_tag (self, languages[i], TAG_LANGUAGE);
+ }
+ }
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_PROJECT_INFO]);
+ }
+}
+
+/**
+ * ide_greeter_row_get_search_text:
+ * @self: a #IdeGreeterRow
+ *
+ * Gets a new string containing the search text for the greeter row.
+ *
+ * Returns: (transfer full) (nullable): a string or %NULL
+ *
+ * Since: 3.32
+ */
+gchar *
+ide_greeter_row_get_search_text (IdeGreeterRow *self)
+{
+ g_return_val_if_fail (IDE_IS_GREETER_ROW (self), NULL);
+
+ return NULL;
+}
+
+gboolean
+ide_greeter_row_get_selection_mode (IdeGreeterRow *self)
+{
+ IdeGreeterRowPrivate *priv = ide_greeter_row_get_instance_private (self);
+
+ g_return_val_if_fail (IDE_IS_GREETER_ROW (self), FALSE);
+
+ return gtk_widget_get_visible (GTK_WIDGET (priv->check_button));
+}
+
+void
+ide_greeter_row_set_selection_mode (IdeGreeterRow *self,
+ gboolean selection_mode)
+{
+ IdeGreeterRowPrivate *priv = ide_greeter_row_get_instance_private (self);
+
+ g_return_if_fail (IDE_IS_GREETER_ROW (self));
+
+ gtk_widget_set_visible (GTK_WIDGET (priv->check_button), selection_mode);
+}
diff --git a/src/libide/greeter/ide-greeter-row.h b/src/libide/greeter/ide-greeter-row.h
new file mode 100644
index 000000000..8857668c4
--- /dev/null
+++ b/src/libide/greeter/ide-greeter-row.h
@@ -0,0 +1,60 @@
+/* ide-greeter-row.h
+ *
+ * Copyright 2019 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#if !defined (IDE_GREETER_INSIDE) && !defined (IDE_GREETER_COMPILATION)
+# error "Only <libide-greeter.h> can be included directly."
+#endif
+
+#include <gtk/gtk.h>
+#include <libide-projects.h>
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_GREETER_ROW (ide_greeter_row_get_type())
+
+IDE_AVAILABLE_IN_3_32
+G_DECLARE_DERIVABLE_TYPE (IdeGreeterRow, ide_greeter_row, IDE, GREETER_ROW, GtkListBoxRow)
+
+struct _IdeGreeterRowClass
+{
+ GtkListBoxRowClass parent_class;
+
+ /*< private >*/
+ gpointer _reserved[8];
+};
+
+IDE_AVAILABLE_IN_3_32
+IdeGreeterRow *ide_greeter_row_new (void);
+IDE_AVAILABLE_IN_3_32
+IdeProjectInfo *ide_greeter_row_get_project_info (IdeGreeterRow *self);
+IDE_AVAILABLE_IN_3_32
+void ide_greeter_row_set_project_info (IdeGreeterRow *self,
+ IdeProjectInfo *project_info);
+IDE_AVAILABLE_IN_3_32
+gchar *ide_greeter_row_get_search_text (IdeGreeterRow *self);
+IDE_AVAILABLE_IN_3_32
+gboolean ide_greeter_row_get_selection_mode (IdeGreeterRow *self);
+IDE_AVAILABLE_IN_3_32
+void ide_greeter_row_set_selection_mode (IdeGreeterRow *self,
+ gboolean selection_mode);
+
+G_END_DECLS
diff --git a/src/libide/greeter/ide-greeter-row.ui b/src/libide/greeter/ide-greeter-row.ui
new file mode 100644
index 000000000..6790db95f
--- /dev/null
+++ b/src/libide/greeter/ide-greeter-row.ui
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="IdeGreeterRow" parent="GtkListBoxRow">
+ <child>
+ <object class="GtkBox">
+ <property name="margin-top">12</property>
+ <property name="margin-bottom">12</property>
+ <property name="margin-start">18</property>
+ <property name="margin-end">18</property>
+ <property name="orientation">horizontal</property>
+ <property name="spacing">12</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkCheckButton" id="check_button">
+ <property name="margin-end">6</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImage" id="image">
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="hexpand">true</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkLabel" id="title">
+ <property name="visible">true</property>
+ <property name="xalign">0.0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="subtitle">
+ <property name="visible">true</property>
+ <property name="xalign">0.0</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox" id="tags">
+ <property name="spacing">6</property>
+ <property name="valign">center</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">go-next-symbolic</property>
+ <property name="margin-start">6</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/src/libide/greeter/libide-greeter.gresource.xml b/src/libide/greeter/libide-greeter.gresource.xml
index 002f2abb2..ee2c4b10e 100644
--- a/src/libide/greeter/libide-greeter.gresource.xml
+++ b/src/libide/greeter/libide-greeter.gresource.xml
@@ -2,6 +2,7 @@
<gresources>
<gresource prefix="/org/gnome/builder/ui">
<file preprocess="xml-stripblanks">ide-clone-surface.ui</file>
+ <file preprocess="xml-stripblanks">ide-greeter-row.ui</file>
<file preprocess="xml-stripblanks">ide-greeter-workspace.ui</file>
</gresource>
</gresources>
diff --git a/src/libide/greeter/libide-greeter.h b/src/libide/greeter/libide-greeter.h
index bce96a180..0f3bc1a97 100644
--- a/src/libide/greeter/libide-greeter.h
+++ b/src/libide/greeter/libide-greeter.h
@@ -28,6 +28,7 @@
#define IDE_GREETER_INSIDE
#include "ide-clone-surface.h"
+#include "ide-greeter-row.h"
#include "ide-greeter-section.h"
#include "ide-greeter-workspace.h"
diff --git a/src/libide/greeter/meson.build b/src/libide/greeter/meson.build
index afaebb382..033137758 100644
--- a/src/libide/greeter/meson.build
+++ b/src/libide/greeter/meson.build
@@ -9,6 +9,7 @@ libide_greeter_generated_headers = []
libide_greeter_public_headers = [
'ide-clone-surface.h',
+ 'ide-greeter-row.h',
'ide-greeter-section.h',
'ide-greeter-workspace.h',
'libide-greeter.h',
@@ -26,6 +27,7 @@ install_headers(libide_greeter_public_headers, subdir: libide_greeter_header_sub
libide_greeter_public_sources = [
'ide-clone-surface.c',
+ 'ide-greeter-row.c',
'ide-greeter-section.c',
'ide-greeter-workspace.c',
]
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]