[gnome-builder/wip/gtk4-port: 399/1774] libide/editor: start on editor workspace
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/gtk4-port: 399/1774] libide/editor: start on editor workspace
- Date: Mon, 11 Jul 2022 22:31:11 +0000 (UTC)
commit 0cf5e1f86423d32a4ec88ba1a8f3d0cabff067d9
Author: Christian Hergert <chergert redhat com>
Date: Tue Apr 5 17:31:30 2022 -0700
libide/editor: start on editor workspace
This is a revamp of the "simple" editor workspace which does not have
project capabilities (except when extending a primary workspace into
a second monitor).
src/libide/editor/ide-editor-workspace.c | 298 ++++++++++++++++++++++++++
src/libide/editor/ide-editor-workspace.h | 39 ++++
src/libide/editor/ide-editor-workspace.ui | 77 +++++++
src/libide/editor/libide-editor.gresource.xml | 1 +
src/libide/editor/libide-editor.h | 1 +
src/libide/editor/meson.build | 2 +
6 files changed, 418 insertions(+)
---
diff --git a/src/libide/editor/ide-editor-workspace.c b/src/libide/editor/ide-editor-workspace.c
new file mode 100644
index 000000000..fb68df80a
--- /dev/null
+++ b/src/libide/editor/ide-editor-workspace.c
@@ -0,0 +1,298 @@
+/* ide-editor-workspace.c
+ *
+ * Copyright 2018-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-editor-workspace"
+
+#include "config.h"
+
+#include "ide-editor-workspace.h"
+
+/**
+ * SECTION:ide-editor-workspace
+ * @title: IdeEditorWorkspace
+ * @short_description: The editor IDE window
+ *
+ * The editor workspace is a secondary workspace that may be added to
+ * supplement the IdePrimaryWorkspace for additional editors. It may
+ * also be used in an "editor" mode without a project.
+ */
+
+struct _IdeEditorWorkspace
+{
+ IdeWorkspace parent_instance;
+
+ /* Template widgets */
+ IdeHeaderBar *header_bar;
+ AdwWindowTitle *project_title;
+ GtkMenuButton *add_button;
+ PanelDock *dock;
+ PanelPaned *edge_start;
+ PanelPaned *edge_end;
+ PanelPaned *edge_bottom;
+ IdeGrid *grid;
+};
+
+G_DEFINE_FINAL_TYPE (IdeEditorWorkspace, ide_editor_workspace, IDE_TYPE_WORKSPACE)
+
+static gboolean
+file_to_short_path (GBinding *binding,
+ const GValue *from,
+ GValue *to,
+ gpointer user_data)
+{
+ GFile *file;
+
+ g_assert (G_IS_BINDING (binding));
+ g_assert (G_VALUE_HOLDS (from, G_TYPE_FILE));
+ g_assert (G_VALUE_HOLDS (to, G_TYPE_STRING));
+ g_assert (user_data == NULL);
+
+ if ((file = g_value_get_object (from)))
+ {
+ if (g_file_is_native (file))
+ g_value_take_string (to, ide_path_collapse (g_file_peek_path (file)));
+ else
+ g_value_take_string (to, g_file_get_uri (file));
+ }
+
+ return TRUE;
+}
+
+static void
+ide_editor_workspace_context_set (IdeWorkspace *workspace,
+ IdeContext *context)
+{
+ IdeEditorWorkspace *self = (IdeEditorWorkspace *)workspace;
+ IdeProjectInfo *project_info;
+ IdeWorkbench *workbench;
+
+ g_assert (IDE_IS_MAIN_THREAD ());
+ g_assert (IDE_IS_EDITOR_WORKSPACE (self));
+ g_assert (IDE_IS_CONTEXT (context));
+
+ IDE_WORKSPACE_CLASS (ide_editor_workspace_parent_class)->context_set (workspace, context);
+
+ workbench = ide_widget_get_workbench (GTK_WIDGET (self));
+ project_info = ide_workbench_get_project_info (workbench);
+
+ if (project_info)
+ g_object_bind_property (project_info, "name",
+ self->project_title, "title",
+ G_BINDING_SYNC_CREATE);
+ else
+ g_object_bind_property_full (context, "workdir",
+ self->project_title, "subtitle",
+ G_BINDING_SYNC_CREATE,
+ file_to_short_path, NULL, NULL, NULL);
+}
+
+static void
+ide_editor_workspace_add_page (IdeWorkspace *workspace,
+ IdePage *page,
+ IdePanelPosition *position)
+{
+ IdeEditorWorkspace *self = (IdeEditorWorkspace *)workspace;
+ PanelFrame *frame;
+ PanelDockPosition edge;
+ guint column;
+ guint row;
+
+ g_assert (IDE_IS_EDITOR_WORKSPACE (self));
+ g_assert (IDE_IS_PAGE (page));
+ g_assert (position != NULL);
+
+ ide_panel_position_get_edge (position, &edge);
+
+ switch (edge)
+ {
+ case PANEL_DOCK_POSITION_START:
+ case PANEL_DOCK_POSITION_END:
+ case PANEL_DOCK_POSITION_BOTTOM:
+ case PANEL_DOCK_POSITION_TOP:
+ default:
+ g_warning ("Editor workspace only supports center position");
+ return;
+
+ case PANEL_DOCK_POSITION_CENTER:
+ break;
+ }
+
+ if (!ide_panel_position_get_column (position, &column))
+ column = 0;
+
+ if (!ide_panel_position_get_row (position, &row))
+ row = 0;
+
+ frame = panel_grid_column_get_row (panel_grid_get_column (PANEL_GRID (self->grid), column), row);
+
+ /* TODO: Handle depth */
+ panel_frame_add (frame, PANEL_WIDGET (page));
+}
+
+static void
+ide_editor_workspace_add_pane (IdeWorkspace *workspace,
+ IdePane *pane,
+ IdePanelPosition *position)
+{
+ IdeEditorWorkspace *self = (IdeEditorWorkspace *)workspace;
+ PanelDockPosition edge;
+ PanelPaned *paned;
+ GtkWidget *parent;
+ guint depth;
+ guint nth = 0;
+
+ g_assert (IDE_IS_EDITOR_WORKSPACE (self));
+ g_assert (IDE_IS_PANE (pane));
+ g_assert (position != NULL);
+
+ ide_panel_position_get_edge (position, &edge);
+
+ switch (edge)
+ {
+ case PANEL_DOCK_POSITION_START:
+ paned = self->edge_start;
+ ide_panel_position_get_row (position, &nth);
+ break;
+
+ case PANEL_DOCK_POSITION_END:
+ paned = self->edge_end;
+ ide_panel_position_get_row (position, &nth);
+ break;
+
+ case PANEL_DOCK_POSITION_BOTTOM:
+ paned = self->edge_bottom;
+ ide_panel_position_get_column (position, &nth);
+ break;
+
+ case PANEL_DOCK_POSITION_TOP:
+ case PANEL_DOCK_POSITION_CENTER:
+ default:
+ g_warning ("Editor workspace only supports left/right/bottom edges");
+ return;
+ }
+
+ while (!(parent = panel_paned_get_nth_child (paned, nth)))
+ {
+ parent = panel_frame_new ();
+
+ if (edge == PANEL_DOCK_POSITION_START ||
+ edge == PANEL_DOCK_POSITION_END)
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (parent), GTK_ORIENTATION_VERTICAL);
+ else
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (parent), GTK_ORIENTATION_HORIZONTAL);
+
+ panel_paned_append (paned, parent);
+ }
+
+ if (ide_panel_position_get_depth (position, &depth))
+ {
+ /* TODO: setup position */
+ panel_frame_add (PANEL_FRAME (parent), PANEL_WIDGET (pane));
+ }
+ else
+ {
+ panel_frame_add (PANEL_FRAME (parent), PANEL_WIDGET (pane));
+ }
+}
+
+static IdeFrame *
+ide_editor_workspace_get_most_recent_frame (IdeWorkspace *workspace)
+{
+ IdeEditorWorkspace *self = (IdeEditorWorkspace *)workspace;
+
+ g_assert (IDE_IS_EDITOR_WORKSPACE (self));
+
+ return IDE_FRAME (panel_grid_get_most_recent_frame (PANEL_GRID (self->grid)));
+}
+
+static void
+ide_editor_workspace_dispose (GObject *object)
+{
+ IdeEditorWorkspace *self = (IdeEditorWorkspace *)object;
+
+ /* Ensure that the grid is removed first so that it will cleanup
+ * addins/pages/etc before we ever get to removing the workspace
+ * addins as part of the parent class.
+ */
+ panel_dock_remove (self->dock, GTK_WIDGET (self->grid));
+ self->grid = NULL;
+
+ G_OBJECT_CLASS (ide_editor_workspace_parent_class)->dispose (object);
+}
+
+static void
+ide_editor_workspace_class_init (IdeEditorWorkspaceClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ IdeWorkspaceClass *workspace_class = IDE_WORKSPACE_CLASS (klass);
+
+ object_class->dispose = ide_editor_workspace_dispose;
+
+ workspace_class->context_set = ide_editor_workspace_context_set;
+ workspace_class->add_page = ide_editor_workspace_add_page;
+ workspace_class->add_pane = ide_editor_workspace_add_pane;
+ workspace_class->get_most_recent_frame = ide_editor_workspace_get_most_recent_frame;
+
+ ide_workspace_class_set_kind (workspace_class, "editor");
+
+ gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/libide-editor/ide-editor-workspace.ui");
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorWorkspace, add_button);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorWorkspace, dock);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorWorkspace, edge_bottom);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorWorkspace, edge_end);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorWorkspace, edge_start);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorWorkspace, grid);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorWorkspace, header_bar);
+ gtk_widget_class_bind_template_child (widget_class, IdeEditorWorkspace, project_title);
+
+ g_type_ensure (IDE_TYPE_GRID);
+ g_type_ensure (IDE_TYPE_NOTIFICATIONS_BUTTON);
+ g_type_ensure (IDE_TYPE_OMNI_BAR);
+}
+
+static void
+ide_editor_workspace_init (IdeEditorWorkspace *self)
+{
+ GMenu *menu;
+
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ menu = ide_application_get_menu_by_id (IDE_APPLICATION_DEFAULT, "new-document-menu");
+ gtk_menu_button_set_menu_model (self->add_button, G_MENU_MODEL (menu));
+}
+
+/**
+ * ide_editor_workspace_new:
+ * @application: an #IdeApplication such as %IDE_APPLICATION_DEFAULT
+ *
+ * Creates a new #IdeEditorWorkspace
+ *
+ * Returns: (transfer full): an #IdeEditorWorkspace
+ */
+IdeEditorWorkspace *
+ide_editor_workspace_new (IdeApplication *application)
+{
+ g_return_val_if_fail (IDE_IS_APPLICATION (application), NULL);
+
+ return g_object_new (IDE_TYPE_EDITOR_WORKSPACE,
+ "application", application,
+ NULL);
+}
diff --git a/src/libide/editor/ide-editor-workspace.h b/src/libide/editor/ide-editor-workspace.h
new file mode 100644
index 000000000..6c5e4c0df
--- /dev/null
+++ b/src/libide/editor/ide-editor-workspace.h
@@ -0,0 +1,39 @@
+/* ide-editor-workspace.h
+ *
+ * Copyright 2018-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_EDITOR_INSIDE) && !defined (IDE_EDITOR_COMPILATION)
+# error "Only <libide-editor.h> can be included directly."
+#endif
+
+#include <libide-gui.h>
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_EDITOR_WORKSPACE (ide_editor_workspace_get_type())
+
+IDE_AVAILABLE_IN_ALL
+G_DECLARE_FINAL_TYPE (IdeEditorWorkspace, ide_editor_workspace, IDE, EDITOR_WORKSPACE, IdeWorkspace)
+
+IDE_AVAILABLE_IN_ALL
+IdeEditorWorkspace *ide_editor_workspace_new (IdeApplication *application);
+
+G_END_DECLS
diff --git a/src/libide/editor/ide-editor-workspace.ui b/src/libide/editor/ide-editor-workspace.ui
new file mode 100644
index 000000000..ee9243735
--- /dev/null
+++ b/src/libide/editor/ide-editor-workspace.ui
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="IdeEditorWorkspace" parent="IdeWorkspace">
+ <child type="titlebar">
+ <object class="IdeHeaderBar" id="header_bar">
+ <property name="menu-id">ide-editor-workspace-menu</property>
+ <child type="left">
+ <object class="GtkMenuButton" id="add_button">
+ <property name="icon-name">list-add-symbolic</property>
+ <property name="always-show-arrow">true</property>
+ </object>
+ </child>
+ <child type="left">
+ <object class="PanelDockSwitcher">
+ <property name="dock">dock</property>
+ <property name="position">start</property>
+ </object>
+ </child>
+ <child type="title">
+ <object class="AdwWindowTitle" id="project_title">
+ <property name="title" translatable="yes">Builder</property>
+ </object>
+ </child>
+ <child type="right">
+ <object class="GtkButton" id="search_button">
+ <property name="icon-name">edit-find-symbolic</property>
+ </object>
+ </child>
+ <child type="right">
+ <object class="IdeNotificationsButton" id="notifications_button"/>
+ </child>
+ <child type="right">
+ <object class="PanelDockSwitcher">
+ <property name="dock">dock</property>
+ <property name="position">end</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="PanelDock" id="dock">
+ <property name="start-width">300</property>
+ <property name="reveal-start">true</property>
+ <property name="vexpand">true</property>
+ <child type="center">
+ <object class="IdeGrid" id="grid">
+ </object>
+ </child>
+ <child type="start">
+ <object class="PanelPaned" id="edge_start">
+ <property name="orientation">vertical</property>
+ </object>
+ </child>
+ <child type="end">
+ <object class="PanelPaned" id="edge_end">
+ <property name="orientation">vertical</property>
+ </object>
+ </child>
+ <child type="bottom">
+ <object class="PanelPaned" id="edge_bottom">
+ <property name="orientation">horizontal</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child internal-child="statusbar">
+ <object class="PanelStatusbar">
+ <child type="suffix">
+ <object class="PanelDockSwitcher">
+ <property name="dock">dock</property>
+ <property name="position">bottom</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/src/libide/editor/libide-editor.gresource.xml b/src/libide/editor/libide-editor.gresource.xml
index 10cd2084c..f59bc8ada 100644
--- a/src/libide/editor/libide-editor.gresource.xml
+++ b/src/libide/editor/libide-editor.gresource.xml
@@ -2,6 +2,7 @@
<gresources>
<gresource prefix="/org/gnome/libide-editor/">
<file preprocess="xml-stripblanks">ide-editor-page.ui</file>
+ <file preprocess="xml-stripblanks">ide-editor-workspace.ui</file>
<file>style.css</file>
</gresource>
</gresources>
diff --git a/src/libide/editor/libide-editor.h b/src/libide/editor/libide-editor.h
index 6712eac86..9eecd565b 100644
--- a/src/libide/editor/libide-editor.h
+++ b/src/libide/editor/libide-editor.h
@@ -24,4 +24,5 @@
# include "ide-editor.h"
# include "ide-editor-page.h"
# include "ide-editor-page-addin.h"
+# include "ide-editor-workspace.h"
#undef IDE_EDITOR_INSIDE
diff --git a/src/libide/editor/meson.build b/src/libide/editor/meson.build
index ff79b834d..ff3abcdbc 100644
--- a/src/libide/editor/meson.build
+++ b/src/libide/editor/meson.build
@@ -14,6 +14,7 @@ libide_editor_public_headers = [
'ide-editor.h',
'ide-editor-page.h',
'ide-editor-page-addin.h',
+ 'ide-editor-workspace.h',
'libide-editor.h',
]
@@ -31,6 +32,7 @@ libide_editor_public_sources = [
'ide-editor.c',
'ide-editor-page.c',
'ide-editor-page-addin.c',
+ 'ide-editor-workspace.c',
]
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]