/* 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 LedCommandWidget : Gtk.HBox {
private const double CYCLE_TIME_MS = 1000.0 / 32768.0;
LedPatternRX51 pattern;
unowned List engine;
LedCommandRX51 command;
public LedCommandWidget (LedPatternRX51 _pattern, List _engine,
LedCommandRX51 _command) {
homogeneous = true;
pattern = _pattern;
engine = _engine;
command = _command;
var button = new Hildon.Button (Hildon.SizeType.FINGER_HEIGHT,
Hildon.ButtonArrangement.VERTICAL);
button.set_style (Hildon.ButtonStyle.PICKER);
button.set_alignment (0, 0.5f, 0, 0.5f);
switch (command.type) {
case CommandType.UNKNOWN:
button.set_title ("???");
button.set_value ("0x%04x".printf (command.code));
button.set_sensitive (false);
break;
case CommandType.RAMP_WAIT:
button.set_title ((command.steps != 0) ? "Ramp" : "Wait");
button.set_value ((command.steps != 0) ?
"%+d steps, %.2f ms each".printf (command.steps,
command.step_time) :
"%.2f ms".printf (command.duration));
button.clicked.connect (on_ramp_wait_clicked);
break;
case CommandType.SET_PWM:
button.set_title ("Set PWM");
button.set_value ("Level = %d".printf (command.level));
button.clicked.connect (on_set_pwm_clicked);
break;
case CommandType.RESET_MUX:
button.set_title ("Reset Mux");
break;
case CommandType.GO_TO_START:
button.set_title ("Go To Start");
button.set_value ("");
button.clicked.connect (on_end_or_go_to_start_clicked);
break;
case CommandType.BRANCH:
button.set_title ("Branch");
button.set_value ("0x%04x".printf (command.code));
button.set_sensitive (false);
break;
case CommandType.END:
button.set_title ("End");
button.set_value ((command.steps == -255) ? "Reset" : "Hold");
button.clicked.connect (on_end_or_go_to_start_clicked);
break;
case CommandType.TRIGGER:
button.set_title ("Trigger");
string text = "";
if (0x0100 in command.code)
text += "wait 2 ";
if (0x0004 in command.code)
text += "set 2 ";
if (0x0080 in command.code)
text += "wait 1 ";
if (0x0002 in command.code)
text += "set 1 ";
if ((command.code & ~0xe186) != 0) {
text = "Unsupported: 0x%04x".printf (command.code);
button.set_sensitive (false);
}
button.set_value (text);
button.clicked.connect (on_trigger_clicked);
break;
}
pack_start (button, true, true, 0);
}
private void on_ramp_wait_clicked (Gtk.Button source) {
double old_step_time = command.step_time;
int old_steps = command.steps;
var dialog = new Gtk.Dialog ();
dialog.set_title ("Ramp / Wait");
var content = (Gtk.VBox) dialog.get_content_area ();
var lpv = new LedPatternView (pattern);
lpv.set_size_request (-1, 70);
content.pack_start (lpv, true, true, 0);
var scale1 = new Gtk.HScale.with_range (1, 62, 1);
scale1.set_increments (1, 1);
var v = (command.step_time / 16 / CYCLE_TIME_MS);
if (v > 62)
v = v / 32 + 31;
scale1.set_value (v);
scale1.format_value.connect ((v) => {
if (v < 32)
return "%.2f ms".printf (v * 16 * CYCLE_TIME_MS);
else
return "%.1f ms".printf ((v - 31) * 512 * CYCLE_TIME_MS);
});
scale1.value_changed.connect ((s) => {
int val = (int) s.get_value ();
if (val < 32)
command.ramp_wait (val * 16 * CYCLE_TIME_MS, command.steps);
else
command.ramp_wait ((val - 31) * 512 * CYCLE_TIME_MS, command.steps);
});
content.pack_start (scale1, true, true, 0);
var hbox = new Gtk.HBox (false, 0);
var hbox2 = new Gtk.HBox (true, 0);
var radio_inc = (Gtk.RadioButton) Hildon.gtk_radio_button_new (Hildon.SizeType.FINGER_HEIGHT, null);
radio_inc.set_mode (false);
radio_inc.set_label ("+");
hbox2.pack_start (radio_inc, false, false, 0);
var radio_dec = (Gtk.RadioButton) Hildon.gtk_radio_button_new_from_widget (Hildon.SizeType.FINGER_HEIGHT, radio_inc);
radio_dec.set_mode (false);
radio_dec.set_label ("-");
bool sign = command.steps < 0;
radio_dec.set_active (sign);
radio_dec.toggled.connect ((s) => {
sign = s.get_active ();
if (sign != (command.steps < 0))
command.ramp_wait (command.step_time, -command.steps);
});
hbox2.pack_start (radio_dec, false, false, 0);
hbox.pack_start (hbox2, false, false, 0);
var scale2 = new Gtk.HScale.with_range (0, 255, 1);
scale2.set_increments (1, 1);
scale2.set_value ((command.steps < 0) ? -command.steps : command.steps);
scale2.set_value_pos (Gtk.PositionType.RIGHT);
scale2.format_value.connect ((v) => {
return "%+d".printf (sign ? -(int) v : (int) v);
});
scale2.value_changed.connect ((s) => {
if (sign)
command.ramp_wait (command.step_time, -(int) scale2.get_value ());
else
command.ramp_wait (command.step_time, (int) scale2.get_value ());
});
hbox.pack_start (scale2, true, true, 0);
content.pack_start (hbox, false, false, 0);
content.show_all ();
dialog.add_button ("Delete", 1);
dialog.add_button ("Done", Gtk.ResponseType.OK);
int response = dialog.run ();
if (response == Gtk.ResponseType.OK) {
var button = source as Hildon.Button;
button.set_title ((command.steps != 0) ? "Ramp" : "Wait");
button.set_value ((command.steps != 0) ?
"%+d steps, %.2f ms each".printf (command.steps,
command.step_time) :
"%.2f ms".printf (command.duration));
} else if (response == 1) {
engine.remove (command);
engine.first ().data.changed ();
this.destroy ();
} else {
command.ramp_wait (old_step_time, old_steps);
}
dialog.destroy ();
}
private void on_set_pwm_clicked (Gtk.Button source) {
int old_level = command.level;
var dialog = new Gtk.Dialog ();
dialog.set_title ("Set PWM");
var content = (Gtk.VBox) dialog.get_content_area ();
var lpv = new LedPatternView (pattern);
lpv.set_size_request (-1, 70);
content.pack_start (lpv, true, true, 0);
var scale = new Gtk.HScale.with_range (0, 255, 1);
scale.set_increments (1, 1);
scale.set_value (command.level);
scale.value_changed.connect ((s) => {
command.set_pwm ((int) s.get_value ());
});
content.pack_start (scale, true, true, 0);
content.show_all ();
dialog.add_button ("Delete", 1);
dialog.add_button ("Done", Gtk.ResponseType.OK);
int response = dialog.run ();
if (response == Gtk.ResponseType.OK) {
command.set_pwm ((int) scale.get_value ());
var button = source as Hildon.Button;
button.set_value ("Level = %d".printf (command.level));
} else if (response == 1) {
engine.remove (command);
engine.first ().data.changed ();
this.destroy ();
} else {
command.set_pwm (old_level);
}
dialog.destroy ();
}
private void on_end_or_go_to_start_clicked (Gtk.Button source) {
CommandType old_type = command.type;
int old_steps = command.steps;
uint16 old_code = command.code;
var dialog = new Gtk.Dialog ();
if (command.type == CommandType.END)
dialog.set_title ("End");
else
dialog.set_title ("Go To Start");
var content = (Gtk.VBox) dialog.get_content_area ();
var lpv = new LedPatternView (pattern);
lpv.set_size_request (-1, 70);
content.pack_start (lpv, true, true, 0);
var hbox = new Gtk.HBox (true, 0);
var radio_end = (Gtk.RadioButton) Hildon.gtk_radio_button_new (Hildon.SizeType.FINGER_HEIGHT, null);
radio_end.set_mode (false);
radio_end.set_label ("End");
hbox.pack_start (radio_end, true, true, 0);
var radio_go_to_start = (Gtk.RadioButton) Hildon.gtk_radio_button_new_from_widget (Hildon.SizeType.FINGER_HEIGHT, radio_end);
radio_go_to_start.set_mode (false);
radio_go_to_start.set_label ("Go To Start");
hbox.pack_start (radio_go_to_start, true, true, 0);
content.pack_start (hbox, true, true, 0);
hbox = new Gtk.HBox (true, 0);
var radio_hold = (Gtk.RadioButton) Hildon.gtk_radio_button_new (Hildon.SizeType.FINGER_HEIGHT, null);
radio_hold.set_mode (false);
radio_hold.set_label ("Hold");
hbox.pack_start (radio_hold, true, true, 0);
var radio_reset = (Gtk.RadioButton) Hildon.gtk_radio_button_new_from_widget (Hildon.SizeType.FINGER_HEIGHT, radio_hold);
radio_reset.set_mode (false);
radio_reset.set_label ("Reset");
hbox.pack_start (radio_reset, true, true, 0);
content.pack_start (hbox, true, true, 0);
if (command.type == CommandType.END)
radio_end.set_active (true);
else
radio_go_to_start.set_active (true);
radio_hold.set_sensitive (command.type == CommandType.END);
radio_reset.set_sensitive (command.type == CommandType.END);
radio_reset.set_active (command.steps == -255);
radio_end.toggled.connect ((s) => {
if (s.get_active ()) {
command.end (radio_reset.get_active ());
radio_hold.set_sensitive (true);
radio_reset.set_sensitive (true);
dialog.set_title ("End");
} else {
command.go_to_start ();
radio_hold.set_sensitive (false);
radio_reset.set_sensitive (false);
dialog.set_title ("Go To Start");
}
command.changed ();
});
radio_reset.toggled.connect ((s) => {
if (command.type == CommandType.END) {
command.end (s.get_active ());
}
});
content.show_all ();
dialog.add_button ("Delete", 1);
dialog.add_button ("Done", Gtk.ResponseType.OK);
int response = dialog.run ();
if (response == Gtk.ResponseType.OK) {
var button = source as Hildon.Button;
button.set_value ((command.type == CommandType.END) ?
"End" : "Go To Start");
button.set_value ((command.type == CommandType.END) ?
((command.steps == -255) ? "Reset" : "Hold") : "");
} else if (response == 1) {
engine.remove (command);
engine.first ().data.changed ();
this.destroy ();
} else {
command.type = old_type;
command.steps = old_steps;
command.code = old_code;
command.changed ();
}
dialog.destroy ();
}
private void on_trigger_clicked (Gtk.Button source) {
uint16 old_code = command.code;
var dialog = new Gtk.Dialog ();
dialog.set_title ("Trigger");
var content = (Gtk.VBox) dialog.get_content_area ();
var lpv = new LedPatternView (pattern);
lpv.set_size_request (-1, 70);
content.pack_start (lpv, true, true, 0);
var check = new Hildon.CheckButton (Hildon.SizeType.FINGER_HEIGHT);
check.set_label ("Set trigger");
if ((command.code & 0x0006) != 0)
check.set_active (true);
check.toggled.connect ((s) => {
int bit = (engine == pattern.engine1) ? 0x0004 : 0x0002;
if (s.get_active ())
command.code |= bit;
else
command.code &= ~bit;
command.changed ();
});
content.pack_start (check, true, true, 0);
check = new Hildon.CheckButton (Hildon.SizeType.FINGER_HEIGHT);
check.set_label ("Wait for trigger");
if ((command.code & 0x0180) != 0)
check.set_active (true);
check.toggled.connect ((s) => {
int bit = (engine == pattern.engine1) ? 0x0100 : 0x0080;
if (s.get_active ())
command.code |= bit;
else
command.code &= ~bit;
command.changed ();
});
content.pack_start (check, true, true, 0);
content.show_all ();
dialog.add_button ("Delete", 1);
dialog.add_button ("Done", Gtk.ResponseType.OK);
int response = dialog.run ();
if (response == Gtk.ResponseType.OK) {
var button = source as Hildon.Button;
string text = "";
if (0x0100 in command.code)
text += "wait 2 ";
if (0x0004 in command.code)
text += "set 2 ";
if (0x0080 in command.code)
text += "wait 1 ";
if (0x0002 in command.code)
text += "set 1 ";
if ((command.code & ~0xe186) != 0) {
text = "Unsupported: 0x%04x".printf (command.code);
button.set_sensitive (false);
}
button.set_value (text);
} else if (response == 1) {
engine.remove (command);
engine.first ().data.changed ();
this.destroy ();
} else {
command.code = old_code;
command.changed ();
}
dialog.destroy ();
}
}