Improve error handling and reporting in the LED pattern parser
[led-pattern-ed] / src / led-program-dialog.vala
index 2fec429..004d0ea 100644 (file)
@@ -20,6 +20,11 @@ class LedProgramDialog : Gtk.Dialog {
        LedPatternView lpv;
        LedPatternRX51 pattern;
 
+       LedColorButton led_color1;
+       LedColorButton led_color2;
+       Gtk.Widget list1;
+       Gtk.Widget list2;
+
        public LedProgramDialog (LedPatternRX51 _pattern) {
                pattern = _pattern;
                set_title ("LED pattern editor - " +
@@ -33,38 +38,126 @@ class LedProgramDialog : Gtk.Dialog {
                lpv.set_size_request (-1, 70);
                content.pack_start (lpv, false, false, 0);
 
-               var pannable = new Hildon.PannableArea ();
-               var vbox = new Gtk.VBox (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);
 
-               foreach (LedCommand command in lpv.pattern.engine1) {
-                       var command_widget = new LedCommandWidget (command);
+               content.show_all ();
+               list2.hide ();
 
-                       vbox.pack_start (command_widget, false, false, 0);
-               }
+               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);
 
-               pannable.add_with_viewport (vbox);
-               content.pack_start (pannable, true, true, 0);
+               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);
 
-               content.show_all ();
+               action_area.show_all ();
 
+               add_button ("Copy", 2);
                add_button ("Test", 1);
                add_button ("Done", Gtk.ResponseType.ACCEPT);
 
+               key_press_event.connect (on_key_pressed);
                response.connect (on_response);
        }
 
+       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<LedCommandRX51> 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 == 1) {
                        Timeout.add (200, delayed_spawn);
-                       return;
-               }
-               if (response == Gtk.ResponseType.ACCEPT) {
+               } else if (response == 2) {
+                       copy ();
+               } else if (response == Gtk.ResponseType.ACCEPT) {
                        if (pattern.dump () != lpv.pattern.dump ()) {
                                pattern.replace_with (lpv.pattern);
                        }
                }
        }
 
+       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");
+               }
+       }
+
        bool delayed_spawn () {
                try {
                        int exit_status;
@@ -82,4 +175,118 @@ class LedProgramDialog : Gtk.Dialog {
 
                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<LedCommandRX51> 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 ();
+       }
 }