00001
00002 #include "vgui_win32_dialog_impl.h"
00003
00004 #include <vcl_algorithm.h>
00005 #include <vcl_cstdio.h>
00006 #include <vcl_cstddef.h>
00007 #include <vcl_cstring.h>
00008 #include <vcl_iostream.h>
00009 #include <vgui/internals/vgui_simple_field.h>
00010 #include <vgui/internals/vgui_file_field.h>
00011 #include <vgui/internals/vgui_button_field.h>
00012 #include <vgui/impl/win32/vgui_win32_adaptor.h>
00013
00014 extern LRESULT CALLBACK globalDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
00015
00016 vgui_win32_dialog_impl::vgui_win32_dialog_impl(const char* name, HWND hWnd)
00017 : vgui_dialog_impl(name), ok_clicked(false), is_modal(true),
00018 hWndParent(hWnd), hWnd(NULL)
00019 {
00020 inline_tableaus.clear();
00021 fb_ids.clear();
00022 cc_ids.clear();
00023 callback_controls.clear();
00024 }
00025
00026 struct vgui_win32_dialog_pushbutton;
00027
00028 vgui_win32_dialog_impl::~vgui_win32_dialog_impl()
00029 {
00030 for ( vcl_vector<inline_tab_data>::iterator
00031 it = inline_tableaus.begin(); it != inline_tableaus.end(); ++it )
00032 delete it->adaptor;
00033
00034 for (vcl_vector<element>::iterator iter = elements.begin();
00035 iter != elements.end(); ++iter) {
00036 if ( iter->type == button_elem )
00037 delete (vgui_win32_dialog_pushbutton *)iter->widget;
00038 }
00039 }
00040
00041
00042 struct vgui_win32_dialog_choice
00043 {
00044 vcl_vector<vcl_string> names;
00045 int index;
00046 };
00047
00048
00049
00050 void* vgui_win32_dialog_impl::choice_field_widget(const char* ,
00051 const vcl_vector<vcl_string>& labels, int& val)
00052 {
00053 vgui_win32_dialog_choice *ch = new vgui_win32_dialog_choice;
00054 ch->names = labels;
00055 ch->index = val;
00056
00057 return (void*)ch;
00058 }
00059
00060
00061 struct vgui_win32_dialog_inline_tab
00062 {
00063 vgui_tableau_sptr tab;
00064 unsigned height;
00065 unsigned width;
00066 };
00067
00068
00069 void* vgui_win32_dialog_impl::inline_tableau_widget(const vgui_tableau_sptr tab,
00070 unsigned width, unsigned height)
00071 {
00072 vgui_win32_dialog_inline_tab* tab_data = new vgui_win32_dialog_inline_tab;
00073 tab_data->tab = tab;
00074 tab_data->height = height;
00075 tab_data->width = width;
00076 return (void*)tab_data;
00077 }
00078
00079
00080 struct vgui_win32_dialog_pushbutton
00081 {
00082
00083 ~vgui_win32_dialog_pushbutton()
00084 { if ( hBitmap!=NULL ) DeleteObject(hBitmap); }
00085
00086 unsigned short ctrl_id;
00087 vcl_string label;
00088 HANDLE hBitmap;
00089 unsigned width, height;
00090 };
00091
00092 void* vgui_win32_dialog_impl::pushbutton_field_widget(const char *label, const void *icon)
00093 {
00094 vgui_win32_dialog_pushbutton *pb = new vgui_win32_dialog_pushbutton;
00095
00096 pb->label = label ? label : "";
00097 pb->hBitmap = NULL;
00098 pb->width = 0;
00099 pb->height = 0;
00100
00101 if ( icon != NULL ) {
00102
00103 pb->hBitmap = LoadImage(NULL, (char*)icon, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
00104 if ( pb->hBitmap != NULL ) {
00105 BITMAP bm;
00106 if ( GetObject(pb->hBitmap, sizeof(bm), &bm) ) {
00107 pb->width = bm.bmWidth;
00108 pb->height = bm.bmHeight;
00109 }
00110 }
00111 }
00112
00113 return (void *)pb;
00114 }
00115
00116
00117 void vgui_win32_dialog_impl::FindDialogSize(int &width, int &height,
00118 int &max_length, int &fbsr_count,
00119 int cxChar, int cyChar, int width_sep, int height_sep,
00120 int button_length, int edit_length, int browser_length)
00121 {
00122
00123 const int cyCaption = GetSystemMetrics(SM_CYCAPTION);
00124 int field_length, field_height;
00125
00126 height = 3*height_sep+cyCaption;
00127 max_length = width_sep;
00128 fbsr_count = 0;
00129
00130
00131 if (ok_button_text_.size() > 0)
00132 max_length += button_length+width_sep;
00133 if (cancel_button_text_.size() > 0)
00134 max_length += button_length+width_sep;
00135
00136 field_length = field_height = 0;
00137 for (vcl_vector<element>::iterator e_iter = elements.begin();
00138 e_iter != elements.end(); ++e_iter) {
00139 element l = *e_iter;
00140 vgui_dialog_field *field = l.field;
00141
00142 if ( !use_line_break ) {
00143 field_length = 0;
00144 field_height = 0;
00145 }
00146
00147 if ( l.type == int_elem || l.type == long_elem ||
00148 l.type == float_elem || l.type == double_elem ||
00149 l.type == string_elem || l.type == choice_elem ||
00150 l.type == color_csr || l.type == inline_color_csr ) {
00151
00152 int w = vcl_strlen(field->label.c_str()) + edit_length;
00153 int h = height_sep;
00154 if ( l.type == color_csr || l.type == inline_color_csr )
00155 h += height_sep;
00156
00157 field_length += w;
00158 if ( field_height < h ) field_height = h;
00159
00160 if ( !use_line_break ) {
00161 if (max_length<field_length)
00162 max_length = field_length;
00163 height += field_height;
00164 }
00165 }
00166 else if (l.type == bool_elem )
00167 {
00168
00169 int w = vcl_strlen(field->label.c_str());
00170 int h = height_sep;
00171
00172 field_length += w;
00173 if ( field_height < h ) field_height = h;
00174
00175 if ( !use_line_break ) {
00176 if (max_length<field_length)
00177 max_length = field_length;
00178 height += field_height;
00179 }
00180 }
00181 else if ( l.type == text_msg )
00182 {
00183
00184 char *text, *next_text;
00185 int w, w1, h;
00186
00187 text = (char *)field->label.c_str();
00188 w = 0; h = 0;
00189 while ( text ) {
00190 next_text = vcl_strchr(text, '\n');
00191 if ( next_text )
00192 w1 = next_text-text;
00193 else
00194 w1 = vcl_strlen(text);
00195 text = next_text ? next_text+1 : NULL;
00196
00197 if ( w < w1 ) w = w1;
00198 h += height_sep;
00199 }
00200
00201 field_length += w;
00202 if ( field_height < h ) field_height = h;
00203
00204 if ( !use_line_break ) {
00205 if (max_length<field_length)
00206 max_length = field_length;
00207 height += field_height;
00208 }
00209 }
00210 else if (l.type == inline_tabl)
00211 {
00212
00213 vgui_win32_dialog_inline_tab* tab_data = (vgui_win32_dialog_inline_tab*)l.widget;
00214 int w = tab_data->width/cxChar + 2*width_sep;
00215 int h = tab_data->height;
00216
00217 field_length += w;
00218 if ( field_height < h ) field_height = h;
00219
00220 if ( !use_line_break ) {
00221 if (max_length < field_length)
00222 max_length = field_length;
00223 height += field_height;
00224 }
00225 }
00226 else if (l.type == file_bsr || l.type == inline_file_bsr || l.type == dir_bsr)
00227 {
00228
00229 int w = vcl_strlen(field->label.c_str()) + browser_length;
00230 int h = 2*height_sep;
00231
00232 field_length += w;
00233 if ( field_height < h ) field_height = h;
00234
00235 if ( !use_line_break ) {
00236 if (max_length<field_length)
00237 max_length = field_length;
00238 height += field_height;
00239 }
00240 fbsr_count++;
00241 }
00242 else if (l.type == button_elem )
00243 {
00244
00245 vgui_win32_dialog_pushbutton *pb = (vgui_win32_dialog_pushbutton*)l.widget;
00246
00247
00248 int w = (pb->width+cxChar-1)/cxChar;
00249 int slen = vcl_strlen(field->label.c_str());
00250 if ( w < slen )
00251 w = slen;
00252
00253 int h = pb->height;
00254 h += height_sep * (field->label.empty() ? 0 : 1);
00255
00256 field_length += w;
00257 if ( field_height < h ) field_height = h;
00258
00259 if ( !use_line_break ) {
00260 if (max_length<field_length)
00261 max_length = field_length;
00262 height += field_height;
00263 }
00264 }
00265 else if ( l.type == line_br )
00266 {
00267 if (max_length<field_length)
00268 max_length = field_length;
00269 height += field_height;
00270
00271 field_length = 0;
00272 field_height = 0;
00273 }
00274 else
00275 {
00276
00277 height += height_sep;
00278 }
00279 }
00280
00281
00282 width = (max_length+width_sep) * cxChar;
00283
00284 max_length -= fbsr_count ? browser_length : edit_length;
00285 }
00286
00287 bool vgui_win32_dialog_impl::ask()
00288 {
00289
00290
00291
00292 const int cxChar = LOWORD(GetDialogBaseUnits());
00293 const int cyChar = HIWORD(GetDialogBaseUnits());
00294
00295 const int height_sep = 6*cyChar/4;
00296 const int width_sep = 2;
00297 const int edit_length = 20;
00298 const int browser_length = 40;
00299 const int button_length = 12;
00300 const int button_height = 6*cyChar/4;
00301 const int edit_height = 5*cyChar/4;
00302
00303 int width, height, max_length, fbsr_count;
00304 short x, y, cx, cy;
00305 RECT rect;
00306
00307
00308 for (vcl_vector<element>::iterator e_iter = elements.begin();
00309 e_iter != elements.end(); ++e_iter) {
00310 if ( e_iter->type == line_br ) {
00311 use_line_break = true;
00312 break;
00313 }
00314 }
00315
00316
00317 FindDialogSize(width, height, max_length, fbsr_count, cxChar, cyChar,
00318 width_sep, height_sep, button_length, edit_length, browser_length);
00319
00320 #ifdef _WIN64
00321 HINSTANCE hInstance = (HINSTANCE)GetWindowLong(hWndParent, GWLP_HINSTANCE);
00322 #else
00323 HINSTANCE hInstance = (HINSTANCE)GetWindowLong(hWndParent, GWL_HINSTANCE);
00324 #endif //_WIN64
00325
00326
00327 GetWindowRect(hWndParent, &rect);
00328 hWnd = CreateWindow(TEXT("vgui_win32_dialog"), name.c_str(),
00329 WS_CAPTION | WS_POPUP | WS_SYSMENU | DS_MODALFRAME,
00330 rect.left+10, rect.top+10, width, height,
00331 hWndParent, NULL, hInstance, NULL);
00332 if ( hWnd == NULL )
00333 MessageBox(NULL, TEXT("Fail to create dialog box window!"),
00334 NULL, MB_ICONERROR);
00335
00336
00337 cx = button_length*cxChar;
00338 cy = button_height;
00339 x = width - 2*(cx + width_sep*cxChar);
00340 y = height - 3*height_sep;
00341
00342
00343 if (ok_button_text_.size() > 0) {
00344 CreateWindow(TEXT("BUTTON"), (char*)ok_button_text_.c_str(),
00345 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, x, y, cx, cy,
00346 hWnd, (HMENU)IDOK, hInstance, NULL);
00347 }
00348
00349
00350 if (cancel_button_text_.size() > 0) {
00351 x += cx+width_sep*cxChar;
00352 CreateWindow(TEXT("BUTTON"), (char*)cancel_button_text_.c_str(),
00353 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, x, y, cx, cy,
00354 hWnd, (HMENU)IDCANCEL, hInstance, NULL);
00355 }
00356
00357
00358 x = cxChar; y = cyChar>>1;
00359 unsigned short ctrl_count = 0;
00360 HWND hCtrlWnd;
00361 short dy = 0;
00362 for (vcl_vector<element>::iterator e_iter = elements.begin();
00363 e_iter != elements.end(); ++e_iter) {
00364 element l = *e_iter;
00365 vgui_dialog_field *field = l.field;
00366
00367 if (l.type == int_elem ||
00368 l.type == long_elem ||
00369 l.type == float_elem ||
00370 l.type == double_elem ||
00371 l.type == string_elem)
00372 {
00373
00374 cx = field->label.size()*cxChar;
00375 cy = edit_height;
00376 CreateWindow(TEXT("STATIC"), (char*)field->label.c_str(),
00377 WS_CHILD | WS_VISIBLE | SS_LEFT, x, y, cx, cy,
00378 hWnd, (HMENU)IDC_STATIC, hInstance, NULL);
00379
00380
00381 int savex = x;
00382 x = (max_length)*cxChar;
00383 cx = edit_length*cxChar;
00384 WORD wDlgCtrlId = DLG_ID_START + ctrl_count++;
00385 CreateWindow(TEXT("EDIT"), (char*)field->current_value().c_str(),
00386 WS_CHILD | WS_VISIBLE | ES_LEFT|ES_AUTOHSCROLL, x, y, cx, cy,
00387 hWnd, (HMENU)wDlgCtrlId, hInstance, NULL);
00388
00389 if ( use_line_break ) {
00390 x += (field->label.size()+edit_length)*cxChar+2*width_sep;
00391 if ( dy < height_sep ) dy = height_sep;
00392 }
00393 else {
00394 x = savex;
00395 y += height_sep;
00396 }
00397 }
00398
00399 else if (l.type == bool_elem)
00400 {
00401 cx = (field->label.size()+3)*cxChar;
00402 cy = button_height;
00403 WORD wDlgCtrlId = DLG_ID_START + ctrl_count++;
00404 CreateWindow(TEXT("BUTTON"), (char*)field->label.c_str(),
00405 WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, x, y, cx, cy,
00406 hWnd, (HMENU)wDlgCtrlId, hInstance, NULL);
00407
00408 vgui_bool_field *bfield = static_cast<vgui_bool_field*>(field);
00409 CheckDlgButton(hWnd, wDlgCtrlId, bfield->var ? BST_CHECKED : BST_UNCHECKED);
00410
00411
00412 if ( use_line_break ) {
00413 x += cx+width_sep;
00414 if ( dy < height_sep ) dy = height_sep;
00415 }
00416 else {
00417 x = cxChar;
00418 y += height_sep;
00419 }
00420 }
00421
00422 else if (l.type == choice_elem)
00423 {
00424
00425 cx = field->label.size()*cxChar;
00426 cy = edit_height;
00427
00428 CreateWindow(TEXT("STATIC"), (char*)field->label.c_str(),
00429 WS_CHILD | WS_VISIBLE | SS_LEFT, x, y, cx, cy,
00430 hWnd, (HMENU)IDC_STATIC, hInstance, NULL);
00431
00432
00433 vgui_win32_dialog_choice *ch = (vgui_win32_dialog_choice*)l.widget;
00434
00435 int savex = x;
00436 x = (max_length)*cxChar;
00437 cx = edit_length*cxChar;
00438 cy = ch->names.size() * cyChar;
00439 WORD wDlgCtrlId = DLG_ID_START + ctrl_count++;
00440 hCtrlWnd = CreateWindow(TEXT("COMBOBOX"), "",
00441 WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWNLIST,
00442 x, y, cx, cy, hWnd, (HMENU)wDlgCtrlId, hInstance, NULL);
00443
00444
00445 for (vcl_vector<vcl_string>::iterator s_iter = ch->names.begin();
00446 s_iter != ch->names.end(); ++s_iter)
00447 SendMessage(hCtrlWnd, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)s_iter->c_str());
00448
00449
00450 SendMessage(hCtrlWnd, CB_SETCURSEL, (WPARAM)ch->index, 0);
00451
00452 if ( use_line_break ) {
00453 x += (field->label.size()+edit_length)*cxChar+2*width_sep;
00454 if ( dy < height_sep ) dy = height_sep;
00455 }
00456 else {
00457 x = savex;
00458 y += height_sep;
00459 }
00460 }
00461
00462 else if (l.type == text_msg)
00463 {
00464
00465 char *text, *next_text;
00466 int field_length;
00467
00468 text = (char *)field->label.c_str();
00469 cx = 0; cy = 0;
00470 while ( text ) {
00471 next_text = vcl_strchr(text, '\n');
00472 if ( next_text )
00473 field_length = next_text-text;
00474 else
00475 field_length = vcl_strlen(text);
00476 if (cx<field_length)
00477 cx = field_length;
00478 cy++;
00479 text = next_text ? next_text+1 : NULL;
00480 }
00481 cx *= cxChar;
00482 cy *= edit_height;
00483 CreateWindow(TEXT("STATIC"), (char*)field->label.c_str(),
00484 WS_CHILD | WS_VISIBLE | SS_LEFT, x, y, cx, cy,
00485 hWnd, (HMENU)IDC_STATIC, hInstance, NULL);
00486
00487 if ( use_line_break ) {
00488 x += cx+width_sep;
00489 if ( dy < cy ) dy = cy;
00490 }
00491 else {
00492 x = cxChar;
00493 y += cy;
00494 }
00495 }
00496
00497 else if (l.type == file_bsr || l.type == inline_file_bsr ||
00498 l.type == color_csr || l.type == inline_color_csr )
00499 {
00500 cx = field->label.size()*cxChar;
00501 cy = edit_height;
00502
00503 CreateWindow(TEXT("STATIC"), (char*)field->label.c_str(),
00504 WS_CHILD | WS_VISIBLE | SS_LEFT, x, y, cx, cy,
00505 hWnd, (HMENU)IDC_STATIC, hInstance, NULL);
00506
00507
00508 int savex = x;
00509 x = (max_length)*cxChar;
00510 if ( l.type == file_bsr || l.type == inline_file_bsr )
00511 cx = browser_length*cxChar;
00512 else
00513 cx = edit_length*cxChar;
00514 WORD wDlgCtrlId = DLG_ID_START + ctrl_count++;
00515 CreateWindow(TEXT("EDIT"), (char*)field->current_value().c_str(),
00516 WS_CHILD | WS_VISIBLE | ES_LEFT|ES_AUTOHSCROLL, x, y, cx, cy,
00517 hWnd, (HMENU)wDlgCtrlId, hInstance, NULL);
00518
00519
00520 int savey = y;
00521 y += height_sep;
00522 cx = button_length*cxChar;
00523 cy = button_height;
00524 wDlgCtrlId = DLG_ID_START + ctrl_count++;
00525 if ( l.type == file_bsr || l.type == inline_file_bsr ) {
00526 CreateWindow(TEXT("BUTTON"), "Browse...",
00527 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, x, y, cx, cy,
00528 hWnd, (HMENU)wDlgCtrlId, hInstance, NULL);
00529 fb_ids.push_back(wDlgCtrlId);
00530 }
00531 else {
00532 CreateWindow(TEXT("BUTTON"), "Colour...",
00533 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, x, y, cx, cy,
00534 hWnd, (HMENU)wDlgCtrlId, hInstance, NULL);
00535 cc_ids.push_back(wDlgCtrlId);
00536 }
00537
00538 if ( use_line_break ) {
00539 x += (field->label.size()+edit_length)*cxChar+2*width_sep;
00540 y = savey;
00541 if ( dy < 2*height_sep ) dy = 2*height_sep;
00542 }
00543 else {
00544 x = savex;
00545 y += height_sep;
00546 }
00547 }
00548
00549 else if (l.type == inline_tabl)
00550 {
00551 vgui_win32_dialog_inline_tab* tab_data = (vgui_win32_dialog_inline_tab *)l.widget;
00552
00553
00554 cx = short(tab_data->width);
00555 cy = short(tab_data->height);
00556 WORD wDlgCtrlId = DLG_ID_START + ctrl_count++;
00557 hCtrlWnd = CreateWindow(TEXT("vgui_win32_inline_tab"), "",
00558 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, x, y, cx, cy,
00559 hWnd, (HMENU)wDlgCtrlId, hInstance, NULL);
00560
00561
00562 vgui_win32_adaptor* adptr = new vgui_win32_adaptor(hCtrlWnd);
00563 adptr->set_tableau(tab_data->tab);
00564 adptr->set_width(tab_data->width);
00565 adptr->set_height(tab_data->height);
00566
00567
00568 inline_tab_data the_tab;
00569 the_tab.childId = wDlgCtrlId;
00570 the_tab.hWnd = hCtrlWnd;
00571 the_tab.adaptor = adptr;
00572 inline_tableaus.push_back(the_tab);
00573
00574 if ( use_line_break ) {
00575 x += cx+width_sep;
00576 if ( dy < cy ) dy = cy;
00577 }
00578 else {
00579 x = cxChar;
00580 y += cy;
00581 }
00582 }
00583
00584 else if (l.type == button_elem) {
00585
00586 vgui_win32_dialog_pushbutton *pb = (vgui_win32_dialog_pushbutton*)l.widget;
00587
00588
00589 cx = field->label.size()*cxChar;
00590 if ( cx < (short)(pb->width) ) cx = pb->width;
00591
00592 cy = pb->height;
00593 cy += field->label.empty() ? 0 : button_height;
00594 WORD wDlgCtrlId = DLG_ID_START + ctrl_count++;
00595 hCtrlWnd = CreateWindow(TEXT("BUTTON"), (char*)field->label.c_str(),
00596 WS_CHILD | WS_VISIBLE | (pb->hBitmap ? BS_OWNERDRAW : BS_PUSHBUTTON),
00597 x, y, cx, cy, hWnd, (HMENU)wDlgCtrlId, hInstance, NULL);
00598 pb->ctrl_id = wDlgCtrlId;
00599
00600 callback_control_data ccd;
00601 vgui_button_field *l = (vgui_button_field *)field;
00602 ccd.child_id = wDlgCtrlId;
00603 ccd.cmnd = l->cmnd;
00604 callback_controls.push_back(ccd);
00605
00606 if ( use_line_break ) {
00607 x += cx+width_sep;
00608 if ( dy < cy ) dy = cy;
00609 }
00610 else {
00611 x = cxChar;
00612 y += cy;
00613 }
00614 }
00615
00616 else if (l.type == line_br) {
00617 x = cxChar;
00618 y += dy;
00619 dy = 0;
00620 }
00621 }
00622
00623
00624 ShowWindow(hWnd, SW_SHOW);
00625 UpdateWindow(hWnd);
00626
00627
00628 for ( vcl_size_t i = 0; i < inline_tableaus.size(); i++ )
00629 inline_tableaus[i].adaptor->post_redraw();
00630
00631
00632 run();
00633
00634 return ok_clicked;
00635 }
00636
00637 void vgui_win32_dialog_impl::run()
00638 {
00639 MSG msg;
00640
00641 while ( GetMessage(&msg, NULL, 0, 0) ) {
00642 TranslateMessage(&msg);
00643 DispatchMessage(&msg);
00644 }
00645 }
00646
00647
00648 LRESULT vgui_win32_dialog_impl::DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
00649 {
00650 switch (message) {
00651 case WM_CREATE:
00652
00653 if ( is_modal )
00654 EnableWindow(GetParent(hDlg), FALSE);
00655 return 1;
00656
00657 case WM_DESTROY:
00658 if ( is_modal )
00659 EnableWindow(GetParent(hDlg), TRUE);
00660 SetActiveWindow(GetParent(hDlg));
00661 PostQuitMessage(0);
00662 return 1;
00663
00664 case WM_DRAWITEM: {
00665 LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)lParam;
00666
00667 HDC hDC = lpDIS->hDC;
00668 RECT rectItem = lpDIS->rcItem;
00669 UINT ctrlID = lpDIS->CtlID;
00670 BOOL isDisabled = lpDIS->itemState & ODS_DISABLED;
00671 BOOL isFocused = lpDIS->itemState & ODS_FOCUS;
00672 BOOL isPressed = lpDIS->itemState & ODS_SELECTED;
00673
00674
00675
00676 vcl_vector<element>::iterator e_iter;
00677 vgui_win32_dialog_pushbutton *pb;
00678 for ( e_iter = elements.begin(); e_iter != elements.end(); ++e_iter) {
00679 if ( e_iter->type == button_elem ) {
00680 pb = (vgui_win32_dialog_pushbutton*)e_iter->widget;
00681 if ( ctrlID == pb->ctrl_id )
00682 break;
00683 }
00684 }
00685
00686 if ( e_iter == elements.end() )
00687 break;
00688
00689 SetBkMode(hDC, TRANSPARENT);
00690
00691
00692 #if 0
00693 if (Themed) {
00694 DWORD state = (bIsPressed)?PBS_PRESSED:PBS_NORMAL;
00695
00696 if (state == PBS_NORMAL) {
00697 if (bIsFocused)
00698 state = PBS_DEFAULTED;
00699 if (bMouseOverButton)
00700 state = PBS_HOT;
00701 }
00702 zDrawThemeBackground(hTheme, hDC, BP_PUSHBUTTON, state, &lpDIS->rcItem, NULL);
00703 }
00704 else {
00705 #endif
00706 if ( isFocused ) {
00707
00708 HBRUSH hbr = CreateSolidBrush(RGB(0,0,0));
00709 FrameRect(hDC, &rectItem, hbr);
00710 InflateRect(&rectItem, -1, -1);
00711 DeleteObject(hbr);
00712 }
00713
00714
00715
00716
00717
00718
00719
00720 if ( isPressed ) {
00721
00722 HBRUSH hbr = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
00723 FrameRect(hDC, &rectItem, hbr);
00724 DeleteObject(hbr);
00725 }
00726 else {
00727 DrawFrameControl(hDC, &rectItem, DFC_BUTTON, DFCS_BUTTONPUSH);
00728 }
00729 #if 0
00730 }
00731 #endif
00732
00733
00734 if ( pb->hBitmap != NULL ) {
00735 RECT rcImage;
00736
00737
00738 CopyRect(&rcImage, &rectItem);
00739 UINT image_width = rcImage.right - rcImage.left;
00740 rcImage.left = (image_width - pb->width)/2;
00741
00742 DrawState(hDC, NULL, NULL, (LPARAM)(HBITMAP)pb->hBitmap, 0,
00743 rcImage.left, rcImage.top,
00744 rcImage.right - rcImage.left,
00745 rcImage.bottom - rcImage.top,
00746 (isDisabled ? DSS_DISABLED : DSS_NORMAL) | DST_BITMAP);
00747
00748 }
00749
00750
00751 if ( !pb->label.empty() ) {
00752 RECT rcLabel;
00753
00754 CopyRect(&rcLabel, &lpDIS->rcItem);
00755
00756
00757
00758
00759
00760
00761
00762
00763 rcLabel.top += pb->height;
00764
00765
00766
00767
00768
00769 #if 0
00770 if (Themed) {
00771
00772 int nTextLen = vcl_strlen(sTitle);
00773 int mlen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (char *)sTitle, nTextLen + 1, NULL, 0);
00774 WCHAR* output = new WCHAR[mlen];
00775 if (output)
00776 {
00777 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (char *)sTitle, nTextLen + 1, output, mlen);
00778 zDrawThemeText(hTheme, hDC, BP_PUSHBUTTON, PBS_NORMAL,
00779 output, wcslen(output),
00780 DT_CENTER | DT_VCENTER | DT_SINGLELINE,
00781 0, &rcLabel);
00782 delete output;
00783 }
00784 }
00785 else {
00786 #endif // 0
00787
00788 if ( isDisabled ) {
00789 OffsetRect(&rcLabel, 1, 1);
00790 SetTextColor(hDC, ::GetSysColor(COLOR_3DHILIGHT));
00791 DrawText(hDC, pb->label.c_str(), -1, &rcLabel, DT_WORDBREAK | DT_CENTER);
00792 OffsetRect(&rcLabel, -1, -1);
00793 SetTextColor(hDC, ::GetSysColor(COLOR_3DSHADOW));
00794 DrawText(hDC, pb->label.c_str(), -1, &rcLabel, DT_WORDBREAK | DT_CENTER);
00795 }
00796 else {
00797 SetTextColor(hDC, GetSysColor(COLOR_BTNTEXT));
00798 SetBkColor(hDC, GetSysColor(COLOR_BTNFACE));
00799 DrawText(hDC, pb->label.c_str(), -1, &rcLabel, DT_WORDBREAK | DT_CENTER);
00800 }
00801
00802 #if 0
00803 }
00804 #endif
00805 }
00806
00807
00808
00809
00810
00811
00812
00813
00814 break;
00815 }
00816
00817 case WM_COMMAND: {
00818 WORD wCtrlId = LOWORD(wParam);
00819 if ( wCtrlId == IDOK ) {
00820 OnOK();
00821 DestroyWindow(hDlg);
00822 return 0;
00823 }
00824 if ( wCtrlId == IDCANCEL ) {
00825 OnCancel();
00826 DestroyWindow(hDlg);
00827 return 0;
00828 }
00829 if ( IsFileBrowserButton(wCtrlId) ) {
00830 OnBrowse(hDlg, wCtrlId);
00831 return 0;
00832 }
00833 if ( IsColorChooserButton(wCtrlId) ) {
00834 char strColor[16];
00835 GetWindowText(GetDlgItem(hDlg, wCtrlId-1), strColor, 16);
00836 OnColor(hDlg, wCtrlId, strColor);
00837 return 0;
00838 }
00839 if ( IsCallbackControl(wCtrlId) ) {
00840 dialog_dispatcher(wCtrlId);
00841 return 0;
00842 }
00843 break;
00844 }
00845 }
00846
00847 return 0;
00848 }
00849
00850
00851 void vgui_win32_dialog_impl::OnOK()
00852 {
00853 HWND hWndCtrl;
00854 char buf[MAX_PATH];
00855 int control_count, ctrl_id;
00856
00857 ok_clicked = true;
00858
00859
00860 control_count = 0;
00861 for (vcl_vector<element>::iterator e_iter = elements.begin();
00862 e_iter != elements.end(); ++e_iter) {
00863 element l = *e_iter;
00864 vgui_dialog_field *field = l.field;
00865 ctrl_id = DLG_ID_START+control_count;
00866 hWndCtrl = GetDlgItem(hWnd, ctrl_id);
00867
00868 if ( l.type == int_elem ||
00869 l.type == long_elem ||
00870 l.type == float_elem ||
00871 l.type == double_elem ||
00872 l.type == string_elem ) {
00873 GetWindowText(hWndCtrl, buf, MAX_PATH);
00874 field->update_value(buf);
00875 control_count++;
00876 }
00877
00878 else if ( l.type == bool_elem ) {
00879 vgui_bool_field *bfield = static_cast<vgui_bool_field*>(field);
00880 bfield->var = IsDlgButtonChecked(hWnd, ctrl_id) ? true : false;
00881 control_count++;
00882 }
00883
00884 else if ( l.type == choice_elem ) {
00885 vgui_int_field *ifield = (vgui_int_field *)field;
00886 ifield->var = SendMessage(hWndCtrl, CB_GETCURSEL, 0, 0);
00887 control_count++;
00888 }
00889
00890 else if ( l.type == file_bsr ||
00891 l.type == color_csr ||
00892 l.type == inline_file_bsr ||
00893 l.type == inline_color_csr ) {
00894 GetWindowText(hWndCtrl, buf, MAX_PATH);
00895 field->update_value(buf);
00896 control_count += 2;
00897 }
00898
00899 else if ( l.type == inline_tabl ) {
00900 control_count++;
00901 }
00902 }
00903 }
00904
00905 void vgui_win32_dialog_impl::OnCancel()
00906 {
00907 ok_clicked = false;
00908 }
00909
00910
00911 BOOL vgui_win32_dialog_impl::OnBrowse(HWND hDlg, WORD wCtrlId)
00912 {
00913 static TCHAR szFileName[MAX_PATH], szTitleName[MAX_PATH];
00914 static TCHAR szFilter[] = TEXT("All Files (*.*)\0*.*\0")
00915 TEXT("All Files (*.*)\0*.*\0\0");
00916 static OPENFILENAME ofn;
00917
00918 ofn.lStructSize = sizeof(OPENFILENAME);
00919 ofn.hwndOwner = hDlg;
00920 ofn.hInstance = NULL;
00921 ofn.lpstrFilter = szFilter;
00922 ofn.lpstrCustomFilter = NULL;
00923 ofn.nMaxCustFilter = 0;
00924 ofn.nFilterIndex = 0;
00925 ofn.lpstrFile = szFileName;
00926 ofn.nMaxFile = MAX_PATH;
00927 ofn.lpstrFileTitle = szTitleName;
00928 ofn.nMaxFileTitle = MAX_PATH;
00929 ofn.lpstrInitialDir = NULL;
00930 ofn.lpstrTitle = NULL;
00931 ofn.Flags = OFN_CREATEPROMPT;
00932 ofn.nFileOffset = 0;
00933 ofn.nFileExtension = 0;
00934 ofn.lpstrDefExt = NULL;
00935 ofn.lCustData = 0;
00936 ofn.lpfnHook = NULL;
00937 ofn.lpTemplateName = NULL;
00938
00939 if ( GetOpenFileName(&ofn) )
00940 SetWindowText(GetDlgItem(hDlg, wCtrlId-1), szFileName);
00941
00942 return TRUE;
00943 }
00944
00945 BOOL vgui_win32_dialog_impl::OnColor(HWND hDlg, WORD wCtrlId, LPTSTR lpColor)
00946 {
00947 char buffer[16];
00948 vcl_string strColor;
00949
00950 static CHOOSECOLOR cc;
00951 static COLORREF crCustColors[16];
00952
00953 cc.lStructSize = sizeof(CHOOSECOLOR);
00954 cc.hwndOwner = hDlg;
00955 cc.hInstance = NULL;
00956 cc.rgbResult = ColorStringToRGB(lpColor);
00957 cc.lpCustColors = crCustColors;
00958 cc.Flags = CC_RGBINIT | CC_FULLOPEN;
00959 cc.lCustData = 0;
00960 cc.lpfnHook = NULL;
00961 cc.lpTemplateName = NULL;
00962
00963 if ( ChooseColor(&cc) ) {
00964 vcl_sprintf(buffer, "%3d", GetRValue(cc.rgbResult));
00965 strColor += buffer;
00966 vcl_sprintf(buffer, " %3d", GetGValue(cc.rgbResult));
00967 strColor += buffer;
00968 vcl_sprintf(buffer, " %3d", GetBValue(cc.rgbResult));
00969 strColor += buffer;
00970 SetWindowText(GetDlgItem(hDlg, wCtrlId-1), strColor.c_str());
00971 }
00972
00973 return TRUE;
00974 }
00975
00976
00977
00978 COLORREF vgui_win32_dialog_impl::ColorStringToRGB(LPTSTR lpColor)
00979 {
00980 int r, g, b;
00981
00982 if ( vcl_strcmp(lpColor, "red") == 0 )
00983 return RGB(255, 0, 0);
00984 if ( vcl_strcmp(lpColor, "green") == 0 )
00985 return RGB(0, 255, 0);
00986 if ( vcl_strcmp(lpColor, "blue") == 0 )
00987 return RGB(0, 0, 255);
00988 if ( vcl_strcmp(lpColor, "yellow") == 0 )
00989 return RGB(255, 255, 0);
00990 if ( vcl_strcmp(lpColor, "pink") == 0 )
00991 return RGB(255, 0, 255);
00992 if ( vcl_strcmp(lpColor, "cyan") == 0 )
00993 return RGB(0, 255, 255);
00994 if ( vcl_strcmp(lpColor, "black") == 0 )
00995 return RGB(0, 0, 0);
00996 if ( vcl_strcmp(lpColor, "white") == 0 )
00997 return RGB(255, 255, 255);
00998
00999 int ret = vcl_sscanf(lpColor, TEXT("%d%d%d"), &r, &g, &b);
01000 if ( ret == 3 )
01001 return COLORREF(RGB(r, g, b));
01002 else
01003 return COLORREF(RGB(0, 0, 0));
01004 }
01005
01006 inline bool vgui_win32_dialog_impl::IsFileBrowserButton(unsigned short ctrl_id)
01007 {
01008 vcl_vector<unsigned short>::iterator result;
01009
01010 result = vcl_find(fb_ids.begin(), fb_ids.end(), ctrl_id);
01011 return result == fb_ids.end() ? false : true;
01012 }
01013
01014
01015 inline bool vgui_win32_dialog_impl::IsColorChooserButton(unsigned short ctrl_id)
01016 {
01017 vcl_vector<unsigned short>::iterator result;
01018
01019 result = vcl_find(cc_ids.begin(), cc_ids.end(), ctrl_id);
01020 return result == cc_ids.end() ? false : true;
01021 }
01022
01023 inline bool vgui_win32_dialog_impl::IsCallbackControl(unsigned short ctrl_id)
01024 {
01025 for ( vcl_size_t i = 0; i < callback_controls.size(); i++ )
01026 if ( ctrl_id == callback_controls[i].child_id )
01027 return true;
01028
01029 return false;
01030 }
01031
01032 vgui_win32_adaptor* vgui_win32_dialog_impl::find_adaptor(unsigned short ctrl_id)
01033 {
01034 for ( vcl_size_t i = 0; i < inline_tableaus.size(); i++ )
01035 if ( ctrl_id == inline_tableaus[i].childId )
01036 return inline_tableaus[i].adaptor;
01037
01038 return NULL;
01039 }
01040
01041 void vgui_win32_dialog_impl::dialog_dispatcher(int ctrl_id)
01042 {
01043 for ( vcl_size_t i = 0; i < callback_controls.size(); i++ ) {
01044 if ( ctrl_id == callback_controls[i].child_id ) {
01045 callback_controls[i].cmnd->execute();
01046 break;
01047 }
01048 }
01049 }
01050
01051 #if 0
01052 void PrepareImageRect(BOOL bHasTitle, RECT* rpItem, RECT* rpTitle, BOOL bIsPressed, DWORD dwWidth, DWORD dwHeight, RECT* rpImage)
01053 {
01054 CopyRect(rpImage, rpItem);
01055
01056 if (bHasTitle == FALSE) {
01057
01058 LONG rpImageWidth = rpImage->right - rpImage->left;
01059 rpImage->left += ((rpImageWidth - (long)dwWidth)/2);
01060 }
01061 else {
01062
01063 LONG rpTitleWidth = rpTitle->right - rpTitle->left;
01064 rpTitle->right = rpTitleWidth - dwWidth - 30;
01065 rpTitle->left = 30;
01066
01067 rpImage->left = rpItem->right - dwWidth - 30;
01068
01069 LONG rpImageHeight = rpImage->bottom - rpImage->top;
01070 rpImage->top += ((rpImageHeight - (long)dwHeight)/2);
01071 }
01072
01073
01074 if (bIsPressed && !Themed)
01075 OffsetRect(rpImage, 1, 1);
01076 }
01077 #endif // 0
01078
01079 void vgui_win32_dialog_impl::DrawImageOnButton(HDC hDC, RECT* lprcItem,
01080 HBITMAP hBitmap, unsigned w, unsigned h, BOOL isDisabled)
01081 {
01082 RECT rcImage;
01083
01084
01085 CopyRect(&rcImage, lprcItem);
01086 UINT image_width = rcImage.right - rcImage.left;
01087 rcImage.left = (image_width - w)/2;
01088
01089 DrawState(hDC, NULL, NULL, (LPARAM)hBitmap, 0,
01090 rcImage.left, rcImage.top,
01091 rcImage.right - rcImage.left,
01092 rcImage.bottom - rcImage.top,
01093 (isDisabled ? DSS_DISABLED : DSS_NORMAL) | DST_BITMAP);
01094
01095 return;
01096 }
01097