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