[gnome-builder] markdown: add markdown preview as self contained tab
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] markdown: add markdown preview as self contained tab
- Date: Tue, 2 Dec 2014 04:25:28 +0000 (UTC)
commit 233f1b54d8db17efc44c6a8c14f3e050dd62ccc9
Author: Christian Hergert <christian hergert me>
Date: Mon Dec 1 20:00:20 2014 -0800
markdown: add markdown preview as self contained tab
src/markdown/gb-markdown-preview.c | 17 +++-
src/markdown/gb-markdown-tab.c | 198 +++++++++++++++++++++++++++++++++++
src/markdown/gb-markdown-tab.h | 56 ++++++++++
src/resources/ui/gb-markdown-tab.ui | 17 +++
4 files changed, 285 insertions(+), 3 deletions(-)
---
diff --git a/src/markdown/gb-markdown-preview.c b/src/markdown/gb-markdown-preview.c
index 8366628..b11021c 100644
--- a/src/markdown/gb-markdown-preview.c
+++ b/src/markdown/gb-markdown-preview.c
@@ -107,6 +107,9 @@ gb_markdown_preview_reload (GbMarkdownPreview *preview)
priv = preview->priv;
+ if (!priv->buffer)
+ EXIT;
+
gtk_text_buffer_get_bounds (priv->buffer, &begin, &end);
text = gtk_text_buffer_get_text (priv->buffer, &begin, &end, TRUE);
@@ -158,12 +161,17 @@ gb_markdown_preview_set_buffer (GbMarkdownPreview *preview,
{
g_signal_handler_disconnect (priv->buffer, priv->buffer_changed_handler);
priv->buffer_changed_handler = 0;
- g_clear_object (&priv->buffer);
+
+ g_object_remove_weak_pointer (G_OBJECT (priv->buffer),
+ (gpointer *)&priv->buffer);
+ priv->buffer = NULL;
}
if (buffer)
{
- priv->buffer = g_object_ref (buffer);
+ priv->buffer = buffer;
+ g_object_add_weak_pointer (G_OBJECT (priv->buffer),
+ (gpointer *)&priv->buffer);
priv->buffer_changed_handler =
g_signal_connect_object (priv->buffer,
"changed",
@@ -183,7 +191,8 @@ gb_markdown_preview_dispose (GObject *object)
{
g_signal_handler_disconnect (priv->buffer, priv->buffer_changed_handler);
priv->buffer_changed_handler = 0;
- g_clear_object (&priv->buffer);
+ g_object_remove_weak_pointer (G_OBJECT (priv->buffer),
+ (gpointer *)&priv->buffer);
}
G_OBJECT_CLASS (gb_markdown_preview_parent_class)->dispose (object);
@@ -202,6 +211,7 @@ gb_markdown_preview_get_property (GObject *object,
case PROP_BUFFER:
g_value_set_object (value, gb_markdown_preview_get_buffer (self));
break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -220,6 +230,7 @@ gb_markdown_preview_set_property (GObject *object,
case PROP_BUFFER:
gb_markdown_preview_set_buffer (self, g_value_get_object (value));
break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
diff --git a/src/markdown/gb-markdown-tab.c b/src/markdown/gb-markdown-tab.c
new file mode 100644
index 0000000..d5b78ef
--- /dev/null
+++ b/src/markdown/gb-markdown-tab.c
@@ -0,0 +1,198 @@
+/* gb-markdown-tab.c
+ *
+ * Copyright (C) 2014 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/>.
+ */
+
+#include <glib/gi18n.h>
+
+#include "gb-markdown-preview.h"
+#include "gb-markdown-tab.h"
+
+struct _GbMarkdownTabPrivate
+{
+ GtkTextBuffer *buffer;
+ GbMarkdownPreview *preview;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GbMarkdownTab, gb_markdown_tab, GB_TYPE_TAB)
+
+enum {
+ PROP_0,
+ PROP_BUFFER,
+ LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+GbTab *
+gb_markdown_tab_new (GtkTextBuffer *buffer)
+{
+ return g_object_new (GB_TYPE_MARKDOWN_TAB,
+ "buffer", buffer,
+ NULL);
+}
+
+static gboolean
+remove_tab (gpointer user_data)
+{
+ GbTab *tab = user_data;
+
+ g_return_val_if_fail (GB_IS_TAB (tab), G_SOURCE_REMOVE);
+
+ gb_tab_close (tab);
+ g_object_unref (tab);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+gb_markdown_tab_weak_unref (gpointer data,
+ GObject *where_object_was)
+{
+ GbMarkdownTab *tab = data;
+
+ g_return_if_fail (GB_IS_MARKDOWN_TAB (tab));
+
+ /*
+ * Close the tab if we lose our buffer. This will happen with the tab owning
+ * the buffer is destroyed. This causes us to destroy with it.
+ */
+ if (where_object_was == (void *)tab->priv->buffer)
+ g_timeout_add (0, remove_tab, g_object_ref (tab));
+}
+
+GtkTextBuffer *
+gb_markdown_tab_get_buffer (GbMarkdownTab *tab)
+{
+ g_return_val_if_fail (GB_IS_MARKDOWN_TAB (tab), NULL);
+
+ return tab->priv->buffer;
+}
+
+static void
+gb_markdown_tab_set_buffer (GbMarkdownTab *tab,
+ GtkTextBuffer *buffer)
+{
+ g_return_if_fail (GB_IS_MARKDOWN_TAB (tab));
+ g_return_if_fail (!buffer || GTK_IS_TEXT_BUFFER (buffer));
+
+ if (tab->priv->buffer != buffer)
+ {
+ if (tab->priv->buffer)
+ {
+ g_object_weak_unref (G_OBJECT (tab->priv->buffer),
+ gb_markdown_tab_weak_unref,
+ tab);
+ tab->priv->buffer = NULL;
+ }
+
+ if (buffer)
+ {
+ tab->priv->buffer = buffer;
+ g_object_weak_ref (G_OBJECT (tab->priv->buffer),
+ gb_markdown_tab_weak_unref,
+ tab);
+ }
+
+ gb_markdown_preview_set_buffer (tab->priv->preview, buffer);
+
+ g_object_notify_by_pspec (G_OBJECT (tab), gParamSpecs [PROP_BUFFER]);
+ }
+}
+
+static void
+gb_markdown_tab_finalize (GObject *object)
+{
+ GbMarkdownTab *tab = GB_MARKDOWN_TAB (object);
+
+ gb_markdown_tab_set_buffer (tab, NULL);
+
+ G_OBJECT_CLASS (gb_markdown_tab_parent_class)->finalize (object);
+}
+
+static void
+gb_markdown_tab_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GbMarkdownTab *self = GB_MARKDOWN_TAB (object);
+
+ switch (prop_id)
+ {
+ case PROP_BUFFER:
+ g_value_set_object (value, gb_markdown_tab_get_buffer (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gb_markdown_tab_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GbMarkdownTab *self = GB_MARKDOWN_TAB (object);
+
+ switch (prop_id)
+ {
+ case PROP_BUFFER:
+ gb_markdown_tab_set_buffer (self, g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gb_markdown_tab_class_init (GbMarkdownTabClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = gb_markdown_tab_finalize;
+ object_class->get_property = gb_markdown_tab_get_property;
+ object_class->set_property = gb_markdown_tab_set_property;
+
+ gParamSpecs [PROP_BUFFER] =
+ g_param_spec_object ("buffer",
+ _("Buffer"),
+ _("The buffer to monitor."),
+ GTK_TYPE_TEXT_BUFFER,
+ (G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_BUFFER,
+ gParamSpecs [PROP_BUFFER]);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/org/gnome/builder/ui/gb-markdown-tab.ui");
+ gtk_widget_class_bind_template_child_private (widget_class, GbMarkdownTab, preview);
+
+ g_type_ensure (GB_TYPE_MARKDOWN_PREVIEW);
+}
+
+static void
+gb_markdown_tab_init (GbMarkdownTab *self)
+{
+ self->priv = gb_markdown_tab_get_instance_private (self);
+
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
diff --git a/src/markdown/gb-markdown-tab.h b/src/markdown/gb-markdown-tab.h
new file mode 100644
index 0000000..a7d06da
--- /dev/null
+++ b/src/markdown/gb-markdown-tab.h
@@ -0,0 +1,56 @@
+/* gb-markdown-tab.h
+ *
+ * Copyright (C) 2014 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/>.
+ */
+
+#ifndef GB_MARKDOWN_TAB_H
+#define GB_MARKDOWN_TAB_H
+
+#include "gb-tab.h"
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_MARKDOWN_TAB (gb_markdown_tab_get_type())
+#define GB_MARKDOWN_TAB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_MARKDOWN_TAB,
GbMarkdownTab))
+#define GB_MARKDOWN_TAB_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_MARKDOWN_TAB,
GbMarkdownTab const))
+#define GB_MARKDOWN_TAB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GB_TYPE_MARKDOWN_TAB,
GbMarkdownTabClass))
+#define GB_IS_MARKDOWN_TAB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GB_TYPE_MARKDOWN_TAB))
+#define GB_IS_MARKDOWN_TAB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GB_TYPE_MARKDOWN_TAB))
+#define GB_MARKDOWN_TAB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GB_TYPE_MARKDOWN_TAB,
GbMarkdownTabClass))
+
+typedef struct _GbMarkdownTab GbMarkdownTab;
+typedef struct _GbMarkdownTabClass GbMarkdownTabClass;
+typedef struct _GbMarkdownTabPrivate GbMarkdownTabPrivate;
+
+struct _GbMarkdownTab
+{
+ GbTab parent;
+
+ /*< private >*/
+ GbMarkdownTabPrivate *priv;
+};
+
+struct _GbMarkdownTabClass
+{
+ GbTabClass parent;
+};
+
+GType gb_markdown_tab_get_type (void);
+GbTab *gb_markdown_tab_new (GtkTextBuffer *buffer);
+
+G_END_DECLS
+
+#endif /* GB_MARKDOWN_TAB_H */
diff --git a/src/resources/ui/gb-markdown-tab.ui b/src/resources/ui/gb-markdown-tab.ui
new file mode 100644
index 0000000..ec49413
--- /dev/null
+++ b/src/resources/ui/gb-markdown-tab.ui
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.8 -->
+ <template class="GbMarkdownTab" parent="GbTab">
+ <property name="visible">true</property>
+ <child internal-child="content">
+ <object class="GtkBox">
+ <child>
+ <object class="GbMarkdownPreview" id="preview">
+ <property name="visible">true</property>
+ <property name="expand">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]