[baobab/wip/valacharts] Port chart widgets to Vala
- From: Stefano Facchini <sfacchini src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [baobab/wip/valacharts] Port chart widgets to Vala
- Date: Sun, 9 Jun 2013 15:48:13 +0000 (UTC)
commit 01a76bc152ab8d958fadfb236619cc6270b1d583
Author: Stefano Facchini <stefano facchini gmail com>
Date: Sun Jun 9 17:37:18 2013 +0200
Port chart widgets to Vala
A line-by-line translation of the original C drawing code.
Everything else is missing: popup menu, tooltips, mouse events
src/Makefile.am | 12 +-
src/baobab-chart.c | 1772 --------------------------------------------
src/baobab-chart.h | 161 ----
src/baobab-chart.vala | 461 ++++++++++++
src/baobab-ringschart.c | 683 -----------------
src/baobab-ringschart.h | 74 --
src/baobab-ringschart.vala | 171 +++++
src/baobab-treemap.c | 354 ---------
src/baobab-treemap.h | 65 --
src/baobab-treemap.vala | 146 ++++
src/baobab-window.vala | 8 +-
src/baobab.vapi | 36 -
12 files changed, 785 insertions(+), 3158 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index b1ad1c4..4e92fd0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,14 +16,12 @@ baobab_VALAFLAGS = \
--pkg gio-unix-2.0 \
--gresources=baobab.gresource.xml
-noinst_HEADERS = \
- baobab-chart.h \
- baobab-treemap.h \
- baobab-ringschart.h
-
VALA_SOURCES = \
baobab-application.vala \
baobab-cellrenderers.vala \
+ baobab-chart.vala \
+ baobab-treemap.vala \
+ baobab-ringschart.vala \
baobab-connect-server.vala \
baobab-location.vala \
baobab-location-list.vala \
@@ -40,11 +38,7 @@ egg_list_box_sources = \
baobab_SOURCES = \
$(VALA_SOURCES) \
fixes.vapi \
- baobab.vapi \
config.vapi \
- baobab-chart.c \
- baobab-treemap.c \
- baobab-ringschart.c \
$(egg_list_box_sources) \
$(BUILT_SOURCES)
diff --git a/src/baobab-chart.vala b/src/baobab-chart.vala
new file mode 100644
index 0000000..b60edeb
--- /dev/null
+++ b/src/baobab-chart.vala
@@ -0,0 +1,461 @@
+/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+namespace Baobab {
+
+ public abstract class ChartItem {
+ public string name;
+ public string size;
+ public uint depth;
+ public double rel_start;
+ public double rel_size;
+ public Gtk.TreeIter iter;
+ public bool visible;
+ public bool has_any_child;
+ public bool has_visible_children;
+ public Gdk.Rectangle rect;
+
+ public unowned List<ChartItem> parent;
+ }
+
+ public abstract class Chart : Gtk.Widget {
+
+ const uint MAX_DEPTH = 8;
+ const uint MIN_DEPTH = 1;
+
+ const Gdk.RGBA TANGO_COLORS[] = {{0.94, 0.16, 0.16, 1.0}, /* tango: ef2929 */
+ {0.68, 0.49, 0.66, 1.0}, /* tango: ad7fa8 */
+ {0.45, 0.62, 0.82, 1.0}, /* tango: 729fcf */
+ {0.54, 0.89, 0.20, 1.0}, /* tango: 8ae234 */
+ {0.91, 0.73, 0.43, 1.0}, /* tango: e9b96e */
+ {0.99, 0.68, 0.25, 1.0}}; /* tango: fcaf3e */
+
+ uint name_column;
+ uint size_column;
+ uint info_column;
+ uint percentage_column;
+ uint valid_column;
+ bool button_pressed;
+ bool is_frozen;
+
+ uint max_depth_ = MAX_DEPTH;
+ public uint max_depth {
+ set {
+ var m = uint.max (uint.min (value, MAX_DEPTH), MIN_DEPTH);
+ if (max_depth_ == m) {
+ return;
+ }
+ max_depth_ = m;
+ model_changed = true;
+ queue_draw ();
+ }
+ get {
+ return max_depth_;
+ }
+ }
+
+ bool model_changed;
+
+ Gtk.TreeModel model;
+ Gtk.TreeRowReference root;
+
+ List<ChartItem> items;
+ ChartItem highlighted_item = null;
+
+ Gtk.Widget popup_menu;
+
+ public signal void item_activated (Gtk.TreeIter iter);
+
+ protected abstract void draw_item (Cairo.Context cr, ChartItem item, bool highlighted);
+ //abstract void pre_draw (Cairo.Context cr);
+ //abstract void post_draw (Cairo.Context cr);
+
+ protected abstract void calculate_item_geometry (ChartItem item);
+
+ //protected abstract bool is_point_over_item (ChartItem item, double x, double y);
+
+ protected abstract void get_item_rectangle (ChartItem item);
+
+ //protected abstract uint max_zoom_int ();
+ //protected abstract uint max_zoom_out ();
+
+ protected abstract ChartItem create_new_chartitem ();
+
+ public override void realize () {
+ Gtk.Allocation allocation;
+ get_allocation (out allocation);
+ set_realized (true);
+
+ Gdk.WindowAttr attributes = {};
+ attributes.window_type = Gdk.WindowType.CHILD;
+ attributes.x = allocation.x;
+ attributes.y = allocation.y;
+ attributes.width = allocation.width;
+ attributes.height = allocation.height;
+ attributes.wclass = Gdk.WindowWindowClass.INPUT_OUTPUT;
+ //attributes.visual = gtk_widget_get_visual (widget);
+ attributes.event_mask = this.get_events () | Gdk.EventMask.EXPOSURE_MASK |
Gdk.EventMask.ENTER_NOTIFY_MASK | Gdk.EventMask.LEAVE_NOTIFY_MASK | Gdk.EventMask.BUTTON_PRESS_MASK |
Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.POINTER_MOTION_HINT_MASK | Gdk.EventMask.SCROLL_MASK;
+
+ var window = new Gdk.Window (get_parent_window (), attributes, Gdk.WindowAttributesType.X |
Gdk.WindowAttributesType.Y);
+
+ set_window (window);
+ window.set_user_data (this);
+
+ get_style_context ().set_background (window);
+ }
+
+ public override void unrealize () {
+ // destroy popup menu...
+ base.unrealize ();
+ }
+
+ public override void size_allocate (Gtk.Allocation allocation) {
+ set_allocation (allocation);
+ if (get_realized ()) {
+ get_window ().move_resize (allocation.x,
+ allocation.y,
+ allocation.width,
+ allocation.height);
+
+ foreach (ChartItem item in items) {
+ item.has_visible_children = false;
+ item.visible = false;
+ calculate_item_geometry (item);
+ }
+ }
+ }
+
+ unowned List<ChartItem> add_item (uint depth, double rel_start, double rel_size, Gtk.TreeIter iter) {
+ string name;
+ uint64 size;
+ model.get (iter, name_column, out name, size_column, out size, -1);
+
+ var item = create_new_chartitem ();
+ item.name = name;
+ item.size = format_size (size);
+ item.depth = depth;
+ item.rel_start = rel_start;
+ item.rel_size = rel_size;
+ item.has_any_child = false;
+ item.visible = false;
+ item.has_visible_children = false;
+ item.iter = iter;
+ item.parent = null;
+
+ items.prepend (item);
+
+ unowned List<ChartItem> ret = items;
+ return ret;
+ }
+
+ void get_items (Gtk.TreePath root) {
+ unowned List<ChartItem> node = null;
+ Gtk.TreeIter initial_iter = {0};
+ double size;
+ Gtk.TreePath model_root_path;
+ Gtk.TreeIter model_root_iter;
+ Gtk.TreeIter child_iter = {0};
+ unowned List<ChartItem> child_node;
+ double rel_start;
+
+ items = null;
+
+ if (!model.get_iter (out initial_iter, root)) {
+ model_changed = false;
+ return;
+ }
+
+ model_root_path = new Gtk.TreePath.first ();
+ model.get_iter (out model_root_iter, model_root_path);
+ model.get (model_root_iter, percentage_column, out size, -1);
+
+ node = add_item (0, 0, 100, initial_iter);
+
+ do {
+ ChartItem item = node.data;
+ item.has_any_child = model.iter_children (out child_iter, item.iter);
+
+ calculate_item_geometry (item);
+
+ if (!item.visible) {
+ node = node.prev;
+ continue;
+ }
+
+ if ((item.has_any_child) && (item.depth < max_depth + 1)) {
+ rel_start = 0;
+ do {
+ model.get (child_iter, percentage_column, out size, -1);
+ child_node = add_item (item.depth + 1, rel_start, size, child_iter);
+ var child = child_node.data;
+ child.parent = node;
+ rel_start += size;
+ } while (model.iter_next (ref child_iter));
+ }
+
+ node = node.prev;
+ } while (node != null);
+
+ items.reverse ();
+
+ model_changed = false;
+ }
+
+ void draw_chart (Cairo.Context cr) {
+ // call pre_draw
+
+ cr.save ();
+
+ foreach (ChartItem item in items) {
+ Gdk.Rectangle clip;
+ if (Gdk.cairo_get_clip_rectangle (cr, out clip) &&
+ item.visible &&
+ clip.intersect (item.rect, null) &&
+ (item.depth <= max_depth)) {
+ bool highlighted = (item == highlighted_item);
+ draw_item (cr, item, highlighted);
+ }
+ }
+
+ cr.restore ();
+
+ // call post_draw
+ }
+
+ void update_draw (Gtk.TreePath path) {
+ if (!get_realized ()) {
+ return;
+ }
+
+ Gtk.TreePath root_path = null;
+
+ if (root != null) {
+ root_path = root.get_path ();
+ if (root_path == null) {
+ root = null;
+ }
+ }
+
+ if (root == null) {
+ root_path = new Gtk.TreePath.first ();
+ }
+
+ var root_depth = root_path.get_depth ();
+ var node_depth = path.get_depth ();
+
+ if (((node_depth - root_depth) <= max_depth) &&
+ (root_path.is_ancestor (path) ||
+ root_path.compare (path) == 0)) {
+ queue_draw ();
+ }
+ }
+
+ void row_changed (Gtk.TreeModel model,
+ Gtk.TreePath path,
+ Gtk.TreeIter iter) {
+ model_changed = true;
+ update_draw (path);
+ }
+
+ void row_inserted (Gtk.TreeModel model,
+ Gtk.TreePath path,
+ Gtk.TreeIter iter) {
+ model_changed = true;
+ update_draw (path);
+ }
+
+ void row_deleted (Gtk.TreeModel model,
+ Gtk.TreePath path) {
+ model_changed = true;
+ update_draw (path);
+ }
+
+ void row_has_child_toggled (Gtk.TreeModel model,
+ Gtk.TreePath path,
+ Gtk.TreeIter iter) {
+ model_changed = true;
+ update_draw (path);
+ }
+
+ void row_reordered (Gtk.TreeModel model,
+ Gtk.TreePath path,
+ Gtk.TreeIter iter,
+ int new_order) {
+ model_changed = true;
+ update_draw (path);
+ }
+
+ public override bool draw (Cairo.Context cr) {
+ if (name_column == percentage_column) {
+ // Columns not set
+ return false;
+ }
+
+ if (model != null) {
+ Gtk.TreePath root_path = null;
+
+ cr.set_source_rgb (1, 1, 1);
+ cr.fill_preserve ();
+
+ if (root != null) {
+ root_path = root.get_path ();
+ }
+
+ if (root_path == null) {
+ root_path = new Gtk.TreePath.first ();
+ root = null;
+ }
+
+ if (model_changed || items == null) {
+ get_items (root_path);
+ } else {
+ var current_path = model.get_path (items.data.iter);
+ if (root_path.compare (current_path) != 0) {
+ get_items (root_path);
+ }
+ }
+
+ draw_chart (cr);
+ }
+
+ return false;
+ }
+
+ Gdk.RGBA interpolate_colors (Gdk.RGBA colora, Gdk.RGBA colorb, double percentage) {
+ var color = Gdk.RGBA ();
+
+ double diff;
+
+ diff = colora.red - colorb.red;
+ color.red = colora.red - diff * percentage;
+ diff = colora.green - colorb.green;
+ color.green = colora.green - diff * percentage;
+ diff = colora.blue - colorb.blue;
+ color.blue = colora.blue - diff * percentage;
+
+ color.alpha = 1.0;
+
+ return color;
+ }
+
+ protected Gdk.RGBA get_item_color (double rel_position, uint depth, bool highlighted) {
+ const Gdk.RGBA level_color = {0.83, 0.84, 0.82, 1.0};
+ const Gdk.RGBA level_color_hi = {0.88, 0.89, 0.87, 1.0};
+
+
+ var color = Gdk.RGBA ();
+
+ double intensity = 1 - (((depth - 1) * 0.3) / MAX_DEPTH);
+
+ if (depth == 0) {
+ color = level_color;
+ } else {
+ int color_number = (int) (rel_position / (100.0/3));
+ int next_color_number = (color_number + 1) % 6;
+
+ color = interpolate_colors (TANGO_COLORS[color_number],
+ TANGO_COLORS[next_color_number],
+ (rel_position - color_number * 100/3) / (100/3));
+ color.red *= intensity;
+ color.green *= intensity;
+ color.blue *= intensity;
+ }
+
+ if (highlighted) {
+ if (depth == 0) {
+ color = level_color_hi;
+ } else {
+ double maximum = double.max (color.red, double.max (color.green, color.blue));
+ color.red /= maximum;
+ color.green /= maximum;
+ color.blue /= maximum;
+ }
+ }
+
+ return color;
+ }
+
+ void set_item_highlight () {
+ }
+
+ public void set_model_with_columns (Gtk.TreeModel model_,
+ uint name_column_,
+ uint size_column_,
+ uint info_column_,
+ uint percentage_column_,
+ uint valid_column_,
+ Gtk.TreePath? root_) {
+ set_model (model_);
+ if (root_ != null) {
+ root = new Gtk.TreeRowReference (model_, root_);
+ // notify ("root");
+ }
+
+ name_column = name_column_;
+ size_column = size_column_;
+ info_column = info_column_;
+ percentage_column = percentage_column_;
+ valid_column = valid_column_;
+ }
+
+ public void set_model (Gtk.TreeModel model_) {
+ if (model == model_) {
+ return;
+ }
+
+ model = model_;
+
+ root = null;
+
+ // notify ("model");
+
+ queue_draw ();
+ }
+
+ public Gtk.TreeModel get_model () {
+ return model;
+ }
+
+ public void set_root (Gtk.TreePath root_) {
+ if (root != null) {
+ var current_root = root.get_path ();
+ if (current_root != null && current_root.compare (root_) == 0) {
+ return;
+ }
+ } else {
+ }
+ root = (root_ != null) ? new Gtk.TreeRowReference (model, root_) : null;
+
+ // notify root
+
+ queue_draw ();
+ }
+
+ public Gtk.TreePath? get_root () {
+ if (root != null) {
+ return root.get_path ();
+ }
+
+ return null;
+ }
+
+ public void move_up_root () {
+ }
+
+ public void zoom_in () {
+ }
+
+ public void zoom_out () {
+ }
+
+ public bool can_zoom_in () {
+ return false;
+ }
+
+ public bool can_zoom_out () {
+ return false;
+ }
+
+ public ChartItem? get_highlighted_item () {
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/baobab-ringschart.vala b/src/baobab-ringschart.vala
new file mode 100644
index 0000000..bba3c75
--- /dev/null
+++ b/src/baobab-ringschart.vala
@@ -0,0 +1,171 @@
+/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+namespace Baobab {
+
+ public class RingschartItem : ChartItem {
+ public double min_radius = 0;
+ public double max_radius = 0;
+ public double start_angle = 0;
+ public double angle = 0;
+ public bool continued = false;
+ }
+
+ public class Ringschart : Chart {
+
+ const int ITEM_BORDER_WIDTH = 1;
+ const int CHART_PADDING = 13;
+ const double ITEM_MIN_ANGLE = 0.03;
+ const double EDGE_ANGLE = 0.004;
+
+ protected override ChartItem create_new_chartitem () {
+ return (new RingschartItem () as ChartItem);
+ }
+
+ void draw_sector (Cairo.Context cr,
+ double center_x,
+ double center_y,
+ double radius,
+ double thickness,
+ double init_angle,
+ double final_angle,
+ Gdk.RGBA fill_color,
+ bool continued,
+ uint border) {
+ cr.set_line_width (border);
+ if (radius > 0) {
+ cr.arc (center_x, center_y, radius, init_angle, final_angle);
+ }
+ cr.arc_negative (center_x, center_y, radius + thickness, final_angle, init_angle);
+
+ cr.close_path ();
+
+ Gdk.cairo_set_source_rgba (cr, fill_color);
+ cr.fill_preserve ();
+ cr.set_source_rgb (0, 0, 0);
+ cr.stroke ();
+
+ if (continued) {
+ cr.set_line_width (3);
+ cr.arc (center_x, center_y, radius + thickness + 4, init_angle + EDGE_ANGLE, final_angle -
EDGE_ANGLE);
+ cr.stroke ();
+ }
+ }
+
+ protected override void draw_item (Cairo.Context cr, ChartItem item, bool highlighted) {
+ RingschartItem ringsitem = item as RingschartItem;
+ // subtips...
+ var fill_color = get_item_color (ringsitem.start_angle / Math.PI * 99,
+ item.depth,
+ highlighted);
+
+ Gtk.Allocation allocation;
+ get_allocation (out allocation);
+
+ draw_sector (cr,
+ allocation.width / 2,
+ allocation.height /2,
+ ringsitem.min_radius,
+ ringsitem.max_radius - ringsitem.min_radius,
+ ringsitem.start_angle,
+ ringsitem.start_angle + ringsitem.angle,
+ fill_color,
+ ringsitem.continued,
+ ITEM_BORDER_WIDTH);
+ }
+
+ protected override void calculate_item_geometry (ChartItem item) {
+ RingschartItem ringsitem = item as RingschartItem;
+
+ ringsitem.continued = false;
+ ringsitem.visible = false;
+
+ Gtk.Allocation allocation;
+ get_allocation (out allocation);
+ var max_radius = int.min (allocation.width / 2, allocation.height / 2) - CHART_PADDING;
+ var thickness = max_radius / (max_depth + 1);
+
+ if (ringsitem.parent == null) {
+ ringsitem.min_radius = 0;
+ ringsitem.max_radius = thickness;
+ ringsitem.start_angle = 0;
+ ringsitem.angle = 2 * Math.PI;
+ } else {
+ var parent = item.parent.data as RingschartItem;
+ ringsitem.min_radius = ringsitem.depth * thickness;
+ if (ringsitem.depth > max_depth) {
+ return;
+ } else {
+ ringsitem.max_radius = ringsitem.min_radius + thickness;
+ }
+
+ ringsitem.angle = parent.angle * ringsitem.rel_size / 100;
+ if (ringsitem.angle < ITEM_MIN_ANGLE) {
+ return;
+ }
+
+ ringsitem.start_angle = parent.start_angle + parent.angle * ringsitem.rel_start / 100;
+ ringsitem.continued = (ringsitem.has_any_child) && (ringsitem.depth == max_depth);
+ parent.has_visible_children = true;
+ }
+
+ ringsitem.visible = true;
+ get_item_rectangle (item);
+ }
+
+ void get_point_min_rect (double cx, double cy, double radius, double angle, ref Gdk.Rectangle r) {
+ double x, y;
+ x = cx + Math.cos (angle) * radius;
+ y = cy + Math.sin (angle) * radius;
+
+ r.x = int.min (r.x, (int)x);
+ r.y = int.min (r.y, (int)y);
+ r.width = int.max (r.width, (int)x);
+ r.height = int.max (r.height, (int)y);
+ }
+
+ protected override void get_item_rectangle (ChartItem item) {
+ RingschartItem ringsitem = item as RingschartItem;
+ Gdk.Rectangle rect = Gdk.Rectangle ();
+ double cx, cy, r1, r2, a1, a2;
+ Gtk.Allocation allocation;
+
+ get_allocation (out allocation);
+ cx = allocation.width / 2;
+ cy = allocation.height / 2;
+ r1 = ringsitem.min_radius;
+ r2 = ringsitem.max_radius;
+ a1 = ringsitem.start_angle;
+ a2 = ringsitem.start_angle + ringsitem.angle;
+
+ rect.x = allocation.width;
+ rect.y = allocation.height;
+ rect.width = 0;
+ rect.height = 0;
+
+ get_point_min_rect (cx, cy, r1, a1, ref rect);
+ get_point_min_rect (cx, cy, r2, a1, ref rect);
+ get_point_min_rect (cx, cy, r1, a2, ref rect);
+ get_point_min_rect (cx, cy, r2, a2, ref rect);
+
+ if ((a1 <= Math.PI / 2) && (a2 >= Math.PI / 2)) {
+ rect.height = (int) double.max (rect.height, cy + Math.sin (Math.PI / 2) * r2);
+ }
+
+ if ((a1 <= Math.PI) && (a2 >= Math.PI)) {
+ rect.x = (int) double.min (rect.x, cx + Math.cos (Math.PI) * r2);
+ }
+
+ if ((a1 <= Math.PI * 1.5) && (a2 >= Math.PI * 1.5)) {
+ rect.y = (int) double.min (rect.y, cy + Math.sin (Math.PI * 1.5) * r2);
+ }
+
+ if ((a1 <= Math.PI * 2) && (a2 >= Math.PI * 2)) {
+ rect.width = (int) double.max (rect.width, cx + Math.cos (Math.PI * 2) * r2);
+ }
+
+ rect.width -= rect.x;
+ rect.height -= rect.y;
+
+ ringsitem.rect = rect;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/baobab-treemap.vala b/src/baobab-treemap.vala
new file mode 100644
index 0000000..385714f
--- /dev/null
+++ b/src/baobab-treemap.vala
@@ -0,0 +1,146 @@
+/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+namespace Baobab {
+
+ public class TreemapItem : ChartItem {
+ public Cairo.Rectangle cr_rect;
+ }
+
+ public class Treemap : Chart {
+
+ const int ITEM_BORDER_WIDTH = 1;
+ const int ITEM_PADDING = 6;
+ const int ITEM_MIN_WIDTH = 3;
+ const int ITEM_MIN_HEIGHT = 3;
+
+ uint max_visible_depth;
+ bool more_visible_children;
+
+ protected override ChartItem create_new_chartitem () {
+ return (new TreemapItem () as ChartItem);
+ }
+
+ void draw_rectangle (Cairo.Context cr,
+ double x,
+ double y,
+ double width,
+ double height,
+ Gdk.RGBA fill_color,
+ string text,
+ bool show_text) {
+ uint border = ITEM_BORDER_WIDTH;
+
+ cr.stroke ();
+
+ cr.set_line_width (border);
+ cr.rectangle (x + border, y + border, width - border * 2, height - border * 2);
+ Gdk.cairo_set_source_rgba (cr, fill_color);
+ cr.fill_preserve ();
+ cr.set_source_rgb (0, 0, 0);
+ cr.stroke ();
+
+ if (show_text) {
+ // show text
+ }
+ }
+
+ protected override void draw_item (Cairo.Context cr, ChartItem item, bool highlighted) {
+ Cairo.Rectangle rect;
+ Gdk.RGBA fill_color = {0};
+ Gtk.Allocation allocation;
+ double width = 0, height = 0;
+
+ rect = (item as TreemapItem).cr_rect;
+ get_allocation (out allocation);
+
+ if ((item.depth % 2) != 0) {
+ fill_color = get_item_color (rect.x / allocation.width * 200,
+ item.depth, highlighted);
+ width = rect.width - ITEM_PADDING;
+ height = rect.height;
+ } else {
+ fill_color = get_item_color (rect.y / allocation.height * 200,
+ item.depth, highlighted);
+ width = rect.width;
+ height = rect.height - ITEM_PADDING;
+ }
+
+ draw_rectangle (cr, rect.x, rect.y, width, height, fill_color, item.name,
(!item.has_visible_children));
+ }
+
+ protected override void calculate_item_geometry (ChartItem item) {
+ TreemapItem treemapitem = item as TreemapItem;
+ Cairo.Rectangle p_area = Cairo.Rectangle ();
+
+ if (item.depth == 0) {
+ max_visible_depth = 0;
+ more_visible_children = false;
+ }
+
+ item.visible = false;
+ if (item.parent == null) {
+ Gtk.Allocation allocation;
+ get_allocation (out allocation);
+ p_area.x = -ITEM_PADDING / 2;
+ p_area.y = -ITEM_PADDING / 2;
+ p_area.width = allocation.width + ITEM_PADDING * 2;
+ p_area.height = allocation.height + ITEM_PADDING * 2;
+ } else {
+ p_area = (item.parent.data as TreemapItem).cr_rect;
+ }
+
+ if (item.depth % 2 != 0) {
+ var width = p_area.width - ITEM_PADDING;
+
+ treemapitem.cr_rect.x = p_area.x + (item.rel_start * width / 100) + ITEM_PADDING;
+ treemapitem.cr_rect.y = p_area.y + ITEM_PADDING;
+ treemapitem.cr_rect.width = width * item.rel_size / 100;
+ treemapitem.cr_rect.height = p_area.height - ITEM_PADDING * 3;
+ } else {
+ var height = p_area.height - ITEM_PADDING;
+
+ treemapitem.cr_rect.x = p_area.x + ITEM_PADDING;
+ treemapitem.cr_rect.y = p_area.y + (item.rel_start * height / 100) + ITEM_PADDING;
+ treemapitem.cr_rect.width = p_area.width - ITEM_PADDING * 3;
+ treemapitem.cr_rect.height = height * item.rel_size / 100;
+ }
+ if ((treemapitem.cr_rect.width - ITEM_PADDING < ITEM_MIN_WIDTH) ||
+ (treemapitem.cr_rect.height - ITEM_PADDING < ITEM_MIN_HEIGHT)) {
+ return;
+ }
+
+ treemapitem.cr_rect.x = Math.floor (treemapitem.cr_rect.x) + 0.5;
+ treemapitem.cr_rect.y = Math.floor (treemapitem.cr_rect.y) + 0.5;
+ treemapitem.cr_rect.width = Math.floor (treemapitem.cr_rect.width);
+ treemapitem.cr_rect.height = Math.floor (treemapitem.cr_rect.height);
+
+ item.visible = true;
+
+ if (item.parent != null) {
+ item.parent.data.has_visible_children = true;
+ }
+
+ get_item_rectangle (item);
+
+ if (item.depth == max_depth + 1) {
+ more_visible_children = true;
+ } else {
+ max_visible_depth = uint.max (max_visible_depth, item.depth);
+ }
+ }
+
+ protected override void get_item_rectangle (ChartItem item) {
+ var crect = (item as TreemapItem).cr_rect;
+
+ item.rect.x = (int) crect.x;
+ item.rect.y = (int) crect.y;
+
+ if (item.depth % 2 != 0) {
+ item.rect.width = (int) crect.width - ITEM_PADDING;
+ item.rect.height = (int) crect.height;
+ } else {
+ item.rect.width = (int) crect.width;
+ item.rect.height = (int) crect.height - ITEM_PADDING;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/baobab-window.vala b/src/baobab-window.vala
index bd42a18..6645e70 100644
--- a/src/baobab-window.vala
+++ b/src/baobab-window.vala
@@ -476,15 +476,15 @@ namespace Baobab {
if (busy) {
cursor = busy_cursor;
disable_drop ();
- rings_chart.freeze_updates ();
- treemap_chart.freeze_updates ();
+ //rings_chart.freeze_updates ();
+ //treemap_chart.freeze_updates ();
(lookup_action ("active-chart") as SimpleAction).set_enabled (false);
chart_stack.visible_child = spinner;
spinner.start ();
} else {
enable_drop ();
- rings_chart.thaw_updates ();
- treemap_chart.thaw_updates ();
+ //rings_chart.thaw_updates ();
+ //treemap_chart.thaw_updates ();
(lookup_action ("active-chart") as SimpleAction).set_enabled (true);
spinner.stop ();
lookup_action ("active-chart").change_state (ui_settings.get_value ("active-chart"));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]