00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
00009
00010
00011 #include "vgui_gtk_dialog_impl.h"
00012
00013 #include <vcl_string.h>
00014 #include <vcl_vector.h>
00015 #include <vcl_iostream.h>
00016 #include <vul/vul_sprintf.h>
00017
00018 #include <vgui/vgui_gl.h>
00019 #include <vgui/impl/gtk/vgui_gtk_adaptor.h>
00020 #include <vgui/internals/vgui_dialog_field.h>
00021 #include <vgui/internals/vgui_simple_field.h>
00022 #include <vgui/vgui_tableau_sptr.h>
00023 #include <gtk/gtkfilesel.h>
00024
00025 static bool debug = false;
00026 static bool is_modal = true;
00027
00028
00029
00030
00031 vgui_gtk_dialog_impl::vgui_gtk_dialog_impl(const char* name)
00032 : vgui_dialog_impl(name)
00033 {
00034 title = name;
00035 ok_text = "OK";
00036 cancel_text = "Cancel";
00037 }
00038
00039
00040
00041
00042 vgui_gtk_dialog_impl::~vgui_gtk_dialog_impl()
00043 {
00044 }
00045
00046
00047 struct vgui_gtk_dialog_impl_choice
00048 {
00049 vcl_vector<vcl_string> names;
00050 int index;
00051 };
00052
00053
00054
00055
00056 void* vgui_gtk_dialog_impl::choice_field_widget(const char* ,
00057 const vcl_vector<vcl_string>& labels,
00058 int& val)
00059 {
00060 vgui_gtk_dialog_impl_choice *ch = new vgui_gtk_dialog_impl_choice;
00061 ch->names = labels;
00062 ch->index = val;
00063
00064 return (void*)ch;
00065 }
00066
00067
00068
00069
00070
00071 void* vgui_gtk_dialog_impl::inline_tableau_widget(const vgui_tableau_sptr tab,
00072 unsigned width, unsigned height)
00073 {
00074 vgui_gtk_adaptor *ct = new vgui_gtk_adaptor();
00075 ct->set_tableau(tab);
00076 GtkWidget *glarea= (( vgui_gtk_adaptor *)ct)->get_glarea_widget();
00077 gtk_widget_set_usize(glarea, width, height);
00078 gtk_widget_show(glarea);
00079
00080 return (void*)ct;
00081 }
00082
00083
00084 extern "C" {
00085
00086 static
00087 void accept_cb(GtkWidget* ,
00088 gpointer data)
00089 {
00090 if (debug) vcl_cerr << "accept\n";
00091 vgui_gtk_dialog_impl::status_type* d = static_cast<vgui_gtk_dialog_impl::status_type*>(data);
00092 *d = vgui_gtk_dialog_impl::OK;
00093 }
00094
00095 static
00096 void cancel_cb(GtkWidget* ,
00097 gpointer data)
00098 {
00099 if (debug) vcl_cerr << "cancel\n";
00100 vgui_gtk_dialog_impl::status_type* d = static_cast<vgui_gtk_dialog_impl::status_type*>(data);
00101 *d = vgui_gtk_dialog_impl::CANCEL;
00102 }
00103
00104 static
00105 gint close_window_cb(GtkWidget* ,
00106 GdkEvent* ,
00107 gpointer data)
00108 {
00109 if (debug) vcl_cerr << "close window\n";
00110 vgui_gtk_dialog_impl::status_type* d = static_cast<vgui_gtk_dialog_impl::status_type*>(data);
00111 *d = vgui_gtk_dialog_impl::CLOSE;
00112 return FALSE;
00113 }
00114
00115 struct vgui_gtk_dialog_impl_int_pair
00116 {
00117 int* val;
00118 int tmp;
00119 };
00120
00121
00122 void choose_cb(GtkWidget* ,
00123 gpointer data)
00124 {
00125 vgui_gtk_dialog_impl_int_pair *ip = (vgui_gtk_dialog_impl_int_pair*) data;
00126 *(ip->val) = ip->tmp;
00127 if (debug) vcl_cerr << "choose " << (ip->tmp) << vcl_endl;
00128 }
00129
00130 }
00131
00132
00133
00134
00135
00136 void vgui_gtk_dialog_impl::modal(const bool m)
00137 {
00138 is_modal = m;
00139 }
00140
00141 void vgui_gtk_dialog_impl::set_ok_button(const char* txt)
00142 {
00143 if (txt)
00144 ok_text = vcl_string(txt);
00145 else
00146 ok_text = vcl_string("REMOVEBUTTON");
00147 }
00148
00149 void vgui_gtk_dialog_impl::set_cancel_button(const char* txt)
00150 {
00151 if (txt)
00152 cancel_text = vcl_string(txt);
00153 else
00154 cancel_text = vcl_string("REMOVEBUTTON");
00155 }
00156
00157 extern "C" {
00158
00159 struct file_ok_data
00160 {
00161 GtkFileSelection* filew;
00162 GtkEntry* file_entry;
00163 };
00164
00165
00166
00167 void ok_file_browse(file_ok_data* data)
00168 {
00169 gtk_entry_set_text( data->file_entry,
00170 gtk_file_selection_get_filename(data->filew) );
00171 gtk_widget_destroy( GTK_WIDGET(data->filew) );
00172 delete data;
00173 }
00174
00175
00176
00177 void cancel_file_browse(file_ok_data* data)
00178 {
00179 gtk_widget_destroy( GTK_WIDGET(data->filew) );
00180 delete data;
00181 }
00182
00183
00184
00185 void browse_files(GtkWidget* , GtkEntry* file_entry)
00186 {
00187 GtkFileSelection* filew = GTK_FILE_SELECTION( gtk_file_selection_new ("File selection") );
00188
00189 file_ok_data* data = new file_ok_data;
00190 data->filew = filew;
00191 data->file_entry = file_entry;
00192
00193 gtk_signal_connect_object (GTK_OBJECT(filew->cancel_button), "clicked",
00194 (GtkSignalFunc) cancel_file_browse, (GtkObject*)(data));
00195 gtk_signal_connect_object (GTK_OBJECT(filew->ok_button), "clicked",
00196 (GtkSignalFunc) ok_file_browse, (GtkObject*)(data));
00197
00198 gtk_file_selection_set_filename (filew, gtk_entry_get_text(file_entry));
00199
00200
00201 gtk_file_selection_hide_fileop_buttons(filew);
00202
00203 gtk_window_set_modal(GTK_WINDOW(filew), is_modal);
00204 gtk_widget_show( GTK_WIDGET(filew) );
00205 }
00206
00207
00208
00209
00210 void color_changed_cb(GtkColorSelection *colorsel, GtkEntry* color_entry)
00211 {
00212
00213 gdouble color[4];
00214 gtk_color_selection_get_color(colorsel, color);
00215
00216 vul_sprintf color_str("%.3f %.3f %.3f", color[0], color[1], color[2]);
00217
00218
00219 gtk_entry_set_text(GTK_ENTRY(color_entry), color_str.c_str());
00220 }
00221
00222
00223 struct cancel_color_data
00224 {
00225 vcl_string* orig_color;
00226 GtkEntry* color_entry;
00227 GtkColorSelectionDialog* colord;
00228 };
00229
00230
00231
00232
00233 void ok_color_chooser(cancel_color_data* data)
00234 {
00235 gtk_widget_destroy(GTK_WIDGET(data->colord));
00236 delete data->orig_color;
00237 delete data;
00238 }
00239
00240
00241
00242
00243
00244 void cancel_color_chooser(cancel_color_data* data)
00245 {
00246 gtk_entry_set_text(GTK_ENTRY(data->color_entry), data->orig_color->c_str());
00247
00248 gtk_widget_destroy(GTK_WIDGET(data->colord));
00249 delete data->orig_color;
00250 delete data;
00251 }
00252
00253
00254
00255 void choose_color(GtkWidget* , GtkEntry* color_entry)
00256 {
00257 GtkColorSelectionDialog* colord = GTK_COLOR_SELECTION_DIALOG( gtk_color_selection_dialog_new("Select color") );
00258 gtk_widget_hide( GTK_WIDGET(colord->help_button) );
00259
00260 cancel_color_data* data = new cancel_color_data;
00261 data->orig_color = new vcl_string(gtk_entry_get_text(GTK_ENTRY(color_entry)));
00262 data->color_entry = color_entry;
00263 data->colord = colord;
00264
00265 gtk_signal_connect(GTK_OBJECT(colord->colorsel), "color_changed",
00266 (GtkSignalFunc)color_changed_cb, color_entry);
00267 gtk_signal_connect_object (GTK_OBJECT(colord->cancel_button), "clicked",
00268 (GtkSignalFunc)cancel_color_chooser, (GtkObject*)data);
00269 gtk_signal_connect_object (GTK_OBJECT(colord->ok_button), "clicked",
00270 (GtkSignalFunc)ok_color_chooser, (GtkObject*)data);
00271
00272 gtk_window_set_modal(GTK_WINDOW(colord), is_modal);
00273 gtk_widget_show(GTK_WIDGET(colord));
00274 }
00275
00276 }
00277
00278
00279
00280 bool vgui_gtk_dialog_impl::ask()
00281 {
00282 GtkWidget* dialog = gtk_dialog_new();
00283
00284 gtk_window_set_title(GTK_WINDOW(dialog), title.c_str());
00285 gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
00286 gtk_window_set_modal(GTK_WINDOW(dialog), is_modal);
00287
00288 if (ok_text.compare("REMOVEBUTTON"))
00289 {
00290 GtkWidget *accept = gtk_button_new_with_label (ok_text.c_str());
00291 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area),
00292 accept, TRUE, TRUE, 0);
00293 gtk_signal_connect(GTK_OBJECT(accept), "clicked",
00294 GTK_SIGNAL_FUNC(accept_cb),
00295 &dialog_status_);
00296 gtk_widget_show(accept);
00297 }
00298 if (cancel_text.compare("REMOVEBUTTON"))
00299 {
00300 GtkWidget *cancel = gtk_button_new_with_label (cancel_text.c_str());
00301 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area),
00302 cancel, TRUE, TRUE, 0);
00303 gtk_signal_connect(GTK_OBJECT(cancel), "clicked",
00304 GTK_SIGNAL_FUNC(cancel_cb),
00305 &dialog_status_);
00306 gtk_widget_show(cancel);
00307 }
00308
00309
00310
00311 gtk_signal_connect(GTK_OBJECT(dialog), "delete_event",
00312 GTK_SIGNAL_FUNC(close_window_cb),
00313 &dialog_status_);
00314
00315
00316 vcl_vector<GtkWidget*> wlist;
00317
00318
00319 vcl_vector<vgui_gtk_adaptor*> adaptor_list;
00320
00321
00322 vcl_vector<GtkWidget*> delete_wlist;
00323
00324 for (vcl_vector<element>::iterator e_iter = elements.begin();
00325 e_iter != elements.end(); ++e_iter) {
00326
00327 element l = *e_iter;
00328 vgui_dialog_field *field = l.field;
00329
00330 GtkWidget* entry;
00331
00332 if (l.type == int_elem ||
00333 l.type == long_elem ||
00334 l.type == float_elem ||
00335 l.type == double_elem ||
00336 l.type == string_elem) {
00337
00338 GtkWidget* hbox = gtk_hbox_new(FALSE, 10);
00339 GtkWidget* label = gtk_label_new(field->label.c_str());
00340 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
00341
00342 entry = gtk_entry_new_with_max_length(50);
00343 gtk_entry_set_text(GTK_ENTRY(entry), l.field->current_value().c_str());
00344
00345 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
00346 gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 5);
00347 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 0);
00348
00349 gtk_widget_show(label);
00350 gtk_widget_show(entry);
00351 gtk_widget_show(hbox);
00352 wlist.push_back(entry);
00353 }
00354 else if (l.type == bool_elem) {
00355 vgui_bool_field *field = static_cast<vgui_bool_field*>(l.field);
00356 entry = gtk_check_button_new_with_label(field->label.c_str());
00357 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(entry), field->var);
00358 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), entry, TRUE, TRUE, 0);
00359 gtk_widget_show(entry);
00360 wlist.push_back(entry);
00361 }
00362 else if (l.type == choice_elem) {
00363 vgui_int_field *field = static_cast<vgui_int_field*>(l.field);
00364
00365 GtkWidget* hbox = gtk_hbox_new(FALSE, 10);
00366 GtkWidget* label = gtk_label_new(field->label.c_str());
00367 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
00368
00369 entry = gtk_option_menu_new();
00370 GtkWidget* menu = gtk_menu_new();
00371
00372
00373 vgui_gtk_dialog_impl_choice *ch = (vgui_gtk_dialog_impl_choice*)l.widget;
00374
00375 int count = 0;
00376 for (vcl_vector<vcl_string>::iterator s_iter = ch->names.begin();
00377 s_iter != ch->names.end(); ++s_iter, ++count) {
00378
00379 GtkWidget* item = gtk_menu_item_new_with_label(s_iter->c_str());
00380 gtk_widget_show(item);
00381 gtk_menu_append(GTK_MENU(menu), item);
00382
00383 vgui_gtk_dialog_impl_int_pair *ip = new vgui_gtk_dialog_impl_int_pair;
00384 ip->val = &(ch->index);
00385 ip->tmp = count;
00386
00387 gtk_signal_connect(GTK_OBJECT(item), "activate",
00388 GTK_SIGNAL_FUNC(choose_cb), ip);
00389 }
00390
00391 gtk_option_menu_set_menu(GTK_OPTION_MENU(entry), menu);
00392 gtk_option_menu_set_history(GTK_OPTION_MENU(entry), field->var);
00393
00394 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
00395 gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 5);
00396 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 0);
00397
00398 gtk_widget_show(label);
00399 gtk_widget_show(entry);
00400 gtk_widget_show(hbox);
00401 wlist.push_back(entry);
00402 }
00403 else if (l.type == text_msg) {
00404 GtkWidget* label = gtk_label_new(field->label.c_str());
00405 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0);
00406 gtk_widget_show(label);
00407 wlist.push_back(entry);
00408 }
00409 else if (l.type == file_bsr){
00410 GtkWidget* hbox = gtk_hbox_new(FALSE, 10);
00411 GtkWidget* label = gtk_label_new(field->label.c_str());
00412 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
00413 GtkWidget* button = gtk_button_new_with_label("Choose file...");
00414 GtkWidget* entry = gtk_entry_new_with_max_length(150);
00415 gtk_entry_set_text(GTK_ENTRY(entry), l.field->current_value().c_str());
00416
00417 gtk_signal_connect (GTK_OBJECT (button), "clicked",
00418 GTK_SIGNAL_FUNC (browse_files), (gpointer)entry);
00419 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
00420 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
00421 gtk_box_pack_start(GTK_BOX(hbox), button,TRUE,TRUE, 0);
00422
00423 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 0);
00424 gtk_widget_show(label);
00425 gtk_widget_show(entry);
00426 gtk_widget_show(button);
00427 gtk_widget_show(hbox);
00428 wlist.push_back(entry);
00429 }
00430 else if (l.type == inline_file_bsr) {
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441 GtkWidget* filew = gtk_file_selection_new ("File selection");
00442 gtk_file_selection_set_filename (GTK_FILE_SELECTION(filew),
00443 l.field->current_value().c_str());
00444
00445
00446 gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(filew));
00447
00448 gtk_widget_hide(GTK_FILE_SELECTION(filew)->ok_button);
00449 gtk_widget_hide(GTK_FILE_SELECTION(filew)->cancel_button);
00450
00451 GtkWidget* file_main_vbox = GTK_FILE_SELECTION(filew)->main_vbox;
00452
00453 gtk_widget_ref( file_main_vbox );
00454 gtk_container_remove( GTK_CONTAINER(filew), file_main_vbox);
00455 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), file_main_vbox, TRUE, TRUE, 0);
00456 gtk_widget_unref( file_main_vbox );
00457
00458 gtk_widget_show( file_main_vbox );
00459 wlist.push_back(filew);
00460 delete_wlist.push_back(filew);
00461 }
00462 else if (l.type == color_csr){
00463 GtkWidget* hbox = gtk_hbox_new(FALSE, 10);
00464 GtkWidget* label = gtk_label_new(field->label.c_str());
00465 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
00466 GtkWidget* button = gtk_button_new_with_label("Choose color...");
00467 GtkWidget* entry = gtk_entry_new_with_max_length(50);
00468 gtk_entry_set_text(GTK_ENTRY(entry), l.field->current_value().c_str());
00469
00470 gtk_signal_connect (GTK_OBJECT (button), "clicked",
00471 GTK_SIGNAL_FUNC (choose_color), entry);
00472 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
00473 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
00474 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
00475 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 0);
00476
00477 gtk_widget_show(label);
00478 gtk_widget_show(entry);
00479 gtk_widget_show(button);
00480 gtk_widget_show(hbox);
00481 wlist.push_back(entry);
00482 }
00483 else if (l.type == inline_color_csr) {
00484 GtkWidget* colorw = gtk_color_selection_new();
00485 GtkWidget* color_entry = gtk_entry_new_with_max_length(50);
00486
00487 gtk_entry_set_text(GTK_ENTRY(color_entry),
00488 l.field->current_value().c_str());
00489 gtk_signal_connect(GTK_OBJECT(colorw), "color_changed",
00490 (GtkSignalFunc)color_changed_cb, color_entry);
00491
00492 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), colorw, TRUE,
00493 TRUE, 0);
00494 gtk_widget_show(colorw);
00495
00496
00497
00498 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), color_entry, TRUE,
00499 TRUE, 0);
00500 gtk_widget_hide(color_entry);
00501 wlist.push_back(color_entry);
00502 }
00503 else if (l.type == inline_tabl) {
00504 vgui_gtk_adaptor* adapt = static_cast<vgui_gtk_adaptor*>(l.widget);
00505 GtkWidget* widg = adapt->get_glarea_widget();
00506 GtkWidget* hbox = gtk_hbox_new(FALSE, 10);
00507
00508 gtk_box_pack_start(GTK_BOX(hbox), widg, TRUE, TRUE, 0);
00509 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 0);
00510 gtk_widget_show(hbox);
00511 wlist.push_back(widg);
00512 adaptor_list.push_back( adapt );
00513 }
00514 else
00515 vcl_cerr << "Unknown type = " << int(l.type) << vcl_endl;
00516 }
00517
00518 gtk_widget_show(dialog);
00519
00520 dialog_status_ = BUSY;
00521
00522 while ( dialog_status_ == BUSY ) {
00523 gtk_main_iteration();
00524 }
00525
00526
00527
00528
00529
00530
00531 for ( vcl_vector<vgui_gtk_adaptor*>::iterator iter = adaptor_list.begin();
00532 iter != adaptor_list.end(); ++iter ) {
00533 delete *iter;
00534 }
00535
00536
00537
00538 bool ret_value = false;
00539 if (dialog_status_ == CLOSE) {
00540
00541
00542 }
00543 else if (dialog_status_ == OK)
00544 {
00545 vcl_vector<GtkWidget*>::iterator w_iter = wlist.begin();
00546 for (vcl_vector<element>::iterator e_iter = elements.begin();
00547 e_iter != elements.end(); ++e_iter, ++w_iter) {
00548 element l = *e_iter;
00549 if (l.type == int_elem ||
00550 l.type == long_elem ||
00551 l.type == float_elem ||
00552 l.type == double_elem ||
00553 l.type == string_elem ||
00554 l.type == file_bsr ||
00555 l.type == color_csr ||
00556 l.type == inline_color_csr) {
00557 GtkWidget *input = *w_iter;
00558 l.field->update_value(gtk_entry_get_text(GTK_ENTRY(input)));
00559 }
00560 if (l.type == inline_file_bsr)
00561 l.field->update_value(gtk_file_selection_get_filename(GTK_FILE_SELECTION(*w_iter)));
00562
00563 if (l.type == bool_elem) {
00564 vgui_bool_field *field = static_cast<vgui_bool_field*>(l.field);
00565 GtkWidget *input = *w_iter;
00566 field->var = (bool) gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(input));
00567 }
00568 if (l.type == choice_elem) {
00569 vgui_int_field *field = static_cast<vgui_int_field*>(l.field);
00570 vgui_gtk_dialog_impl_choice *ch = static_cast<vgui_gtk_dialog_impl_choice*>(l.widget);
00571 field->var = ch->index;
00572 }
00573 }
00574
00575 glFlush();
00576 gtk_widget_destroy(dialog);
00577
00578 ret_value = true;
00579 }
00580 else
00581 {
00582 gtk_widget_destroy(dialog);
00583 }
00584
00585
00586 for ( vcl_vector<GtkWidget*>::iterator iter = delete_wlist.begin();
00587 iter != delete_wlist.end(); ++iter ) {
00588 gtk_widget_destroy( *iter );
00589 }
00590
00591 return ret_value;
00592 }