[gnome-builder] greeter: add IdeGreeterSection pluggable API
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] greeter: add IdeGreeterSection pluggable API
- Date: Fri, 17 Nov 2017 22:53:11 +0000 (UTC)
commit a6d60d30dac9e10ad159af548b5c3c10a4e497d9
Author: Christian Hergert <chergert redhat com>
Date: Fri Nov 17 14:43:15 2017 -0800
greeter: add IdeGreeterSection pluggable API
This adds a new IdeGreeterSection interface to be used for
defining sections in the primary greeter. As part of this, the
newcomers section has been removed from libide and will come
back as a plugin.
Additionally, we should be able to remove the recent projects
section from libide and move that to a plugin. That is not part
of this refactoring and can happen at some point in the future,
as it is fairly low priority.
src/libide/greeter/icons/org.gnome.Calendar.png | Bin 197273 -> 0 bytes
src/libide/greeter/icons/org.gnome.Games.png | Bin 173231 -> 0 bytes
src/libide/greeter/icons/org.gnome.Maps.png | Bin 43685 -> 0 bytes
src/libide/greeter/icons/org.gnome.Music.png | Bin 93983 -> 0 bytes
src/libide/greeter/icons/org.gnome.Nautilus.png | Bin 60905 -> 0 bytes
src/libide/greeter/icons/org.gnome.Photos.png | Bin 60258 -> 0 bytes
src/libide/greeter/icons/org.gnome.Polari.png | Bin 42950 -> 0 bytes
src/libide/greeter/icons/org.gnome.Todo.png | Bin 85334 -> 0 bytes
src/libide/greeter/ide-greeter-perspective.c | 415 +++++++++++++----------
src/libide/greeter/ide-greeter-perspective.ui | 101 +------
src/libide/greeter/ide-greeter-section.c | 104 ++++++
src/libide/greeter/ide-greeter-section.h | 53 +++
src/libide/greeter/ide-newcomer-project.c | 164 ---------
src/libide/greeter/ide-newcomer-project.h | 33 --
src/libide/greeter/ide-newcomer-project.ui | 27 --
src/libide/greeter/meson.build | 4 +-
src/libide/ide.h | 1 +
src/libide/libide.gresource.xml | 13 -
18 files changed, 398 insertions(+), 517 deletions(-)
---
diff --git a/src/libide/greeter/ide-greeter-perspective.c b/src/libide/greeter/ide-greeter-perspective.c
index daa7f82..f102f6b 100644
--- a/src/libide/greeter/ide-greeter-perspective.c
+++ b/src/libide/greeter/ide-greeter-perspective.c
@@ -29,7 +29,7 @@
#include "genesis/ide-genesis-addin.h"
#include "greeter/ide-greeter-perspective.h"
#include "greeter/ide-greeter-project-row.h"
-#include "greeter/ide-newcomer-project.h"
+#include "greeter/ide-greeter-section.h"
#include "util/ide-gtk.h"
#include "workbench/ide-perspective.h"
#include "workbench/ide-workbench-private.h"
@@ -47,6 +47,8 @@ struct _IdeGreeterPerspective
GBinding *ready_binding;
GCancellable *cancellable;
+ PeasExtensionSet *sections;
+
GtkStack *stack;
GtkStack *top_stack;
GtkButton *genesis_continue_button;
@@ -67,13 +69,22 @@ struct _IdeGreeterPerspective
DzlStateMachine *state_machine;
GtkScrolledWindow *scrolled_window;
DzlPriorityBox *genesis_buttons;
- GtkFlowBox *newcomer_projects;
+ DzlPriorityBox *sections_container;
gint selected_count;
};
-static void ide_perspective_iface_init (IdePerspectiveInterface *iface);
-static void ide_greeter_perspective_genesis_continue (IdeGreeterPerspective *self);
+typedef struct
+{
+ IdeGreeterPerspective *self;
+ IdeVcsUri *vcs_uri;
+ gboolean handled;
+} LoadProject;
+
+static void ide_perspective_iface_init (IdePerspectiveInterface *iface);
+static void ide_greeter_perspective_genesis_continue (IdeGreeterPerspective *self);
+static gboolean ide_greeter_perspective_load_project (IdeGreeterPerspective *self,
+ IdeProjectInfo *project_info);
G_DEFINE_TYPE_EXTENDED (IdeGreeterPerspective, ide_greeter_perspective, GTK_TYPE_BIN, 0,
G_IMPLEMENT_INTERFACE (IDE_TYPE_PERSPECTIVE,
@@ -177,6 +188,23 @@ ide_greeter_perspective_apply_filter (IdeGreeterPerspective *self,
}
static void
+ide_greeter_perspective_filter_sections (PeasExtensionSet *set,
+ PeasPluginInfo *plugin_info,
+ PeasExtension *exten,
+ gpointer user_data)
+{
+ IdeGreeterPerspective *self = user_data;
+ IdeGreeterSection *section = (IdeGreeterSection *)exten;
+
+ g_assert (PEAS_IS_EXTENSION_SET (set));
+ g_assert (plugin_info != NULL);
+ g_assert (IDE_IS_GREETER_SECTION (section));
+ g_assert (IDE_IS_GREETER_PERSPECTIVE (self));
+
+ ide_greeter_section_filter (section, self->pattern_spec);
+}
+
+static void
ide_greeter_perspective_apply_filter_all (IdeGreeterPerspective *self)
{
const gchar *text;
@@ -190,6 +218,11 @@ ide_greeter_perspective_apply_filter_all (IdeGreeterPerspective *self)
ide_greeter_perspective_apply_filter (self,
self->my_projects_list_box,
GTK_WIDGET (self->my_projects_container));
+
+ if (self->sections != NULL)
+ peas_extension_set_foreach (self->sections,
+ ide_greeter_perspective_filter_sections,
+ self);
}
static void
@@ -454,62 +487,24 @@ ide_greeter_perspective__row_activated (IdeGreeterPerspective *self,
GtkListBox *list_box)
{
IdeProjectInfo *project_info;
- IdeWorkbench *workbench = NULL;
- GFile *project_file;
- GList *list;
- GtkWindow *window;
- IdeContext *context;
g_assert (IDE_IS_GREETER_PERSPECTIVE (self));
g_assert (IDE_IS_GREETER_PROJECT_ROW (row));
g_assert (GTK_IS_LIST_BOX (list_box));
- if (ide_str_equal0 (dzl_state_machine_get_state (self->state_machine), "selection"))
+ if (dzl_state_machine_is_state (self->state_machine, "selection"))
{
gboolean selected = FALSE;
g_object_get (row, "selected", &selected, NULL);
g_object_set (row, "selected", !selected, NULL);
+
return;
}
project_info = ide_greeter_project_row_get_project_info (row);
- project_file = ide_project_info_get_file (project_info);
-
- gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
- gtk_widget_set_sensitive (GTK_WIDGET (self->titlebar), FALSE);
-
- workbench = ide_widget_get_workbench (GTK_WIDGET (self));
-
- list = gtk_application_get_windows (gtk_window_get_application (GTK_WINDOW (workbench)));
-
- for (; list != NULL; list = list->next)
- {
- window = list->data;
- context = ide_workbench_get_context (IDE_WORKBENCH (window));
-
- if (context != NULL)
- {
- if (g_file_equal (ide_context_get_project_file (context), project_file))
- {
- gtk_window_present (window);
- gtk_window_close (GTK_WINDOW (workbench));
- workbench = NULL;
- break;
- }
- }
- }
-
- if(workbench != NULL)
- {
- ide_workbench_open_project_async (workbench,
- project_file,
- NULL,
- ide_greeter_perspective_open_project_cb,
- g_object_ref (self));
- }
- ide_project_info_set_is_recent (project_info, TRUE);
+ ide_greeter_perspective_load_project (self, project_info);
}
static gboolean
@@ -1069,43 +1064,6 @@ ide_greeter_perspective_info_bar_response (IdeGreeterPerspective *self,
gtk_revealer_set_reveal_child (self->info_bar_revealer, FALSE);
}
-static void
-ide_greeter_perspective_maybe_clone (PeasExtensionSet *set,
- PeasPluginInfo *plugin_info,
- PeasExtension *exten,
- gpointer user_data)
-{
- IdeGenesisAddin *addin = (IdeGenesisAddin *)exten;
- struct {
- IdeGreeterPerspective *self;
- IdeVcsUri *uri;
- gboolean found;
- } *lookup = user_data;
-
- g_assert (PEAS_IS_EXTENSION_SET (set));
- g_assert (plugin_info != NULL);
- g_assert (IDE_IS_GENESIS_ADDIN (addin));
- g_assert (lookup != NULL);
-
- if (lookup->found)
- return;
-
- lookup->found = ide_genesis_addin_apply_uri (addin, lookup->uri);
-
- if (lookup->found)
- {
- GtkWidget *child = ide_genesis_addin_get_widget (addin);
-
- if (child != NULL)
- {
- gtk_stack_set_visible_child (lookup->self->genesis_stack, child);
- dzl_state_machine_set_state (lookup->self->state_machine, "genesis");
- gtk_widget_hide (GTK_WIDGET (lookup->self->genesis_continue_button));
- ide_greeter_perspective_genesis_continue (lookup->self);
- }
- }
-}
-
static gchar *
get_project_directory (const gchar *name)
{
@@ -1122,130 +1080,222 @@ get_project_directory (const gchar *name)
}
static void
-ide_greeter_perspective_open_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
+ide_greeter_perspective_load_project_cb (PeasExtensionSet *set,
+ PeasPluginInfo *plugin_info,
+ PeasExtension *exten,
+ gpointer user_data)
{
- IdeWorkbench *workbench = (IdeWorkbench *)object;
- g_autoptr(IdeGreeterPerspective) self = user_data;
-
- g_assert (IDE_IS_GREETER_PERSPECTIVE (self));
- g_assert (G_IS_ASYNC_RESULT (result));
-
- if (!ide_workbench_open_project_finish (workbench, result, NULL))
- gtk_widget_set_sensitive (GTK_WIDGET (self), TRUE);
-}
+ IdeGenesisAddin *addin = (IdeGenesisAddin *)exten;
+ LoadProject *load = user_data;
-static void
-ide_greeter_perspective_do_open (IdeGreeterPerspective *self,
- const gchar *path)
-{
- g_autoptr(GFile) file = NULL;
- IdeWorkbench *workbench;
+ g_assert (PEAS_IS_EXTENSION_SET (set));
+ g_assert (plugin_info != NULL);
+ g_assert (IDE_IS_GENESIS_ADDIN (addin));
+ g_assert (load != NULL);
+ g_assert (IDE_IS_GREETER_PERSPECTIVE (load->self));
+ g_assert (load->vcs_uri != NULL);
- g_assert (IDE_IS_GREETER_PERSPECTIVE (self));
- g_assert (path != NULL);
+ if (load->handled)
+ return;
- file = g_file_new_for_path (path);
- workbench = ide_widget_get_workbench (GTK_WIDGET (self));
+ load->handled = ide_genesis_addin_apply_uri (addin, load->vcs_uri);
- gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
+ if (load->handled)
+ {
+ GtkWidget *child = ide_genesis_addin_get_widget (addin);
- ide_workbench_open_project_async (workbench,
- file,
- NULL,
- ide_greeter_perspective_open_cb,
- g_object_ref (self));
+ if (child != NULL)
+ {
+ gtk_stack_set_visible_child (load->self->genesis_stack, child);
+ dzl_state_machine_set_state (load->self->state_machine, "genesis");
+ gtk_widget_hide (GTK_WIDGET (load->self->genesis_continue_button));
+ ide_greeter_perspective_genesis_continue (load->self);
+ }
+ }
}
static gboolean
ide_greeter_perspective_load_project (IdeGreeterPerspective *self,
- IdeNewcomerProject *project)
+ IdeProjectInfo *project_info)
{
- g_autofree gchar *dir = NULL;
- g_autofree gchar *maybe_project = NULL;
- g_autofree gchar *relocated = NULL;
- IdeRecentProjects *projects;
- const gchar *path;
- const gchar *str;
- IdeVcsUri *uri;
+ IdeWorkbench *workbench;
+ IdeVcsUri *vcs_uri;
+ GFile *project_file;
- g_assert (IDE_IS_GREETER_PERSPECTIVE (self));
- g_assert (IDE_IS_NEWCOMER_PROJECT (project));
+ IDE_ENTRY;
- projects = ide_application_get_recent_projects (IDE_APPLICATION_DEFAULT);
- str = ide_newcomer_project_get_uri (project);
- uri = ide_vcs_uri_new (str);
- path = ide_vcs_uri_get_path (uri);
- dir = g_path_get_basename (path);
+ g_assert (IDE_IS_GREETER_PERSPECTIVE (self));
+ g_assert (IDE_IS_PROJECT_INFO (project_info));
- if (g_str_has_suffix (dir, ".git"))
- dir[strlen (dir) - 4] = '\0';
+ workbench = ide_widget_get_workbench (GTK_WIDGET (self));
- maybe_project = get_project_directory (dir);
- relocated = ide_recent_projects_find_by_directory (projects, maybe_project);
+ /* Mark this project info as having been selected */
+ ide_project_info_set_is_recent (project_info, TRUE);
- if (relocated != NULL)
+ /* If the project info has a project file, open that. */
+ if (NULL != (project_file = ide_project_info_get_file (project_info)))
{
- ide_greeter_perspective_do_open (self, relocated);
- return TRUE;
+ gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
+ gtk_widget_set_sensitive (GTK_WIDGET (self->titlebar), FALSE);
+ ide_workbench_open_project_async (workbench,
+ project_file,
+ NULL,
+ ide_greeter_perspective_open_project_cb,
+ g_object_ref (self));
+ IDE_RETURN (TRUE);
}
- /* If the test exists, we probably should just open that
- * instead of trying to reclone, which would fail anyway since
- * this directory already exists.
+ /*
+ * If this project info has a uri, we might be able to find it already
+ * checked out on the system.
*/
- if (g_file_test (maybe_project, G_FILE_TEST_IS_DIR))
+ if (NULL != (vcs_uri = ide_project_info_get_vcs_uri (project_info)))
{
- ide_greeter_perspective_do_open (self, maybe_project);
- return TRUE;
+ LoadProject load = { 0 };
+ const gchar *path;
+
+ if (NULL != (path = ide_vcs_uri_get_path (vcs_uri)))
+ {
+ IdeApplication *app = IDE_APPLICATION_DEFAULT;
+ IdeRecentProjects *projects = ide_application_get_recent_projects (app);
+ g_autofree gchar *dir = NULL;
+ g_autofree gchar *maybe_project = NULL;
+ g_autofree gchar *relocated = NULL;
+ const gchar *previous = NULL;
+
+ dir = g_path_get_basename (path);
+
+ /* XXX: Would be nice if this could be abstracted */
+ if (g_str_has_suffix (dir, ".git"))
+ dir[strlen (dir) - 4] = '\0';
+
+ maybe_project = get_project_directory (dir);
+
+ /*
+ * We might find the project already cloned (using our simple check
+ * for the directory name), or possibly from our recent projects.
+ */
+ if (g_file_test (maybe_project, G_FILE_TEST_IS_DIR))
+ previous = maybe_project;
+ else
+ previous = relocated = ide_recent_projects_find_by_directory (projects, maybe_project);
+
+ if (previous != NULL)
+ {
+ g_autoptr(GFile) file = g_file_new_for_path (previous);
+
+ gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
+ gtk_widget_set_sensitive (GTK_WIDGET (self->titlebar), FALSE);
+ ide_workbench_open_project_async (workbench,
+ file,
+ NULL,
+ ide_greeter_perspective_open_project_cb,
+ g_object_ref (self));
+ IDE_RETURN (TRUE);
+ }
+ }
+
+ /*
+ * Okay, we didn't handle this, see if one of the genesis plugins
+ * knows how to handle the given vcs uri.
+ */
+
+ load.self = self;
+ load.vcs_uri = vcs_uri;
+ load.handled = FALSE;
+
+ peas_extension_set_foreach (self->genesis_set,
+ ide_greeter_perspective_load_project_cb,
+ &load);
+
+ if (load.handled)
+ IDE_RETURN (TRUE);
}
- return FALSE;
+ /*
+ * TODO: Failed to locate something that could open this project.
+ * Notify the user of the error and continue.
+ */
+
+ IDE_RETURN (FALSE);
}
static void
-ide_greeter_perspective__newcomer_activated (IdeGreeterPerspective *self,
- GtkFlowBoxChild *child,
- GtkFlowBox *flow_box)
+ide_greeter_perspective_project_activated (IdeGreeterPerspective *self,
+ IdeProjectInfo *project_info,
+ IdeGreeterSection *section)
{
- g_autoptr(IdeVcsUri) vcs_uri = NULL;
- IdeNewcomerProject *project;
- const gchar *uri;
- struct {
- IdeGreeterPerspective *self;
- IdeVcsUri *uri;
- gboolean found;
- } lookup;
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_GREETER_PERSPECTIVE (self));
+ g_assert (IDE_IS_PROJECT_INFO (project_info));
+ g_assert (IDE_IS_GREETER_SECTION (section));
+
+ ide_greeter_perspective_load_project (self, project_info);
+
+ IDE_EXIT;
+}
+
+static void
+ide_greeter_perspective_section_added (PeasExtensionSet *set,
+ PeasPluginInfo *plugin_info,
+ PeasExtension *exten,
+ gpointer user_data)
+{
+ IdeGreeterPerspective *self = user_data;
+ IdeGreeterSection *section = (IdeGreeterSection *)exten;
+ gint priority;
IDE_ENTRY;
+ g_return_if_fail (PEAS_IS_EXTENSION_SET (set));
+ g_return_if_fail (plugin_info != NULL);
g_return_if_fail (IDE_IS_GREETER_PERSPECTIVE (self));
- g_return_if_fail (GTK_IS_FLOW_BOX_CHILD (child));
- g_return_if_fail (GTK_IS_FLOW_BOX (flow_box));
+ g_return_if_fail (IDE_IS_GREETER_SECTION (section));
- project = IDE_NEWCOMER_PROJECT (gtk_bin_get_child (GTK_BIN (child)));
+ /* Take the floating GtkWidget reference */
+ if (g_object_is_floating (section))
+ g_object_ref_sink (section);
- /* Try to reload the project if they've already opened
- * this one before. Look at our recent projects and if not
- * there, the Projects directory for a matching project
- * directory name from the uri.
- */
- if (ide_greeter_perspective_load_project (self, project))
- IDE_EXIT;
+ g_signal_connect_object (section,
+ "project-activated",
+ G_CALLBACK (ide_greeter_perspective_project_activated),
+ self,
+ G_CONNECT_SWAPPED);
+
+ /* Add the section to our box with priority */
+ priority = ide_greeter_section_get_priority (section);
+ gtk_container_add_with_properties (GTK_CONTAINER (self->sections_container),
+ GTK_WIDGET (section),
+ "priority", priority,
+ NULL);
+ gtk_widget_show (GTK_WIDGET (section));
- uri = ide_newcomer_project_get_uri (project);
- vcs_uri = ide_vcs_uri_new (uri);
+ IDE_EXIT;
+}
- IDE_TRACE_MSG ("Looking for genesis addin to handle %s", uri);
+static void
+ide_greeter_perspective_section_removed (PeasExtensionSet *set,
+ PeasPluginInfo *plugin_info,
+ PeasExtension *exten,
+ gpointer user_data)
+{
+ IdeGreeterPerspective *self = user_data;
+ IdeGreeterSection *section = (IdeGreeterSection *)exten;
- lookup.self = self;
- lookup.uri = vcs_uri;
- lookup.found = FALSE;
+ IDE_ENTRY;
- peas_extension_set_foreach (self->genesis_set,
- ide_greeter_perspective_maybe_clone,
- &lookup);
+ g_return_if_fail (PEAS_IS_EXTENSION_SET (set));
+ g_return_if_fail (plugin_info != NULL);
+ g_return_if_fail (IDE_IS_GREETER_PERSPECTIVE (self));
+ g_return_if_fail (IDE_IS_GREETER_SECTION (section));
+
+ g_signal_handlers_disconnect_by_func (section,
+ G_CALLBACK (ide_greeter_perspective_project_activated),
+ self);
+
+ gtk_container_remove (GTK_CONTAINER (self->sections_container),
+ GTK_WIDGET (section));
IDE_EXIT;
}
@@ -1262,6 +1312,21 @@ ide_greeter_perspective_constructed (GObject *object)
ide_greeter_perspective_set_recent_projects (self, recent_projects);
ide_greeter_perspective_load_genesis_addins (self);
+
+ self->sections = peas_extension_set_new (peas_engine_get_default (),
+ IDE_TYPE_GREETER_SECTION,
+ NULL);
+ g_signal_connect (self->sections,
+ "extension-added",
+ G_CALLBACK (ide_greeter_perspective_section_added),
+ self);
+ g_signal_connect (self->sections,
+ "extension-removed",
+ G_CALLBACK (ide_greeter_perspective_section_removed),
+ self);
+ peas_extension_set_foreach (self->sections,
+ ide_greeter_perspective_section_added,
+ self);
}
static void
@@ -1272,6 +1337,8 @@ ide_greeter_perspective_destroy (GtkWidget *widget)
if (self->titlebar != NULL)
gtk_widget_destroy (GTK_WIDGET (self->titlebar));
+ g_clear_object (&self->sections);
+
GTK_WIDGET_CLASS (ide_greeter_perspective_parent_class)->destroy (widget);
}
@@ -1362,18 +1429,16 @@ ide_greeter_perspective_class_init (IdeGreeterPerspectiveClass *klass)
gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, info_bar_revealer);
gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, my_projects_container);
gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, my_projects_list_box);
- gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, newcomer_projects);
gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, open_button);
gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, remove_button);
gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, scrolled_window);
gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, search_entry);
+ gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, sections_container);
gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, stack);
gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, state_machine);
gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, titlebar);
gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, top_stack);
gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, viewport);
-
- g_type_ensure (IDE_TYPE_NEWCOMER_PROJECT);
}
static const GActionEntry actions[] = {
@@ -1424,12 +1489,6 @@ ide_greeter_perspective_init (IdeGreeterPerspective *self)
self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (self->newcomer_projects,
- "child-activated",
- G_CALLBACK (ide_greeter_perspective__newcomer_activated),
- self,
- G_CONNECT_SWAPPED);
-
g_signal_connect_object (self->top_stack,
"notify::visible-child",
G_CALLBACK (ide_greeter_perspective_genesis_changed),
diff --git a/src/libide/greeter/ide-greeter-perspective.ui b/src/libide/greeter/ide-greeter-perspective.ui
index 445cbf3..3411887 100644
--- a/src/libide/greeter/ide-greeter-perspective.ui
+++ b/src/libide/greeter/ide-greeter-perspective.ui
@@ -71,7 +71,7 @@
<property name="expand">true</property>
<property name="visible">true</property>
<child>
- <object class="GtkBox">
+ <object class="DzlPriorityBox" id="sections_container">
<property name="orientation">vertical</property>
<property name="spacing">32</property>
<property name="visible">true</property>
@@ -143,99 +143,6 @@
</child>
</object>
</child>
- <child>
- <object class="GtkBox" id="newcomer_container">
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <property name="visible">true</property>
- <child>
- <object class="GtkLabel">
- <property name="label" translatable="yes">Newcomer
Projects</property>
- <property name="visible">true</property>
- <style>
- <class name="dim-label"/>
- </style>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- </child>
- <child>
- <object class="GtkFlowBox" id="newcomer_projects">
- <property name="visible">true</property>
- <property name="halign">center</property>
- <property name="valign">start</property>
- <property name="selection-mode">browse</property>
- <property name="min-children-per-line">3</property>
- <property name="max-children-per-line">5</property>
- <child>
- <object class="IdeNewcomerProject">
- <property name="name" translatable="yes">Polari</property>
- <property name="icon-name">org.gnome.Polari</property>
- <property
name="uri">https://gitlab.gnome.org/GNOME/polari.git</property>
- <property name="visible">true</property>
- </object>
- </child>
- <child>
- <object class="IdeNewcomerProject">
- <property name="name" translatable="yes">Games</property>
- <property name="icon-name">org.gnome.Games</property>
- <property
name="uri">https://git.gnome.org/browse/gnome-games</property>
- <property name="visible">true</property>
- </object>
- </child>
- <child>
- <object class="IdeNewcomerProject">
- <property name="name" translatable="yes">Maps</property>
- <property name="icon-name">org.gnome.Maps</property>
- <property
name="uri">https://git.gnome.org/browse/gnome-maps</property>
- <property name="visible">true</property>
- </object>
- </child>
- <child>
- <object class="IdeNewcomerProject">
- <property name="name" translatable="yes">Todo</property>
- <property name="icon-name">org.gnome.Todo</property>
- <property
name="uri">https://gitlab.gnome.org/GNOME/gnome-todo.git</property>
- <property name="visible">true</property>
- </object>
- </child>
- <child>
- <object class="IdeNewcomerProject">
- <property name="name" translatable="yes">Music</property>
- <property name="icon-name">org.gnome.Music</property>
- <property
name="uri">https://git.gnome.org/browse/gnome-music</property>
- <property name="visible">true</property>
- </object>
- </child>
- <child>
- <object class="IdeNewcomerProject">
- <property name="name" translatable="yes">Nautilus</property>
- <property name="icon-name">org.gnome.Nautilus</property>
- <property
name="uri">https://gitlab.gnome.org/GNOME/nautilus.git</property>
- <property name="visible">true</property>
- </object>
- </child>
- <child>
- <object class="IdeNewcomerProject">
- <property name="name" translatable="yes">Photos</property>
- <property name="icon-name">org.gnome.Photos</property>
- <property
name="uri">https://git.gnome.org/browse/gnome-photos</property>
- <property name="visible">true</property>
- </object>
- </child>
- <child>
- <object class="IdeNewcomerProject">
- <property name="name" translatable="yes">Calendar</property>
- <property name="icon-name">org.gnome.Calendar</property>
- <property
name="uri">https://git.gnome.org/browse/gnome-calendar.git</property>
- <property name="visible">true</property>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
</object>
</child>
</object>
@@ -428,9 +335,6 @@
<object id="genesis_continue_button">
<property name="visible">false</property>
</object>
- <object id="newcomer_container">
- <property name="visible">true</property>
- </object>
<object id="top_stack">
<property name="visible-child-name">greeter</property>
</object>
@@ -466,9 +370,6 @@
<object id="genesis_continue_button">
<property name="visible">false</property>
</object>
- <object id="newcomer_container">
- <property name="visible">false</property>
- </object>
<object id="top_stack">
<property name="visible-child-name">greeter</property>
</object>
diff --git a/src/libide/greeter/ide-greeter-section.c b/src/libide/greeter/ide-greeter-section.c
new file mode 100644
index 0000000..230446a
--- /dev/null
+++ b/src/libide/greeter/ide-greeter-section.c
@@ -0,0 +1,104 @@
+/* ide-greeter-section.c
+ *
+ * Copyright (C) 2017 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/>.
+ */
+
+#define G_LOG_DOMAIN "ide-greeter-section"
+
+#include "greeter/ide-greeter-section.h"
+
+G_DEFINE_INTERFACE (IdeGreeterSection, ide_greeter_section, GTK_TYPE_WIDGET)
+
+enum {
+ PROJECT_ACTIVATED,
+ N_SIGNALS
+};
+
+static guint signals [N_SIGNALS];
+
+static void
+ide_greeter_section_default_init (IdeGreeterSectionInterface *iface)
+{
+ /**
+ * IdeGreeterSection::project-activated:
+ *
+ * The "project-activated" signal is emitted when a project has been
+ * selected by the user in the section.
+ *
+ * Use ide_greeter_section_emit_project_activated() to activate
+ * this signal.
+ *
+ * Since: 3.28
+ */
+ signals [PROJECT_ACTIVATED] =
+ g_signal_new ("project-activated",
+ G_TYPE_FROM_INTERFACE (iface),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IdeGreeterSectionInterface, project_activated),
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 1, IDE_TYPE_PROJECT_INFO);
+}
+
+/**
+ * ide_greeter_section_get_priority:
+ * @self: an #IdeGreeterSection
+ *
+ * Get the priority of the section. The lowest integral value is
+ * sorted first in the list of sections.
+ *
+ * Returns: the priority for the section
+ *
+ * Since: 3.28
+ */
+gint
+ide_greeter_section_get_priority (IdeGreeterSection *self)
+{
+ g_return_val_if_fail (IDE_IS_GREETER_SECTION (self), 0);
+
+ if (IDE_GREETER_SECTION_GET_IFACE (self)->get_priority)
+ return IDE_GREETER_SECTION_GET_IFACE (self)->get_priority (self);
+
+ return 0;
+}
+
+/**
+ * ide_greeter_section_filter:
+ * @self: a #IdeGreeterSection
+ * @spec: (nullable): a #DzlPatternSpec or %NULL
+ *
+ * Refilter the visibile items based on the current search.
+ *
+ * Since: 3.28
+ */
+void
+ide_greeter_section_filter (IdeGreeterSection *self,
+ DzlPatternSpec *spec)
+{
+ g_return_if_fail (IDE_IS_GREETER_SECTION (self));
+
+ if (IDE_GREETER_SECTION_GET_IFACE (self)->filter)
+ IDE_GREETER_SECTION_GET_IFACE (self)->filter (self, spec);
+}
+
+void
+ide_greeter_section_emit_project_activated (IdeGreeterSection *self,
+ IdeProjectInfo *project_info)
+{
+ g_return_if_fail (IDE_IS_GREETER_SECTION (self));
+ g_return_if_fail (IDE_IS_PROJECT_INFO (project_info));
+
+ g_signal_emit (self, signals [PROJECT_ACTIVATED], 0, project_info);
+}
diff --git a/src/libide/greeter/ide-greeter-section.h b/src/libide/greeter/ide-greeter-section.h
new file mode 100644
index 0000000..741e261
--- /dev/null
+++ b/src/libide/greeter/ide-greeter-section.h
@@ -0,0 +1,53 @@
+/* ide-greeter-section.h
+ *
+ * Copyright (C) 2017 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/>.
+ */
+
+#pragma once
+
+#include <dazzle.h>
+
+#include "ide-version-macros.h"
+
+#include "projects/ide-project-info.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_GREETER_SECTION (ide_greeter_section_get_type ())
+
+G_DECLARE_INTERFACE (IdeGreeterSection, ide_greeter_section, IDE, GREETER_SECTION, GtkWidget)
+
+struct _IdeGreeterSectionInterface
+{
+ GTypeInterface parent_iface;
+
+ void (*project_activated) (IdeGreeterSection *self,
+ IdeProjectInfo *project_info);
+ gint (*get_priority) (IdeGreeterSection *self);
+ void (*filter) (IdeGreeterSection *self,
+ DzlPatternSpec *pattern);
+};
+
+IDE_AVAILABLE_IN_3_28
+gint ide_greeter_section_get_priority (IdeGreeterSection *self);
+IDE_AVAILABLE_IN_3_28
+void ide_greeter_section_filter (IdeGreeterSection *self,
+ DzlPatternSpec *spec);
+IDE_AVAILABLE_IN_3_28
+void ide_greeter_section_emit_project_activated (IdeGreeterSection *self,
+ IdeProjectInfo *project_info);
+
+G_END_DECLS
diff --git a/src/libide/greeter/meson.build b/src/libide/greeter/meson.build
index 574db12..594ba66 100644
--- a/src/libide/greeter/meson.build
+++ b/src/libide/greeter/meson.build
@@ -3,8 +3,8 @@ greeter_private_sources = [
'ide-greeter-perspective.h',
'ide-greeter-project-row.c',
'ide-greeter-project-row.h',
- 'ide-newcomer-project.c',
- 'ide-newcomer-project.h',
+ 'ide-greeter-section.c',
+ 'ide-greeter-section.h',
]
libide_private_sources += files(greeter_private_sources)
diff --git a/src/libide/ide.h b/src/libide/ide.h
index 63f7b37..3b94426 100644
--- a/src/libide/ide.h
+++ b/src/libide/ide.h
@@ -101,6 +101,7 @@ G_BEGIN_DECLS
#include "files/ide-file-settings.h"
#include "files/ide-file.h"
#include "genesis/ide-genesis-addin.h"
+#include "greeter/ide-greeter-section.h"
#include "highlighting/ide-highlight-engine.h"
#include "highlighting/ide-highlight-index.h"
#include "highlighting/ide-highlighter.h"
diff --git a/src/libide/libide.gresource.xml b/src/libide/libide.gresource.xml
index ebfe845..c238e6b 100644
--- a/src/libide/libide.gresource.xml
+++ b/src/libide/libide.gresource.xml
@@ -76,7 +76,6 @@
<file preprocess="xml-stripblanks" alias="ide-editor-view.ui">editor/ide-editor-view.ui</file>
<file preprocess="xml-stripblanks"
alias="ide-greeter-perspective.ui">greeter/ide-greeter-perspective.ui</file>
<file preprocess="xml-stripblanks"
alias="ide-greeter-project-row.ui">greeter/ide-greeter-project-row.ui</file>
- <file preprocess="xml-stripblanks" alias="ide-newcomer-project.ui">greeter/ide-newcomer-project.ui</file>
<file preprocess="xml-stripblanks" alias="ide-omni-bar.ui">workbench/ide-omni-bar.ui</file>
<file preprocess="xml-stripblanks"
alias="ide-omni-pausable-row.ui">workbench/ide-omni-pausable-row.ui</file>
<file preprocess="xml-stripblanks"
alias="ide-preferences-language-row.ui">preferences/ide-preferences-language-row.ui</file>
@@ -91,18 +90,6 @@
<file preprocess="xml-stripblanks"
alias="ide-workbench-message.ui">workbench/ide-workbench-message.ui</file>
</gresource>
- <!-- Icons used by the greeter for newcomer projects -->
- <gresource prefix="/org/gnome/builder/icons">
- <file alias="256x256/apps/org.gnome.Maps.png">greeter/icons/org.gnome.Maps.png</file>
- <file alias="256x256/apps/org.gnome.Music.png">greeter/icons/org.gnome.Music.png</file>
- <file alias="256x256/apps/org.gnome.Photos.png">greeter/icons/org.gnome.Photos.png</file>
- <file alias="512x512/apps/org.gnome.Calendar.png">greeter/icons/org.gnome.Calendar.png</file>
- <file alias="512x512/apps/org.gnome.Games.png">greeter/icons/org.gnome.Games.png</file>
- <file alias="512x512/apps/org.gnome.Nautilus.png">greeter/icons/org.gnome.Nautilus.png</file>
- <file alias="512x512/apps/org.gnome.Polari.png">greeter/icons/org.gnome.Polari.png</file>
- <file alias="512x512/apps/org.gnome.Todo.png">greeter/icons/org.gnome.Todo.png</file>
- </gresource>
-
<gresource prefix="/org/gnome/builder/plugins/buildconfig">
<file alias="buildconfig.plugin">buildconfig/buildconfig.plugin</file>
</gresource>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]