[gnome-builder] plugins/create-project: port to GTK 4



commit 4654715ece03cab30f7786d35c25fce356bcc9f7
Author: Christian Hergert <chergert redhat com>
Date:   Mon Jul 11 22:25:38 2022 -0700

    plugins/create-project: port to GTK 4
    
    This vastly cleans up how we create projects using the new help from
    libide-projects to instantiate templates.
    
     - Remove surfaces
     - Remove license resources
     - Remove libdazzle usage
     - Add page to greeter workspace

 .../create-project/create-project.gresource.xml    |  24 +-
 .../gbp-create-project-application-addin.c         |   5 +-
 .../create-project/gbp-create-project-surface.c    | 976 ---------------------
 .../create-project/gbp-create-project-surface.h    |  39 -
 .../create-project/gbp-create-project-surface.ui   | 397 ---------
 .../gbp-create-project-template-icon.c             | 154 ----
 .../gbp-create-project-template-icon.h             |  33 -
 .../gbp-create-project-template-icon.ui            |  27 -
 .../create-project/gbp-create-project-widget.c     | 430 +++++++++
 .../create-project/gbp-create-project-widget.h     |  39 +
 .../create-project/gbp-create-project-widget.ui    | 199 +++++
 .../gbp-create-project-workspace-addin.c           |  34 +-
 src/plugins/create-project/gtk/menus.ui            |  12 +-
 src/plugins/create-project/meson.build             |   3 +-
 src/plugins/create-project/resources/agpl_3_full   | 662 --------------
 src/plugins/create-project/resources/agpl_3_short  |  16 -
 src/plugins/create-project/resources/apache_2_full | 202 -----
 .../create-project/resources/apache_2_short        |  15 -
 src/plugins/create-project/resources/gpl_2_full    | 340 -------
 src/plugins/create-project/resources/gpl_2_short   |  17 -
 src/plugins/create-project/resources/gpl_3_full    | 675 --------------
 src/plugins/create-project/resources/gpl_3_short   |  16 -
 src/plugins/create-project/resources/lgpl_2_1_full | 502 -----------
 .../create-project/resources/lgpl_2_1_short        |  17 -
 src/plugins/create-project/resources/lgpl_3_full   | 165 ----
 src/plugins/create-project/resources/lgpl_3_short  |  16 -
 src/plugins/create-project/resources/mit_x11_full  |  25 -
 src/plugins/create-project/resources/mit_x11_short |  27 -
 src/plugins/create-project/themes/shared.css       |  17 -
 29 files changed, 702 insertions(+), 4382 deletions(-)
---
diff --git a/src/plugins/create-project/create-project.gresource.xml 
b/src/plugins/create-project/create-project.gresource.xml
index cd061bf4e..abadc3aa2 100644
--- a/src/plugins/create-project/create-project.gresource.xml
+++ b/src/plugins/create-project/create-project.gresource.xml
@@ -2,29 +2,7 @@
 <gresources>
   <gresource prefix="/plugins/create-project">
     <file preprocess="xml-stripblanks">gtk/menus.ui</file>
-    <file preprocess="xml-stripblanks">gbp-create-project-surface.ui</file>
-    <file preprocess="xml-stripblanks">gbp-create-project-template-icon.ui</file>
+    <file preprocess="xml-stripblanks">gbp-create-project-widget.ui</file>
     <file>create-project.plugin</file>
-    <file>themes/shared.css</file>
-  </gresource>
-
-  <gresource prefix="/plugins/create-project/license/full">
-    <file compressed="true" alias="agpl_3">resources/agpl_3_full</file>
-    <file compressed="true" alias="apache_2">resources/apache_2_full</file>
-    <file compressed="true" alias="gpl_2">resources/gpl_2_full</file>
-    <file compressed="true" alias="gpl_3">resources/gpl_3_full</file>
-    <file compressed="true" alias="lgpl_2_1">resources/lgpl_2_1_full</file>
-    <file compressed="true" alias="lgpl_3">resources/lgpl_3_full</file>
-    <file compressed="true" alias="mit_x11">resources/mit_x11_full</file>
-  </gresource>
-
-  <gresource prefix="/plugins/create-project/license/short">
-    <file compressed="true" alias="agpl_3">resources/agpl_3_short</file>
-    <file compressed="true" alias="apache_2">resources/apache_2_short</file>
-    <file compressed="true" alias="gpl_2">resources/gpl_2_short</file>
-    <file compressed="true" alias="gpl_3">resources/gpl_3_short</file>
-    <file compressed="true" alias="lgpl_2_1">resources/lgpl_2_1_short</file>
-    <file compressed="true" alias="lgpl_3">resources/lgpl_3_short</file>
-    <file compressed="true" alias="mit_x11">resources/mit_x11_short</file>
   </gresource>
 </gresources>
diff --git a/src/plugins/create-project/gbp-create-project-application-addin.c 
b/src/plugins/create-project/gbp-create-project-application-addin.c
index d99dd8220..0a28aa276 100644
--- a/src/plugins/create-project/gbp-create-project-application-addin.c
+++ b/src/plugins/create-project/gbp-create-project-application-addin.c
@@ -23,6 +23,7 @@
 #include "config.h"
 
 #include <glib/gi18n.h>
+
 #include <libide-greeter.h>
 #include <libide-gui.h>
 
@@ -81,7 +82,7 @@ gbp_create_project_application_addin_handle_command_line (IdeApplicationAddin
       workspace = ide_greeter_workspace_new (app);
       ide_workbench_add_workspace (workbench, IDE_WORKSPACE (workspace));
 
-      ide_workspace_set_visible_surface_name (IDE_WORKSPACE (workspace), "create-project");
+      ide_greeter_workspace_set_page_name (workspace, "create-project");
       ide_workbench_focus_workspace (workbench, IDE_WORKSPACE (workspace));
     }
 }
@@ -103,7 +104,7 @@ create_project_cb (GSimpleAction *action,
   workspace = ide_greeter_workspace_new (IDE_APPLICATION_DEFAULT);
   ide_workbench_add_workspace (workbench, IDE_WORKSPACE (workspace));
 
-  ide_workspace_set_visible_surface_name (IDE_WORKSPACE (workspace), "create-project");
+  ide_greeter_workspace_set_page_name (workspace, "create-project");
   ide_workbench_focus_workspace (workbench, IDE_WORKSPACE (workspace));
 }
 
diff --git a/src/plugins/create-project/gbp-create-project-widget.c 
b/src/plugins/create-project/gbp-create-project-widget.c
new file mode 100644
index 000000000..7d31a44f8
--- /dev/null
+++ b/src/plugins/create-project/gbp-create-project-widget.c
@@ -0,0 +1,430 @@
+/* gbp-create-project-widget.c
+ *
+ * Copyright 2016-2022 Christian Hergert <christian hergert me>
+ *
+ * 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 "gbp-create-project-widget"
+
+#include "config.h"
+
+#include <adwaita.h>
+#include <glib/gi18n.h>
+
+#include <libide-greeter.h>
+#include <libide-plugins.h>
+#include <libide-projects.h>
+#include <libide-vcs.h>
+
+#include "gbp-create-project-widget.h"
+
+struct _GbpCreateProjectWidget
+{
+  GtkWidget         parent_instance;
+
+  GtkWidget        *main;
+  IdeTemplateInput *input;
+  GtkImage         *directory_clash;
+
+  AdwEntryRow      *app_id_row;
+  AdwEntryRow      *language_row;
+  AdwComboRow      *license_row;
+  AdwEntryRow      *location_row;
+  AdwEntryRow      *name_row;
+  AdwEntryRow      *template_row;
+
+  guint             loaded : 1;
+};
+
+enum {
+  PROP_0,
+  PROP_IS_READY,
+  N_PROPS
+};
+
+G_DEFINE_FINAL_TYPE (GbpCreateProjectWidget, gbp_create_project_widget, GTK_TYPE_WIDGET)
+
+static GParamSpec *properties [N_PROPS];
+
+#define ADD_ERROR(widget) gtk_widget_add_css_class(GTK_WIDGET(widget),"error")
+#define REMOVE_ERROR(widget) gtk_widget_remove_css_class(GTK_WIDGET(widget),"error")
+
+static gboolean
+gbp_create_project_widget_check_ready (GbpCreateProjectWidget *self)
+{
+  g_assert (GBP_IS_CREATE_PROJECT_WIDGET (self));
+
+  return TRUE;
+}
+
+static void
+template_changed_cb (GbpCreateProjectWidget *self,
+                     GParamSpec             *pspec,
+                     AdwComboRow            *row)
+{
+  IdeProjectTemplate *template;
+  const char *id;
+
+  g_assert (GBP_IS_CREATE_PROJECT_WIDGET (self));
+  g_assert (ADW_IS_COMBO_ROW (row));
+
+  template = adw_combo_row_get_selected_item (row);
+
+  id = ide_project_template_get_id (template);
+  ide_template_input_set_template (self->input, id);
+}
+
+static void
+language_changed_cb (GbpCreateProjectWidget *self,
+                     GParamSpec             *pspec,
+                     AdwComboRow            *row)
+{
+  GtkStringObject *string;
+
+  g_assert (GBP_IS_CREATE_PROJECT_WIDGET (self));
+  g_assert (ADW_IS_COMBO_ROW (row));
+
+  string = adw_combo_row_get_selected_item (row);
+
+  ide_template_input_set_language (self->input,
+                                   gtk_string_object_get_string (string));
+}
+
+static void
+license_changed_cb (GbpCreateProjectWidget *self,
+                    GParamSpec             *pspec,
+                    AdwComboRow            *row)
+{
+  GtkStringObject *string;
+
+  g_assert (GBP_IS_CREATE_PROJECT_WIDGET (self));
+  g_assert (ADW_IS_COMBO_ROW (row));
+
+  string = adw_combo_row_get_selected_item (row);
+
+  ide_template_input_set_license_name (self->input,
+                                       gtk_string_object_get_string (string));
+}
+
+static void
+location_row_changed_cb (GbpCreateProjectWidget *self,
+                         GtkEditable            *editable)
+{
+  g_autofree char *expanded = NULL;
+  g_autoptr(GFile) directory = NULL;
+  const char *text;
+
+  g_assert (GBP_IS_CREATE_PROJECT_WIDGET (self));
+  g_assert (GTK_IS_EDITABLE (editable));
+
+  text = gtk_editable_get_text (editable);
+  expanded = ide_path_expand (text);
+  directory = g_file_new_for_path (expanded);
+
+  ide_template_input_set_directory (self->input, directory);
+}
+
+static void
+input_notify_cb (GbpCreateProjectWidget *self,
+                 GParamSpec             *pspec,
+                 IdeTemplateInput       *input)
+{
+  IdeTemplateInputValidation flags;
+
+  g_assert (GBP_IS_CREATE_PROJECT_WIDGET (self));
+  g_assert (IDE_IS_TEMPLATE_INPUT (input));
+
+  if (!self->loaded)
+    return;
+
+  flags = ide_template_input_validate (input);
+
+#define CHECK_FLAG(FLAG,widget)                         \
+  G_STMT_START {                                        \
+    if ((flags & IDE_TEMPLATE_INPUT_INVAL_##FLAG) != 0) \
+      ADD_ERROR(widget);                                \
+    else                                                \
+      REMOVE_ERROR(widget);                             \
+  } G_STMT_END
+
+  CHECK_FLAG (APP_ID, self->app_id_row);
+  CHECK_FLAG (LANGUAGE, self->language_row);
+  CHECK_FLAG (LOCATION, self->location_row);
+  CHECK_FLAG (NAME, self->name_row);
+  CHECK_FLAG (TEMPLATE, self->template_row);
+
+#undef CHECK_FLAG
+
+  if ((flags & IDE_TEMPLATE_INPUT_INVAL_LOCATION) &&
+      !(flags & IDE_TEMPLATE_INPUT_INVAL_NAME))
+    {
+      ADD_ERROR (self->name_row);
+      gtk_widget_show (GTK_WIDGET (self->directory_clash));
+    }
+  else
+    {
+      gtk_widget_hide (GTK_WIDGET (self->directory_clash));
+    }
+
+  gtk_widget_action_set_enabled (GTK_WIDGET (self),
+                                 "create-project.expand",
+                                 flags == IDE_TEMPLATE_INPUT_VALID);
+}
+
+static void
+select_folder_response_cb (GbpCreateProjectWidget *self,
+                           int                     response_id,
+                           GtkFileChooserNative   *native)
+{
+  g_assert (GBP_IS_CREATE_PROJECT_WIDGET (self));
+  g_assert (GTK_IS_FILE_CHOOSER_NATIVE (native));
+
+  if (response_id == GTK_RESPONSE_ACCEPT)
+    {
+      g_autoptr(GFile) file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (native));
+      g_autofree char *path = ide_path_collapse (g_file_peek_path (file));
+
+      gtk_editable_set_text (GTK_EDITABLE (self->location_row), path);
+    }
+
+  gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (native));
+}
+
+static void
+select_folder_action (GtkWidget  *widget,
+                      const char *action_name,
+                      GVariant   *param)
+{
+  GbpCreateProjectWidget *self = (GbpCreateProjectWidget *)widget;
+  GtkFileChooserNative *native;
+  GtkRoot *root;
+
+  g_assert (GBP_IS_CREATE_PROJECT_WIDGET (self));
+
+  root = gtk_widget_get_root (widget);
+  native = gtk_file_chooser_native_new (_("Select Location"),
+                                        GTK_WINDOW (root),
+                                        GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+                                        _("Select"),
+                                        _("Cancel"));
+  gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (native),
+                                       ide_template_input_get_directory (self->input),
+                                       NULL);
+  g_signal_connect_object (native,
+                           "response",
+                           G_CALLBACK (select_folder_response_cb),
+                           self,
+                           G_CONNECT_SWAPPED);
+  gtk_native_dialog_show (GTK_NATIVE_DIALOG (native));
+}
+
+static void
+gbp_create_project_widget_expand_cb (GObject      *object,
+                                     GAsyncResult *result,
+                                     gpointer      user_data)
+{
+  IdeTemplateInput *input = (IdeTemplateInput *)object;
+  g_autoptr(IdeGreeterWorkspace) greeter = user_data;
+  g_autoptr(GError) error = NULL;
+  g_autoptr(GFile) directory = NULL;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_TEMPLATE_INPUT (input));
+  g_assert (G_IS_ASYNC_RESULT (result));
+  g_assert (IDE_IS_GREETER_WORKSPACE (greeter));
+
+  if (!(directory = ide_template_input_expand_finish (input, result, &error)))
+    {
+      /* Make sure it wasn't closed/cancelled */
+      if (gtk_widget_get_visible (GTK_WIDGET (greeter)))
+        {
+          GtkWidget *dialog;
+
+          dialog = gtk_message_dialog_new (GTK_WINDOW (greeter),
+                                           (GTK_DIALOG_MODAL |
+                                            GTK_DIALOG_DESTROY_WITH_PARENT |
+                                            GTK_DIALOG_USE_HEADER_BAR),
+                                           GTK_MESSAGE_ERROR,
+                                           GTK_BUTTONS_CLOSE,
+                                           "%s",
+                                           _("Failed to Create Project"));
+          gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                                                    "%s", error->message);
+          g_signal_connect (dialog,
+                            "response",
+                            G_CALLBACK (gtk_window_destroy),
+                            NULL);
+          gtk_window_present (GTK_WINDOW (dialog));
+        }
+    }
+  else
+    {
+      g_autoptr(IdeProjectInfo) project_info = NULL;
+
+      project_info = ide_project_info_new ();
+      ide_project_info_set_file (project_info, directory);
+      ide_project_info_set_directory (project_info, directory);
+
+      ide_greeter_workspace_open_project (greeter, project_info);
+    }
+
+  ide_greeter_workspace_end (greeter);
+
+  IDE_EXIT;
+}
+
+static void
+expand_action (GtkWidget  *widget,
+               const char *action_name,
+               GVariant   *param)
+{
+  GbpCreateProjectWidget *self = (GbpCreateProjectWidget *)widget;
+  IdeGreeterWorkspace *greeter;
+  IdeContext *context;
+
+  IDE_ENTRY;
+
+  g_assert (GBP_IS_CREATE_PROJECT_WIDGET (self));
+
+  greeter = IDE_GREETER_WORKSPACE (ide_widget_get_workspace (widget));
+  context = ide_workspace_get_context (IDE_WORKSPACE (greeter));
+
+  ide_greeter_workspace_begin (greeter);
+
+  gtk_widget_action_set_enabled (widget, "create-project.expand", FALSE);
+  ide_template_input_expand_async (self->input,
+                                   context,
+                                   ide_workspace_get_cancellable (IDE_WORKSPACE (greeter)),
+                                   gbp_create_project_widget_expand_cb,
+                                   g_object_ref (greeter));
+
+  IDE_EXIT;
+}
+
+static guint
+find_license (GbpCreateProjectWidget *self,
+              const char             *license)
+{
+  GListModel *model;
+  guint n_items;
+
+  g_assert (GBP_IS_CREATE_PROJECT_WIDGET (self));
+  g_assert (license != NULL);
+
+  model = ide_template_input_get_licenses_model (self->input);
+  n_items = g_list_model_get_n_items (model);
+
+  for (guint i = 0; i < n_items; i++)
+    {
+      g_autoptr(GtkStringObject) strobj = g_list_model_get_item (model, i);
+      const char *str = gtk_string_object_get_string (strobj);
+
+      if (ide_str_equal0 (str, license))
+        return i;
+    }
+
+  return 0;
+}
+
+static void
+gbp_create_project_widget_dispose (GObject *object)
+{
+  GbpCreateProjectWidget *self = (GbpCreateProjectWidget *)object;
+
+  g_clear_pointer (&self->main, gtk_widget_unparent);
+
+  G_OBJECT_CLASS (gbp_create_project_widget_parent_class)->dispose (object);
+}
+
+static void
+gbp_create_project_widget_get_property (GObject    *object,
+                                        guint       prop_id,
+                                        GValue     *value,
+                                        GParamSpec *pspec)
+{
+  GbpCreateProjectWidget *self = GBP_CREATE_PROJECT_WIDGET (object);
+
+  switch (prop_id)
+    {
+    case PROP_IS_READY:
+      g_value_set_boolean (value, gbp_create_project_widget_check_ready (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gbp_create_project_widget_class_init (GbpCreateProjectWidgetClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->dispose = gbp_create_project_widget_dispose;
+  object_class->get_property = gbp_create_project_widget_get_property;
+
+  properties [PROP_IS_READY] =
+    g_param_spec_boolean ("is-ready", NULL, NULL, FALSE,
+                          (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+
+  gtk_widget_class_set_template_from_resource (widget_class, 
"/plugins/create-project/gbp-create-project-widget.ui");
+
+  gtk_widget_class_bind_template_child (widget_class, GbpCreateProjectWidget, app_id_row);
+  gtk_widget_class_bind_template_child (widget_class, GbpCreateProjectWidget, directory_clash);
+  gtk_widget_class_bind_template_child (widget_class, GbpCreateProjectWidget, input);
+  gtk_widget_class_bind_template_child (widget_class, GbpCreateProjectWidget, language_row);
+  gtk_widget_class_bind_template_child (widget_class, GbpCreateProjectWidget, license_row);
+  gtk_widget_class_bind_template_child (widget_class, GbpCreateProjectWidget, location_row);
+  gtk_widget_class_bind_template_child (widget_class, GbpCreateProjectWidget, main);
+  gtk_widget_class_bind_template_child (widget_class, GbpCreateProjectWidget, name_row);
+  gtk_widget_class_bind_template_child (widget_class, GbpCreateProjectWidget, template_row);
+
+  gtk_widget_class_bind_template_callback (widget_class, template_changed_cb);
+  gtk_widget_class_bind_template_callback (widget_class, language_changed_cb);
+  gtk_widget_class_bind_template_callback (widget_class, license_changed_cb);
+  gtk_widget_class_bind_template_callback (widget_class, location_row_changed_cb);
+  gtk_widget_class_bind_template_callback (widget_class, input_notify_cb);
+
+  gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
+
+  gtk_widget_class_install_action (widget_class, "create-project.select-folder", NULL, select_folder_action);
+  gtk_widget_class_install_action (widget_class, "create-project.expand", NULL, expand_action);
+
+  g_type_ensure (IDE_TYPE_TEMPLATE_INPUT);
+}
+
+static void
+gbp_create_project_widget_init (GbpCreateProjectWidget *self)
+{
+  g_autofree char *projects_dir = ide_path_collapse (ide_get_projects_dir ());
+  g_autoptr(GSettings) settings = g_settings_new ("org.gnome.builder");
+  g_autofree char *default_license = g_settings_get_string (settings, "default-license");
+
+  gtk_widget_init_template (GTK_WIDGET (self));
+
+  gtk_editable_set_text (GTK_EDITABLE (self->location_row), projects_dir);
+  adw_combo_row_set_selected (self->license_row, find_license (self, default_license));
+
+  /* Always start disabled */
+  gtk_widget_action_set_enabled (GTK_WIDGET (self), "create-project.expand", FALSE);
+
+  self->loaded = TRUE;
+}
diff --git a/src/plugins/create-project/gbp-create-project-widget.h 
b/src/plugins/create-project/gbp-create-project-widget.h
new file mode 100644
index 000000000..36ca939f0
--- /dev/null
+++ b/src/plugins/create-project/gbp-create-project-widget.h
@@ -0,0 +1,39 @@
+/* gbp-create-project-widget.h
+ *
+ * Copyright 2016-2022 Christian Hergert <christian hergert me>
+ *
+ * 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
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_CREATE_PROJECT_WIDGET (gbp_create_project_widget_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpCreateProjectWidget, gbp_create_project_widget, GBP, CREATE_PROJECT_WIDGET, 
GtkWidget)
+
+void     gbp_create_project_widget_create_async  (GbpCreateProjectWidget  *self,
+                                                  GCancellable            *cancellable,
+                                                  GAsyncReadyCallback      callback,
+                                                  gpointer                 user_data);
+gboolean gbp_create_project_widget_create_finish (GbpCreateProjectWidget  *self,
+                                                  GAsyncResult            *result,
+                                                  GError                 **error);
+
+G_END_DECLS
diff --git a/src/plugins/create-project/gbp-create-project-widget.ui 
b/src/plugins/create-project/gbp-create-project-widget.ui
new file mode 100644
index 000000000..604b1c41e
--- /dev/null
+++ b/src/plugins/create-project/gbp-create-project-widget.ui
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="GbpCreateProjectWidget" parent="GtkWidget">
+    <child>
+      <object class="AdwClamp" id="main">
+        <property name="orientation">horizontal</property>
+        <property name="maximum-size">550</property>
+        <child>
+          <object class="GtkBox">
+            <property name="margin-top">64</property>
+            <property name="margin-bottom">64</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">24</property>
+            <child>
+              <object class="AdwPreferencesGroup">
+                <child>
+                  <object class="AdwEntryRow" id="name_row">
+                    <property name="title" translatable="yes">Project Name</property>
+                    <property name="text" bind-source="input" bind-property="name" 
bind-flags="sync-create|bidirectional"/>
+                    <child type="suffix">
+                      <object class="GtkImage" id="directory_clash">
+                        <property name="visible">false</property>
+                        <property name="icon-name">dialog-error-symbolic</property>
+                        <property name="tooltip-text" translatable="yes">A subdirectory with this name 
already exists</property>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="label" translatable="yes">A unique name that is used for the project 
folder and other resources. The name should be in lower case without spaces and should not start with a 
number.</property>
+                    <property name="margin-top">12</property>
+                    <property name="wrap">true</property>
+                    <property name="xalign">0</property>
+                    <style>
+                      <class name="caption"/>
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="AdwPreferencesGroup">
+                <child>
+                  <object class="AdwEntryRow" id="app_id_row">
+                    <property name="title" translatable="yes">Application ID…</property>
+                    <property name="text" bind-source="input" bind-property="app-id" 
bind-flags="sync-create|bidirectional"/>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="label" translatable="yes">A reverse domain-name identifier used to 
identify the application, such as "org.gnome.Builder". It may not contain dashes.</property>
+                    <property name="margin-top">12</property>
+                    <property name="wrap">true</property>
+                    <property name="xalign">0</property>
+                    <style>
+                      <class name="caption"/>
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="AdwPreferencesGroup">
+                <child>
+                  <object class="AdwEntryRow" id="location_row">
+                    <property name="title" translatable="yes">Location</property>
+                    <signal name="changed" handler="location_row_changed_cb" swapped="true" 
object="GbpCreateProjectWidget"/>
+                    <child type="suffix">
+                      <object class="GtkButton">
+                        <property name="action-name">create-project.select-folder</property>
+                        <property name="valign">center</property>
+                        <property name="icon-name">folder-symbolic</property>
+                        <style>
+                          <class name="flat"/>
+                        </style>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="label" translatable="yes">The project will be created in a new 
subdirectory.</property>
+                    <property name="margin-top">12</property>
+                    <property name="wrap">true</property>
+                    <property name="xalign">0</property>
+                    <style>
+                      <class name="caption"/>
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="AdwPreferencesGroup">
+                <child>
+                  <object class="AdwComboRow" id="language_row">
+                    <property name="title" translatable="yes">Language</property>
+                    <property name="model" bind-source="input" bind-property="languages-model" 
bind-flags="sync-create"/>
+                    <signal name="notify::selected-item" handler="language_changed_cb" swapped="true" 
object="GbpCreateProjectWidget"/>
+                  </object>
+                </child>
+                <child>
+                  <object class="AdwComboRow" id="license_row">
+                    <property name="title" translatable="yes">License</property>
+                    <property name="model" bind-source="input" bind-property="licenses-model" 
bind-flags="sync-create"/>
+                    <signal name="notify::selected-item" handler="license_changed_cb" swapped="true" 
object="GbpCreateProjectWidget"/>
+                  </object>
+                </child>
+                <child>
+                  <object class="AdwActionRow">
+                    <property name="title" translatable="yes">Version Control</property>
+                    <property name="activatable-widget">version_control_switch</property>
+                    <child type="suffix">
+                      <object class="GtkSwitch" id="version_control_switch">
+                        <property name="valign">center</property>
+                        <property name="active" bind-source="input" bind-property="use-version-control" 
bind-flags="sync-create"/>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="AdwComboRow" id="template_row">
+                    <property name="title" translatable="yes">Template</property>
+                    <property name="model" bind-source="input" bind-property="templates-model" 
bind-flags="sync-create"/>
+                    <property name="expression">
+                      <lookup name="name" type="IdeProjectTemplate"/>
+                    </property>
+                    <signal name="notify::selected-item" handler="template_changed_cb" swapped="true" 
object="GbpCreateProjectWidget"/>
+                    <property name="list-factory">
+                      <object class="GtkBuilderListItemFactory">
+                        <property name="bytes"><![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="GtkListItem">
+    <property name="child">
+      <object class="GtkBox">
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkLabel">
+            <property name="xalign">0</property>
+            <property name="hexpand">true</property>
+            <binding name="label">
+              <lookup name="name" type="IdeProjectTemplate">
+                <lookup name="item">GtkListItem</lookup>
+              </lookup>
+            </binding>
+          </object>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="xalign">0</property>
+            <property name="hexpand">true</property>
+            <style>
+              <class name="caption"/>
+              <class name="dim-label"/>
+            </style>
+            <binding name="label">
+              <lookup name="description" type="IdeProjectTemplate">
+                <lookup name="item">GtkListItem</lookup>
+              </lookup>
+            </binding>
+          </object>
+        </child>
+      </object>
+    </property>
+  </template>
+</interface>
+]]>
+                        </property>
+                      </object>
+                    </property>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkButton">
+                <property name="action-name">create-project.expand</property>
+                <property name="label" translatable="yes">Create Project</property>
+                <property name="margin-top">12</property>
+                <property name="halign">end</property>
+                <style>
+                  <class name="suggested-action"/>
+                </style>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+  <object class="IdeTemplateInput" id="input">
+    <signal name="notify" handler="input_notify_cb" swapped="true" object="GbpCreateProjectWidget"/>
+  </object>
+</interface>
diff --git a/src/plugins/create-project/gbp-create-project-workspace-addin.c 
b/src/plugins/create-project/gbp-create-project-workspace-addin.c
index b8000ed6a..4e4fed890 100644
--- a/src/plugins/create-project/gbp-create-project-workspace-addin.c
+++ b/src/plugins/create-project/gbp-create-project-workspace-addin.c
@@ -23,15 +23,16 @@
 #include "config.h"
 
 #include <glib/gi18n.h>
+
 #include <libide-greeter.h>
 
-#include "gbp-create-project-surface.h"
+#include "gbp-create-project-widget.h"
 #include "gbp-create-project-workspace-addin.h"
 
 struct _GbpCreateProjectWorkspaceAddin
 {
-  GObject     parent_instance;
-  IdeSurface *surface;
+  GObject                 parent_instance;
+  GbpCreateProjectWidget *widget;
 };
 
 static void
@@ -40,23 +41,28 @@ gbp_create_project_workspace_addin_load (IdeWorkspaceAddin *addin,
 {
   GbpCreateProjectWorkspaceAddin *self = (GbpCreateProjectWorkspaceAddin *)addin;
 
+  IDE_ENTRY;
+
   g_assert (GBP_IS_CREATE_PROJECT_WORKSPACE_ADDIN (self));
   g_assert (IDE_IS_GREETER_WORKSPACE (workspace));
 
   ide_greeter_workspace_add_button (IDE_GREETER_WORKSPACE (workspace),
                                     g_object_new (GTK_TYPE_BUTTON,
-                                                  "action-name", "win.surface",
+                                                  "action-name", "greeter.page",
                                                   "action-target", g_variant_new_string ("create-project"),
-                                                  "label", _("Start _New Project…"),
+                                                  "label", _("Create _New Project…"),
                                                   "use-underline", TRUE,
                                                   "visible", TRUE,
                                                   NULL),
                                     -10);
 
-  self->surface = g_object_new (GBP_TYPE_CREATE_PROJECT_SURFACE,
-                                "visible", TRUE,
-                                NULL);
-  ide_workspace_add_surface (workspace, self->surface);
+  self->widget = g_object_new (GBP_TYPE_CREATE_PROJECT_WIDGET, NULL);
+  ide_greeter_workspace_add_page (IDE_GREETER_WORKSPACE (workspace),
+                                  GTK_WIDGET (self->widget),
+                                  "create-project",
+                                  _("Create New Project"));
+
+  IDE_EXIT;
 }
 
 static void
@@ -65,10 +71,16 @@ gbp_create_project_workspace_addin_unload (IdeWorkspaceAddin *addin,
 {
   GbpCreateProjectWorkspaceAddin *self = (GbpCreateProjectWorkspaceAddin *)addin;
 
+  IDE_ENTRY;
+
   g_assert (GBP_IS_CREATE_PROJECT_WORKSPACE_ADDIN (self));
   g_assert (IDE_IS_GREETER_WORKSPACE (workspace));
 
-  gtk_widget_destroy (GTK_WIDGET (self->surface));
+  ide_greeter_workspace_remove_page (IDE_GREETER_WORKSPACE (workspace),
+                                     GTK_WIDGET (self->widget));
+  self->widget = NULL;
+
+  IDE_EXIT;
 }
 
 static void
@@ -79,7 +91,7 @@ workspace_addin_iface_init (IdeWorkspaceAddinInterface *iface)
 }
 
 G_DEFINE_FINAL_TYPE_WITH_CODE (GbpCreateProjectWorkspaceAddin, gbp_create_project_workspace_addin, 
G_TYPE_OBJECT,
-                         G_IMPLEMENT_INTERFACE (IDE_TYPE_WORKSPACE_ADDIN, workspace_addin_iface_init))
+                               G_IMPLEMENT_INTERFACE (IDE_TYPE_WORKSPACE_ADDIN, workspace_addin_iface_init))
 
 static void
 gbp_create_project_workspace_addin_class_init (GbpCreateProjectWorkspaceAddinClass *klass)
diff --git a/src/plugins/create-project/gtk/menus.ui b/src/plugins/create-project/gtk/menus.ui
index b63f5159b..9bdd78a0b 100644
--- a/src/plugins/create-project/gtk/menus.ui
+++ b/src/plugins/create-project/gtk/menus.ui
@@ -4,8 +4,8 @@
     <section id="ide-greeter-workspace-menu-projects">
       <item>
         <attribute name="id">ide-greeter-workspace-menu-new</attribute>
-        <attribute name="label" translatable="yes">_Start New Project…</attribute>
-        <attribute name="action">win.surface</attribute>
+        <attribute name="label" translatable="yes">Create New Project…</attribute>
+        <attribute name="action">greeter.page</attribute>
         <attribute name="target" type="s">'create-project'</attribute>
         <attribute name="before">ide-greeter-workspace-menu-clone</attribute>
       </item>
@@ -15,8 +15,8 @@
     <section id="ide-primary-workspace-menu-projects-section">
       <item>
         <attribute name="id">ide-primary-workspace-menu-new</attribute>
-        <attribute name="label" translatable="yes">_Start New Project…</attribute>
-        <attribute name="action">app.present-greeter-with-surface</attribute>
+        <attribute name="label" translatable="yes">Create New Project…</attribute>
+        <attribute name="action">app.present-greeter-with-page</attribute>
         <attribute name="target" type="s">'create-project'</attribute>
         <attribute name="after">ide-primary-workspace-menu-open</attribute>
       </item>
@@ -26,8 +26,8 @@
     <section id="ide-editor-workspace-menu-projects-section">
       <item>
         <attribute name="id">ide-editor-workspace-menu-new</attribute>
-        <attribute name="label" translatable="yes">_Start New Project…</attribute>
-        <attribute name="action">app.present-greeter-with-surface</attribute>
+        <attribute name="label" translatable="yes">Create New Project…</attribute>
+        <attribute name="action">app.present-greeter-with-page</attribute>
         <attribute name="target" type="s">'create-project'</attribute>
         <attribute name="after">ide-editor-workspace-menu-open</attribute>
       </item>
diff --git a/src/plugins/create-project/meson.build b/src/plugins/create-project/meson.build
index 94f1f09b4..87f3014e5 100644
--- a/src/plugins/create-project/meson.build
+++ b/src/plugins/create-project/meson.build
@@ -1,8 +1,7 @@
 plugins_sources += files([
   'create-project-plugin.c',
   'gbp-create-project-application-addin.c',
-  'gbp-create-project-template-icon.c',
-  'gbp-create-project-surface.c',
+  'gbp-create-project-widget.c',
   'gbp-create-project-workspace-addin.c',
 ])
 


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