[gnome-builder] GbEditorTab: new tab design using GbEditorFrame and splits
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] GbEditorTab: new tab design using GbEditorFrame and splits
- Date: Tue, 2 Dec 2014 04:26:24 +0000 (UTC)
commit c106d85929214e2c3957b9a2385ad0ce14da1289
Author: Christian Hergert <christian hergert me>
Date: Mon Dec 1 20:09:40 2014 -0800
GbEditorTab: new tab design using GbEditorFrame and splits
src/editor/gb-editor-tab-private.h | 99 +--
src/editor/gb-editor-tab.c | 1463 +++++++++--------------------
src/editor/gb-editor-tab.h | 31 +-
src/resources/gnome-builder.gresource.xml | 1 +
src/resources/ui/gb-editor-tab.ui | 154 +---
src/resources/ui/gb-editor-workspace.ui | 30 +-
6 files changed, 527 insertions(+), 1251 deletions(-)
---
diff --git a/src/editor/gb-editor-tab-private.h b/src/editor/gb-editor-tab-private.h
index fd597b6..8b65539 100644
--- a/src/editor/gb-editor-tab-private.h
+++ b/src/editor/gb-editor-tab-private.h
@@ -19,104 +19,35 @@
#ifndef GB_EDITOR_TAB_PRIVATE_H
#define GB_EDITOR_TAB_PRIVATE_H
-#include <gtk/gtk.h>
#include <gtksourceview/gtksource.h>
#include "gb-animation.h"
-#include "gb-box-theatric.h"
#include "gb-editor-document.h"
-#include "gb-markdown-preview.h"
-#include "gb-notebook.h"
-#include "gb-source-change-monitor.h"
-#include "gb-source-search-highlighter.h"
-#include "gb-source-view.h"
-#include "gca-service.h"
-#include "gd-tagged-entry.h"
-#include "nautilus-floating-bar.h"
+#include "gb-editor-frame.h"
+#include "gb-editor-tab.h"
G_BEGIN_DECLS
struct _GbEditorTabPrivate
{
- /*
- * Our underlying document, the GtkTextBuffer.
- */
- GbEditorDocument *document;
-
- /*
- * Search releated components.
- */
- GbSourceSearchHighlighter *search_highlighter;
- GtkSourceSearchSettings *search_settings;
- GtkSourceSearchContext *search_context;
-
- /*
- * Change (add, change, etc) tracking of the editor.
- */
- GbSourceChangeMonitor *change_monitor;
- GtkSourceGutterRenderer *change_renderer;
-
- /*
- * Weak reference bindings for tracking settings.
- */
- GBinding *auto_indent_binding;
- GBinding *highlight_current_line_binding;
- GBinding *highlight_matching_brackets_binding;
- GBinding *insert_spaces_instead_of_tabs_binding;
- GBinding *right_margin_position_binding;
- GBinding *show_line_marks_binding;
- GBinding *show_line_numbers_binding;
- GBinding *show_right_margin_binding;
- GBinding *smart_home_end_binding;
- GBinding *tab_width_binding;
+ /* Widgets owned by GtkBuilder */
+ GbEditorFrame *frame;
+ GtkPaned *paned;
+ GtkProgressBar *progress_bar;
+ GtkToggleButton *split_button;
- /*
- * Tab related widgets, filled in with GtkBuilder templates.
- */
- NautilusFloatingBar *floating_bar;
- GtkButton *go_down_button;
- GtkButton *go_up_button;
- GtkOverlay *overlay;
- GtkSpinner *parsing_spinner;
- GtkBox *preview_container;
- GtkProgressBar *progress_bar;
- GtkRevealer *revealer;
- GtkScrolledWindow *scroller;
- GbSourceView *source_view;
- GdTaggedEntry *search_entry;
- GdTaggedEntryTag *search_entry_tag;
+ /* Weak references */
+ GbEditorFrame *last_frame;
+ GbAnimation *progress_animation;
- /*
- * Information about our target file and encoding.
- */
- GtkSourceFile *file;
-
- /*
- * Code Assistance.
- */
- GCancellable *gca_cancellable;
- GcaService *gca_service;
- gchar *gca_tmpfile;
- gint gca_tmpfd;
- gulong gca_buffer_changed_handler;
- guint gca_parse_timeout;
- gulong gca_tooltip_handler;
- GArray *gca_diagnostics;
- gulong gca_draw_layer;
- GtkSourceGutterRenderer *gca_gutter;
- GHashTable *gca_error_lines;
-
- /*
- * Animation for save progress.
- */
- GbAnimation *save_animation;
+ /* Objects owned by GbEditorTab */
+ GbEditorDocument *document;
- /*
- * If we want to use word completion in this editor.
- */
- guint enable_word_completion : 1;
+ guint unsaved_id;
};
+GbEditorFrame *gb_editor_tab_get_last_frame (GbEditorTab *tab);
+
G_END_DECLS
#endif /* GB_EDITOR_TAB_PRIVATE_H */
diff --git a/src/editor/gb-editor-tab.c b/src/editor/gb-editor-tab.c
index 18f1a45..823fe10 100644
--- a/src/editor/gb-editor-tab.c
+++ b/src/editor/gb-editor-tab.c
@@ -16,1271 +16,690 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#define G_LOG_DOMAIN "editor"
+#define G_LOG_DOMAIN "editor-tab"
#include <glib/gi18n.h>
-#include "gb-editor-code-assistant.h"
-#include "gb-editor-file-mark.h"
-#include "gb-editor-file-marks.h"
+#include "gb-doc-seq.h"
+#include "gb-editor-frame-private.h"
#include "gb-editor-tab.h"
#include "gb-editor-tab-private.h"
-#include "gb-editor-workspace.h"
-#include "gb-gtk.h"
+#include "gb-editor-file-mark.h"
+#include "gb-editor-file-marks.h"
#include "gb-log.h"
-#include "gb-rgba.h"
-#include "gb-source-change-gutter-renderer.h"
-#include "gb-source-highlight-menu.h"
-#include "gb-source-snippet.h"
-#include "gb-source-snippets-manager.h"
-#include "gb-source-snippets.h"
-#include "gb-string.h"
+#include "gb-markdown-tab.h"
#include "gb-widget.h"
-#include "gb-workbench.h"
-
-#define GB_EDITOR_TAB_UI_RESOURCE "/org/gnome/builder/ui/gb-editor-tab.ui"
-
-enum {
- PROP_0,
- PROP_DOCUMENT,
- PROP_FILE,
- LAST_PROP
-};
G_DEFINE_TYPE_WITH_PRIVATE (GbEditorTab, gb_editor_tab, GB_TYPE_TAB)
-static GParamSpec *gParamSpecs[LAST_PROP];
-
-GtkWidget *
+GbEditorTab *
gb_editor_tab_new (void)
{
return g_object_new (GB_TYPE_EDITOR_TAB, NULL);
}
-/**
- * gb_editor_tab_get_is_default:
- * @tab: A #GbEditorTab.
- *
- * Returns #TRUE if the tab has not been modified since being created
- * from an empty state. This means the tab is a candidate to be
- * dropped or repurposed for loading a new file.
- *
- * Returns: #TRUE if tab is in default state.
- */
-gboolean
-gb_editor_tab_get_is_default (GbEditorTab *tab)
-{
- GbEditorTabPrivate *priv;
- GtkTextIter begin;
- GtkTextIter end;
-
- g_return_val_if_fail (GB_IS_EDITOR_TAB (tab), FALSE);
-
- priv = tab->priv;
-
- if (gtk_source_file_get_location (priv->file))
- return FALSE;
-
- if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (priv->document)))
- return FALSE;
-
- gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (priv->document), &begin, &end);
-
- if (gtk_text_iter_compare (&begin, &end) != 0)
- return FALSE;
-
- return TRUE;
-}
-
-/**
- * gb_editor_tab_get_document:
- * @tab: A #GbEditorTab.
- *
- * Fetches the document for the tab.
- *
- * Returns: (transfer none): A #GbEditorDocument.
- */
-GbEditorDocument *
-gb_editor_tab_get_document (GbEditorTab *tab)
-{
- g_return_val_if_fail (GB_IS_EDITOR_TAB (tab), NULL);
-
- return tab->priv->document;
-}
-
-/**
- * gb_editor_tab_get_file:
- * @tab: A #GbEditorTab.
- *
- * Returns the current file for this tab, if there is one.
- * If no file has been specified, then NULL is returned.
- *
- * Returns: (transfer none): A #GtkSourceFile.
- */
-GtkSourceFile *
-gb_editor_tab_get_file (GbEditorTab *tab)
-{
- g_return_val_if_fail (GB_IS_EDITOR_TAB (tab), NULL);
-
- return tab->priv->file;
-}
-
static void
-set_search_position_label (GbEditorTab *tab,
- const gchar *text)
+gb_editor_tab_progress_cb (goffset current_num_bytes,
+ goffset total_num_bytes,
+ gpointer user_data)
{
GbEditorTabPrivate *priv;
+ GbEditorTab *tab = user_data;
+ gdouble fraction;
g_return_if_fail (GB_IS_EDITOR_TAB (tab));
priv = tab->priv;
- if (!text || !*text)
+ if (priv->progress_animation)
{
- if (priv->search_entry_tag)
- {
- gd_tagged_entry_remove_tag (priv->search_entry,
- priv->search_entry_tag);
- g_clear_object (&priv->search_entry_tag);
- }
- return;
+ g_object_remove_weak_pointer (G_OBJECT (priv->progress_animation),
+ (gpointer *)&priv->progress_animation);
+ gb_animation_stop (priv->progress_animation);
+ priv->progress_animation = NULL;
}
- if (!priv->search_entry_tag)
- {
- priv->search_entry_tag = gd_tagged_entry_tag_new ("");
- gd_tagged_entry_tag_set_style (priv->search_entry_tag,
- "gb-search-entry-occurrences-tag");
- gd_tagged_entry_add_tag (priv->search_entry,
- priv->search_entry_tag);
- }
+ fraction = total_num_bytes
+ ? ((gdouble)current_num_bytes / (gdouble)total_num_bytes)
+ : 1.0;
- gd_tagged_entry_tag_set_label (priv->search_entry_tag, text);
+ priv->progress_animation =
+ gb_object_animate (priv->progress_bar,
+ GB_ANIMATION_LINEAR,
+ 250,
+ NULL,
+ "fraction", fraction,
+ NULL);
+ g_object_add_weak_pointer (G_OBJECT (priv->progress_animation),
+ (gpointer *)&priv->progress_animation);
}
static void
-update_search_position_label (GbEditorTab *tab)
+gb_editor_tab_save_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- GbEditorTabPrivate *priv;
- GtkStyleContext *context;
- GtkTextIter begin;
- GtkTextIter end;
- const gchar *search_text;
- gchar *text;
- gint count;
- gint pos;
-
- g_assert (GB_IS_EDITOR_TAB (tab));
+ GbEditorTab *tab = user_data;
+ GbEditorDocument *document = (GbEditorDocument *)source_object;
+ GError *error = NULL;
- priv = tab->priv;
+ ENTRY;
- gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (priv->document),
- &begin, &end);
- pos = gtk_source_search_context_get_occurrence_position (
- priv->search_context, &begin, &end);
- count = gtk_source_search_context_get_occurrences_count (
- priv->search_context);
+ g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
+ g_return_if_fail (G_IS_ASYNC_RESULT (result));
+ g_return_if_fail (GB_IS_EDITOR_TAB (tab));
- if ((pos == -1) || (count == -1))
+ if (!gb_editor_document_save_finish (document, result, &error))
{
- /*
- * We are not yet done scanning the buffer.
- * We will be updated when we know more, so just hide it for now.
- */
- set_search_position_label (tab, NULL);
- return;
+ g_print ("%s\n", error->message);
+ //gb_editor_tab_set_error (tab, error);
+ g_clear_error (&error);
}
- context = gtk_widget_get_style_context (GTK_WIDGET (priv->search_entry));
- search_text = gtk_entry_get_text (GTK_ENTRY (priv->search_entry));
+ gb_widget_fade_hide (GTK_WIDGET (tab->priv->progress_bar));
- if ((count == 0) && !gb_str_empty0 (search_text))
- gtk_style_context_add_class (context, GTK_STYLE_CLASS_ERROR);
- else
- gtk_style_context_remove_class (context, GTK_STYLE_CLASS_ERROR);
-
- text = g_strdup_printf (_("%u of %u"), pos, count);
- set_search_position_label (tab, text);
- g_free (text);
-}
-
-static void
-on_search_occurrences_notify (GbEditorTab *tab,
- GParamSpec *pspec,
- GtkSourceSearchContext *search_context)
-{
- g_return_if_fail (GB_IS_EDITOR_TAB (tab));
- g_return_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search_context));
+ g_object_unref (tab);
- update_search_position_label (tab);
+ EXIT;
}
static void
-gb_editor_tab_cursor_moved (GbEditorTab *tab,
- GbEditorDocument *document)
+gb_editor_tab_do_save (GbEditorTab *tab)
{
- GtkSourceView *source_view;
- GtkTextBuffer *buffer;
- GbSourceVim *vim;
- GtkTextIter iter;
- GtkTextMark *mark;
- const gchar *phrase;
- gchar *text;
- guint ln;
- guint col;
+ ENTRY;
g_return_if_fail (GB_IS_EDITOR_TAB (tab));
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
- source_view = GTK_SOURCE_VIEW (tab->priv->source_view);
- buffer = GTK_TEXT_BUFFER (document);
+ gtk_progress_bar_set_fraction (tab->priv->progress_bar, 0.0);
+ gtk_widget_show (GTK_WIDGET (tab->priv->progress_bar));
- mark = gtk_text_buffer_get_insert (buffer);
- gtk_text_buffer_get_iter_at_mark (buffer, &iter, mark);
+ gb_editor_document_save_async (tab->priv->document,
+ NULL, /* cancellable */
+ gb_editor_tab_progress_cb,
+ tab,
+ NULL,
+ gb_editor_tab_save_cb,
+ g_object_ref (tab));
- ln = gtk_text_iter_get_line (&iter);
- col = gtk_source_view_get_visual_column (source_view, &iter);
-
- vim = gb_source_view_get_vim (tab->priv->source_view);
- phrase = gb_source_vim_get_phrase (vim);
-
- if (!gb_str_empty0 (phrase))
- text = g_strdup_printf (_("%s\tLine %u, Column %u"),
- phrase, ln + 1, col + 1);
- else
- text = g_strdup_printf (_("Line %u, Column %u"), ln + 1, col + 1);
-
- nautilus_floating_bar_set_primary_label (tab->priv->floating_bar, text);
- g_free (text);
-
- update_search_position_label (tab);
+ EXIT;
}
-static void
-gb_editor_tab_language_changed (GbEditorTab *tab,
- GParamSpec *pspec,
- GtkSourceBuffer *buffer)
+void
+gb_editor_tab_save_as (GbEditorTab *tab)
{
- GtkSourceLanguage *language;
+ const gchar *title;
+ GtkWidget *toplevel;
+ GtkDialog *dialog;
+ GtkWidget *suggested;
+ GFile *chosen_file;
+ guint response;
+
+ ENTRY;
g_return_if_fail (GB_IS_EDITOR_TAB (tab));
- g_return_if_fail (GTK_SOURCE_IS_BUFFER (buffer));
- language = gtk_source_buffer_get_language (buffer);
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (tab));
+ dialog = g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG,
+ "action", GTK_FILE_CHOOSER_ACTION_SAVE,
+ "do-overwrite-confirmation", TRUE,
+ "local-only", FALSE,
+ "select-multiple", FALSE,
+ "show-hidden", FALSE,
+ "transient-for", toplevel,
+ "title", _("Save Document As"),
+ NULL);
- gb_editor_code_assistant_destroy (tab);
- if (language)
- gb_editor_code_assistant_init (tab);
-}
+ title = gb_tab_get_title (GB_TAB (tab));
+ gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), title);
-static void
-gb_editor_tab_modified_changed (GbEditorTab *tab,
- GtkTextBuffer *buffer)
-{
- gboolean dirty;
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+ _("Cancel"), GTK_RESPONSE_CANCEL,
+ _("Save"), GTK_RESPONSE_OK,
+ NULL);
- g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
- g_return_if_fail (GB_IS_EDITOR_TAB (tab));
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
- dirty = gtk_text_buffer_get_modified (buffer);
- gb_tab_set_dirty (GB_TAB (tab), dirty);
-}
+ suggested = gtk_dialog_get_widget_for_response (GTK_DIALOG (dialog),
+ GTK_RESPONSE_OK);
+ gtk_style_context_add_class (gtk_widget_get_style_context (suggested),
+ GTK_STYLE_CLASS_SUGGESTED_ACTION);
-static void
-gb_editor_tab_freeze_drag (GbTab *tab)
-{
- GbEditorTab *editor = (GbEditorTab *) tab;
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_hide (GTK_WIDGET (dialog));
- ENTRY;
+ if (response == GTK_RESPONSE_OK)
+ {
+ GtkSourceFile *sfile;
- g_return_if_fail (GB_IS_EDITOR_TAB (editor));
+ sfile = gb_editor_document_get_file (tab->priv->document);
+ chosen_file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
+ gtk_source_file_set_location (sfile, chosen_file);
+ gb_editor_tab_do_save (tab);
+ g_clear_object (&chosen_file);
+ }
- /*
- * WORKAROUND:
- *
- * Unset drag 'n drop for the source view so that it doesn't
- * highjack drop target signals when what we really want is to
- * be dropped into a notebook.
- */
- gtk_drag_dest_unset (GTK_WIDGET (editor->priv->source_view));
+ gtk_widget_destroy (GTK_WIDGET (dialog));
EXIT;
}
-static void
-gb_editor_tab_thaw_drag (GbTab *tab)
+void
+gb_editor_tab_save (GbEditorTab *tab)
{
- GbEditorTabPrivate *priv;
- GtkTargetList *target_list;
- GbEditorTab *editor = (GbEditorTab *) tab;
+ GtkSourceFile *file;
+ gboolean has_location;
ENTRY;
- g_return_if_fail (GB_IS_EDITOR_TAB (editor));
+ g_return_if_fail (GB_IS_EDITOR_TAB (tab));
- priv = editor->priv;
+ file = gb_editor_document_get_file (tab->priv->document);
+ has_location = !!gtk_source_file_get_location (file);
- /*
- * WORKAROUND:
- *
- * Restore drag 'n drop for this tab. These match the values in
- * gtktextview.c.
- */
- gtk_drag_dest_set (GTK_WIDGET (priv->source_view), 0, NULL, 0,
- GDK_ACTION_COPY | GDK_ACTION_MOVE);
- target_list = gtk_target_list_new (NULL, 0);
- gtk_drag_dest_set_target_list (GTK_WIDGET (priv->source_view), target_list);
- gtk_target_list_unref (target_list);
+ if (has_location)
+ gb_editor_tab_do_save (tab);
+ else
+ gb_editor_tab_save_as (tab);
EXIT;
}
static void
-gb_editor_tab_grab_focus (GtkWidget *widget)
+gb_editor_tab_open_file_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- GbEditorTab *tab = (GbEditorTab *) widget;
+ GbEditorTab *tab = user_data;
+ GbEditorDocument *document = (GbEditorDocument *)source_object;
+ GError *error = NULL;
ENTRY;
+ g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
+ g_return_if_fail (G_IS_ASYNC_RESULT (result));
g_return_if_fail (GB_IS_EDITOR_TAB (tab));
- gtk_widget_grab_focus (GTK_WIDGET (tab->priv->source_view));
-
- EXIT;
-}
-
-static gboolean
-on_search_entry_key_press_event (GdTaggedEntry *entry,
- GdkEventKey *event,
- GbEditorTab *tab)
-{
- g_assert (GD_IS_TAGGED_ENTRY (entry));
- g_assert (GB_IS_EDITOR_TAB (tab));
-
- if (event->keyval == GDK_KEY_Escape)
+ if (!gb_editor_document_load_finish (document, result, &error))
{
- gtk_revealer_set_reveal_child (tab->priv->revealer, FALSE);
- gb_source_view_set_show_shadow (tab->priv->source_view, FALSE);
- gtk_widget_grab_focus (GTK_WIDGET (tab->priv->source_view));
- return GDK_EVENT_STOP;
+ g_print ("%s\n", error->message);
+ //gb_editor_tab_set_error (tab, error);
+ g_clear_error (&error);
}
- return GDK_EVENT_PROPAGATE;
-}
+ gb_editor_tab_restore_file_mark (tab);
-static gboolean
-on_search_entry_focus_in (GdTaggedEntry *entry,
- GdkEvent *event,
- GbEditorTab *tab)
-{
- g_return_val_if_fail (GD_IS_TAGGED_ENTRY (entry), FALSE);
- g_return_val_if_fail (GB_IS_EDITOR_TAB (tab), FALSE);
-
- gtk_widget_queue_draw (GTK_WIDGET (tab->priv->source_view));
-
- return FALSE;
-}
-
-static gboolean
-on_search_entry_focus_out (GdTaggedEntry *entry,
- GdkEvent *event,
- GbEditorTab *tab)
-{
- g_return_val_if_fail (GD_IS_TAGGED_ENTRY (entry), FALSE);
- g_return_val_if_fail (GB_IS_EDITOR_TAB (tab), FALSE);
-
- gtk_widget_queue_draw (GTK_WIDGET (tab->priv->source_view));
-
- return FALSE;
-}
-
-static gboolean
-do_delayed_animation (gpointer data)
-{
- GbEditorTabPrivate *priv;
- GbBoxTheatric *theatric;
- GdkFrameClock *frame_clock;
- GbEditorTab *tab = data;
- GtkTextView *text_view;
- GtkTextBuffer *buffer;
- GtkSourceStyleScheme *scheme;
- GtkSourceStyle *style;
- GdkRectangle begin_rect;
- GdkRectangle end_rect;
- GtkTextIter begin;
- GtkTextIter end;
- GdkRGBA rgba;
- gchar *color;
-
- priv = tab->priv;
-
- gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (priv->document),
- &begin, &end);
- if (gtk_text_iter_compare (&begin, &end) == 0)
- return G_SOURCE_REMOVE;
-
- text_view = GTK_TEXT_VIEW (priv->source_view);
- buffer = gtk_text_view_get_buffer (text_view);
- scheme = gtk_source_buffer_get_style_scheme (GTK_SOURCE_BUFFER (buffer));
- style = gtk_source_style_scheme_get_style (scheme, "search-match");
- g_object_get (style, "background", &color, NULL);
- gdk_rgba_parse (&rgba, color);
- gb_rgba_shade (&rgba, &rgba, 1.2);
- g_free (color);
- color = gdk_rgba_to_string (&rgba);
-
- gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->source_view),
- &begin, &begin_rect);
- gtk_text_view_buffer_to_window_coords (GTK_TEXT_VIEW (priv->source_view),
- GTK_TEXT_WINDOW_WIDGET,
- begin_rect.x,
- begin_rect.y,
- &begin_rect.x,
- &begin_rect.y);
-
- gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->source_view),
- &end, &end_rect);
- gtk_text_view_buffer_to_window_coords (GTK_TEXT_VIEW (priv->source_view),
- GTK_TEXT_WINDOW_WIDGET,
- end_rect.x,
- end_rect.y,
- &end_rect.x,
- &end_rect.y);
-
- /*
- * TODO: This might actually need to wrap around more.
- */
- gdk_rectangle_union (&begin_rect, &end_rect, &begin_rect);
-
-#define X_GROW 25
-#define Y_GROW 25
-
- end_rect = begin_rect;
- end_rect.x -= X_GROW;
- end_rect.y -= Y_GROW;
- end_rect.width += X_GROW * 2;
- end_rect.height += Y_GROW * 2;
-
- theatric = g_object_new (GB_TYPE_BOX_THEATRIC,
- "target", priv->source_view,
- "x", begin_rect.x,
- "y", begin_rect.y,
- "width", begin_rect.width,
- "height", begin_rect.height,
- "background", color,
- "alpha", 0.5,
- NULL);
-
- frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (priv->source_view));
-
- gb_object_animate (theatric,
- GB_ANIMATION_EASE_OUT_CUBIC,
- 250,
- frame_clock,
- "alpha", 0.0,
- "height", end_rect.height,
- "width", end_rect.width,
- "x", end_rect.x,
- "y", end_rect.y,
- NULL);
-
-#undef X_GROW
-#undef Y_GROW
+ gb_widget_fade_hide (GTK_WIDGET (tab->priv->progress_bar));
g_object_unref (tab);
- g_free (color);
-
- return G_SOURCE_REMOVE;
-}
-static void
-delayed_animation (GbEditorTab *tab)
-{
- g_timeout_add (200, do_delayed_animation, g_object_ref (tab));
+ EXIT;
}
-static void
-select_and_animate (GbEditorTab *tab,
- const GtkTextIter *begin,
- const GtkTextIter *end)
+void
+gb_editor_tab_open_file (GbEditorTab *tab,
+ GFile *file)
{
- GbEditorTabPrivate *priv;
- GtkTextIter copy;
+ ENTRY;
g_return_if_fail (GB_IS_EDITOR_TAB (tab));
- g_return_if_fail (begin);
- g_return_if_fail (end);
- priv = tab->priv;
+ gtk_progress_bar_set_fraction (tab->priv->progress_bar, 0.0);
+ gtk_widget_show (GTK_WIDGET (tab->priv->progress_bar));
- gtk_text_iter_assign (©, begin);
+ gb_editor_document_load_async (tab->priv->document,
+ file,
+ NULL, /* cancellable */
+ gb_editor_tab_progress_cb,
+ tab,
+ NULL,
+ gb_editor_tab_open_file_cb,
+ g_object_ref (tab));
-#if 0
- /* select the entire word */
- gtk_text_buffer_select_range (GTK_TEXT_BUFFER (priv->document), begin, end);
-#else
- /* move the cursor to the first character of the word */
- gtk_text_buffer_select_range (GTK_TEXT_BUFFER (priv->document), begin, begin);
-#endif
- gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->source_view), ©, 0.0,
- TRUE, 0.5, 0.5);
-
- if (!gtk_text_iter_equal (begin, end))
- delayed_animation (tab);
+ EXIT;
}
-static void
-gb_editor_tab_move_next_match (GbEditorTab *tab)
+void
+gb_editor_tab_restore_file_mark (GbEditorTab *tab)
{
GbEditorTabPrivate *priv;
- GtkTextBuffer *buffer;
- GtkTextIter select_begin;
- GtkTextIter select_end;
- GtkTextIter match_begin;
- GtkTextIter match_end;
- gboolean has_selection;
-
- ENTRY;
+ GtkSourceFile *file;
+ GSettings *settings;
+ gboolean restore_mark;
+ GFile *location;
g_return_if_fail (GB_IS_EDITOR_TAB (tab));
priv = tab->priv;
- buffer = GTK_TEXT_BUFFER (priv->document);
-
- /*
- * Start by trying from our current location.
- */
- has_selection = gtk_text_buffer_get_selection_bounds (buffer, &select_begin,
- &select_end);
- if (!has_selection)
- if (!gtk_text_iter_forward_char (&select_end))
- gtk_text_buffer_get_end_iter (buffer, &select_end);
+ settings = g_settings_new ("org.gnome.builder.editor");
+ restore_mark = g_settings_get_boolean (settings, "restore-insert-mark");
+ g_object_unref (settings);
- if (gtk_source_search_context_forward (priv->search_context, &select_end,
- &match_begin, &match_end))
+ if (!restore_mark)
{
- select_and_animate (tab, &match_begin, &match_end);
- EXIT;
- }
-
- /*
- * Didn't find anything, let's try from the beginning of the buffer.
- */
+ GtkTextIter iter;
- gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (priv->document),
- &select_begin, &select_end);
-
- if (gtk_source_search_context_forward (priv->search_context, &select_begin,
- &match_begin, &match_end))
- {
- select_and_animate (tab, &match_begin, &match_end);
- EXIT;
+ gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (tab->priv->document),
+ &iter);
+ gtk_text_buffer_select_range (GTK_TEXT_BUFFER (tab->priv->document),
+ &iter, &iter);
+ return;
}
- EXIT;
-}
-
-static void
-gb_editor_tab_move_previous_match (GbEditorTab *tab)
-{
- GbEditorTabPrivate *priv;
- GtkTextIter select_begin;
- GtkTextIter select_end;
- GtkTextIter match_begin;
- GtkTextIter match_end;
-
- ENTRY;
-
- g_return_if_fail (GB_IS_EDITOR_TAB (tab));
+ file = gb_editor_document_get_file (priv->document);
+ location = gtk_source_file_get_location (file);
- priv = tab->priv;
-
- gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (priv->document),
- &select_begin, &select_end);
-
- if (gtk_source_search_context_backward (priv->search_context, &select_begin,
- &match_begin, &match_end))
- GOTO (found_match);
- else
+ if (location)
{
- /*
- * We need to wrap around from the end to find the last search result.
- */
- gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (priv->document),
- &select_begin);
- if (gtk_source_search_context_backward (priv->search_context,
- &select_begin, &match_begin,
- &match_end))
- GOTO (found_match);
- }
-
- EXIT;
+ GbEditorFileMarks *marks;
+ GbEditorFileMark *mark;
+ guint line;
+ guint column;
-found_match:
- select_and_animate (tab, &match_begin, &match_end);
+ marks = gb_editor_file_marks_get_default ();
+ mark = gb_editor_file_marks_get_for_file (marks, location);
- EXIT;
-}
-
-static void
-on_search_entry_activate (GdTaggedEntry *search_entry,
- GbEditorTab *tab)
-{
- g_return_if_fail (GD_IS_TAGGED_ENTRY (search_entry));
- g_return_if_fail (GB_IS_EDITOR_TAB (tab));
+ if (mark)
+ {
+ line = gb_editor_file_mark_get_line (mark);
+ column = gb_editor_file_mark_get_column (mark);
- gb_editor_tab_move_next_match (tab);
- gtk_widget_grab_focus (GTK_WIDGET (tab->priv->source_view));
+ gb_editor_tab_scroll_to_line (tab, line, column);
+ }
+ }
}
-static gboolean
-on_source_view_focus_in_event (GbSourceView *view,
- GdkEvent *event,
- GbEditorTab *tab)
+void
+gb_editor_tab_toggle_split (GbEditorTab *tab)
{
- g_return_val_if_fail (GB_IS_EDITOR_TAB (tab), FALSE);
+ gboolean active;
- gtk_revealer_set_reveal_child (tab->priv->revealer, FALSE);
- gtk_source_search_context_set_highlight (tab->priv->search_context, FALSE);
+ g_return_if_fail (GB_IS_EDITOR_TAB (tab));
- return GDK_EVENT_PROPAGATE;
+ active = gtk_toggle_button_get_active (tab->priv->split_button);
+ gtk_toggle_button_set_active (tab->priv->split_button, !active);
}
static void
-on_source_view_populate_popup (GtkTextView *text_view,
- GtkWidget *popup,
- GbEditorTab *tab)
+gb_editor_tab_on_frame_focused (GbEditorTab *tab,
+ GbEditorFrame *frame)
{
- GbWorkbench *workbench;
- GbWorkspace *workspace;
+ GbEditorTabPrivate *priv;
- g_return_if_fail (GB_IS_SOURCE_VIEW (text_view));
g_return_if_fail (GB_IS_EDITOR_TAB (tab));
+ g_return_if_fail (GB_IS_EDITOR_FRAME (frame));
- if (GTK_IS_MENU (popup))
- {
- PangoFontDescription *font = NULL;
- GtkStyleContext *context;
- GMenuModel *model;
- GtkWidget *menu_item;
- GtkWidget *menu;
- GtkWidget *separator;
-
- workbench = GB_WORKBENCH (gtk_widget_get_toplevel (GTK_WIDGET (text_view)));
- workspace = gb_workbench_get_active_workspace (workbench);
-
- /*
- * WORKAROUND:
- *
- * GtkSourceView (and really, GtkTextView) inherit the font for the
- * popup window from the GtkTextView. This is problematic since we
- * override it to be a font such as Monospace.
- *
- * The following code works around that by applying the font that
- * is the default for the editor tab to the popup window.
- */
- context = gtk_widget_get_style_context (GTK_WIDGET (tab));
- gtk_style_context_get (context, GTK_STATE_FLAG_NORMAL,
- "font", &font,
- NULL);
- if (font)
- {
- gtk_widget_override_font (popup, font);
- pango_font_description_free (font);
- }
+ priv = tab->priv;
- /*
- * TODO: Add menu for controlling font size.
- */
-
- /*
- * Add separator.
- */
- separator = gtk_separator_menu_item_new ();
- gtk_menu_shell_prepend (GTK_MENU_SHELL (popup), GTK_WIDGET (separator));
- gtk_widget_show (separator);
-
- /*
- * Add menu for highlight mode.
- */
- model = gb_source_highlight_menu_new ();
- menu = gtk_menu_new_from_model (model);
- menu_item = gtk_menu_item_new_with_label (_("Highlight Mode"));
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), menu);
- gtk_menu_shell_prepend (GTK_MENU_SHELL (popup), GTK_WIDGET (menu_item));
- gtk_widget_insert_action_group (GTK_WIDGET (menu_item), "editor",
- gb_workspace_get_actions (workspace));
- gtk_widget_show (GTK_WIDGET (menu_item));
- g_object_unref (model);
+ if (priv->last_frame)
+ {
+ g_object_remove_weak_pointer (G_OBJECT (priv->last_frame),
+ (gpointer *)&priv->last_frame);
+ priv->last_frame = NULL;
}
-}
-static void
-on_source_view_push_snippet (GbSourceView *source_view,
- GbSourceSnippet *snippet,
- GbSourceSnippetContext *context,
- GtkTextIter *iter,
- GbEditorTab *tab)
-{
- GFile *file;
-
- g_return_if_fail (GB_IS_SOURCE_VIEW (source_view));
- g_return_if_fail (GB_IS_SOURCE_SNIPPET (snippet));
- g_return_if_fail (GB_IS_SOURCE_SNIPPET_CONTEXT (context));
- g_return_if_fail (iter);
- g_return_if_fail (GB_IS_EDITOR_TAB (tab));
-
- file = gtk_source_file_get_location (tab->priv->file);
- g_assert (!file || G_IS_FILE (file));
-
- if (file)
+ if (frame)
{
- gchar *name = g_file_get_basename (file);
- gb_source_snippet_context_add_variable (context, "filename", name);
- g_free (name);
+ priv->last_frame = frame;
+ g_object_add_weak_pointer (G_OBJECT (priv->last_frame),
+ (gpointer *)&priv->last_frame);
}
}
static void
-on_source_view_begin_search (GbSourceView *source_view,
- GtkDirectionType direction,
- const gchar *search_text,
- GbEditorTab *tab)
+gb_editor_tab_on_split_toggled (GbEditorTab *tab,
+ GtkToggleButton *button)
{
GbEditorTabPrivate *priv;
+ GtkWidget *child2;
g_return_if_fail (GB_IS_EDITOR_TAB (tab));
- g_return_if_fail (GB_IS_SOURCE_VIEW (source_view));
priv = tab->priv;
- if (search_text)
- gtk_entry_set_text (GTK_ENTRY (priv->search_entry), search_text);
-
- gtk_revealer_set_reveal_child (priv->revealer, TRUE);
- gtk_source_search_context_set_highlight (priv->search_context, TRUE);
- gtk_widget_grab_focus (GTK_WIDGET (priv->search_entry));
+ child2 = gtk_paned_get_child2 (priv->paned);
- if (search_text)
+ if (child2)
{
- if (direction == GTK_DIR_DOWN)
- gb_editor_tab_move_next_match (tab);
- else if (direction == GTK_DIR_UP)
- gb_editor_tab_move_previous_match (tab);
+ gtk_container_remove (GTK_CONTAINER (priv->paned), child2);
}
else
{
- const gchar *text;
- guint len;
-
- text = gtk_entry_get_text (GTK_ENTRY (priv->search_entry));
- len = g_utf8_strlen (text, -1);
- gtk_editable_select_region (GTK_EDITABLE (priv->search_entry), 0, len);
+ child2 = g_object_new (GB_TYPE_EDITOR_FRAME,
+ "document", priv->document,
+ "visible", TRUE,
+ NULL);
+ gtk_paned_add2 (priv->paned, child2);
+ gtk_container_child_set (GTK_CONTAINER (priv->paned), child2,
+ "resize", TRUE,
+ "shrink", FALSE,
+ NULL);
+ g_signal_connect_object (child2,
+ "focused",
+ G_CALLBACK (gb_editor_tab_on_frame_focused),
+ tab,
+ G_CONNECT_SWAPPED);
+ gtk_widget_grab_focus (child2);
}
}
+GbEditorFrame *
+gb_editor_tab_get_last_frame (GbEditorTab *tab)
+{
+ g_return_val_if_fail (GB_IS_EDITOR_TAB (tab), NULL);
+
+ if (tab->priv->last_frame)
+ return tab->priv->last_frame;
+
+ return tab->priv->frame;
+}
+
void
gb_editor_tab_scroll_to_line (GbEditorTab *tab,
guint line,
guint line_offset)
{
+ GbEditorFrame *frame;
GtkTextIter iter;
g_return_if_fail (GB_IS_EDITOR_TAB (tab));
+ frame = gb_editor_tab_get_last_frame (tab);
+
gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (tab->priv->document),
&iter, line);
- gtk_text_iter_set_line_offset (&iter, line_offset);
+ for (; line_offset; line_offset--)
+ {
+ if (gtk_text_iter_ends_line (&iter))
+ break;
+ if (!gtk_text_iter_forward_char (&iter))
+ break;
+ }
+
gtk_text_buffer_select_range (GTK_TEXT_BUFFER (tab->priv->document),
&iter, &iter);
- gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (tab->priv->source_view), &iter,
+
+ gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (frame->priv->source_view), &iter,
0.0, FALSE, 0.0, 0.5);
}
static void
-on_vim_command_visibility_toggled (GbSourceVim *vim,
- gboolean visible,
- GbEditorTab *tab)
+gb_editor_tab_scroll (GbEditorTab *tab,
+ GtkDirectionType dir)
{
- GbWorkbench *workbench;
- GAction *action;
- GVariant *params;
-
- ENTRY;
+ GtkAdjustment *vadj;
+ GbEditorFrame *last_frame;
+ GtkScrolledWindow *scroller;
+ GtkTextMark *insert;
+ GtkTextView *view;
+ GtkTextBuffer *buffer;
+ GdkRectangle rect;
+ GtkTextIter iter;
+ gdouble amount;
+ gdouble value;
+ gdouble upper;
- g_return_if_fail (GB_IS_SOURCE_VIM (vim));
- g_return_if_fail (GB_IS_EDITOR_TAB (tab));
+ g_assert (GB_IS_EDITOR_TAB (tab));
- workbench = gb_widget_get_workbench (GTK_WIDGET (tab));
- if (!workbench)
- return;
+ last_frame = gb_editor_tab_get_last_frame (tab);
+ scroller = last_frame->priv->scrolled_window;
+ view = GTK_TEXT_VIEW (last_frame->priv->source_view);
+ buffer = GTK_TEXT_BUFFER (last_frame->priv->document);
- action = g_action_map_lookup_action (G_ACTION_MAP (workbench),
- "toggle-command-bar");
- if (!action)
- return;
+ insert = gtk_text_buffer_get_insert (buffer);
+ gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
+ gtk_text_view_get_iter_location (view, &iter, &rect);
- params = g_variant_new_boolean (visible);
- g_action_activate (action, params);
+ amount = (dir == GTK_DIR_UP) ? -rect.height : rect.height;
- EXIT;
+ vadj = gtk_scrolled_window_get_vadjustment (scroller);
+ value = gtk_adjustment_get_value (vadj);
+ upper = gtk_adjustment_get_upper (vadj);
+ gtk_adjustment_set_value (vadj, CLAMP (value + amount, 0, upper));
}
-static void
-on_vim_begin_search (GbSourceVim *vim,
- const gchar *search_text,
- GbEditorTab *tab)
+void
+gb_editor_tab_scroll_up (GbEditorTab *tab)
{
g_return_if_fail (GB_IS_EDITOR_TAB (tab));
- gb_source_view_begin_search (tab->priv->source_view, GTK_DIR_DOWN,
- search_text);
+ gb_editor_tab_scroll (tab, GTK_DIR_UP);
}
-static void
-on_vim_notify_phrase (GbSourceVim *vim,
- GParamSpec *pspec,
- GbEditorTab *tab)
+void
+gb_editor_tab_scroll_down (GbEditorTab *tab)
{
- g_return_if_fail (GB_IS_SOURCE_VIM (vim));
g_return_if_fail (GB_IS_EDITOR_TAB (tab));
- gb_editor_tab_cursor_moved (tab, tab->priv->document);
+ gb_editor_tab_scroll (tab, GTK_DIR_DOWN);
}
static void
-on_vim_notify_mode (GbSourceVim *vim,
- GParamSpec *pspec,
- GbEditorTab *tab)
+gb_editor_tab_grab_focus (GtkWidget *widget)
{
- GbSourceVimMode mode;
+ GbEditorFrame *last_frame;
- g_return_if_fail (GB_IS_SOURCE_VIM (vim));
- g_return_if_fail (GB_IS_EDITOR_TAB (tab));
+ g_return_if_fail (GB_IS_EDITOR_TAB (widget));
- mode = gb_source_vim_get_mode (vim);
+ last_frame = gb_editor_tab_get_last_frame (GB_EDITOR_TAB (widget));
- if (mode != GB_SOURCE_VIM_INSERT)
- gb_source_view_clear_snippets (tab->priv->source_view);
+ gtk_widget_grab_focus (GTK_WIDGET (last_frame));
}
-static gboolean
-transform_file_to_language (GBinding *binding,
- const GValue *src_value,
- GValue *dst_value,
- gpointer user_data)
+static void
+gb_editor_tab_update_title (GbEditorTab *tab)
{
- GbEditorTab *tab = user_data;
- GtkSourceLanguage *language = NULL;
+ GtkSourceFile *file;
GFile *location;
+ gchar *title;
- g_assert (GB_IS_EDITOR_TAB (tab));
+ g_return_if_fail (GB_IS_EDITOR_TAB (tab));
- location = g_value_get_object (src_value);
+ file = gb_editor_document_get_file (tab->priv->document);
+ location = gtk_source_file_get_location (file);
if (location)
{
- GtkSourceLanguageManager *manager;
- gchar *filename;
- gchar *content_type = NULL;
-
- filename = g_file_get_basename (location);
-
- /*
- * TODO: Load content_type using g_file_query_info().
- * Also, don't do this here, do it async.
- */
-
- manager = gtk_source_language_manager_get_default ();
- language = gtk_source_language_manager_guess_language (manager, filename,
- content_type);
- gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (tab->priv->document),
- language);
-
- gb_editor_code_assistant_destroy (tab);
+ if (tab->priv->unsaved_id)
+ {
+ gb_doc_seq_release (tab->priv->unsaved_id);
+ tab->priv->unsaved_id = 0;
+ }
- g_free (filename);
- g_free (content_type);
+ title = g_file_get_basename (location);
+ gb_tab_set_title (GB_TAB (tab), title);
+ g_free (title);
+ }
+ else
+ {
+ if (!tab->priv->unsaved_id)
+ {
+ tab->priv->unsaved_id = gb_doc_seq_acquire ();
+ title = g_strdup_printf (_("unsaved %u"), tab->priv->unsaved_id);
+ gb_tab_set_title (GB_TAB (tab), title);
+ g_free (title);
+ }
}
-
- g_value_set_object (dst_value, language);
-
- return TRUE;
}
-static gboolean
-transform_file_to_title (GBinding *binding,
- const GValue *src_value,
- GValue *dst_value,
- gpointer user_data)
+static void
+gb_editor_tab_on_notify_location (GbEditorTab *tab,
+ GParamSpec *pspec,
+ GtkSourceFile *file)
{
- GbEditorTab *tab = user_data;
- gchar *title;
- GFile *file;
-
- g_return_val_if_fail (GB_IS_EDITOR_TAB (tab), FALSE);
- g_return_val_if_fail (G_VALUE_HOLDS (src_value, G_TYPE_FILE), FALSE);
- g_return_val_if_fail (G_VALUE_HOLDS (dst_value, G_TYPE_STRING), FALSE);
- file = g_value_get_object (src_value);
-
- if (file)
- title = g_file_get_basename (file);
- else
- title = g_strdup (_("unsaved file"));
-
- g_value_take_string (dst_value, title);
+ g_return_if_fail (GB_IS_EDITOR_TAB (tab));
+ g_return_if_fail (GTK_SOURCE_IS_FILE (file));
- return TRUE;
+ gb_editor_tab_update_title (tab);
}
static void
-gb_editor_tab_constructed (GObject *object)
+gb_editor_tab_on_modified_changed (GbEditorTab *tab,
+ GtkTextBuffer *buffer)
{
- GtkSourceCompletion *comp;
- GbEditorTabPrivate *priv;
- GbEditorTab *tab = (GbEditorTab *) object;
- GbSourceVim *vim;
- GtkSourceGutter *gutter;
-
- ENTRY;
+ gboolean modified;
g_return_if_fail (GB_IS_EDITOR_TAB (tab));
- priv = tab->priv;
+ modified = gtk_text_buffer_get_modified (buffer);
+ gb_tab_set_dirty (GB_TAB (tab), modified);
- if (!priv->document)
- priv->document = gb_editor_document_new ();
-
- gtk_text_view_set_buffer (GTK_TEXT_VIEW (priv->source_view),
- GTK_TEXT_BUFFER (priv->document));
-
- if (!priv->file)
- priv->file = gtk_source_file_new ();
-
- if (!priv->change_monitor)
- priv->change_monitor = gb_source_change_monitor_new (GTK_TEXT_BUFFER (priv->document));
-
- priv->search_settings =
- g_object_new (GTK_SOURCE_TYPE_SEARCH_SETTINGS,
- NULL);
-
- priv->search_context =
- g_object_new (GTK_SOURCE_TYPE_SEARCH_CONTEXT,
- "buffer", priv->document,
- "settings", priv->search_settings,
- "highlight", TRUE,
- NULL);
-
- priv->search_highlighter =
- g_object_new (GB_TYPE_SOURCE_SEARCH_HIGHLIGHTER,
- "search-context", priv->search_context,
- "search-settings", priv->search_settings,
- NULL);
- g_object_set (priv->source_view,
- "search-highlighter", priv->search_highlighter,
- NULL);
-
- g_signal_connect_swapped (priv->document,
- "notify::language",
- G_CALLBACK (gb_editor_tab_language_changed),
- tab);
- g_signal_connect_swapped (priv->document,
- "modified-changed",
- G_CALLBACK (gb_editor_tab_modified_changed),
- tab);
- g_signal_connect_swapped (priv->document,
- "cursor-moved",
- G_CALLBACK (gb_editor_tab_cursor_moved),
- tab);
-
- g_signal_connect (priv->source_view,
- "focus-in-event",
- G_CALLBACK (on_source_view_focus_in_event),
- tab);
- g_signal_connect (priv->source_view,
- "populate-popup",
- G_CALLBACK (on_source_view_populate_popup),
- tab);
- g_signal_connect (priv->source_view,
- "push-snippet",
- G_CALLBACK (on_source_view_push_snippet),
- tab);
- g_signal_connect (priv->source_view,
- "begin-search",
- G_CALLBACK (on_source_view_begin_search),
- tab);
-
- g_signal_connect_swapped (priv->go_down_button,
- "clicked",
- G_CALLBACK (gb_editor_tab_move_next_match),
- tab);
- g_signal_connect_swapped (priv->go_up_button,
- "clicked",
- G_CALLBACK (gb_editor_tab_move_previous_match),
- tab);
-
- g_signal_connect_object (priv->search_context,
- "notify::occurrences-count",
- G_CALLBACK (on_search_occurrences_notify),
- tab,
- G_CONNECT_SWAPPED);
-
-
- /*
- * WORKAROUND:
- *
- * Once GtkSourceView exports this as an internal child, we can do this from
- * the gb-editor-tab.ui file.
- */
- comp = gtk_source_view_get_completion (GTK_SOURCE_VIEW (priv->source_view));
- g_object_set (comp,
- "show-headers", FALSE,
- "select-on-show", TRUE,
- NULL);
-
- g_signal_connect (priv->search_entry,
- "activate",
- G_CALLBACK (on_search_entry_activate),
- tab);
- g_signal_connect (priv->search_entry,
- "key-press-event",
- G_CALLBACK (on_search_entry_key_press_event),
- tab);
- g_signal_connect (priv->search_entry,
- "focus-in-event",
- G_CALLBACK (on_search_entry_focus_in),
- tab);
- g_signal_connect (priv->search_entry,
- "focus-out-event",
- G_CALLBACK (on_search_entry_focus_out),
- tab);
- g_object_bind_property (priv->search_entry, "text",
- priv->search_settings, "search-text",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (priv->revealer, "reveal-child",
- priv->source_view, "show-shadow",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (priv->file, "location",
- priv->change_monitor, "file",
- G_BINDING_SYNC_CREATE);
- g_object_bind_property_full (priv->file, "location", tab, "title",
- G_BINDING_SYNC_CREATE, transform_file_to_title,
- NULL, tab, NULL);
- g_object_bind_property_full (priv->file, "location", priv->document,
- "language", G_BINDING_SYNC_CREATE,
- transform_file_to_language, NULL, tab, NULL);
-
- gutter = gtk_source_view_get_gutter (GTK_SOURCE_VIEW (priv->source_view),
- GTK_TEXT_WINDOW_LEFT);
- priv->change_renderer =
- g_object_new (GB_TYPE_SOURCE_CHANGE_GUTTER_RENDERER,
- "change-monitor", priv->change_monitor,
- "size", 2,
- "visible", TRUE,
- "xpad", 1,
- NULL);
- gtk_source_gutter_insert (gutter, priv->change_renderer, 0);
-
- vim = gb_source_view_get_vim (priv->source_view);
- g_signal_connect (vim,
- "command-visibility-toggled",
- G_CALLBACK (on_vim_command_visibility_toggled),
- tab);
- g_signal_connect (vim,
- "begin-search",
- G_CALLBACK (on_vim_begin_search),
- tab);
- g_signal_connect (vim,
- "notify::phrase",
- G_CALLBACK (on_vim_notify_phrase),
- tab);
- g_signal_connect (vim,
- "notify::mode",
- G_CALLBACK (on_vim_notify_mode),
- tab);
-
-#if 0
- g_settings_bind (settings, "word-completion", tab, "enable-word-completion",
- G_SETTINGS_BIND_DEFAULT);
-#endif
-
- gb_editor_tab_cursor_moved (tab, priv->document);
-
- EXIT;
+ /* notify helper for tab labels wanting to render dirty tabs specially */
+ g_object_notify (G_OBJECT (tab), "title");
}
void
-gb_editor_tab_load_file_mark (GbEditorTab *tab)
+gb_editor_tab_find (GbEditorTab *tab)
{
- GbEditorFileMarks *marks;
- GbEditorFileMark *mark;
- GtkTextBuffer *buffer;
- GtkTextIter iter;
- GSettings *settings;
- gboolean load_mark;
- GFile *file;
- guint line;
- guint column;
+ GbEditorFrame *frame;
g_return_if_fail (GB_IS_EDITOR_TAB (tab));
- settings = g_settings_new ("org.gnome.builder.editor");
- load_mark = g_settings_get_boolean (settings, "restore-insert-mark");
- g_clear_object (&settings);
-
- buffer = GTK_TEXT_BUFFER (tab->priv->document);
-
- if (!load_mark)
- {
- gtk_text_buffer_get_start_iter (buffer, &iter);
- gtk_text_buffer_select_range (buffer, &iter, &iter);
- gb_gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (tab->priv->source_view),
- &iter, 0.0, TRUE, 0.5, 0.5);
- return;
- }
-
- file = gtk_source_file_get_location (tab->priv->file);
- if (!file)
- return;
-
- marks = gb_editor_file_marks_get_default ();
- mark = gb_editor_file_marks_get_for_file (marks, file);
-
- line = gb_editor_file_mark_get_line (mark);
- column = gb_editor_file_mark_get_column (mark);
-
- gb_gtk_text_buffer_get_iter_at_line_and_offset (buffer, &iter, line, column);
- gtk_text_buffer_select_range (buffer, &iter, &iter);
- gb_gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (tab->priv->source_view),
- &iter, 0.0, TRUE, 0.5, 0.5);
+ frame = gb_editor_tab_get_last_frame (tab);
+ gb_editor_frame_find (frame, NULL);
}
-static void
-gb_editor_tab_save_file_mark (GbEditorTab *tab)
+void
+gb_editor_tab_reformat (GbEditorTab *tab)
{
- GbEditorFileMarks *marks;
- GbEditorFileMark *mark;
- GtkTextBuffer *buffer;
- GtkTextIter iter;
- GtkTextMark *insert;
- GFile *file;
+ GbEditorFrame *frame;
g_return_if_fail (GB_IS_EDITOR_TAB (tab));
- buffer = GTK_TEXT_BUFFER (tab->priv->document);
- insert = gtk_text_buffer_get_insert (buffer);
- gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
+ frame = gb_editor_tab_get_last_frame (tab);
+ gb_editor_frame_reformat (frame);
+}
- file = gtk_source_file_get_location (tab->priv->file);
- if (!file)
- return;
+static gboolean
+markdown_preview_title (GBinding *binding,
+ const GValue *from_value,
+ GValue *to_value,
+ gpointer user_data)
+{
+ gchar *str;
+
+ str = g_strdup_printf (_("%s (Markdown Preview)"),
+ g_value_get_string (from_value));
+ g_value_take_string (to_value, str);
- marks = gb_editor_file_marks_get_default ();
- mark = gb_editor_file_marks_get_for_file (marks, file);
- gb_editor_file_mark_set_line (mark, gtk_text_iter_get_line (&iter));
- gb_editor_file_mark_set_column (mark, gtk_text_iter_get_line_offset (&iter));
+ return TRUE;
}
-static void
-gb_editor_tab_close (GbTab *tab)
+
+GbTab *
+gb_editor_tab_preview (GbEditorTab *tab)
{
GbEditorTabPrivate *priv;
- GtkTextBuffer *buffer;
-
- ENTRY;
-
- g_return_if_fail (GB_IS_EDITOR_TAB (tab));
+ GtkSourceLanguage *lang;
+ const gchar *lang_id;
+ GbTab *preview = NULL;
- priv = GB_EDITOR_TAB (tab)->priv;
+ g_return_val_if_fail (GB_IS_EDITOR_TAB (tab), NULL);
- buffer = GTK_TEXT_BUFFER (priv->document);
+ priv = tab->priv;
- if (gtk_text_buffer_get_modified (buffer))
- g_message ("TODO: handle dirty editor state.");
+ lang = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (priv->document));
- gb_editor_tab_save_file_mark (GB_EDITOR_TAB (tab));
+ if (!lang || !(lang_id = gtk_source_language_get_id (lang)))
+ return NULL;
- gtk_widget_destroy (GTK_WIDGET (tab));
+ if (g_str_equal (lang_id, "markdown"))
+ {
+ preview = g_object_new (GB_TYPE_MARKDOWN_TAB,
+ "buffer", priv->document,
+ "visible", TRUE,
+ NULL);
+ g_object_bind_property_full (tab, "title", preview, "title",
+ G_BINDING_SYNC_CREATE,
+ markdown_preview_title,
+ NULL, NULL, NULL);
+ }
- EXIT;
+ return preview;
}
static void
-gb_editor_tab_dispose (GObject *object)
+gb_editor_tab_constructed (GObject *object)
{
- GbEditorTab *tab = (GbEditorTab *) object;
+ GbEditorTabPrivate *priv;
+ GbEditorTab *tab = (GbEditorTab *)object;
+ GtkSourceFile *file;
- ENTRY;
+ g_return_if_fail (GB_IS_EDITOR_TAB (tab));
- g_assert (GB_IS_EDITOR_TAB (tab));
+ priv = tab->priv;
- gb_editor_code_assistant_destroy (tab);
+ G_OBJECT_CLASS (gb_editor_tab_parent_class)->constructed (object);
- g_clear_object (&tab->priv->change_monitor);
- g_clear_object (&tab->priv->search_entry_tag);
- g_clear_object (&tab->priv->file);
- g_clear_object (&tab->priv->search_highlighter);
- g_clear_object (&tab->priv->search_settings);
- g_clear_object (&tab->priv->search_context);
- g_clear_object (&tab->priv->document);
+ priv->document = g_object_new (GB_TYPE_EDITOR_DOCUMENT,
+ NULL);
+ gb_editor_frame_set_document (priv->frame, priv->document);
- G_OBJECT_CLASS (gb_editor_tab_parent_class)->dispose (object);
+ g_signal_connect_object (priv->document,
+ "modified-changed",
+ G_CALLBACK (gb_editor_tab_on_modified_changed),
+ tab,
+ G_CONNECT_SWAPPED);
- EXIT;
-}
+ file = gb_editor_document_get_file (priv->document);
+ g_signal_connect_object (file,
+ "notify::location",
+ G_CALLBACK (gb_editor_tab_on_notify_location),
+ tab,
+ G_CONNECT_SWAPPED);
-static void
-gb_editor_tab_finalize (GObject *object)
-{
- ENTRY;
+ g_signal_connect_object (priv->frame,
+ "focused",
+ G_CALLBACK (gb_editor_tab_on_frame_focused),
+ tab,
+ G_CONNECT_SWAPPED);
- G_OBJECT_CLASS (gb_editor_tab_parent_class)->finalize (object);
+ g_signal_connect_object (priv->split_button,
+ "toggled",
+ G_CALLBACK (gb_editor_tab_on_split_toggled),
+ tab,
+ G_CONNECT_SWAPPED);
- EXIT;
+ gb_editor_tab_update_title (tab);
}
static void
-gb_editor_tab_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+gb_editor_tab_dispose (GObject *object)
{
- GbEditorTab *tab = GB_EDITOR_TAB (object);
+ GbEditorTabPrivate *priv = GB_EDITOR_TAB (object)->priv;
- switch (prop_id)
- {
- case PROP_DOCUMENT:
- g_value_set_object (value, gb_editor_tab_get_document (tab));
- break;
+ g_clear_object (&priv->document);
- case PROP_FILE:
- g_value_set_object (value, gb_editor_tab_get_file (tab));
- break;
+ if (priv->last_frame)
+ {
+ g_object_remove_weak_pointer (G_OBJECT (priv->last_frame),
+ (gpointer *)&priv->last_frame);
+ priv->last_frame = NULL;
+ }
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ if (priv->progress_animation)
+ {
+ g_object_remove_weak_pointer (G_OBJECT (priv->progress_animation),
+ (gpointer *)&priv->progress_animation);
+ priv->progress_animation = NULL;
}
+
+ G_OBJECT_CLASS (gb_editor_tab_parent_class)->dispose (object);
}
static void
-gb_editor_tab_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
+gb_editor_tab_finalize (GObject *object)
{
-#if 0
- GbEditorTab *tab = GB_EDITOR_TAB (object);
-#endif
+ GbEditorTabPrivate *priv = GB_EDITOR_TAB (object)->priv;
- switch (prop_id)
+ if (priv->unsaved_id)
{
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ gb_doc_seq_release (priv->unsaved_id);
+ priv->unsaved_id = 0;
}
+
+ G_OBJECT_CLASS (gb_editor_tab_parent_class)->finalize (object);
}
static void
@@ -1288,61 +707,21 @@ gb_editor_tab_class_init (GbEditorTabClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- GbTabClass *tab_class = GB_TAB_CLASS (klass);
object_class->constructed = gb_editor_tab_constructed;
object_class->dispose = gb_editor_tab_dispose;
object_class->finalize = gb_editor_tab_finalize;
- object_class->get_property = gb_editor_tab_get_property;
- object_class->set_property = gb_editor_tab_set_property;
widget_class->grab_focus = gb_editor_tab_grab_focus;
- tab_class->close = gb_editor_tab_close;
- tab_class->freeze_drag = gb_editor_tab_freeze_drag;
- tab_class->thaw_drag = gb_editor_tab_thaw_drag;
-
- gParamSpecs [PROP_DOCUMENT] =
- g_param_spec_object ("document",
- _("Document"),
- _("The document to edit."),
- GB_TYPE_EDITOR_DOCUMENT,
- (G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_DOCUMENT,
- gParamSpecs[PROP_DOCUMENT]);
-
- gParamSpecs [PROP_FILE] =
- g_param_spec_object ("file",
- _("File"),
- _("The file for the tab."),
- GTK_SOURCE_TYPE_FILE,
- (G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_FILE,
- gParamSpecs [PROP_FILE]);
-
gtk_widget_class_set_template_from_resource (widget_class,
- GB_EDITOR_TAB_UI_RESOURCE);
-
- gtk_widget_class_bind_template_child_private (widget_class, GbEditorTab, floating_bar);
- gtk_widget_class_bind_template_child_private (widget_class, GbEditorTab, go_down_button);
- gtk_widget_class_bind_template_child_private (widget_class, GbEditorTab, go_up_button);
- gtk_widget_class_bind_template_child_private (widget_class, GbEditorTab, overlay);
- gtk_widget_class_bind_template_child_private (widget_class, GbEditorTab, parsing_spinner);
- gtk_widget_class_bind_template_child_private (widget_class, GbEditorTab, preview_container);
+ "/org/gnome/builder/ui/gb-editor-tab.ui");
+ gtk_widget_class_bind_template_child_private (widget_class, GbEditorTab, frame);
+ gtk_widget_class_bind_template_child_private (widget_class, GbEditorTab, paned);
gtk_widget_class_bind_template_child_private (widget_class, GbEditorTab, progress_bar);
- gtk_widget_class_bind_template_child_private (widget_class, GbEditorTab, revealer);
- gtk_widget_class_bind_template_child_private (widget_class, GbEditorTab, scroller);
- gtk_widget_class_bind_template_child_private (widget_class, GbEditorTab, search_entry);
- gtk_widget_class_bind_template_child_private (widget_class, GbEditorTab, source_view);
-
- g_type_ensure (GB_TYPE_EDITOR_DOCUMENT);
- g_type_ensure (GB_TYPE_SOURCE_CHANGE_MONITOR);
- g_type_ensure (GB_TYPE_SOURCE_VIEW);
- g_type_ensure (GB_TYPE_SOURCE_SEARCH_HIGHLIGHTER);
- g_type_ensure (GD_TYPE_TAGGED_ENTRY);
- g_type_ensure (NAUTILUS_TYPE_FLOATING_BAR);
+ gtk_widget_class_bind_template_child_private (widget_class, GbEditorTab, split_button);
+
+ g_type_ensure (GB_TYPE_EDITOR_FRAME);
}
static void
diff --git a/src/editor/gb-editor-tab.h b/src/editor/gb-editor-tab.h
index b7e2625..6013923 100644
--- a/src/editor/gb-editor-tab.h
+++ b/src/editor/gb-editor-tab.h
@@ -19,8 +19,10 @@
#ifndef GB_EDITOR_TAB_H
#define GB_EDITOR_TAB_H
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+
#include "gb-tab.h"
-#include "gb-editor-document.h"
G_BEGIN_DECLS
@@ -49,17 +51,22 @@ struct _GbEditorTabClass
GbTabClass parent_class;
};
-GType gb_editor_tab_get_type (void) G_GNUC_CONST;
-GtkWidget *gb_editor_tab_new (void);
-GbEditorDocument *gb_editor_tab_get_document (GbEditorTab *tab);
-GtkSourceFile *gb_editor_tab_get_file (GbEditorTab *tab);
-void gb_editor_tab_set_font_desc (GbEditorTab *tab,
- const PangoFontDescription *font_desc);
-gboolean gb_editor_tab_get_is_default (GbEditorTab *tab);
-void gb_editor_tab_load_file_mark (GbEditorTab *tab);
-void gb_editor_tab_scroll_to_line (GbEditorTab *tab,
- guint line,
- guint line_offset);
+GbEditorTab *gb_editor_tab_new (void);
+GType gb_editor_tab_get_type (void) G_GNUC_CONST;
+void gb_editor_tab_save (GbEditorTab *tab);
+void gb_editor_tab_save_as (GbEditorTab *tab);
+void gb_editor_tab_open_file (GbEditorTab *tab,
+ GFile *file);
+void gb_editor_tab_scroll_up (GbEditorTab *tab);
+void gb_editor_tab_scroll_down (GbEditorTab *tab);
+void gb_editor_tab_toggle_split (GbEditorTab *tab);
+void gb_editor_tab_find (GbEditorTab *tab);
+void gb_editor_tab_reformat (GbEditorTab *tab);
+void gb_editor_tab_scroll_to_line (GbEditorTab *tab,
+ guint line,
+ guint line_offset);
+void gb_editor_tab_restore_file_mark (GbEditorTab *tab);
+GbTab *gb_editor_tab_preview (GbEditorTab *tab);
G_END_DECLS
diff --git a/src/resources/gnome-builder.gresource.xml b/src/resources/gnome-builder.gresource.xml
index 96516db..07ad845 100644
--- a/src/resources/gnome-builder.gresource.xml
+++ b/src/resources/gnome-builder.gresource.xml
@@ -23,6 +23,7 @@
<file>ui/gb-credits-widget.ui</file>
<file>ui/gb-devhelp-tab.ui</file>
<file>ui/gb-editor-settings-widget.ui</file>
+ <file>ui/gb-editor-frame.ui</file>
<file>ui/gb-editor-tab.ui</file>
<file>ui/gb-editor-workspace.ui</file>
<file>ui/gb-preferences-window.ui</file>
diff --git a/src/resources/ui/gb-editor-tab.ui b/src/resources/ui/gb-editor-tab.ui
index 56c9fef..3f9476c 100644
--- a/src/resources/ui/gb-editor-tab.ui
+++ b/src/resources/ui/gb-editor-tab.ui
@@ -4,135 +4,75 @@
<template class="GbEditorTab" parent="GbTab">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="orientation">horizontal</property>
<property name="expand">True</property>
- <child internal-child="content">
- <object class="GtkBox" id="content">
+ <child internal-child="controls">
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <style>
+ <class name="linked"/>
+ </style>
+ <child>
+ <object class="GtkComboBox" id="symbol_browser">
+ <property name="visible">true</property>
+ <property name="hexpand">true</property>
+ <style>
+ <class name="tab-control-first"/>
+ </style>
+ </object>
+ </child>
<child>
- <object class="GtkOverlay" id="overlay">
+ <object class="GtkToggleButton" id="split_button">
<property name="visible">True</property>
+ <property name="tooltip_text">Split tab vertically</property>
+ <style>
+ <class name="image-button"/>
+ <class name="tab-control-last"/>
+ </style>
<child>
- <object class="GtkScrolledWindow" id="scroller">
+ <object class="GtkImage">
<property name="visible">True</property>
- <property name="expand">True</property>
- <child>
- <object class="GbSourceView" id="source_view">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="show_line_numbers">True</property>
- <property name="show_right_margin">True</property>
- <property name="right_margin_position">80</property>
- </object>
- </child>
+ <property name="icon_size">1</property>
+ <property name="icon_name">builder-split-tab</property>
</object>
</child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child internal-child="content">
+ <object class="GtkBox" id="content">
+ <child>
+ <object class="GtkOverlay">
+ <property name="visible">true</property>
<child type="overlay">
<object class="GtkProgressBar" id="progress_bar">
- <property name="visible">False</property>
- <property name="halign">fill</property>
- <property name="valign">start</property>
+ <property name="visible">false</property>
<property name="fraction">0.0</property>
+ <property name="valign">start</property>
+ <property name="halign">fill</property>
+ <property name="vexpand">false</property>
<style>
<class name="osd"/>
</style>
</object>
</child>
- <child type="overlay">
- <object class="NautilusFloatingBar" id="floating_bar">
- <property name="visible">True</property>
- <property name="halign">end</property>
- <property name="valign">end</property>
+ <child>
+ <object class="GtkPaned" id="paned">
+ <property name="visible">true</property>
+ <property name="orientation">vertical</property>
+ <property name="vexpand">true</property>
<child>
- <object class="GtkSpinner" id="parsing_spinner">
- <property name="visible">False</property>
- <property name="active">False</property>
- <property name="margin-start">6</property>
- <property name="tooltip-text" translatable="yes">Currently parsing document.</property>
+ <object class="GbEditorFrame" id="frame">
+ <property name="visible">true</property>
+ <property name="vexpand">true</property>
</object>
<packing>
- <property name="pack_type">GTK_PACK_START</property>
- <property name="position">0</property>
+ <property name="resize">true</property>
+ <property name="shrink">false</property>
</packing>
</child>
</object>
</child>
- <child type="overlay">
- <object class="GtkRevealer" id="revealer">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">end</property>
- <property name="valign">start</property>
- <child>
- <object class="GtkFrame" id="frame">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="margin_end">12</property>
- <style>
- <class name="gb-search-slider"/>
- </style>
- <child>
- <object class="GtkBox" id="hbox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">horizontal</property>
- <style>
- <class name="linked"/>
- </style>
- <child>
- <object class="GdTaggedEntry" id="search_entry">
- <property name="visible">True</property>
- <property name="tag-close-visible">False</property>
- <property name="can_focus">True</property>
- <property name="width-request">260</property>
- <property name="primary-icon-activatable">True</property>
- <property name="primary-icon-sensitive">True</property>
- </object>
- </child>
- <child>
- <object class="GtkButton" id="go_up_button">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkImage" id="up_image">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="icon_size">1</property>
- <property name="icon_name">go-up-symbolic</property>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkButton" id="go_down_button">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkImage" id="down_image">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="icon_size">1</property>
- <property name="icon_name">go-down-symbolic</property>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- <child internal-child="footer">
- <object class="GtkBox">
- <child>
- <object class="GtkBox" id="preview_container">
- <property name="orientation">horizontal</property>
- <property name="visible">False</property>
- <property name="hexpand">True</property>
</object>
</child>
</object>
diff --git a/src/resources/ui/gb-editor-workspace.ui b/src/resources/ui/gb-editor-workspace.ui
index 26e4635..705d989 100644
--- a/src/resources/ui/gb-editor-workspace.ui
+++ b/src/resources/ui/gb-editor-workspace.ui
@@ -8,20 +8,38 @@
<property name="orientation">horizontal</property>
<property name="position">250</property>
<child>
- <object class="GtkScrolledWindow" id="scroller">
- <property name="visible">False</property>
+ <object class="GtkBox">
+ <property name="visible">false</property>
+ <property name="orientation">vertical</property>
<child>
- <object class="GbTree" id="tree">
- <property name="headers-visible">False</property>
+ <object class="GtkLabel" id="project_label">
+ <property name="name">project-title</property>
<property name="visible">True</property>
+ <property name="label"></property>
+ <property name="xalign">0.0</property>
+ <style>
+ <class name="button"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scroller">
+ <property name="visible">True</property>
+ <property name="vexpand">True</property>
+ <child>
+ <object class="GbTree" id="tree">
+ <property name="headers-visible">False</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
</object>
</child>
</object>
</child>
<child>
- <object class="GbMultiNotebook" id="multi_notebook">
- <property name="group-name">GB_EDITOR_WORKSPACE</property>
+ <object class="GbTabGrid" id="tab_grid">
<property name="visible">True</property>
+ <property name="hexpand">True</property>
</object>
</child>
</object>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]