Several updates - added support for second pattern engine and adding commands
[led-pattern-ed] / src / led-command-widget.vala
index 36f18d7..3e33bea 100644 (file)
 class LedCommandWidget : Gtk.HBox {
        private const double CYCLE_TIME_MS = 1000.0 / 32768.0;
 
-       LedCommand command;
+       LedPatternRX51 pattern;
+       unowned List<LedCommandRX51> engine;
+       LedCommandRX51 command;
 
-       public LedCommandWidget (LedCommand _command) {
+       public LedCommandWidget (LedPatternRX51 _pattern, List<LedCommandRX51> _engine,
+                                LedCommandRX51 _command) {
                homogeneous = true;
+               pattern = _pattern;
+               engine = _engine;
                command = _command;
 
-               string text = "";
+               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:
-                       LedCommandRX51 cmd = command as LedCommandRX51;
-                       if (cmd != null)
-                               text = "??? (0x%04x)".printf (cmd.code);
-                       else
-                               text = "???";
+                       button.set_title ("???");
+                       button.set_value ("0x%04x".printf (command.code));
+                       button.set_sensitive (false);
                        break;
                case CommandType.RAMP_WAIT:
-                       text = "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:
-                       text = "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:
-                       text = "Reset Mux";
+                       button.set_title ("Reset Mux");
                        break;
                case CommandType.GO_TO_START:
-                       text = "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:
-                       text = "Branch";
+                       button.set_title ("Branch");
+                       button.set_value ("0x%04x".printf (command.code));
+                       button.set_sensitive (false);
                        break;
                case CommandType.END:
-                       text = "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:
-                       text = "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);
+       }
 
-               var label = new Gtk.Label (text);
-               label.set_alignment (0.0f, 0.5f);
-               pack_start (label, 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");
 
-               switch (command.type) {
-               case CommandType.RAMP_WAIT:
-                       var selector = new Hildon.TouchSelector.text ();
-                       for (int i = 1; i <= 31; i++)
-                               selector.append_text ("%.2f ms".printf (i * (16 * CYCLE_TIME_MS)));
-                       for (int i = 1; i <= 31; i++)
-                               selector.append_text ("%.1f ms".printf (i * (512 * CYCLE_TIME_MS)));
-                       var picker = new Hildon.PickerButton (Hildon.SizeType.FINGER_HEIGHT,
-                                                             Hildon.ButtonArrangement.VERTICAL);
-                       picker.set_title ("Step time");
-                       picker.set_selector (selector);
-                       int j;
-                       if (command.step_time <= 31*(16 * CYCLE_TIME_MS))
-                               j = (int) ((command.step_time + 0.001) / (16 * CYCLE_TIME_MS)) - 1;
+               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);
+               int v = (int) (command.step_time / 16 / CYCLE_TIME_MS);
+               if (v > 62)
+                       v /= 32;
+               scale1.set_value (v);
+               scale1.format_value.connect ((v) => {
+                       if (v < 32)
+                               return "%.2f ms".printf (v * 16 * CYCLE_TIME_MS);
                        else
-                               j = (int) ((command.step_time + 0.01) / (512 * CYCLE_TIME_MS)) + 30;
-                       picker.set_active (j);
-                       picker.value_changed.connect ((s) => {
-                               double step_time;
-                               int i = s.get_active ();
-                               if (i < 31)
-                                       step_time = (i + 1) * (16 * CYCLE_TIME_MS);
-                               else
-                                       step_time = (i - 30) * (512 * CYCLE_TIME_MS);
-                               command.ramp_wait (step_time, command.steps);
-                       });
-                       pack_start (picker, true, true, 0);
-
-                       selector = new Hildon.TouchSelector.text ();
-                       for (int i = -255; i < 256; i++)
-                               selector.append_text ("%+d".printf (i));
-                       picker = new Hildon.PickerButton (Hildon.SizeType.FINGER_HEIGHT,
-                                                         Hildon.ButtonArrangement.VERTICAL);
-                       picker.set_title ("Steps");
-                       picker.set_selector (selector);
-                       picker.set_active (command.steps + 255);
-                       picker.value_changed.connect ((s) => {
-                               int steps = s.get_active () - 255;
-                               command.ramp_wait (command.step_time, steps);
-                       });
-                       pack_start (picker, true, true, 0);
-                       break;
-               case CommandType.SET_PWM:
-                       label = new Gtk.Label ("");
-                       pack_start (label, true, true, 0);
-                       var selector = new Hildon.TouchSelector.text ();
-                       for (int i = 0; i < 256; i++)
-                               selector.append_text ("%d".printf (i));
-                       var picker = new Hildon.PickerButton (Hildon.SizeType.FINGER_HEIGHT,
-                                                             Hildon.ButtonArrangement.VERTICAL);
-                       picker.set_title ("Level");
-                       picker.set_selector (selector);
-                       picker.set_active (command.level);
-                       picker.value_changed.connect ((s) => {
-                               int level = s.get_active ();
-                               command.set_pwm (level);
-                       });
-                       pack_start (picker, true, true, 0);
-                       break;
-               case CommandType.END:
-                       var check = new Hildon.CheckButton (Hildon.SizeType.FINGER_HEIGHT);
-                       check.set_label ("Reset");
-                       check.set_active (command.steps == -255);
-                       check.toggled.connect ((s) => {
-                               command.steps = s.get_active () ? -255 : 0;
-                               command.changed ();
-                       });
-                       pack_start (check, true, true, 0);
-                       label = new Gtk.Label ("");
-                       pack_start (label, true, true, 0);
-                       break;
-               case CommandType.UNKNOWN:
-               case CommandType.RESET_MUX:
-               case CommandType.GO_TO_START:
-               case CommandType.BRANCH:
-               case CommandType.TRIGGER:
-                       label = new Gtk.Label ("");
-                       pack_start (label, true, true, 0);
-                       label = new Gtk.Label ("");
-                       pack_start (label, true, true, 0);
-                       break;
+                               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_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_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 ();
        }
 }