/* 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 LedProgramDialog : Gtk.Dialog {
private const string MCE_SERVICE = "com.nokia.mce";
private const string MCE_REQUEST_IF = "com.nokia.mce.request";
private const string MCE_REQUEST_PATH = "/com/nokia/mce/request";
private enum ResponseType {
TEST = 1,
COPY = 2
}
LedPatternView lpv;
LedPatternRX51 pattern;
LedColorButton led_color1;
LedColorButton led_color2;
Gtk.Widget list1;
Gtk.Widget list2;
Gtk.ToggleButton test_button;
DBus.Connection bus;
dynamic DBus.Object mce;
public LedProgramDialog (LedPatternRX51 _pattern) {
pattern = _pattern;
set_title (_("LED pattern editor - ") +
(pattern.name.has_prefix ("Pattern") ?
pattern.name.offset (7) : pattern.name) + _(" pattern"));
var content = (Gtk.VBox) get_content_area ();
content.set_size_request (-1, 5*70);
lpv = new LedPatternView (pattern.copy ());
lpv.set_size_request (-1, 70);
content.pack_start (lpv, false, false, 0);
var hbox = new Gtk.HBox (true, 0);
list1 = led_command_list (1);
hbox.pack_start (list1, true, true, 0);
list2 = led_command_list (2);
hbox.pack_start (list2, true, true, 0);
content.pack_start (hbox, true, true, 0);
content.show_all ();
list2.hide ();
hbox = new Gtk.HBox (true, 0);
led_color1 = new LedColorButton.with_color (lpv.pattern.color1);
led_color1.clicked.connect (on_color1_clicked);
hbox.pack_start (led_color1, true, true, 0);
led_color2 = new LedColorButton.with_color (lpv.pattern.color2);
led_color2.clicked.connect (on_color2_clicked);
hbox.pack_start (led_color2, true, true, 0);
add_action_widget (hbox, 2);
action_area.set_child_secondary (hbox, true);
hbox = new Gtk.HBox (true, 0);
var radio = (Gtk.RadioButton) Hildon.gtk_radio_button_new (Hildon.SizeType.FINGER_HEIGHT, null);
radio.set_mode (false);
radio.set_label ("1");
radio.set_active (true);
radio.toggled.connect (on_engine1_toggled);
hbox.pack_start (radio, true, true, 0);
radio = (Gtk.RadioButton) Hildon.gtk_radio_button_new_from_widget (Hildon.SizeType.FINGER_HEIGHT, radio);
radio.set_mode (false);
radio.set_label ("2");
radio.toggled.connect (on_engine2_toggled);
hbox.pack_start (radio, true, true, 0);
add_action_widget (hbox, 2);
action_area.set_child_secondary (hbox, true);
test_button = (Gtk.ToggleButton) Hildon.gtk_toggle_button_new (Hildon.SizeType.FINGER_HEIGHT);
test_button.set_label (_("Test"));
add_action_widget (test_button, ResponseType.TEST);
add_button (_("Copy"), ResponseType.COPY);
add_button (_("Done"), Gtk.ResponseType.ACCEPT);
action_area.show_all ();
test_button.toggled.connect (on_test_toggled);
key_press_event.connect (on_key_pressed);
response.connect (on_response);
bus = DBus.Bus.get (DBus.BusType.SYSTEM);
mce = bus.get_object (MCE_SERVICE, MCE_REQUEST_PATH, MCE_REQUEST_IF);
}
private bool on_key_pressed (Gdk.EventKey event) {
if (Gdk.ModifierType.CONTROL_MASK in event.state) {
string key = Gdk.keyval_name (event.keyval);
if (key == "c")
copy ();
else if (key == "v")
paste ();
}
return true;
}
private Gtk.Widget led_command_list (int engine) {
var pannable = new Hildon.PannableArea ();
var vbox = new Gtk.VBox (false, 0);
var label = new Gtk.Label (_("Engine %d:").printf (engine));
label.set_alignment (0, 0.5f);
vbox.pack_start (label, false, false, 0);
unowned List list = (engine == 1) ?
lpv.pattern.engine1 : lpv.pattern.engine2;
foreach (LedCommandRX51 command in list) {
if (command.type == CommandType.RESET_MUX)
continue;
var command_widget = new LedCommandWidget (lpv.pattern, list,
command);
vbox.pack_start (command_widget, false, false, 0);
}
var button = new Gtk.Button.with_label (_("New command"));
Hildon.gtk_widget_set_theme_size (button, Hildon.SizeType.FINGER_HEIGHT);
button.clicked.connect (on_new_command_clicked);
vbox.pack_end (button, false, false, 0);
pannable.add_with_viewport (vbox);
return pannable;
}
void on_response (int response) {
if (response == ResponseType.COPY) {
copy ();
return;
} else if (response == Gtk.ResponseType.ACCEPT) {
if (pattern.dump () != lpv.pattern.dump ()) {
pattern.replace_with (lpv.pattern);
}
test_button.set_active (false);
} else if (response == Gtk.ResponseType.CANCEL) {
test_button.set_active (false);
}
}
void copy () {
var clipboard = Gtk.Clipboard.@get (Gdk.SELECTION_CLIPBOARD);
clipboard.set_text (lpv.pattern.dump (), -1);
clipboard.store ();
Hildon.Banner.show_information (null, null, _("Copied"));
}
void paste () {
var clipboard = Gtk.Clipboard.@get (Gdk.SELECTION_CLIPBOARD);
clipboard.request_text (on_text_received);
}
void on_text_received (Gtk.Clipboard clipboard, string text) {
var clip_pattern = new LedPatternRX51 ();
try {
clip_pattern.parse (text);
lpv.pattern.replace_with (clip_pattern);
} catch (LedPatternError e) {
Hildon.Banner.show_information (null, null, _("Not a valid pattern"));
}
}
void on_test_toggled (Gtk.ToggleButton source) {
if (source.get_active ()) {
try {
mce.req_led_pattern_activate ("PatternError");
} catch (DBus.Error e) {
Hildon.Banner.show_information (null, null, e.message);
}
Timeout.add (200, delayed_spawn);
} else {
try {
mce.req_led_pattern_deactivate ("PatternError");
} catch (DBus.Error e) {
Hildon.Banner.show_information (null, null, e.message);
}
}
}
bool delayed_spawn () {
try {
int exit_status;
string error;
var command = "sudo /usr/bin/led-pattern-helper test \"" +
lpv.pattern.dump () + "\"";
Process.spawn_command_line_sync (command, null, out error, out exit_status);
if (exit_status != 0) {
var information = "Exit status: %d\n%s".printf (exit_status, error);
Hildon.Banner.show_information (null, null, information);
}
} catch (SpawnError e) {
Hildon.Banner.show_information (null, null, e.message);
}
return false;
}
void on_color1_clicked (Gtk.Button button) {
var dialog = new LedColorDialog ();
int response = dialog.run ();
if (response > 0) {
LedColor color = (LedColor) response;
led_color1.set_color (color);
lpv.pattern.color1 = color;
color = led_color2.get_color () & ~response;
led_color2.set_color (color);
lpv.pattern.color2 = color;
lpv.pattern.changed ();
}
dialog.destroy ();
}
void on_color2_clicked (Gtk.Button button) {
var dialog = new LedColorDialog ();
int response = dialog.run ();
if (response > 0) {
LedColor color = (LedColor) response;
led_color2.set_color (color);
lpv.pattern.color2 = color;
color = led_color1.get_color () & ~response;
led_color1.set_color (color);
lpv.pattern.color1 = color;
lpv.pattern.changed ();
}
dialog.destroy ();
}
void on_engine1_toggled (Gtk.ToggleButton source) {
if (source.get_active ())
list1.show ();
else
list1.hide ();
}
void on_engine2_toggled (Gtk.ToggleButton source) {
if (source.get_active ())
list2.show ();
else
list2.hide ();
}
void on_new_command_clicked (Gtk.Button button) {
var widget = button.parent.parent.parent;
unowned List engine;
if (widget == list1) {
engine = lpv.pattern.engine1;
} else if (widget == list2) {
engine = lpv.pattern.engine2;
} else {
return;
}
var dialog = new Hildon.PickerDialog (this);
dialog.set_title (_("New command"));
var touch_selector = new Hildon.TouchSelector.text ();
touch_selector.append_text (_("Set PWM"));
touch_selector.append_text (_("Ramp"));
touch_selector.append_text (_("Wait"));
touch_selector.append_text (_("Trigger"));
touch_selector.append_text (_("Go To Start"));
touch_selector.append_text (_("End"));
dialog.set_selector (touch_selector);
int response = dialog.run ();
if (response == Gtk.ResponseType.OK) {
var command = new LedCommandRX51 ();
LedCommandRX51 last_command = engine.last ().data;
engine.append (command);
command.changed.connect (lpv.pattern.on_changed);
switch (touch_selector.get_active (0)) {
case 0:
command.set_pwm (127);
break;
case 1:
if (last_command.type == CommandType.RAMP_WAIT) {
command.ramp_wait (last_command.step_time,
-last_command.steps);
} else if (last_command.level > 0) {
command.ramp_wait (125.0 / last_command.level,
-last_command.level);
} else {
command.ramp_wait (0.49, 255);
}
break;
case 2:
command.ramp_wait (100.0, 0);
break;
case 3:
command.type = CommandType.TRIGGER;
command.code = 0xe000;
command.changed ();
break;
case 4:
command.go_to_start ();
break;
case 5:
command.end (false);
break;
}
var vbox = (Gtk.VBox) button.parent;
var command_widget = new LedCommandWidget (lpv.pattern, engine,
command);
vbox.pack_start (command_widget, false, false, 0);
command_widget.show_all ();
}
dialog.destroy ();
}
}