91840f302a4183c5028d605a6b6f2d7f4668f5ca
[led-pattern-ed] / src / led-program-dialog.vala
1 /* This file is part of LED Pattern Editor.
2  *
3  * Copyright (C) 2010 Philipp Zabel
4  *
5  * LED Pattern Editor is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * LED Pattern Editor is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with LED Pattern Editor. If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 class LedProgramDialog : Gtk.Dialog {
20         LedPatternView lpv;
21         LedPatternRX51 pattern;
22
23         LedColorButton led_color1;
24         LedColorButton led_color2;
25         Gtk.Widget list1;
26         Gtk.Widget list2;
27
28         public LedProgramDialog (LedPatternRX51 _pattern) {
29                 pattern = _pattern;
30                 set_title (_("LED pattern editor - ") +
31                            (pattern.name.has_prefix ("Pattern") ?
32                             pattern.name.offset (7) : pattern.name) + _(" pattern"));
33
34                 var content = (Gtk.VBox) get_content_area ();
35                 content.set_size_request (-1, 5*70);
36
37                 lpv = new LedPatternView (pattern.copy ());
38                 lpv.set_size_request (-1, 70);
39                 content.pack_start (lpv, false, false, 0);
40
41                 var hbox = new Gtk.HBox (true, 0);
42                 list1 = led_command_list (1);
43                 hbox.pack_start (list1, true, true, 0);
44                 list2 = led_command_list (2);
45                 hbox.pack_start (list2, true, true, 0);
46                 content.pack_start (hbox, true, true, 0);
47
48                 content.show_all ();
49                 list2.hide ();
50
51                 hbox = new Gtk.HBox (true, 0);
52                 led_color1 = new LedColorButton.with_color (lpv.pattern.color1);
53                 led_color1.clicked.connect (on_color1_clicked);
54                 hbox.pack_start (led_color1, true, true, 0);
55                 led_color2 = new LedColorButton.with_color (lpv.pattern.color2);
56                 led_color2.clicked.connect (on_color2_clicked);
57                 hbox.pack_start (led_color2, true, true, 0);
58                 add_action_widget (hbox, 2);
59                 action_area.set_child_secondary (hbox, true);
60
61                 hbox = new Gtk.HBox (true, 0);
62                 var radio = (Gtk.RadioButton) Hildon.gtk_radio_button_new (Hildon.SizeType.FINGER_HEIGHT, null);
63                 radio.set_mode (false);
64                 radio.set_label ("1");
65                 radio.set_active (true);
66                 radio.toggled.connect (on_engine1_toggled);
67                 hbox.pack_start (radio, true, true, 0);
68                 radio = (Gtk.RadioButton) Hildon.gtk_radio_button_new_from_widget (Hildon.SizeType.FINGER_HEIGHT, radio);
69                 radio.set_mode (false);
70                 radio.set_label ("2");
71                 radio.toggled.connect (on_engine2_toggled);
72                 hbox.pack_start (radio, true, true, 0);
73                 add_action_widget (hbox, 2);
74                 action_area.set_child_secondary (hbox, true);
75
76                 action_area.show_all ();
77
78                 add_button (_("Copy"), 2);
79                 add_button (_("Test"), 1);
80                 add_button (_("Done"), Gtk.ResponseType.ACCEPT);
81
82                 key_press_event.connect (on_key_pressed);
83                 response.connect (on_response);
84         }
85
86         private bool on_key_pressed (Gdk.EventKey event) {
87                 if (Gdk.ModifierType.CONTROL_MASK in event.state) {
88                         string key = Gdk.keyval_name (event.keyval);
89                         if (key == "c")
90                                 copy ();
91                         else if (key == "v")
92                                 paste ();
93                 }
94                 return true;
95         }
96
97         private Gtk.Widget led_command_list (int engine) {
98                 var pannable = new Hildon.PannableArea ();
99                 var vbox = new Gtk.VBox (false, 0);
100
101                 var label = new Gtk.Label (_("Engine %d:").printf (engine));
102                 label.set_alignment (0, 0.5f);
103                 vbox.pack_start (label, false, false, 0);
104
105                 unowned List<LedCommandRX51> list = (engine == 1) ?
106                                                     lpv.pattern.engine1 : lpv.pattern.engine2;
107                 foreach (LedCommandRX51 command in list) {
108                         if (command.type == CommandType.RESET_MUX)
109                                 continue;
110                         var command_widget = new LedCommandWidget (lpv.pattern, list,
111                                                                    command);
112
113                         vbox.pack_start (command_widget, false, false, 0);
114                 }
115
116                 var button = new Gtk.Button.with_label (_("New command"));
117                 Hildon.gtk_widget_set_theme_size (button, Hildon.SizeType.FINGER_HEIGHT);
118                 button.clicked.connect (on_new_command_clicked);
119                 vbox.pack_end (button, false, false, 0);
120
121                 pannable.add_with_viewport (vbox);
122                 return pannable;
123         }
124
125         void on_response (int response) {
126                 if (response == 1) {
127                         Timeout.add (200, delayed_spawn);
128                 } else if (response == 2) {
129                         copy ();
130                 } else if (response == Gtk.ResponseType.ACCEPT) {
131                         if (pattern.dump () != lpv.pattern.dump ()) {
132                                 pattern.replace_with (lpv.pattern);
133                         }
134                 }
135         }
136
137         void copy () {
138                 var clipboard = Gtk.Clipboard.@get (Gdk.SELECTION_CLIPBOARD);
139
140                 clipboard.set_text (lpv.pattern.dump (), -1);
141                 clipboard.store ();
142                 Hildon.Banner.show_information (null, null, _("Copied"));
143         }
144
145         void paste () {
146                 var clipboard = Gtk.Clipboard.@get (Gdk.SELECTION_CLIPBOARD);
147
148                 clipboard.request_text (on_text_received);
149         }
150
151         void on_text_received (Gtk.Clipboard clipboard, string text) {
152                 var clip_pattern = new LedPatternRX51 ();
153                 try {
154                         clip_pattern.parse (text);
155                         lpv.pattern.replace_with (clip_pattern);
156                 } catch (LedPatternError e) {
157                         Hildon.Banner.show_information (null, null, _("Not a valid pattern"));
158                 }
159         }
160
161         bool delayed_spawn () {
162                 try {
163                         int exit_status;
164                         string error;
165                         var command = "sudo /usr/bin/led-pattern-helper test \"" +
166                                       lpv.pattern.dump () + "\"";
167                         Process.spawn_command_line_sync (command, null, out error, out exit_status);
168                         if (exit_status != 0) {
169                                 var information = "Exit status: %d\n%s".printf (exit_status, error);
170                                 Hildon.Banner.show_information (null, null, information);
171                         }
172                 } catch (SpawnError e) {
173                         Hildon.Banner.show_information (null, null, e.message);
174                 }
175
176                 return false;
177         }
178
179         void on_color1_clicked (Gtk.Button button) {
180                 var dialog = new LedColorDialog ();
181                 int response = dialog.run ();
182                 if (response > 0) {
183                         LedColor color = (LedColor) response;
184                         led_color1.set_color (color);
185                         lpv.pattern.color1 = color;
186                         color = led_color2.get_color () & ~response;
187                         led_color2.set_color (color);
188                         lpv.pattern.color2 = color;
189                         lpv.pattern.changed ();
190                 }
191                 dialog.destroy ();
192         }
193
194         void on_color2_clicked (Gtk.Button button) {
195                 var dialog = new LedColorDialog ();
196                 int response = dialog.run ();
197                 if (response > 0) {
198                         LedColor color = (LedColor) response;
199                         led_color2.set_color (color);
200                         lpv.pattern.color2 = color;
201                         color = led_color1.get_color () & ~response;
202                         led_color1.set_color (color);
203                         lpv.pattern.color1 = color;
204                         lpv.pattern.changed ();
205                 }
206                 dialog.destroy ();
207         }
208
209         void on_engine1_toggled (Gtk.ToggleButton source) {
210                 if (source.get_active ())
211                         list1.show ();
212                 else
213                         list1.hide ();
214         }
215
216         void on_engine2_toggled (Gtk.ToggleButton source) {
217                 if (source.get_active ())
218                         list2.show ();
219                 else
220                         list2.hide ();
221         }
222
223         void on_new_command_clicked (Gtk.Button button) {
224                 var widget = button.parent.parent.parent;
225                 unowned List<LedCommandRX51> engine;
226                 if (widget == list1) {
227                         engine = lpv.pattern.engine1;
228                 } else if (widget == list2) {
229                         engine = lpv.pattern.engine2;
230                 } else {
231                         return;
232                 }
233
234                 var dialog = new Hildon.PickerDialog (this);
235                 dialog.set_title (_("New command"));
236
237                 var touch_selector = new Hildon.TouchSelector.text ();
238                 touch_selector.append_text (_("Set PWM"));
239                 touch_selector.append_text (_("Ramp"));
240                 touch_selector.append_text (_("Wait"));
241                 touch_selector.append_text (_("Trigger"));
242                 touch_selector.append_text (_("Go To Start"));
243                 touch_selector.append_text (_("End"));
244                 dialog.set_selector (touch_selector);
245
246                 int response = dialog.run ();
247                 if (response == Gtk.ResponseType.OK) {
248                         var command = new LedCommandRX51 ();
249                         LedCommandRX51 last_command = engine.last ().data;
250                         engine.append (command);
251                         command.changed.connect (lpv.pattern.on_changed);
252
253                         switch (touch_selector.get_active (0)) {
254                         case 0:
255                                 command.set_pwm (127);
256                                 break;
257                         case 1:
258                                 if (last_command.type == CommandType.RAMP_WAIT) {
259                                         command.ramp_wait (last_command.step_time,
260                                                            -last_command.steps);
261                                 } else if (last_command.level > 0) {
262                                         command.ramp_wait (125.0 / last_command.level,
263                                                            -last_command.level);
264                                 } else {
265                                         command.ramp_wait (0.49, 255);
266                                 }
267                                 break;
268                         case 2:
269                                 command.ramp_wait (100.0, 0);
270                                 break;
271                         case 3:
272                                 command.type = CommandType.TRIGGER;
273                                 command.code = 0xe000;
274                                 command.changed ();
275                                 break;
276                         case 4:
277                                 command.go_to_start ();
278                                 break;
279                         case 5:
280                                 command.end (false);
281                                 break;
282                         }
283                         var vbox = (Gtk.VBox) button.parent;
284                         var command_widget = new LedCommandWidget (lpv.pattern, engine,
285                                                                    command);
286                         vbox.pack_start (command_widget, false, false, 0);
287                         command_widget.show_all ();
288
289                 }
290                 dialog.destroy ();
291         }
292 }