From: Philipp Zabel Date: Wed, 24 Feb 2010 16:59:37 +0000 (+0100) Subject: Add LED pattern view X-Git-Tag: v0.0.1~10 X-Git-Url: http://vcs.maemo.org/git/?a=commitdiff_plain;ds=sidebyside;h=6ce0a94c212b0fff2cb496c02e0b3964d4d4a060;p=led-pattern-ed Add LED pattern view --- diff --git a/Makefile b/Makefile index d817137..a7d73ad 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,7 @@ led_pattern_editor_VALASOURCES = \ src/led-pattern.vala \ src/led-pattern-rx51.vala \ src/led-pattern-dialog.vala \ + src/led-pattern-view.vala \ src/mce-ini-parse.vala led_pattern_editor_VALAFLAGS = --pkg hildon-1 --pkg libosso diff --git a/src/led-pattern-view.vala b/src/led-pattern-view.vala new file mode 100644 index 0000000..a4f7444 --- /dev/null +++ b/src/led-pattern-view.vala @@ -0,0 +1,212 @@ +/* This file is part of LED Pattern Editor. + * + * Copyright (C) 2010 Philipp Zabel + * + * LED Pattern Editor 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. + * + * LED Pattern Editor 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 LED Pattern Editor. If not, see . + */ + +class LedPatternView : Gtk.DrawingArea { + public LedPatternRX51 pattern; + public double duration; + + public LedPatternView (LedPatternRX51? _pattern = null) { + pattern = _pattern; + if (pattern != null) + pattern.changed.connect (update); + update_duration (); + } + + public void update_duration () { + duration = 1.0; + if (pattern != null) { + while (pattern.duration > 1000 * duration) { + duration += 1.0; + } + } + } + + public override bool expose_event (Gdk.EventExpose event) { + + update_duration (); + + var ctx = Gdk.cairo_create (window); + int height = allocation.height; + int width = allocation.width; + double pps = width / duration; // pixel per second + + ctx.rectangle (event.area.x, event.area.y, event.area.width, event.area.height); + ctx.clip (); + + ctx.set_source_rgb (0, 0, 0); + ctx.set_line_width (1.0); + + ctx.set_line_join (Cairo.LineJoin.ROUND); + + ctx.new_path (); + ctx.move_to (0, 0); + ctx.line_to (width, 0); + ctx.line_to (width, height); + ctx.line_to (0, height); + ctx.close_path (); + ctx.fill (); + + ctx.set_source_rgb (0.33, 0.33, 0.33); + ctx.new_path (); + + // 0%, 50%, 100% + ctx.move_to (0.5, 0.5); + ctx.line_to (width - 0.5, 0.5); + + ctx.move_to (0.5, height / 2 - 0.5); + ctx.line_to (width - 0.5, height / 2 - 0.5); + + ctx.move_to (0.5, height - 0.5); + ctx.line_to (width - 0.5, height - 0.5); + + // 0s, 1s, 2s, 3s, 4s + for (double time = 0; time <= duration; time += 1.0) { + ctx.move_to (time * pps + 0.5, 0.5); + ctx.line_to (time * pps + 0.5, 139.5); + } + ctx.stroke (); + + if (pattern != null) { + ctx.new_path (); + + if (pattern.led_map == "r") { + ctx.set_source_rgb (1, 0, 0); + } else if (pattern.led_map == "g") { + ctx.set_source_rgb (0, 1, 0); + } else if (pattern.led_map == "b") { + ctx.set_source_rgb (0, 0, 1); + } else if (pattern.led_map == "rg") { + ctx.set_source_rgb (1, 1, 0); + } else if (pattern.led_map == "rb") { + ctx.set_source_rgb (1, 0, 1); + } else if (pattern.led_map == "gb") { + ctx.set_source_rgb (0, 1, 1); + } else if (pattern.led_map == "rgb") { + ctx.set_source_rgb (1, 1, 1); + } else { + ctx.set_source_rgb (0.75, 0.75, 0.75); + } + ctx.set_line_width (3.0); + + double x = 0, y = 0; + foreach (LedCommand command in pattern.engine1) { + x = command.time * pps/1000.0; + y = (255 - command.level) * (height - 1)/255.0; + switch (command.type) { + case CommandType.RAMP_WAIT: + x += command.duration * pps/1000.0; + y -= command.steps * (height - 1)/255.0; + if (y < 0) + y = 0; + if (y > (height - 1)) + y = height - 1; + ctx.line_to (x, y); + break; + default: + ctx.line_to (x, y); + break; + } + } + ctx.stroke (); + + if (pattern.led_map == "r") { + ctx.set_source_rgb (0.75, 0, 0); + } else if (pattern.led_map == "g") { + ctx.set_source_rgb (0, 0.75, 0); + } else if (pattern.led_map == "b") { + ctx.set_source_rgb (0, 0, 0.75); + } else if (pattern.led_map == "rg") { + ctx.set_source_rgb (0.75, 0.75, 0); + } else if (pattern.led_map == "rb") { + ctx.set_source_rgb (0.75, 0, 0.75); + } else if (pattern.led_map == "gb") { + ctx.set_source_rgb (0, 0.75, 0.75); + } else if (pattern.led_map == "rgb") { + ctx.set_source_rgb (0.75, 0.75, 0.75); + } else { + ctx.set_source_rgb (0.66, 0.66, 0.66); + } + ctx.set_line_width (1.0); + + CommandType type = CommandType.UNKNOWN; + foreach (LedCommandRX51 command in pattern.engine1) { + if (command.type == CommandType.STOP || + command.type == CommandType.REPEAT) { + type = command.type; + break; + } + } + + if (type == CommandType.STOP) { + ctx.new_path (); + + ctx.move_to (x, y); + ctx.line_to (width - 0.5, y); + + ctx.stroke (); + } + if (type == CommandType.REPEAT && pattern.duration > 0.0) { + ctx.new_path (); + + for (double offset = pattern.duration; (offset * pps/1000.0) <= width; offset += pattern.duration) { + ctx.move_to (x, y); + foreach (LedCommand command in pattern.engine1) { + x = (command.time + offset) * pps/1000.0; + y = (255 - command.level) * (height - 1)/255.0; + if (x >= width) + break; + switch (command.type) { + case CommandType.RAMP_WAIT: + x += command.duration * pps/1000.0; + y -= command.steps * (height - 1)/255.0; + if (y < 0) + y = 0; + if (y > (height - 1)) + y = height - 1; + ctx.line_to (x, y); + break; + default: + ctx.line_to (x, y); + break; + } + } + } + + ctx.stroke (); + } + if (type == CommandType.REPEAT && pattern.duration == 0.0) { + ctx.new_path (); + + + ctx.move_to (x, y); + ctx.line_to (width - 0.5, y); + + ctx.stroke (); + } + } + return true; + } + + public void update () { + unowned Gdk.Region region = window.get_clip_region (); + + // redraw the cairo canvas completely by exposing it + window.invalidate_region (region, true); + window.process_updates (true); + } +}