1 /* gAlan - Graphical Audio Language
2 * Copyright (C) 1999 Tony Garnock-Jones
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "generator.h"
33 #include "gtkslider.h"
36 #include "galan_jack.h"
41 PUBLIC GtkWidget
*control_panel
= NULL
;
42 PRIVATE ControlPanel
*global_panel
= NULL
;
43 PRIVATE GtkWidget
*control_notebook
= NULL
;
44 PRIVATE GList
*control_panels
= NULL
;
45 PRIVATE GThread
*update_thread
;
46 PRIVATE GAsyncQueue
*update_queue
;
48 PRIVATE
char *pixmap_path
= NULL
;
50 PRIVATE
void mylayout_sizerequest( GtkContainer
*container
, GtkRequisition
*requisition
) {
52 GList
*list
= gtk_container_get_children( container
);
55 requisition
->width
= 0;
56 requisition
->height
= 0;
59 for( listX
=list
; listX
!= NULL
; listX
= g_list_next( listX
) ) {
61 GtkWidget
*widget
= listX
->data
;
65 gtk_container_child_get( container
, widget
, "x", &x
, NULL
);
66 gtk_container_child_get( container
, widget
, "y", &y
, NULL
);
68 gtk_widget_size_request( widget
, &req
);
72 if( x
+w
> requisition
->width
) requisition
->width
= x
+w
;
73 if( y
+h
> requisition
->height
) requisition
->height
= y
+h
;
76 gtk_layout_set_size( GTK_LAYOUT( container
), requisition
->width
, requisition
->height
);
81 PUBLIC
void control_panel_register_panel( ControlPanel
*panel
, char *name
, gboolean add_fixed
) {
83 panel
->scrollwin
= gtk_scrolled_window_new( NULL
, NULL
);
85 //gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW( panel->scrollwin ), panel->fixedwidget );
86 gtk_container_add( GTK_CONTAINER( panel
->scrollwin
), panel
->fixedwidget
);
87 //gtk_layout_set_size( GTK_LAYOUT( panel->fixedwidget ), 1024, 2048 );
88 gtk_layout_set_vadjustment( GTK_LAYOUT( panel
->fixedwidget
),
89 gtk_scrolled_window_get_vadjustment( GTK_SCROLLED_WINDOW( panel
->scrollwin
) ) );
90 gtk_layout_set_hadjustment( GTK_LAYOUT( panel
->fixedwidget
),
91 gtk_scrolled_window_get_hadjustment( GTK_SCROLLED_WINDOW( panel
->scrollwin
) ) );
95 gtk_widget_show(panel
->scrollwin
);
97 gtk_notebook_append_page( GTK_NOTEBOOK( control_notebook
), panel
->scrollwin
, gtk_label_new( name
) );
98 gtk_container_check_resize( GTK_CONTAINER( panel
->fixedwidget
) );
99 control_panels
= g_list_append( control_panels
, panel
);
100 panel
->visible
= TRUE
;
103 PUBLIC
void control_panel_unregister_panel( ControlPanel
*panel
) {
107 control_panels
= g_list_remove( control_panels
, panel
);
108 pagenum
= gtk_notebook_page_num( GTK_NOTEBOOK( control_notebook
), panel
->scrollwin
);
109 gtk_notebook_remove_page( GTK_NOTEBOOK( control_notebook
), pagenum
);
110 panel
->scrollwin
= NULL
;
111 panel
->visible
= FALSE
;
114 PUBLIC
void update_panel_name( ControlPanel
*panel
) {
116 gtk_notebook_set_tab_label_text( GTK_NOTEBOOK( control_notebook
), panel
->scrollwin
, panel
->name
);
118 control_update_names( panel
->sheet
->panel_control
);
121 PUBLIC
void control_moveto(Control
*c
, int x
, int y
) {
122 x
= floor((x
+ (GRANULARITY
>>1)) / ((gdouble
) GRANULARITY
)) * GRANULARITY
;
123 y
= floor((y
+ (GRANULARITY
>>1)) / ((gdouble
) GRANULARITY
)) * GRANULARITY
;
125 if (x
!= c
->x
|| y
!= c
->y
) {
127 ControlPanel
*panel
= c
->panel
== NULL
? global_panel
: c
->panel
;
132 gtk_layout_move(GTK_LAYOUT(panel
->fixedwidget
),
135 if( c
->move_callback
)
136 c
->move_callback( c
);
143 PRIVATE
void knob_slider_handler(GtkWidget
*adj
, Control
*c
) {
144 control_emit(c
, GTK_ADJUSTMENT(adj
)->value
);
147 PRIVATE
void toggled_handler(GtkWidget
*button
, Control
*c
) {
148 control_emit(c
, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button
)) ? 1 : 0);
151 PRIVATE
void clicked_handler(GtkWidget
*button
, Control
*c
) {
155 PRIVATE
void entry_changed(GtkEntry
*entry
, GtkAdjustment
*adj
) {
156 adj
->value
= atof(gtk_entry_get_text(entry
));
157 gtk_signal_handler_block_by_data(GTK_OBJECT(adj
), entry
);
158 gtk_signal_emit_by_name(GTK_OBJECT(adj
), "value_changed");
159 gtk_signal_handler_unblock_by_data(GTK_OBJECT(adj
), entry
);
162 PRIVATE
void update_entry(GtkAdjustment
*adj
, GtkEntry
*entry
) {
164 sprintf(buf
, "%g", adj
->value
);
165 gtk_signal_handler_block_by_data(GTK_OBJECT(entry
), adj
);
166 gtk_entry_set_text(entry
, buf
);
167 gtk_signal_handler_unblock_by_data(GTK_OBJECT(entry
), adj
);
170 PRIVATE
void delete_ctrl_handler(GtkWidget
*widget
, Control
*c
) {
171 control_kill_control(c
, FALSE
);
174 PUBLIC
void control_update_bg(Control
*c
) {
177 if( c
->desc
->kind
!= CONTROL_KIND_PANEL
)
181 if( c
->testbg_active
|| (c
->this_panel
->bg_type
!= CONTROL_PANEL_BG_DEFAULT
) ) {
183 GdkPixbuf
*pb
= NULL
;
187 if( c
->testbg_active
) {
188 pb
= gdk_pixbuf_new_from_file( PIXMAPDIRIFY( "galan-bg-ref.png" ), &err
);
189 gdk_pixbuf_render_pixmap_and_mask( pb
, &pixmap
, &mask
, 100 );
191 if( ! GTK_WIDGET_MAPPED( c
->widget
) )
193 switch( c
->this_panel
->bg_type
) {
194 case CONTROL_PANEL_BG_IMAGE
:
195 if( c
->this_panel
->bg_image_name
)
196 pb
= gdk_pixbuf_new_from_file( c
->this_panel
->bg_image_name
, &err
);
198 popup_msgbox("Error Loading Pixmap", MSGBOX_OK
, 120000, MSGBOX_OK
,
199 "File not found, or file format error: %s",
200 c
->this_panel
->bg_image_name
);
204 gdk_pixbuf_render_pixmap_and_mask( pb
, &pixmap
, &mask
, 100 );
205 gdk_window_set_back_pixmap( GTK_LAYOUT(c
->widget
)->bin_window
, pixmap
, FALSE
);
206 gtk_widget_queue_draw( c
->widget
);
208 case CONTROL_PANEL_BG_GRADIENT
:
210 GdkWindow
*win
= GTK_LAYOUT(c
->widget
)->bin_window
;
212 gdk_drawable_get_size( GDK_DRAWABLE( win
), &w
, &h
);
213 //pb = gdk_pixbuf_new( GDK_COLORSPACE_RGB, FALSE, 8, w, h );
214 pixmap
= gdk_pixmap_new( GDK_DRAWABLE( win
), w
, h
, -1 );
215 if( gdk_drawable_get_colormap( GDK_DRAWABLE( win
) ) == NULL
)
216 gdk_drawable_set_colormap( GDK_DRAWABLE( win
), gdk_colormap_get_system() );
218 cairo_t
*cr
= gdk_cairo_create( GDK_DRAWABLE(pixmap
) );
222 //cairo_scale( cr, w, h );
223 cairo_pattern_t
*pat
= cairo_pattern_create_linear( 0,0,0,h
);
224 cairo_pattern_add_color_stop_rgb( pat
, 0,
225 c
->this_panel
->color1
.red
/65536.0,
226 c
->this_panel
->color1
.green
/65536.0,
227 c
->this_panel
->color1
.blue
/65536.0 );
228 cairo_pattern_add_color_stop_rgb( pat
, 1,
229 c
->this_panel
->color2
.red
/65536.0,
230 c
->this_panel
->color2
.green
/65536.0,
231 c
->this_panel
->color2
.blue
/65536.0 );
232 cairo_set_source( cr
, pat
);
233 cairo_rectangle( cr
, 0,0,w
,h
);
235 cairo_set_source_rgba( cr
,
236 c
->this_panel
->frame_color
.red
/65536.0,
237 c
->this_panel
->frame_color
.green
/65536.0,
238 c
->this_panel
->frame_color
.blue
/65536.0,
239 c
->this_panel
->frame_alpha
/65536.0);
240 cairo_rectangle( cr
, 0,0,w
,h
);
241 cairo_set_line_width (cr
, 8.0);
243 cairo_pattern_destroy( pat
);
245 gdk_window_set_back_pixmap( GTK_LAYOUT(c
->widget
)->bin_window
, pixmap
, FALSE
);
246 gtk_widget_queue_draw( c
->widget
);
251 case CONTROL_PANEL_BG_DEFAULT
:
252 case CONTROL_PANEL_BG_COLOR
:
259 //gtk_style_set_background(c->widget->style, GTK_LAYOUT(c->widget)->bin_window, GTK_STATE_NORMAL);
260 gtk_style_set_background(control_panel
->style
, GTK_LAYOUT(c
->widget
)->bin_window
, GTK_STATE_NORMAL
);
264 PRIVATE
void change_bg_handler(GtkWidget
*widget
, Control
*c
) {
265 GtkWidget
*dialog
, *vbox2
, *color1
, *color2
, *filename
, *framecolor
; //*type;
267 dialog
= gtk_dialog_new_with_buttons( "Panel Background Settings", GTK_WINDOW(control_panel
), GTK_DIALOG_DESTROY_WITH_PARENT
,
268 "Image", CONTROL_PANEL_BG_IMAGE
, "Gradient", CONTROL_PANEL_BG_GRADIENT
, "Default", CONTROL_PANEL_BG_DEFAULT
, NULL
);
270 vbox2
= gtk_vbox_new( FALSE
, 10 );
271 color1
= g_object_new( GTK_TYPE_COLOR_BUTTON
, "color", &(c
->this_panel
->color1
), "title", "color1", "use-alpha", FALSE
, NULL
);
272 color2
= g_object_new( GTK_TYPE_COLOR_BUTTON
, "color", &(c
->this_panel
->color2
), "title", "color2", "use-alpha", FALSE
, NULL
);
273 framecolor
= g_object_new( GTK_TYPE_COLOR_BUTTON
,
274 "color", &(c
->this_panel
->frame_color
), "title", "frame color", "use-alpha", TRUE
, "alpha", c
->this_panel
->frame_alpha
, NULL
);
276 filename
= gtk_file_chooser_button_new( "Background Image", GTK_FILE_CHOOSER_ACTION_OPEN
);
279 if( c
->this_panel
->bg_image_name
) {
280 if( ! g_path_is_absolute( c
->this_panel
->bg_image_name
) ) {
281 gchar
*current_dir
= g_get_current_dir();
282 gchar
*abspath
= g_build_filename( current_dir
, c
->this_panel
->bg_image_name
, NULL
);
283 g_free( c
->this_panel
->bg_image_name
);
284 c
->this_panel
->bg_image_name
= abspath
;
285 g_free( current_dir
);
288 gtk_file_chooser_set_filename( GTK_FILE_CHOOSER(filename
), c
->this_panel
->bg_image_name
);
290 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(filename
), pixmap_path
);
293 gtk_container_add( GTK_CONTAINER( vbox2
), color1
);
294 gtk_container_add( GTK_CONTAINER( vbox2
), color2
);
295 gtk_container_add( GTK_CONTAINER( vbox2
), framecolor
);
296 gtk_container_add( GTK_CONTAINER( vbox2
), filename
);
298 gtk_container_add( GTK_CONTAINER( GTK_DIALOG( dialog
)->vbox
), vbox2
);
299 gtk_widget_show_all( dialog
);
301 gint response
= gtk_dialog_run( GTK_DIALOG(dialog
) );
302 if( response
!= GTK_RESPONSE_DELETE_EVENT
) {
303 gtk_color_button_get_color( GTK_COLOR_BUTTON(color1
), &(c
->this_panel
->color1
) );
304 gtk_color_button_get_color( GTK_COLOR_BUTTON(color2
), &(c
->this_panel
->color2
) );
305 gtk_color_button_get_color( GTK_COLOR_BUTTON(framecolor
), &(c
->this_panel
->frame_color
) );
306 c
->this_panel
->frame_alpha
= gtk_color_button_get_alpha( GTK_COLOR_BUTTON(framecolor
) );
308 if( c
->this_panel
->bg_image_name
) free( c
->this_panel
->bg_image_name
);
309 c
->this_panel
->bg_image_name
= gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(filename
) );
310 c
->this_panel
->bg_type
= response
;
314 gtk_widget_destroy( dialog
);
316 control_update_bg( c
);
324 PRIVATE GtkWidget
*ctrl_rename_text_widget
= NULL
;
326 PRIVATE
void ctrl_rename_handler(MsgBoxResponse action_taken
, Control
*c
) {
327 if (action_taken
== MSGBOX_OK
) {
328 const char *newname
= gtk_entry_get_text(GTK_ENTRY(ctrl_rename_text_widget
));
330 if (c
->name
!= NULL
) {
335 if (newname
[0] != '\0') /* nonempty string */
336 c
->name
= safe_string_dup(newname
);
338 control_update_names(c
);
342 PRIVATE
void rename_ctrl_handler(GtkWidget
*widget
, Control
*c
) {
343 GtkWidget
*hb
= gtk_hbox_new(FALSE
, 5);
344 GtkWidget
*label
= gtk_label_new("Rename control:");
345 GtkWidget
*text
= gtk_entry_new();
347 gtk_box_pack_start(GTK_BOX(hb
), label
, TRUE
, FALSE
, 0);
348 gtk_box_pack_start(GTK_BOX(hb
), text
, TRUE
, FALSE
, 0);
350 gtk_widget_show(label
);
351 gtk_widget_show(text
);
353 gtk_entry_set_text(GTK_ENTRY(text
), c
->name
? c
->name
: "");
355 ctrl_rename_text_widget
= text
;
356 popup_dialog("Rename", MSGBOX_OK
| MSGBOX_CANCEL
, 0, MSGBOX_OK
, hb
,
357 (MsgBoxResponseHandler
) ctrl_rename_handler
, c
);
360 PRIVATE
void midi_learn_handler(GtkWidget
*widget
, Control
*c
) {
361 midilearn_set_target_control( c
);
364 PRIVATE
void control_visible_ctrl_handler(GtkWidget
*widget
, Control
*c
) {
366 c
->control_visible
= !(c
->control_visible
);
368 if( c
->control_visible
)
369 gtk_widget_show( c
->widget
);
371 gtk_widget_hide( c
->widget
);
373 gtk_widget_queue_resize( c
->whole
);
376 PRIVATE
void control_panel_test_bg_ctrl_handler(GtkWidget
*widget
, Control
*c
) {
378 c
->testbg_active
= !(c
->testbg_active
);
380 control_update_bg( c
);
383 PRIVATE
void entry_visible_ctrl_handler(GtkWidget
*widget
, Control
*c
) {
385 c
->entry_visible
= !(c
->entry_visible
);
387 if( c
->entry_visible
)
388 gtk_widget_show( c
->entry
);
390 gtk_widget_hide( c
->entry
);
392 gtk_widget_queue_resize( c
->whole
);
395 PRIVATE
void frame_visible_ctrl_handler(GtkWidget
*widget
, Control
*c
) {
396 c
->frame_visible
= !(c
->frame_visible
);
398 if( ! c
->frame_visible
){
399 gtk_frame_set_shadow_type (GTK_FRAME (c
->title_frame
) , GTK_SHADOW_NONE
);
400 gtk_frame_set_label (GTK_FRAME (c
->title_frame
) , NULL
);
402 gtk_frame_set_shadow_type (GTK_FRAME (c
->title_frame
) , GTK_SHADOW_ETCHED_IN
);
403 gtk_label_set_text(GTK_LABEL(c
->title_label
),c
->desc
->name
);
405 gtk_widget_queue_resize( c
->whole
);
408 PRIVATE
void name_visible_ctrl_handler(GtkWidget
*widget
, Control
*c
) {
409 c
->name_visible
= !(c
->name_visible
);
411 if( ! c
->name_visible
){
413 /* In order for this to work, you need the pixmap to bring up the menu...
414 * gtk_widget_hide( c->title_label );
415 * the following is a temp hack.
417 gtk_label_set_text(GTK_LABEL(c
->title_label
)," ");
420 /* In order for this to work, you need the pixmap to bring up the menu...
421 * gtk_widget_show( c->title_label );
422 * the following is a temp hack
424 control_update_names(c
);
426 gtk_widget_queue_resize( c
->whole
);
428 PRIVATE
void control_panel_sizer_visible_ctrl_handler(GtkWidget
*widget
, Control
*c
) {
430 c
->this_panel
->sizer_visible
= !(c
->this_panel
->sizer_visible
);
432 if( c
->this_panel
->sizer_visible
) {
433 gtk_widget_show( c
->this_panel
->sizer_image
);
434 gtk_layout_move( GTK_LAYOUT(c
->this_panel
->fixedwidget
), c
->this_panel
->sizer_ebox
,
435 c
->this_panel
->sizer_x
, c
->this_panel
->sizer_y
);
440 gtk_widget_hide( c
->this_panel
->sizer_image
);
441 gtk_layout_move( GTK_LAYOUT(c
->this_panel
->fixedwidget
), c
->this_panel
->sizer_ebox
,
442 c
->this_panel
->sizer_x
+ 16, c
->this_panel
->sizer_y
+ 16 );
446 PRIVATE
void popup_menu(Control
*c
, GdkEventButton
*be
) {
447 static GtkWidget
*old_popup_menu
= NULL
;
451 if (old_popup_menu
!= NULL
) {
452 gtk_widget_unref(old_popup_menu
);
453 old_popup_menu
= NULL
;
456 menu
= gtk_menu_new();
458 item
= gtk_menu_item_new_with_label("Delete");
459 gtk_widget_show(item
);
460 gtk_menu_append(GTK_MENU(menu
), item
);
461 gtk_signal_connect(GTK_OBJECT(item
), "activate", GTK_SIGNAL_FUNC(delete_ctrl_handler
), c
);
463 item
= gtk_menu_item_new_with_label("Rename...");
464 gtk_widget_show(item
);
465 gtk_menu_append(GTK_MENU(menu
), item
);
466 gtk_signal_connect(GTK_OBJECT(item
), "activate", GTK_SIGNAL_FUNC(rename_ctrl_handler
), c
);
469 item = gtk_check_menu_item_new_with_label( "Folded" );
470 gtk_check_menu_item_set_state( GTK_CHECK_MENU_ITEM( item ), c->folded );
471 gtk_widget_show(item);
472 gtk_menu_append(GTK_MENU(menu), item);
473 gtk_signal_connect(GTK_OBJECT(item), "toggled", GTK_SIGNAL_FUNC(fold_ctrl_handler), c);
475 item = gtk_check_menu_item_new_with_label( "Discreet" );
476 gtk_check_menu_item_set_state( GTK_CHECK_MENU_ITEM( item ), c->discreet );
477 gtk_widget_show(item);
478 gtk_menu_append(GTK_MENU(menu), item);
479 gtk_signal_connect(GTK_OBJECT(item), "toggled", GTK_SIGNAL_FUNC(discreet_ctrl_handler), c);
482 item
= gtk_check_menu_item_new_with_label( "Frame" );
483 gtk_check_menu_item_set_state( GTK_CHECK_MENU_ITEM( item
), c
->frame_visible
);
484 gtk_widget_show(item
);
485 gtk_menu_append(GTK_MENU(menu
), item
);
486 gtk_signal_connect(GTK_OBJECT(item
), "toggled", GTK_SIGNAL_FUNC(frame_visible_ctrl_handler
), c
);
488 item
= gtk_check_menu_item_new_with_label( "Name" );
489 gtk_check_menu_item_set_state( GTK_CHECK_MENU_ITEM( item
), c
->name_visible
);
490 gtk_widget_show(item
);
491 gtk_menu_append(GTK_MENU(menu
), item
);
492 gtk_signal_connect(GTK_OBJECT(item
), "toggled", GTK_SIGNAL_FUNC(name_visible_ctrl_handler
), c
);
495 item
= gtk_check_menu_item_new_with_label( "Entry" );
496 gtk_check_menu_item_set_state( GTK_CHECK_MENU_ITEM( item
), c
->entry_visible
);
497 gtk_widget_show(item
);
498 gtk_menu_append(GTK_MENU(menu
), item
);
499 gtk_signal_connect(GTK_OBJECT(item
), "toggled", GTK_SIGNAL_FUNC(entry_visible_ctrl_handler
), c
);
502 item
= gtk_check_menu_item_new_with_label( "Control" );
503 gtk_check_menu_item_set_state( GTK_CHECK_MENU_ITEM( item
), c
->control_visible
);
504 gtk_widget_show(item
);
505 gtk_menu_append(GTK_MENU(menu
), item
);
506 gtk_signal_connect(GTK_OBJECT(item
), "toggled", GTK_SIGNAL_FUNC(control_visible_ctrl_handler
), c
);
508 if( c
->desc
->kind
== CONTROL_KIND_PANEL
) {
509 item
= gtk_menu_item_new_with_label("Set Background");
510 gtk_widget_show(item
);
511 gtk_menu_append(GTK_MENU(menu
), item
);
512 gtk_signal_connect(GTK_OBJECT(item
), "activate", GTK_SIGNAL_FUNC(change_bg_handler
), c
);
514 item
= gtk_check_menu_item_new_with_label( "Reference Background" );
515 gtk_check_menu_item_set_state( GTK_CHECK_MENU_ITEM( item
), c
->testbg_active
);
516 gtk_widget_show(item
);
517 gtk_menu_append(GTK_MENU(menu
), item
);
518 gtk_signal_connect(GTK_OBJECT(item
), "toggled", GTK_SIGNAL_FUNC(control_panel_test_bg_ctrl_handler
), c
);
520 item
= gtk_check_menu_item_new_with_label( "Sizer" );
521 gtk_check_menu_item_set_state( GTK_CHECK_MENU_ITEM( item
), c
->this_panel
->sizer_visible
);
522 gtk_widget_show(item
);
523 gtk_menu_append(GTK_MENU(menu
), item
);
524 gtk_signal_connect(GTK_OBJECT(item
), "toggled", GTK_SIGNAL_FUNC(control_panel_sizer_visible_ctrl_handler
), c
);
528 if( c
->desc
->kind
== CONTROL_KIND_KNOB
|| c
->desc
->kind
== CONTROL_KIND_SLIDER
) {
529 item
= gtk_menu_item_new_with_label("MIDI Learn");
530 gtk_widget_show(item
);
531 gtk_menu_append(GTK_MENU(menu
), item
);
532 gtk_signal_connect(GTK_OBJECT(item
), "activate", GTK_SIGNAL_FUNC(midi_learn_handler
), c
);
535 gtk_menu_popup(GTK_MENU(menu
), NULL
, NULL
, NULL
, NULL
,
536 be
->button
, be
->time
);
538 g_object_ref( menu
);
539 old_popup_menu
= menu
;
542 PRIVATE gboolean
eventbox_handler(GtkWidget
*eventbox
, GdkEvent
*event
, Control
*c
) {
544 switch (event
->type
) {
545 case GDK_BUTTON_PRESS
: {
546 GdkEventButton
*be
= (GdkEventButton
*) event
;
548 switch (be
->button
) {
552 gtk_grab_add(eventbox
);
553 c
->saved_x
= c
->x
- be
->x_root
;
554 c
->saved_y
= c
->y
- be
->y_root
;
566 case GDK_BUTTON_RELEASE
: {
569 gtk_grab_remove(eventbox
);
574 case GDK_MOTION_NOTIFY
: {
575 GdkEventMotion
*me
= (GdkEventMotion
*) event
;
579 c
->saved_x
+ me
->x_root
,
580 c
->saved_y
+ me
->y_root
);
583 gtk_widget_queue_draw( eventbox
);
593 PRIVATE gboolean
control_map_handler(GtkWidget
*eventbox
, Control
*c
) {
595 gtk_widget_queue_resize( c
->whole
);
596 control_update_bg( c
);
602 PUBLIC Control
*control_new_control(ControlDescriptor
*desc
, Generator
*g
, ControlPanel
*panel
) {
603 Control
*c
= safe_malloc(sizeof(Control
));
604 GtkAdjustment
*adj
= NULL
;
611 c
->step
= desc
->step
;
612 c
->page
= desc
->page
;
614 c
->frame_visible
= TRUE
;
615 c
->name_visible
= TRUE
;
616 c
->entry_visible
= TRUE
;
617 c
->control_visible
= TRUE
;
618 c
->testbg_active
= FALSE
;
620 if( panel
== NULL
&& global_panel
== NULL
)
621 global_panel
= control_panel_new( "Global", TRUE
, NULL
);
625 c
->moving
= c
->saved_x
= c
->saved_y
= 0;
628 c
->events_flow
= TRUE
;
630 c
->update_refcount
= 0;
636 c
->move_callback
= NULL
;
638 switch (desc
->kind
) {
639 case CONTROL_KIND_SLIDER
:
640 c
->widget
= gtk_slider_new(NULL
, c
->desc
->size
);
641 adj
= gtk_slider_get_adjustment(GTK_SLIDER(c
->widget
));
644 case CONTROL_KIND_KNOB
:
645 c
->widget
= gtk_knob_new(NULL
);
646 adj
= gtk_knob_get_adjustment(GTK_KNOB(c
->widget
));
649 case CONTROL_KIND_TOGGLE
:
650 c
->widget
= gtk_toggle_button_new_with_label("0/1");
651 gtk_signal_connect(GTK_OBJECT(c
->widget
), "toggled", GTK_SIGNAL_FUNC(toggled_handler
), c
);
654 case CONTROL_KIND_BUTTON
:
655 c
->widget
= gtk_button_new();
656 gtk_widget_set_usize(c
->widget
, 24, 8);
657 gtk_signal_connect(GTK_OBJECT(c
->widget
), "clicked", GTK_SIGNAL_FUNC(clicked_handler
), c
);
660 case CONTROL_KIND_USERDEF
:
661 case CONTROL_KIND_PANEL
:
666 g_error("Unknown control kind %d (ControlDescriptor named '%s')",
671 if (desc
->initialize
)
674 if (c
->widget
== NULL
) {
683 adj
->step_increment
= c
->step
;
684 adj
->page_increment
= c
->page
;
686 gtk_signal_connect(GTK_OBJECT(adj
), "value_changed", GTK_SIGNAL_FUNC(knob_slider_handler
), c
);
693 if( desc
->kind
== CONTROL_KIND_PANEL
)
694 c
->this_panel
= desc
->refresh_data
;
696 c
->this_panel
= NULL
;
698 c
->title_frame
= gtk_frame_new(g
== NULL
? c
->this_panel
->name
: g
->name
);
699 gtk_widget_show(c
->title_frame
);
701 vbox
= gtk_vbox_new(FALSE
, 0);
702 gtk_container_add(GTK_CONTAINER(c
->title_frame
), vbox
);
703 gtk_widget_show(vbox
);
705 eventbox
= gtk_event_box_new();
706 gtk_box_pack_start(GTK_BOX(vbox
), eventbox
, FALSE
, FALSE
, 0);
707 gtk_widget_show(eventbox
);
708 gtk_signal_connect(GTK_OBJECT(eventbox
), "event", GTK_SIGNAL_FUNC(eventbox_handler
), c
);
710 c
->title_label
= gtk_label_new(c
->name
? c
->name
: desc
->name
);
711 gtk_container_add(GTK_CONTAINER(eventbox
), c
->title_label
);
712 gtk_widget_show(c
->title_label
);
714 if( desc
->kind
== CONTROL_KIND_PANEL
)
715 gtk_widget_reparent( c
->widget
, vbox
);
717 gtk_box_pack_start(GTK_BOX(vbox
), c
->widget
, FALSE
, FALSE
, 0);
719 gtk_widget_show(c
->widget
);
721 if (adj
!= NULL
&& c
->desc
->allow_direct_edit
) {
722 c
->entry
= gtk_entry_new();
723 gtk_widget_set_usize(c
->entry
, GAUGE_SIZE
, 0);
724 gtk_widget_show(c
->entry
);
726 gtk_box_pack_start(GTK_BOX(vbox
), c
->entry
, FALSE
, FALSE
, 0);
728 gtk_signal_connect(GTK_OBJECT(c
->entry
), "activate",
729 GTK_SIGNAL_FUNC(entry_changed
), adj
);
730 gtk_signal_connect(GTK_OBJECT(adj
), "value_changed",
731 GTK_SIGNAL_FUNC(update_entry
), c
->entry
);
736 c
->whole
= gtk_event_box_new();
738 gtk_signal_connect_after(GTK_OBJECT(c
->whole
), "map", GTK_SIGNAL_FUNC(control_map_handler
), c
);
740 g_object_ref( G_OBJECT(c
->whole
) );
741 g_object_set_data( G_OBJECT(c
->whole
), "Control", c
);
742 gtk_container_add(GTK_CONTAINER(c
->whole
), c
->title_frame
);
743 gtk_widget_show( c
->whole
);
745 gtk_layout_put(GTK_LAYOUT(panel
== NULL
? global_panel
->fixedwidget
: panel
->fixedwidget
),
746 c
->whole
, c
->x
, c
->y
);
748 g_object_ref( G_OBJECT( panel
== NULL
? global_panel
->fixedwidget
: panel
->fixedwidget
) );
750 if (!GTK_WIDGET_REALIZED(eventbox
))
751 gtk_widget_realize(eventbox
);
753 gdk_window_set_events(eventbox
->window
,
754 GDK_EXPOSURE_MASK
| GDK_BUTTON_PRESS_MASK
| GDK_BUTTON_RELEASE_MASK
| GDK_POINTER_MOTION_MASK
);
757 if( c
->desc
->kind
!= CONTROL_KIND_PANEL
) {
758 gen_register_control(c
->g
, c
);
759 gen_update_controls( c
->g
, -1 );
763 g_object_ref( G_OBJECT(c
->widget
) );
769 * \brief Kill a Control
771 * \param c The Control to be removed
773 * with the gdk_threads_enter/leave pair i need to assure this is a different thread.
774 * it could be safe to call check for kill Control from the update processor.
776 * i will put gdk_threads enter leave outside of this function.
777 * So make sure you hold the gdk-lock when you call this function.
780 PUBLIC
void control_kill_control(Control
*c
, gboolean lock_taken
) {
781 g_return_if_fail(c
!= NULL
);
783 midilearn_remove_control( c
);
786 gen_deregister_control(c
->g
, c
, lock_taken
);
791 PRIVATE
void control_dispose( Control
*c
)
794 g_object_unref( G_OBJECT( c
->widget
) );
795 if( c
->desc
->destroy
!= NULL
)
796 c
->desc
->destroy( c
);
797 //gtk_widget_hide(c->whole);
798 //gtk_container_remove(GTK_CONTAINER(c->panel == NULL ? global_panel->fixedwidget : c->panel->fixedwidget), c->whole);
799 gtk_widget_destroy( c
->whole
);
800 g_object_unref( G_OBJECT(c
->whole
) );
801 g_object_unref( G_OBJECT(c
->panel
== NULL
? global_panel
->fixedwidget
: c
->panel
->fixedwidget
) );
808 // TODO: a race condition with the updater_thread. let the updater delete the control.
809 // need to add a lock for the controls list.
811 //control_update_value( c );
814 PUBLIC
void control_ref( Control
*c
)
816 g_atomic_int_inc( &(c
->refcnt
) );
819 PUBLIC
void control_unref( Control
*c
)
821 if( g_atomic_int_dec_and_test( &(c
->refcnt
) ) )
823 control_dispose( c
);
827 PRIVATE
int find_control_index(Control
*c
) {
830 for (i
= 0; i
< c
->g
->klass
->numcontrols
; i
++)
831 if (&c
->g
->klass
->controls
[i
] == c
->desc
)
834 g_error("Control index unfindable! c->desc->name is %p (%s)", c
->desc
->name
, c
->desc
->name
);
838 PRIVATE GtkWidget
*panel_fixed
= NULL
;
840 PRIVATE
void init_panel( Control
*control
) {
841 control
->widget
= panel_fixed
;
844 PRIVATE
void done_panel( Control
*control
) {
846 control
->this_panel
->sheet
->panel_control_active
= FALSE
;
847 control
->this_panel
->sheet
->panel_control
= NULL
;
849 control_panel_register_panel( control
->this_panel
, control
->this_panel
->name
, FALSE
);
851 g_object_ref( G_OBJECT(control
->this_panel
->fixedwidget
) );
852 gtk_widget_reparent( control
->this_panel
->fixedwidget
, control
->this_panel
->scrollwin
);
853 g_object_unref( G_OBJECT(control
->this_panel
->fixedwidget
) );
855 gtk_layout_set_vadjustment( GTK_LAYOUT( control
->this_panel
->fixedwidget
),
856 gtk_scrolled_window_get_vadjustment( GTK_SCROLLED_WINDOW( control
->this_panel
->scrollwin
) ) );
857 gtk_layout_set_hadjustment( GTK_LAYOUT( control
->this_panel
->fixedwidget
),
858 gtk_scrolled_window_get_hadjustment( GTK_SCROLLED_WINDOW( control
->this_panel
->scrollwin
) ) );
860 gtk_widget_show( control
->this_panel
->fixedwidget
);
861 gtk_widget_queue_resize( control
->this_panel
->fixedwidget
);
864 PRIVATE ControlDescriptor desc
=
865 { CONTROL_KIND_PANEL
, "panel", 0,0,0,0, 0,FALSE
, TRUE
,0, init_panel
, done_panel
, NULL
, NULL
};
868 PUBLIC Control
*control_unpickle(ObjectStoreItem
*item
) {
870 Generator
*g
= gen_unpickle(objectstore_item_get_object(item
, "generator"));
871 int control_index
= objectstore_item_get_integer(item
, "desc_index", 0);
872 ObjectStoreItem
*ccp
= objectstore_item_get_object( item
, "panel" );
873 ControlPanel
*cp
= ((ccp
== NULL
) ? NULL
: control_panel_unpickle( ccp
));
874 ControlPanel
*tp
= control_panel_unpickle( objectstore_item_get_object( item
, "this_panel" ));
878 int folded
, discreet
;
881 desc
.refresh_data
= tp
;
882 panel_fixed
= tp
->fixedwidget
;
883 c
= control_new_control( &desc
, NULL
, cp
);
884 control_panel_unregister_panel( tp
);
886 c
= control_new_control(&g
->klass
->controls
[control_index
], g
, cp
);
890 name
= objectstore_item_get_string(item
, "name", NULL
);
891 c
->name
= name
? safe_string_dup(name
) : NULL
;
893 control_update_names(c
);
895 c
->min
= objectstore_item_get_double(item
, "min", 0);
896 c
->max
= objectstore_item_get_double(item
, "max", 100);
897 c
->step
= objectstore_item_get_double(item
, "step", 1);
898 c
->page
= objectstore_item_get_double(item
, "page", 1);
900 folded
= objectstore_item_get_integer(item
, "folded", 0);
901 discreet
= objectstore_item_get_integer(item
, "discreet", 0);
903 if( ! (c
->frame_visible
= objectstore_item_get_integer( item
, "frame_visible", ! discreet
) ) ) {
904 gtk_frame_set_shadow_type (GTK_FRAME (c
->title_frame
) , GTK_SHADOW_NONE
);
905 gtk_frame_set_label (GTK_FRAME (c
->title_frame
) , NULL
);
906 //gtk_label_set_text(GTK_LABEL(c->title_label)," ");
909 if( ! (c
->name_visible
= objectstore_item_get_integer( item
, "name_visible", c
->frame_visible
) ) ) {
910 gtk_label_set_text(GTK_LABEL(c
->title_label
)," ");
913 if( ! (c
->entry_visible
= objectstore_item_get_integer( item
, "entry_visible", ! discreet
) ) ) {
915 gtk_widget_hide( c
->entry
);
918 if( ! (c
->control_visible
= objectstore_item_get_integer( item
, "control_visible", ! folded
) ) ) {
919 gtk_widget_hide( c
->widget
);
924 // XXX: always or default ?
925 if( c
->this_panel
&& c
->this_panel
->bg_image_name
) {
928 control_update_bg( c
);
931 x
= objectstore_item_get_integer(item
, "x_coord", 0);
932 y
= objectstore_item_get_integer(item
, "y_coord", 0);
933 control_moveto(c
, x
, y
);
934 c
->events_flow
= TRUE
;
936 c
->update_refcount
= 0;
941 PUBLIC ObjectStoreItem
*control_pickle(Control
*c
, ObjectStore
*db
) {
942 ObjectStoreItem
*item
= objectstore_new_item(db
, "Control", c
);
944 objectstore_item_set_object(item
, "generator", gen_pickle(c
->g
, db
));
945 objectstore_item_set_integer(item
, "desc_index", find_control_index(c
));
949 objectstore_item_set_object(item
, "this_panel", control_panel_pickle(c
->this_panel
, db
));
952 objectstore_item_set_object(item
, "panel", control_panel_pickle(c
->panel
, db
));
955 objectstore_item_set_string(item
, "name", c
->name
);
957 objectstore_item_set_double(item
, "min", c
->min
);
958 objectstore_item_set_double(item
, "max", c
->max
);
959 objectstore_item_set_double(item
, "step", c
->step
);
960 objectstore_item_set_double(item
, "page", c
->page
);
961 objectstore_item_set_integer(item
, "x_coord", c
->x
);
962 objectstore_item_set_integer(item
, "y_coord", c
->y
);
963 // objectstore_item_set_integer(item, "folded", c->folded);
964 // objectstore_item_set_integer(item, "discreet", c->discreet);
965 objectstore_item_set_integer(item
, "control_visible", c
->control_visible
);
966 objectstore_item_set_integer(item
, "frame_visible", c
->frame_visible
);
967 objectstore_item_set_integer(item
, "name_visible", c
->name_visible
);
968 objectstore_item_set_integer(item
, "entry_visible", c
->entry_visible
);
971 /* don't save c->data in any form, Controls are MVC views, not models. */
975 Control
*control_clone( Control
*c
, Generator
*g
, ControlPanel
*cp
) {
977 Control
*retval
= control_new_control( c
->desc
, g
, cp
);
979 retval
->name
= c
->name
? safe_string_dup(c
->name
) : NULL
;
981 control_update_names(retval
);
984 retval
->frame_visible
= c
->frame_visible
;
985 if( ! (c
->frame_visible
) ) {
986 gtk_frame_set_shadow_type (GTK_FRAME (retval
->title_frame
) , GTK_SHADOW_NONE
);
987 gtk_frame_set_label (GTK_FRAME (retval
->title_frame
) , NULL
);
988 gtk_label_set_text(GTK_LABEL(retval
->title_label
)," ");
991 retval
->entry_visible
= c
->entry_visible
;
992 if( ! (c
->entry_visible
) ) {
994 gtk_widget_hide( retval
->entry
);
997 retval
->control_visible
= c
->control_visible
;
998 if( ! (c
->control_visible
) ) {
999 gtk_widget_hide( retval
->widget
);
1001 retval
->min
= c
->min
;
1002 retval
->max
= c
->max
;
1003 retval
->step
= c
->step
;
1004 retval
->page
= c
->page
;
1006 control_moveto( retval
, c
->x
, c
->y
);
1011 PUBLIC
void control_emit(Control
*c
, gdouble number
) {
1014 if (!c
->events_flow
)
1017 gen_init_aevent(&e
, AE_NUMBER
, NULL
, 0, c
->g
, c
->desc
->queue_number
, gen_get_sampletime());
1018 e
.d
.number
= number
;
1020 if (c
->desc
->is_dst_gen
)
1021 gen_post_aevent(&e
); /* send to c->g as dest */
1023 gen_send_events(c
->g
, c
->desc
->queue_number
, -1, &e
); /* send *from* c->g */
1026 PUBLIC
void control_update_names(Control
*c
) {
1027 g_return_if_fail(c
!= NULL
);
1029 if( c
->frame_visible
) {
1032 gtk_frame_set_label(GTK_FRAME(c
->title_frame
), c
->g
->name
);
1034 gtk_frame_set_label(GTK_FRAME(c
->title_frame
), c
->this_panel
->name
);
1037 if( c
->name_visible
) {
1038 gtk_label_set_text(GTK_LABEL(c
->title_label
), c
->name
? c
->name
: c
->desc
->name
);
1042 PUBLIC
void control_update_range(Control
*c
) {
1043 GtkAdjustment
*adj
= NULL
;
1045 switch (c
->desc
->kind
) {
1046 case CONTROL_KIND_SLIDER
: adj
= gtk_slider_get_adjustment(GTK_SLIDER(c
->widget
)); break;
1047 case CONTROL_KIND_KNOB
: adj
= gtk_knob_get_adjustment(GTK_KNOB(c
->widget
)); break;
1053 adj
->lower
= c
->min
;
1054 adj
->upper
= c
->max
;
1055 adj
->step_increment
= c
->step
;
1056 adj
->page_increment
= c
->page
;
1058 gtk_signal_emit_by_name(GTK_OBJECT(adj
), "changed");
1062 PUBLIC
void control_update_value(Control
*c
) {
1064 g_async_queue_push( update_queue
, c
);
1067 PRIVATE
void control_update_value_real(Control
*c
) {
1068 c
->events_flow
= FALSE
; /* as already stated... not very elegant. */
1070 if (c
->desc
->refresh
!= NULL
)
1071 c
->desc
->refresh(c
);
1073 c
->events_flow
= TRUE
;
1076 PRIVATE gboolean
control_panel_delete_handler(GtkWidget
*cp
, GdkEvent
*event
) {
1077 hide_control_panel();
1082 PRIVATE gboolean
sizerbox_handler(GtkWidget
*eventbox
, GdkEvent
*event
, ControlPanel
*panel
) {
1084 switch (event
->type
) {
1085 case GDK_BUTTON_PRESS
:
1087 GdkEventButton
*be
= (GdkEventButton
*) event
;
1089 switch (be
->button
) {
1091 if (!panel
->sizer_moving
) {
1092 panel
->sizer_moving
= 1;
1093 gtk_grab_add(eventbox
);
1094 panel
->sizer_saved_x
= panel
->sizer_x
- be
->x_root
;
1095 panel
->sizer_saved_y
= panel
->sizer_y
- be
->y_root
;
1102 case GDK_BUTTON_RELEASE
:
1104 if (panel
->sizer_moving
) {
1105 panel
->sizer_moving
= 0;
1106 gtk_grab_remove(eventbox
);
1111 case GDK_MOTION_NOTIFY
:
1113 GdkEventMotion
*me
= (GdkEventMotion
*) event
;
1115 if (panel
->sizer_moving
) {
1116 gtk_layout_move( GTK_LAYOUT(panel
->fixedwidget
), eventbox
,
1117 panel
->sizer_saved_x
+ me
->x_root
,
1118 panel
->sizer_saved_y
+ me
->y_root
);
1120 panel
->sizer_x
= panel
->sizer_saved_x
+ me
->x_root
;
1121 panel
->sizer_y
= panel
->sizer_saved_y
+ me
->y_root
;
1132 PRIVATE
void control_invoke_move_callback( GtkWidget
*control_widget
, gpointer user_data
) {
1133 Control
*c
= g_object_get_data( G_OBJECT(control_widget
), "Control" );
1134 if( c
&& c
->move_callback
)
1135 c
->move_callback( c
);
1138 PRIVATE
void control_panel_scroll_handler( GtkAdjustment
*adjustment
, ControlPanel
*cp
) {
1139 gtk_container_foreach( GTK_CONTAINER(cp
->fixedwidget
), control_invoke_move_callback
, NULL
);
1142 PUBLIC ControlPanel
*control_panel_new( char *name
, gboolean visible
, Sheet
*sheet
) {
1144 ControlPanel
*panel
= safe_malloc( sizeof( ControlPanel
) );
1145 panel
->scrollwin
= NULL
; //gtk_scrolled_window_new(NULL, NULL);
1146 panel
->name
= safe_string_dup(name
);
1148 panel
->fixedwidget
= gtk_layout_new(NULL
,NULL
);
1156 panel
->sizer_moving
= 0;
1157 panel
->sizer_visible
= 0;
1158 panel
->bg_image_name
= NULL
;
1159 gdk_color_white( gdk_colormap_get_system(), &(panel
->color1
) );
1160 gdk_color_black( gdk_colormap_get_system(), &(panel
->color2
) );
1162 g_signal_connect( G_OBJECT( panel
->fixedwidget
), "size_request", G_CALLBACK(mylayout_sizerequest
), NULL
);
1167 control_panel_register_panel( panel
, name
, TRUE
);
1169 panel
->visible
= FALSE
;
1171 g_signal_connect_after( gtk_layout_get_hadjustment( GTK_LAYOUT( panel
->fixedwidget
) ),
1172 "value-changed", (GCallback
) control_panel_scroll_handler
, panel
);
1173 g_signal_connect_after( gtk_layout_get_vadjustment( GTK_LAYOUT( panel
->fixedwidget
) ),
1174 "value-changed", (GCallback
) control_panel_scroll_handler
, panel
);
1176 panel
->sheet
= sheet
;
1178 gtk_widget_show(panel
->fixedwidget
);
1180 // if (!GTK_WIDGET_REALIZED(panel->fixedwidget))
1181 // gtk_widget_realize(panel->fixedwidget);
1183 gtk_container_check_resize( GTK_CONTAINER(panel
->fixedwidget
) );
1184 update_panel_name( panel
);
1186 // code for the sizer.
1188 panel
->sizer_image
= gtk_image_new_from_file( PIXMAPDIRIFY( "corner-widget.png" ) );
1189 panel
->sizer_ebox
= gtk_event_box_new();
1191 gtk_container_add( GTK_CONTAINER( panel
->sizer_ebox
), panel
->sizer_image
);
1193 gtk_layout_put( GTK_LAYOUT( panel
->fixedwidget
), panel
->sizer_ebox
, 0, 0 );
1195 gtk_widget_show( panel
->sizer_ebox
);
1197 gtk_signal_connect(GTK_OBJECT(panel
->sizer_ebox
), "event", GTK_SIGNAL_FUNC(sizerbox_handler
), panel
);
1203 PUBLIC ControlPanel
*control_panel_unpickle(ObjectStoreItem
*item
) {
1209 cp
= objectstore_get_object( item
);
1211 char *name
= objectstore_item_get_string(item
, "name", "Panel" );
1212 ObjectStoreItem
*sitem
= objectstore_item_get_object( item
, "sheet" );
1213 //gboolean visible = objectstore_item_get_integer( item, "visible", TRUE );
1214 cp
= control_panel_new( name
, TRUE
, NULL
);
1215 objectstore_set_object(item
, cp
);
1216 cp
->sizer_x
= objectstore_item_get_integer( item
, "sizer_x", 0 );
1217 cp
->sizer_y
= objectstore_item_get_integer( item
, "sizer_y", 0 );
1218 cp
->sheet
= ( sitem
== NULL
? NULL
: sheet_unpickle( sitem
) );
1219 cp
->bg_type
= CONTROL_PANEL_BG_DEFAULT
;
1220 cp
->bg_image_name
= objectstore_item_get_string( item
, "current_bg", NULL
);
1221 if( cp
->bg_image_name
) {
1222 if( g_file_test( cp
->bg_image_name
, G_FILE_TEST_EXISTS
) ) {
1223 cp
->bg_image_name
= safe_string_dup( cp
->bg_image_name
);
1224 cp
->bg_type
= CONTROL_PANEL_BG_IMAGE
;
1226 char *bg_basename
= g_path_get_basename( cp
->bg_image_name
);
1227 char *bg_in_pixmap_dir
= g_build_filename( pixmap_path
, bg_basename
, NULL
);
1229 if( g_file_test( bg_in_pixmap_dir
, G_FILE_TEST_EXISTS
) ) {
1230 cp
->bg_image_name
= bg_in_pixmap_dir
;
1231 cp
->bg_type
= CONTROL_PANEL_BG_IMAGE
;
1233 cp
->bg_image_name
= NULL
;
1234 g_free( bg_in_pixmap_dir
);
1237 g_free( bg_basename
);
1240 cp
->color1
.red
= objectstore_item_get_integer( item
, "color1_red", 65535 );
1241 cp
->color1
.green
= objectstore_item_get_integer( item
, "color1_green", 65535 );
1242 cp
->color1
.blue
= objectstore_item_get_integer( item
, "color1_blue", 65535 );
1243 cp
->color2
.red
= objectstore_item_get_integer( item
, "color2_red", 0 );
1244 cp
->color2
.green
= objectstore_item_get_integer( item
, "color2_green", 0 );
1245 cp
->color2
.blue
= objectstore_item_get_integer( item
, "color2_blue", 0 );
1246 cp
->frame_color
.red
= objectstore_item_get_integer( item
, "frame_color_red", 0 );
1247 cp
->frame_color
.green
= objectstore_item_get_integer( item
, "frame_color_green", 0 );
1248 cp
->frame_color
.blue
= objectstore_item_get_integer( item
, "frame_color_blue", 0 );
1249 cp
->frame_alpha
= objectstore_item_get_integer( item
, "frame_alpha", 0 );
1250 cp
->bg_type
= objectstore_item_get_integer( item
, "bg_type", cp
->bg_type
);
1252 gtk_layout_move( GTK_LAYOUT(cp
->fixedwidget
), cp
->sizer_ebox
,
1253 cp
->sizer_x
+ 16, cp
->sizer_y
+ 16 );
1259 PUBLIC ObjectStoreItem
*control_panel_pickle(ControlPanel
*cp
, ObjectStore
*db
) {
1260 ObjectStoreItem
*item
= objectstore_get_item(db
, cp
);
1263 item
= objectstore_new_item(db
, "ControlPanel", cp
);
1265 objectstore_item_set_string(item
, "name", cp
->name
);
1267 objectstore_item_set_object( item
, "sheet", sheet_pickle( cp
->sheet
, db
) );
1269 if ( cp
->bg_image_name
)
1270 objectstore_item_set_string( item
, "current_bg", cp
->bg_image_name
);
1271 objectstore_item_set_integer( item
, "visible", cp
->visible
);
1272 objectstore_item_set_integer( item
, "sizer_x", cp
->sizer_x
);
1273 objectstore_item_set_integer( item
, "sizer_y", cp
->sizer_y
);
1275 objectstore_item_set_integer( item
, "color1_red", cp
->color1
.red
);
1276 objectstore_item_set_integer( item
, "color1_green", cp
->color1
.green
);
1277 objectstore_item_set_integer( item
, "color1_blue", cp
->color1
.blue
);
1278 objectstore_item_set_integer( item
, "color2_red", cp
->color2
.red
);
1279 objectstore_item_set_integer( item
, "color2_green", cp
->color2
.green
);
1280 objectstore_item_set_integer( item
, "color2_blue", cp
->color2
.blue
);
1281 objectstore_item_set_integer( item
, "frame_color_red", cp
->frame_color
.red
);
1282 objectstore_item_set_integer( item
, "frame_color_green", cp
->frame_color
.green
);
1283 objectstore_item_set_integer( item
, "frame_color_blue", cp
->frame_color
.blue
);
1284 objectstore_item_set_integer( item
, "frame_alpha", cp
->frame_alpha
);
1285 objectstore_item_set_integer( item
, "bg_type", cp
->bg_type
);
1291 PRIVATE gpointer
update_processor( gpointer data
) {
1293 Control
*c
= g_async_queue_pop( update_queue
);
1294 gdk_threads_enter();
1295 control_update_value_real( c
);
1297 gdk_threads_leave();
1302 PUBLIC
void init_control_thread(void) {
1304 update_thread
= g_thread_create( update_processor
, NULL
, TRUE
, &err
);
1307 PUBLIC
void init_control(void) {
1309 pixmap_path
= getenv("GALAN_PIXMAP_PATH");
1311 pixmap_path
= SITE_PKGDATA_DIR G_DIR_SEPARATOR_S
"pixmaps";
1313 if( ! g_path_is_absolute( pixmap_path
) ) {
1314 gchar
*current_dir
= g_get_current_dir();
1315 gchar
*abspath
= g_build_filename( current_dir
, pixmap_path
, NULL
);
1316 //g_free( pixmap_path );
1317 pixmap_path
= abspath
;
1318 g_free( current_dir
);
1321 update_queue
= g_async_queue_new();
1323 control_panel
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
1324 gtk_window_set_title(GTK_WINDOW(control_panel
), "gAlan Control Panel");
1325 gtk_window_position(GTK_WINDOW(control_panel
), GTK_WIN_POS_CENTER
);
1326 gtk_window_set_policy(GTK_WINDOW(control_panel
), TRUE
, TRUE
, FALSE
);
1327 gtk_window_set_wmclass(GTK_WINDOW(control_panel
), "gAlan_controls", "gAlan");
1328 gtk_widget_set_usize(control_panel
, 400, 300);
1329 gtk_widget_set_name( control_panel
, "control_panel" );
1330 gtk_signal_connect(GTK_OBJECT(control_panel
), "delete_event",
1331 GTK_SIGNAL_FUNC(control_panel_delete_handler
), NULL
);
1334 control_notebook
= gtk_notebook_new();
1335 gtk_widget_show( control_notebook
);
1336 gtk_container_add(GTK_CONTAINER(control_panel
), control_notebook
);
1339 PUBLIC
void show_control_panel(void) {
1340 gtk_widget_show(control_panel
);
1343 PUBLIC
void hide_control_panel(void) {
1344 gtk_widget_hide(control_panel
);
1347 PUBLIC
void reset_control_panel(void) {
1348 /* A NOOP currently.
1349 * When I get round to figuring out a good way of making newly-created controls
1350 * appear in an empty spot, this routine may become useful. */
1353 PUBLIC
void control_set_value(Control
*c
, gfloat value
) {
1356 switch (c
->desc
->kind
) {
1357 case CONTROL_KIND_SLIDER
: adj
= gtk_slider_get_adjustment(GTK_SLIDER(c
->widget
)); break;
1358 case CONTROL_KIND_KNOB
: adj
= gtk_knob_get_adjustment(GTK_KNOB(c
->widget
)); break;
1360 case CONTROL_KIND_TOGGLE
:
1361 value
= MAX(MIN(value
, 1), 0);
1362 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(c
->widget
), value
>= 0.5);
1370 //adj->value = value;
1371 //gtk_signal_emit_by_name(GTK_OBJECT(adj), "value_changed");
1372 gtk_adjustment_set_value( GTK_ADJUSTMENT( adj
), value
);
1376 PUBLIC
void control_int32_updater(Control
*c
) {
1377 control_set_value(c
, * (gint32
*) ((gpointer
) c
->g
->data
+ (size_t) c
->desc
->refresh_data
));
1380 PUBLIC
void control_double_updater(Control
*c
) {
1381 control_set_value(c
, * (gdouble
*) ((gpointer
) c
->g
->data
+ (size_t) c
->desc
->refresh_data
));