2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 Camera plugin for GtkRadiant
24 Copyright (C) 2002 Splash Damage Ltd.
29 static GSList *g_pEditTypeRadio = NULL;
30 static GtkWidget *g_pEditModeEditRadioButton = NULL;
31 GtkWidget *g_pEditModeAddRadioButton = NULL;
32 static GtkWidget *g_pSecondsEntry = NULL;
33 static GtkWidget *g_pEventsList = NULL;
34 static GtkLabel *g_pCurrentTime = NULL;
35 static GtkLabel *g_pTotalTime = NULL;
36 static GtkAdjustment *g_pTimeLine = NULL;
37 static GtkWidget *g_pTrackCamera = NULL;
38 static GtkWidget *g_pCamName = NULL;
39 static char *g_cNull = '\0';
41 static gint ci_editmode_edit( GtkWidget *widget, gpointer data ){
47 static gint ci_editmode_add( GtkWidget *widget, gpointer data ){
53 /*static gint ci_delete_selected( GtkWidget *widget, gpointer data )
58 static gint ci_select_all( GtkWidget *widget, gpointer data )
63 static gint ci_new( GtkWidget *widget, gpointer data ){
64 GtkWidget *w, *hbox; //, *name;
65 GtkWidget *fixed, *interpolated, *spline;
66 EMessageBoxReturn ret;
68 GSList *targetTypeRadio = NULL;
72 auto window = ui::Window( ui::window_type::TOP );
73 gtk_window_set_title( GTK_WINDOW( window ), "New Camera" );
74 window.connect( "delete_event", G_CALLBACK( dialog_delete_callback ), NULL );
75 window.connect( "destroy", G_CALLBACK( gtk_widget_destroy ), NULL );
76 gtk_window_set_transient_for( GTK_WINDOW( window ), GTK_WINDOW( g_pCameraInspectorWnd ) );
78 g_object_set_data( G_OBJECT( window ), "loop", &loop );
79 g_object_set_data( G_OBJECT( window ), "ret", &ret );
81 gtk_widget_realize( window );
84 auto vbox = ui::VBox( FALSE, 5 );
88 // -------------------------- //
90 hbox = ui::HBox( FALSE, 5 );
91 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
92 gtk_widget_show( hbox );
94 auto frame = ui::Frame( "Type" );
95 gtk_box_pack_start( GTK_BOX( hbox ), frame, TRUE, TRUE, 0 );
96 gtk_widget_show( frame );
98 auto vbox2 = ui::VBox( FALSE, 5 );
100 gtk_container_set_border_width( GTK_CONTAINER( vbox2 ), 5 );
101 gtk_widget_show( vbox2 );
103 // -------------------------- //
105 fixed = gtk_radio_button_new_with_label( targetTypeRadio, "Fixed" );
106 gtk_box_pack_start( GTK_BOX( vbox2 ), fixed, FALSE, FALSE, 3 );
107 gtk_widget_show( fixed );
108 targetTypeRadio = gtk_radio_button_get_group( GTK_RADIO_BUTTON( fixed ) );
110 interpolated = gtk_radio_button_new_with_label( targetTypeRadio, "Interpolated" );
111 gtk_box_pack_start( GTK_BOX( vbox2 ), interpolated, FALSE, FALSE, 3 );
112 gtk_widget_show( interpolated );
113 targetTypeRadio = gtk_radio_button_get_group( GTK_RADIO_BUTTON( interpolated ) );
115 spline = gtk_radio_button_new_with_label( targetTypeRadio, "Spline" );
116 gtk_box_pack_start( GTK_BOX( vbox2 ), spline, FALSE, FALSE, 3 );
117 gtk_widget_show( spline );
118 targetTypeRadio = gtk_radio_button_get_group( GTK_RADIO_BUTTON( spline ) );
120 // -------------------------- //
122 w = gtk_hseparator_new();
123 gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 2 );
124 gtk_widget_show( w );
126 // -------------------------- //
128 hbox = ui::HBox( FALSE, 5 );
129 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
130 gtk_widget_show( hbox );
132 w = ui::Button( "Ok" );
133 gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 );
134 w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) );
135 gtk_widget_show( w );
137 gtk_widget_set_can_default( w, true );
138 gtk_widget_grab_default( w );
140 w = ui::Button( "Cancel" );
141 gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 );
142 w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) );
143 gtk_widget_show( w );
146 // -------------------------- //
148 gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER );
149 gtk_widget_show( window );
150 gtk_grab_add( window );
152 bool dialogError = TRUE;
153 while ( dialogError ) {
156 gtk_main_iteration();
160 if ( ret == eIDOK ) {
161 if ( gtk_toggle_button_get_active( (GtkToggleButton*)fixed ) ) {
164 else if ( gtk_toggle_button_get_active( (GtkToggleButton*)interpolated ) ) {
165 DoNewInterpolatedCamera();
167 else if ( gtk_toggle_button_get_active( (GtkToggleButton*)spline ) ) {
173 gtk_grab_remove( window );
179 static gint ci_load( GtkWidget *widget, gpointer data ){
185 static gint ci_save( GtkWidget *widget, gpointer data ){
191 static gint ci_unload( GtkWidget *widget, gpointer data ){
197 static gint ci_apply( GtkWidget *widget, gpointer data ){
198 if ( GetCurrentCam() ) {
203 str = gtk_entry_get_text( GTK_ENTRY( g_pCamName ) );
206 GetCurrentCam()->GetCam()->setName( str );
210 str = gtk_entry_get_text( GTK_ENTRY( g_pSecondsEntry ) );
213 GetCurrentCam()->GetCam()->setBaseTime( atof( str ) );
218 GetCurrentCam()->GetCam()->buildCamera();
221 sprintf( buf, "%.2f", GetCurrentCam()->GetCam()->getBaseTime() );
222 gtk_entry_set_text( GTK_ENTRY( g_pSecondsEntry ), buf );
224 sprintf( buf, "%.2f", GetCurrentCam()->GetCam()->getTotalTime() );
225 gtk_label_set_text( g_pCurrentTime, "0.00" );
226 gtk_label_set_text( g_pTotalTime, buf );
228 gtk_adjustment_set_value( g_pTimeLine, 0.f );
229 g_pTimeLine->upper = GetCurrentCam()->GetCam()->getTotalTime() * 1000;
231 GetCurrentCam()->HasBeenModified();
237 static gint ci_preview( GtkWidget *widget, gpointer data ){
238 if ( GetCurrentCam() ) {
239 g_iPreviewRunning = 1;
240 g_FuncTable.m_pfnSysUpdateWindows( W_XY_OVERLAY | W_CAMERA );
246 static gint ci_expose( GtkWidget *widget, gpointer data ){
248 DoStartEdit( GetCurrentCam() );
253 static gint ci_close( GtkWidget *widget, gpointer data ){
254 gtk_widget_hide( g_pCameraInspectorWnd );
262 static GtkWidget *g_pPathListCombo = NULL;
263 static GtkLabel *g_pPathType = NULL;
265 static void RefreshPathListCombo( void ){
266 if ( !g_pPathListCombo ) {
270 GList *combo_list = (GList*)NULL;
272 if ( GetCurrentCam() ) {
273 combo_list = g_list_append( combo_list, (void *)GetCurrentCam()->GetCam()->getPositionObj()->getName() );
274 for ( int i = 0; i < GetCurrentCam()->GetCam()->numTargets(); i++ ) {
275 combo_list = g_list_append( combo_list, (void *)GetCurrentCam()->GetCam()->getActiveTarget( i )->getName() );
279 // add one empty string make gtk be quiet
280 combo_list = g_list_append( combo_list, (gpointer)g_cNull );
283 gtk_combo_set_popdown_strings( GTK_COMBO( g_pPathListCombo ), combo_list );
284 g_list_free( combo_list );
287 static gint ci_pathlist_changed( GtkWidget *widget, gpointer data ){
288 const char *str = gtk_entry_get_text( GTK_ENTRY( widget ) );
290 if ( !str || !GetCurrentCam() ) {
295 for ( i = 0; i < GetCurrentCam()->GetCam()->numTargets(); i++ ) {
296 if ( !strcmp( str, GetCurrentCam()->GetCam()->getActiveTarget( i )->getName() ) ) {
301 if ( i >= 0 && i < GetCurrentCam()->GetCam()->numTargets() ) {
302 GetCurrentCam()->GetCam()->setActiveTarget( i );
306 gtk_label_set_text( g_pPathType, GetCurrentCam()->GetCam()->getActiveTarget( g_iActiveTarget )->typeStr() );
310 g_iActiveTarget = -1;
312 gtk_label_set_text( g_pPathType, GetCurrentCam()->GetCam()->getPositionObj()->typeStr() );
317 if ( g_pCameraInspectorWnd && gtk_widget_get_visible( g_pCameraInspectorWnd ) ) {
318 DoStartEdit( GetCurrentCam() );
324 static void RefreshEventList( void ){
329 gtk_clist_freeze( GTK_CLIST( g_pEventsList ) );
330 gtk_clist_clear( GTK_CLIST( g_pEventsList ) );
332 if ( GetCurrentCam() ) {
334 for ( i = 0; i < GetCurrentCam()->GetCam()->numEvents(); i++ ) {
335 char rowbuf[3][128], *row[3];
336 // FIXME: sort by time?
337 sprintf( rowbuf[0], "%li", GetCurrentCam()->GetCam()->getEvent( i )->getTime() ); row[0] = rowbuf[0];
338 strncpy( rowbuf[1], GetCurrentCam()->GetCam()->getEvent( i )->typeStr(), sizeof( rowbuf[0] ) ); row[1] = rowbuf[1];
339 strncpy( rowbuf[2], GetCurrentCam()->GetCam()->getEvent( i )->getParam(), sizeof( rowbuf[1] ) ); row[2] = rowbuf[2];
340 gtk_clist_append( GTK_CLIST( g_pEventsList ), row );
343 // Total duration might have changed
344 sprintf( buf, "%.2f", GetCurrentCam()->GetCam()->getTotalTime() );
345 gtk_label_set_text( g_pCurrentTime, "0.00" );
346 gtk_label_set_text( g_pTotalTime, buf );
348 gtk_adjustment_set_value( g_pTimeLine, 0.f );
349 g_pTimeLine->upper = ( GetCurrentCam()->GetCam()->getTotalTime() * 1000 );
352 gtk_clist_thaw( GTK_CLIST( g_pEventsList ) );
355 static gint ci_rename( GtkWidget *widget, gpointer data ){
356 GtkWidget *w, *hbox, *name;
357 EMessageBoxReturn ret;
360 if ( !GetCurrentCam() ) {
365 auto window = ui::Window( ui::window_type::TOP );
366 gtk_window_set_title( GTK_WINDOW( window ), "Rename Path" );
367 window.connect( "delete_event", G_CALLBACK( dialog_delete_callback ), NULL );
368 window.connect( "destroy", G_CALLBACK( gtk_widget_destroy ), NULL );
369 gtk_window_set_transient_for( GTK_WINDOW( window ), GTK_WINDOW( g_pCameraInspectorWnd ) );
371 g_object_set_data( G_OBJECT( window ), "loop", &loop );
372 g_object_set_data( G_OBJECT( window ), "ret", &ret );
374 gtk_widget_realize( window );
377 auto vbox = ui::VBox( FALSE, 5 );
381 // -------------------------- //
383 hbox = ui::HBox( FALSE, 5 );
384 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
385 gtk_widget_show( hbox );
387 w = ui::Label( "Name:" );
388 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 );
389 gtk_widget_show( w );
392 gtk_box_pack_start( GTK_BOX( hbox ), name, FALSE, FALSE, 0 );
393 gtk_widget_show( name );
395 if ( g_iActiveTarget < 0 ) {
396 gtk_entry_set_text( GTK_ENTRY( name ), GetCurrentCam()->GetCam()->getPositionObj()->getName() );
399 gtk_entry_set_text( GTK_ENTRY( name ), GetCurrentCam()->GetCam()->getActiveTarget( g_iActiveTarget )->getName() );
402 // -------------------------- //
404 w = gtk_hseparator_new();
405 gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 2 );
406 gtk_widget_show( w );
408 // -------------------------- //
410 hbox = ui::HBox( FALSE, 5 );
411 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
412 gtk_widget_show( hbox );
414 w = ui::Button( "Ok" );
415 gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 );
416 w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) );
417 gtk_widget_show( w );
419 gtk_widget_set_can_default( w, true );
420 gtk_widget_grab_default( w );
422 w = ui::Button( "Cancel" );
423 gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 );
424 w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) );
425 gtk_widget_show( w );
428 // -------------------------- //
430 gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER );
431 gtk_widget_show( window );
432 gtk_grab_add( window );
434 bool dialogError = TRUE;
435 while ( dialogError ) {
438 gtk_main_iteration();
442 if ( ret == eIDOK ) {
443 const char *str = gtk_entry_get_text( GTK_ENTRY( name ) );
445 if ( str && str[0] ) {
447 if ( g_iActiveTarget < 0 ) {
448 GetCurrentCam()->GetCam()->getPositionObj()->setName( str );
451 GetCurrentCam()->GetCam()->getActiveTarget( g_iActiveTarget )->setName( str );
454 GetCurrentCam()->GetCam()->buildCamera();
456 // Rebuild the listbox
457 RefreshPathListCombo();
465 gtk_grab_remove( window );
471 static gint ci_add_target( GtkWidget *widget, gpointer data ){
472 GtkWidget *w, *hbox, *name;
473 GtkWidget *fixed, *interpolated, *spline;
474 EMessageBoxReturn ret;
476 GSList *targetTypeRadio = NULL;
479 if ( !GetCurrentCam() ) {
484 auto window = ui::Window( ui::window_type::TOP );
485 gtk_window_set_title( GTK_WINDOW( window ), "Add Target" );
486 window.connect( "delete_event", G_CALLBACK( dialog_delete_callback ), NULL );
487 window.connect( "destroy", G_CALLBACK( gtk_widget_destroy ), NULL );
488 gtk_window_set_transient_for( GTK_WINDOW( window ), GTK_WINDOW( g_pCameraInspectorWnd ) );
490 g_object_set_data( G_OBJECT( window ), "loop", &loop );
491 g_object_set_data( G_OBJECT( window ), "ret", &ret );
493 gtk_widget_realize( window );
496 auto vbox = ui::VBox( FALSE, 5 );
500 // -------------------------- //
502 hbox = ui::HBox( FALSE, 5 );
503 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
504 gtk_widget_show( hbox );
506 w = ui::Label( "Name:" );
507 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 );
508 gtk_widget_show( w );
511 gtk_box_pack_start( GTK_BOX( hbox ), name, TRUE, TRUE, 0 );
512 gtk_widget_show( name );
514 sprintf( buf, "target%i", GetCurrentCam()->GetCam()->numTargets() + 1 );
515 gtk_entry_set_text( GTK_ENTRY( name ), buf );
517 // -------------------------- //
519 hbox = ui::HBox( FALSE, 5 );
520 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
521 gtk_widget_show( hbox );
523 auto frame = ui::Frame( "Type" );
524 gtk_box_pack_start( GTK_BOX( hbox ), frame, TRUE, TRUE, 0 );
525 gtk_widget_show( frame );
527 auto vbox2 = ui::VBox( FALSE, 5 );
529 gtk_container_set_border_width( GTK_CONTAINER( vbox2 ), 5 );
530 gtk_widget_show( vbox2 );
532 // -------------------------- //
534 fixed = gtk_radio_button_new_with_label( targetTypeRadio, "Fixed" );
535 gtk_box_pack_start( GTK_BOX( vbox2 ), fixed, FALSE, FALSE, 3 );
536 gtk_widget_show( fixed );
537 targetTypeRadio = gtk_radio_button_get_group( GTK_RADIO_BUTTON( fixed ) );
539 interpolated = gtk_radio_button_new_with_label( targetTypeRadio, "Interpolated" );
540 gtk_box_pack_start( GTK_BOX( vbox2 ), interpolated, FALSE, FALSE, 3 );
541 gtk_widget_show( interpolated );
542 targetTypeRadio = gtk_radio_button_get_group( GTK_RADIO_BUTTON( interpolated ) );
544 spline = gtk_radio_button_new_with_label( targetTypeRadio, "Spline" );
545 gtk_box_pack_start( GTK_BOX( vbox2 ), spline, FALSE, FALSE, 3 );
546 gtk_widget_show( spline );
547 targetTypeRadio = gtk_radio_button_get_group( GTK_RADIO_BUTTON( spline ) );
549 // -------------------------- //
551 w = gtk_hseparator_new();
552 gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 2 );
553 gtk_widget_show( w );
555 // -------------------------- //
557 hbox = ui::HBox( FALSE, 5 );
558 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
559 gtk_widget_show( hbox );
561 w = ui::Button( "Ok" );
562 gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 );
563 w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) );
564 gtk_widget_show( w );
566 gtk_widget_set_can_default( w, true );
567 gtk_widget_grab_default( w );
569 w = ui::Button( "Cancel" );
570 gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 );
571 w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) );
572 gtk_widget_show( w );
575 // -------------------------- //
577 gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER );
578 gtk_widget_show( window );
579 gtk_grab_add( window );
581 bool dialogError = TRUE;
582 while ( dialogError ) {
585 gtk_main_iteration();
589 if ( ret == eIDOK ) {
590 const char *str = gtk_entry_get_text( GTK_ENTRY( name ) );
592 if ( str && str[0] ) {
596 if ( gtk_toggle_button_get_active( (GtkToggleButton*)fixed ) ) {
599 else if ( gtk_toggle_button_get_active( (GtkToggleButton*)interpolated ) ) {
602 else if ( gtk_toggle_button_get_active( (GtkToggleButton*)spline ) ) {
607 GetCurrentCam()->GetCam()->addTarget( str, static_cast<idCameraPosition::positionType>( type ) );
609 // Rebuild the listbox
610 RefreshPathListCombo();
612 // Select the last item in the listbox
613 li = g_list_last( GTK_LIST( GTK_COMBO( g_pPathListCombo )->list )->children );
614 gtk_list_select_child( GTK_LIST( GTK_COMBO( g_pPathListCombo )->list ), GTK_WIDGET( li->data ) );
616 // If this was the first one, refresh the event list
617 if ( GetCurrentCam()->GetCam()->numTargets() == 1 ) {
621 // Go to editmode Add
622 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( g_pEditModeAddRadioButton ), TRUE );
631 gtk_grab_remove( window );
637 static GtkWidget *g_pCamListCombo = NULL;
638 static GtkLabel *g_pCamType = NULL;
640 void RefreshCamListCombo( void ){
641 if ( !g_pCamListCombo ) {
645 GList *combo_list = (GList*)NULL;
646 CCamera *combo_cam = firstCam;
648 while ( combo_cam ) {
649 //combo_list = g_list_append( combo_list, (void *)combo_cam->GetCam()->getName() );
650 //if( combo_cam->HasBeenSaved() ) {
651 combo_list = g_list_append( combo_list, (void *)combo_cam->GetFileName() );
654 sprintf( buf, "Unsaved Camera %i", combo_cam->GetCamNum() );
655 combo_list = g_list_append( combo_list, (void *)buf );
657 //combo_list = g_list_append( combo_list, (void *)combo_cam->GetCam()->getName() ); // FIXME: this requires camera.dll to create unique names for new cams
659 combo_cam = combo_cam->GetNext();
663 // add one empty string make gtk be quiet
664 combo_list = g_list_append( combo_list, (gpointer)g_cNull );
666 gtk_combo_set_popdown_strings( GTK_COMBO( g_pCamListCombo ), combo_list );
667 g_list_free( combo_list );
669 // select our current entry in the list
670 if ( GetCurrentCam() ) {
671 // stop editing on the current cam
672 //GetCurrentCam()->GetCam()->stopEdit(); // FIXME: this crashed on creating new cameras, why is it here?
674 GList *li = GTK_LIST( GTK_COMBO( g_pCamListCombo )->list )->children;
675 combo_cam = firstCam;
676 while ( li && combo_cam ) {
677 if ( combo_cam == GetCurrentCam() ) {
678 gtk_list_select_child( GTK_LIST( GTK_COMBO( g_pCamListCombo )->list ), GTK_WIDGET( li->data ) );
682 combo_cam = combo_cam->GetNext();
686 RefreshPathListCombo();
689 static gint ci_camlist_changed( GtkWidget *widget, gpointer data ){
690 const char *str = gtk_entry_get_text( GTK_ENTRY( widget ) );
692 CCamera *combo_cam = firstCam;
693 while ( str && combo_cam ) {
694 //if( !strcmp( str, combo_cam->GetCam()->getName() ) )
695 //if( combo_cam->HasBeenSaved() ) {
696 if ( !strcmp( str, combo_cam->GetFileName() ) ) {
701 sprintf( buf, "Unsaved Camera %i", combo_cam->GetCamNum() );
702 if( !strcmp( str, buf ) )
703 //if( !strcmp( str, combo_cam->GetCam()->getName() ) )
707 combo_cam = combo_cam->GetNext();
710 SetCurrentCam( combo_cam );
713 if ( GetCurrentCam() ) {
714 // Fill in our widgets fields for this camera
718 gtk_entry_set_text( GTK_ENTRY( g_pCamName ), GetCurrentCam()->GetCam()->getName() );
721 gtk_label_set_text( g_pCamType, GetCurrentCam()->GetCam()->getPositionObj()->typeStr() );
724 sprintf( buf, "%.2f", GetCurrentCam()->GetCam()->getBaseTime() );
725 gtk_entry_set_text( GTK_ENTRY( g_pSecondsEntry ), buf );
727 sprintf( buf, "%.2f", GetCurrentCam()->GetCam()->getTotalTime() );
728 gtk_label_set_text( g_pCurrentTime, "0.00" );
729 gtk_label_set_text( g_pTotalTime, buf );
731 gtk_adjustment_set_value( g_pTimeLine, 0.f );
732 g_pTimeLine->upper = GetCurrentCam()->GetCam()->getTotalTime() * 1000;
736 gtk_entry_set_text( GTK_ENTRY( g_pCamName ), "" );
739 gtk_label_set_text( g_pCamType, "" );
742 gtk_entry_set_text( GTK_ENTRY( g_pSecondsEntry ), "30.00" );
744 gtk_label_set_text( g_pCurrentTime, "0.00" );
745 gtk_label_set_text( g_pTotalTime, "30.00" );
747 gtk_adjustment_set_value( g_pTimeLine, 0.f );
748 g_pTimeLine->upper = 30000;
751 // Refresh event list
755 RefreshPathListCombo();
758 g_iActiveTarget = -1;
759 if ( g_pCameraInspectorWnd && gtk_widget_get_visible( g_pCameraInspectorWnd ) ) {
760 DoStartEdit( GetCurrentCam() );
771 EVENT_TARGET, // char(name)
773 EVENT_FOV, // int(time), int(targetfov)
778 EVENT_FADEOUT, // int(time)
779 EVENT_FADEIN, // int(time)
784 // { requires parameters, enabled }
785 const bool camEventFlags[][2] = {
802 const char *camEventStr[] = {
807 "Change Target <string:name>",
809 "FOV <int:duration> <int:targetfov>",
813 "Change to Camera <string:camera> (or <int:cameranum> <string:camera>",
814 "Fade Out <int:duration>",
815 "Fade In <int:duration>",
819 static gint ci_add( GtkWidget *widget, gpointer data ){
820 GtkWidget *w, *hbox, *parameters;
821 GtkWidget *eventWidget[EVENT_COUNT];
822 EMessageBoxReturn ret;
824 GSList *eventTypeRadio = NULL;
827 if ( !GetCurrentCam() ) {
832 auto window = ui::Window( ui::window_type::TOP );
833 gtk_window_set_title( GTK_WINDOW( window ), "Add Event" );
834 window.connect( "delete_event", G_CALLBACK( dialog_delete_callback ), NULL );
835 window.connect( "destroy", G_CALLBACK( gtk_widget_destroy ), NULL );
836 gtk_window_set_transient_for( GTK_WINDOW( window ), GTK_WINDOW( g_pCameraInspectorWnd ) );
838 g_object_set_data( G_OBJECT( window ), "loop", &loop );
839 g_object_set_data( G_OBJECT( window ), "ret", &ret );
841 gtk_widget_realize( window );
844 auto vbox = ui::VBox( FALSE, 5 );
848 // -------------------------- //
850 hbox = ui::HBox( FALSE, 5 );
851 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
852 gtk_widget_show( hbox );
854 auto frame = ui::Frame( "Type" );
855 gtk_box_pack_start( GTK_BOX( hbox ), frame, TRUE, TRUE, 0 );
856 gtk_widget_show( frame );
858 auto vbox2 = ui::VBox( FALSE, 5 );
860 gtk_container_set_border_width( GTK_CONTAINER( vbox2 ), 5 );
861 gtk_widget_show( vbox2 );
863 // -------------------------- //
865 for ( i = 1; i < EVENT_COUNT; i++ ) {
866 eventWidget[i] = gtk_radio_button_new_with_label( eventTypeRadio, camEventStr[i] );
867 gtk_box_pack_start( GTK_BOX( vbox2 ), eventWidget[i], FALSE, FALSE, 3 );
868 gtk_widget_show( eventWidget[i] );
869 eventTypeRadio = gtk_radio_button_get_group( GTK_RADIO_BUTTON( eventWidget[i] ) );
870 if ( camEventFlags[i][1] == false ) {
871 gtk_widget_set_sensitive( eventWidget[i], FALSE );
875 // -------------------------- //
877 hbox = ui::HBox( FALSE, 5 );
878 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
879 gtk_widget_show( hbox );
881 w = ui::Label( "Parameters:" );
882 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 );
883 gtk_widget_show( w );
885 parameters = ui::Entry();
886 gtk_box_pack_start( GTK_BOX( hbox ), parameters, TRUE, TRUE, 0 );
887 gtk_widget_show( parameters );
889 // -------------------------- //
891 w = gtk_hseparator_new();
892 gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 2 );
893 gtk_widget_show( w );
895 // -------------------------- //
897 hbox = ui::HBox( FALSE, 5 );
898 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
899 gtk_widget_show( hbox );
901 w = ui::Button( "Ok" );
902 gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 );
903 w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) );
904 gtk_widget_show( w );
906 gtk_widget_set_can_default( w, true );
907 gtk_widget_grab_default( w );
909 w = ui::Button( "Cancel" );
910 gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 );
911 w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) );
912 gtk_widget_show( w );
915 // -------------------------- //
917 gtk_window_set_position( GTK_WINDOW( window ),GTK_WIN_POS_CENTER );
918 gtk_widget_show( window );
919 gtk_grab_add( window );
921 bool dialogError = TRUE;
922 while ( dialogError ) {
925 gtk_main_iteration();
929 if ( ret == eIDOK ) {
930 const char *str = gtk_entry_get_text( GTK_ENTRY( parameters ) );
932 if ( !camEventFlags[i][0] || ( str && str[0] ) ) {
936 for ( type = 1; type < EVENT_COUNT; type++ ) {
937 if ( gtk_toggle_button_get_active( (GtkToggleButton*)eventWidget[type] ) ) {
943 GetCurrentCam()->GetCam()->addEvent( static_cast<idCameraEvent::eventType>( type ), str, (long)( g_pTimeLine->value ) );
945 // Refresh event list
954 gtk_grab_remove( window );
960 static gint ci_del( GtkWidget *widget, gpointer data ){
961 // TODO: add support to splines lib
962 if ( GetCurrentCam() && GTK_CLIST( g_pEventsList )->focus_row >= 0 ) {
963 GetCurrentCam()->GetCam()->removeEvent( GTK_CLIST( g_pEventsList )->focus_row );
964 // Refresh event list
971 static gint ci_timeline_changed( GtkAdjustment *adjustment ){
974 sprintf( buf, "%.2f", adjustment->value / 1000.f );
975 gtk_label_set_text( g_pCurrentTime, buf );
977 // FIXME: this will never work completely perfect. Startcamera calls buildcamera, which sets all events to 'nottriggered'.
978 // So if you have a wait at the end of the path, this will go to nontriggered immediately when you go over it and the camera
979 // will have no idea where on the track it should be.
980 if ( GetCurrentCam() && gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( g_pTrackCamera ) ) ) {
982 vec3_t origin = { 0.0f, 0.0f, 0.0f }, dir = { 0.0f, 0.0f, 0.0f}, angles;
984 GetCurrentCam()->GetCam()->startCamera( 0 );
986 GetCurrentCam()->GetCam()->getCameraInfo( (long)( adjustment->value ), &origin[0], &dir[0], &fov );
987 VectorSet( angles, asin( dir[2] ) * 180 / 3.14159, atan2( dir[1], dir[0] ) * 180 / 3.14159, 0 );
988 g_CameraTable.m_pfnSetCamera( origin, angles );
994 GtkWidget *CreateCameraInspectorDialog( void ){
998 auto window = ui::Window( ui::window_type::TOP );
999 gtk_window_set_title( GTK_WINDOW( window ), "Camera Inspector" );
1000 window.connect( "delete_event", G_CALLBACK( ci_close ), NULL );
1001 window.connect( "expose_event", G_CALLBACK( ci_expose ), NULL );
1002 // window.connect( "destroy", G_CALLBACK( gtk_widget_destroy ), NULL );
1003 gtk_window_set_transient_for( GTK_WINDOW( window ), GTK_WINDOW( g_pRadiantWnd ) );
1005 // don't use show, as you don't want to have it displayed on startup ;-)
1006 gtk_widget_realize( window );
1011 // -------------------------- //
1013 auto table = ui::Table( 3, 2, FALSE );
1016 gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1017 gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
1018 gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
1020 // the properties column
1021 // -------------------------- //
1023 vbox = ui::VBox( FALSE, 5 );
1024 gtk_widget_show( vbox );
1025 gtk_table_attach( GTK_TABLE( table ), vbox, 0, 1, 0, 1,
1026 (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1027 (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1029 // -------------------------- //
1031 hbox = ui::HBox( FALSE, 5 );
1032 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
1033 gtk_widget_show( hbox );
1035 w = ui::Label( "File:" );
1036 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 );
1037 gtk_widget_show( w );
1039 g_pCamListCombo = gtk_combo_new();
1040 gtk_box_pack_start( GTK_BOX( hbox ), g_pCamListCombo, TRUE, TRUE, 0 );
1041 gtk_widget_show( g_pCamListCombo );
1043 // -------------------------- //
1045 hbox = ui::HBox( FALSE, 5 );
1046 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
1047 gtk_widget_show( hbox );
1049 w = ui::Label( "Name:" );
1050 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 );
1051 gtk_widget_show( w );
1053 g_pCamName = ui::Entry();
1054 gtk_box_pack_start( GTK_BOX( hbox ), g_pCamName, FALSE, FALSE, 0 );
1055 gtk_widget_show( g_pCamName );
1057 w = ui::Label( "Type: " );
1058 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 );
1059 gtk_widget_show( w );
1061 w = ui::Label( "" );
1062 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 );
1063 gtk_widget_show( w );
1064 g_pCamType = GTK_LABEL( w );
1066 RefreshCamListCombo();
1068 gtk_editable_set_editable( GTK_EDITABLE( GTK_COMBO( g_pCamListCombo )->entry ), FALSE );
1069 ( GTK_COMBO( g_pCamListCombo )->entry ).connect( "changed", G_CALLBACK( ci_camlist_changed ), NULL );
1071 // -------------------------- //
1073 auto frame = ui::Frame( "Path and Target editing" );
1075 gtk_table_attach( GTK_TABLE( table ), frame, 0, 1, 1, 2,
1076 (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1077 (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1079 auto vbox = ui::VBox( FALSE, 5 );
1081 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1084 // -------------------------- //
1086 hbox = ui::HBox( FALSE, 5 );
1087 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
1088 gtk_widget_show( hbox );
1090 w = ui::Label( "Edit:" );
1091 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 );
1092 gtk_widget_show( w );
1094 g_pPathListCombo = gtk_combo_new();
1095 gtk_box_pack_start( GTK_BOX( hbox ), g_pPathListCombo, TRUE, TRUE, 0 );
1096 gtk_widget_show( g_pPathListCombo );
1098 RefreshPathListCombo();
1100 gtk_editable_set_editable( GTK_EDITABLE( GTK_COMBO( g_pPathListCombo )->entry ), FALSE );
1101 ( GTK_COMBO( g_pPathListCombo )->entry ).connect( "changed", G_CALLBACK( ci_pathlist_changed ), NULL );
1103 // -------------------------- //
1105 hbox = ui::HBox( FALSE, 5 );
1106 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
1107 gtk_widget_show( hbox );
1109 g_pEditModeEditRadioButton = gtk_radio_button_new_with_label( g_pEditTypeRadio, "Edit Points" );
1110 gtk_box_pack_start( GTK_BOX( hbox ), g_pEditModeEditRadioButton, FALSE, FALSE, 3 );
1111 gtk_widget_show( g_pEditModeEditRadioButton );
1112 g_pEditTypeRadio = gtk_radio_button_get_group( GTK_RADIO_BUTTON( g_pEditModeEditRadioButton ) );
1114 g_pEditModeEditRadioButton.connect( "clicked", G_CALLBACK( ci_editmode_edit ), NULL );
1116 g_pEditModeAddRadioButton = gtk_radio_button_new_with_label( g_pEditTypeRadio, "Add Points" );
1117 gtk_box_pack_start( GTK_BOX( hbox ), g_pEditModeAddRadioButton, FALSE, FALSE, 3 );
1118 gtk_widget_show( g_pEditModeAddRadioButton );
1119 g_pEditTypeRadio = gtk_radio_button_get_group( GTK_RADIO_BUTTON( g_pEditModeAddRadioButton ) );
1121 g_pEditModeAddRadioButton.connect( "clicked", G_CALLBACK( ci_editmode_add ), NULL );
1123 // see if we should use a different default
1124 if ( g_iEditMode == 1 ) {
1125 // Go to editmode Add
1126 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( g_pEditModeAddRadioButton ), TRUE );
1129 w = ui::Label( "Type: " );
1130 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 );
1131 gtk_widget_show( w );
1133 w = ui::Label( "" );
1134 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 );
1135 gtk_widget_show( w );
1136 g_pPathType = GTK_LABEL( w );
1138 // -------------------------- //
1140 hbox = ui::HBox( FALSE, 5 );
1141 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
1142 gtk_widget_show( hbox );
1144 w = ui::Button( "Rename..." );
1145 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, TRUE, 0 );
1146 w.connect( "clicked", G_CALLBACK( ci_rename ), NULL );
1147 gtk_widget_show( w );
1149 w = ui::Button( "Add Target..." );
1150 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, TRUE, 0 );
1151 w.connect( "clicked", G_CALLBACK( ci_add_target ), NULL );
1152 gtk_widget_show( w );
1154 // not available in splines library
1155 /*w = gtk_button_new_with_label( "Delete Selected" );
1156 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, TRUE, 0);
1157 w.connect( "clicked", G_CALLBACK( ci_delete_selected ), NULL );
1158 gtk_widget_show( w );
1160 w = gtk_button_new_with_label( "Select All" );
1161 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, TRUE, 0);
1162 w.connect( "clicked", G_CALLBACK( ci_select_all ), NULL );
1163 gtk_widget_show( w );*/
1165 // -------------------------- //
1167 frame = ui::Frame( "Time" );
1168 gtk_widget_show( frame );
1169 gtk_table_attach( GTK_TABLE( table ), frame, 0, 1, 2, 3,
1170 (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
1171 (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1173 vbox = ui::VBox( FALSE, 5 );
1175 gtk_container_set_border_width( GTK_CONTAINER( vbox ), 5 );
1178 // -------------------------- //
1180 hbox = ui::HBox( FALSE, 5 );
1181 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
1182 gtk_widget_show( hbox );
1184 w = ui::Label( "Length (seconds):" );
1185 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 );
1186 gtk_widget_show( w );
1188 g_pSecondsEntry = ui::Entry();
1189 gtk_box_pack_start( GTK_BOX( hbox ), g_pSecondsEntry, FALSE, FALSE, 0 );
1190 gtk_widget_show( g_pSecondsEntry );
1192 // -------------------------- //
1194 hbox = ui::HBox( FALSE, 5 );
1195 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
1196 gtk_widget_show( hbox );
1198 w = ui::Label( "Current Time: " );
1199 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 );
1200 gtk_widget_show( w );
1202 w = ui::Label( "0.00" );
1203 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 );
1204 gtk_widget_show( w );
1205 g_pCurrentTime = GTK_LABEL( w );
1207 w = ui::Label( " of " );
1208 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 );
1209 gtk_widget_show( w );
1211 w = ui::Label( "0.00" );
1212 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 );
1213 gtk_widget_show( w );
1214 g_pTotalTime = GTK_LABEL( w );
1216 // -------------------------- //
1218 hbox = ui::HBox( FALSE, 5 );
1219 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
1220 gtk_widget_show( hbox );
1222 g_pTimeLine = ui::Adjustment( 0, 0, 30000, 100, 250, 0 );
1223 g_pTimeLine.connect( "value_changed", G_CALLBACK( ci_timeline_changed ), NULL );
1224 w = ui::HScale( g_pTimeLine );
1225 gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 );
1226 gtk_widget_show( w );
1227 gtk_scale_set_draw_value( GTK_SCALE( w ), FALSE );
1229 // -------------------------- //
1231 hbox = ui::HBox( FALSE, 5 );
1232 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
1233 gtk_widget_show( hbox );
1235 g_pTrackCamera = ui::CheckButton( "Track Camera" );
1236 gtk_box_pack_start( GTK_BOX( hbox ), g_pTrackCamera, FALSE, FALSE, 0 );
1237 gtk_widget_show( g_pTrackCamera );
1239 // -------------------------- //
1241 hbox = ui::HBox( FALSE, 5 );
1242 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
1243 gtk_widget_show( hbox );
1245 w = ui::Label( "Events:" );
1246 gtk_box_pack_start( GTK_BOX( hbox ), w, FALSE, FALSE, 0 );
1247 gtk_widget_show( w );
1249 // -------------------------- //
1251 hbox = ui::HBox( FALSE, 5 );
1252 gtk_box_pack_start( GTK_BOX( vbox ), hbox, FALSE, FALSE, 0 );
1253 gtk_widget_show( hbox );
1255 auto scr = w = ui::ScrolledWindow();
1256 gtk_widget_set_size_request( w, 0, 150 );
1257 gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( w ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
1258 gtk_box_pack_start( GTK_BOX( hbox ), w, TRUE, TRUE, 0 );
1259 gtk_widget_show( w );
1261 g_pEventsList = gtk_clist_new( 3 );
1262 scr.add(g_pEventsList);
1263 //g_pEventsList.connect( "select_row", G_CALLBACK (proplist_select_row), NULL);
1264 gtk_clist_set_selection_mode( GTK_CLIST( g_pEventsList ), GTK_SELECTION_BROWSE );
1265 gtk_clist_column_titles_hide( GTK_CLIST( g_pEventsList ) );
1266 gtk_clist_set_column_auto_resize( GTK_CLIST( g_pEventsList ), 0, TRUE );
1267 gtk_clist_set_column_auto_resize( GTK_CLIST( g_pEventsList ), 1, TRUE );
1268 gtk_clist_set_column_auto_resize( GTK_CLIST( g_pEventsList ), 2, TRUE );
1269 gtk_widget_show( g_pEventsList );
1271 vbox = ui::VBox( FALSE, 5 );
1272 gtk_box_pack_start( GTK_BOX( hbox ), vbox, FALSE, FALSE, 0 );
1273 gtk_widget_show( vbox );
1275 w = ui::Button( "Add..." );
1276 gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 );
1277 w.connect( "clicked", G_CALLBACK( ci_add ), NULL );
1278 gtk_widget_show( w );
1280 w = ui::Button( "Del" );
1281 gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 );
1282 w.connect( "clicked", G_CALLBACK( ci_del ), NULL );
1283 gtk_widget_show( w );
1285 // -------------------------- //
1293 // the buttons column
1294 // -------------------------- //
1296 vbox = gtk_vbox_new( FALSE, 5 );
1297 gtk_widget_show( vbox );
1298 gtk_table_attach( GTK_TABLE( table ), vbox, 1, 2, 0, 1,
1299 (GtkAttachOptions) ( GTK_FILL ),
1300 (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1302 w = gtk_button_new_with_label( "New..." );
1303 gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 );
1304 w.connect( "clicked", G_CALLBACK( ci_new ), NULL );
1305 gtk_widget_show( w );
1307 w = gtk_button_new_with_label( "Load..." );
1308 gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 );
1309 w.connect( "clicked", G_CALLBACK( ci_load ), NULL );
1310 gtk_widget_show( w );
1312 // -------------------------- //
1314 vbox = gtk_vbox_new( FALSE, 5 );
1315 gtk_widget_show( vbox );
1316 gtk_table_attach( GTK_TABLE( table ), vbox, 1, 2, 1, 2,
1317 (GtkAttachOptions) ( GTK_FILL ),
1318 (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1320 w = gtk_button_new_with_label( "Save..." );
1321 gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 );
1322 w.connect( "clicked", G_CALLBACK( ci_save ), NULL );
1323 gtk_widget_show( w );
1325 w = gtk_button_new_with_label( "Unload" );
1326 gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 );
1327 w.connect( "clicked", G_CALLBACK( ci_unload ), NULL );
1328 gtk_widget_show( w );
1330 hbox = gtk_hbox_new( FALSE, 5 );
1331 gtk_box_pack_start( GTK_BOX( vbox ), hbox, TRUE, TRUE, 0 );
1332 gtk_widget_show( hbox );
1334 w = gtk_button_new_with_label( "Apply" );
1335 gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 );
1336 w.connect( "clicked", G_CALLBACK( ci_apply ), NULL );
1337 gtk_widget_show( w );
1339 w = gtk_button_new_with_label( "Preview" );
1340 gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 );
1341 w.connect( "clicked", G_CALLBACK( ci_preview ), NULL );
1342 gtk_widget_show( w );
1344 // -------------------------- //
1346 vbox = gtk_vbox_new( FALSE, 5 );
1347 gtk_widget_show( vbox );
1348 gtk_table_attach( GTK_TABLE( table ), vbox, 1, 2, 2, 3,
1349 (GtkAttachOptions) ( GTK_FILL ),
1350 (GtkAttachOptions) ( GTK_FILL ), 0, 0 );
1352 hbox = gtk_hbox_new( FALSE, 5 );
1353 gtk_box_pack_start( GTK_BOX( vbox ), hbox, TRUE, TRUE, 0 );
1354 gtk_widget_show( hbox );
1356 w = gtk_button_new_with_label( "Close" );
1357 gtk_box_pack_start( GTK_BOX( vbox ), w, FALSE, FALSE, 0 );
1358 w.connect( "clicked", G_CALLBACK( ci_close ), NULL );
1359 gtk_widget_set_can_default( w, true );
1360 gtk_widget_grab_default( w );
1361 gtk_widget_show( w );
1363 // -------------------------- //