summaryrefslogtreecommitdiff
path: root/src/renderers/centerRenderer.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderers/centerRenderer.vala')
-rw-r--r--src/renderers/centerRenderer.vala146
1 files changed, 146 insertions, 0 deletions
diff --git a/src/renderers/centerRenderer.vala b/src/renderers/centerRenderer.vala
new file mode 100644
index 0000000..c30e9ce
--- /dev/null
+++ b/src/renderers/centerRenderer.vala
@@ -0,0 +1,146 @@
+/*
+Copyright (c) 2011 by Simon Schneegans
+
+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/>.
+*/
+
+using GLib.Math;
+
+namespace GnomePie {
+
+// Renders the center of a Pie.
+
+public class CenterRenderer : GLib.Object {
+
+ private unowned PieRenderer parent;
+ private unowned Image? caption;
+ private Color color;
+
+ private AnimatedValue activity;
+ private AnimatedValue alpha;
+
+ public CenterRenderer(PieRenderer parent) {
+ this.parent = parent;
+ this.activity = new AnimatedValue.linear(0.0, 0.0, Config.global.theme.transition_time);
+ this.alpha = new AnimatedValue.linear(0.0, 1.0, Config.global.theme.fade_in_time);
+ this.color = new Color();
+ this.caption = null;
+ }
+
+ public void fade_out() {
+ this.activity.reset_target(0.0, Config.global.theme.fade_out_time);
+ this.alpha.reset_target(0.0, Config.global.theme.fade_out_time);
+ }
+
+ public void set_active_slice(SliceRenderer? active_slice) {
+ if (active_slice == null) {
+ this.activity.reset_target(0.0, Config.global.theme.transition_time);
+ } else {
+ this.activity.reset_target(1.0, Config.global.theme.transition_time);
+ this.caption = active_slice.caption;
+ this.color = active_slice.color;
+ }
+ }
+
+ public void draw(double frame_time, Cairo.Context ctx, double angle, double distance) {
+
+ var layers = Config.global.theme.center_layers;
+
+ this.activity.update(frame_time);
+ this.alpha.update(frame_time);
+
+ foreach (var layer in layers) {
+
+ ctx.save();
+
+ double active_speed = (layer.active_rotation_mode == CenterLayer.RotationMode.TO_MOUSE) ?
+ 0.0 : layer.active_rotation_speed;
+ double inactive_speed = (layer.inactive_rotation_mode == CenterLayer.RotationMode.TO_MOUSE) ?
+ 0.0 : layer.inactive_rotation_speed;
+ double max_scale = layer.active_scale*this.activity.val
+ + layer.inactive_scale*(1.0-this.activity.val);
+ double max_alpha = layer.active_alpha*this.activity.val
+ + layer.inactive_alpha*(1.0-this.activity.val);
+ double colorize = ((layer.active_colorize == true) ? this.activity.val : 0.0)
+ + ((layer.inactive_colorize == true) ? 1.0 - this.activity.val : 0.0);
+ double max_rotation_speed = active_speed*this.activity.val
+ + inactive_speed*(1.0-this.activity.val);
+ CenterLayer.RotationMode rotation_mode = ((this.activity.val > 0.5) ?
+ layer.active_rotation_mode : layer.inactive_rotation_mode);
+
+ if (rotation_mode == CenterLayer.RotationMode.TO_MOUSE) {
+ double diff = angle-layer.rotation;
+ max_rotation_speed = layer.active_rotation_speed*this.activity.val
+ + layer.inactive_rotation_speed*(1.0-this.activity.val);
+ double smoothy = fabs(diff) < 0.9 ? fabs(diff) + 0.1 : 1.0;
+ double step = max_rotation_speed*frame_time*smoothy;
+
+ if (fabs(diff) <= step || fabs(diff) >= 2.0*PI - step)
+ layer.rotation = angle;
+ else {
+ if ((diff > 0 && diff < PI) || diff < -PI) layer.rotation += step;
+ else layer.rotation -= step;
+ }
+
+ } else if (rotation_mode == CenterLayer.RotationMode.TO_ACTIVE) {
+ max_rotation_speed *= this.activity.val;
+
+ double slice_angle = parent.slice_count() > 0 ? 2*PI/parent.slice_count() : 0;
+ double direction = (int)((angle+0.5*slice_angle) / (slice_angle))*slice_angle;
+ double diff = direction-layer.rotation;
+ double step = max_rotation_speed*frame_time;
+
+ if (fabs(diff) <= step || fabs(diff) >= 2.0*PI - step)
+ layer.rotation = direction;
+ else {
+ if ((diff > 0 && diff < PI) || diff < -PI) layer.rotation += step;
+ else layer.rotation -= step;
+ }
+
+ } else layer.rotation += max_rotation_speed*frame_time;
+
+ layer.rotation = fmod(layer.rotation+2*PI, 2*PI);
+
+ if (colorize > 0.0) ctx.push_group();
+
+ ctx.rotate(layer.rotation);
+ ctx.scale(max_scale, max_scale);
+ layer.image.paint_on(ctx, this.alpha.val*max_alpha);
+
+ if (colorize > 0.0) {
+ ctx.set_operator(Cairo.Operator.ATOP);
+ ctx.set_source_rgb(this.color.r, this.color.g, this.color.b);
+ ctx.paint_with_alpha(colorize);
+
+ ctx.set_operator(Cairo.Operator.OVER);
+ ctx.pop_group_to_source();
+ ctx.paint();
+ }
+
+ ctx.restore();
+ }
+
+ // draw caption
+ if (Config.global.theme.caption && caption != null && this.activity.val > 0) {
+ ctx.save();
+ ctx.identity_matrix();
+ int pos = this.parent.get_size()/2;
+ ctx.translate(pos, (int)(Config.global.theme.caption_position) + pos);
+ caption.paint_on(ctx, this.activity.val*this.alpha.val);
+ ctx.restore();
+ }
+ }
+}
+
+}