2 * irreco - Ir Remote Control
3 * Copyright (C) 2007 Arto Karppinen (arto.karppinen@iki.fi)
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program 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.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "irreco_cmd_dlg.h"
21 #include "irreco_backend_dlg.h"
22 #include "irreco_backend_instance.h"
23 #include <hildon/hildon-pannable-area.h>
26 * @addtogroup IrrecoCmdDlg
29 * Show a dialog where the user can select one command from a list of all
37 * Source file of @ref IrrecoCmdDlg.
41 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
42 /* Types and definitions. */
43 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
46 #define IRRECO_SELECT_CMD_DLG_BUTTON_ROW_WIDTH 520
47 #define IRRECO_SELECT_CMD_DLG_BUTTON_PAD 5
48 #define IRRECO_SELECT_CMD_DLG_EXPAND_BUTTONS FALSE
52 IRRECO_RESPONCE_EDIT
= 1,
53 IRRECO_RESPONCE_REFRESH
,
54 IRRECO_RESPONCE_COMMAND_SET
57 typedef struct _IrrecoButtonAppend IrrecoButtonAppend
;
58 struct _IrrecoButtonAppend
{
65 typedef struct _IrrecoSelectCmdDlg IrrecoSelectCmdDlg
;
66 struct _IrrecoSelectCmdDlg
{
67 IrrecoData
*irreco_data
;
76 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
78 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
81 void irreco_cmd_dlg_create_command_list(IrrecoSelectCmdDlg
* cmd_dlg
);
82 void irreco_cmd_dlg_append_device(IrrecoSelectCmdDlg
* cmd_dlg
,
83 IrrecoBackendDevice
* device
);
84 void irreco_cmd_dlg_append_special(IrrecoSelectCmdDlg
* cmd_dlg
);
85 void irreco_cmd_dlg_append_wait_button(IrrecoSelectCmdDlg
* cmd_dlg
,
86 IrrecoButtonAppend
* button_append
,
88 GtkWidget
*irreco_cmd_dlg_append_hbox(GtkWidget
*vbox
,
89 guint padding_between
,
94 gfloat x_expand_scale
,
95 gfloat y_expand_scale
);
96 GtkWidget
*irreco_cmd_dlg_append_title_hbox(GtkWidget
*vbox
);
97 GtkWidget
*irreco_cmd_dlg_append_command_hbox(GtkWidget
*vbox
);
98 void irreco_cmd_dlg_append_button_init(IrrecoButtonAppend
* data
,
100 GtkWidget
*irreco_cmd_dlg_append_button(IrrecoButtonAppend
* data
,
105 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
107 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
115 gboolean
irreco_cmd_dlg_run(IrrecoData
*irreco_data
, IrrecoCmd
* command
,
118 IrrecoSelectCmdDlg cmd_dlg
;
122 memset(&cmd_dlg
, '\0', sizeof(cmd_dlg
));
123 cmd_dlg
.irreco_data
= irreco_data
;
124 cmd_dlg
.command
= command
;
126 /* Create objects. */
127 cmd_dlg
.dialog
= gtk_dialog_new_with_buttons(
128 _("Select command"), parent
,
129 /*irreco_window_manager_get_gtk_window(
130 irreco_data->window_manager),*/
131 GTK_DIALOG_MODAL
| GTK_DIALOG_DESTROY_WITH_PARENT
/* |
132 GTK_DIALOG_NO_SEPARATOR*/,
133 _("Refresh"), IRRECO_RESPONCE_REFRESH
,
134 /*_("Device controllers"), IRRECO_RESPONCE_EDIT,*/
136 cmd_dlg
.scrolled
= hildon_pannable_area_new();
138 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(cmd_dlg
.dialog
)->vbox
),
140 irreco_cmd_dlg_create_command_list(&cmd_dlg
);
142 /* Min width, max height. */
143 gtk_window_resize(GTK_WINDOW(cmd_dlg
.dialog
), 1, 300);
144 gtk_widget_show_all(cmd_dlg
.dialog
);
146 while (rvalue
== -1) {
147 switch (gtk_dialog_run(GTK_DIALOG(cmd_dlg
.dialog
))) {
148 case GTK_RESPONSE_DELETE_EVENT
:
152 case IRRECO_RESPONCE_COMMAND_SET
:
156 case IRRECO_RESPONCE_EDIT
:
157 irreco_show_backend_dlg(irreco_data
,
158 GTK_WINDOW(cmd_dlg
.dialog
));
159 irreco_cmd_dlg_create_command_list(&cmd_dlg
);
162 case IRRECO_RESPONCE_REFRESH
:
163 irreco_backend_manager_get_devcmd_lists(
164 irreco_data
->irreco_backend_manager
);
165 irreco_cmd_dlg_create_command_list(&cmd_dlg
);
170 gtk_widget_destroy(cmd_dlg
.dialog
);
171 IRRECO_RETURN_INT(rvalue
);
174 void irreco_cmd_dlg_create_command_list(IrrecoSelectCmdDlg
* cmd_dlg
)
176 const gchar
*name
= NULL
;
179 if (cmd_dlg
->vbox
!= NULL
) {
180 gtk_widget_destroy(cmd_dlg
->vbox
);
182 cmd_dlg
->vbox
= gtk_vbox_new(FALSE
, 0);
183 hildon_pannable_area_add_with_viewport(HILDON_PANNABLE_AREA(cmd_dlg
->scrolled
),
184 GTK_WIDGET(cmd_dlg
->vbox
));
187 /* Iterate trough instance, device and command arrays. */
188 IRRECO_DEBUG("Generating command list\n");
189 IRRECO_BACKEND_MANAGER_FOREACH_INSTANCE(
190 cmd_dlg
->irreco_data
->irreco_backend_manager
, instance
)
192 name
= irreco_backend_instance_get_name(instance
);
193 IRRECO_DEBUG("Instance: \"%s\"\n", name
);
195 IRRECO_BACKEND_INSTANCE_FOREACH(instance
, device
)
196 IRRECO_DEBUG("Device: \"%s\"\n", device
->name
);
197 irreco_cmd_dlg_append_device(cmd_dlg
, device
);
198 IRRECO_BACKEND_INSTANCE_FOREACH_END
200 IRRECO_STRING_TABLE_FOREACH_END
202 IRRECO_DEBUG("Special commands.\n");
203 irreco_cmd_dlg_append_special(cmd_dlg
);
204 gtk_widget_show_all(cmd_dlg
->dialog
);
213 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
214 /* Signal handlers. */
215 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
218 * @name Signal handlers
223 void irreco_cmd_dlg_set_built_in(GtkButton
* button
,
224 IrrecoSelectCmdDlg
* cmd_dlg
)
229 type
= g_object_get_data(G_OBJECT(button
), "IrrecoCmdType");
230 irreco_cmd_set_builtin(cmd_dlg
->command
, (IrrecoCmdType
) type
);
231 gtk_dialog_response(GTK_DIALOG(cmd_dlg
->dialog
),
232 IRRECO_RESPONCE_COMMAND_SET
);
237 void irreco_cmd_dlg_set_layout(GtkButton
* button
,
238 IrrecoSelectCmdDlg
* cmd_dlg
)
243 name
= g_object_get_data(G_OBJECT(button
), "IrrecoCmdLayout");
244 irreco_cmd_set_layout(cmd_dlg
->command
, (const gchar
*) name
);
245 gtk_dialog_response(GTK_DIALOG(cmd_dlg
->dialog
),
246 IRRECO_RESPONCE_COMMAND_SET
);
251 void irreco_cmd_dlg_set_backend(GtkButton
* button
,
252 IrrecoSelectCmdDlg
* cmd_dlg
)
254 IrrecoBackendDevice
*device
;
255 const gchar
*command
;
258 device
= (IrrecoBackendDevice
*) g_object_get_data(
259 G_OBJECT(button
), "IrrecoCmdBackendDevice");
260 command
= (const gchar
*) g_object_get_data(
261 G_OBJECT(button
), "IrrecoCmdBackendCommand");
262 irreco_cmd_set_backend(cmd_dlg
->command
,
263 device
->backend_instance
,
266 gtk_dialog_response(GTK_DIALOG(cmd_dlg
->dialog
),
267 IRRECO_RESPONCE_COMMAND_SET
);
272 void irreco_cmd_dlg_set_wait(GtkButton
* button
, IrrecoSelectCmdDlg
* cmd_dlg
)
277 delay
= g_object_get_data(G_OBJECT(button
), "IrrecoCmdWaitDelay");
278 irreco_cmd_set_wait(cmd_dlg
->command
, (gulong
) delay
);
279 gtk_dialog_response(GTK_DIALOG(cmd_dlg
->dialog
),
280 IRRECO_RESPONCE_COMMAND_SET
);
290 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
291 /* Dialog construction. */
292 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
295 * @name Dialog construction
300 void irreco_cmd_dlg_append_commands(IrrecoSelectCmdDlg
* cmd_dlg
,
301 IrrecoBackendDevice
* device
)
303 IrrecoButtonAppend button_append
;
307 irreco_cmd_dlg_append_button_init(&button_append
, cmd_dlg
->vbox
);
308 IRRECO_BACKEND_DEVICE_FOREACH(device
, command
)
309 button
= irreco_cmd_dlg_append_button(&button_append
,
311 g_object_set_data(G_OBJECT(button
),
312 "IrrecoCmdBackendDevice",
314 g_object_set_data(G_OBJECT(button
),
315 "IrrecoCmdBackendCommand",
317 g_signal_connect(G_OBJECT(button
), "clicked",
318 G_CALLBACK(irreco_cmd_dlg_set_backend
),
320 IRRECO_BACKEND_DEVICE_FOREACH_END
324 void irreco_cmd_dlg_append_device(IrrecoSelectCmdDlg
* cmd_dlg
,
325 IrrecoBackendDevice
* device
)
329 GtkWidget
*arrow_align
;
330 GtkWidget
*device_label
;
331 GtkWidget
*instance_label
;
334 hbox
= irreco_cmd_dlg_append_title_hbox(cmd_dlg
->vbox
);
335 arrow
= gtk_arrow_new(GTK_ARROW_RIGHT
, GTK_SHADOW_NONE
);
336 arrow_align
= gtk_alignment_new(0.5, 0.5, 1, 1);
337 device_label
= gtk_label_new(device
->name
);
338 instance_label
= gtk_label_new(
339 irreco_backend_instance_get_name(device
->backend_instance
));
342 instance_label = gtk_label_new(
343 irreco_backend_instance_get_name_and_description(
344 device->backend_instance));
347 /* Arrow: 25px width, auto height, 5px padding left and right.*/
348 gtk_widget_set_size_request(arrow
, 25, 0);
349 gtk_misc_set_alignment(GTK_MISC(arrow
), 0.5, 0.5);
350 gtk_alignment_set_padding(GTK_ALIGNMENT(arrow_align
), 0, 0, 8, 8);
352 gtk_misc_set_alignment(GTK_MISC(device_label
), 0, 0.5);
353 gtk_misc_set_alignment(GTK_MISC(instance_label
), 0, 0.5);
355 gtk_container_add(GTK_CONTAINER(arrow_align
), arrow
);
356 gtk_box_pack_start(GTK_BOX(hbox
), instance_label
, 0, 0, 0);
357 gtk_box_pack_start(GTK_BOX(hbox
), arrow_align
, 0, 0, 0);
358 gtk_box_pack_start(GTK_BOX(hbox
), device_label
, 0, 0, 0);
360 if (irreco_backend_device_is_empty(device
)) {
361 GtkWidget
*label
= gtk_label_new(_("This device does not "
362 "have any commands."));
363 hbox
= irreco_cmd_dlg_append_command_hbox(cmd_dlg
->vbox
);
364 gtk_box_pack_start_defaults(GTK_BOX(hbox
), label
);
366 /*GtkWidget *command_vbox = gtk_vbox_new(FALSE, 10);*/
367 irreco_cmd_dlg_append_commands(cmd_dlg
, device
);
375 void irreco_cmd_dlg_append_special(IrrecoSelectCmdDlg
* cmd_dlg
)
380 IrrecoButtonAppend button_append
;
384 hbox
= irreco_cmd_dlg_append_title_hbox(cmd_dlg
->vbox
);
385 label
= gtk_label_new(_("Special commands"));
386 gtk_box_pack_start(GTK_BOX(hbox
), label
, 0, 0, 0);
388 /* Create next remote button. */
389 irreco_cmd_dlg_append_button_init(&button_append
, cmd_dlg
->vbox
);
390 button
= irreco_cmd_dlg_append_button(
391 &button_append
, _(IRRECO_COMMAND_NEXT_REMOTE_TITLE
));
392 g_object_set_data(G_OBJECT(button
), "IrrecoCmdType",
393 (gpointer
) IRRECO_COMMAND_NEXT_REMOTE
);
394 g_signal_connect(G_OBJECT(button
), "clicked",
395 G_CALLBACK(irreco_cmd_dlg_set_built_in
),
398 /* Create previous remote button. */
399 button
= irreco_cmd_dlg_append_button(
400 &button_append
, _(IRRECO_COMMAND_PREVIOUS_REMOTE_TITLE
));
401 g_object_set_data(G_OBJECT(button
), "IrrecoCmdType",
402 (gpointer
) IRRECO_COMMAND_PREVIOUS_REMOTE
);
403 g_signal_connect(G_OBJECT(button
), "clicked",
404 G_CALLBACK(irreco_cmd_dlg_set_built_in
),
407 /* Fullscreen toggle button. */
408 /* button = irreco_cmd_dlg_append_button(
409 &button_append, _(IRRECO_COMMAND_FULLSCREEN_TOGGLE_TITLE));
410 g_object_set_data(G_OBJECT(button), "IrrecoCmdType",
411 (gpointer) IRRECO_COMMAND_FULLSCREEN_TOGGLE);
412 g_signal_connect(G_OBJECT(button), "clicked",
413 G_CALLBACK(irreco_cmd_dlg_set_built_in),
416 /* Create show remote buttons. */
417 string
= g_string_new("");
418 IRRECO_STRING_TABLE_FOREACH_KEY(
419 cmd_dlg
->irreco_data
->irreco_layout_array
, layout_name
)
420 g_string_append(g_string_set_size(string
, 0),
421 _(IRRECO_COMMAND_SHOW_LAYOUT_TITLE_PREFIX
));
422 g_string_append(string
, layout_name
);
423 button
= irreco_cmd_dlg_append_button(&button_append
,
425 g_object_set_data(G_OBJECT(button
), "IrrecoCmdLayout",
426 (gpointer
) layout_name
);
427 g_signal_connect(G_OBJECT(button
), "clicked",
428 G_CALLBACK(irreco_cmd_dlg_set_layout
),
430 IRRECO_STRING_TABLE_FOREACH_END
431 g_string_free(string
, TRUE
);
433 /* Append wait buttons. */
434 irreco_cmd_dlg_append_wait_button(cmd_dlg
, &button_append
,
435 IRRECO_SECONDS_TO_USEC(0.3));
436 irreco_cmd_dlg_append_wait_button(cmd_dlg
, &button_append
,
437 IRRECO_SECONDS_TO_USEC(0.6));
438 irreco_cmd_dlg_append_wait_button(cmd_dlg
, &button_append
,
439 IRRECO_SECONDS_TO_USEC(1));
440 irreco_cmd_dlg_append_wait_button(cmd_dlg
, &button_append
,
441 IRRECO_SECONDS_TO_USEC(1.5));
442 irreco_cmd_dlg_append_wait_button(cmd_dlg
, &button_append
,
443 IRRECO_SECONDS_TO_USEC(2));
444 irreco_cmd_dlg_append_wait_button(cmd_dlg
, &button_append
,
445 IRRECO_SECONDS_TO_USEC(3));
446 irreco_cmd_dlg_append_wait_button(cmd_dlg
, &button_append
,
447 IRRECO_SECONDS_TO_USEC(5));
448 irreco_cmd_dlg_append_wait_button(cmd_dlg
, &button_append
,
449 IRRECO_SECONDS_TO_USEC(7));
450 irreco_cmd_dlg_append_wait_button(cmd_dlg
, &button_append
,
451 IRRECO_SECONDS_TO_USEC(10));
455 void irreco_cmd_dlg_append_wait_button(IrrecoSelectCmdDlg
* cmd_dlg
,
456 IrrecoButtonAppend
* button_append
,
464 command
= irreco_cmd_create();
465 irreco_cmd_set_wait(command
, delay
);
466 button
= irreco_cmd_dlg_append_button(
467 button_append
, irreco_cmd_get_short_name(command
));
468 irreco_cmd_destroy(command
);
471 string = g_string_new(NULL);
472 g_string_printf(string, _(IRRECO_COMMAND_WAIT_TITLE_FORMAT),
473 (float)(delay) / 1000);
475 g_string_free(string, TRUE);
479 g_object_set_data(G_OBJECT(button
), "IrrecoCmdWaitDelay",
481 g_signal_connect(G_OBJECT(button
), "clicked",
482 G_CALLBACK(irreco_cmd_dlg_set_wait
),
491 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
492 /* GtkHBox utility functions. */
493 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
496 * @name GtkHBox utility functions
501 GtkWidget
*irreco_cmd_dlg_append_hbox(GtkWidget
* vbox
,
502 guint padding_between
,
504 guint padding_bottom
,
507 gfloat x_expand_scale
,
508 gfloat y_expand_scale
)
514 hbox
= gtk_hbox_new(FALSE
, padding_between
);
515 align
= irreco_gtk_align(hbox
, 0, 0, x_expand_scale
, y_expand_scale
,
516 padding_top
, padding_bottom
, padding_left
,
518 gtk_box_pack_start(GTK_BOX(vbox
), align
, 0, 0, 0);
519 IRRECO_RETURN_PTR(hbox
);
522 void irreco_cmd_dlg_append_separator(GtkWidget
* vbox
,
524 guint padding_bottom
)
529 align
= irreco_gtk_align(gtk_hseparator_new(), 0, 0, 1, 1,
530 padding_top
, padding_bottom
, 20, 0);
531 gtk_box_pack_start(GTK_BOX(vbox
), align
, 0, 0, 0);
535 GtkWidget
*irreco_cmd_dlg_append_title_hbox(GtkWidget
* vbox
)
540 hbox
= irreco_cmd_dlg_append_hbox(vbox
,
541 0, /*padding_between */
543 0, /*padding_bottom */
544 25, /*padding_left */
545 20, /*padding_right */
546 0, /* x_expand_scale */
547 0 /* y_expand_scale */
549 irreco_cmd_dlg_append_separator(vbox
, 2, 6);
550 IRRECO_RETURN_PTR(hbox
);
553 GtkWidget
*irreco_cmd_dlg_append_command_hbox(GtkWidget
* vbox
)
555 return irreco_cmd_dlg_append_hbox(vbox
,
556 IRRECO_SELECT_CMD_DLG_BUTTON_PAD
, /* padding_between */
558 IRRECO_SELECT_CMD_DLG_BUTTON_PAD
, /* padding_bottom */
559 25, /* padding_left */
560 20, /* padding_right */
561 IRRECO_SELECT_CMD_DLG_EXPAND_BUTTONS
, /* x_expand_scale */
562 0 /* y_expand_scale */
570 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
571 /* Button adding to button rows. */
572 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
575 * @name Button adding to button rows
581 * Initialize IrrecoButtonAppend structure.
583 * There is no need to clean IrrecoButtonAppend structure because all
584 * created widgets will be attached to the vbox.
586 void irreco_cmd_dlg_append_button_init(IrrecoButtonAppend
* data
,
591 data
->hbox
= irreco_cmd_dlg_append_command_hbox(vbox
);
598 * Add a button to button row. Creates a new button row if current is full.
600 * Returns: a new GtkButton.
602 GtkWidget
*irreco_cmd_dlg_append_button(IrrecoButtonAppend
* data
,
606 GtkRequisition requisition
;
609 /* Because you cant get widget data->width without adding it to a
610 container, this code does thing a bit backwards. */
611 button
= gtk_button_new_with_label(title
);
612 gtk_box_pack_start_defaults(GTK_BOX(data
->hbox
), button
);
613 gtk_widget_size_request(GTK_WIDGET(button
), &requisition
);
614 data
->width
+= requisition
.width
+ IRRECO_SELECT_CMD_DLG_BUTTON_PAD
;
616 /* If we have too much buttons on one row, destroy button,
617 and create another button on a new row. */
618 if (data
->width
> IRRECO_SELECT_CMD_DLG_BUTTON_ROW_WIDTH
619 && data
->count
> 0) {
620 gtk_widget_destroy(button
);
622 data
->width
= requisition
.width
+
623 IRRECO_SELECT_CMD_DLG_BUTTON_PAD
;
624 data
->hbox
= irreco_cmd_dlg_append_command_hbox(data
->vbox
);
625 button
= gtk_button_new_with_label(title
);
626 gtk_box_pack_start_defaults(GTK_BOX(data
->hbox
), button
);
630 IRRECO_RETURN_PTR(button
);