1 #include "ToolbarStrip.h"
2 #include "Resource.h"
3 #include "LDViewWindow.h"
4 #include "ModelWindow.h"
5 #include "LDViewPreferences.h"
6 #include <TCFoundation/TCJpegOptions.h>
7 #include <TCFoundation/mystring.h>
8 #include <TCFoundation/TCLocalStrings.h>
9 #include <TCFoundation/TCAlertManager.h>
10 #include <LDLib/LDUserDefaultsKeys.h>
11 #include <CUI/CUIScaler.h>
12 #if _MSC_VER >= 1300 && !defined(TC_NO_UNICODE) // VC >= VC 2003
13 #define min(x, y) ((x) < (y) ? (x) : (y))
14 #define max(x, y) ((x) > (y) ? (x) : (y))
15 #pragma warning(push)
16 #pragma warning(disable:4458)
17 #include <gdiplus.h>
18 #include <gdiplusflat.h>
19 #pragma warning(pop)
20 #define USE_GDIPLUS
21 #endif // VC >= VC 2005
22
23 #if defined(_MSC_VER) && _MSC_VER >= 1400 && defined(_DEBUG)
24 #define new DEBUG_CLIENTBLOCK
25 #endif // _DEBUG
26
27
28 #define NUM_DEFAULT_TB_BUTTONS 13
29 #define STEP_COUNT_CHANGED_TIMER 42
30
31 #ifdef USE_GDIPLUS
32
33 typedef Gdiplus::Status (WINAPI *PFNGDIPLUSSTARTUP)(
34 OUT ULONG_PTR *token,
35 const Gdiplus::GdiplusStartupInput *input,
36 OUT Gdiplus::GdiplusStartupOutput *output);
37 typedef VOID (WINAPI *PFNGDIPLUSSHUTDOWN)(ULONG_PTR token);
38 typedef Gdiplus::GpStatus (WINGDIPAPI *PFNGDIPCREATEBITMAPFROMHICON)(
39 HICON hicon, Gdiplus::GpBitmap** bitmap);
40 typedef Gdiplus::GpStatus (WINGDIPAPI *PFNGDIPCREATEHBITMAPFROMBITMAP)(
41 Gdiplus::GpBitmap* bitmap, HBITMAP* hbmReturn, Gdiplus::ARGB background);
42 typedef Gdiplus::GpStatus (WINGDIPAPI *PFNGDIPDISPOSEIMAGE)(
43 Gdiplus::GpImage *image);
44
45 static PFNGDIPLUSSTARTUP GdiplusStartup = NULL;
46 static PFNGDIPLUSSHUTDOWN GdiplusShutdown = NULL;
47 static PFNGDIPCREATEBITMAPFROMHICON GdipCreateBitmapFromHICON = NULL;
48 static PFNGDIPCREATEHBITMAPFROMBITMAP GdipCreateHBITMAPFromBitmap = NULL;
49 static PFNGDIPDISPOSEIMAGE GdipDisposeImage = NULL;
50 #endif // USE_GDIPLUS
51
ToolbarStrip(HINSTANCE hInstance)52 ToolbarStrip::ToolbarStrip(HINSTANCE hInstance):
53 CUIDialog(hInstance),
54 m_stdBitmapStartId(-1),
55 m_tbBitmapStartId(-1),
56 m_numSteps(0),
57 m_hDeactivatedTooltip(NULL),
58 m_hGdiPlus(NULL),
59 m_showMain(TCUserDefaults::boolForKey(SHOW_MAIN_TOOLBAR_KEY, true, false)),
60 m_showSteps(TCUserDefaults::boolForKey(SHOW_STEPS_TOOLBAR_KEY, true, false))
61 {
62 ModelWindow::initCommonControls(ICC_BAR_CLASSES | ICC_WIN95_CLASSES);
63 TCAlertManager::registerHandler(ModelWindow::alertClass(), this,
64 (TCAlertCallback)&ToolbarStrip::modelAlertCallback);
65 m_commandMap[ID_TOOLS_ERRORS] = IDR_TB_ERRORS;
66 m_commandMap[ID_VIEW_EXAMINE] = IDR_TB_EXAMINE;
67 m_commandMap[ID_VIEW_EXAMINE_LAT_LONG] = IDR_TB_LATLONROT;
68 m_commandMap[ID_VIEW_FLYTHROUGH] = IDR_TB_FLYTHROUGH;
69 m_commandMap[ID_VIEW_WALK] = IDR_TB_WALK;
70 m_commandMap[ID_VIEW_FULLSCREEN] = IDR_TB_FULLSCREEN;
71 m_commandMap[ID_FILE_OPEN] = IDR_TB_OPEN;
72 m_commandMap[ID_EDIT_PREFERENCES] = IDR_TB_PREFERENCES;
73 m_commandMap[ID_FILE_RELOAD] = IDR_TB_RELOAD;
74 m_commandMap[ID_VIEW_RIGHTSIDEUP] = IDR_TB_RIGHTSIDEUP;
75 m_commandMap[ID_FILE_SAVE] = IDR_TB_SAVE;
76 m_commandMap[ID_VIEW_ZOOMTOFIT] = IDR_TB_ZOOMTOFIT;
77 m_commandMap[ID_FIRST_STEP] = IDR_TB_FIRST_STEP;
78 m_commandMap[ID_LAST_STEP] = IDR_TB_LAST_STEP;
79 m_commandMap[ID_NEXT_STEP] = IDR_TB_NEXT_STEP;
80 m_commandMap[ID_PREV_STEP] = IDR_TB_PREV_STEP;
81 m_commandMap[ID_HELP_CONTENTS] = IDR_TB_HELP;
82 m_commandMap[ID_TOOLS_MODELTREE] = IDR_TB_MODELTREE;
83 m_commandMap[ID_TOOLS_BOUNDINGBOX] = IDR_TB_MODELBBOX;
84 m_commandMap[ID_VIEW_ALWAYSONTOP] = IDR_TB_TOPMOST;
85 m_commandMap[ID_VIEW_FRONT] = IDR_TB_VIEW_FRONT;
86 m_commandMap[ID_VIEW_BACK] = IDR_TB_VIEW_BACK;
87 m_commandMap[ID_VIEW_LEFT] = IDR_TB_VIEW_LEFT;
88 m_commandMap[ID_VIEW_RIGHT] = IDR_TB_VIEW_RIGHT;
89 m_commandMap[ID_VIEW_TOP] = IDR_TB_VIEW_TOP;
90 m_commandMap[ID_VIEW_BOTTOM] = IDR_TB_VIEW_BOTTOM;
91 m_commandMap[ID_VIEW_ISO] = IDR_TB_VIEW_2_3RDS;
92 m_commandMap[ID_VIEW_SPECIFYLATLON] = IDR_TB_LATLON;
93 m_commandMap[ID_PRIMITIVES_TEXTURESTUDS] = IDR_TB_STUD;
94 m_commandMap[ID_PRIMITIVES_TEXMAPS] = IDR_TB_TEXMAPS;
95 m_commandMap[ID_FILE_EXPORT] = IDR_TB_EXPORT;
96 m_commandMap[ID_FILE_PRINT] = IDR_TB_PRINT;
97 m_commandMap[ID_TOOLS_PARTSLIST] = IDR_TB_PARTSLIST;
98 m_commandMap[ID_TOOLS_MPD] = IDR_TB_MPD;
99 m_commandMap[ID_TOOLS_POV_CAMERA] = IDR_TB_POVCAMERA;
100 }
101
~ToolbarStrip(void)102 ToolbarStrip::~ToolbarStrip(void)
103 {
104 }
105
dealloc(void)106 void ToolbarStrip::dealloc(void)
107 {
108 if (m_hGdiPlus != NULL)
109 {
110 FreeLibrary(m_hGdiPlus);
111 m_hGdiPlus = NULL;
112 }
113 for (size_t i = 0; i < m_imageLists.size(); i++)
114 {
115 ImageList_Destroy(m_imageLists[i]);
116 }
117 TCAlertManager::unregisterHandler(this);
118 m_prefs->release();
119 CUIDialog::dealloc();
120 }
121
modelAlertCallback(TCAlert * alert)122 void ToolbarStrip::modelAlertCallback(TCAlert *alert)
123 {
124 if (alert->getSender() == m_ldviewWindow->getModelWindow())
125 {
126 if (ucstrcmp(alert->getMessageUC(), _UC("ModelLoaded")) == 0 ||
127 ucstrcmp(alert->getMessageUC(), _UC("ModelLoadCanceled")) == 0 ||
128 ucstrcmp(alert->getMessageUC(), _UC("ModelParsed")) == 0 ||
129 ucstrcmp(alert->getMessageUC(), _UC("ModelParseCanceled")) == 0)
130 {
131 updateStep();
132 updateNumSteps();
133 }
134 }
135 }
136
create(LDViewWindow * parent)137 void ToolbarStrip::create(LDViewWindow *parent)
138 {
139 m_ldviewWindow = parent;
140 m_prefs = m_ldviewWindow->getModelWindow()->getPrefs();
141 m_prefs->retain();
142 ::CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_TOOLBAR),
143 parent->getHWindow(), staticDialogProc, (LPARAM)this);
144 }
145
show(void)146 void ToolbarStrip::show(void)
147 {
148 ::ShowWindow(hWindow, SW_SHOW);
149 }
150
hide(void)151 void ToolbarStrip::hide(void)
152 {
153 ::ShowWindow(hWindow, SW_HIDE);
154 }
155
updateMenus(void)156 void ToolbarStrip::updateMenus(void)
157 {
158 HMENU hMenu = NULL;
159
160 hMenu = GetMenu(GetParent(hWindow));
161 if (hMenu != NULL)
162 {
163 updateMenuImages(hMenu, true);
164 updateMenuImages(m_hMainToolbarMenu);
165 updateMenuImages(m_hContextMenu);
166 updateMenuImages(m_hPrimitivesMenu);
167 }
168 }
169
initToolbar(HWND hToolbar,TbButtonInfoVector & infos,HIMAGELIST hImageList)170 void ToolbarStrip::initToolbar(
171 HWND hToolbar,
172 TbButtonInfoVector &infos,
173 HIMAGELIST hImageList)
174 {
175 TBBUTTON *buttons;
176 UCCHAR buttonTitle[128];
177 int i;
178 int count;
179
180 #ifndef TC_NO_UNICODE
181 SendMessage(hToolbar, TB_SETUNICODEFORMAT, (WPARAM)TRUE, 0);
182 #endif // !TC_NO_UNICODE
183 SendMessage(hToolbar, TB_SETEXTENDEDSTYLE, 0,
184 TBSTYLE_EX_DRAWDDARROWS | WS_EX_TRANSPARENT);
185 memset(buttonTitle, 0, sizeof(buttonTitle));
186 SendMessage(hToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
187 SendMessage(hToolbar, TB_SETBUTTONWIDTH, 0, MAKELONG(m_buttonWidth, m_buttonWidth));
188 SendMessage(hToolbar, TB_SETIMAGELIST, 0, (LPARAM)hImageList);
189 m_stdBitmapStartId = m_tbBitmapStartId = 0;
190 SendMessage(hToolbar, TB_ADDSTRING, 0, (LPARAM)buttonTitle);
191 count = (int)infos.size();
192 buttons = new TBBUTTON[count];
193 for (i = 0; i < count; i++)
194 {
195 fillTbButton(buttons[i], infos[i]);
196 buttons[i].iBitmap += infos[i].getSelection();
197 }
198 SendMessage(hToolbar, TB_ADDBUTTONS, count, (LPARAM)buttons);
199 if (!CUIThemes::isThemeActive() ||
200 ((CUIThemes::getThemeAppProperties() & STAP_ALLOW_CONTROLS) == 0))
201 {
202 SendMessage(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(m_buttonWidth, m_buttonHeight));
203 }
204 sizeToolbar(hToolbar, count);
205 delete[] buttons;
206 SendMessage(hToolbar, TB_SETHOTITEM, (WPARAM)-1, 0);
207 ShowWindow(hToolbar, SW_SHOW);
208 }
209
sizeToolbar(HWND hToolbar,int count)210 void ToolbarStrip::sizeToolbar(HWND hToolbar, int count)
211 {
212 RECT buttonRect;
213 RECT rect;
214 int lwidth;
215 int lheight;
216
217 GetWindowRect(hToolbar, &rect);
218 screenToClient(hWindow, &rect);
219 if (!SendMessage(hToolbar, TB_GETITEMRECT, count - 1, (LPARAM)&buttonRect))
220 {
221 buttonRect = rect;
222 buttonRect.left -= rect.left;
223 buttonRect.right -= rect.right;
224 }
225 lwidth = buttonRect.right;
226 lheight = buttonRect.bottom - buttonRect.top;
227 MoveWindow(hToolbar, rect.left, rect.top, lwidth, lheight, FALSE);
228 }
229
fillTbButton(TBBUTTON & button,const TbButtonInfo & buttonInfo)230 void ToolbarStrip::fillTbButton(
231 TBBUTTON &button,
232 const TbButtonInfo &buttonInfo)
233 {
234 button.iBitmap = buttonInfo.getBmpIndex();
235 button.idCommand = buttonInfo.getCommandId();
236 button.fsState = buttonInfo.getState();
237 button.fsStyle = buttonInfo.getStyle();
238 button.dwData = (DWORD_PTR)this;
239 button.iString = -1;
240 }
241
loadMainToolbarMenus(void)242 void ToolbarStrip::loadMainToolbarMenus(void)
243 {
244 m_hMainToolbarMenu = LoadMenu(getLanguageModule(),
245 MAKEINTRESOURCE(IDR_TOOLBAR_MENU));
246 m_hContextMenu = GetSubMenu(m_hMainToolbarMenu, 0);
247 m_hWireframeMenu = GetSubMenu(m_hMainToolbarMenu, 1);
248 m_hEdgesMenu = GetSubMenu(m_hMainToolbarMenu, 2);
249 m_hPrimitivesMenu = GetSubMenu(m_hMainToolbarMenu, 3);
250 m_hLightingMenu = GetSubMenu(m_hMainToolbarMenu, 4);
251 m_hBFCMenu = GetSubMenu(m_hMainToolbarMenu, 5);
252 }
253
initMainToolbar(void)254 void ToolbarStrip::initMainToolbar(void)
255 {
256 DWORD style = GetWindowLong(m_hToolbar, GWL_STYLE);
257
258 loadMainToolbarMenus();
259 populateMainTbButtonInfos();
260 SendMessage(m_hToolbar, TB_SETSTYLE, 0, style | CCS_ADJUSTABLE);
261 fillMainToolbar();
262 }
263
fillMainToolbar(void)264 void ToolbarStrip::fillMainToolbar(void)
265 {
266 size_t i;
267 LongVector mainButtonIDs;
268 LongSizeTMap mainButtonsMap;
269 TbButtonInfoVector buttonInfos;
270
271 for (i = 0; i < m_mainButtonInfos.size(); i++)
272 {
273 long commandID = m_mainButtonInfos[i].getCommandId();
274
275 if (i < NUM_DEFAULT_TB_BUTTONS)
276 {
277 mainButtonIDs.push_back(commandID);
278 }
279 mainButtonsMap[commandID] = i;
280 }
281 mainButtonIDs = TCUserDefaults::longVectorForKey(MAIN_TOOLBAR_IDS_KEY,
282 mainButtonIDs, false);
283 for (i = 0; i < mainButtonIDs.size(); i++)
284 {
285 int commandId = mainButtonIDs[i];
286
287 if (commandId > 0)
288 {
289 LongSizeTMap::const_iterator it = mainButtonsMap.find(commandId);
290
291 if (it != mainButtonsMap.end())
292 {
293 buttonInfos.push_back(m_mainButtonInfos[it->second]);
294 }
295 }
296 else
297 {
298 addTbSeparatorInfo(buttonInfos);
299 }
300 }
301 initToolbar(m_hToolbar, buttonInfos, m_imageLists.front());
302 }
303
initStepToolbar(void)304 void ToolbarStrip::initStepToolbar(void)
305 {
306 populateStepTbButtonInfos();
307 initToolbar(m_hStepToolbar, m_stepButtonInfos, m_imageLists.back());
308 }
309
autoSize(void)310 void ToolbarStrip::autoSize(void)
311 {
312 RECT rect;
313 RECT parentRect;
314
315 GetWindowRect(hWindow, &rect);
316 GetClientRect(m_ldviewWindow->getHWindow(), &parentRect);
317 screenToClient(m_ldviewWindow->getHWindow(), &rect);
318 MoveWindow(hWindow, rect.left, rect.top, parentRect.right - parentRect.left,
319 m_stripHeight, TRUE);
320 }
321
initLayout(void)322 void ToolbarStrip::initLayout(void)
323 {
324 RECT tbRect;
325 RECT rect;
326 int delta;
327 int left;
328 //int right;
329 int lmaxHeight;
330 size_t i;
331 int show = m_showSteps ? SW_SHOW : SW_HIDE;
332
333 ShowWindow(m_hToolbar, m_showMain ? SW_SHOW : SW_HIDE);
334 ShowWindow(m_hStepLabel, show);
335 ShowWindow(m_hNumStepsLabel, show);
336 GetWindowRect(m_hToolbar, &tbRect);
337 screenToClient(hWindow, &tbRect);
338 GetWindowRect(m_hStepLabel, &rect);
339 screenToClient(hWindow, &rect);
340 if (m_showMain)
341 {
342 delta = tbRect.right + 16 - rect.left;
343 }
344 else
345 {
346 delta = 4 - rect.left;
347 }
348 lmaxHeight = tbRect.bottom - tbRect.top;
349 for (i = 1; i < m_controls.size(); i++)
350 {
351 int lheight;
352
353 ShowWindow(m_controls[i], show);
354 GetWindowRect(m_controls[i], &rect);
355 screenToClient(hWindow, &rect);
356 lheight = rect.bottom - rect.top;
357 MoveWindow(m_controls[i], rect.left + delta, rect.top,
358 rect.right - rect.left, lheight, FALSE);
359 if (lheight > lmaxHeight)
360 {
361 lmaxHeight = lheight;
362 }
363 }
364 m_stripHeight = lmaxHeight + 4;
365 lmaxHeight += 4;
366 left = 4;
367 for (i = 0; i < m_controls.size(); i++)
368 {
369 int lheight;
370
371 GetWindowRect(m_controls[i], &rect);
372 screenToClient(hWindow, &rect);
373 lheight = rect.bottom - rect.top;
374 MoveWindow(m_controls[i], left, (lmaxHeight - lheight) / 2,
375 rect.right - rect.left, lheight, TRUE);
376 left += rect.right - rect.left + 2;
377 }
378 autoSize();
379 RedrawWindow(hWindow, NULL, NULL, RDW_ERASE | RDW_INVALIDATE);
380 }
381
stepChanged(void)382 void ToolbarStrip::stepChanged(void)
383 {
384 ModelWindow *modelWindow = m_ldviewWindow->getModelWindow();
385 LDrawModelViewer *modelViewer = modelWindow->getModelViewer();
386
387 if (modelViewer)
388 {
389 int step;
390
391 if (windowGetValue(IDC_STEP, step))
392 {
393 m_step = m_ldviewWindow->setStep(step);
394 updateStep();
395 }
396 }
397 else
398 {
399 updateStep();
400 }
401 }
402
enableToolbarButton(HWND hToolbar,UINT buttonId,bool enable)403 void ToolbarStrip::enableToolbarButton(
404 HWND hToolbar,
405 UINT buttonId,
406 bool enable)
407 {
408 BYTE state = (BYTE)SendMessage(hToolbar, TB_GETSTATE, (WPARAM)buttonId, 0);
409
410 if (state == -1)
411 {
412 state = 0;
413 }
414 if (enable)
415 {
416 state |= TBSTATE_ENABLED;
417 }
418 else
419 {
420 state &= ~TBSTATE_ENABLED;
421 }
422 SendMessage(hToolbar, TB_SETSTATE, (WPARAM)buttonId, MAKELONG(state, 0));
423 }
424
updateStep(void)425 void ToolbarStrip::updateStep(void)
426 {
427 LDrawModelViewer *modelViewer =
428 m_ldviewWindow->getModelWindow()->getModelViewer();
429 bool prevEnabled = false;
430 bool nextEnabled = false;
431
432 if (modelViewer)
433 {
434 m_step = modelViewer->getStep();
435 }
436 else
437 {
438 m_step = 0;
439 }
440 if (m_step > 0)
441 {
442 UCCHAR buf[1024];
443
444 sucprintf(buf, COUNT_OF(buf), _UC("%d"), m_step);
445 windowSetText(IDC_STEP, buf);
446 if (GetFocus() == m_hStepField)
447 {
448 SendMessage(m_hStepField, EM_SETSEL, 0, (LPARAM)-1);
449 }
450 prevEnabled = m_step > 1;
451 nextEnabled = m_step < modelViewer->getNumSteps();
452 }
453 else
454 {
455 windowSetText(IDC_STEP, _UC("--"));
456 }
457 enableToolbarButton(m_hStepToolbar, ID_FIRST_STEP, prevEnabled);
458 enableToolbarButton(m_hStepToolbar, ID_PREV_STEP, prevEnabled);
459 enableToolbarButton(m_hStepToolbar, ID_NEXT_STEP, nextEnabled);
460 enableToolbarButton(m_hStepToolbar, ID_LAST_STEP, nextEnabled);
461 RedrawWindow(m_hStepField, NULL, NULL, RDW_ERASE | RDW_INVALIDATE |
462 RDW_ERASENOW | RDW_UPDATENOW);
463 RedrawWindow(m_hStepToolbar, NULL, NULL, RDW_ERASE | RDW_INVALIDATE |
464 RDW_ERASENOW | RDW_UPDATENOW);
465 }
466
doTimer(UINT_PTR timerID)467 LRESULT ToolbarStrip::doTimer(UINT_PTR timerID)
468 {
469 switch (timerID)
470 {
471 case STEP_COUNT_CHANGED_TIMER:
472 stepCountChanged();
473 break;
474 }
475 return 0;
476 }
477
stepCountChanged(void)478 void ToolbarStrip::stepCountChanged(void)
479 {
480 KillTimer(hWindow, STEP_COUNT_CHANGED_TIMER);
481 UCCHAR buf[1024] = _UC("");
482
483 if (m_numSteps > 0)
484 {
485 sucprintf(buf, COUNT_OF(buf), m_numStepsFormat.c_str(), m_numSteps);
486 }
487 SIZE size;
488 HDC hNumStepsLabelDC = ::GetDC(m_hNumStepsLabel);
489 HANDLE hFont = (HANDLE)::SendMessage(m_hNumStepsLabel, WM_GETFONT, 0, 0);
490 HANDLE hOldFont = ::SelectObject(hNumStepsLabelDC, hFont);
491 CUIWindow::getTextExtentPoint32UC(hNumStepsLabelDC, buf, (int)ucstrlen(buf), &size);
492 ::SelectObject(hNumStepsLabelDC, hOldFont);
493 ::ReleaseDC(m_hNumStepsLabel, hNumStepsLabelDC);
494 RECT rect;
495 ::GetWindowRect(m_hNumStepsLabel, &rect);
496 CUIWindow::screenToClient(hWindow, &rect);
497 ::MoveWindow(m_hNumStepsLabel, rect.left, rect.top, size.cx + 4,
498 rect.bottom - rect.top, FALSE);
499 windowSetText(IDC_NUM_STEPS, buf);
500 initLayout();
501 }
502
updateNumSteps(void)503 void ToolbarStrip::updateNumSteps(void)
504 {
505 LDrawModelViewer *modelViewer =
506 m_ldviewWindow->getModelWindow()->getModelViewer();
507
508 if (modelViewer)
509 {
510 m_numSteps = modelViewer->getNumSteps();
511 }
512 else
513 {
514 m_numSteps = 0;
515 }
516 ::SetTimer(hWindow, STEP_COUNT_CHANGED_TIMER, 0, NULL);
517 }
518
519 #ifdef USE_GDIPLUS
updateMenuImages(HMENU hMenu,bool topMenu)520 void ToolbarStrip::updateMenuImages(HMENU hMenu, bool topMenu /*= false*/)
521 {
522 bool themed = m_ldviewWindow->isVisualStyleEnabled() ||
523 TCUserDefaults::boolForKey(FORCE_THEMED_MENUS_KEY, false, false);
524
525 //if (m_hGdiPlus == NULL)
526 //{
527 // return;
528 //}
529 int count = GetMenuItemCount(hMenu);
530
531 for (int i = 0; i < count; i++)
532 {
533 MENUITEMINFOUC mii;
534 UCCHAR stringBuf[1024];
535 HBITMAP hOldBitmap = NULL;
536
537 memset(&mii, 0, sizeof(mii));
538 mii.cbSize = sizeof(mii);
539 mii.fMask = MIIM_ID | MIIM_SUBMENU | MIIM_BITMAP;
540 if ((!themed || !have32BitBmps) && !topMenu)
541 {
542 mii.fMask |= MIIM_STRING;
543 mii.dwTypeData = stringBuf;
544 mii.cch = COUNT_OF(stringBuf);
545 }
546 GetMenuItemInfoUC(hMenu, i, TRUE, &mii);
547 hOldBitmap = mii.hbmpItem;
548 if ((!themed || !have32BitBmps) && !topMenu)
549 {
550 // Window sucks. When themes are disabled, menu item icons encroach
551 // into the beginning of the menu item text. So, to combat this, we
552 // need to add a space to the beginning of all menu items to allow
553 // space for the icon. Since the app's main menu doesn't have any
554 // icons, we'll skip the spaces on that.
555 ucstring menuString(_UC(" "));
556 MENUITEMINFOUC mii2 = mii;
557
558 menuString += mii.dwTypeData;
559 mii2.dwTypeData = &menuString[0];
560 mii2.fMask = MIIM_STRING;
561 SetMenuItemInfoUC(hMenu, i, TRUE, &mii2);
562 }
563 if (mii.hSubMenu)
564 {
565 updateMenuImages(mii.hSubMenu);
566 }
567 else
568 {
569 ImageIndexMap::const_iterator it = m_imagesMap.find(mii.wID);
570
571 if (it != m_imagesMap.end())
572 {
573 HBITMAP hMenuBitmap = NULL;
574
575 if (CUIScaler::use32bit())
576 {
577 double scaleFactor = m_scaleFactor;
578 // Menu sizes don't scale exactly with screen scale
579 // factor, and we want the icon to be as big as possible
580 // without being too big.
581 if (scaleFactor > 1.0 && scaleFactor <= 1.25)
582 {
583 // For some reason, the icon gets squished by Windows
584 // if we don't do this. I have no idea why.
585 scaleFactor = 1.0;
586 }
587 hMenuBitmap = TCImage::loadBmpFromPngResource(NULL,
588 translateCommandId(mii.wID), scaleFactor, true, 1);
589 }
590 else
591 {
592 HIMAGELIST hImageList = m_imageLists[it->second.first];
593 HICON hIcon = ImageList_GetIcon(hImageList,
594 it->second.second, ILD_TRANSPARENT);
595 Gdiplus::GpBitmap *pBitmap;
596 if (have32BitBmps)
597 {
598 if (GdipCreateBitmapFromHICON(hIcon, &pBitmap) ==
599 Gdiplus::Ok)
600 {
601 if (GdipCreateHBITMAPFromBitmap(pBitmap,
602 &hMenuBitmap, 0) != Gdiplus::Ok)
603 {
604 hMenuBitmap = NULL;
605 }
606 GdipDisposeImage(pBitmap);
607 }
608 }
609 else if (hIcon != NULL)
610 {
611 ICONINFO ii;
612 BITMAP bi;
613
614 if (::GetIconInfo(hIcon, &ii) &&
615 ::GetObject(ii.hbmColor, sizeof(bi), &bi))
616 {
617 HWND hParentWnd = ::GetParent(hWindow);
618 HDC hdcWin = ::GetDC(hParentWnd);
619 HDC hCompatDC = ::CreateCompatibleDC(hdcWin);
620 RECT rect;
621
622 rect.left = rect.top = 0;
623 // Windows has an off by one error, where it
624 // clobbers the right pixel of menu images.
625 rect.right = bi.bmWidth + 1;
626 rect.bottom = bi.bmHeight;
627 hMenuBitmap = ::CreateCompatibleBitmap(hdcWin,
628 bi.bmWidth + 1, bi.bmHeight);
629 HBITMAP hOldBitmap =
630 (HBITMAP)::SelectObject(hCompatDC, hMenuBitmap);
631 ::FillRect(hCompatDC, &rect,
632 ::GetSysColorBrush(COLOR_MENU));
633 ::DrawIconEx(hCompatDC, 0, 0, hIcon, bi.bmWidth,
634 bi.bmHeight, 0, NULL, DI_NORMAL);
635 ::SelectObject(hCompatDC, hOldBitmap);
636 ::ReleaseDC(hParentWnd, hdcWin);
637 ::ReleaseDC(NULL, hCompatDC);
638 }
639 }
640 if (hIcon != NULL)
641 {
642 ::DestroyIcon(hIcon);
643 }
644 }
645 if (hMenuBitmap != NULL)
646 {
647 mii.fMask = MIIM_BITMAP;
648 mii.hbmpItem = hMenuBitmap;
649 SetMenuItemInfoUC(hMenu, i, TRUE, &mii);
650 if (hOldBitmap != NULL)
651 {
652 DeleteObject(hOldBitmap);
653 }
654 }
655 }
656 }
657 }
658 }
659 #else // USE_GDIPLUS
updateMenuImages(HMENU,bool)660 void ToolbarStrip::updateMenuImages(HMENU, bool)
661 {
662 }
663 #endif // USE_GDIPLUS
664
doInitDialog(HWND)665 BOOL ToolbarStrip::doInitDialog(HWND /*hKbControl*/)
666 {
667 m_hToolbar = GetDlgItem(hWindow, IDC_TOOLBAR);
668 m_hStepLabel = GetDlgItem(hWindow, IDC_STEP_LABEL);
669 m_hStepField = GetDlgItem(hWindow, IDC_STEP);
670 m_hNumStepsLabel = GetDlgItem(hWindow, IDC_NUM_STEPS);
671 m_hStepToolbar = GetDlgItem(hWindow, IDC_STEP_TOOLBAR);
672 m_controls.push_back(m_hToolbar);
673 m_controls.push_back(m_hStepLabel);
674 m_controls.push_back(m_hStepField);
675 m_controls.push_back(m_hNumStepsLabel);
676 m_controls.push_back(m_hStepToolbar);
677
678 #ifdef USE_GDIPLUS
679 #pragma warning(push)
680 #pragma warning(disable:4996)
681 if ((GetVersion() & 0xFF) >= 6)
682 {
683 // We use GDI+ for creation of 32-bit color menu item bitmaps. These
684 // are only supported in menus in Vista and beyond, so don't even try
685 // to load it in earlier OSes.
686 m_hGdiPlus = LoadLibrary(_UC("gdiplus.dll"));
687 }
688 #pragma warning(pop)
689 ULONG_PTR gdiplusToken = 0;
690
691 if (m_hGdiPlus != NULL)
692 {
693 bool started = false;
694
695 GdiplusStartup = (PFNGDIPLUSSTARTUP)GetProcAddress(m_hGdiPlus,
696 "GdiplusStartup");
697 GdiplusShutdown = (PFNGDIPLUSSHUTDOWN)GetProcAddress(m_hGdiPlus,
698 "GdiplusShutdown");
699 GdipCreateBitmapFromHICON =
700 (PFNGDIPCREATEBITMAPFROMHICON)GetProcAddress(m_hGdiPlus,
701 "GdipCreateBitmapFromHICON");
702 GdipCreateHBITMAPFromBitmap =
703 (PFNGDIPCREATEHBITMAPFROMBITMAP)GetProcAddress(m_hGdiPlus,
704 "GdipCreateHBITMAPFromBitmap");
705 GdipDisposeImage = (PFNGDIPDISPOSEIMAGE)GetProcAddress(m_hGdiPlus,
706 "GdipDisposeImage");
707
708 if (GdiplusStartup != NULL &&
709 GdiplusShutdown != NULL &&
710 GdipCreateBitmapFromHICON != NULL &&
711 GdipCreateHBITMAPFromBitmap != NULL &&
712 GdipDisposeImage != NULL)
713 {
714 Gdiplus::GdiplusStartupInput gdiplusStartupInput;
715
716 // Initialize GDI+.
717 if (GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) ==
718 Gdiplus::Ok)
719 {
720 started = true;
721 have32BitBmps = true;
722 }
723 }
724 if (!started)
725 {
726 FreeLibrary(m_hGdiPlus);
727 m_hGdiPlus = NULL;
728 }
729 }
730 #endif // USE_GDIPLUS
731
732 windowGetText(IDC_NUM_STEPS, m_numStepsFormat);
733 windowSetText(IDC_NUM_STEPS, _UC(""));
734 m_scaleFactor = m_ldviewWindow->getScaleFactor();
735 if (m_scaleFactor > 1.0)
736 {
737 m_imageSize = (int)(16.0 * m_scaleFactor);
738 m_buttonWidth = (int)(22.0 * m_scaleFactor);
739 m_buttonHeight = (int)(24.0 * m_scaleFactor);
740 }
741 else
742 {
743 m_imageSize = 16;
744 m_buttonWidth = 22;
745 m_buttonHeight = 24;
746 }
747 initMainToolbar();
748 initStepToolbar();
749 checksReflect();
750 updateMenus();
751 initLayout();
752 updateStep();
753 updateNumSteps();
754 #ifdef USE_GDIPLUS
755 if (m_hGdiPlus != NULL)
756 {
757 GdiplusShutdown(gdiplusToken);
758 }
759 #endif // USE_GDIPLUS
760 return TRUE;
761 }
762
doTextFieldChange(int controlId,HWND control)763 LRESULT ToolbarStrip::doTextFieldChange(int controlId, HWND control)
764 {
765 return CUIDialog::doTextFieldChange(controlId, control);
766 }
767
doCommand(int notifyCode,int commandId,HWND control)768 LRESULT ToolbarStrip::doCommand(
769 int notifyCode,
770 int commandId,
771 HWND control)
772 {
773 switch (commandId)
774 {
775 case IDOK:
776 case EN_KILLFOCUS:
777 stepChanged();
778 return 0;
779 case ID_EDIT_PREFERENCES:
780 case ID_FILE_OPEN:
781 case ID_FILE_SAVE:
782 case ID_FILE_RELOAD:
783 case ID_VIEW_RESET:
784 case ID_VIEW_DEFAULT:
785 case ID_VIEW_FRONT:
786 case ID_VIEW_BACK:
787 case ID_VIEW_LEFT:
788 case ID_VIEW_RIGHT:
789 case ID_VIEW_TOP:
790 case ID_VIEW_BOTTOM:
791 case ID_VIEW_SPECIFYLATLON:
792 case ID_VIEW_ISO:
793 case ID_VIEW_SAVE_DEFAULT:
794 case ID_NEXT_STEP:
795 case ID_PREV_STEP:
796 case ID_FIRST_STEP:
797 case ID_LAST_STEP:
798 case ID_TOOLS_ERRORS:
799 case ID_VIEW_FULLSCREEN:
800 case ID_VIEW_ZOOMTOFIT:
801 case ID_HELP_CONTENTS:
802 case ID_TOOLS_MODELTREE:
803 case ID_TOOLS_BOUNDINGBOX:
804 case ID_VIEW_ALWAYSONTOP:
805 case ID_FILE_EXPORT:
806 case ID_FILE_PRINT:
807 case ID_VIEW_EXAMINE_LAT_LONG:
808 case ID_TOOLS_PARTSLIST:
809 case ID_TOOLS_MPD:
810 case ID_TOOLS_POV_CAMERA:
811 case ID_VIEW_RIGHTSIDEUP:
812 // Forward all these messages to LDViewWindow.
813 return SendMessage(m_ldviewWindow->getHWindow(), WM_COMMAND,
814 MAKEWPARAM(commandId, notifyCode), (LPARAM)control);
815 case IDC_WIREFRAME:
816 doWireframe();
817 break;
818 case IDC_SEAMS:
819 doSeams();
820 break;
821 case IDC_HIGHLIGHTS:
822 doEdges();
823 break;
824 case IDC_PRIMITIVE_SUBSTITUTION:
825 doPrimitiveSubstitution();
826 break;
827 case IDC_LIGHTING:
828 doLighting();
829 break;
830 case IDC_BFC:
831 doBfc();
832 break;
833 case IDC_SHOW_AXES:
834 doShowAxes();
835 break;
836 case IDC_RANDOM_COLORS:
837 doRandomColors();
838 break;
839 case IDC_ALL_CONDITIONAL:
840 doAllConditionals();
841 break;
842 case IDC_CONDITIONAL_CONTROLS:
843 doConditionalControls();
844 break;
845 case IDC_FLAT_SHADING:
846 doFlatShading();
847 break;
848 case IDC_CUTAWAY:
849 doCutaway();
850 break;
851 case IDC_STUD_QUALITY:
852 doStudQuality();
853 break;
854 case IDC_PART_BOUNDING_BOXES:
855 doPartBoundingBoxes();
856 break;
857 case IDC_SMOOTH_CURVES:
858 doSmoothCurves();
859 break;
860 case IDC_TRANS_DEFAULT_COLOR:
861 doTransDefaultColor();
862 break;
863 case ID_WIREFRAME_FOG:
864 doFog();
865 break;
866 case ID_WIREFRAME_REMOVEHIDDENLINES:
867 doRemoveHiddenLines();
868 break;
869 case ID_EDGES_SHOWEDGESONLY:
870 doShowEdgesOnly();
871 break;
872 case ID_EDGES_CONDITIONALLINES:
873 doConditionalLines();
874 break;
875 case ID_EDGES_HIGHQUALITY:
876 doHighQualityEdges();
877 break;
878 case ID_EDGES_ALWAYSBLACK:
879 doAlwaysBlack();
880 break;
881 case ID_PRIMITIVES_TEXTURESTUDS:
882 doTextureStuds();
883 break;
884 case ID_PRIMITIVES_TEXMAPS:
885 doTexmaps();
886 break;
887 case ID_LIGHTING_HIGHQUALITY:
888 doQualityLighting();
889 break;
890 case ID_LIGHTING_SUBDUED:
891 doSubduedLighting();
892 break;
893 case ID_LIGHTING_SPECULARHIGHLIGHT:
894 doSpecularHighlight();
895 break;
896 case ID_LIGHTING_ALTERNATESETUP:
897 doAlternateLighting();
898 break;
899 case ID_LIGHTING_DRAWDATS:
900 doDrawLightDats();
901 break;
902 case ID_LIGHTING_OPTIONALMAIN:
903 doOptionalStandardLight();
904 break;
905 case ID_BFC_REDBACKFACES:
906 doRedBackFaces();
907 break;
908 case ID_BFC_GREENFRONTFACES:
909 doGreenFrontFaces();
910 break;
911 case ID_BFC_BLUENEUTRALFACES:
912 doBlueNeutralFaces();
913 break;
914 case ID_TBCONTEXT_CUSTOMIZE:
915 doCustomizeMainToolbar();
916 break;
917 case ID_TBCONTEXT_MAIN:
918 doMainToolbar();
919 break;
920 case ID_TBCONTEXT_STEPS:
921 doStepsToolbar();
922 break;
923 case ID_VIEW_EXAMINE:
924 doViewMode();
925 break;
926 default:
927 return CUIDialog::doCommand(notifyCode, commandId, control);
928 }
929 return 0;
930 }
931
translateCommandId(int commandId)932 int ToolbarStrip::translateCommandId(int commandId)
933 {
934 IntIntMap::const_iterator it = m_commandMap.find(commandId);
935 if (it != m_commandMap.end())
936 {
937 return it->second;
938 }
939 return commandId;
940 }
941
addToImageList(int commandId)942 int ToolbarStrip::addToImageList(int commandId)
943 {
944 int newCommandId = translateCommandId(commandId);
945 TCImage *image;
946 static bool disableHighRes = false;
947
948 //#ifdef _DEBUG
949 // // Make sure scaling works, but also make sure high-res versions work.
950 // disableHighRes = !disableHighRes;
951 //#endif
952 image = TCImage::createFromResource(NULL, newCommandId, 4, true,
953 disableHighRes ? 1.0 : m_scaleFactor);
954 if (image != NULL)
955 {
956 SIZE imageSize = { m_imageSize, m_imageSize };
957 int imageIndex = addImageToImageList(m_imageLists.back(), image, imageSize);
958 image->release();
959 if (imageIndex >= 0)
960 {
961 m_imagesMap[commandId].first = m_imageLists.size() - 1;
962 m_imagesMap[commandId].second = imageIndex;
963 }
964 return imageIndex;
965 }
966 return -1;
967 }
968
addTbButtonInfo(TbButtonInfoVector & infos,CUCSTR tooltipText,int commandId,BYTE style,BYTE state)969 void ToolbarStrip::addTbButtonInfo(
970 TbButtonInfoVector &infos,
971 CUCSTR tooltipText,
972 int commandId,
973 BYTE style,
974 BYTE state)
975 {
976 infos.resize(infos.size() + 1);
977 TbButtonInfo &buttonInfo = infos.back();
978 buttonInfo.setTooltipText(tooltipText);
979 buttonInfo.setCommandId(commandId);
980 buttonInfo.setBmpIndex(addToImageList(commandId));
981 buttonInfo.setStyle(style);
982 buttonInfo.setState(state);
983 }
984
addTbCheckButtonInfo(TbButtonInfoVector & infos,CUCSTR tooltipText,int commandId,bool checked,BYTE style,BYTE state)985 void ToolbarStrip::addTbCheckButtonInfo(
986 TbButtonInfoVector &infos,
987 CUCSTR tooltipText,
988 int commandId,
989 bool checked,
990 BYTE style,
991 BYTE state)
992 {
993 state &= ~TBSTATE_CHECKED;
994 if (checked)
995 {
996 state |= TBSTATE_CHECKED;
997 }
998 addTbButtonInfo(infos, tooltipText, commandId, style, state);
999 }
1000
addTbStateButtonInfo(TbButtonInfoVector & infos,CUCSTR tooltipText,IntVector commandIds,int selection,BYTE style,BYTE state)1001 void ToolbarStrip::addTbStateButtonInfo(
1002 TbButtonInfoVector &infos,
1003 CUCSTR tooltipText,
1004 IntVector commandIds,
1005 int selection,
1006 BYTE style /*= TBSTYLE_BUTTON*/,
1007 BYTE state /*= TBSTATE_ENABLED*/)
1008 {
1009 addTbButtonInfo(infos, tooltipText, commandIds.front(), style,
1010 state | TBSTATE_CHECKED);
1011 TbButtonInfo &buttonInfo = infos.back();
1012 buttonInfo.setSelection(selection);
1013 for (size_t i = 1; i < commandIds.size(); i++)
1014 {
1015 buttonInfo.addCommandId(commandIds[i]);
1016 addToImageList(commandIds[i]);
1017 }
1018 }
1019
addTbSeparatorInfo(TbButtonInfoVector & infos)1020 void ToolbarStrip::addTbSeparatorInfo(TbButtonInfoVector &infos)
1021 {
1022 infos.resize(infos.size() + 1);
1023 TbButtonInfo &buttonInfo = infos.back();
1024
1025 buttonInfo.setStyle(TBSTYLE_SEP);
1026 }
1027
populateStepTbButtonInfos(void)1028 void ToolbarStrip::populateStepTbButtonInfos(void)
1029 {
1030 if (m_stepButtonInfos.size() == 0)
1031 {
1032 m_imageLists.push_back(ImageList_Create(m_imageSize, m_imageSize,
1033 CUIScaler::imageListCreateFlags(), 0, 10));
1034 addTbButtonInfo(m_stepButtonInfos,
1035 ls(_UC("FirstStep")), ID_FIRST_STEP);
1036 addTbButtonInfo(m_stepButtonInfos,
1037 ls(_UC("PrevStep")), ID_PREV_STEP);
1038 addTbButtonInfo(m_stepButtonInfos,
1039 ls(_UC("NextStep")), ID_NEXT_STEP);
1040 addTbButtonInfo(m_stepButtonInfos,
1041 ls(_UC("LastStep")), ID_LAST_STEP);
1042 }
1043 }
1044
syncViewMode(void)1045 void ToolbarStrip::syncViewMode(void)
1046 {
1047 m_viewMode =
1048 (LDInputHandler::ViewMode)TCUserDefaults::longForKey(VIEW_MODE_KEY, 0,
1049 false);
1050 }
1051
populateMainTbButtonInfos(void)1052 void ToolbarStrip::populateMainTbButtonInfos(void)
1053 {
1054 if (m_mainButtonInfos.size() == 0)
1055 {
1056 m_imageLists.push_back(ImageList_Create(m_imageSize, m_imageSize,
1057 CUIScaler::imageListCreateFlags(), 0, 100));
1058 addTbButtonInfo(m_mainButtonInfos, ls(_UC("OpenFile")),
1059 ID_FILE_OPEN);
1060 addTbButtonInfo(m_mainButtonInfos,
1061 ls(_UC("SaveSnapshot")), ID_FILE_SAVE);
1062 addTbButtonInfo(m_mainButtonInfos, ls(_UC("Reload")),
1063 ID_FILE_RELOAD);
1064 addTbSeparatorInfo(m_mainButtonInfos);
1065 m_drawWireframe = m_prefs->getDrawWireframe();
1066 m_seams = m_prefs->getUseSeams() != 0;
1067 m_edges = m_prefs->getShowsHighlightLines();
1068 m_primitiveSubstitution = m_prefs->getAllowPrimitiveSubstitution();
1069 m_lighting = m_prefs->getUseLighting();
1070 m_bfc = m_prefs->getBfc();
1071 m_showAxes = m_prefs->getShowAxes();
1072 m_randomColors = m_prefs->getRandomColors();
1073 m_allConditionals = m_prefs->getShowAllConditionalLines();
1074 m_conditionalControls = m_prefs->getShowConditionalControlPoints();
1075 m_flat = m_prefs->getUseFlatShading();
1076 m_wireframeCutaway = m_prefs->getCutawayMode() == LDVCutawayWireframe;
1077 m_lowStuds = !m_prefs->getQualityStuds();
1078 m_partBBoxes = m_prefs->getBoundingBoxesOnly();
1079 m_smoothCurves = m_prefs->getPerformSmoothing();
1080 m_transDefaultColor = m_prefs->getTransDefaultColor();
1081 m_texmaps = m_prefs->getTexmaps();
1082 m_examineLatLong = TCUserDefaults::longForKey(EXAMINE_MODE_KEY,
1083 LDrawModelViewer::EMFree, false) == LDrawModelViewer::EMLatLong;
1084 m_modelBoundingBox = m_ldviewWindow->isBoundingBoxVisible();
1085 m_topmost = m_ldviewWindow->isTopmost();
1086 syncViewMode();
1087 addTbCheckButtonInfo(m_mainButtonInfos,
1088 ls(_UC("Wireframe")), IDC_WIREFRAME,
1089 m_drawWireframe, TBSTYLE_CHECK | TBSTYLE_DROPDOWN);
1090 addTbCheckButtonInfo(m_mainButtonInfos,
1091 ls(_UC("Seams")), IDC_SEAMS, m_seams);
1092 addTbCheckButtonInfo(m_mainButtonInfos,
1093 ls(_UC("EdgeLines")), IDC_HIGHLIGHTS, m_edges,
1094 TBSTYLE_CHECK | TBSTYLE_DROPDOWN);
1095 addTbCheckButtonInfo(m_mainButtonInfos,
1096 ls(_UC("PrimitiveSubstitution")),
1097 IDC_PRIMITIVE_SUBSTITUTION, m_primitiveSubstitution,
1098 TBSTYLE_CHECK | TBSTYLE_DROPDOWN);
1099 addTbCheckButtonInfo(m_mainButtonInfos,
1100 ls(_UC("Lighting")), IDC_LIGHTING, m_lighting,
1101 TBSTYLE_CHECK | TBSTYLE_DROPDOWN);
1102 addTbButtonInfo(m_mainButtonInfos,
1103 ls(_UC("RightSideUp")), ID_VIEW_RIGHTSIDEUP);
1104 addTbButtonInfo(m_mainButtonInfos,
1105 ls(_UC("SelectView")), ID_VIEWANGLE,
1106 TBSTYLE_DROPDOWN | BTNS_WHOLEDROPDOWN);
1107 IntVector viewCommandIds;
1108 viewCommandIds.push_back(ID_VIEW_EXAMINE);
1109 viewCommandIds.push_back(ID_VIEW_FLYTHROUGH);
1110 viewCommandIds.push_back(ID_VIEW_WALK);
1111 addTbStateButtonInfo(m_mainButtonInfos,
1112 ls(_UC("ViewMode")), viewCommandIds, m_viewMode);
1113 addTbButtonInfo(m_mainButtonInfos,
1114 ls(_UC("Preferences")), ID_EDIT_PREFERENCES);
1115 addTbCheckButtonInfo(m_mainButtonInfos,
1116 ls(_UC("ViewLatLonRot")),
1117 ID_VIEW_EXAMINE_LAT_LONG, m_examineLatLong);
1118 addTbCheckButtonInfo(m_mainButtonInfos,
1119 ls(_UC("TransDefaultColor")),
1120 IDC_TRANS_DEFAULT_COLOR, m_transDefaultColor);
1121 addTbCheckButtonInfo(m_mainButtonInfos,
1122 ls(_UC("RandomColors")), IDC_RANDOM_COLORS,
1123 m_randomColors);
1124 addTbCheckButtonInfo(m_mainButtonInfos,
1125 ls(_UC("ShowAxes")), IDC_SHOW_AXES, m_showAxes);
1126 addTbCheckButtonInfo(m_mainButtonInfos,
1127 ls(_UC("PartBoundingBoxesOnly")),
1128 IDC_PART_BOUNDING_BOXES, m_partBBoxes);
1129 addTbCheckButtonInfo(m_mainButtonInfos, ls(_UC("BFC")),
1130 IDC_BFC, m_bfc, TBSTYLE_CHECK | TBSTYLE_DROPDOWN);
1131 addTbCheckButtonInfo(m_mainButtonInfos,
1132 ls(_UC("ShowAllConditionals")), IDC_ALL_CONDITIONAL,
1133 m_allConditionals);
1134 addTbCheckButtonInfo(m_mainButtonInfos,
1135 ls(_UC("ShowConditionalControls")),
1136 IDC_CONDITIONAL_CONTROLS, m_conditionalControls);
1137 addTbCheckButtonInfo(m_mainButtonInfos,
1138 ls(_UC("WireframeCutaway")), IDC_CUTAWAY,
1139 m_wireframeCutaway);
1140 addTbCheckButtonInfo(m_mainButtonInfos,
1141 ls(_UC("FlatShading")), IDC_FLAT_SHADING, m_flat);
1142 addTbCheckButtonInfo(m_mainButtonInfos,
1143 ls(_UC("SmoothCurves")), IDC_SMOOTH_CURVES,
1144 m_smoothCurves);
1145 addTbCheckButtonInfo(m_mainButtonInfos, ls(_UC("Texmaps")),
1146 ID_PRIMITIVES_TEXMAPS, m_texmaps);
1147 addTbCheckButtonInfo(m_mainButtonInfos,
1148 ls(_UC("TextureStuds")),
1149 ID_PRIMITIVES_TEXTURESTUDS, m_prefs->getTextureStuds());
1150 addTbCheckButtonInfo(m_mainButtonInfos,
1151 ls(_UC("LowQualityStuds")), IDC_STUD_QUALITY,
1152 m_lowStuds);
1153 addTbButtonInfo(m_mainButtonInfos, ls(_UC("Export")),
1154 ID_FILE_EXPORT);
1155 addTbButtonInfo(m_mainButtonInfos, ls(_UC("Print")),
1156 ID_FILE_PRINT);
1157 addTbButtonInfo(m_mainButtonInfos,
1158 ls(_UC("FullScreen")), ID_VIEW_FULLSCREEN);
1159 addTbCheckButtonInfo(m_mainButtonInfos,
1160 ls(_UC("AlwaysOnTop")), ID_VIEW_ALWAYSONTOP,
1161 m_topmost);
1162 addTbButtonInfo(m_mainButtonInfos,
1163 ls(_UC("ZoomToFit")), ID_VIEW_ZOOMTOFIT);
1164 addTbButtonInfo(m_mainButtonInfos,
1165 ls(_UC("FrontView")), ID_VIEW_FRONT);
1166 addTbButtonInfo(m_mainButtonInfos,
1167 ls(_UC("BackView")), ID_VIEW_BACK);
1168 addTbButtonInfo(m_mainButtonInfos, ls(_UC("LeftView")),
1169 ID_VIEW_LEFT);
1170 addTbButtonInfo(m_mainButtonInfos,
1171 ls(_UC("RightView")), ID_VIEW_RIGHT);
1172 addTbButtonInfo(m_mainButtonInfos, ls(_UC("TopView")),
1173 ID_VIEW_TOP);
1174 addTbButtonInfo(m_mainButtonInfos,
1175 ls(_UC("BottomView")), ID_VIEW_BOTTOM);
1176 addTbButtonInfo(m_mainButtonInfos,
1177 ls(_UC("LatLonView")), ID_VIEW_SPECIFYLATLON);
1178 addTbButtonInfo(m_mainButtonInfos,
1179 ls(_UC("TwoThirdsView")), ID_VIEW_ISO);
1180 addTbButtonInfo(m_mainButtonInfos,
1181 ls(_UC("ErrorsAndWarnings")), ID_TOOLS_ERRORS);
1182 addTbButtonInfo(m_mainButtonInfos,
1183 ls(_UC("PartsList")), ID_TOOLS_PARTSLIST);
1184 addTbButtonInfo(m_mainButtonInfos,
1185 ls(_UC("ModelTree")), ID_TOOLS_MODELTREE);
1186 addTbCheckButtonInfo(m_mainButtonInfos,
1187 ls(_UC("ModelBBox")), ID_TOOLS_BOUNDINGBOX,
1188 m_modelBoundingBox);
1189 addTbButtonInfo(m_mainButtonInfos,
1190 ls(_UC("MPDModelSelection")), ID_TOOLS_MPD);
1191 addTbButtonInfo(m_mainButtonInfos,
1192 ls(_UC("POVCameraInfo")), ID_TOOLS_POV_CAMERA);
1193 addTbButtonInfo(m_mainButtonInfos, ls(_UC("Help")),
1194 ID_HELP_CONTENTS);
1195 }
1196 }
1197
doToolbarGetInfotip(TbButtonInfoVector & infos,LPNMTBGETINFOTIPUC dispInfo)1198 LRESULT ToolbarStrip::doToolbarGetInfotip(
1199 TbButtonInfoVector &infos,
1200 LPNMTBGETINFOTIPUC dispInfo)
1201 {
1202 int i;
1203 int count = (int)infos.size();
1204
1205 for (i = 0; i < count; i++)
1206 {
1207 TbButtonInfo &buttonInfo = infos[i];
1208
1209 if (buttonInfo.getCommandId() == dispInfo->iItem)
1210 {
1211 if (CUIThemes::isThemeLibLoaded())
1212 {
1213 //HWND hTooltip = (HWND)SendMessage(dispInfo->hdr.hwndFrom,
1214 // TB_GETTOOLTIPS, 0, 0);
1215 //// Turning off theme support in the tooltip makes it
1216 //// work properly. With theme support on, it gets erased
1217 //// by the OpenGL window immediately after being drawn.
1218 //// Haven't the foggiest why this happens, but turning
1219 //// off theme support solves the problem. This has to
1220 //// be done every time the tooltip is about to pop up.
1221 //// Not sure why that is either, but it is.
1222 //CUIThemes::setWindowTheme(hTooltip, NULL, L"");
1223 }
1224 if (m_ldviewWindow->getLoading())
1225 {
1226 // Don't allow tooltips to pop up while loading; they
1227 // prevent the loading from continuing until they go
1228 // away.
1229 dispInfo->pszText = NULL;
1230 }
1231 else
1232 {
1233 ucstrncpy(dispInfo->pszText, buttonInfo.getTooltipText(),
1234 dispInfo->cchTextMax);
1235 dispInfo->pszText[dispInfo->cchTextMax - 1] = 0;
1236 }
1237 break;
1238 }
1239 }
1240 return 0;
1241 }
1242
doMainTbGetButtonInfo(NMTOOLBARUC * notification)1243 LRESULT ToolbarStrip::doMainTbGetButtonInfo(NMTOOLBARUC *notification)
1244 {
1245 int index = notification->iItem;
1246 int skipCount = 0;
1247
1248 for (int i = 0; i <= index && i + skipCount < (int)m_mainButtonInfos.size();
1249 i++)
1250 {
1251 if (m_mainButtonInfos[i].getStyle() == TBSTYLE_SEP)
1252 {
1253 skipCount++;
1254 }
1255 }
1256 if (index + skipCount < (int)m_mainButtonInfos.size())
1257 {
1258 TbButtonInfo &buttonInfo = m_mainButtonInfos[index + skipCount];
1259
1260 ucstrncpy(notification->pszText, buttonInfo.getTooltipText(),
1261 notification->cchText);
1262 notification->pszText[notification->cchText - 1] = 0;
1263 notification->cchText = (int)ucstrlen(notification->pszText);
1264 fillTbButton(notification->tbButton, buttonInfo);
1265 SetWindowLongPtr(hWindow, DWLP_MSGRESULT, TRUE);
1266 return TRUE;
1267 }
1268 SetWindowLongPtr(hWindow, DWLP_MSGRESULT, FALSE);
1269 return FALSE;
1270 }
1271
doMainToolbarReset(void)1272 LRESULT ToolbarStrip::doMainToolbarReset(void)
1273 {
1274 for (int i = 0; true; i++)
1275 {
1276 if (SendMessage(m_hToolbar, TB_DELETEBUTTON, 0, 0))
1277 {
1278 char key[128];
1279
1280 sprintf(key, "%s%02d", MAIN_TOOLBAR_IDS_KEY, i);
1281 TCUserDefaults::removeValue(key, false);
1282 }
1283 else
1284 {
1285 break;
1286 }
1287
1288 }
1289 fillMainToolbar();
1290 initLayout();
1291 return 0;
1292 }
1293
doMainToolbarChange(void)1294 LRESULT ToolbarStrip::doMainToolbarChange(void)
1295 {
1296 LongVector mainButtonIDs;
1297
1298 for (int i = 0; true; i++)
1299 {
1300 TBBUTTON button;
1301
1302 if (SendMessage(m_hToolbar, TB_GETBUTTON, i, (LPARAM)&button))
1303 {
1304 mainButtonIDs.push_back(button.idCommand);
1305 }
1306 else
1307 {
1308 break;
1309 }
1310 }
1311 TCUserDefaults::setLongVectorForKey(mainButtonIDs, MAIN_TOOLBAR_IDS_KEY,
1312 false);
1313 sizeToolbar(m_hToolbar, (int)mainButtonIDs.size());
1314 initLayout();
1315 return 0; // ignored
1316 }
1317
doMainToolbarNotify(int controlId,LPNMHDR notification)1318 LRESULT ToolbarStrip::doMainToolbarNotify(int controlId, LPNMHDR notification)
1319 {
1320 //debugPrintf("LDViewWindow::doMainToolbarNotify: 0x%04X, %s\n", controlId,
1321 // notificationName(notification->code).c_str());
1322 switch (notification->code)
1323 {
1324 case TBN_GETINFOTIPUC:
1325 return doToolbarGetInfotip(m_mainButtonInfos,
1326 (LPNMTBGETINFOTIPUC)notification);
1327 case TBN_DROPDOWN:
1328 if (notification->idFrom == ID_TOOLBAR ||
1329 notification->idFrom == IDC_TOOLBAR)
1330 {
1331 doDropDown((LPNMTOOLBAR)notification);
1332 }
1333 break;
1334 case TBN_QUERYDELETE:
1335 case TBN_QUERYINSERT:
1336 SetWindowLongPtr(hWindow, DWLP_MSGRESULT, TRUE);
1337 return TRUE;
1338 case TBN_GETBUTTONINFOUC:
1339 return doMainTbGetButtonInfo((NMTOOLBARUC *)notification);
1340 case TBN_TOOLBARCHANGE:
1341 return doMainToolbarChange();
1342 case TBN_RESET:
1343 return doMainToolbarReset();
1344 default:
1345 return CUIWindow::doNotify(controlId, notification);
1346 }
1347 return 0;
1348 }
1349
doStepToolbarNotify(int controlId,LPNMHDR notification)1350 LRESULT ToolbarStrip::doStepToolbarNotify(int controlId, LPNMHDR notification)
1351 {
1352 //debugPrintf("LDViewWindow::doStepToolbarNotify: 0x%04X, %s\n", controlId,
1353 // notificationName(notification->code).c_str());
1354 switch (notification->code)
1355 {
1356 case TBN_GETINFOTIPUC:
1357 return doToolbarGetInfotip(m_stepButtonInfos,
1358 (LPNMTBGETINFOTIPUC)notification);
1359 default:
1360 return CUIWindow::doNotify(controlId, notification);
1361 }
1362 return 0;
1363 }
1364
doNotify(int controlId,LPNMHDR notification)1365 LRESULT ToolbarStrip::doNotify(int controlId, LPNMHDR notification)
1366 {
1367 if (notification->hwndFrom == m_hToolbar)
1368 {
1369 return doMainToolbarNotify(controlId, notification);
1370 }
1371 else if (notification->hwndFrom == m_hStepToolbar)
1372 {
1373 return doStepToolbarNotify(controlId, notification);
1374 }
1375 else
1376 {
1377 return CUIDialog::doNotify(controlId, notification);
1378 }
1379 }
1380
enableMainToolbarButton(UINT buttonId,bool enable)1381 void ToolbarStrip::enableMainToolbarButton(UINT buttonId, bool enable)
1382 {
1383 enableToolbarButton(m_hToolbar, buttonId, enable);
1384 }
1385
updateContextMenu(void)1386 void ToolbarStrip::updateContextMenu(void)
1387 {
1388 setMenuCheck(m_hContextMenu, ID_TBCONTEXT_MAIN, m_showMain);
1389 setMenuCheck(m_hContextMenu, ID_TBCONTEXT_STEPS, m_showSteps);
1390 }
1391
updateWireframeMenu(void)1392 void ToolbarStrip::updateWireframeMenu(void)
1393 {
1394 setMenuCheck(m_hWireframeMenu, ID_WIREFRAME_FOG,
1395 m_prefs->getUseWireframeFog());
1396 setMenuCheck(m_hWireframeMenu, ID_WIREFRAME_REMOVEHIDDENLINES,
1397 m_prefs->getRemoveHiddenLines());
1398 setMenuItemsEnabled(m_hWireframeMenu, m_drawWireframe);
1399 }
1400
updateEdgesMenu(void)1401 void ToolbarStrip::updateEdgesMenu(void)
1402 {
1403 setMenuCheck(m_hEdgesMenu, ID_EDGES_SHOWEDGESONLY,
1404 m_prefs->getEdgesOnly());
1405 setMenuCheck(m_hEdgesMenu, ID_EDGES_CONDITIONALLINES,
1406 m_prefs->getDrawConditionalHighlights());
1407 setMenuCheck(m_hEdgesMenu, ID_EDGES_HIGHQUALITY,
1408 m_prefs->getUsePolygonOffset());
1409 setMenuCheck(m_hEdgesMenu, ID_EDGES_ALWAYSBLACK,
1410 m_prefs->getBlackHighlights());
1411 setMenuItemsEnabled(m_hEdgesMenu, m_edges);
1412 }
1413
updatePrimitivesMenu(void)1414 void ToolbarStrip::updatePrimitivesMenu(void)
1415 {
1416 setMenuCheck(m_hPrimitivesMenu, ID_PRIMITIVES_TEXTURESTUDS,
1417 m_prefs->getTextureStuds());
1418 setMenuCheck(m_hPrimitivesMenu, ID_PRIMITIVES_TEXMAPS,
1419 m_texmaps);
1420 setMenuItemsEnabled(m_hPrimitivesMenu, m_primitiveSubstitution);
1421 }
1422
updateLightingMenu(void)1423 void ToolbarStrip::updateLightingMenu(void)
1424 {
1425 setMenuCheck(m_hLightingMenu, ID_LIGHTING_HIGHQUALITY,
1426 m_prefs->getQualityLighting());
1427 setMenuCheck(m_hLightingMenu, ID_LIGHTING_SUBDUED,
1428 m_prefs->getSubduedLighting());
1429 setMenuCheck(m_hLightingMenu, ID_LIGHTING_SPECULARHIGHLIGHT,
1430 m_prefs->getUsesSpecular());
1431 setMenuCheck(m_hLightingMenu, ID_LIGHTING_ALTERNATESETUP,
1432 m_prefs->getOneLight());
1433 setMenuCheck(m_hLightingMenu, ID_LIGHTING_DRAWDATS,
1434 m_prefs->getDrawLightDats());
1435 setMenuCheck(m_hLightingMenu, ID_LIGHTING_OPTIONALMAIN,
1436 m_prefs->getOptionalStandardLight());
1437 setMenuItemsEnabled(m_hLightingMenu, m_lighting);
1438 if (!m_prefs->getDrawLightDats())
1439 {
1440 setMenuEnabled(m_hLightingMenu, ID_LIGHTING_OPTIONALMAIN, false,
1441 FALSE);
1442 setMenuCheck(m_hLightingMenu, ID_LIGHTING_OPTIONALMAIN, false);
1443 }
1444 }
1445
updateBFCMenu(void)1446 void ToolbarStrip::updateBFCMenu(void)
1447 {
1448 setMenuCheck(m_hBFCMenu, ID_BFC_REDBACKFACES,
1449 m_prefs->getRedBackFaces());
1450 setMenuCheck(m_hBFCMenu, ID_BFC_GREENFRONTFACES,
1451 m_prefs->getGreenFrontFaces());
1452 setMenuCheck(m_hBFCMenu, ID_BFC_BLUENEUTRALFACES,
1453 m_prefs->getBlueNeutralFaces());
1454 setMenuItemsEnabled(m_hBFCMenu, m_bfc);
1455 }
1456
doDropDown(LPNMTOOLBAR toolbarNot)1457 void ToolbarStrip::doDropDown(LPNMTOOLBAR toolbarNot)
1458 {
1459 RECT rect;
1460 TPMPARAMS tpm;
1461 HMENU hMenu = NULL;
1462
1463 SendMessage(toolbarNot->hdr.hwndFrom, TB_GETRECT, (WPARAM)toolbarNot->iItem,
1464 (LPARAM)&rect);
1465 MapWindowPoints(toolbarNot->hdr.hwndFrom, HWND_DESKTOP, (LPPOINT)&rect, 2);
1466 tpm.cbSize = sizeof(TPMPARAMS);
1467 tpm.rcExclude.top = rect.top;
1468 tpm.rcExclude.left = rect.left;
1469 tpm.rcExclude.bottom = rect.bottom;
1470 tpm.rcExclude.right = rect.right;
1471 switch (toolbarNot->iItem)
1472 {
1473 case IDC_WIREFRAME:
1474 hMenu = m_hWireframeMenu;
1475 break;
1476 case IDC_HIGHLIGHTS:
1477 hMenu = m_hEdgesMenu;
1478 break;
1479 case IDC_PRIMITIVE_SUBSTITUTION:
1480 hMenu = m_hPrimitivesMenu;
1481 break;
1482 case IDC_LIGHTING:
1483 hMenu = m_hLightingMenu;
1484 break;
1485 case IDC_BFC:
1486 hMenu = m_hBFCMenu;
1487 break;
1488 case ID_VIEWANGLE:
1489 hMenu = m_ldviewWindow->getViewAngleMenu();
1490 break;
1491 }
1492 if (hMenu)
1493 {
1494 BOOL fade;
1495
1496 // Note: selection fade causes a display glitch. This is an obscenely
1497 // ugly hack to get rid of that, but it does work. The problem still
1498 // exists when the menu item is selected from the main menu, though.
1499 // Did I mention yet today that Microsoft sucks?
1500 SystemParametersInfo(SPI_GETSELECTIONFADE, 0, &fade, 0);
1501 if (fade)
1502 {
1503 // We better pray it doesn't crash between here and where we put
1504 // things back below.
1505 SystemParametersInfo(SPI_SETSELECTIONFADE, FALSE, NULL, 0);
1506 }
1507 TrackPopupMenuEx(hMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL,
1508 rect.left, rect.bottom, hWindow, &tpm);
1509 if (fade)
1510 {
1511 SystemParametersInfo(SPI_SETSELECTIONFADE, 0, &fade, 0);
1512 }
1513 }
1514 }
1515
forceRedraw(void)1516 void ToolbarStrip::forceRedraw(void)
1517 {
1518 ModelWindow *modelWindow = m_ldviewWindow->getModelWindow();
1519
1520 if (modelWindow)
1521 {
1522 modelWindow->forceRedraw();
1523 }
1524 }
1525
doWireframe(void)1526 void ToolbarStrip::doWireframe(void)
1527 {
1528 if (doCheck(m_drawWireframe, IDC_WIREFRAME))
1529 {
1530 m_prefs->setDrawWireframe(m_drawWireframe);
1531 forceRedraw();
1532 }
1533 }
1534
doSeams(void)1535 void ToolbarStrip::doSeams(void)
1536 {
1537 if (doCheck(m_seams, IDC_SEAMS))
1538 {
1539 m_prefs->setUseSeams(m_seams);
1540 forceRedraw();
1541 }
1542 }
1543
doEdges(void)1544 void ToolbarStrip::doEdges(void)
1545 {
1546 if (doCheck(m_edges, IDC_HIGHLIGHTS))
1547 {
1548 m_prefs->setShowsHighlightLines(m_edges);
1549 forceRedraw();
1550 }
1551 }
1552
doPrimitiveSubstitution(void)1553 void ToolbarStrip::doPrimitiveSubstitution(void)
1554 {
1555 if (doCheck(m_primitiveSubstitution, IDC_PRIMITIVE_SUBSTITUTION))
1556 {
1557 m_prefs->setAllowPrimitiveSubstitution(m_primitiveSubstitution);
1558 forceRedraw();
1559 }
1560 }
1561
doLighting(void)1562 void ToolbarStrip::doLighting(void)
1563 {
1564 if (doCheck(m_lighting, IDC_LIGHTING))
1565 {
1566 m_prefs->setUseLighting(m_lighting);
1567 forceRedraw();
1568 }
1569 }
1570
doFog(void)1571 void ToolbarStrip::doFog(void)
1572 {
1573 m_prefs->setUseWireframeFog(!m_prefs->getUseWireframeFog());
1574 setMenuCheck(m_hWireframeMenu, ID_WIREFRAME_FOG,
1575 m_prefs->getUseWireframeFog());
1576 }
1577
doRemoveHiddenLines(void)1578 void ToolbarStrip::doRemoveHiddenLines(void)
1579 {
1580 m_prefs->setRemoveHiddenLines(!m_prefs->getRemoveHiddenLines());
1581 setMenuCheck(m_hWireframeMenu, ID_WIREFRAME_REMOVEHIDDENLINES,
1582 m_prefs->getRemoveHiddenLines());
1583 }
1584
doShowEdgesOnly(void)1585 void ToolbarStrip::doShowEdgesOnly(void)
1586 {
1587 m_prefs->setEdgesOnly(!m_prefs->getEdgesOnly());
1588 setMenuCheck(m_hEdgesMenu, ID_EDGES_SHOWEDGESONLY,
1589 m_prefs->getEdgesOnly());
1590 }
1591
doConditionalLines(void)1592 void ToolbarStrip::doConditionalLines(void)
1593 {
1594 m_prefs->setDrawConditionalHighlights(!m_prefs->getDrawConditionalHighlights());
1595 setMenuCheck(m_hEdgesMenu, ID_EDGES_CONDITIONALLINES,
1596 m_prefs->getDrawConditionalHighlights());
1597 }
1598
doHighQualityEdges(void)1599 void ToolbarStrip::doHighQualityEdges(void)
1600 {
1601 m_prefs->setUsePolygonOffset(!m_prefs->getUsePolygonOffset());
1602 setMenuCheck(m_hEdgesMenu, ID_EDGES_HIGHQUALITY,
1603 m_prefs->getUsePolygonOffset());
1604 }
1605
doAlwaysBlack(void)1606 void ToolbarStrip::doAlwaysBlack(void)
1607 {
1608 m_prefs->setBlackHighlights(!m_prefs->getBlackHighlights());
1609 setMenuCheck(m_hEdgesMenu, ID_EDGES_ALWAYSBLACK,
1610 m_prefs->getBlackHighlights());
1611 }
1612
doTexmaps(void)1613 void ToolbarStrip::doTexmaps(void)
1614 {
1615 m_texmaps = !m_texmaps;
1616 m_prefs->setTexmaps(m_texmaps);
1617 setMenuCheck(m_hPrimitivesMenu, ID_PRIMITIVES_TEXMAPS, m_texmaps);
1618 forceRedraw();
1619 checksReflect();
1620 }
1621
doTextureStuds(void)1622 void ToolbarStrip::doTextureStuds(void)
1623 {
1624 m_prefs->setTextureStuds(!m_prefs->getTextureStuds());
1625 setMenuCheck(m_hPrimitivesMenu, ID_PRIMITIVES_TEXTURESTUDS,
1626 m_prefs->getTextureStuds());
1627 forceRedraw();
1628 checksReflect();
1629 }
1630
doQualityLighting(void)1631 void ToolbarStrip::doQualityLighting(void)
1632 {
1633 m_prefs->setQualityLighting(!m_prefs->getQualityLighting());
1634 setMenuCheck(m_hLightingMenu, ID_LIGHTING_HIGHQUALITY,
1635 m_prefs->getQualityLighting());
1636 }
1637
doSubduedLighting(void)1638 void ToolbarStrip::doSubduedLighting(void)
1639 {
1640 m_prefs->setSubduedLighting(!m_prefs->getSubduedLighting());
1641 setMenuCheck(m_hLightingMenu, ID_LIGHTING_SUBDUED,
1642 m_prefs->getSubduedLighting());
1643 }
1644
doSpecularHighlight(void)1645 void ToolbarStrip::doSpecularHighlight(void)
1646 {
1647 m_prefs->setUsesSpecular(!m_prefs->getUsesSpecular());
1648 setMenuCheck(m_hLightingMenu, ID_LIGHTING_SPECULARHIGHLIGHT,
1649 m_prefs->getUsesSpecular());
1650 }
1651
doAlternateLighting(void)1652 void ToolbarStrip::doAlternateLighting(void)
1653 {
1654 m_prefs->setOneLight(!m_prefs->getOneLight());
1655 setMenuCheck(m_hLightingMenu, ID_LIGHTING_ALTERNATESETUP,
1656 m_prefs->getOneLight());
1657 }
1658
doDrawLightDats(void)1659 void ToolbarStrip::doDrawLightDats(void)
1660 {
1661 m_prefs->setDrawLightDats(!m_prefs->getDrawLightDats());
1662 setMenuCheck(m_hLightingMenu, ID_LIGHTING_DRAWDATS,
1663 m_prefs->getDrawLightDats());
1664 }
1665
doOptionalStandardLight(void)1666 void ToolbarStrip::doOptionalStandardLight(void)
1667 {
1668 m_prefs->setOptionalStandardLight(!m_prefs->getOptionalStandardLight());
1669 setMenuCheck(m_hLightingMenu, ID_LIGHTING_OPTIONALMAIN,
1670 m_prefs->getOptionalStandardLight());
1671 }
1672
doRedBackFaces(void)1673 void ToolbarStrip::doRedBackFaces(void)
1674 {
1675 m_prefs->setRedBackFaces(!m_prefs->getRedBackFaces());
1676 setMenuCheck(m_hBFCMenu, ID_BFC_REDBACKFACES,
1677 m_prefs->getRedBackFaces());
1678 }
1679
doGreenFrontFaces(void)1680 void ToolbarStrip::doGreenFrontFaces(void)
1681 {
1682 m_prefs->setGreenFrontFaces(!m_prefs->getGreenFrontFaces());
1683 setMenuCheck(m_hBFCMenu, ID_BFC_GREENFRONTFACES,
1684 m_prefs->getGreenFrontFaces());
1685 }
1686
doBlueNeutralFaces(void)1687 void ToolbarStrip::doBlueNeutralFaces(void)
1688 {
1689 m_prefs->setBlueNeutralFaces(!m_prefs->getBlueNeutralFaces());
1690 setMenuCheck(m_hBFCMenu, ID_BFC_BLUENEUTRALFACES,
1691 m_prefs->getBlueNeutralFaces());
1692 }
1693
doCustomizeMainToolbar(void)1694 void ToolbarStrip::doCustomizeMainToolbar(void)
1695 {
1696 SendMessage(m_hToolbar, TB_CUSTOMIZE, 0, 0);
1697 }
1698
doMainToolbar(void)1699 void ToolbarStrip::doMainToolbar(void)
1700 {
1701 m_showMain = !m_showMain;
1702 TCUserDefaults::setBoolForKey(m_showMain, SHOW_MAIN_TOOLBAR_KEY, false);
1703 initLayout();
1704 }
1705
doViewMode(void)1706 void ToolbarStrip::doViewMode(void)
1707 {
1708 int commandId = ID_VIEW_EXAMINE;
1709
1710 if (m_viewMode == LDInputHandler::VMExamine)
1711 {
1712 commandId = ID_VIEW_FLYTHROUGH;
1713 }
1714 else if (m_viewMode == LDInputHandler::VMFlyThrough)
1715 {
1716 commandId = ID_VIEW_WALK;
1717 }
1718 SendMessage(m_ldviewWindow->getHWindow(), WM_COMMAND,
1719 MAKEWPARAM(commandId, BN_CLICKED), (LPARAM)m_hToolbar);
1720 }
1721
doStepsToolbar(void)1722 void ToolbarStrip::doStepsToolbar(void)
1723 {
1724 m_showSteps = !m_showSteps;
1725 TCUserDefaults::setBoolForKey(m_showSteps, SHOW_STEPS_TOOLBAR_KEY, false);
1726 initLayout();
1727 }
1728
doBfc(void)1729 void ToolbarStrip::doBfc(void)
1730 {
1731 if (doCheck(m_bfc, IDC_BFC))
1732 {
1733 m_prefs->setBfc(m_bfc);
1734 forceRedraw();
1735 }
1736 }
1737
doShowAxes(void)1738 void ToolbarStrip::doShowAxes(void)
1739 {
1740 if (doCheck(m_showAxes, IDC_SHOW_AXES))
1741 {
1742 m_prefs->setShowAxes(m_showAxes);
1743 forceRedraw();
1744 }
1745 }
1746
doRandomColors(void)1747 void ToolbarStrip::doRandomColors(void)
1748 {
1749 if (doCheck(m_randomColors, IDC_RANDOM_COLORS))
1750 {
1751 m_prefs->setRandomColors(m_randomColors);
1752 forceRedraw();
1753 }
1754 }
1755
doAllConditionals(void)1756 void ToolbarStrip::doAllConditionals(void)
1757 {
1758 if (doCheck(m_allConditionals, IDC_ALL_CONDITIONAL))
1759 {
1760 m_prefs->setShowAllConditionalLines(m_allConditionals);
1761 forceRedraw();
1762 }
1763 }
1764
doConditionalControls(void)1765 void ToolbarStrip::doConditionalControls(void)
1766 {
1767 if (doCheck(m_conditionalControls, IDC_CONDITIONAL_CONTROLS))
1768 {
1769 m_prefs->setShowConditionalControlPoints(m_conditionalControls);
1770 forceRedraw();
1771 }
1772 }
1773
doFlatShading(void)1774 void ToolbarStrip::doFlatShading(void)
1775 {
1776 if (doCheck(m_flat, IDC_FLAT_SHADING))
1777 {
1778 m_prefs->setUsesFlatShading(m_flat);
1779 if (m_flat && m_smoothCurves)
1780 {
1781 m_prefs->setPerformSmoothing(false);
1782 checksReflect();
1783 }
1784 forceRedraw();
1785 }
1786 }
1787
doCutaway(void)1788 void ToolbarStrip::doCutaway(void)
1789 {
1790 if (doCheck(m_wireframeCutaway, IDC_CUTAWAY))
1791 {
1792 m_prefs->setCutawayMode(m_wireframeCutaway ? LDVCutawayWireframe :
1793 LDVCutawayNormal);
1794 forceRedraw();
1795 }
1796 }
1797
doStudQuality(void)1798 void ToolbarStrip::doStudQuality(void)
1799 {
1800 if (doCheck(m_lowStuds, IDC_STUD_QUALITY))
1801 {
1802 m_prefs->setQualityStuds(!m_lowStuds);
1803 forceRedraw();
1804 }
1805 }
1806
doPartBoundingBoxes(void)1807 void ToolbarStrip::doPartBoundingBoxes(void)
1808 {
1809 if (doCheck(m_partBBoxes, IDC_PART_BOUNDING_BOXES))
1810 {
1811 m_prefs->setBoundingBoxesOnly(m_partBBoxes);
1812 forceRedraw();
1813 }
1814 }
1815
doSmoothCurves(void)1816 void ToolbarStrip::doSmoothCurves(void)
1817 {
1818 if (doCheck(m_smoothCurves, IDC_SMOOTH_CURVES))
1819 {
1820 m_prefs->setPerformSmoothing(m_smoothCurves);
1821 if (m_flat && m_smoothCurves)
1822 {
1823 m_prefs->setUseFlatShading(false);
1824 checksReflect();
1825 }
1826 forceRedraw();
1827 }
1828 }
1829
doTransDefaultColor(void)1830 void ToolbarStrip::doTransDefaultColor(void)
1831 {
1832 if (doCheck(m_transDefaultColor, IDC_TRANS_DEFAULT_COLOR))
1833 {
1834 m_prefs->setTransDefaultColor(m_transDefaultColor);
1835 forceRedraw();
1836 }
1837 }
1838
doCheck(bool & value,LPARAM commandId)1839 bool ToolbarStrip::doCheck(bool &value, LPARAM commandId)
1840 {
1841 BYTE state = (BYTE)SendMessage(m_hToolbar, TB_GETSTATE, commandId, 0);
1842 bool newValue = false;
1843
1844 if (state & TBSTATE_CHECKED)
1845 {
1846 newValue = true;
1847 }
1848 if (newValue != value)
1849 {
1850 if (m_hDeactivatedTooltip)
1851 {
1852 SendMessage(m_hDeactivatedTooltip, TTM_ACTIVATE, 1, 0);
1853 }
1854 m_hDeactivatedTooltip = (HWND)SendMessage(m_hToolbar, TB_GETTOOLTIPS, 0,
1855 0);
1856 SendMessage(m_hDeactivatedTooltip, TTM_POP, 0, 0);
1857 SendMessage(m_hDeactivatedTooltip, TTM_ACTIVATE, 0, 0);
1858 value = newValue;
1859 return true;
1860 }
1861 else
1862 {
1863 return false;
1864 }
1865 }
1866
activateDeactivatedTooltip(void)1867 void ToolbarStrip::activateDeactivatedTooltip(void)
1868 {
1869 if (m_hDeactivatedTooltip)
1870 {
1871 SendMessage(m_hDeactivatedTooltip, TTM_ACTIVATE, 1, 0);
1872 }
1873 }
1874
doInitMenuPopup(HMENU hPopupMenu,UINT,BOOL)1875 LRESULT ToolbarStrip::doInitMenuPopup(
1876 HMENU hPopupMenu,
1877 UINT /*uPos*/,
1878 BOOL /*fSystemMenu*/)
1879 {
1880 if (hPopupMenu == m_hContextMenu)
1881 {
1882 updateContextMenu();
1883 }
1884 else if (hPopupMenu == m_hWireframeMenu)
1885 {
1886 updateWireframeMenu();
1887 }
1888 else if (hPopupMenu == m_hEdgesMenu)
1889 {
1890 updateEdgesMenu();
1891 }
1892 else if (hPopupMenu == m_hPrimitivesMenu)
1893 {
1894 updatePrimitivesMenu();
1895 }
1896 else if (hPopupMenu == m_hLightingMenu)
1897 {
1898 updateLightingMenu();
1899 }
1900 else if (hPopupMenu == m_hBFCMenu)
1901 {
1902 updateBFCMenu();
1903 }
1904 return 1;
1905 }
1906
checkReflect(bool & value,bool prefsValue,LPARAM commandID)1907 void ToolbarStrip::checkReflect(bool &value, bool prefsValue, LPARAM commandID)
1908 {
1909 if (value != prefsValue)
1910 {
1911 BYTE state = (BYTE)SendMessage(m_hToolbar, TB_GETSTATE, commandID, 0);
1912
1913 value = prefsValue;
1914 state &= ~TBSTATE_CHECKED;
1915 if (value)
1916 {
1917 state |= TBSTATE_CHECKED;
1918 }
1919 SendMessage(m_hToolbar, TB_SETSTATE, commandID, MAKELONG(state, 0));
1920 }
1921 }
1922
viewModeReflect(void)1923 void ToolbarStrip::viewModeReflect(void)
1924 {
1925 int oldViewMode = m_viewMode;
1926 syncViewMode();
1927 int bmpIndex = (int)SendMessage(m_hToolbar, TB_GETBITMAP, ID_VIEW_EXAMINE, 0);
1928 TBBUTTONINFO bi;
1929 bmpIndex += m_viewMode - oldViewMode;
1930 memset(&bi, 0, sizeof(bi));
1931 bi.cbSize = sizeof(bi);
1932 bi.dwMask = TBIF_IMAGE;
1933 bi.iImage = bmpIndex;
1934 SendMessage(m_hToolbar, TB_SETBUTTONINFO, ID_VIEW_EXAMINE, (LPARAM)&bi);
1935 checksReflect();
1936 }
1937
checksReflect(void)1938 void ToolbarStrip::checksReflect(void)
1939 {
1940 checkReflect(m_drawWireframe, m_prefs->getDrawWireframe(), IDC_WIREFRAME);
1941 checkReflect(m_seams, m_prefs->getUseSeams() != 0, IDC_SEAMS);
1942 checkReflect(m_edges, m_prefs->getShowsHighlightLines(), IDC_HIGHLIGHTS);
1943 checkReflect(m_primitiveSubstitution,
1944 m_prefs->getAllowPrimitiveSubstitution(), IDC_PRIMITIVE_SUBSTITUTION);
1945 checkReflect(m_lighting, m_prefs->getUseLighting(), IDC_LIGHTING);
1946 checkReflect(m_bfc, m_prefs->getBfc(), IDC_BFC);
1947 checkReflect(m_showAxes, m_prefs->getShowAxes(), IDC_SHOW_AXES);
1948 checkReflect(m_randomColors, m_prefs->getRandomColors(), IDC_RANDOM_COLORS);
1949 checkReflect(m_allConditionals, m_prefs->getShowAllConditionalLines(),
1950 IDC_ALL_CONDITIONAL);
1951 checkReflect(m_conditionalControls,
1952 m_prefs->getShowConditionalControlPoints(), IDC_CONDITIONAL_CONTROLS);
1953 checkReflect(m_flat, m_prefs->getUseFlatShading(), IDC_FLAT_SHADING);
1954 checkReflect(m_lowStuds, !m_prefs->getQualityStuds(), IDC_STUD_QUALITY);
1955 checkReflect(m_partBBoxes, m_prefs->getBoundingBoxesOnly(),
1956 IDC_PART_BOUNDING_BOXES);
1957 checkReflect(m_smoothCurves, m_prefs->getPerformSmoothing(),
1958 IDC_SMOOTH_CURVES);
1959 checkReflect(m_transDefaultColor, m_prefs->getTransDefaultColor(),
1960 IDC_TRANS_DEFAULT_COLOR);
1961 checkReflect(m_modelBoundingBox, m_ldviewWindow->isBoundingBoxVisible(),
1962 ID_TOOLS_BOUNDINGBOX);
1963 checkReflect(m_topmost, m_ldviewWindow->isTopmost(), ID_VIEW_ALWAYSONTOP);
1964 checkReflect(m_wireframeCutaway,
1965 m_prefs->getCutawayMode() == LDVCutawayWireframe ||
1966 m_prefs->getCutawayMode() == LDVCutawayStencil, IDC_CUTAWAY);
1967 bool dummy = !m_prefs->getTextureStuds();
1968 checkReflect(dummy, !dummy, ID_PRIMITIVES_TEXTURESTUDS);
1969 checkReflect(m_texmaps, m_prefs->getTexmaps(), ID_PRIMITIVES_TEXMAPS);
1970 if (m_viewMode == LDInputHandler::VMExamine)
1971 {
1972 checkReflect(m_examineLatLong,
1973 TCUserDefaults::longForKey(EXAMINE_MODE_KEY,
1974 LDrawModelViewer::EMFree, false) == LDrawModelViewer::EMLatLong,
1975 ID_VIEW_EXAMINE_LAT_LONG);
1976 enableMainToolbarButton(ID_VIEW_EXAMINE_LAT_LONG, true);
1977 }
1978 else
1979 {
1980 checkReflect(m_examineLatLong, false, ID_VIEW_EXAMINE_LAT_LONG);
1981 enableMainToolbarButton(ID_VIEW_EXAMINE_LAT_LONG, false);
1982 }
1983 }
1984
doEnterMenuLoop(bool)1985 LRESULT ToolbarStrip::doEnterMenuLoop(bool /*isTrackPopupMenu*/)
1986 {
1987 ModelWindow *modelWindow = m_ldviewWindow->getModelWindow();
1988
1989 if (m_ldviewWindow->getLoading())
1990 {
1991 return 0;
1992 }
1993 if (modelWindow)
1994 {
1995 LDrawModelViewer *modelViewer = modelWindow->getModelViewer();
1996
1997 if (modelViewer)
1998 {
1999 modelViewer->pause();
2000 }
2001 }
2002 return 1;
2003 }
2004
doExitMenuLoop(bool)2005 LRESULT ToolbarStrip::doExitMenuLoop(bool /*isTrackPopupMenu*/)
2006 {
2007 ModelWindow *modelWindow = m_ldviewWindow->getModelWindow();
2008
2009 if (modelWindow)
2010 {
2011 LDrawModelViewer *modelViewer = modelWindow->getModelViewer();
2012
2013 if (modelViewer)
2014 {
2015 modelViewer->unpause();
2016 }
2017 modelWindow->forceRedraw();
2018 }
2019 return 1;
2020 }
2021
doContextMenu(HWND hWnd,int xPos,int yPos)2022 LRESULT ToolbarStrip::doContextMenu(HWND hWnd, int xPos, int yPos)
2023 {
2024 if (m_hContextMenu != NULL)
2025 {
2026 BOOL fade;
2027
2028 //setMenuEnabled(m_hContextMenu, ID_TBCONTEXT_CUSTOMIZE,
2029 // hWnd == m_hToolbar);
2030 // Note: selection fade causes a display glitch. This is an obscenely
2031 // ugly hack to get rid of that, but it does work. The problem still
2032 // exists when the menu item is selected from the main menu, though.
2033 // Did I mention yet today that Microsoft sucks?
2034 SystemParametersInfo(SPI_GETSELECTIONFADE, 0, &fade, 0);
2035 if (fade)
2036 {
2037 // We better pray it doesn't crash between here and where we put
2038 // things back below.
2039 SystemParametersInfo(SPI_SETSELECTIONFADE, FALSE, NULL, 0);
2040 }
2041 TrackPopupMenuEx(m_hContextMenu,
2042 TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL,
2043 xPos, yPos, hWindow, NULL);
2044 if (fade)
2045 {
2046 SystemParametersInfo(SPI_SETSELECTIONFADE, 0, &fade, 0);
2047 }
2048 return 0;
2049 }
2050 return CUIDialog::doContextMenu(hWnd, xPos, yPos);
2051 }
2052