00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
00009
00010
00011
00012 #include "vgui_mfc_dialog_impl.h"
00013
00014 #include <vcl_string.h>
00015 #include <vcl_iostream.h>
00016 #include <vcl_vector.h>
00017 #include <vcl_cstdio.h>
00018 #include <vcl_cstring.h>
00019
00020 #include <vgui/internals/vgui_dialog_field.h>
00021 #include <vgui/internals/vgui_simple_field.h>
00022 #include <vgui/impl/mfc/vgui_mfc_adaptor.h>
00023 #include <winuser.h>
00024
00025 static bool debug = false;
00026
00027 CString TempsNewClass;
00028 BEGIN_MESSAGE_MAP(vgui_mfc_dialog_impl, CDialog)
00029 ON_COMMAND(IDOK,OnOk)
00030 ON_COMMAND(IDCANCEL,OnCancel)
00031 ON_WM_CLOSE()
00032 ON_CONTROL_RANGE(BN_CLICKED,ID_BROWSE_FILES,ID_BROWSE_FILES+100, OnBrowse)
00033 ON_CONTROL_RANGE(BN_CLICKED,ID_CHOOSE_COLOUR,ID_CHOOSE_COLOUR+100,OnChooseColour)
00034 END_MESSAGE_MAP()
00035
00036
00037
00038 vgui_mfc_dialog_impl::vgui_mfc_dialog_impl(const char* name)
00039 : CDialog(),vgui_dialog_impl(name)
00040 {
00041
00042 count_fbsr = 0;
00043 count_csr = 0;
00044 nResult = 0;
00045 ok_clicked = false;
00046 }
00047
00048
00049
00050 vgui_mfc_dialog_impl::~vgui_mfc_dialog_impl()
00051 {
00052 }
00053
00054
00055 struct vgui_mfc_dialog_choice
00056 {
00057 vcl_vector<vcl_string> names;
00058 int index;
00059 };
00060
00061
00062
00063
00064 void* vgui_mfc_dialog_impl::choice_field_widget(const char* ,
00065 const vcl_vector<vcl_string>& labels, int& val) {
00066
00067 vgui_mfc_dialog_choice *ch = new vgui_mfc_dialog_choice;
00068 ch->names = labels;
00069 ch->index = val;
00070
00071 return (void*)ch;
00072 }
00073
00074
00075 struct vgui_mfc_dialog_inline_tab
00076 {
00077 vgui_tableau_sptr tab;
00078 unsigned height;
00079 unsigned width;
00080 };
00081
00082
00083
00084 void* vgui_mfc_dialog_impl::inline_tableau_widget(const vgui_tableau_sptr tab,
00085 unsigned width, unsigned height)
00086 {
00087 vgui_mfc_dialog_inline_tab* tab_data = new vgui_mfc_dialog_inline_tab;
00088 tab_data->tab = tab;
00089 tab_data->height = height;
00090 tab_data->width = width;
00091 TempsNewClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_OWNDC|CS_GLOBALCLASS);
00092 return (void*)tab_data;
00093 }
00094
00095 #if 0 // is_modal is not used anywhere
00096
00097
00098
00099
00100 static bool is_modal = true;
00101 void vgui_mfc_dialog_impl::modal(bool m)
00102 {
00103 is_modal = m;
00104 }
00105 #endif // 0
00106
00107
00108 void vgui_mfc_dialog_impl::OnOk()
00109 {
00110 ASSERT(::IsWindow(m_hWnd));
00111
00112 if (m_nFlags & (WF_MODALLOOP|WF_CONTINUEMODAL))
00113 EndModalLoop(nResult);
00114
00115 ::EndDialog(m_hWnd, nResult);
00116 ok_clicked = true;
00117 }
00118
00119
00120 void vgui_mfc_dialog_impl::OnCancel()
00121 {
00122 ASSERT(::IsWindow(m_hWnd));
00123
00124 if (m_nFlags & (WF_MODALLOOP|WF_CONTINUEMODAL))
00125 EndModalLoop(nResult);
00126
00127 ::EndDialog(m_hWnd, nResult);
00128 }
00129
00130
00131
00132 void vgui_mfc_dialog_impl::OnBrowse(UINT uID)
00133 {
00134 int which = uID-ID_BROWSE_FILES;
00135 ASSERT(which>=0 && which<100);
00136 vcl_cerr<<"File browser loading...";
00137 CFileDialog file_dialog(TRUE,"*.*",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "All Files (*.*)|*.*||", this);
00138 file_dialog.DoModal();
00139 CString s(file_dialog.GetPathName());
00140 fbsrs[which]->SetWindowText(s);
00141 }
00142
00143
00144
00145 void vgui_mfc_dialog_impl::OnChooseColour(UINT uID)
00146 {
00147 char buffer[20];
00148 int which = uID-ID_CHOOSE_COLOUR;
00149 ASSERT(which>=0 && which<100);
00150 vcl_cerr<<"File browser loading...";
00151 CColorDialog colour_dialog(0,0, this);
00152 colour_dialog.DoModal();
00153 COLORREF colour = colour_dialog.GetColor();
00154 vcl_sprintf(buffer,"%4.3f",float(colour&0xff)/255.0);
00155 CString s(buffer);
00156 s+=" ";
00157 vcl_sprintf(buffer,"%4.3f",float((colour>>8)&0xff)/255.0);
00158 s+=buffer;
00159 s+=" ";
00160 vcl_sprintf(buffer,"%4.3f",float((colour>>16)&0xff)/255.0);
00161 s+=buffer;
00162 csrs[which]->SetWindowText(s);
00163 }
00164
00165
00166 void vgui_mfc_dialog_impl::OnClose()
00167 {
00168 OnCancel();
00169 }
00170
00171
00172 bool vgui_mfc_dialog_impl::ask()
00173 {
00174
00175 CWnd *main_window = AfxGetApp()->GetMainWnd();
00176
00177
00178 int width, max_length = 0,fbsr_count = 0;
00179 int height = 45 + 6*8;
00180
00181 for (vcl_vector<element>::iterator e_iter1 = elements.begin();
00182 e_iter1 != elements.end(); ++e_iter1)
00183 {
00184 element l = *e_iter1;
00185 vgui_dialog_field *field = l.field;
00186
00187 if (l.type == bool_elem)
00188 {
00189 vgui_bool_field *field = static_cast<vgui_bool_field*>(l.field);
00190 int field_length = vcl_strlen(field->label.c_str());
00191 if (max_length<field_length)
00192 max_length = field_length;
00193 height += 45;
00194 }
00195 else if (l.type == inline_tabl)
00196 {
00197 vgui_mfc_dialog_inline_tab* tab_data = (vgui_mfc_dialog_inline_tab*)l.widget;
00198 if (max_length < int(tab_data->width/8 + 5))
00199 max_length = int((7+tab_data->width)/8) + 5;
00200 height += int(tab_data->height) + 20;
00201 }
00202 else if (l.type == text_msg)
00203 {
00204 vgui_int_field *field = static_cast<vgui_int_field*>(l.field);
00205 if (max_length<int(field->label.size()+field->current_value().size()))
00206 max_length = field->label.size()+field->current_value().size();
00207 height += 45;
00208 }
00209 else
00210 {
00211
00212
00213 int field_length = vcl_strlen(field->label.c_str()) + 40;
00214 if (max_length<field_length)
00215 max_length = field_length;
00216 height += 45;
00217 }
00218
00219 if (l.type == file_bsr || l.type == inline_file_bsr ||
00220 l.type == color_csr || l.type == inline_color_csr)
00221 {
00222 fbsr_count++;
00223 height += 45;
00224 }
00225 }
00226
00227
00228 width = 8*max_length;
00229
00230 if (width < 200)
00231 width = 200;
00232 max_length = max_length - 40;
00233
00234 fbsr_count++;
00235
00236
00237 CreateEx(WS_EX_CONTROLPARENT,
00238 AfxRegisterWndClass(0,::LoadCursor(NULL, IDC_ARROW),(HBRUSH)(COLOR_WINDOW)),
00239 _T(vgui_dialog_impl::name.c_str()),
00240 WS_CAPTION|WS_VISIBLE|WS_SYSMENU|WS_POPUP|DS_MODALFRAME,
00241 100, 100, width, height, NULL, NULL, 0);
00242 UpdateWindow();
00243 ShowWindow(SW_SHOW);
00244
00245
00246 vcl_memset(&m_logfont, 0, sizeof m_logfont);
00247 m_logfont.lfHeight = -8;
00248 lstrcpy(m_logfont.lfFaceName, _T("Microsoft Sans Serif Regular"));
00249 m_logfont.lfOutPrecision = OUT_TT_PRECIS;
00250 m_logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
00251 m_logfont.lfQuality = PROOF_QUALITY;
00252 m_logfont.lfPitchAndFamily = FF_SWISS | VARIABLE_PITCH;
00253 m_logfont.lfHeight = -::MulDiv(-m_logfont.lfHeight,GetDC()->GetDeviceCaps(LOGPIXELSY), 72);
00254 font = new CFont();
00255 font->CreateFontIndirect(&m_logfont);
00256 SetFont(font);
00257
00258
00259
00260
00261 CButton* accept = 0;
00262 int right_of_ok_button;
00263 if (ok_button_text_.size() > 0)
00264 {
00265 CRect r;
00266 r.left = width-2*10*8-3*8;
00267 r.right = r.left+10*8;
00268 r.top = height-9*8;
00269 r.bottom = height-5*8;
00270 right_of_ok_button = r.right;
00271 accept = new CButton();
00272 accept->Create(_T(ok_button_text_.c_str()),
00273 WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_PUSHBUTTON,
00274 r,this,IDOK);
00275 accept->SetFocus();
00276 accept->SetFont(font);
00277 }
00278
00279
00280 CButton* cancel = 0;
00281 if (cancel_button_text_.size() > 0)
00282 {
00283 CRect r;
00284 r.left = right_of_ok_button+1*8;
00285 r.right = r.left+10*8;
00286 r.top = height-9*8;
00287 r.bottom = height-5*8;
00288 cancel = new CButton();
00289 cancel->Create(_T(cancel_button_text_.c_str()),
00290 WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_PUSHBUTTON,
00291 r,this,IDCANCEL);
00292 cancel->SetFont(font);
00293 }
00294
00295
00296 CRect r;
00297 r.left = 999;
00298 r.right = 999;
00299 r.top = 0;
00300 r.bottom = 3*8+2;
00301 for (vcl_vector<element>::iterator e_iter2 = elements.begin();
00302 e_iter2 != elements.end(); ++e_iter2)
00303 {
00304 element l = *e_iter2;
00305 vgui_dialog_field *field = l.field;
00306
00307 if (l.type == int_elem ||
00308 l.type == long_elem ||
00309 l.type == float_elem ||
00310 l.type == double_elem ||
00311 l.type == string_elem)
00312 {
00313
00314 r.left = 2*4;
00315 r.top+=4*8;
00316 r.bottom+=4*8;
00317 r.right = r.left+field->label.size()*8;
00318
00319 CStatic *text = new CStatic();
00320 text->Create(_T(field->label.c_str()),WS_CHILD|WS_VISIBLE|SS_LEFT,r,this);
00321 text->SetFont(font);
00322 awlist.push_back(text);
00323
00324 CEdit *edit = new CEdit();
00325 r.left = width-2*8-20*8;
00326 r.left = 2*4+max_length*8+2*8;
00327 r.right = width-2*8;
00328
00329
00330
00331
00332 edit->CreateEx(WS_EX_CLIENTEDGE,_T("EDIT"),NULL,
00333 WS_CHILD|WS_BORDER|WS_TABSTOP|ES_LEFT|ES_AUTOHSCROLL,r,this,IDOK);
00334 edit->SetFont(font);
00335 edit->SetWindowText(l.field->current_value().c_str());
00336 edit->UpdateWindow();
00337 edit->ShowWindow(SW_SHOW);
00338 text->UpdateWindow();
00339 text->ShowWindow(SW_SHOW);
00340 awlist.push_back(edit);
00341 wlist.push_back(edit);
00342 }
00343 else if (l.type == bool_elem)
00344 {
00345 r.left = 2*4;
00346 r.top+=5*8;
00347 r.bottom+=5*8;
00348 r.right = r.left+(field->label.size()+3)*8;
00349 vgui_bool_field *field = static_cast<vgui_bool_field*>(l.field);
00350 CButton *checkbox = new CButton();
00351 checkbox->Create(_T(field->label.c_str()),
00352 WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX, r,this,4);
00353 checkbox->SetFont(font);
00354 checkbox->SetCheck(field->var);
00355 checkbox->UpdateWindow();
00356 checkbox->ShowWindow(SW_SHOW);
00357 awlist.push_back(checkbox);
00358 wlist.push_back(checkbox);
00359 }
00360 else if (l.type == choice_elem)
00361 {
00362 vgui_int_field *field = static_cast<vgui_int_field*>(l.field);
00363 r.left = 2*4;
00364 r.top+=4*8;
00365 r.bottom+=4*8;
00366 r.right = r.left+field->label.size()*8;
00367
00368 CStatic *text = new CStatic();
00369 text->Create(_T(field->label.c_str()),WS_CHILD|WS_VISIBLE|SS_LEFT,r,this);
00370 text->SetFont(font);
00371 awlist.push_back(text);
00372
00373 r.left = width-2*8-20*8;
00374 r.left = 2*4+max_length*8+2*8;
00375 r.right = width-2*8;
00376 vgui_mfc_dialog_choice *ch = (vgui_mfc_dialog_choice*)l.widget;
00377 r.bottom+=__min(ch->names.size(),4)*32;
00378 CComboBox *combobox = new CComboBox();
00379 combobox->CreateEx(WS_EX_CLIENTEDGE,_T("COMBOBOX"),NULL,
00380 WS_CHILD|WS_BORDER|CBS_DROPDOWNLIST|WS_VSCROLL,r,this,4);
00381 combobox->SetFont(font);
00382 r.bottom-=__min(ch->names.size(),4)*32;
00383
00384 int count = 0;
00385 for (vcl_vector<vcl_string>::iterator s_iter = ch->names.begin();
00386 s_iter != ch->names.end(); ++s_iter, ++count)
00387 combobox->AddString(_T(s_iter->c_str()));
00388
00389 combobox->SetCurSel(ch->index);
00390 combobox->UpdateWindow();
00391 combobox->ShowWindow(SW_SHOW);
00392 awlist.push_back(combobox);
00393 wlist.push_back(combobox);
00394 }
00395 else if (l.type == text_msg)
00396 {
00397 r.left = 2*4;
00398 r.top+=5*8;
00399 r.bottom+=5*8;
00400 r.right = r.left+field->label.size()*8;
00401
00402 CStatic *text = new CStatic();
00403 text->Create(_T(field->label.c_str()),WS_CHILD|WS_VISIBLE|SS_LEFT,r,this);
00404 text->SetFont(font);
00405 awlist.push_back(text);
00406 wlist.push_back(text);
00407 }
00408 else if (l.type == file_bsr || l.type == inline_file_bsr)
00409 {
00410 r.left = 2*4;
00411 r.top+=4*8;
00412 r.bottom+=4*8;
00413 r.right = r.left+field->label.size()*8;
00414
00415 CStatic *text = new CStatic();
00416 text->Create(_T(field->label.c_str()),WS_CHILD|WS_VISIBLE|SS_LEFT,r,this);
00417 text->SetFont(font);
00418 awlist.push_back(text);
00419
00420
00421 CEdit *edit = new CEdit();
00422 int savey = r.top;
00423 r.left = r.right+3*8;
00424 r.left = 2*4+max_length*8+2*8;
00425 r.right = width-2*8;
00426
00427
00428
00429
00430 edit->CreateEx(WS_EX_CLIENTEDGE,_T("EDIT"),NULL,
00431 WS_CHILD|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL,r,this,IDOK);
00432 edit->SetFont(font);
00433 edit->SetWindowText(l.field->current_value().c_str());
00434 edit->UpdateWindow();
00435 edit->ShowWindow(SW_SHOW);
00436 CButton *button = new CButton();
00437
00438 r.left = width-2*8-10*8;
00439 r.right = width-2*8;
00440 r.top+=4*8;
00441 r.bottom+=4*8;
00442 button->Create(_T("Browse..."),WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_PUSHBUTTON,
00443 r,this,ID_BROWSE_FILES+count_fbsr);
00444 fbsrs[count_fbsr++] = edit;
00445
00446 button->SetFont(font);
00447 button->UpdateWindow();
00448 button->ShowWindow(SW_SHOW);
00449 awlist.push_back(edit);
00450 awlist.push_back(button);
00451 wlist.push_back(edit);
00452 }
00453 else if (l.type == color_csr || l.type == inline_color_csr)
00454 {
00455 r.left = 2*4;
00456 r.top+=4*8;
00457 r.bottom+=4*8;
00458 r.right = r.left+field->label.size()*8;
00459
00460 CStatic *text = new CStatic();
00461 text->Create(_T(field->label.c_str()),WS_CHILD|WS_VISIBLE|SS_LEFT,r,this);
00462 text->SetFont(font);
00463 awlist.push_back(text);
00464
00465
00466 CEdit *edit = new CEdit();
00467 r.left = r.right+3*8;
00468 r.left = 2*4+max_length*8+2*8;
00469 r.right = width-2*8;
00470
00471
00472
00473 edit->CreateEx(WS_EX_CLIENTEDGE,_T("EDIT"),NULL,
00474 WS_CHILD|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL,r,this,IDOK);
00475 edit->SetFont(font);
00476 edit->SetWindowText(l.field->current_value().c_str());
00477 edit->UpdateWindow();
00478 edit->ShowWindow(SW_SHOW);
00479 CButton *button = new CButton();
00480
00481 r.left = width-2*8-10*8;
00482 r.right = width-2*8;
00483 r.top+=4*8;
00484 r.bottom+=4*8;
00485 button->Create(_T("Colour..."),WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_PUSHBUTTON,
00486 r,this,ID_CHOOSE_COLOUR+count_csr);
00487 csrs[count_csr++] = edit;
00488 button->SetFont(font);
00489 button->UpdateWindow();
00490 button->ShowWindow(SW_SHOW);
00491 awlist.push_back(edit);
00492 awlist.push_back(button);
00493 wlist.push_back(edit);
00494 }
00495 else if (l.type == inline_tabl)
00496 {
00497 vgui_mfc_dialog_inline_tab* tab_data
00498 = (vgui_mfc_dialog_inline_tab*)l.widget;
00499 vgui_mfc_adaptor *widg = new vgui_mfc_adaptor();
00500 widg->set_tableau(tab_data->tab);
00501
00502 widg->setup_adaptor(this, wglGetCurrentDC(), wglGetCurrentContext());
00503 r.left=8;
00504 r.right=r.left + long(tab_data->width);
00505 r.top += 5;
00506 r.bottom += r.top + long(tab_data->height);
00507 widg->CreateEx(WS_EX_CLIENTEDGE,TempsNewClass,NULL,
00508 WS_CHILD|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL,r,this,IDOK);
00509
00510 widg->ShowWindow(SW_SHOW);
00511 awlist.push_back(widg);
00512 wlist.push_back(widg);
00513 delete tab_data;
00514 }
00515 }
00516 if (accept)
00517 {
00518 accept->UpdateWindow();
00519 accept->ShowWindow(SW_SHOW);
00520 }
00521 if (cancel)
00522 {
00523 cancel->UpdateWindow();
00524 cancel->ShowWindow(SW_SHOW);
00525 }
00526 AfxGetApp()->EnableModeless(FALSE);
00527 AfxGetApp()->GetMainWnd()->EnableWindow(FALSE);
00528 nResult = RunModalLoop(MLF_SHOWONIDLE);
00529 if (m_hWnd != NULL)
00530 SetWindowPos(NULL, 0, 0, 0, 0, SWP_HIDEWINDOW|
00531 SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
00532 if (ok_clicked)
00533 {
00534 vcl_vector<CWnd *>::iterator w_iter = wlist.begin();
00535 for (vcl_vector<element>::iterator e_iter3 = elements.begin();
00536 e_iter3 != elements.end(); ++e_iter3, ++w_iter)
00537 {
00538 element l = *e_iter3;
00539 CWnd *input = *w_iter;
00540
00541 if (l.type == int_elem ||
00542 l.type == long_elem ||
00543 l.type == float_elem ||
00544 l.type == double_elem ||
00545 l.type == string_elem ||
00546 l.type == file_bsr ||
00547 l.type == color_csr ||
00548 l.type == inline_color_csr ||
00549 l.type == inline_file_bsr)
00550 {
00551 CString s;
00552 input->GetWindowText(s);
00553 l.field->update_value((LPCSTR)s);
00554 }
00555 else if (l.type == bool_elem)
00556 {
00557 vgui_bool_field *field = static_cast<vgui_bool_field*>(l.field);
00558 field->var =((CButton *)input)->GetCheck()!=0;
00559 }
00560 if (l.type == choice_elem)
00561 {
00562 vgui_int_field *field = static_cast<vgui_int_field*>(l.field);
00563 field->var = ((CComboBox *)input)->GetCurSel();
00564 }
00565 }
00566 }
00567
00568 for (vcl_vector<CWnd *>::iterator w_iter = awlist.begin();w_iter!=awlist.end();++w_iter)
00569 delete *w_iter;
00570
00571 awlist.clear();
00572 wlist.clear();
00573
00574 count_fbsr = 0;
00575 count_csr = 0;
00576
00577 delete accept;
00578 delete cancel;
00579 DestroyWindow();
00580
00581 delete font;
00582
00583
00584 AfxGetApp()->EnableModeless(TRUE);
00585 AfxGetApp()->GetMainWnd()->EnableWindow(TRUE);
00586 main_window->SetActiveWindow();
00587 return ok_clicked;
00588 }