[gitg/wip/commit: 24/28] Added sidebar widget
- From: Jesse van den Kieboom <jessevdk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gitg/wip/commit: 24/28] Added sidebar widget
- Date: Wed, 3 Jul 2013 14:55:30 +0000 (UTC)
commit 1dbeca4fdc8308d6ca09001b9d9a38add36b8173
Author: Jesse van den Kieboom <jessevdk gmail com>
Date: Wed Jul 3 16:41:51 2013 +0200
Added sidebar widget
libgitg/Makefile.am | 3 +-
libgitg/gitg-sidebar.vala | 418 +++++++++++++++++++++++++++++++++++++
libgitg/resources/resources.xml | 3 +
libgitg/resources/sidebar-view.ui | 63 ++++++
4 files changed, 486 insertions(+), 1 deletions(-)
---
diff --git a/libgitg/Makefile.am b/libgitg/Makefile.am
index 305a9a1..a440222 100644
--- a/libgitg/Makefile.am
+++ b/libgitg/Makefile.am
@@ -64,7 +64,8 @@ VALA_FILES = \
gitg-when-mapped.vala \
gitg-progress-bin.vala \
gitg-stage.vala \
- gitg-stage-status-enumerator.vala
+ gitg-stage-status-enumerator.vala \
+ gitg-sidebar.vala
# Ignore all warnings for vala code...
libgitg_1_0_la_CFLAGS = \
diff --git a/libgitg/gitg-sidebar.vala b/libgitg/gitg-sidebar.vala
new file mode 100644
index 0000000..b5b4ea4
--- /dev/null
+++ b/libgitg/gitg-sidebar.vala
@@ -0,0 +1,418 @@
+/*
+ * This file is part of gitg
+ *
+ * Copyright (C) 2013 - Jesse van den Kieboom
+ *
+ * gitg 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * gitg 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 gitg. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Gitg
+{
+
+public enum SidebarHint
+{
+ NONE,
+ HEADER,
+ DEFAULT,
+ SEPARATOR,
+ DUMMY
+}
+
+public enum SidebarColumn
+{
+ ICON_NAME,
+ NAME,
+ TEXT,
+ HEADER,
+ HINT,
+ SECTION,
+ OID
+}
+
+public delegate void SidebarActivated(int numclick);
+
+[GtkTemplate ( ui = "/org/gnome/gitg/gtk/sidebar/sidebar-store.ui" )]
+public class SidebarStore : Gtk.TreeStore
+{
+ private class Activated : Object
+ {
+ private SidebarActivated d_activated;
+
+ public Activated(owned SidebarActivated? activated)
+ {
+ d_activated = (owned)activated;
+ }
+
+ public void activate(int numclick)
+ {
+ if (d_activated != null)
+ {
+ d_activated(numclick);
+ }
+ }
+ }
+
+ private Activated[] d_callbacks;
+ private uint d_oid;
+ private uint d_sections;
+ private SList<Gtk.TreeIter?> d_parents;
+
+ construct
+ {
+ d_callbacks = new Activated[100];
+ d_callbacks.length = 0;
+ }
+
+ private new void append(string text,
+ string? name,
+ string? icon_name,
+ uint hint,
+ owned SidebarActivated? callback,
+ out Gtk.TreeIter iter)
+ {
+ if (d_parents != null)
+ {
+ base.append(out iter, d_parents.data);
+ }
+ else
+ {
+ base.append(out iter, null);
+ }
+
+ @set(iter,
+ SidebarColumn.ICON_NAME, icon_name,
+ SidebarColumn.NAME, name,
+ hint == SidebarHint.HEADER ? SidebarColumn.HEADER : SidebarColumn.TEXT, text,
+ SidebarColumn.HINT, hint,
+ SidebarColumn.SECTION, d_sections,
+ SidebarColumn.OID, d_oid);
+
+ d_callbacks += new Activated((owned)callback);
+ ++d_oid;
+ }
+
+ public SidebarStore append_dummy(string text,
+ string? name = null,
+ string? icon_name = null,
+ owned SidebarActivated? callback = null)
+ {
+ Gtk.TreeIter iter;
+ append(text, name, icon_name, SidebarHint.DUMMY, (owned)callback, out iter);
+
+ return this;
+ }
+
+ public SidebarStore append_normal(string text,
+ string? name = null,
+ string? icon_name = null,
+ owned SidebarActivated? callback = null)
+ {
+ Gtk.TreeIter iter;
+ append(text, name, icon_name, SidebarHint.NONE, (owned)callback, out iter);
+
+ return this;
+ }
+
+ public SidebarStore append_default(string text,
+ string? name = null,
+ string? icon_name = null,
+ owned SidebarActivated? callback = null)
+ {
+ Gtk.TreeIter iter;
+ append(text, name, icon_name, SidebarHint.DEFAULT, (owned)callback, out iter);
+
+ return this;
+ }
+
+ public SidebarStore begin_header(string text,
+ string? icon_name = null)
+ {
+ Gtk.TreeIter iter;
+
+ append(text, null, icon_name, SidebarHint.HEADER, null, out iter);
+ d_parents.prepend(iter);
+
+ return this;
+ }
+
+ public SidebarStore end_header()
+ {
+ if (d_parents != null)
+ {
+ d_parents.delete_link(d_parents);
+ }
+
+ return this;
+ }
+
+ public uint begin_section()
+ {
+ d_parents = null;
+ return d_sections;
+ }
+
+ public void end_section()
+ {
+ ++d_sections;
+ }
+
+ public new void clear()
+ {
+ base.clear();
+
+ d_oid = 0;
+ d_sections = 0;
+ d_callbacks.length = 0;
+ }
+
+ public void activate(Gtk.TreeIter iter, int numclick)
+ {
+ uint oid;
+
+ @get(iter, SidebarColumn.OID, out oid);
+
+ if (d_callbacks[oid] != null)
+ {
+ d_callbacks[oid].activate(numclick);
+ }
+ }
+}
+
+public class SidebarRendererText : Gtk.CellRendererText
+{
+ private string d_icon_name;
+ private Gdk.Pixbuf d_pixbuf;
+ private Gtk.StateFlags d_state;
+
+ public string? icon_name
+ {
+ get { return d_icon_name;}
+ set
+ {
+ if (d_icon_name != value)
+ {
+ d_icon_name = value;
+ reset_pixbuf();
+ }
+ }
+ }
+
+ public uint hint
+ {
+ get;
+ set;
+ }
+
+ construct
+ {
+ ellipsize = Pango.EllipsizeMode.MIDDLE;
+ }
+
+ private void reset_pixbuf()
+ {
+ d_pixbuf = null;
+ }
+
+ private void ensure_pixbuf(Gtk.StyleContext ctx)
+ {
+ if (d_icon_name == null || (d_pixbuf != null && d_state == ctx.get_state()))
+ {
+ return;
+ }
+
+ d_pixbuf = null;
+
+ d_state = ctx.get_state();
+
+ var screen = ctx.get_screen();
+ var settings = Gtk.Settings.get_for_screen(screen);
+
+ int w = 16;
+ int h = 16;
+
+ Gtk.icon_size_lookup_for_settings(settings, Gtk.IconSize.MENU, out w, out h);
+
+ var theme = Gtk.IconTheme.get_default();
+
+ Gtk.IconInfo? info = theme.lookup_icon(d_icon_name,
+ int.min(w, h),
+ Gtk.IconLookupFlags.USE_BUILTIN);
+
+ if (info == null)
+ {
+ return;
+ }
+
+ bool symbolic = false;
+
+ try
+ {
+ d_pixbuf = info.load_symbolic_for_context(ctx, out symbolic);
+ } catch {};
+
+ if (d_pixbuf != null)
+ {
+ var source = new Gtk.IconSource();
+ source.set_pixbuf(d_pixbuf);
+
+ source.set_size(Gtk.IconSize.SMALL_TOOLBAR);
+ source.set_size_wildcarded(false);
+
+ d_pixbuf = ctx.render_icon_pixbuf(source, Gtk.IconSize.SMALL_TOOLBAR);
+ }
+ }
+
+ protected override void get_preferred_width(Gtk.Widget widget,
+ out int minimum_width,
+ out int minimum_height)
+ {
+ ensure_pixbuf(widget.get_style_context());
+
+ // Size of text
+ base.get_preferred_width(widget, out minimum_width, out minimum_height);
+
+ if (d_pixbuf != null)
+ {
+ minimum_width += d_pixbuf.get_width() + 3;
+ minimum_height += d_pixbuf.get_height();
+ }
+ }
+
+ protected override void get_preferred_height_for_width(Gtk.Widget widget,
+ int width,
+ out int minimum_height,
+ out int natural_height)
+ {
+ base.get_preferred_height_for_width(widget, width,
+ out minimum_height,
+ out natural_height);
+
+ ensure_pixbuf(widget.get_style_context());
+
+ if (d_pixbuf != null)
+ {
+ minimum_height = int.max(minimum_height, d_pixbuf.height);
+ natural_height = int.max(natural_height, d_pixbuf.height);
+ }
+ }
+
+ protected override void render(Cairo.Context ctx,
+ Gtk.Widget widget,
+ Gdk.Rectangle background_area,
+ Gdk.Rectangle cell_area,
+ Gtk.CellRendererState state)
+ {
+ var stx = widget.get_style_context();
+ ensure_pixbuf(stx);
+
+ if (d_pixbuf == null)
+ {
+ base.render(ctx, widget, background_area, cell_area, state);
+ }
+ else
+ {
+ // render the text with an additional padding
+ Gdk.Rectangle area = cell_area;
+ area.x += d_pixbuf.width + 3;
+
+ base.render(ctx, widget, background_area, area, state);
+
+ // render the pixbuf
+ int yp = (cell_area.height - d_pixbuf.height) / 2;
+
+ stx.render_icon(ctx, d_pixbuf, cell_area.x, cell_area.y + yp);
+ }
+ }
+}
+
+[GtkTemplate ( ui = "/org/gnome/gitg/gtk/sidebar/sidebar-view.ui" )]
+public class Sidebar : Gtk.TreeView
+{
+ [GtkChild (name = "column")]
+ private Gtk.TreeViewColumn d_column;
+
+ [GtkChild (name = "renderer_header")]
+ private SidebarRendererText d_renderer_header;
+
+ [GtkChild (name = "renderer_text")]
+ private SidebarRendererText d_renderer_text;
+
+ construct
+ {
+ d_column.set_cell_data_func(d_renderer_header, (layout, cell, model, iter) => {
+ SidebarHint hint;
+ model.get(iter, SidebarColumn.HINT, out hint);
+
+ cell.visible = (hint == SidebarHint.HEADER);
+ });
+
+ d_column.set_cell_data_func(d_renderer_text, (layout, cell, model, iter) => {
+ SidebarHint hint;
+ model.get(iter, SidebarColumn.HINT, out hint);
+
+ cell.visible = (hint != SidebarHint.HEADER);
+
+ var r = (Gtk.CellRendererText)cell;
+
+ if (hint == SidebarHint.DUMMY)
+ {
+ var col = get_style_context().get_color(Gtk.StateFlags.INSENSITIVE);
+ r.foreground_rgba = col;
+ }
+ else
+ {
+ r.foreground_set = false;
+ }
+ });
+
+ set_row_separator_func((model, iter) => {
+ SidebarHint hint;
+ model.get(iter, SidebarColumn.HINT, out hint);
+
+ return hint == SidebarHint.SEPARATOR;
+ });
+
+ var sel = get_selection();
+
+ sel.set_select_function((sel, model, path, cursel) => {
+ Gtk.TreeIter iter;
+ model.get_iter(out iter, path);
+
+ uint hint;
+
+ model.get(iter, SidebarColumn.HINT, out hint);
+
+ return hint != SidebarHint.HEADER && hint != SidebarHint.DUMMY;
+ });
+
+ sel.changed.connect((sel) => {
+ Gtk.TreeIter iter;
+
+ if (sel.get_selected(null, out iter))
+ {
+ model.activate(iter, 1);
+ }
+ });
+ }
+
+ public new SidebarStore model
+ {
+ get { return base.get_model() as SidebarStore; }
+ set { base.set_model(value); }
+ }
+}
+
+}
+
+// ex: ts=4 noet
diff --git a/libgitg/resources/resources.xml b/libgitg/resources/resources.xml
index a94611d..4a29d03 100644
--- a/libgitg/resources/resources.xml
+++ b/libgitg/resources/resources.xml
@@ -10,6 +10,9 @@
<gresource prefix="/org/gnome/gitg/gtk/dash-view">
<file compressed="true" preprocess="xml-stripblanks">gitg-dash-view-row.ui</file>
</gresource>
+ <gresource prefix="/org/gnome/gitg/gtk/sidebar">
+ <file compressed="true">sidebar-view.ui</file>
+ </gresource>
</gresources>
<!-- ex: et ts=2 -->
diff --git a/libgitg/resources/sidebar-view.ui b/libgitg/resources/sidebar-view.ui
new file mode 100644
index 0000000..ae8a86a
--- /dev/null
+++ b/libgitg/resources/sidebar-view.ui
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.3 -->
+ <!-- interface-requires gitg 0.0 -->
+ <!-- interface-requires gd 1.0 -->
+ <template class="GitgSidebar">
+ <property name="model">sidebar_store</property>
+ <property name="show-expanders">False</property>
+ <property name="headers-visible">False</property>
+ <property name="level-indentation">12</property>
+ <child>
+ <object class="GtkTreeViewColumn" id="column">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkCellRendererText" id="renderer_padding">
+ <property name="xpad">6</property>
+ <property name="visible">True</property>
+ </object>
+ <cell-packing>
+ <property name="expand">False</property>
+ </cell-packing>
+ </child>
+ <child>
+ <object class="GitgSidebarRendererText" id="renderer_header">
+ <property name="ypad">6</property>
+ <property name="weight">700</property>
+ </object>
+ <attributes>
+ <attribute name="icon_name">0</attribute>
+ <attribute name="text">3</attribute>
+ </attributes>
+ <cell-packing>
+ <property name="expand">True</property>
+ </cell-packing>
+ </child>
+ <child>
+ <object class="GitgSidebarRendererText" id="renderer_text">
+ </object>
+ <attributes>
+ <attribute name="icon_name">0</attribute>
+ <attribute name="text">2</attribute>
+ </attributes>
+ <cell-packing>
+ <property name="expand">True</property>
+ </cell-packing>
+ </child>
+ </object>
+ </child>
+ </template>
+ <object class="GitgSidebarStore" id="sidebar_store">
+ <columns>
+ <column type="gchararray"/>
+ <column type="gchararray"/>
+ <column type="gchararray"/>
+ <column type="gchararray"/>
+ <column type="guint"/>
+ <column type="guint"/>
+ <column type="guint"/>
+ </columns>
+ </object>
+</interface>
+
+<!-- ex:set ts=2 et: -->
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]