1 #include "LDViewPreferences.h"
2 #include <CUI/CUIDialog.h>
3 #pragma warning(push)
4 #pragma warning(disable:4091)
5 #include <shlobj.h>
6 #include <shlwapi.h>
7 #pragma warning(pop)
8 #include <LDLib/LDrawModelViewer.h>
9 #include <LDLib/LDPreferences.h>
10 #include <LDLoader/LDLPalette.h>
11 #include <TCFoundation/TCMacros.h>
12 #include <TCFoundation/TCWebClient.h>
13 #include "LDVExtensionsSetup.h"
14 #include "Resource.h"
15 #include <LDLib/LDUserDefaultsKeys.h>
16 #include "ModelWindow.h"
17 #include "LDViewWindow.h"
18 #include <CUI/CUIScaler.h>
19 
20 #include <TCFoundation/TCUserDefaults.h>
21 #include <TCFoundation/mystring.h>
22 #include <TCFoundation/TCStringArray.h>
23 #include <TCFoundation/TCAlertManager.h>
24 #include <Commctrl.h>
25 #include <stdio.h>
26 //#include <tmschema.h>
27 #include <TRE/TREGLExtensions.h>
28 #include <HtmlHelp.h>
29 
30 #if defined(_MSC_VER) && _MSC_VER >= 1400 && defined(_DEBUG)
31 #define new DEBUG_CLIENTBLOCK
32 #endif // _DEBUG
33 
34 //#define WILLY_DEBUG
35 
36 #ifdef WILLY_DEBUG
WillyMessage(const char * message)37 void WillyMessage(const char *message)
38 {
39 	FILE *debugFile = ucfopen("C:\\LDView-Debug.txt", "a");
40 	if (debugFile)
41 	{
42 		fprintf(debugFile, "%s\n", message);
43 		fclose(debugFile);
44 	}
45 }
46 #else // WILLY_DEBUG
WillyMessage(const char *)47 void WillyMessage(const char *)
48 {
49 }
50 #endif //WILLY_DEBUG
51 
52 #ifndef IDC_HARDWARE_STEREO
53 #define IDC_HARDWARE_STEREO 1030
54 #endif
55 
56 #if (_WIN32_WINNT < 0x0500)
57 #define ODS_NOFOCUSRECT 0x0200
58 #endif // (_WIN32_WINNT < 0x0500)
59 
60 #define DEFAULT_PREF_SET ls(_UC("DefaultPrefSet"))
61 
62 ucstring LDViewPreferences::ldviewPath;
63 
LDViewPreferences(HINSTANCE hInstance,LDrawModelViewer * modelViewer)64 LDViewPreferences::LDViewPreferences(HINSTANCE hInstance,
65 									 LDrawModelViewer* modelViewer)
66 	:CUIPropertySheet(ls(_UC("LDViewPreferences")), hInstance),
67 	modelViewer(modelViewer ? ((LDrawModelViewer*)modelViewer->retain()) :
68 		NULL),
69 	ldPrefs(new LDPreferences(modelViewer)),
70 	generalPageNumber(0),
71 	geometryPageNumber(1),
72 	effectsPageNumber(2),
73 	primitivesPageNumber(3),
74 	updatesPageNumber(4),
75 	prefSetsPageNumber(5),
76 	hGeneralPage(NULL),
77 	hBackgroundColorBitmap(NULL),
78 	hBackgroundColorButton(NULL),
79 	hDefaultColorBitmap(NULL),
80 	hDefaultColorButton(NULL),
81 	hMouseOverButton(NULL),
82 	origButtonWindowProc(NULL),
83 	hButtonColorDC(NULL),
84 	hGeometryPage(NULL),
85 	hEffectsPage(NULL),
86 	hPrimitivesPage(NULL),
87 	hUpdatesPage(NULL),
88 	hPrefSetsPage(NULL),
89 	setActiveWarned(false),
90 	checkAbandon(true),
91 	hButtonTheme(NULL)
92 //	hTabTheme(NULL)
93 {
94 	WillyMessage("\n\n\n");
95 	CUIThemes::init();
96 	loadSettings();
97 	applySettings();
98 	TCAlertManager::registerHandler(TCUserDefaults::alertClass(), this,
99 		(TCAlertCallback)&LDViewPreferences::userDefaultChangedAlertCallback);
100 	TCAlertManager::registerHandler(
101 		LDPreferences::lightVectorChangedAlertClass(), this,
102 		(TCAlertCallback)&LDViewPreferences::lightVectorChangedCallback);
103 	lightDirIndexToId[0] = IDR_LIGHT_ANGLE_UL;
104 	lightDirIndexToId[1] = IDR_LIGHT_ANGLE_UM;
105 	lightDirIndexToId[2] = IDR_LIGHT_ANGLE_UR;
106 	lightDirIndexToId[3] = IDR_LIGHT_ANGLE_ML;
107 	lightDirIndexToId[4] = IDR_LIGHT_ANGLE_MM;
108 	lightDirIndexToId[5] = IDR_LIGHT_ANGLE_MR;
109 	lightDirIndexToId[6] = IDR_LIGHT_ANGLE_LL;
110 	lightDirIndexToId[7] = IDR_LIGHT_ANGLE_LM;
111 	lightDirIndexToId[8] = IDR_LIGHT_ANGLE_LR;
112 	for (IntIntMap::const_iterator it = lightDirIndexToId.begin()
113 		; it != lightDirIndexToId.end(); it++)
114 	{
115 		lightDirIdToIndex[it->second] = it->first;
116 	}
117 }
118 
~LDViewPreferences(void)119 LDViewPreferences::~LDViewPreferences(void)
120 {
121 }
122 
dealloc(void)123 void LDViewPreferences::dealloc(void)
124 {
125 	TCAlertManager::unregisterHandler(this);
126 	TCObject::release(modelViewer);
127 	TCObject::release(ldPrefs);
128 	if (hButtonTheme)
129 	{
130 		CUIThemes::closeThemeData(hButtonTheme);
131 		hButtonTheme = NULL;
132 	}
133 /*
134 	if (hTabTheme)
135 	{
136 		CUIThemes::closeThemeData(hTabTheme);
137 		hTabTheme = NULL;
138 	}
139 */
140 	CUIPropertySheet::dealloc();
141 }
142 
lightVectorChangedCallback(TCAlert *)143 void LDViewPreferences::lightVectorChangedCallback(TCAlert * /*alert*/)
144 {
145 	checkLightVector();
146 }
147 
userDefaultChangedAlertCallback(TCAlert * alert)148 void LDViewPreferences::userDefaultChangedAlertCallback(TCAlert *alert)
149 {
150 	const char *key = alert->getMessage();
151 
152 	if (key)
153 	{
154 		if (strcmp(key, CHECK_PART_TRACKER_KEY) == 0)
155 		{
156 			if (hUpdatesPage)
157 			{
158 				setCheck(hUpdatesPage, IDC_CHECK_PART_TRACKER,
159 					ldPrefs->getCheckPartTracker());
160 			}
161 		}
162 	}
163 }
164 
applySettings(void)165 void LDViewPreferences::applySettings(void)
166 {
167 	ldPrefs->applySettings();
168 }
169 
loadSettings(void)170 void LDViewPreferences::loadSettings(void)
171 {
172 	ldPrefs->loadSettings();
173 }
174 
getColor(const char * key,COLORREF defaultColor)175 COLORREF LDViewPreferences::getColor(const char *key, COLORREF defaultColor)
176 {
177 	return (COLORREF)htonl(TCUserDefaults::longForKey(key,
178 		(long)(htonl(defaultColor) >> 8)) << 8);
179 }
180 
setColor(const char * key,COLORREF color)181 void LDViewPreferences::setColor(const char *key, COLORREF color)
182 {
183 	TCUserDefaults::setLongForKey((long)(htonl(color) >> 8), key);
184 }
185 
setUseSeams(bool value)186 void LDViewPreferences::setUseSeams(bool value)
187 {
188 	if (value != ldPrefs->getUseSeams())
189 	{
190 		ldPrefs->setUseSeams(value, true, true);
191 		if (hGeometryPage)
192 		{
193 			setCheck(hGeometryPage, IDC_SEAMS, value);
194 			if (value)
195 			{
196 				enableSeams();
197 			}
198 			else
199 			{
200 				disableSeams();
201 			}
202 		}
203 	}
204 }
205 
setDrawWireframe(bool value)206 void LDViewPreferences::setDrawWireframe(bool value)
207 {
208 	if (value != ldPrefs->getDrawWireframe())
209 	{
210 		ldPrefs->setDrawWireframe(value, true, true);
211 		if (hGeometryPage)
212 		{
213 			setupGroupCheckButton(hGeometryPage, IDC_WIREFRAME, value);
214 			if (value)
215 			{
216 				enableWireframe();
217 			}
218 			else
219 			{
220 				disableWireframe();
221 			}
222 		}
223 	}
224 }
225 
setUseWireframeFog(bool value)226 void LDViewPreferences::setUseWireframeFog(bool value)
227 {
228 	if (value != ldPrefs->getUseWireframeFog())
229 	{
230 		ldPrefs->setUseWireframeFog(value, true, true);
231 		if (hGeometryPage)
232 		{
233 			setCheck(hGeometryPage, IDC_WIREFRAME_FOG, value);
234 		}
235 	}
236 }
237 
setRemoveHiddenLines(bool value)238 void LDViewPreferences::setRemoveHiddenLines(bool value)
239 {
240 	if (value != ldPrefs->getRemoveHiddenLines())
241 	{
242 		ldPrefs->setRemoveHiddenLines(value, true, true);
243 		if (hGeometryPage)
244 		{
245 			setCheck(hGeometryPage, IDC_REMOVE_HIDDEN_LINES, value);
246 		}
247 	}
248 }
249 
setEdgesOnly(bool value)250 void LDViewPreferences::setEdgesOnly(bool value)
251 {
252 	if (value != ldPrefs->getEdgesOnly())
253 	{
254 		ldPrefs->setEdgesOnly(value, true, true);
255 		if (hGeometryPage)
256 		{
257 			setCheck(hGeometryPage, IDC_EDGES_ONLY, value);
258 		}
259 	}
260 }
261 
getFullScreenRefresh(void)262 int LDViewPreferences::getFullScreenRefresh(void)
263 {
264 	return ldPrefs->getFullScreenRefresh();
265 }
266 
getSeamWidth(void)267 int LDViewPreferences::getSeamWidth(void)
268 {
269 	return ldPrefs->getSeamWidth();
270 }
271 
getQualityLighting(void)272 bool LDViewPreferences::getQualityLighting(void)
273 {
274 	return ldPrefs->getQualityLighting();
275 }
276 
getUsesFlatShading(void)277 bool LDViewPreferences::getUsesFlatShading(void)
278 {
279 	return ldPrefs->getUseFlatShading();
280 }
281 
getCutawayMode(void)282 LDVCutawayMode LDViewPreferences::getCutawayMode(void)
283 {
284 	return ldPrefs->getCutawayMode();
285 }
286 
getUsesSpecular(void)287 bool LDViewPreferences::getUsesSpecular(void)
288 {
289 	return ldPrefs->getUseSpecular();
290 }
291 
getOneLight(void)292 bool LDViewPreferences::getOneLight(void)
293 {
294 	return ldPrefs->getOneLight();
295 }
296 
getDrawLightDats(void)297 bool LDViewPreferences::getDrawLightDats(void)
298 {
299 	return ldPrefs->getDrawLightDats();
300 }
301 
getOptionalStandardLight(void)302 bool LDViewPreferences::getOptionalStandardLight(void)
303 {
304 	return ldPrefs->getOptionalStandardLight();
305 }
306 
getPerformSmoothing(void)307 bool LDViewPreferences::getPerformSmoothing(void)
308 {
309 	return ldPrefs->getPerformSmoothing();
310 }
311 
getShowsFPS(void)312 bool LDViewPreferences::getShowsFPS(void)
313 {
314 	return ldPrefs->getShowFps();
315 }
316 
getLineSmoothing(void)317 bool LDViewPreferences::getLineSmoothing(void)
318 {
319 	return ldPrefs->getLineSmoothing();
320 }
321 
getQualityStuds(void)322 bool LDViewPreferences::getQualityStuds(void)
323 {
324 	return ldPrefs->getQualityStuds();
325 }
326 
getAllowPrimitiveSubstitution(void)327 bool LDViewPreferences::getAllowPrimitiveSubstitution(void)
328 {
329 	return ldPrefs->getAllowPrimitiveSubstitution();
330 }
331 
getShowsHighlightLines(void)332 bool LDViewPreferences::getShowsHighlightLines(void)
333 {
334 	return ldPrefs->getShowHighlightLines();
335 }
336 
getEdgesOnly(void)337 bool LDViewPreferences::getEdgesOnly(void)
338 {
339 	return ldPrefs->getEdgesOnly();
340 }
341 
getDrawConditionalHighlights(void)342 bool LDViewPreferences::getDrawConditionalHighlights(void)
343 {
344 	return ldPrefs->getDrawConditionalHighlights();
345 }
346 
getShowAllConditionalLines(void)347 bool LDViewPreferences::getShowAllConditionalLines(void)
348 {
349 	return ldPrefs->getShowAllConditionalLines();
350 }
351 
getShowConditionalControlPoints(void)352 bool LDViewPreferences::getShowConditionalControlPoints(void)
353 {
354 	return ldPrefs->getShowConditionalControlPoints();
355 }
356 
getUseFlatShading(void)357 bool LDViewPreferences::getUseFlatShading(void)
358 {
359 	return ldPrefs->getUseFlatShading();
360 }
361 
getBoundingBoxesOnly(void)362 bool LDViewPreferences::getBoundingBoxesOnly(void)
363 {
364 	return ldPrefs->getBoundingBoxesOnly();
365 }
366 
getTransDefaultColor(void)367 bool LDViewPreferences::getTransDefaultColor(void)
368 {
369 	return ldPrefs->getTransDefaultColor();
370 }
371 
getUseSeams(void)372 bool LDViewPreferences::getUseSeams(void)
373 {
374 	return ldPrefs->getUseSeams();
375 }
376 
getDrawWireframe(void)377 bool LDViewPreferences::getDrawWireframe(void)
378 {
379 	return ldPrefs->getDrawWireframe();
380 }
381 
getBfc(void)382 bool LDViewPreferences::getBfc(void)
383 {
384 	return ldPrefs->getBfc();
385 }
386 
getShowAxes(void)387 bool LDViewPreferences::getShowAxes(void)
388 {
389 	return ldPrefs->getShowAxes();
390 }
391 
getRandomColors(void)392 bool LDViewPreferences::getRandomColors(void)
393 {
394 	return ldPrefs->getRandomColors();
395 }
396 
getRedBackFaces(void)397 bool LDViewPreferences::getRedBackFaces(void)
398 {
399 	return ldPrefs->getRedBackFaces();
400 }
401 
getGreenFrontFaces(void)402 bool LDViewPreferences::getGreenFrontFaces(void)
403 {
404 	return ldPrefs->getGreenFrontFaces();
405 }
406 
getBlueNeutralFaces(void)407 bool LDViewPreferences::getBlueNeutralFaces(void)
408 {
409 	return ldPrefs->getBlueNeutralFaces();
410 }
411 
getUseWireframeFog(void)412 bool LDViewPreferences::getUseWireframeFog(void)
413 {
414 	return ldPrefs->getUseWireframeFog();
415 }
416 
getRemoveHiddenLines(void)417 bool LDViewPreferences::getRemoveHiddenLines(void)
418 {
419 	return ldPrefs->getRemoveHiddenLines();
420 }
421 
getUsePolygonOffset(void)422 bool LDViewPreferences::getUsePolygonOffset(void)
423 {
424 	return ldPrefs->getUsePolygonOffset();
425 }
426 
getBlackHighlights(void)427 bool LDViewPreferences::getBlackHighlights(void)
428 {
429 	return ldPrefs->getBlackHighlights();
430 }
431 
getUseLighting(void)432 bool LDViewPreferences::getUseLighting(void)
433 {
434 	return ldPrefs->getUseLighting();
435 }
436 
getSubduedLighting(void)437 bool LDViewPreferences::getSubduedLighting(void)
438 {
439 	return ldPrefs->getSubduedLighting();
440 }
441 
getUseStipple(void)442 bool LDViewPreferences::getUseStipple(void)
443 {
444 	return ldPrefs->getUseStipple();
445 }
446 
getSortTransparent(void)447 bool LDViewPreferences::getSortTransparent(void)
448 {
449 	return ldPrefs->getSortTransparent();
450 }
451 
getTextureStuds(void)452 bool LDViewPreferences::getTextureStuds(void)
453 {
454 	return ldPrefs->getTextureStuds();
455 }
456 
getTexmaps(void)457 bool LDViewPreferences::getTexmaps(void)
458 {
459 	return ldPrefs->getTexmaps();
460 }
461 
getBackgroundColor(void)462 COLORREF LDViewPreferences::getBackgroundColor(void)
463 {
464 	int r, g, b;
465 
466 	ldPrefs->getBackgroundColor(r, g, b);
467 	return RGB((BYTE)r, (BYTE)g, (BYTE)b);
468 }
469 
getDefaultColor(void)470 COLORREF LDViewPreferences::getDefaultColor(void)
471 {
472 	int r, g, b;
473 
474 	ldPrefs->getDefaultColor(r, g, b);
475 	return RGB((BYTE)r, (BYTE)g, (BYTE)b);
476 }
477 
setDrawConditionalHighlights(bool value)478 void LDViewPreferences::setDrawConditionalHighlights(bool value)
479 {
480 	if (value != ldPrefs->getDrawConditionalHighlights())
481 	{
482 		ldPrefs->setDrawConditionalHighlights(value, true, true);
483 		if (hGeometryPage)
484 		{
485 			setCheck(hGeometryPage, IDC_CONDITIONAL_HIGHLIGHTS, value);
486 		}
487 	}
488 }
489 
setShowAllConditionalLines(bool value)490 void LDViewPreferences::setShowAllConditionalLines(bool value)
491 {
492 	if (value != ldPrefs->getShowAllConditionalLines())
493 	{
494 		ldPrefs->setShowAllConditionalLines(value, true, true);
495 		if (hGeometryPage)
496 		{
497 			setCheck(hGeometryPage, IDC_ALL_CONDITIONAL, value);
498 		}
499 	}
500 }
501 
setShowConditionalControlPoints(bool value)502 void LDViewPreferences::setShowConditionalControlPoints(bool value)
503 {
504 	if (value != ldPrefs->getShowConditionalControlPoints())
505 	{
506 		ldPrefs->setShowConditionalControlPoints(value, true, true);
507 		if (hGeometryPage)
508 		{
509 			setCheck(hGeometryPage, IDC_CONDITIONAL_CONTROLS, value);
510 		}
511 	}
512 }
513 
setUseFlatShading(bool value)514 void LDViewPreferences::setUseFlatShading(bool value)
515 {
516 	if (value != ldPrefs->getUseFlatShading())
517 	{
518 		ldPrefs->setUseFlatShading(value, true, true);
519 		if (hEffectsPage)
520 		{
521 			setCheck(hEffectsPage, IDC_FLAT_SHADING, value);
522 		}
523 	}
524 }
525 
setBoundingBoxesOnly(bool value)526 void LDViewPreferences::setBoundingBoxesOnly(bool value)
527 {
528 	if (value != ldPrefs->getBoundingBoxesOnly())
529 	{
530 		ldPrefs->setBoundingBoxesOnly(value, true, true);
531 		if (hGeometryPage)
532 		{
533 			setCheck(hGeometryPage, IDC_PART_BOUNDING_BOXES, value);
534 		}
535 	}
536 }
537 
setTransDefaultColor(bool value)538 void LDViewPreferences::setTransDefaultColor(bool value)
539 {
540 	if (value != ldPrefs->getTransDefaultColor())
541 	{
542 		ldPrefs->setTransDefaultColor(value, true, true);
543 		if (hGeneralPage)
544 		{
545 			setCheck(hGeneralPage, IDC_TRANS_DEFAULT_COLOR, value);
546 		}
547 	}
548 }
549 
setPerformSmoothing(bool value)550 void LDViewPreferences::setPerformSmoothing(bool value)
551 {
552 	if (value != ldPrefs->getPerformSmoothing())
553 	{
554 		ldPrefs->setPerformSmoothing(value, true, true);
555 		if (hEffectsPage)
556 		{
557 			setCheck(hEffectsPage, IDC_SMOOTH_CURVES, value);
558 		}
559 	}
560 }
561 
setCutawayMode(LDVCutawayMode value)562 void LDViewPreferences::setCutawayMode(LDVCutawayMode value)
563 {
564 	if (value != ldPrefs->getCutawayMode())
565 	{
566 		ldPrefs->setCutawayMode(value, true, true);
567 		if (hEffectsPage)
568 		{
569 			setupCutaway();
570 		}
571 	}
572 }
573 
setUsePolygonOffset(bool value)574 void LDViewPreferences::setUsePolygonOffset(bool value)
575 {
576 	if (value != ldPrefs->getUsePolygonOffset())
577 	{
578 		ldPrefs->setUsePolygonOffset(value, true, true);
579 		if (hGeometryPage)
580 		{
581 			setCheck(hGeometryPage, IDC_QUALITY_LINES, value);
582 		}
583 	}
584 }
585 
setBlackHighlights(bool value)586 void LDViewPreferences::setBlackHighlights(bool value)
587 {
588 	if (value != ldPrefs->getBlackHighlights())
589 	{
590 		ldPrefs->setBlackHighlights(value, true, true);
591 		if (hGeometryPage)
592 		{
593 			setCheck(hGeometryPage, IDC_ALWAYS_BLACK, value);
594 		}
595 	}
596 }
597 
setShowsHighlightLines(bool value)598 void LDViewPreferences::setShowsHighlightLines(bool value)
599 {
600 	if (value != ldPrefs->getShowHighlightLines())
601 	{
602 		ldPrefs->setShowHighlightLines(value, true, true);
603 		if (hGeometryPage)
604 		{
605 			setupGroupCheckButton(hGeometryPage, IDC_HIGHLIGHTS, value);
606 			if (value)
607 			{
608 				enableEdges();
609 			}
610 			else
611 			{
612 				disableEdges();
613 			}
614 		}
615 	}
616 }
617 
setTextureStuds(bool value)618 void LDViewPreferences::setTextureStuds(bool value)
619 {
620 	if (value != ldPrefs->getTextureStuds())
621 	{
622 		ldPrefs->setTextureStuds(value, true, true);
623 		if (hPrimitivesPage)
624 		{
625 			setCheck(hPrimitivesPage, IDC_TEXTURE_STUDS, value);
626 		}
627 	}
628 }
629 
setTexmaps(bool value)630 void LDViewPreferences::setTexmaps(bool value)
631 {
632 	if (value != ldPrefs->getTexmaps())
633 	{
634 		ldPrefs->setTexmaps(value, true, true);
635 		if (hPrimitivesPage)
636 		{
637 			setCheck(hPrimitivesPage, IDC_TEXMAPS, value);
638 		}
639 	}
640 }
641 
setAllowPrimitiveSubstitution(bool value)642 void LDViewPreferences::setAllowPrimitiveSubstitution(bool value)
643 {
644 	if (value != ldPrefs->getAllowPrimitiveSubstitution())
645 	{
646 		ldPrefs->setAllowPrimitiveSubstitution(value, true, true);
647 		if (hPrimitivesPage)
648 		{
649 			setupGroupCheckButton(hPrimitivesPage, IDC_PRIMITIVE_SUBSTITUTION,
650 				value);
651 			if (value)
652 			{
653 				enablePrimitives();
654 			}
655 			else
656 			{
657 				disablePrimitives();
658 			}
659 		}
660 	}
661 }
662 
setRedBackFaces(bool value)663 void LDViewPreferences::setRedBackFaces(bool value)
664 {
665 	if (value != ldPrefs->getRedBackFaces())
666 	{
667 		ldPrefs->setRedBackFaces(value, true, true);
668 		if (hGeometryPage)
669 		{
670 			setCheck(hGeometryPage, IDC_RED_BACK_FACES, value);
671 		}
672 	}
673 }
674 
setGreenFrontFaces(bool value)675 void LDViewPreferences::setGreenFrontFaces(bool value)
676 {
677 	if (value != ldPrefs->getGreenFrontFaces())
678 	{
679 		ldPrefs->setGreenFrontFaces(value, true, true);
680 		if (hGeometryPage)
681 		{
682 			setCheck(hGeometryPage, IDC_GREEN_FRONT_FACES, value);
683 		}
684 	}
685 }
686 
setBlueNeutralFaces(bool value)687 void LDViewPreferences::setBlueNeutralFaces(bool value)
688 {
689 	if (value != ldPrefs->getBlueNeutralFaces())
690 	{
691 		ldPrefs->setBlueNeutralFaces(value, true, true);
692 		if (hGeometryPage)
693 		{
694 			setCheck(hGeometryPage, IDC_BLUE_NEUTRAL_FACES, value);
695 		}
696 	}
697 }
698 
setBfc(bool value)699 void LDViewPreferences::setBfc(bool value)
700 {
701 	if (value != ldPrefs->getBfc())
702 	{
703 		ldPrefs->setBfc(value, true, true);
704 		if (hGeometryPage)
705 		{
706 			setupGroupCheckButton(hGeometryPage, IDC_BFC, value);
707 			if (value)
708 			{
709 				enableBfc();
710 			}
711 			else
712 			{
713 				disableBfc();
714 			}
715 		}
716 	}
717 }
718 
setShowAxes(bool value)719 void LDViewPreferences::setShowAxes(bool value)
720 {
721 	if (value != ldPrefs->getShowAxes())
722 	{
723 		ldPrefs->setShowAxes(value, true, true);
724 		if (hGeneralPage)
725 		{
726 			setCheck(hGeneralPage, IDC_SHOW_AXES, value);
727 		}
728 	}
729 }
730 
setRandomColors(bool value)731 void LDViewPreferences::setRandomColors(bool value)
732 {
733 	if (value != ldPrefs->getRandomColors())
734 	{
735 		ldPrefs->setRandomColors(value, true, true);
736 		if (hGeneralPage)
737 		{
738 			setCheck(hGeneralPage, IDC_RANDOM_COLORS, value);
739 		}
740 	}
741 }
742 
743 // This is called from LDViewWindow.
setQualityLighting(bool value)744 void LDViewPreferences::setQualityLighting(bool value)
745 {
746 	if (value != ldPrefs->getQualityLighting())
747 	{
748 		ldPrefs->setQualityLighting(value, true, true);
749 		if (hEffectsPage)
750 		{
751 			setCheck(hEffectsPage, IDC_LIGHTING_QUALITY, value);
752 		}
753 	}
754 }
755 
setSubduedLighting(bool value)756 void LDViewPreferences::setSubduedLighting(bool value)
757 {
758 	if (value != ldPrefs->getSubduedLighting())
759 	{
760 		ldPrefs->setSubduedLighting(value, true, true);
761 		if (hEffectsPage)
762 		{
763 			setCheck(hEffectsPage, IDC_LIGHTING_SUBDUED, value);
764 		}
765 	}
766 }
767 
setQualityStuds(bool value)768 void LDViewPreferences::setQualityStuds(bool value)
769 {
770 	if (value != ldPrefs->getQualityStuds())
771 	{
772 		ldPrefs->setQualityStuds(value, true, true);
773 		if (hPrimitivesPage)
774 		{
775 			setCheck(hPrimitivesPage, IDC_STUD_QUALITY, !value);
776 		}
777 	}
778 }
779 
setUsesFlatShading(bool value)780 void LDViewPreferences::setUsesFlatShading(bool value)
781 {
782 	if (value != ldPrefs->getUseFlatShading())
783 	{
784 		ldPrefs->setUseFlatShading(value, true, true);
785 		if (hEffectsPage)
786 		{
787 			setCheck(hEffectsPage, IDC_FLAT_SHADING, value);
788 		}
789 	}
790 }
791 
setUsesSpecular(bool value)792 void LDViewPreferences::setUsesSpecular(bool value)
793 {
794 	if (value != ldPrefs->getUseSpecular())
795 	{
796 		ldPrefs->setUseSpecular(value, true, true);
797 		if (hEffectsPage)
798 		{
799 			setCheck(hEffectsPage, IDC_SPECULAR, value);
800 		}
801 	}
802 }
803 
setOneLight(bool value)804 void LDViewPreferences::setOneLight(bool value)
805 {
806 	if (value != ldPrefs->getOneLight())
807 	{
808 		ldPrefs->setOneLight(value, true, true);
809 		if (hEffectsPage)
810 		{
811 			setCheck(hEffectsPage, IDC_ALTERNATE_LIGHTING, value);
812 		}
813 	}
814 }
815 
setDrawLightDats(bool value)816 void LDViewPreferences::setDrawLightDats(bool value)
817 {
818 	if (value != ldPrefs->getDrawLightDats())
819 	{
820 		ldPrefs->setDrawLightDats(value, true, true);
821 		if (hEffectsPage)
822 		{
823 			setCheck(hEffectsPage, IDC_DRAW_LIGHT_DATS, value);
824 		}
825 	}
826 }
827 
setOptionalStandardLight(bool value)828 void LDViewPreferences::setOptionalStandardLight(bool value)
829 {
830 	if (value != ldPrefs->getOptionalStandardLight())
831 	{
832 		ldPrefs->setOptionalStandardLight(value, true, true);
833 		if (hEffectsPage)
834 		{
835 			setCheck(hEffectsPage, IDC_OPTIONAL_STANDARD_LIGHT, value);
836 		}
837 	}
838 }
839 
setUseLighting(bool value)840 void LDViewPreferences::setUseLighting(bool value)
841 {
842 	if (value != ldPrefs->getUseLighting())
843 	{
844 		ldPrefs->setUseLighting(value, true, true);
845 		if (hEffectsPage)
846 		{
847 			setupGroupCheckButton(hEffectsPage, IDC_LIGHTING, value);
848 			if (value)
849 			{
850 				enableLighting();
851 			}
852 			else
853 			{
854 				disableLighting();
855 			}
856 		}
857 	}
858 }
859 
run(void)860 INT_PTR LDViewPreferences::run(void)
861 {
862 	bool wasPaused = true;
863 	INT_PTR retValue;
864 
865 	if (modelViewer)
866 	{
867 		wasPaused = modelViewer->getPaused() != 0;
868 		if (!wasPaused)
869 		{
870 			modelViewer->pause();
871 		}
872 	}
873 	addPage(IDD_GENERAL_PREFS);
874 	addPage(IDD_GEOMETRY_PREFS);
875 	addPage(IDD_EFFECTS_PREFS);
876 	addPage(IDD_PRIMITIVES_PREFS);
877 	addPage(IDD_UPDATES_PREFS);
878 	addPage(IDD_PREFSETS_PREFS);
879 	checkAbandon = true;
880 	retValue = CUIPropertySheet::run();
881 	if (!wasPaused)
882 	{
883 		modelViewer->unpause();
884 	}
885 	return retValue;
886 }
887 
doDialogNotify(HWND hDlg,int controlId,LPNMHDR notification)888 BOOL LDViewPreferences::doDialogNotify(HWND hDlg, int controlId,
889 									   LPNMHDR notification)
890 {
891 //	debugPrintf("LDViewPreferences::doDialogNotify: %d 0x%08X\n",
892 //		notification->code, notification->code);
893 	if (notification->code == NM_RELEASEDCAPTURE)
894 	{
895 		if (hDlg == hEffectsPage)
896 		{
897 			if (controlId == IDC_STEREO_SPACING ||
898 				controlId == IDC_CUTAWAY_OPACITY ||
899 				controlId == IDC_CUTAWAY_THICKNESS)
900 			{
901 				enableApply(hEffectsPage);
902 				return FALSE;
903 			}
904 		}
905 		else if (hDlg == hGeometryPage)
906 		{
907 			if (controlId == IDC_WIREFRAME_THICKNESS ||
908 				controlId == IDC_EDGE_THICKNESS)
909 			{
910 				enableApply(hGeometryPage);
911 				return FALSE;
912 			}
913 		}
914 		else if (hDlg == hPrimitivesPage)
915 		{
916 			if (controlId == IDC_CURVE_QUALITY)
917 			{
918 				enableApply(hPrimitivesPage);
919 				return FALSE;
920 			}
921 			else if (controlId == IDC_ANISO_LEVEL)
922 			{
923 				enableApply(hPrimitivesPage);
924 				setAniso(trackBarGetPos(hAnisoLevelSlider));
925 				return FALSE;
926 			}
927 			else if (controlId == IDC_TEXTURE_OFFSET)
928 			{
929 				enableApply(hPrimitivesPage);
930 				return FALSE;
931 			}
932 		}
933 	}
934 	else if (notification->code == CBN_SELCHANGE)
935 	{
936 		debugPrintf("combo sel\n");
937 	}
938 	return CUIPropertySheet::doDialogNotify(hDlg, controlId, notification);
939 }
940 
getLDViewPath(bool useQuotes)941 UCSTR LDViewPreferences::getLDViewPath(bool useQuotes)
942 {
943 	UCCHAR origPath[MAX_PATH];
944 	UCCHAR newPath[MAX_PATH];
945 
946 	if (ldviewPath.empty())
947 	{
948 		UCSTR commandLine = copyString(GetCommandLine());
949 
950 		PathRemoveArgs(commandLine);
951 		PathUnquoteSpaces(commandLine);
952 		PathRemoveFileSpec(commandLine);
953 		GetCurrentDirectory(MAX_PATH, origPath);
954 		if (SetCurrentDirectory(commandLine))
955 		{
956 			GetCurrentDirectory(MAX_PATH, newPath);
957 			PathUnquoteSpaces(newPath);
958 			ldviewPath = newPath;
959 			SetCurrentDirectory(origPath);
960 		}
961 		else
962 		{
963 			ldviewPath = origPath;
964 		}
965 		delete commandLine;
966 	}
967 	ucstrcpy(newPath, ldviewPath.c_str());
968 	if (useQuotes)
969 	{
970 		PathQuoteSpaces(newPath);
971 	}
972 	return copyString(newPath);
973 }
974 
getLDViewPath(CUCSTR helpFilename,bool useQuotes)975 UCSTR LDViewPreferences::getLDViewPath(CUCSTR helpFilename, bool useQuotes)
976 {
977 	UCSTR programPath = getLDViewPath();
978 	UCCHAR tmpPath[MAX_PATH];
979 
980 	ucstrcpy(tmpPath, programPath);
981 	delete[] programPath;
982 	if (helpFilename)
983 	{
984 		PathAppend(tmpPath, helpFilename);
985 	}
986 	if (useQuotes)
987 	{
988 		PathQuoteSpaces(tmpPath);
989 	}
990 	return copyString(tmpPath);
991 }
992 
getPageDialogID(HWND hDlg)993 DWORD LDViewPreferences::getPageDialogID(HWND hDlg)
994 {
995 	if (hDlg == hGeneralPage)
996 	{
997 		return IDD_GENERAL_PREFS;
998 	}
999 	else if (hDlg == hGeometryPage)
1000 	{
1001 		return IDD_GEOMETRY_PREFS;
1002 	}
1003 	else if (hDlg == hEffectsPage)
1004 	{
1005 		return IDD_EFFECTS_PREFS;
1006 	}
1007 	else if (hDlg == hPrimitivesPage)
1008 	{
1009 		return IDD_PRIMITIVES_PREFS;
1010 	}
1011 	else if (hDlg == hUpdatesPage)
1012 	{
1013 		return IDD_UPDATES_PREFS;
1014 	}
1015 	else if (hDlg == hPrefSetsPage)
1016 	{
1017 		return IDD_PREFSETS_PREFS;
1018 	}
1019 	return 0;
1020 }
1021 
doDialogHelp(HWND hDlg,LPHELPINFO helpInfo)1022 BOOL LDViewPreferences::doDialogHelp(HWND hDlg, LPHELPINFO helpInfo)
1023 {
1024 	DWORD dialogId = getPageDialogID(hDlg);
1025 
1026 	if (dialogId)
1027 	{
1028 		return CUIDialog::DoHtmlHelp(hDlg, helpInfo);
1029 	}
1030 	return FALSE;
1031 }
1032 
getPrefSet(int index)1033 ucstring LDViewPreferences::getPrefSet(int index)
1034 {
1035 	ucstring prefSet;
1036 	listBoxGetText(hPrefSetsList, index, prefSet);
1037 	return prefSet;
1038 }
1039 
getSelectedPrefSet(void)1040 ucstring LDViewPreferences::getSelectedPrefSet(void)
1041 {
1042 	int selectedIndex = listBoxGetCurSel(hPrefSetsList);
1043 
1044 	if (selectedIndex != LB_ERR)
1045 	{
1046 		return getPrefSet(selectedIndex);
1047 	}
1048 	return ucstring();
1049 }
1050 
abandonChanges(void)1051 void LDViewPreferences::abandonChanges(void)
1052 {
1053 	int i;
1054 	HWND hPage;
1055 
1056 	doReset();
1057 	for (i = 0; i < prefSetsPageNumber; i++)
1058 	{
1059 		hPage = hwndArray->pointerAtIndex(i);
1060 		if (hPage)
1061 		{
1062 			disableApply(hPage);
1063 			hwndArray->replacePointer(NULL, i);
1064 		}
1065 	}
1066 	hPage = hwndArray->pointerAtIndex(prefSetsPageNumber);
1067 	if (hPage)
1068 	{
1069 		disableApply(hPage);
1070 	}
1071 }
1072 
runPrefSetApplyDialog(void)1073 INT_PTR LDViewPreferences::runPrefSetApplyDialog(void)
1074 {
1075 	INT_PTR retValue = DialogBoxParam(getLanguageModule(),
1076 		MAKEINTRESOURCE(IDD_PREFSET_APPLY), hWindow, staticDialogProc,
1077 		(LPARAM)this);
1078 
1079 	if (retValue == IDC_APPLY)
1080 	{
1081 		PropSheet_Apply(hPropSheet);
1082 	}
1083 	else if (retValue == IDC_ABANDON)
1084 	{
1085 		abandonChanges();
1086 	}
1087 	return retValue;
1088 }
1089 
doPrefSetSelected(bool force)1090 BOOL LDViewPreferences::doPrefSetSelected(bool force)
1091 {
1092 	ucstring selectedPrefSet = getSelectedPrefSet();
1093 	bool needToReselect = false;
1094 
1095 	if (checkAbandon && getApplyEnabled() && !force)
1096 	{
1097 		char *savedSession =
1098 			TCUserDefaults::getSavedSessionNameFromKey(PREFERENCE_SET_KEY);
1099 		ucstring ucSavedSession;
1100 
1101 		if (!savedSession || !savedSession[0])
1102 		{
1103 			ucSavedSession = DEFAULT_PREF_SET;
1104 		}
1105 		else
1106 		{
1107 			 utf8toucstring(ucSavedSession, savedSession);
1108 		}
1109 		delete[] savedSession;
1110 		if (selectedPrefSet == ucSavedSession)
1111 		{
1112 			return FALSE;
1113 		}
1114 		else
1115 		{
1116 			needToReselect = true;
1117 			selectPrefSet(_UC(""), true);
1118 			if (runPrefSetApplyDialog() == IDCANCEL)
1119 			{
1120 				checkAbandon = true;
1121 				return TRUE;
1122 			}
1123 		}
1124 	}
1125 	if (!selectedPrefSet.empty())
1126 	{
1127 		BOOL enabled = TRUE;
1128 
1129 		if (needToReselect)
1130 		{
1131 			selectPrefSet(selectedPrefSet);
1132 		}
1133 		if (selectedPrefSet == DEFAULT_PREF_SET)
1134 		{
1135 			enabled = FALSE;
1136 		}
1137 		EnableWindow(hDeletePrefSetButton, enabled);
1138 	}
1139 	enableApply(hPrefSetsPage);
1140 	checkAbandon = false;
1141 	return FALSE;
1142 }
1143 
doDialogThemeChanged(void)1144 BOOL LDViewPreferences::doDialogThemeChanged(void)
1145 {
1146 	if (hButtonTheme)
1147 	{
1148 		CUIThemes::closeThemeData(hButtonTheme);
1149 		hButtonTheme = NULL;
1150 	}
1151 /*
1152 	if (hTabTheme)
1153 	{
1154 		CUIThemes::closeThemeData(hTabTheme);
1155 		hTabTheme = NULL;
1156 	}
1157 */
1158 	if (CUIThemes::isThemeLibLoaded())
1159 	{
1160 		if (hBackgroundColorButton)
1161 		{
1162 			setupBackgroundColorButton();
1163 		}
1164 		if (hDefaultColorButton)
1165 		{
1166 			setupDefaultColorButton();
1167 		}
1168 		if (hGeometryPage)
1169 		{
1170 			setupGroupCheckButton(hGeometryPage, IDC_WIREFRAME,
1171 				ldPrefs->getDrawWireframe());
1172 		}
1173 /*
1174 		if (hLightDirStatic)
1175 		{
1176 			initThemesTab(hLightDirStatic);
1177 		}
1178 */
1179 	}
1180 	return FALSE;
1181 }
1182 
doDialogCommand(HWND hDlg,int controlId,int notifyCode,HWND controlHWnd)1183 BOOL LDViewPreferences::doDialogCommand(HWND hDlg, int controlId,
1184 										int notifyCode, HWND controlHWnd)
1185 {
1186 	UCCHAR className[1024];
1187 
1188 	GetClassName(controlHWnd, className, COUNT_OF(className));
1189 	if (ucstrcmp(className, WC_COMBOBOX) == 0)
1190 	{
1191 		if (notifyCode == CBN_SELCHANGE)
1192 		{
1193 			return doComboSelChange(hDlg, controlId, controlHWnd);
1194 		}
1195 	}
1196 	else if (notifyCode == BN_CLICKED)
1197 	{
1198 		return doClick(hDlg, controlId, controlHWnd);
1199 	}
1200 	else if (notifyCode == EN_CHANGE)
1201 	{
1202 		if (controlId == IDC_FS_RATE || controlId == IDC_FOV ||
1203 			controlId == IDC_PROXY_SERVER || controlId == IDC_PROXY_PORT ||
1204 			controlId == IDC_MISSING_DAYS || controlId == IDC_UPDATED_DAYS)
1205 		{
1206 			enableApply(hDlg);
1207 			return 0;
1208 		}
1209 	}
1210 	else if (notifyCode == LBN_SELCHANGE)
1211 	{
1212 		if (hDlg == hPrefSetsPage)
1213 		{
1214 			return doPrefSetSelected();
1215 		}
1216 	}
1217 	return LDP_UNKNOWN_COMMAND;
1218 }
1219 
setupBackgroundColorButton(void)1220 void LDViewPreferences::setupBackgroundColorButton(void)
1221 {
1222 	setupColorButton(hGeneralPage, hBackgroundColorButton,
1223 		IDC_BACKGROUND_COLOR, hBackgroundColorBitmap,
1224 		getBackgroundColor());
1225 }
1226 
setupDefaultColorButton(void)1227 void LDViewPreferences::setupDefaultColorButton(void)
1228 {
1229 	setupColorButton(hGeneralPage, hDefaultColorButton,
1230 		IDC_DEFAULT_COLOR, hDefaultColorBitmap,
1231 		getDefaultColor());
1232 }
1233 
staticIconButtonProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)1234 LRESULT CALLBACK LDViewPreferences::staticIconButtonProc(
1235 	HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1236 {
1237 	LDViewPreferences *thisPtr =
1238 		(LDViewPreferences *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
1239 
1240 	return thisPtr->iconButtonProc(hWnd, message, wParam, lParam);
1241 }
1242 
iconButtonProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)1243 LRESULT LDViewPreferences::iconButtonProc(
1244 	HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1245 {
1246 	switch (message)
1247 	{
1248 	case WM_MOUSEMOVE:
1249 		if (hMouseOverButton != hWnd)
1250 		{
1251 			if (hMouseOverButton)
1252 			{
1253 				InvalidateRect(hMouseOverButton, NULL, FALSE);
1254 			}
1255 			hMouseOverButton = hWnd;
1256 			InvalidateRect(hWnd, NULL, FALSE);
1257 		}
1258 		break;
1259 	}
1260 	return CallWindowProc((WNDPROC)origButtonWindowProc, hWnd, message, wParam,
1261 		lParam);
1262 }
1263 
staticGroupCheckButtonProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)1264 LRESULT CALLBACK LDViewPreferences::staticGroupCheckButtonProc(HWND hWnd,
1265 															   UINT message,
1266 															   WPARAM wParam,
1267 															   LPARAM lParam)
1268 {
1269 	LDViewPreferences *thisPtr =
1270 		(LDViewPreferences *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
1271 
1272 	return thisPtr->groupCheckButtonProc(hWnd, message, wParam, lParam);
1273 }
1274 
groupCheckButtonProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)1275 LRESULT LDViewPreferences::groupCheckButtonProc(HWND hWnd, UINT message,
1276 												WPARAM wParam, LPARAM lParam)
1277 {
1278 	switch (message)
1279 	{
1280 	case WM_MOUSEMOVE:
1281 		if (hMouseOverButton != hWnd)
1282 		{
1283 			if (hMouseOverButton)
1284 			{
1285 				InvalidateRect(hMouseOverButton, NULL, FALSE);
1286 			}
1287 			hMouseOverButton = hWnd;
1288 			InvalidateRect(hWnd, NULL, FALSE);
1289 		}
1290 		break;
1291 	}
1292 	return CallWindowProc((WNDPROC)origButtonWindowProc, hWnd, message, wParam,
1293 		lParam);
1294 }
1295 
staticColorButtonProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)1296 LRESULT CALLBACK LDViewPreferences::staticColorButtonProc(HWND hWnd,
1297 														  UINT message,
1298 														  WPARAM wParam,
1299 														  LPARAM lParam)
1300 {
1301 	LDViewPreferences *thisPtr =
1302 		(LDViewPreferences *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
1303 
1304 	return thisPtr->colorButtonProc(hWnd, message, wParam, lParam);
1305 }
1306 
colorButtonProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)1307 LRESULT LDViewPreferences::colorButtonProc(HWND hWnd, UINT message,
1308 										   WPARAM wParam, LPARAM lParam)
1309 {
1310 	switch (message)
1311 	{
1312 	case WM_MOUSEMOVE:
1313 		if (hMouseOverButton != hWnd)
1314 		{
1315 			if (hMouseOverButton)
1316 			{
1317 				InvalidateRect(hMouseOverButton, NULL, FALSE);
1318 			}
1319 			hMouseOverButton = hWnd;
1320 			InvalidateRect(hWnd, NULL, FALSE);
1321 		}
1322 		break;
1323 	}
1324 	return CallWindowProc((WNDPROC)origButtonWindowProc, hWnd, message, wParam,
1325 		lParam);
1326 }
1327 
setupIconButton(HWND hButton)1328 void LDViewPreferences::setupIconButton(HWND hButton)
1329 {
1330 	initThemesButton(hButton);
1331 	if (hButtonTheme)
1332 	{
1333 		LONG_PTR oldWindowProc;
1334 		DWORD dwStyle = GetWindowLong(hButton, GWL_STYLE);
1335 		int buttonType = dwStyle & BS_TYPEMASK;
1336 
1337 		buttonTypes[hButton] = buttonType;
1338 		if (buttonType != BS_OWNERDRAW)
1339 		{
1340 			dwStyle = (dwStyle & ~BS_TYPEMASK) | BS_OWNERDRAW;
1341 			buttonSetStyle(hButton, dwStyle);
1342 		}
1343 		// subclass the button so we can know when the mouse has moved over it
1344 		SetWindowLongPtr(hButton, GWLP_USERDATA, (LONG_PTR)this);
1345 		oldWindowProc = SetWindowLongPtr(hButton, GWLP_WNDPROC,
1346 			(LONG_PTR)staticIconButtonProc);
1347 		if (!origButtonWindowProc)
1348 		{
1349 			origButtonWindowProc = oldWindowProc;
1350 		}
1351 	}
1352 	else
1353 	{
1354 		if (origButtonWindowProc)
1355 		{
1356 			if (buttonTypes.find(hButton) != buttonTypes.end())
1357 			{
1358 				DWORD dwStyle = GetWindowLong(hButton, GWL_STYLE);
1359 
1360 				dwStyle = (dwStyle & ~BS_TYPEMASK) | buttonTypes[hButton];
1361 				buttonSetStyle(hButton, dwStyle);
1362 				// Put the window proc back if we've every overridden one.  Maybe
1363 				// the user disabled themes.
1364 				SetWindowLongPtr(hButton, GWLP_WNDPROC,
1365 					(LONG_PTR)origButtonWindowProc);
1366 			}
1367 		}
1368 	}
1369 }
1370 
setupColorButton(HWND hPage,HWND & hColorButton,int controlID,HBITMAP & hButtonBitmap,COLORREF color)1371 void LDViewPreferences::setupColorButton(HWND hPage, HWND &hColorButton,
1372 										 int controlID, HBITMAP &hButtonBitmap,
1373 										 COLORREF color)
1374 {
1375 	int imageWidth;
1376 	int imageHeight;
1377 	HDC hPageDC;
1378 	RECT clientRect;
1379 
1380 	initThemesButton(hColorButton);
1381 	if (hButtonBitmap)
1382 	{
1383 		DeleteObject(hButtonBitmap);
1384 		if (origButtonWindowProc)
1385 		{
1386 			SetWindowLongPtr(hColorButton, GWLP_WNDPROC,
1387 				(LONG_PTR)origButtonWindowProc);
1388 		}
1389 	}
1390 	hColorButton = GetDlgItem(hPage, controlID);
1391 	GetClientRect(hColorButton, &clientRect);
1392 	if (hButtonTheme)
1393 	{
1394 		RECT contentRect;
1395 
1396 		// subclass the Wizard button so we can know when the mouse has moved
1397 		// over it
1398 		SetWindowLongPtr(hColorButton, GWLP_USERDATA, (LONG_PTR)this);
1399 		if (origButtonWindowProc)
1400 		{
1401 			SetWindowLongPtr(hColorButton, GWLP_WNDPROC,
1402 				(LONG_PTR)staticColorButtonProc);
1403 		}
1404 		else
1405 		{
1406 			origButtonWindowProc = SetWindowLongPtr(hColorButton, GWLP_WNDPROC,
1407 				(LONG_PTR)staticColorButtonProc);
1408 		}
1409 		CUIThemes::getThemeBackgroundContentRect(hButtonTheme, NULL,
1410 			BP_PUSHBUTTON, PBS_HOT, &clientRect, &contentRect);
1411 		LONG margin = scalePoints(6);
1412 		imageWidth = contentRect.right - contentRect.left - margin;
1413 		imageHeight = contentRect.bottom - contentRect.top - margin;
1414 	}
1415 	else
1416 	{
1417 		LONG margin = scalePoints(10);
1418 		imageWidth = clientRect.right - clientRect.left - margin;
1419 		imageHeight = clientRect.bottom - clientRect.top - margin;
1420 	}
1421 	hPageDC = GetDC(hPage);
1422 	if (!hButtonColorDC)
1423 	{
1424 		hButtonColorDC = CreateCompatibleDC(hPageDC);
1425 	}
1426 	hButtonBitmap = CreateCompatibleBitmap(hPageDC, imageWidth, imageHeight);
1427 	ReleaseDC(hPage, hPageDC);
1428 	SetBitmapDimensionEx(hButtonBitmap, imageWidth, imageHeight, NULL);
1429 	redrawColorBitmap(hColorButton, hButtonBitmap, color);
1430 	CUIDialog::buttonSetBitmap(hPage, controlID, hButtonBitmap);
1431 }
1432 
enableSeams(void)1433 void LDViewPreferences::enableSeams(void)
1434 {
1435 	UCCHAR seamWidthString[128];
1436 
1437 	EnableWindow(hSeamSpin, TRUE);
1438 	setCheck(hGeometryPage, IDC_SEAMS, true);
1439 	sucprintf(seamWidthString, COUNT_OF(seamWidthString), _UC("%0.2f"),
1440 		ldPrefs->getSeamWidth() / 100.0f);
1441 	CUIDialog::windowSetText(hGeometryPage, IDC_SEAM_WIDTH_FIELD, seamWidthString);
1442 }
1443 
disableSeams(void)1444 void LDViewPreferences::disableSeams(void)
1445 {
1446 	EnableWindow(hSeamSpin, FALSE);
1447 	setCheck(hGeometryPage, IDC_SEAMS, false);
1448 	CUIDialog::windowSetText(hGeometryPage, IDC_SEAM_WIDTH_FIELD, _UC(""));
1449 }
1450 
enableTextureFiltering(void)1451 void LDViewPreferences::enableTextureFiltering(void)
1452 {
1453 	int activeTextureFilter;
1454 
1455 	EnableWindow(hTextureNearestButton, TRUE);
1456 	EnableWindow(hTextureBilinearButton, TRUE);
1457 	EnableWindow(hTextureTrilinearButton, TRUE);
1458 	EnableWindow(hAnisoLevelLabel, TRUE);
1459 	if (TREGLExtensions::haveAnisoExtension())
1460 	{
1461 		EnableWindow(hTextureAnisoButton, TRUE);
1462 	}
1463 	else
1464 	{
1465 		EnableWindow(hTextureAnisoButton, FALSE);
1466 	}
1467 	setCheck(hPrimitivesPage, IDC_TEXTURE_NEAREST, false);
1468 	setCheck(hPrimitivesPage, IDC_TEXTURE_BILINEAR, false);
1469 	setCheck(hPrimitivesPage, IDC_TEXTURE_TRILINEAR, false);
1470 	setCheck(hPrimitivesPage, IDC_TEXTURE_ANISO, false);
1471 	switch (ldPrefs->getTextureFilterType())
1472 	{
1473 	case GL_NEAREST_MIPMAP_NEAREST:
1474 		activeTextureFilter = IDC_TEXTURE_NEAREST;
1475 		break;
1476 	case GL_LINEAR_MIPMAP_NEAREST:
1477 		activeTextureFilter = IDC_TEXTURE_BILINEAR;
1478 		break;
1479 	case GL_LINEAR_MIPMAP_LINEAR:
1480 		activeTextureFilter = IDC_TEXTURE_TRILINEAR;
1481 		break;
1482 	default:
1483 		ldPrefs->setTextureFilterType(GL_LINEAR_MIPMAP_LINEAR);
1484 		activeTextureFilter = IDC_TEXTURE_TRILINEAR;
1485 		break;
1486 	}
1487 	if (activeTextureFilter == IDC_TEXTURE_TRILINEAR &&
1488 		ldPrefs->getAnisoLevel() > 1.0)
1489 	{
1490 		EnableWindow(hAnisoLevelSlider, TRUE);
1491 		activeTextureFilter = IDC_TEXTURE_ANISO;
1492 	}
1493 	else
1494 	{
1495 		EnableWindow(hAnisoLevelSlider, FALSE);
1496 	}
1497 	setCheck(hPrimitivesPage, activeTextureFilter, true);
1498 }
1499 
disableTextureFiltering(void)1500 void LDViewPreferences::disableTextureFiltering(void)
1501 {
1502 	EnableWindow(hTextureNearestButton, FALSE);
1503 	EnableWindow(hTextureBilinearButton, FALSE);
1504 	EnableWindow(hTextureTrilinearButton, FALSE);
1505 	EnableWindow(hTextureAnisoButton, FALSE);
1506 	EnableWindow(hAnisoLevelSlider, FALSE);
1507 	EnableWindow(hAnisoLevelLabel, FALSE);
1508 	setCheck(hPrimitivesPage, IDC_TEXTURE_NEAREST, false);
1509 	setCheck(hPrimitivesPage, IDC_TEXTURE_BILINEAR, false);
1510 	setCheck(hPrimitivesPage, IDC_TEXTURE_TRILINEAR, false);
1511 	setCheck(hPrimitivesPage, IDC_TEXTURE_ANISO, false);
1512 }
1513 
enableTexmaps(void)1514 void LDViewPreferences::enableTexmaps(void)
1515 {
1516 	EnableWindow(hTextureOffsetLabel, TRUE);
1517 	EnableWindow(hTextureOffsetSlider, TRUE);
1518 }
1519 
disableTexmaps(void)1520 void LDViewPreferences::disableTexmaps(void)
1521 {
1522 	EnableWindow(hTextureOffsetLabel, FALSE);
1523 	EnableWindow(hTextureOffsetSlider, FALSE);
1524 }
1525 
enablePrimitives(void)1526 void LDViewPreferences::enablePrimitives(void)
1527 {
1528 	EnableWindow(hTextureStudsButton, TRUE);
1529 	EnableWindow(hCurveQualityLabel, TRUE);
1530 	EnableWindow(hCurveQualitySlider, TRUE);
1531 	setCheck(hPrimitivesPage, IDC_TEXTURE_STUDS,ldPrefs->getTextureStuds());
1532 	updateTextureFilteringEnabled();
1533 	updateTexmapsEnabled();
1534 }
1535 
disablePrimitives(void)1536 void LDViewPreferences::disablePrimitives(void)
1537 {
1538 	EnableWindow(hTextureStudsButton, FALSE);
1539 	EnableWindow(hCurveQualityLabel, FALSE);
1540 	EnableWindow(hCurveQualitySlider, FALSE);
1541 	setCheck(hPrimitivesPage, IDC_TEXTURE_STUDS, false);
1542 	updateTextureFilteringEnabled();
1543 	updateTexmapsEnabled();
1544 }
1545 
setupSeamWidth(void)1546 void LDViewPreferences::setupSeamWidth(void)
1547 {
1548 	UDACCEL accels[] = {{0, 1}, {1, 10}, {2, 20}};
1549 
1550 	hSeamSpin = GetDlgItem(hGeometryPage, IDC_SEAM_SPIN);
1551 	SendDlgItemMessage(hGeometryPage, IDC_SEAM_SPIN, UDM_SETRANGE, 0,
1552 		MAKELONG((short)500, (short)0));
1553 	SendDlgItemMessage(hGeometryPage, IDC_SEAM_SPIN, UDM_SETPOS, 0,
1554 		ldPrefs->getSeamWidth());
1555 	SendDlgItemMessage(hGeometryPage, IDC_SEAM_SPIN, UDM_SETACCEL,
1556 		COUNT_OF(accels), (LPARAM)accels);
1557 	if (ldPrefs->getUseSeams())
1558 	{
1559 		enableSeams();
1560 	}
1561 	else
1562 	{
1563 		disableSeams();
1564 	}
1565 }
1566 
setupFullScreenRefresh(void)1567 void LDViewPreferences::setupFullScreenRefresh(void)
1568 {
1569 	int fullScreenRefresh = ldPrefs->getFullScreenRefresh();
1570 
1571 	hFullScreenRateField = GetDlgItem(hGeneralPage, IDC_FS_RATE);
1572 	SendDlgItemMessage(hGeneralPage, IDC_FS_RATE, EM_SETLIMITTEXT, 3, 0);
1573 	if (fullScreenRefresh)
1574 	{
1575 		UCCHAR buf[128];
1576 
1577 		sucprintf(buf, COUNT_OF(buf), _UC("%d"), fullScreenRefresh);
1578 		buf[3] = 0;
1579 		CUIDialog::windowSetText(hGeneralPage, IDC_FS_RATE, buf);
1580 		setCheck(hGeneralPage, IDC_FS_REFRESH, true);
1581 		EnableWindow(hFullScreenRateField, TRUE);
1582 	}
1583 	else
1584 	{
1585 		CUIDialog::windowSetText(hGeneralPage, IDC_FS_RATE, _UC(""));
1586 		setCheck(hGeneralPage, IDC_FS_REFRESH, false);
1587 		EnableWindow(hFullScreenRateField, FALSE);
1588 	}
1589 }
1590 
redrawColorBitmap(HWND hColorButton,HBITMAP hButtonBitmap,COLORREF color)1591 void LDViewPreferences::redrawColorBitmap(HWND hColorButton,
1592 										  HBITMAP hButtonBitmap, COLORREF color)
1593 {
1594 	HBRUSH hBrush = CreateSolidBrush(color);
1595 	RECT bitmapRect;
1596 	SIZE bitmapSize;
1597 	HBITMAP hOldBitmap;
1598 	HBRUSH hOldBrush;
1599 
1600 	GetBitmapDimensionEx(hButtonBitmap, &bitmapSize);
1601 	bitmapRect.left = 0;
1602 	bitmapRect.top = 0;
1603 	bitmapRect.right = bitmapSize.cx;
1604 	bitmapRect.bottom = bitmapSize.cy;
1605 	hOldBrush = (HBRUSH)SelectObject(hButtonColorDC, hBrush);
1606 	hOldBitmap = (HBITMAP)SelectObject(hButtonColorDC, hButtonBitmap);
1607 	FillRect(hButtonColorDC, &bitmapRect, hBrush);
1608 	if (CUIThemes::isThemeLibLoaded() && hButtonTheme)
1609 	{
1610 		CUIThemes::drawThemeEdge(hButtonTheme, hButtonColorDC, BP_PUSHBUTTON,
1611 			PBS_PRESSED, &bitmapRect, EDGE_SUNKEN, BF_SOFT | BF_RECT, NULL);
1612 	}
1613 	else
1614 	{
1615 		DrawEdge(hButtonColorDC, &bitmapRect, EDGE_SUNKEN,
1616 			BF_BOTTOMLEFT | BF_TOPRIGHT);
1617 	}
1618 	SelectObject(hButtonColorDC, hOldBrush);
1619 	SelectObject(hButtonColorDC, hOldBitmap);
1620 	DeleteObject(hBrush);
1621 	InvalidateRect(hColorButton, NULL, 1);
1622 }
1623 
applyPrefSetsChanges(void)1624 void LDViewPreferences::applyPrefSetsChanges(void)
1625 {
1626 	if (hPrefSetsPage)
1627 	{
1628 		TCStringArray *oldPrefSetNames = TCUserDefaults::getAllSessionNames();
1629 		int i;
1630 		int count = oldPrefSetNames->getCount();
1631 		ucstring ucPrefSetName;
1632 		const char *sessionName = TCUserDefaults::getSessionName();
1633 		bool changed = false;
1634 
1635 		for (i = 0; i < count; i++)
1636 		{
1637 			char *oldPrefSetName = oldPrefSetNames->stringAtIndex(i);
1638 			ucstring ucOldPrefSetName;
1639 			utf8toucstring(ucOldPrefSetName, oldPrefSetName);
1640 			int index = listBoxFindStringExact(hPrefSetsList, ucOldPrefSetName);
1641 
1642 			if (index == LB_ERR)
1643 			{
1644 				TCUserDefaults::removeSession(oldPrefSetName);
1645 			}
1646 		}
1647 		count = listBoxGetCount(hPrefSetsList);
1648 		for (i = 1; i < count; i++)
1649 		{
1650 			ucPrefSetName = getPrefSet(i);
1651 			std::string prefSetName;
1652 			ucstringtoutf8(prefSetName, ucPrefSetName);
1653 			if (oldPrefSetNames->indexOfString(prefSetName.c_str()) < 0)
1654 			{
1655 				TCUserDefaults::setSessionName(prefSetName.c_str(),
1656 					PREFERENCE_SET_KEY);
1657 			}
1658 		}
1659 		oldPrefSetNames->release();
1660 		ucPrefSetName = getSelectedPrefSet();
1661 		if (ucPrefSetName == DEFAULT_PREF_SET)
1662 		{
1663 			if (sessionName && sessionName[0])
1664 			{
1665 				TCUserDefaults::setSessionName(NULL, PREFERENCE_SET_KEY);
1666 				changed = true;
1667 			}
1668 		}
1669 		else
1670 		{
1671 			ucstring ucSessionName;
1672 			utf8toucstring(ucSessionName, sessionName);
1673 			if (ucPrefSetName != ucSessionName)
1674 			{
1675 				std::string prefSetName;
1676 				ucstringtoutf8(prefSetName, ucPrefSetName);
1677 				TCUserDefaults::setSessionName(prefSetName.c_str(),
1678 					PREFERENCE_SET_KEY);
1679 				changed = true;
1680 			}
1681 		}
1682 		if (changed)
1683 		{
1684 			loadSettings();
1685 			applySettings();
1686 			if (hGeneralPage)
1687 			{
1688 				setupPage(generalPageNumber);
1689 			}
1690 			if (hGeometryPage)
1691 			{
1692 				setupPage(geometryPageNumber);
1693 			}
1694 			if (hEffectsPage)
1695 			{
1696 				setupPage(effectsPageNumber);
1697 			}
1698 			if (hPrimitivesPage)
1699 			{
1700 				setupPage(primitivesPageNumber);
1701 			}
1702 			if (hUpdatesPage)
1703 			{
1704 				setupPage(updatesPageNumber);
1705 			}
1706 		}
1707 	}
1708 }
1709 
applyGeneralChanges(void)1710 void LDViewPreferences::applyGeneralChanges(void)
1711 {
1712 	if (hGeneralPage)
1713 	{
1714 		int iTemp = 0;
1715 		float fTemp;
1716 
1717 		ldPrefs->setLineSmoothing(getCheck(hGeneralPage, IDC_LINE_AA));
1718 		ldPrefs->setTransDefaultColor(getCheck(hGeneralPage,
1719 			IDC_TRANS_DEFAULT_COLOR));
1720 		ldPrefs->setProcessLdConfig(getCheck(hGeneralPage,
1721 			IDC_PROCESS_LDCONFIG));
1722 		ldPrefs->setRandomColors(getCheck(hGeneralPage, IDC_RANDOM_COLORS));
1723 		ldPrefs->setShowFps(getCheck(hGeneralPage, IDC_FRAME_RATE));
1724 		ldPrefs->setShowAxes(getCheck(hGeneralPage, IDC_SHOW_AXES));
1725 		ldPrefs->setShowErrors(getCheck(hGeneralPage, IDC_SHOW_ERRORS));
1726 		ldPrefs->setMemoryUsage(CUIDialog::comboGetCurSel(hGeneralPage,
1727 			IDC_MEMORY_COMBO));
1728 		if (getCheck(hGeneralPage, IDC_FS_REFRESH))
1729 		{
1730 			if (CUIDialog::windowGetValue(hGeneralPage, IDC_FS_RATE, iTemp))
1731 			{
1732 				if (!iTemp)
1733 				{
1734 					iTemp = -1;
1735 				}
1736 			}
1737 			else
1738 			{
1739 				iTemp = -1;
1740 			}
1741 		}
1742 		if (iTemp >= 0)
1743 		{
1744 			ldPrefs->setFullScreenRefresh(iTemp);
1745 		}
1746 		if (CUIDialog::windowGetValue(hGeneralPage, IDC_FOV, fTemp))
1747 		{
1748 			if (fTemp >= getMinFov() && fTemp <= getMaxFov())
1749 			{
1750 				ldPrefs->setFov(fTemp);
1751 			}
1752 			else
1753 			{
1754 				setupFov(true);
1755 			}
1756 		}
1757 		else
1758 		{
1759 			setupFov(true);
1760 		}
1761 		ldPrefs->setSnapshotsDirMode(snapshotDirMode);
1762 		if (snapshotDirMode == LDPreferences::DDMSpecificDir)
1763 		{
1764 			windowGetText(hSnapshotDirField, snapshotDir);
1765 			if (snapshotDir.length() > 0)
1766 			{
1767 				std::string utf8Dir;
1768 				ucstringtoutf8(utf8Dir, snapshotDir);
1769 				ldPrefs->setSnapshotsDir(utf8Dir.c_str());
1770 			}
1771 			else
1772 			{
1773 				ldPrefs->setSnapshotsDirMode(LDPreferences::DDMLastDir);
1774 			}
1775 		}
1776 		ldPrefs->setPartsListsDirMode(partsListDirMode);
1777 		if (partsListDirMode == LDPreferences::DDMSpecificDir)
1778 		{
1779 			windowGetText(hPartsListDirField, partsListDir);
1780 			if (partsListDir.length() > 0)
1781 			{
1782 				std::string utf8Dir;
1783 				ucstringtoutf8(utf8Dir, partsListDir);
1784 				ldPrefs->setPartsListsDir(utf8Dir.c_str());
1785 			}
1786 			else
1787 			{
1788 				ldPrefs->setPartsListsDirMode(LDPreferences::DDMLastDir);
1789 			}
1790 		}
1791 		ldPrefs->setSaveDirMode(LDPreferences::SOExport, exportDirMode);
1792 		if (exportDirMode == LDPreferences::DDMSpecificDir)
1793 		{
1794 			windowGetText(hExportDirField, exportDir);
1795 			if (exportDir.length() > 0)
1796 			{
1797 				std::string utf8Dir;
1798 				ucstringtoutf8(utf8Dir, exportDir);
1799 				ldPrefs->setSaveDir(LDPreferences::SOExport, utf8Dir.c_str());
1800 			}
1801 			else
1802 			{
1803 				ldPrefs->setSaveDirMode(LDPreferences::SOExport,
1804 					LDPreferences::DDMLastDir);
1805 			}
1806 		}
1807 		ldPrefs->applyGeneralSettings();
1808 	}
1809 	ldPrefs->commitGeneralSettings();
1810 }
1811 
applyGeometryChanges(void)1812 void LDViewPreferences::applyGeometryChanges(void)
1813 {
1814 	if (hGeometryPage)
1815 	{
1816 		ldPrefs->setUseSeams(getCheck(hGeometryPage, IDC_SEAMS));
1817 		ldPrefs->setBoundingBoxesOnly(getCheck(hGeometryPage,
1818 			IDC_PART_BOUNDING_BOXES));
1819 		ldPrefs->setDrawWireframe(getCachedCheck(hGeometryPage, IDC_WIREFRAME));
1820 		ldPrefs->setUseWireframeFog(getCheck(hGeometryPage, IDC_WIREFRAME_FOG));
1821 		ldPrefs->setRemoveHiddenLines(getCheck(hGeometryPage,
1822 			IDC_REMOVE_HIDDEN_LINES));
1823 		ldPrefs->setWireframeThickness(CUIDialog::trackBarGetPos(hGeometryPage,
1824 			IDC_WIREFRAME_THICKNESS));
1825 		ldPrefs->setBfc(getCachedCheck(hGeometryPage, IDC_BFC));
1826 		ldPrefs->setRedBackFaces(getCheck(hGeometryPage, IDC_RED_BACK_FACES));
1827 		ldPrefs->setGreenFrontFaces(getCheck(hGeometryPage,
1828 			IDC_GREEN_FRONT_FACES));
1829 		ldPrefs->setBlueNeutralFaces(getCheck(hGeometryPage,
1830 			IDC_BLUE_NEUTRAL_FACES));
1831 		ldPrefs->setShowHighlightLines(getCachedCheck(hGeometryPage,
1832 			IDC_HIGHLIGHTS));
1833 		if (ldPrefs->getShowHighlightLines())
1834 		{
1835 			ldPrefs->setEdgesOnly(getCheck(hGeometryPage, IDC_EDGES_ONLY));
1836 			ldPrefs->setDrawConditionalHighlights(getCheck(hGeometryPage,
1837 				IDC_CONDITIONAL_HIGHLIGHTS));
1838 			if (ldPrefs->getDrawConditionalHighlights())
1839 			{
1840 				ldPrefs->setShowAllConditionalLines(getCheck(hGeometryPage,
1841 					IDC_ALL_CONDITIONAL));
1842 				ldPrefs->setShowConditionalControlPoints(getCheck(hGeometryPage,
1843 					IDC_CONDITIONAL_CONTROLS));
1844 			}
1845 			ldPrefs->setUsePolygonOffset(getCheck(hGeometryPage,
1846 				IDC_QUALITY_LINES));
1847 			ldPrefs->setBlackHighlights(getCheck(hGeometryPage,
1848 				IDC_ALWAYS_BLACK));
1849 		}
1850 		ldPrefs->setEdgeThickness(CUIDialog::trackBarGetPos(hGeometryPage,
1851 			IDC_EDGE_THICKNESS));
1852 		ldPrefs->applyGeometrySettings();
1853 	}
1854 	ldPrefs->commitGeometrySettings();
1855 }
1856 
getSelectedLightDirection(void)1857 LDPreferences::LightDirection LDViewPreferences::getSelectedLightDirection(void)
1858 {
1859 	LDPreferences::LightDirection lightDirection =
1860 		LDPreferences::CustomDirection;
1861 	for (IntIntMap::const_iterator it = lightDirIndexToId.begin()
1862 		; it != lightDirIndexToId.end(); it++)
1863 	{
1864 		if (getCachedCheck(hEffectsPage, it->second))
1865 		{
1866 			lightDirection =
1867 				(LDPreferences::LightDirection)(it->first + 1);
1868 			break;
1869 		}
1870 	}
1871 	return lightDirection;
1872 }
1873 
applyEffectsChanges(void)1874 void LDViewPreferences::applyEffectsChanges(void)
1875 {
1876 	if (hEffectsPage)
1877 	{
1878 		ldPrefs->setUseLighting(getCachedCheck(hEffectsPage, IDC_LIGHTING));
1879 		if (ldPrefs->getUseLighting())
1880 		{
1881 			LDPreferences::LightDirection lightDirection =
1882 				getSelectedLightDirection();
1883 			ldPrefs->setQualityLighting(getCheck(hEffectsPage,
1884 				IDC_LIGHTING_QUALITY));
1885 			ldPrefs->setSubduedLighting(getCheck(hEffectsPage,
1886 				IDC_LIGHTING_SUBDUED));
1887 			ldPrefs->setUseSpecular(getCheck(hEffectsPage, IDC_SPECULAR));
1888 			ldPrefs->setOneLight(getCheck(hEffectsPage,
1889 				IDC_ALTERNATE_LIGHTING));
1890 			if (lightDirection != LDPreferences::CustomDirection)
1891 			{
1892 				ldPrefs->setLightDirection(lightDirection);
1893 			}
1894 			if (getCheck(hEffectsPage, IDC_DRAW_LIGHT_DATS))
1895 			{
1896 				ldPrefs->setDrawLightDats(true);
1897 				ldPrefs->setOptionalStandardLight(getCheck(hEffectsPage,
1898 					IDC_OPTIONAL_STANDARD_LIGHT));
1899 			}
1900 			else
1901 			{
1902 				ldPrefs->setDrawLightDats(false);
1903 			}
1904 		}
1905 		// NOTE: the following setting doesn't require lighting to be enabled.
1906 		ldPrefs->setNoLightGeom(getCheck(hEffectsPage, IDC_HIDE_LIGHT_DAT));
1907 		ldPrefs->setStereoEyeSpacing(CUIDialog::trackBarGetPos(hEffectsPage,
1908 			IDC_STEREO_SPACING));
1909 		ldPrefs->setCutawayAlpha(CUIDialog::trackBarGetPos(hEffectsPage,
1910 			IDC_CUTAWAY_OPACITY));
1911 		ldPrefs->setCutawayThickness(CUIDialog::trackBarGetPos(hEffectsPage,
1912 			IDC_CUTAWAY_THICKNESS));
1913 		ldPrefs->setUseStipple(getCheck(hEffectsPage, IDC_STIPPLE));
1914 		ldPrefs->setSortTransparent(getCheck(hEffectsPage, IDC_SORT));
1915 		ldPrefs->setUseFlatShading(getCheck(hEffectsPage, IDC_FLAT_SHADING));
1916 		ldPrefs->setPerformSmoothing(getCheck(hEffectsPage, IDC_SMOOTH_CURVES));
1917 		ldPrefs->applyEffectsSettings();
1918 	}
1919 	ldPrefs->commitEffectsSettings();
1920 }
1921 
applyPrimitivesChanges(void)1922 void LDViewPreferences::applyPrimitivesChanges(void)
1923 {
1924 	if (hPrimitivesPage)
1925 	{
1926 		ldPrefs->setAllowPrimitiveSubstitution(getCachedCheck(hPrimitivesPage,
1927 			IDC_PRIMITIVE_SUBSTITUTION));
1928 		if (ldPrefs->getAllowPrimitiveSubstitution())
1929 		{
1930 			ldPrefs->setTextureStuds(getCheck(hPrimitivesPage,
1931 				IDC_TEXTURE_STUDS));
1932 			ldPrefs->setCurveQuality(CUIDialog::trackBarGetPos(hPrimitivesPage,
1933 				IDC_CURVE_QUALITY));
1934 		}
1935 		ldPrefs->setTexmaps(getCheck(hPrimitivesPage, IDC_TEXMAPS));
1936 		if (getTexmaps())
1937 		{
1938 			ldPrefs->setTextureOffsetFactor(textureOffsetFromSliderValue(
1939 				trackBarGetPos(hTextureOffsetSlider)));
1940 		}
1941 		ldPrefs->setQualityStuds(!getCheck(hPrimitivesPage, IDC_STUD_QUALITY));
1942 		ldPrefs->setHiResPrimitives(getCheck(hPrimitivesPage, IDC_HI_RES));
1943 		ldPrefs->applyPrimitivesSettings();
1944 	}
1945 	ldPrefs->commitPrimitivesSettings();
1946 }
1947 
applyUpdatesChanges(void)1948 void LDViewPreferences::applyUpdatesChanges(void)
1949 {
1950 	if (hUpdatesPage)
1951 	{
1952 		ucstring tempString;
1953 		int tempNum;
1954 
1955 		ldPrefs->setCheckPartTracker(getCheck(hUpdatesPage,
1956 			IDC_CHECK_PART_TRACKER));
1957 		if (ldPrefs->getCheckPartTracker())
1958 		{
1959 			UCCHAR buf[128];
1960 
1961 			if (windowGetValue(hMissingParts, tempNum))
1962 			{
1963 				if (tempNum > 0)
1964 				{
1965 					ldPrefs->setMissingPartWait(tempNum);
1966 				}
1967 			}
1968 			sucprintf(buf, COUNT_OF(buf), _UC("%0d"), ldPrefs->getMissingPartWait());
1969 			windowSetText(hMissingParts, buf);
1970 			if (windowGetValue(hUpdatedParts, tempNum))
1971 			{
1972 				if (tempNum > 0)
1973 				{
1974 					ldPrefs->setUpdatedPartWait(tempNum);
1975 				}
1976 			}
1977 			sucprintf(buf, COUNT_OF(buf), _UC("%0d"), ldPrefs->getUpdatedPartWait());
1978 			windowSetText(hUpdatedParts, buf);
1979 		}
1980 		windowGetText(hProxyServer, tempString);
1981 		if (!tempString.empty())
1982 		{
1983 			std::string utf8Temp;
1984 			ucstringtoutf8(utf8Temp, tempString);
1985 			ldPrefs->setProxyServer(utf8Temp.c_str());
1986 		}
1987 		if (windowGetValue(hProxyPort, tempNum))
1988 		{
1989 			ldPrefs->setProxyPort(tempNum);
1990 		}
1991 		ldPrefs->applyUpdatesSettings();
1992 	}
1993 	ldPrefs->commitUpdatesSettings();
1994 }
1995 
applyChanges(void)1996 void LDViewPreferences::applyChanges(void)
1997 {
1998 	applyGeneralChanges();
1999 	applyGeometryChanges();
2000 	applyEffectsChanges();
2001 	applyPrimitivesChanges();
2002 	applyUpdatesChanges();
2003 	applyPrefSetsChanges();	// Note that if there are any pref sets changes,
2004 							// there can't be any other changes.
2005 }
2006 
saveDefaultView(void)2007 void LDViewPreferences::saveDefaultView(void)
2008 {
2009 	ldPrefs->saveDefaultView();
2010 }
2011 
resetDefaultView(void)2012 void LDViewPreferences::resetDefaultView(void)
2013 {
2014 	ldPrefs->resetDefaultView();
2015 }
2016 
getRGB(int color,int & r,int & g,int & b)2017 void LDViewPreferences::getRGB(int color, int &r, int &g, int &b)
2018 {
2019 	r = color & 0xFF;
2020 	g = (color >> 8) & 0xFF;
2021 	b = (color >> 16) & 0xFF;
2022 }
2023 
chooseBackgroundColor(void)2024 void LDViewPreferences::chooseBackgroundColor(void)
2025 {
2026 	COLORREF backgroundColor = getBackgroundColor();
2027 	int r, g, b;
2028 
2029 	chooseColor(hBackgroundColorButton, hBackgroundColorBitmap,
2030 		backgroundColor);
2031 	r = GetRValue(backgroundColor);
2032 	g = GetGValue(backgroundColor);
2033 	b = GetBValue(backgroundColor);
2034 	ldPrefs->setBackgroundColor(r, g, b);
2035 }
2036 
chooseDefaultColor(void)2037 void LDViewPreferences::chooseDefaultColor(void)
2038 {
2039 	COLORREF defaultColor = getDefaultColor();
2040 	int r, g, b;
2041 
2042 	chooseColor(hDefaultColorButton, hDefaultColorBitmap, defaultColor);
2043 	r = GetRValue(defaultColor);
2044 	g = GetGValue(defaultColor);
2045 	b = GetBValue(defaultColor);
2046 	ldPrefs->setDefaultColor(r, g, b);
2047 }
2048 
chooseColor(HWND hColorButton,HBITMAP hColorBitmap,COLORREF & color)2049 void LDViewPreferences::chooseColor(HWND hColorButton, HBITMAP hColorBitmap,
2050 									COLORREF &color)
2051 {
2052 	CHOOSECOLOR chooseColor;
2053 	int i;
2054 	COLORREF customColors[16];
2055 	int r, g, b;
2056 
2057 	for (i = 0; i < 16; i++)
2058 	{
2059 		ldPrefs->getCustomColor(i, r, g, b);
2060 		customColors[i] = RGB(r, g, b);
2061 	}
2062 	memset(&chooseColor, 0, sizeof CHOOSECOLOR);
2063 	chooseColor.lStructSize = sizeof CHOOSECOLOR;
2064 	chooseColor.hwndOwner = hPropSheet;
2065 	chooseColor.rgbResult = color;
2066 	chooseColor.lpCustColors = customColors;
2067 	chooseColor.Flags = CC_ANYCOLOR | CC_RGBINIT;
2068 	EnableWindow(hPropSheet, FALSE);
2069 	if (ChooseColor(&chooseColor))
2070 	{
2071 		color = chooseColor.rgbResult;
2072 		redrawColorBitmap(hColorButton, hColorBitmap, color);
2073 	}
2074 	for (i = 0; i < 16; i++)
2075 	{
2076 		r = GetRValue(customColors[i]);
2077 		g = GetGValue(customColors[i]);
2078 		b = GetBValue(customColors[i]);
2079 		ldPrefs->setCustomColor(i, r, g, b);
2080 	}
2081 	EnableWindow(hPropSheet, TRUE);
2082 }
2083 
browseForDir(CUCSTR prompt,HWND hTextField,ucstring & dir)2084 void LDViewPreferences::browseForDir(
2085 	CUCSTR prompt,
2086 	HWND hTextField,
2087 	ucstring &dir)
2088 {
2089 	ucstring newDir = LDViewWindow::browseForDir(prompt, dir.c_str());
2090 
2091 	if (!newDir.empty())
2092 	{
2093 		dir = newDir;
2094 		SetWindowText(hTextField, dir.c_str());
2095 		enableApply(GetParent(hTextField));
2096 	}
2097 }
2098 
doGeneralClick(int controlId,HWND)2099 void LDViewPreferences::doGeneralClick(int controlId, HWND /*controlHWnd*/)
2100 {
2101 	switch (controlId)
2102 	{
2103 		case IDC_FS_REFRESH:
2104 			doFSRefresh();
2105 			break;
2106 		case IDC_BACKGROUND_COLOR:
2107 			chooseBackgroundColor();
2108 			break;
2109 		case IDC_DEFAULT_COLOR:
2110 			chooseDefaultColor();
2111 			break;
2112 		case IDC_GENERAL_RESET:
2113 			ldPrefs->loadDefaultGeneralSettings(false);
2114 			setupGeneralPage();
2115 			break;
2116 		case IDC_BROWSE_SNAPSHOTS_DIR:
2117 			browseForDir(ls(_UC("BrowseForSnapshotDir")), hSnapshotDirField,
2118 				snapshotDir);
2119 			break;
2120 		case IDC_BROWSE_PARTS_LIST_DIR:
2121 			browseForDir(ls(_UC("BrowseForPartsListDir")), hPartsListDirField,
2122 				partsListDir);
2123 			break;
2124 		case IDC_BROWSE_EXPORT_DIR:
2125 			browseForDir(ls(_UC("BrowseForExportListDir")), hExportDirField,
2126 				exportDir);
2127 			break;
2128 	}
2129 	enableApply(hGeneralPage);
2130 }
2131 
doGeometryClick(int controlId,HWND)2132 void LDViewPreferences::doGeometryClick(int controlId, HWND /*controlHWnd*/)
2133 {
2134 	switch (controlId)
2135 	{
2136 		case IDC_HIGHLIGHTS:
2137 			doHighlights();
2138 			break;
2139 		case IDC_CONDITIONAL_HIGHLIGHTS:
2140 			doConditionals();
2141 			break;
2142 		case IDC_WIREFRAME:
2143 			doWireframe();
2144 			break;
2145 		case IDC_BFC:
2146 			doBfc();
2147 			break;
2148 		case IDC_SEAMS:
2149 			doSeams();
2150 			break;
2151 		case IDC_GEOMETRY_RESET:
2152 			ldPrefs->loadDefaultGeometrySettings(false);
2153 			setupGeometryPage();
2154 			break;
2155 	}
2156 	enableApply(hGeometryPage);
2157 }
2158 
doEffectsClick(int controlId,HWND)2159 void LDViewPreferences::doEffectsClick(int controlId, HWND /*controlHWnd*/)
2160 {
2161 	switch (controlId)
2162 	{
2163 		case IDC_LIGHTING:
2164 			doLighting();
2165 			break;
2166 		case IDC_DRAW_LIGHT_DATS:
2167 			doDrawLightDats();
2168 			break;
2169 		case IDC_STIPPLE:
2170 			doStipple();
2171 			break;
2172 		case IDC_SORT:
2173 			doSort();
2174 			break;
2175 		case IDC_FLAT_SHADING:
2176 			doFlatShading();
2177 			break;
2178 		case IDC_SMOOTH_CURVES:
2179 			doSmoothCurves();
2180 			break;
2181 		case IDC_STEREO:
2182 			doStereo();
2183 			break;
2184 		case IDC_HARDWARE_STEREO:
2185 			ldPrefs->setStereoMode(LDVStereoHardware);
2186 			break;
2187 		case IDC_CROSS_EYED_STEREO:
2188 			ldPrefs->setStereoMode(LDVStereoCrossEyed);
2189 			break;
2190 		case IDC_PARALLEL_STEREO:
2191 			ldPrefs->setStereoMode(LDVStereoParallel);
2192 			break;
2193 		case IDC_CUTAWAY:
2194 			doCutaway();
2195 			break;
2196 		case IDC_CUTAWAY_COLOR:
2197 			ldPrefs->setCutawayMode(LDVCutawayWireframe);
2198 			setupOpacitySlider();
2199 			break;
2200 		case IDC_CUTAWAY_MONOCHROME:
2201 			ldPrefs->setCutawayMode(LDVCutawayStencil);
2202 			setupOpacitySlider();
2203 			break;
2204 		case IDC_EFFECTS_RESET:
2205 			ldPrefs->loadDefaultEffectsSettings(false);
2206 			setupEffectsPage();
2207 			break;
2208 	}
2209 	if (lightDirIdToIndex.find(controlId) != lightDirIdToIndex.end())
2210 	{
2211 		if (!getCachedCheck(hEffectsPage, controlId))
2212 		{
2213 			for (IntIntMap::const_iterator it = lightDirIndexToId.begin()
2214 				; it != lightDirIndexToId.end(); it++)
2215 			{
2216 				if (getCachedCheck(hEffectsPage, it->second))
2217 				{
2218 					getCachedCheck(hEffectsPage, it->second, true);
2219 					InvalidateRect(lightAngleButtons[it->first], NULL, TRUE);
2220 				}
2221 			}
2222 			getCachedCheck(hEffectsPage, controlId, true);
2223 		}
2224 	}
2225 	enableApply(hEffectsPage);
2226 }
2227 
doDeletePrefSet(void)2228 void LDViewPreferences::doDeletePrefSet(void)
2229 {
2230 	ucstring selectedPrefSet = getSelectedPrefSet();
2231 
2232 	if (!selectedPrefSet.empty())
2233 	{
2234 		int selectedIndex = listBoxFindStringExact(hPrefSetsList, selectedPrefSet);
2235 
2236 		if (checkAbandon && getApplyEnabled())
2237 		{
2238 			if (messageBoxUC(hWindow,
2239 				ls(_UC("PrefSetAbandonConfirm")),
2240 				ls(_UC("AbandonChanges")),
2241 				MB_YESNO | MB_ICONQUESTION) == IDYES)
2242 			{
2243 				abandonChanges();
2244 			}
2245 			else
2246 			{
2247 				return;
2248 			}
2249 		}
2250 		checkAbandon = false;
2251 		listBoxDeleteString(hPrefSetsList, selectedIndex);
2252 		while (selectedIndex >= listBoxGetCount(hPrefSetsList) &&
2253 			selectedIndex > 0)
2254 		{
2255 			--selectedIndex;
2256 		}
2257 		selectedPrefSet = getPrefSet(selectedIndex);
2258 		selectPrefSet(selectedPrefSet, true);
2259 	}
2260 }
2261 
doNewPrefSet(void)2262 void LDViewPreferences::doNewPrefSet(void)
2263 {
2264 	newPrefSetName.clear();
2265 	if (DialogBoxParam(getLanguageModule(), MAKEINTRESOURCE(IDD_NEW_PREF_SET),
2266 		hPropSheet, staticDialogProc, (LPARAM)this) == IDOK)
2267 	{
2268 		if (!newPrefSetName.empty())
2269 		{
2270 			listBoxAddString(hPrefSetsList, newPrefSetName);
2271 			selectPrefSet(newPrefSetName);
2272 		}
2273 	}
2274 }
2275 
getHotKey(int index)2276 ucstring LDViewPreferences::getHotKey(int index)
2277 {
2278 	char key[128];
2279 
2280 	sprintf(key, "%s/Key%d", HOT_KEYS_KEY, index);
2281 	UCSTR hotKeyTemp = TCUserDefaults::stringForKeyUC(key, NULL, false);
2282 	ucstring hotKey = hotKeyTemp;
2283 	delete[] hotKeyTemp;
2284 	return hotKey;
2285 }
2286 
getHotKey(const ucstring & currentPrefSetName)2287 int LDViewPreferences::getHotKey(const ucstring& currentPrefSetName)
2288 {
2289 	int i;
2290 	int retValue = -1;
2291 
2292 	for (i = 0; i < 10 && retValue == -1; i++)
2293 	{
2294 		ucstring prefSetName = getHotKey(i);
2295 
2296 		if (!prefSetName.empty())
2297 		{
2298 			if (currentPrefSetName == prefSetName)
2299 			{
2300 				retValue = i;
2301 			}
2302 		}
2303 	}
2304 	return retValue;
2305 }
2306 
getCurrentHotKey(void)2307 int LDViewPreferences::getCurrentHotKey(void)
2308 {
2309 	ucstring currentPrefSetName = getSelectedPrefSet();
2310 	int retValue = -1;
2311 
2312 	if (!currentPrefSetName.empty())
2313 	{
2314 		retValue = getHotKey(currentPrefSetName);
2315 	}
2316 	return retValue;
2317 }
2318 
performHotKey(int lhotKeyIndex)2319 bool LDViewPreferences::performHotKey(int lhotKeyIndex)
2320 {
2321 	ucstring hotKeyPrefSetName = getHotKey(lhotKeyIndex);
2322 	bool retValue = false;
2323 
2324 	if (!hotKeyPrefSetName.empty() && !hPropSheet)
2325 	{
2326 		const char *currentSessionName = TCUserDefaults::getSessionName();
2327 		bool hotKeyIsDefault = hotKeyPrefSetName == DEFAULT_PREF_SET;
2328 
2329 		if (currentSessionName)
2330 		{
2331 			ucstring ucCurrentSessionName;
2332 			utf8toucstring(ucCurrentSessionName, currentSessionName);
2333 			if (ucCurrentSessionName == hotKeyPrefSetName)
2334 			{
2335 				retValue = true;
2336 			}
2337 		}
2338 		else if (hotKeyIsDefault)
2339 		{
2340 			retValue = true;
2341 		}
2342 		if (!retValue)
2343 		{
2344 			bool changed = false;
2345 
2346 			if (hotKeyIsDefault)
2347 			{
2348 				TCUserDefaults::setSessionName(NULL, PREFERENCE_SET_KEY);
2349 				changed = true;
2350 			}
2351 			else
2352 			{
2353 				TCStringArray *sessionNames =
2354 					TCUserDefaults::getAllSessionNames();
2355 
2356 				std::string utf8Name;
2357 				ucstringtoutf8(utf8Name, hotKeyPrefSetName);
2358 				if (sessionNames->indexOfString(utf8Name.c_str()) != -1)
2359 				{
2360 					TCUserDefaults::setSessionName(utf8Name.c_str(),
2361 						PREFERENCE_SET_KEY);
2362 					{
2363 						changed = true;
2364 					}
2365 				}
2366 				sessionNames->release();
2367 			}
2368 			if (changed)
2369 			{
2370 				loadSettings();
2371 				applySettings();
2372 				retValue = true;
2373 			}
2374 		}
2375 	}
2376 	return retValue;
2377 }
2378 
saveCurrentHotKey(void)2379 void LDViewPreferences::saveCurrentHotKey(void)
2380 {
2381 	int currentHotKey = getCurrentHotKey();
2382 
2383 	if (currentHotKey >= 0)
2384 	{
2385 		char key[128];
2386 
2387 		sprintf(key, "%s/Key%d", HOT_KEYS_KEY, currentHotKey);
2388 		TCUserDefaults::removeValue(key, false);
2389 	}
2390 	if (hotKeyIndex > 0)
2391 	{
2392 		char key[128];
2393 		ucstring currentSessionName = getSelectedPrefSet();
2394 
2395 		sprintf(key, "%s/Key%d", HOT_KEYS_KEY, hotKeyIndex % 10);
2396 		TCUserDefaults::setStringForKey(currentSessionName.c_str(), key, false);
2397 	}
2398 }
2399 
doPrefSetHotKey(void)2400 void LDViewPreferences::doPrefSetHotKey(void)
2401 {
2402 	hotKeyIndex = getCurrentHotKey();
2403 
2404 	if (hotKeyIndex == -1)
2405 	{
2406 		hotKeyIndex++;
2407 	}
2408 	else if (hotKeyIndex == 0)
2409 	{
2410 		hotKeyIndex = 10;
2411 	}
2412 	if (DialogBoxParam(getLanguageModule(), MAKEINTRESOURCE(IDD_HOTKEY),
2413 		hPropSheet, staticDialogProc, (LPARAM)this) == IDOK)
2414 	{
2415 		if (hotKeyIndex != CB_ERR)
2416 		{
2417 			saveCurrentHotKey();
2418 		}
2419 	}
2420 }
2421 
doPrefSetsClick(int controlId,HWND)2422 void LDViewPreferences::doPrefSetsClick(int controlId, HWND /*controlHWnd*/)
2423 {
2424 	switch (controlId)
2425 	{
2426 	case IDC_DELETE_PREF_SET:
2427 		doDeletePrefSet();
2428 		break;
2429 	case IDC_NEW_PREF_SET:
2430 		doNewPrefSet();
2431 		break;
2432 	case IDC_PREF_SET_HOT_KEY:
2433 		doPrefSetHotKey();
2434 		break;
2435 	}
2436 	enableApply(hPrefSetsPage);
2437 }
2438 
doOtherClick(HWND hDlg,int controlId,HWND)2439 void LDViewPreferences::doOtherClick(HWND hDlg, int controlId,
2440 									 HWND /*controlHWnd*/)
2441 {
2442 	if (controlId == IDC_NEW_PREF_SET_CANCEL)
2443 	{
2444 		EndDialog(hDlg, IDCANCEL);
2445 	}
2446 	else if (controlId == IDC_NEW_PREF_SET_OK)
2447 	{
2448 		ucstring editText;
2449 
2450 		CUIDialog::windowGetText(hDlg, IDC_NEW_PREF_SET_FIELD, editText);
2451 		if (!editText.empty())
2452 		{
2453 			int index = listBoxFindStringExact(hPrefSetsList, editText);
2454 
2455 			if (index == LB_ERR)
2456 			{
2457 				if (editText.find('/') < editText.size() || editText.find('\\') < editText.size())
2458 				{
2459 					messageBoxUC(hDlg,
2460 						ls(_UC("PrefSetNameBadChars")),
2461 						ls(_UC("InvalidName")),
2462 						MB_OK | MB_ICONWARNING);
2463 				}
2464 				else
2465 				{
2466 					newPrefSetName = editText;
2467 					EndDialog(hDlg, IDOK);
2468 				}
2469 			}
2470 			else
2471 			{
2472 				messageBoxUC(hDlg,
2473 					ls(_UC("PrefSetAlreadyExists")),
2474 					ls(_UC("DuplicateName")),
2475 					MB_OK | MB_ICONWARNING);
2476 			}
2477 		}
2478 		else
2479 		{
2480 			messageBoxUC(hDlg,
2481 				ls(_UC("PrefSetNameRequired")),
2482 				ls(_UC("EmptyName")), MB_OK | MB_ICONWARNING);
2483 		}
2484 	}
2485 	else if (controlId == IDC_HOTKEY_OK)
2486 	{
2487 		hotKeyIndex = CUIDialog::comboGetCurSel(hDlg, IDC_HOTKEY_COMBO);
2488 		EndDialog(hDlg, IDOK);
2489 	}
2490 	else if (controlId == IDC_APPLY || controlId == IDC_ABANDON ||
2491 		controlId == IDCANCEL)
2492 	{
2493 		EndDialog(hDlg, controlId);
2494 	}
2495 }
2496 
setAniso(int value)2497 void LDViewPreferences::setAniso(int value)
2498 {
2499 	UCCHAR label[128];
2500 	float level = anisoFromSliderValue(value);
2501 	int intLevel = (int)(level + 0.5);
2502 
2503 	ldPrefs->setAnisoLevel(level);
2504 	if (intLevel >= 2)
2505 	{
2506 		sucprintf(label, COUNT_OF(label), ls(_UC("AnisoNx")), intLevel);
2507 	}
2508 	else
2509 	{
2510 		label[0] = 0;
2511 	}
2512 	windowSetText(hAnisoLevelLabel, label);
2513 }
2514 
doPrimitivesClick(int controlId,HWND)2515 void LDViewPreferences::doPrimitivesClick(int controlId, HWND /*controlHWnd*/)
2516 {
2517 	bool bDisableAniso = false;
2518 
2519 	switch (controlId)
2520 	{
2521 		case IDC_PRIMITIVE_SUBSTITUTION:
2522 			doPrimitives();
2523 			break;
2524 		case IDC_TEXTURE_STUDS:
2525 			doTextureStuds();
2526 			break;
2527 		case IDC_TEXMAPS:
2528 			doTexmaps();
2529 			break;
2530 		case IDC_TEXTURE_NEAREST:
2531 			ldPrefs->setTextureFilterType(GL_NEAREST_MIPMAP_NEAREST);
2532 			bDisableAniso = true;
2533 			break;
2534 		case IDC_TEXTURE_BILINEAR:
2535 			ldPrefs->setTextureFilterType(GL_LINEAR_MIPMAP_NEAREST);
2536 			bDisableAniso = true;
2537 			break;
2538 		case IDC_TEXTURE_TRILINEAR:
2539 			ldPrefs->setTextureFilterType(GL_LINEAR_MIPMAP_LINEAR);
2540 			bDisableAniso = true;
2541 			break;
2542 		case IDC_TEXTURE_ANISO:
2543 			{
2544 				ldPrefs->setTextureFilterType(GL_LINEAR_MIPMAP_LINEAR);
2545 				setAniso(trackBarGetPos(hAnisoLevelSlider));
2546 				EnableWindow(hAnisoLevelSlider, TRUE);
2547 			}
2548 			break;
2549 		case IDC_PRIMITIVES_RESET:
2550 			ldPrefs->loadDefaultPrimitivesSettings(false);
2551 			setupPrimitivesPage();
2552 			break;
2553 	}
2554 	if (bDisableAniso)
2555 	{
2556 		setAniso(0);
2557 		EnableWindow(hAnisoLevelSlider, FALSE);
2558 	}
2559 	enableApply(hPrimitivesPage);
2560 }
2561 
doCheckPartTracker(void)2562 void LDViewPreferences::doCheckPartTracker(void)
2563 {
2564 	if (getCheck(hUpdatesPage, IDC_CHECK_PART_TRACKER))
2565 	{
2566 		enableCheckPartTracker();
2567 	}
2568 	else
2569 	{
2570 		disableCheckPartTracker();
2571 	}
2572 }
2573 
doUpdatesClick(int controlId,HWND)2574 void LDViewPreferences::doUpdatesClick(int controlId, HWND /*controlHWnd*/)
2575 {
2576 	ucstring tempString;
2577 	int tempNum;
2578 
2579 	windowGetText(hProxyServer, tempString);
2580 	if (!tempString.empty())
2581 	{
2582 		std::string utf8Temp;
2583 		ucstringtoutf8(utf8Temp, tempString);
2584 		ldPrefs->setProxyServer(utf8Temp.c_str());
2585 	}
2586 	if (windowGetValue(hProxyPort, tempNum))
2587 	{
2588 		ldPrefs->setProxyPort(tempNum);
2589 	}
2590 	switch (controlId)
2591 	{
2592 	case IDC_PROXY_NONE:
2593 		ldPrefs->setProxyType(0);
2594 		disableProxyServer();
2595 		break;
2596 	case IDC_PROXY_WINDOWS:
2597 		ldPrefs->setProxyType(1);
2598 		disableProxyServer();
2599 		break;
2600 	case IDC_PROXY_MANUAL:
2601 		ldPrefs->setProxyType(2);
2602 		enableProxyServer();
2603 		break;
2604 	case IDC_UPDATES_RESET:
2605 		ldPrefs->loadDefaultUpdatesSettings(false);
2606 		setupUpdatesPage();
2607 		break;
2608 	case IDC_RESET_TIMES:
2609 		LDrawModelViewer::resetUnofficialDownloadTimes();
2610 		break;
2611 	case IDC_CHECK_PART_TRACKER:
2612 		doCheckPartTracker();
2613 		break;
2614 	}
2615 	enableApply(hUpdatesPage);
2616 }
2617 
doComboSelChange(HWND hPage,int controlId,HWND)2618 DWORD LDViewPreferences::doComboSelChange(HWND hPage, int controlId,
2619 										  HWND /*controlHWnd*/)
2620 {
2621 	ucstring selectedString;
2622 	switch (controlId)
2623 	{
2624 	case IDC_FSAA_COMBO:
2625 		int fsaaMode;
2626 
2627 		CUIDialog::windowGetText(hPage, controlId, selectedString);
2628 		if (selectedString == ls(_UC("FsaaNone")))
2629 		{
2630 			fsaaMode = 0;
2631 		}
2632 		else
2633 		{
2634 			sucscanf(selectedString.c_str(), _UC("%d"), &fsaaMode);
2635 			if (fsaaMode > 4)
2636 			{
2637 				fsaaMode = fsaaMode << 3;
2638 			}
2639 			else if (selectedString.find(ls(_UC("FsaaEnhanced"))) <
2640 				selectedString.size())
2641 			{
2642 				fsaaMode |= 1;
2643 			}
2644 		}
2645 		ldPrefs->setFsaaMode(fsaaMode);
2646 		enableApply(hPage);
2647 		break;
2648 	case IDC_MEMORY_COMBO:
2649 		enableApply(hPage);
2650 		break;
2651 	case IDC_SNAPSHOTS_DIR_COMBO:
2652 		snapshotDirMode = (LDPreferences::DefaultDirMode)comboGetCurSel(
2653 			hSnapshotDirCombo);
2654 		updateSaveDir(hSnapshotDirField, hSnapshotBrowseButton, snapshotDirMode,
2655 			snapshotDir);
2656 		enableApply(hPage);
2657 		break;
2658 	case IDC_PARTS_LIST_DIR_COMBO:
2659 		partsListDirMode = (LDPreferences::DefaultDirMode)comboGetCurSel(
2660 			hPartsListDirCombo);
2661 		updateSaveDir(hPartsListDirField, hPartsListBrowseButton,
2662 			partsListDirMode, partsListDir);
2663 		enableApply(hPage);
2664 		break;
2665 	case IDC_EXPORT_DIR_COMBO:
2666 		exportDirMode = (LDPreferences::DefaultDirMode)comboGetCurSel(
2667 			hExportDirCombo);
2668 		updateSaveDir(hExportDirField, hExportBrowseButton, exportDirMode,
2669 			exportDir);
2670 		enableApply(hPage);
2671 		break;
2672 	}
2673 	return 0;
2674 }
2675 
doClick(HWND hPage,int controlId,HWND controlHWnd)2676 DWORD LDViewPreferences::doClick(HWND hPage, int controlId, HWND controlHWnd)
2677 {
2678 	bool wasPaused = true;
2679 
2680 	if (modelViewer)
2681 	{
2682 		wasPaused = modelViewer->getPaused() != 0;
2683 		if (!wasPaused)
2684 		{
2685 			modelViewer->pause();
2686 		}
2687 	}
2688 	if (hPage == hGeneralPage)
2689 	{
2690 		doGeneralClick(controlId, controlHWnd);
2691 	}
2692 	else if (hPage == hGeometryPage)
2693 	{
2694 		doGeometryClick(controlId, controlHWnd);
2695 	}
2696 	else if (hPage == hEffectsPage)
2697 	{
2698 		doEffectsClick(controlId, controlHWnd);
2699 	}
2700 	else if (hPage == hPrimitivesPage)
2701 	{
2702 		doPrimitivesClick(controlId, controlHWnd);
2703 	}
2704 	else if (hPage == hUpdatesPage)
2705 	{
2706 		doUpdatesClick(controlId, controlHWnd);
2707 	}
2708 	else if (hPage == hPrefSetsPage)
2709 	{
2710 		doPrefSetsClick(controlId, controlHWnd);
2711 	}
2712 	else
2713 	{
2714 		doOtherClick(hPage, controlId, controlHWnd);
2715 	}
2716 	if (!wasPaused)
2717 	{
2718 		modelViewer->unpause();
2719 	}
2720 	return 0;
2721 }
2722 
doFSRefresh(void)2723 void LDViewPreferences::doFSRefresh(void)
2724 {
2725 	if (getCheck(hGeneralPage, IDC_FS_REFRESH))
2726 	{
2727 		EnableWindow(hFullScreenRateField, TRUE);
2728 	}
2729 	else
2730 	{
2731 		CUIDialog::windowSetText(hGeneralPage, IDC_FS_RATE, _UC(""));
2732 		EnableWindow(hFullScreenRateField, FALSE);
2733 	}
2734 }
2735 
doStipple(void)2736 void LDViewPreferences::doStipple(void)
2737 {
2738 	if (getCheck(hEffectsPage, IDC_STIPPLE))
2739 	{
2740 		setCheck(hEffectsPage, IDC_SORT, false);
2741 	}
2742 }
2743 
doSort(void)2744 void LDViewPreferences::doSort(void)
2745 {
2746 	if (getCheck(hEffectsPage, IDC_SORT))
2747 	{
2748 		setCheck(hEffectsPage, IDC_STIPPLE, false);
2749 	}
2750 }
2751 
doFlatShading(void)2752 void LDViewPreferences::doFlatShading(void)
2753 {
2754 	if (getCheck(hEffectsPage, IDC_FLAT_SHADING))
2755 	{
2756 		setCheck(hEffectsPage, IDC_SMOOTH_CURVES, false);
2757 	}
2758 }
2759 
doSmoothCurves(void)2760 void LDViewPreferences::doSmoothCurves(void)
2761 {
2762 	if (getCheck(hEffectsPage, IDC_SMOOTH_CURVES))
2763 	{
2764 		setCheck(hEffectsPage, IDC_FLAT_SHADING, false);
2765 	}
2766 }
2767 
doHighlights(void)2768 void LDViewPreferences::doHighlights(void)
2769 {
2770 	if (getCachedCheck(hGeometryPage, IDC_HIGHLIGHTS, true))
2771 	{
2772 		enableEdges();
2773 	}
2774 	else
2775 	{
2776 		disableEdges();
2777 	}
2778 }
2779 
doConditionals(void)2780 void LDViewPreferences::doConditionals(void)
2781 {
2782 	if (getCheck(hGeometryPage, IDC_CONDITIONAL_HIGHLIGHTS))
2783 	{
2784 		enableConditionals();
2785 	}
2786 	else
2787 	{
2788 		disableConditionals();
2789 	}
2790 }
2791 
setCheck(HWND hPage,int buttonId,bool value)2792 void LDViewPreferences::setCheck(HWND hPage, int buttonId, bool value)
2793 {
2794 	CUIDialog::buttonSetChecked(hPage, buttonId, value);
2795 }
2796 
getCheck(HWND hPage,int buttonId)2797 bool LDViewPreferences::getCheck(HWND hPage, int buttonId)
2798 {
2799 	return CUIDialog::buttonIsChecked(hPage, buttonId);
2800 }
2801 
getCachedCheck(HWND hPage,int buttonId,bool action)2802 bool LDViewPreferences::getCachedCheck(HWND hPage, int buttonId, bool action)
2803 {
2804 	if (hButtonTheme)
2805 	{
2806 		HWND hButton = GetDlgItem(hPage, buttonId);
2807 
2808 		if (action)
2809 		{
2810 			checkStates[hButton] = !checkStates[hButton];
2811 		}
2812 		return checkStates[hButton];
2813 	}
2814 	else
2815 	{
2816 		return getCheck(hPage, buttonId);
2817 	}
2818 }
2819 
doWireframe(void)2820 void LDViewPreferences::doWireframe(void)
2821 {
2822 	if (getCachedCheck(hGeometryPage, IDC_WIREFRAME, true))
2823 	{
2824 		enableWireframe();
2825 	}
2826 	else
2827 	{
2828 		disableWireframe();
2829 	}
2830 }
2831 
doBfc(void)2832 void LDViewPreferences::doBfc(void)
2833 {
2834 	if (getCachedCheck(hGeometryPage, IDC_BFC, true))
2835 	{
2836 		enableBfc();
2837 	}
2838 	else
2839 	{
2840 		disableBfc();
2841 	}
2842 }
2843 
doLighting(void)2844 void LDViewPreferences::doLighting(void)
2845 {
2846 	if (getCachedCheck(hEffectsPage, IDC_LIGHTING, true))
2847 	{
2848 		enableLighting();
2849 	}
2850 	else
2851 	{
2852 		disableLighting();
2853 	}
2854 }
2855 
doDrawLightDats(void)2856 void LDViewPreferences::doDrawLightDats(void)
2857 {
2858 	BOOL enabled = FALSE;
2859 	BOOL checked = FALSE;
2860 
2861 	if (getCachedCheck(hEffectsPage, IDC_DRAW_LIGHT_DATS, true))
2862 	{
2863 		enabled = TRUE;
2864 		checked = ldPrefs->getOptionalStandardLight() ? TRUE : FALSE;
2865 	}
2866 	EnableWindow(hLightOptionalStandardButton, enabled);
2867 	buttonSetCheck(hLightOptionalStandardButton, checked);
2868 }
2869 
doStereo(void)2870 void LDViewPreferences::doStereo(void)
2871 {
2872 	if (getCachedCheck(hEffectsPage, IDC_STEREO, true))
2873 	{
2874 		ldPrefs->setStereoMode(LDVStereoCrossEyed);
2875 		enableStereo();
2876 	}
2877 	else
2878 	{
2879 		ldPrefs->setStereoMode(LDVStereoNone);
2880 		disableStereo();
2881 	}
2882 }
2883 
doCutaway(void)2884 void LDViewPreferences::doCutaway(void)
2885 {
2886 	if (getCachedCheck(hEffectsPage, IDC_CUTAWAY, true))
2887 	{
2888 		ldPrefs->setCutawayMode(LDVCutawayWireframe);
2889 		enableCutaway();
2890 	}
2891 	else
2892 	{
2893 		ldPrefs->setCutawayMode(LDVCutawayNormal);
2894 		disableCutaway();
2895 	}
2896 }
2897 
doSeams(void)2898 void LDViewPreferences::doSeams(void)
2899 {
2900 	if (getCheck(hGeometryPage, IDC_SEAMS))
2901 	{
2902 		enableSeams();
2903 	}
2904 	else
2905 	{
2906 		disableSeams();
2907 	}
2908 }
2909 
doPrimitives(void)2910 void LDViewPreferences::doPrimitives(void)
2911 {
2912 	if (getCachedCheck(hPrimitivesPage, IDC_PRIMITIVE_SUBSTITUTION, true))
2913 	{
2914 		enablePrimitives();
2915 	}
2916 	else
2917 	{
2918 		disablePrimitives();
2919 	}
2920 }
2921 
updateTextureFilteringEnabled(void)2922 void LDViewPreferences::updateTextureFilteringEnabled(void)
2923 {
2924 	if (getCheck(hPrimitivesPage, IDC_TEXMAPS) ||
2925 		(getCachedCheck(hPrimitivesPage, IDC_PRIMITIVE_SUBSTITUTION, false) &&
2926 		getCheck(hPrimitivesPage, IDC_TEXTURE_STUDS)))
2927 	{
2928 		enableTextureFiltering();
2929 	}
2930 	else
2931 	{
2932 		disableTextureFiltering();
2933 	}
2934 }
2935 
updateTexmapsEnabled(void)2936 void LDViewPreferences::updateTexmapsEnabled(void)
2937 {
2938 	if (getCheck(hPrimitivesPage, IDC_TEXMAPS))
2939 	{
2940 		enableTexmaps();
2941 	}
2942 	else
2943 	{
2944 		disableTexmaps();
2945 	}
2946 }
2947 
doTextureStuds(void)2948 void LDViewPreferences::doTextureStuds(void)
2949 {
2950 	updateTextureFilteringEnabled();
2951 }
2952 
doTexmaps(void)2953 void LDViewPreferences::doTexmaps(void)
2954 {
2955 	updateTextureFilteringEnabled();
2956 	updateTexmapsEnabled();
2957 }
2958 
doReset(void)2959 void LDViewPreferences::doReset(void)
2960 {
2961 	loadSettings();
2962 }
2963 
doDialogVScroll(HWND hDlg,int scrollCode,int position,HWND hScrollBar)2964 BOOL LDViewPreferences::doDialogVScroll(HWND hDlg, int scrollCode, int position,
2965 										HWND hScrollBar)
2966 {
2967 	if (scrollCode == SB_THUMBPOSITION && hScrollBar == hSeamSpin)
2968 	{
2969 		UCCHAR seamWidthString[128];
2970 		int seamWidth = ldPrefs->getSeamWidth();
2971 
2972 		seamWidth += (position - seamWidth);
2973 		ldPrefs->setSeamWidth(seamWidth);
2974 		sucprintf(seamWidthString, COUNT_OF(seamWidthString), _UC("%0.2f"),
2975 			seamWidth / 100.0f);
2976 		CUIDialog::windowSetText(hDlg, IDC_SEAM_WIDTH_FIELD, seamWidthString);
2977 		SendDlgItemMessage(hDlg, IDC_SEAM_SPIN, UDM_SETPOS, 0, seamWidth);
2978 		setCheck(hGeometryPage, IDC_SEAMS, seamWidth != 0);
2979 		enableApply(hGeometryPage);
2980 	}
2981 	return TRUE;
2982 }
2983 
setupPage(int pageNumber)2984 void LDViewPreferences::setupPage(int pageNumber)
2985 {
2986 	if (pageNumber == generalPageNumber)
2987 	{
2988 		setupGeneralPage();
2989 	}
2990 	else if (pageNumber == geometryPageNumber)
2991 	{
2992 		setupGeometryPage();
2993 	}
2994 	else if (pageNumber == effectsPageNumber)
2995 	{
2996 		setupEffectsPage();
2997 	}
2998 	else if (pageNumber == primitivesPageNumber)
2999 	{
3000 		setupPrimitivesPage();
3001 	}
3002 	else if (pageNumber == updatesPageNumber)
3003 	{
3004 		setupUpdatesPage();
3005 	}
3006 	else if (pageNumber == prefSetsPageNumber)
3007 	{
3008 		setupPrefSetsPage();
3009 	}
3010 	disableApply(hwndArray->pointerAtIndex(pageNumber));
3011 }
3012 
setupFov(bool warn)3013 void LDViewPreferences::setupFov(bool warn)
3014 {
3015 	UCCHAR buf[1024];
3016 	TCFloat minFov = getMinFov();
3017 	TCFloat maxFov = getMaxFov();
3018 
3019 	SendDlgItemMessage(hGeneralPage, IDC_FOV, EM_SETLIMITTEXT, 5, 0);
3020 	sucprintf(buf, COUNT_OF(buf), _UC("%.4g"), ldPrefs->getFov());
3021 	CUIDialog::windowSetText(hGeneralPage, IDC_FOV, buf);
3022 	sucprintf(buf, COUNT_OF(buf), _UC("(%g - %g)"), minFov, maxFov);
3023 	CUIDialog::windowSetText(hGeneralPage, IDC_FOV_RANGE_LABEL, buf);
3024 	if (warn)
3025 	{
3026 		sucprintf(buf, COUNT_OF(buf), ls(_UC("FovRangeError")), minFov, maxFov);
3027 		messageBoxUC(hPropSheet, buf, ls(_UC("InvalidValue")),
3028 			MB_OK | MB_ICONWARNING);
3029 	}
3030 }
3031 
setupMemoryUsage(void)3032 void LDViewPreferences::setupMemoryUsage(void)
3033 {
3034 	CUIDialog::comboResetContent(hGeneralPage, IDC_MEMORY_COMBO);
3035 	CUIDialog::comboAddString(hGeneralPage, IDC_MEMORY_COMBO, ls(_UC("Low")));
3036 	CUIDialog::comboAddString(hGeneralPage, IDC_MEMORY_COMBO, ls(_UC("Medium")));
3037 	CUIDialog::comboAddString(hGeneralPage, IDC_MEMORY_COMBO, ls(_UC("High")));
3038 	CUIDialog::comboSetCurSel(hGeneralPage, IDC_MEMORY_COMBO, ldPrefs->getMemoryUsage());
3039 }
3040 
updateSaveDir(HWND hTextField,HWND hBrowseButton,LDPreferences::DefaultDirMode dirMode,const ucstring & filename)3041 void LDViewPreferences::updateSaveDir(
3042 	HWND hTextField,
3043 	HWND hBrowseButton,
3044 	LDPreferences::DefaultDirMode dirMode,
3045 	const ucstring &filename)
3046 {
3047 	BOOL enable = FALSE;
3048 
3049 	if (dirMode == LDPreferences::DDMSpecificDir)
3050 	{
3051 		SetWindowText(hTextField, filename.c_str());
3052 		enable = TRUE;
3053 	}
3054 	else
3055 	{
3056 		SetWindowText(hTextField, _UC(""));
3057 	}
3058 	EnableWindow(hTextField, enable);
3059 	EnableWindow(hBrowseButton, enable);
3060 }
3061 
setupSaveDir(HWND hComboBox,HWND hTextField,HWND hBrowseButton,LDPreferences::DefaultDirMode dirMode,const ucstring & filename,CUCSTR nameKey)3062 void LDViewPreferences::setupSaveDir(
3063 	HWND hComboBox,
3064 	HWND hTextField,
3065 	HWND hBrowseButton,
3066 	LDPreferences::DefaultDirMode dirMode,
3067 	const ucstring &filename,
3068 	CUCSTR nameKey)
3069 {
3070 	ucstring lastSaved = ls(_UC("LastSaved"));
3071 
3072 	lastSaved += ls(nameKey);
3073 	comboResetContent(hComboBox);
3074 	comboAddString(hComboBox, ls(_UC("Model")));
3075 	comboAddString(hComboBox, lastSaved.c_str());
3076 	comboAddString(hComboBox, ls(_UC("Specified")));
3077 	comboSetCurSel(hComboBox, dirMode);
3078 	updateSaveDir(hTextField, hBrowseButton, dirMode, filename);
3079 }
3080 
setupSaveDirs(void)3081 void LDViewPreferences::setupSaveDirs(void)
3082 {
3083 	hSnapshotDirCombo = GetDlgItem(hGeneralPage, IDC_SNAPSHOTS_DIR_COMBO);
3084 	hSnapshotDirField = GetDlgItem(hGeneralPage, IDC_SNAPSHOTS_DIR);
3085 	hSnapshotBrowseButton = GetDlgItem(hGeneralPage, IDC_BROWSE_SNAPSHOTS_DIR);
3086 	snapshotDirMode = ldPrefs->getSaveDirMode(LDPreferences::SOSnapshot);
3087 	utf8toucstring(snapshotDir,
3088 		ldPrefs->getSaveDir(LDPreferences::SOSnapshot));
3089 	setupSaveDir(hSnapshotDirCombo, hSnapshotDirField, hSnapshotBrowseButton,
3090 		snapshotDirMode, snapshotDir, _UC("Snapshot"));
3091 
3092 	hPartsListDirCombo = GetDlgItem(hGeneralPage, IDC_PARTS_LIST_DIR_COMBO);
3093 	hPartsListDirField = GetDlgItem(hGeneralPage, IDC_PARTS_LIST_DIR);
3094 	hPartsListBrowseButton = GetDlgItem(hGeneralPage,
3095 		IDC_BROWSE_PARTS_LIST_DIR);
3096 	partsListDirMode = ldPrefs->getSaveDirMode(LDPreferences::SOPartsList);
3097 	utf8toucstring(partsListDir,
3098 		ldPrefs->getSaveDir(LDPreferences::SOPartsList));
3099 	setupSaveDir(hPartsListDirCombo, hPartsListDirField, hPartsListBrowseButton,
3100 		partsListDirMode, partsListDir, _UC("PartsList"));
3101 
3102 	hExportDirCombo = GetDlgItem(hGeneralPage, IDC_EXPORT_DIR_COMBO);
3103 	hExportDirField = GetDlgItem(hGeneralPage, IDC_EXPORT_DIR);
3104 	hExportBrowseButton = GetDlgItem(hGeneralPage, IDC_BROWSE_EXPORT_DIR);
3105 	exportDirMode = ldPrefs->getSaveDirMode(LDPreferences::SOExport);
3106 	utf8toucstring(exportDir,
3107 		ldPrefs->getSaveDir(LDPreferences::SOExport));
3108 	setupSaveDir(hExportDirCombo, hExportDirField, hExportBrowseButton,
3109 		exportDirMode, exportDir, _UC("Export"));
3110 }
3111 
setupGeneralPage(void)3112 void LDViewPreferences::setupGeneralPage(void)
3113 {
3114 	hGeneralPage = hwndArray->pointerAtIndex(generalPageNumber);
3115 	setupAntialiasing();
3116 	setCheck(hGeneralPage, IDC_TRANS_DEFAULT_COLOR,
3117 		ldPrefs->getTransDefaultColor());
3118 	setCheck(hGeneralPage, IDC_PROCESS_LDCONFIG,
3119 		ldPrefs->getProcessLdConfig());
3120 	setCheck(hGeneralPage, IDC_RANDOM_COLORS, ldPrefs->getRandomColors());
3121 	setCheck(hGeneralPage, IDC_FRAME_RATE, ldPrefs->getShowFps());
3122 	setCheck(hGeneralPage, IDC_SHOW_AXES, ldPrefs->getShowAxes());
3123 	setCheck(hGeneralPage, IDC_SHOW_ERRORS, ldPrefs->getShowErrors());
3124 	setupFov();
3125 	setupFullScreenRefresh();
3126 	setupBackgroundColorButton();
3127 	setupDefaultColorButton();
3128 	setupMemoryUsage();
3129 	setupSaveDirs();
3130 }
3131 
enableWireframe(BOOL enable)3132 void LDViewPreferences::enableWireframe(BOOL enable /*= TRUE*/)
3133 {
3134 	EnableWindow(hWireframeFogButton, enable);
3135 	EnableWindow(hRemoveHiddenLinesButton, enable);
3136 	EnableWindow(hWireframeThicknessLabel, enable);
3137 	EnableWindow(hWireframeThicknessSlider, enable);
3138 }
3139 
disableWireframe(void)3140 void LDViewPreferences::disableWireframe(void)
3141 {
3142 	enableWireframe(FALSE);
3143 }
3144 
enableBfc(BOOL enable)3145 void LDViewPreferences::enableBfc(BOOL enable /*= TRUE*/)
3146 {
3147 	EnableWindow(hRedBackFacesButton, enable);
3148 	EnableWindow(hGreenFrontFacesButton, enable);
3149 	EnableWindow(hBlueNeutralFacesButton, enable);
3150 }
3151 
disableBfc(void)3152 void LDViewPreferences::disableBfc(void)
3153 {
3154 	enableBfc(FALSE);
3155 }
3156 
initThemesButton(HWND hButton)3157 void LDViewPreferences::initThemesButton(HWND hButton)
3158 {
3159 	if (CUIThemes::isThemeLibLoaded() && !hButtonTheme)
3160 	{
3161 		hButtonTheme = CUIThemes::openThemeData(hButton, L"Button");
3162 	}
3163 }
3164 
3165 /*
3166 void LDViewPreferences::initThemesTab(HWND hStatic)
3167 {
3168 	if (CUIThemes::isThemeLibLoaded() && !hTabTheme)
3169 	{
3170 		hTabTheme = CUIThemes::openThemeData(hStatic, L"Tab");
3171 	}
3172 }
3173 */
3174 
setupGroupCheckButton(HWND hPage,int buttonId,bool state)3175 void LDViewPreferences::setupGroupCheckButton(HWND hPage, int buttonId,
3176 											  bool state)
3177 {
3178 	bool done = false;
3179 	HWND hButton = GetDlgItem(hPage, buttonId);
3180 	checkStates[hButton] = state;
3181 	if (CUIThemes::isThemeLibLoaded() && !haveWindowsVistaOrLater())
3182 	{
3183 		// This is really only useful in Windows XP, since all it does
3184 		// is make the button text color match XP's group box text color.
3185 		// Later versions of Windows don't use a special group box text
3186 		// color. And in Windows 10, for some reason the check box comes
3187 		// out too big on a screen set to 96DPI.
3188 
3189 		if (hButton)
3190 		{
3191 			initThemesButton(hButton);
3192 			if (hButtonTheme)
3193 			{
3194 				DWORD dwStyle = GetWindowLong(hButton, GWL_STYLE);
3195 
3196 				if ((dwStyle & BS_TYPEMASK) != BS_OWNERDRAW)
3197 				{
3198 					dwStyle = (dwStyle & ~BS_TYPEMASK) | BS_OWNERDRAW;
3199 					buttonSetStyle(hButton, dwStyle);
3200 				}
3201 				if (GetWindowLongPtr(hButton, GWLP_WNDPROC) !=
3202 					(LONG_PTR)staticGroupCheckButtonProc)
3203 				{
3204 					SetWindowLongPtr(hButton, GWLP_USERDATA, (LONG_PTR)this);
3205 					if (origButtonWindowProc)
3206 					{
3207 						SetWindowLongPtr(hButton, GWLP_WNDPROC,
3208 							(LONG_PTR)staticGroupCheckButtonProc);
3209 					}
3210 					else
3211 					{
3212 						origButtonWindowProc = SetWindowLongPtr(hButton,
3213 							GWLP_WNDPROC, (LONG_PTR)staticGroupCheckButtonProc);
3214 					}
3215 				}
3216 				fixControlSize(hButton);
3217 				InvalidateRect(hButton, NULL, TRUE);
3218 				done = true;
3219 			}
3220 			else if (origButtonWindowProc)
3221 			{
3222 				SetWindowLongPtr(hButton, GWLP_WNDPROC,
3223 					(LONG_PTR)origButtonWindowProc);
3224 			}
3225 		}
3226 	}
3227 	if (!done)
3228 	{
3229 		setCheck(hPage, buttonId, state);
3230 	}
3231 }
3232 
setupWireframe(void)3233 void LDViewPreferences::setupWireframe(void)
3234 {
3235 	setupGroupCheckButton(hGeometryPage, IDC_WIREFRAME,
3236 		ldPrefs->getDrawWireframe());
3237 	hWireframeFogButton = GetDlgItem(hGeometryPage, IDC_WIREFRAME_FOG);
3238 	hRemoveHiddenLinesButton = GetDlgItem(hGeometryPage,
3239 		IDC_REMOVE_HIDDEN_LINES);
3240 	hWireframeThicknessLabel = GetDlgItem(hGeometryPage,
3241 		IDC_WIREFRAME_THICKNESS_LABEL);
3242 	hWireframeThicknessSlider = GetDlgItem(hGeometryPage,
3243 		IDC_WIREFRAME_THICKNESS);
3244 	setCheck(hGeometryPage, IDC_WIREFRAME_FOG, ldPrefs->getUseWireframeFog());
3245 	setCheck(hGeometryPage, IDC_REMOVE_HIDDEN_LINES,
3246 		ldPrefs->getRemoveHiddenLines());
3247 	CUIDialog::trackBarSetup(hGeometryPage, IDC_WIREFRAME_THICKNESS, 0, 5, 1,
3248 		ldPrefs->getWireframeThickness());
3249 	if (ldPrefs->getDrawWireframe())
3250 	{
3251 		enableWireframe();
3252 	}
3253 	else
3254 	{
3255 		disableWireframe();
3256 	}
3257 }
3258 
setupBfc(void)3259 void LDViewPreferences::setupBfc(void)
3260 {
3261 	setupGroupCheckButton(hGeometryPage, IDC_BFC, ldPrefs->getBfc());
3262 	hRedBackFacesButton = GetDlgItem(hGeometryPage, IDC_RED_BACK_FACES);
3263 	hGreenFrontFacesButton = GetDlgItem(hGeometryPage, IDC_GREEN_FRONT_FACES);
3264 	hBlueNeutralFacesButton = GetDlgItem(hGeometryPage, IDC_BLUE_NEUTRAL_FACES);
3265 	setCheck(hGeometryPage, IDC_RED_BACK_FACES, ldPrefs->getRedBackFaces());
3266 	setCheck(hGeometryPage, IDC_GREEN_FRONT_FACES,
3267 		ldPrefs->getGreenFrontFaces());
3268 	setCheck(hGeometryPage, IDC_BLUE_NEUTRAL_FACES,
3269 		ldPrefs->getBlueNeutralFaces());
3270 	if (ldPrefs->getBfc())
3271 	{
3272 		enableBfc();
3273 	}
3274 	else
3275 	{
3276 		disableBfc();
3277 	}
3278 }
3279 
enableConditionals(void)3280 void LDViewPreferences::enableConditionals(void)
3281 {
3282 	EnableWindow(hShowAllConditionalButton, TRUE);
3283 	EnableWindow(hShowConditionalControlsButton, TRUE);
3284 	setCheck(hGeometryPage, IDC_ALL_CONDITIONAL,
3285 		ldPrefs->getShowAllConditionalLines());
3286 	setCheck(hGeometryPage, IDC_CONDITIONAL_CONTROLS,
3287 		ldPrefs->getShowConditionalControlPoints());
3288 }
3289 
disableConditionals(void)3290 void LDViewPreferences::disableConditionals(void)
3291 {
3292 	EnableWindow(hShowAllConditionalButton, FALSE);
3293 	EnableWindow(hShowConditionalControlsButton, FALSE);
3294 	setCheck(hGeometryPage, IDC_ALL_CONDITIONAL, false);
3295 	setCheck(hGeometryPage, IDC_CONDITIONAL_CONTROLS, false);
3296 }
3297 
enableEdges(void)3298 void LDViewPreferences::enableEdges(void)
3299 {
3300 	EnableWindow(hConditionalHighlightsButton, TRUE);
3301 	EnableWindow(hEdgesOnlyButton, TRUE);
3302 	EnableWindow(hQualityLinesButton, TRUE);
3303 	EnableWindow(hAlwaysBlackButton, TRUE);
3304 	EnableWindow(hEdgeThicknessLabel, TRUE);
3305 	EnableWindow(hEdgeThicknessSlider, TRUE);
3306 	if (ldPrefs->getDrawConditionalHighlights())
3307 	{
3308 		enableConditionals();
3309 	}
3310 	else
3311 	{
3312 		disableConditionals();
3313 	}
3314 	setCheck(hGeometryPage, IDC_EDGES_ONLY, ldPrefs->getEdgesOnly());
3315 	setCheck(hGeometryPage, IDC_CONDITIONAL_HIGHLIGHTS,
3316 		ldPrefs->getDrawConditionalHighlights());
3317 	setCheck(hGeometryPage, IDC_QUALITY_LINES, ldPrefs->getUsePolygonOffset());
3318 	setCheck(hGeometryPage, IDC_ALWAYS_BLACK, ldPrefs->getBlackHighlights());
3319 }
3320 
disableEdges(void)3321 void LDViewPreferences::disableEdges(void)
3322 {
3323 	EnableWindow(hConditionalHighlightsButton, FALSE);
3324 	EnableWindow(hEdgesOnlyButton, FALSE);
3325 	EnableWindow(hQualityLinesButton, FALSE);
3326 	EnableWindow(hAlwaysBlackButton, FALSE);
3327 	EnableWindow(hEdgeThicknessLabel, FALSE);
3328 	EnableWindow(hEdgeThicknessSlider, FALSE);
3329 	disableConditionals();
3330 	setCheck(hGeometryPage, IDC_EDGES_ONLY, false);
3331 	setCheck(hGeometryPage, IDC_CONDITIONAL_HIGHLIGHTS, false);
3332 	setCheck(hGeometryPage, IDC_QUALITY_LINES, false);
3333 	setCheck(hGeometryPage, IDC_ALWAYS_BLACK, false);
3334 }
3335 
setupEdgeLines(void)3336 void LDViewPreferences::setupEdgeLines(void)
3337 {
3338 	setupGroupCheckButton(hGeometryPage, IDC_HIGHLIGHTS,
3339 		ldPrefs->getShowHighlightLines());
3340 	hConditionalHighlightsButton = GetDlgItem(hGeometryPage,
3341 		IDC_CONDITIONAL_HIGHLIGHTS);
3342 	hShowAllConditionalButton = GetDlgItem(hGeometryPage, IDC_ALL_CONDITIONAL);
3343 	hShowConditionalControlsButton = GetDlgItem(hGeometryPage,
3344 		IDC_CONDITIONAL_CONTROLS);
3345 	hEdgesOnlyButton = GetDlgItem(hGeometryPage, IDC_EDGES_ONLY);
3346 	hQualityLinesButton = GetDlgItem(hGeometryPage, IDC_QUALITY_LINES);
3347 	hAlwaysBlackButton = GetDlgItem(hGeometryPage, IDC_ALWAYS_BLACK);
3348 	hEdgeThicknessLabel = GetDlgItem(hGeometryPage, IDC_EDGE_THICKNESS_LABEL);
3349 	hEdgeThicknessSlider = GetDlgItem(hGeometryPage, IDC_EDGE_THICKNESS);
3350 	CUIDialog::trackBarSetup(hGeometryPage, IDC_EDGE_THICKNESS, 0, 5, 1,
3351 		ldPrefs->getEdgeThickness());
3352 	if (ldPrefs->getShowHighlightLines())
3353 	{
3354 		enableEdges();
3355 	}
3356 	else
3357 	{
3358 		disableEdges();
3359 	}
3360 }
3361 
setupGeometryPage(void)3362 void LDViewPreferences::setupGeometryPage(void)
3363 {
3364 	hGeometryPage = hwndArray->pointerAtIndex(geometryPageNumber);
3365 	setCheck(hGeometryPage, IDC_PART_BOUNDING_BOXES,
3366 		ldPrefs->getBoundingBoxesOnly());
3367 	setupSeamWidth();
3368 	setupWireframe();
3369 	setupBfc();
3370 	setupEdgeLines();
3371 }
3372 
setupOpacitySlider(void)3373 void LDViewPreferences::setupOpacitySlider(void)
3374 {
3375 	if (ldPrefs->getCutawayMode() == LDVCutawayWireframe &&
3376 		!LDVExtensionsSetup::haveAlpha())
3377 	{
3378 		ldPrefs->setCutawayAlpha(100);
3379 		EnableWindow(hCutawayOpacitySlider, FALSE);
3380 		EnableWindow(hCutawayOpacityLabel, FALSE);
3381 		CUIDialog::trackBarSetPos(hEffectsPage, IDC_CUTAWAY_OPACITY, 100);
3382 	}
3383 	else
3384 	{
3385 		EnableWindow(hCutawayOpacitySlider, TRUE);
3386 		EnableWindow(hCutawayOpacityLabel, TRUE);
3387 	}
3388 }
3389 
enableCutaway(void)3390 void LDViewPreferences::enableCutaway(void)
3391 {
3392 	int activeCutaway = 0;
3393 
3394 	EnableWindow(hCutawayColorButton, TRUE);
3395 	if (LDVExtensionsSetup::haveStencil())
3396 	{
3397 		EnableWindow(hCutawayMonochromButton, TRUE);
3398 	}
3399 	else
3400 	{
3401 		if (ldPrefs->getCutawayMode() == LDVCutawayStencil)
3402 		{
3403 			ldPrefs->setCutawayMode(LDVCutawayWireframe);
3404 		}
3405 		EnableWindow(hCutawayMonochromButton, FALSE);
3406 	}
3407 	setupOpacitySlider();
3408 	EnableWindow(hCutawayThicknessSlider, TRUE);
3409 	EnableWindow(hCutawayThicknessLabel, TRUE);
3410 	setCheck(hEffectsPage, IDC_CUTAWAY_COLOR, false);
3411 	setCheck(hEffectsPage, IDC_CUTAWAY_MONOCHROME, false);
3412 	switch (ldPrefs->getCutawayMode())
3413 	{
3414 	case LDVCutawayWireframe:
3415 		activeCutaway = IDC_CUTAWAY_COLOR;
3416 		break;
3417 	case LDVCutawayStencil:
3418 		activeCutaway = IDC_CUTAWAY_MONOCHROME;
3419 		break;
3420 	}
3421 	setCheck(hEffectsPage, activeCutaway, true);
3422 }
3423 
disableCutaway(void)3424 void LDViewPreferences::disableCutaway(void)
3425 {
3426 	EnableWindow(hCutawayColorButton, FALSE);
3427 	EnableWindow(hCutawayMonochromButton, FALSE);
3428 	EnableWindow(hCutawayOpacityLabel, FALSE);
3429 	EnableWindow(hCutawayOpacitySlider, FALSE);
3430 	EnableWindow(hCutawayThicknessLabel, FALSE);
3431 	EnableWindow(hCutawayThicknessSlider, FALSE);
3432 	setCheck(hEffectsPage, IDC_CUTAWAY_COLOR, false);
3433 	setCheck(hEffectsPage, IDC_CUTAWAY_MONOCHROME, false);
3434 }
3435 
setupCutaway(void)3436 void LDViewPreferences::setupCutaway(void)
3437 {
3438 	setupGroupCheckButton(hEffectsPage, IDC_CUTAWAY,
3439 		ldPrefs->getCutawayMode() != LDVCutawayNormal);
3440 	hCutawayColorButton = GetDlgItem(hEffectsPage, IDC_CUTAWAY_COLOR);
3441 	hCutawayMonochromButton = GetDlgItem(hEffectsPage, IDC_CUTAWAY_MONOCHROME);
3442 	hCutawayOpacityLabel = GetDlgItem(hEffectsPage, IDC_CUTAWAY_OPACITY_LABEL);
3443 	hCutawayOpacitySlider = GetDlgItem(hEffectsPage, IDC_CUTAWAY_OPACITY);
3444 	hCutawayThicknessLabel = GetDlgItem(hEffectsPage,
3445 		IDC_CUTAWAY_THICKNESS_LABEL);
3446 	hCutawayThicknessSlider = GetDlgItem(hEffectsPage, IDC_CUTAWAY_THICKNESS);
3447 	CUIDialog::trackBarSetup(hEffectsPage, IDC_CUTAWAY_OPACITY, 1, 100, 10,
3448 		ldPrefs->getCutawayAlpha());
3449 	CUIDialog::trackBarSetup(hEffectsPage, IDC_CUTAWAY_THICKNESS, 0, 5, 1,
3450 		ldPrefs->getCutawayThickness());
3451 	if (ldPrefs->getCutawayMode() == LDVCutawayNormal)
3452 	{
3453 		disableCutaway();
3454 	}
3455 	else
3456 	{
3457 		enableCutaway();
3458 	}
3459 }
3460 
enableStereo(void)3461 void LDViewPreferences::enableStereo(void)
3462 {
3463 	int activeStereo = 0;
3464 
3465 	EnableWindow(hHardwareStereoButton, TRUE);
3466 	EnableWindow(hCrossEyedStereoButton, TRUE);
3467 	EnableWindow(hParallelStereoButton, TRUE);
3468 	EnableWindow(hStereoSpacingSlider, TRUE);
3469 	EnableWindow(hStereoSpacingLabel, TRUE);
3470 	setCheck(hEffectsPage, IDC_HARDWARE_STEREO, false);
3471 	setCheck(hEffectsPage, IDC_CROSS_EYED_STEREO, false);
3472 	setCheck(hEffectsPage, IDC_PARALLEL_STEREO, false);
3473 	switch (ldPrefs->getStereoMode())
3474 	{
3475 	case LDVStereoHardware:
3476 		activeStereo = IDC_HARDWARE_STEREO;
3477 		break;
3478 	case LDVStereoCrossEyed:
3479 		activeStereo = IDC_CROSS_EYED_STEREO;
3480 		break;
3481 	case LDVStereoParallel:
3482 		activeStereo = IDC_PARALLEL_STEREO;
3483 		break;
3484 	}
3485 	setCheck(hEffectsPage, activeStereo, true);
3486 }
3487 
disableStereo(void)3488 void LDViewPreferences::disableStereo(void)
3489 {
3490 	EnableWindow(hHardwareStereoButton, FALSE);
3491 	EnableWindow(hCrossEyedStereoButton, FALSE);
3492 	EnableWindow(hParallelStereoButton, FALSE);
3493 	EnableWindow(hStereoSpacingSlider, FALSE);
3494 	EnableWindow(hStereoSpacingLabel, FALSE);
3495 	setCheck(hEffectsPage, IDC_HARDWARE_STEREO, false);
3496 	setCheck(hEffectsPage, IDC_CROSS_EYED_STEREO, false);
3497 	setCheck(hEffectsPage, IDC_PARALLEL_STEREO, false);
3498 }
3499 
setupStereo(void)3500 void LDViewPreferences::setupStereo(void)
3501 {
3502 	setupGroupCheckButton(hEffectsPage, IDC_STEREO,
3503 		ldPrefs->getStereoMode() != LDVStereoNone);
3504 	hHardwareStereoButton = GetDlgItem(hEffectsPage, IDC_HARDWARE_STEREO);
3505 	hCrossEyedStereoButton = GetDlgItem(hEffectsPage, IDC_CROSS_EYED_STEREO);
3506 	hParallelStereoButton = GetDlgItem(hEffectsPage, IDC_PARALLEL_STEREO);
3507 	hStereoSpacingSlider = GetDlgItem(hEffectsPage, IDC_STEREO_SPACING);
3508 	hStereoSpacingLabel = GetDlgItem(hEffectsPage, IDC_STEREO_SPACING_LABEL);
3509 	CUIDialog::trackBarSetup(hEffectsPage, IDC_STEREO_SPACING, 0, 100, 10,
3510 		ldPrefs->getStereoEyeSpacing());
3511 	if (ldPrefs->getStereoMode() == LDVStereoNone)
3512 	{
3513 		disableStereo();
3514 	}
3515 	else
3516 	{
3517 		enableStereo();
3518 	}
3519 }
3520 
uncheckLightDirections(void)3521 void LDViewPreferences::uncheckLightDirections(void)
3522 {
3523 	for (IntIntMap::const_iterator it = lightDirIndexToId.begin()
3524 		; it != lightDirIndexToId.end(); it++)
3525 	{
3526 		checkStates[GetDlgItem(hEffectsPage, it->second)] = false;
3527 		if (!CUIThemes::isThemeLibLoaded())
3528 		{
3529 			setCheck(hEffectsPage, it->second, false);
3530 		}
3531 	}
3532 }
3533 
enableLighting(void)3534 void LDViewPreferences::enableLighting(void)
3535 {
3536 	int lightDirButton = -1;
3537 	BOOL enabled = TRUE;
3538 
3539 	EnableWindow(hLightQualityButton, TRUE);
3540 	EnableWindow(hLightSubduedButton, TRUE);
3541 	EnableWindow(hLightSpecularButton, TRUE);
3542 	EnableWindow(hLightAlternateButton, TRUE);
3543 	EnableWindow(hLightDrawLightDatsButton, TRUE);
3544 	if (!ldPrefs->getDrawLightDats())
3545 	{
3546 		enabled = FALSE;
3547 	}
3548 	EnableWindow(hLightOptionalStandardButton, enabled);
3549 	EnableWindow(GetDlgItem(hEffectsPage, IDC_LIGHT_DIR), TRUE);
3550 	setCheck(hEffectsPage, IDC_LIGHTING_QUALITY, ldPrefs->getQualityLighting());
3551 	setCheck(hEffectsPage, IDC_LIGHTING_SUBDUED, ldPrefs->getSubduedLighting());
3552 	setCheck(hEffectsPage, IDC_SPECULAR, ldPrefs->getUseSpecular());
3553 	setCheck(hEffectsPage, IDC_ALTERNATE_LIGHTING, ldPrefs->getOneLight());
3554 	setCheck(hEffectsPage, IDC_DRAW_LIGHT_DATS, ldPrefs->getDrawLightDats());
3555 	setCheck(hEffectsPage, IDC_OPTIONAL_STANDARD_LIGHT,
3556 		ldPrefs->getOptionalStandardLight());
3557 	lightDirButton = lightDirIndexToId[(int)ldPrefs->getLightDirection() - 1];
3558 	uncheckLightDirections();
3559 	if (lightDirButton != 0)
3560 	{
3561 		checkStates[GetDlgItem(hEffectsPage, lightDirButton)] = true;
3562 		if (!CUIThemes::isThemeLibLoaded())
3563 		{
3564 			setCheck(hEffectsPage, lightDirButton, true);
3565 		}
3566 	}
3567 	for (int i = 0; i < (int)lightAngleButtons.size(); i++)
3568 	{
3569 		EnableWindow(lightAngleButtons[i], TRUE);
3570 	}
3571 }
3572 
disableLighting(void)3573 void LDViewPreferences::disableLighting(void)
3574 {
3575 	EnableWindow(hLightQualityButton, FALSE);
3576 	EnableWindow(hLightSubduedButton, FALSE);
3577 	EnableWindow(hLightSpecularButton, FALSE);
3578 	EnableWindow(hLightAlternateButton, FALSE);
3579 	EnableWindow(hLightDrawLightDatsButton, FALSE);
3580 	EnableWindow(hLightOptionalStandardButton, FALSE);
3581 	EnableWindow(GetDlgItem(hEffectsPage, IDC_LIGHT_DIR), FALSE);
3582 	// Don't disable IDC_HIDE_LIGHT_DAT.
3583 	for (int i = 0; i < (int)lightAngleButtons.size(); i++)
3584 	{
3585 		EnableWindow(lightAngleButtons[i], FALSE);
3586 	}
3587 	setCheck(hEffectsPage, IDC_LIGHTING, false);
3588 	setCheck(hEffectsPage, IDC_LIGHTING_QUALITY, false);
3589 	setCheck(hEffectsPage, IDC_LIGHTING_SUBDUED, false);
3590 	setCheck(hEffectsPage, IDC_SPECULAR, false);
3591 	setCheck(hEffectsPage, IDC_ALTERNATE_LIGHTING, false);
3592 	setCheck(hEffectsPage, IDC_DRAW_LIGHT_DATS, false);
3593 	setCheck(hEffectsPage, IDC_OPTIONAL_STANDARD_LIGHT, false);
3594 	uncheckLightDirections();
3595 }
3596 
setupLightAngleButtons(void)3597 void LDViewPreferences::setupLightAngleButtons(void)
3598 {
3599 	lightAngleButtons.clear();
3600 	double scaleFactor = getScaleFactor();
3601 	HIMAGELIST hImageList = NULL;
3602 	SIZE size;
3603 	size.cx = size.cy = scalePoints(16);
3604 	hImageList = ImageList_Create(size.cx, size.cy, ILC_COLOR32, 9, 0);
3605 	for (IntIntMap::const_iterator it = lightDirIndexToId.begin()
3606 		; it != lightDirIndexToId.end(); it++)
3607 	{
3608 		HWND hButton = GetDlgItem(hEffectsPage, it->second);
3609 
3610 		if (hButton)
3611 		{
3612 			RECT buttonRect;
3613 			GetWindowRect(hButton, &buttonRect);
3614 			LONG buttonSize = buttonRect.bottom - buttonRect.top;
3615 			screenToClient(hEffectsPage, &buttonRect);
3616 			// For some reason, Windows messes up the sizes of these buttons,
3617 			// making them a bunch of different widths, which looks awful,
3618 			// since they are arranged in a 3x3 grid.
3619 			MoveWindow(hButton, buttonRect.left, buttonRect.top,
3620 				buttonSize, buttonSize, TRUE);
3621 			HICON hIcon = NULL;
3622 			if (scaleFactor > 1.0)
3623 			{
3624 				TCImage *image = TCImage::createFromResource(NULL, it->second, 4, true, scaleFactor);
3625 				if (image != NULL)
3626 				{
3627 					int index = addImageToImageList(hImageList, image, size);
3628 					UINT flags = ILD_TRANSPARENT;
3629 					if (!CUIScaler::use32bit())
3630 					{
3631 						// Note: this doesn't work quite right, but it's close.
3632 						flags = ILD_IMAGE;
3633 					}
3634 					hIcon = ImageList_GetIcon(hImageList, index, flags);
3635 					image->release();
3636 				}
3637 			}
3638 			if (!hIcon)
3639 			{
3640 				hIcon = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(it->second),
3641 					IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
3642 			}
3643 			if (hIcon)
3644 			{
3645 				lightAngleButtons.push_back(hButton);
3646 				HICON hOldIcon = buttonSetIcon(hButton, hIcon);
3647 				if (hOldIcon != NULL)
3648 				{
3649 					DestroyIcon(hOldIcon);
3650 				}
3651 				setupIconButton(hButton);
3652 			}
3653 		}
3654 	}
3655 	ImageList_Destroy(hImageList);
3656 }
3657 
setupLighting(void)3658 void LDViewPreferences::setupLighting(void)
3659 {
3660 	setupGroupCheckButton(hEffectsPage, IDC_LIGHTING,
3661 		ldPrefs->getUseLighting());
3662 	hLightQualityButton = GetDlgItem(hEffectsPage, IDC_LIGHTING_QUALITY);
3663 	hLightSubduedButton = GetDlgItem(hEffectsPage, IDC_LIGHTING_SUBDUED);
3664 	hLightSpecularButton = GetDlgItem(hEffectsPage, IDC_SPECULAR);
3665 	hLightAlternateButton = GetDlgItem(hEffectsPage, IDC_ALTERNATE_LIGHTING);
3666 	hLightDrawLightDatsButton = GetDlgItem(hEffectsPage, IDC_DRAW_LIGHT_DATS);
3667 	checkStates[hLightDrawLightDatsButton] = ldPrefs->getDrawLightDats();
3668 	hLightOptionalStandardButton = GetDlgItem(hEffectsPage,
3669 		IDC_OPTIONAL_STANDARD_LIGHT);
3670 	setupLightAngleButtons();
3671 	if (ldPrefs->getUseLighting())
3672 	{
3673 		enableLighting();
3674 	}
3675 	else
3676 	{
3677 		disableLighting();
3678 	}
3679 	setCheck(hEffectsPage, IDC_HIDE_LIGHT_DAT, ldPrefs->getNoLightGeom());
3680 }
3681 
setupEffectsPage(void)3682 void LDViewPreferences::setupEffectsPage(void)
3683 {
3684 	hEffectsPage = hwndArray->pointerAtIndex(effectsPageNumber);
3685 	setupLighting();
3686 	setupStereo();
3687 	setupCutaway();
3688 	setCheck(hEffectsPage, IDC_STIPPLE, ldPrefs->getUseStipple());
3689 	setCheck(hEffectsPage, IDC_SORT, ldPrefs->getSortTransparent());
3690 	setCheck(hEffectsPage, IDC_FLAT_SHADING, ldPrefs->getUseFlatShading());
3691 	setCheck(hEffectsPage, IDC_SMOOTH_CURVES, ldPrefs->getPerformSmoothing());
3692 }
3693 
sliderValueFromTextureOffset(double value)3694 int LDViewPreferences::sliderValueFromTextureOffset(double value)
3695 {
3696 	return (int)(value * 10.0);
3697 }
3698 
textureOffsetFromSliderValue(int value)3699 TCFloat32 LDViewPreferences::textureOffsetFromSliderValue(int value)
3700 {
3701 	return (TCFloat32)(value / 10.0f);
3702 }
3703 
sliderValueFromAniso(double value)3704 int LDViewPreferences::sliderValueFromAniso(double value)
3705 {
3706 	return (int)(log(value) / log(2.0) + 0.5f);
3707 }
3708 
anisoFromSliderValue(int value)3709 TCFloat32 LDViewPreferences::anisoFromSliderValue(int value)
3710 {
3711 	return (TCFloat32)(1 << value);
3712 }
3713 
setupSubstitution(void)3714 void LDViewPreferences::setupSubstitution(void)
3715 {
3716 	setupGroupCheckButton(hPrimitivesPage, IDC_PRIMITIVE_SUBSTITUTION,
3717 		ldPrefs->getAllowPrimitiveSubstitution());
3718 	hCurveQualityLabel = GetDlgItem(hPrimitivesPage, IDC_CURVE_QUALITY_LABEL);
3719 	hCurveQualitySlider = GetDlgItem(hPrimitivesPage, IDC_CURVE_QUALITY);
3720 	CUIDialog::trackBarSetup(hPrimitivesPage, IDC_CURVE_QUALITY, 1, 12, 1,
3721 		ldPrefs->getCurveQuality());
3722 	if (ldPrefs->getAllowPrimitiveSubstitution())
3723 	{
3724 		enablePrimitives();
3725 	}
3726 	else
3727 	{
3728 		disablePrimitives();
3729 	}
3730 }
3731 
setupTextures(void)3732 void LDViewPreferences::setupTextures(void)
3733 {
3734 	GLfloat maxAniso = TREGLExtensions::getMaxAnisoLevel();
3735 	short numAnisoLevels = (short)sliderValueFromAniso(maxAniso);
3736 	TCFloat32 anisoLevel = ldPrefs->getAnisoLevel();
3737 	TCFloat32 textureOffset = ldPrefs->getTextureOffsetFactor();
3738 
3739 	hTextureStudsButton = GetDlgItem(hPrimitivesPage, IDC_TEXTURE_STUDS);
3740 	hTextureOffsetLabel = GetDlgItem(hPrimitivesPage, IDC_TEXTURE_OFFSET_LABEL);
3741 	hTextureOffsetSlider = GetDlgItem(hPrimitivesPage, IDC_TEXTURE_OFFSET);
3742 	hTextureNearestButton = GetDlgItem(hPrimitivesPage, IDC_TEXTURE_NEAREST);
3743 	hTextureBilinearButton = GetDlgItem(hPrimitivesPage, IDC_TEXTURE_BILINEAR);
3744 	hTextureTrilinearButton = GetDlgItem(hPrimitivesPage,
3745 		IDC_TEXTURE_TRILINEAR);
3746 	hTextureAnisoButton = GetDlgItem(hPrimitivesPage, IDC_TEXTURE_ANISO);
3747 	hAnisoLevelSlider = GetDlgItem(hPrimitivesPage, IDC_ANISO_LEVEL);
3748 	hAnisoLevelLabel = GetDlgItem(hPrimitivesPage, IDC_ANISO_LEVEL_LABEL);
3749 	CUIDialog::trackBarSetup(hPrimitivesPage, IDC_TEXTURE_OFFSET, 10, 100, 10,
3750 		sliderValueFromTextureOffset(textureOffset));
3751 	if (anisoLevel > maxAniso)
3752 	{
3753 		anisoLevel = (TCFloat32)maxAniso;
3754 	}
3755 	setAniso(sliderValueFromAniso(anisoLevel));
3756 	if (anisoLevel < 2.0f)
3757 	{
3758 		anisoLevel = 2.0f;
3759 	}
3760 	CUIDialog::trackBarSetup(hPrimitivesPage, IDC_ANISO_LEVEL, 1, numAnisoLevels, 1,
3761 		sliderValueFromAniso(anisoLevel));
3762 	setCheck(hPrimitivesPage, IDC_TEXMAPS, ldPrefs->getTexmaps());
3763 	updateTextureFilteringEnabled();
3764 	updateTexmapsEnabled();
3765 }
3766 
setupPrimitivesPage(void)3767 void LDViewPreferences::setupPrimitivesPage(void)
3768 {
3769 	hPrimitivesPage = hwndArray->pointerAtIndex(primitivesPageNumber);
3770 	setupTextures();
3771 	setupSubstitution();
3772 	setCheck(hPrimitivesPage, IDC_STUD_QUALITY, !ldPrefs->getQualityStuds());
3773 	setCheck(hPrimitivesPage, IDC_HI_RES, ldPrefs->getHiResPrimitives());
3774 }
3775 
enableProxyServer(void)3776 void LDViewPreferences::enableProxyServer(void)
3777 {
3778 	UCCHAR proxyPortString[128];
3779 
3780 	EnableWindow(hProxyServerLabel, TRUE);
3781 	EnableWindow(hProxyServer, TRUE);
3782 	EnableWindow(hProxyPortLabel, TRUE);
3783 	EnableWindow(hProxyPort, TRUE);
3784 	ucstring ucProxyServerString;
3785 	utf8toucstring(ucProxyServerString, ldPrefs->getProxyServer());
3786 	windowSetText(hProxyServer, ucProxyServerString);
3787 	sucprintf(proxyPortString, COUNT_OF(proxyPortString), _UC("%d"),
3788 		ldPrefs->getProxyPort());
3789 	windowSetText(hProxyPort, proxyPortString);
3790 }
3791 
disableProxyServer(void)3792 void LDViewPreferences::disableProxyServer(void)
3793 {
3794 	EnableWindow(hProxyServerLabel, FALSE);
3795 	EnableWindow(hProxyServer, FALSE);
3796 	EnableWindow(hProxyPortLabel, FALSE);
3797 	EnableWindow(hProxyPort, FALSE);
3798 	windowSetText(hProxyServer, _UC(""));
3799 	windowSetText(hProxyPort, _UC(""));
3800 }
3801 
setupProxy(void)3802 void LDViewPreferences::setupProxy(void)
3803 {
3804 	int activeProxyType = IDC_PROXY_NONE;
3805 
3806 	setCheck(hUpdatesPage, IDC_PROXY_NONE, false);
3807 	setCheck(hUpdatesPage, IDC_PROXY_WINDOWS, false);
3808 	setCheck(hUpdatesPage, IDC_PROXY_MANUAL, false);
3809 	switch (ldPrefs->getProxyType())
3810 	{
3811 	case 0:
3812 		activeProxyType = IDC_PROXY_NONE;
3813 		disableProxyServer();
3814 		break;
3815 	case 1:
3816 		activeProxyType = IDC_PROXY_WINDOWS;
3817 		disableProxyServer();
3818 		break;
3819 	case 2:
3820 		activeProxyType = IDC_PROXY_MANUAL;
3821 		enableProxyServer();
3822 		break;
3823 	}
3824 	setCheck(hUpdatesPage, activeProxyType, true);
3825 }
3826 
enableCheckPartTracker(void)3827 void LDViewPreferences::enableCheckPartTracker(void)
3828 {
3829 	UCCHAR tmpString[128];
3830 
3831 	EnableWindow(hMissingPartsLabel, TRUE);
3832 	EnableWindow(hMissingParts, TRUE);
3833 	EnableWindow(hUpdatedPartsLabel, TRUE);
3834 	EnableWindow(hUpdatedParts, TRUE);
3835 	sucprintf(tmpString, COUNT_OF(tmpString), _UC("%0d"),
3836 		ldPrefs->getMissingPartWait());
3837 	windowSetText(hMissingParts, tmpString);
3838 	sucprintf(tmpString, COUNT_OF(tmpString), _UC("%0d"),
3839 		ldPrefs->getUpdatedPartWait());
3840 	windowSetText(hUpdatedParts, tmpString);
3841 }
3842 
disableCheckPartTracker(void)3843 void LDViewPreferences::disableCheckPartTracker(void)
3844 {
3845 	EnableWindow(hMissingPartsLabel, FALSE);
3846 	EnableWindow(hMissingParts, FALSE);
3847 	EnableWindow(hUpdatedPartsLabel, FALSE);
3848 	EnableWindow(hUpdatedParts, FALSE);
3849 	windowSetText(hMissingParts, _UC(""));
3850 	windowSetText(hUpdatedParts, _UC(""));
3851 }
3852 
setupUpdatesPage(void)3853 void LDViewPreferences::setupUpdatesPage(void)
3854 {
3855 	hUpdatesPage = hwndArray->pointerAtIndex(updatesPageNumber);
3856 	hProxyServerLabel = GetDlgItem(hUpdatesPage, IDC_PROXY_SERVER_LABEL);
3857 	hProxyServer = GetDlgItem(hUpdatesPage, IDC_PROXY_SERVER);
3858 	hProxyPortLabel = GetDlgItem(hUpdatesPage, IDC_PROXY_PORT_LABEL);
3859 	hProxyPort = GetDlgItem(hUpdatesPage, IDC_PROXY_PORT);
3860 	hCheckPartTracker = GetDlgItem(hUpdatesPage, IDC_CHECK_PART_TRACKER);
3861 	hMissingPartsLabel = GetDlgItem(hUpdatesPage, IDC_MISSING_DAYS_LABEL);
3862 	hMissingParts = GetDlgItem(hUpdatesPage, IDC_MISSING_DAYS);
3863 	hUpdatedPartsLabel = GetDlgItem(hUpdatesPage, IDC_UPDATED_DAYS_LABEL);
3864 	hUpdatedParts = GetDlgItem(hUpdatesPage, IDC_UPDATED_DAYS);
3865 	if (ldPrefs->getCheckPartTracker())
3866 	{
3867 		enableCheckPartTracker();
3868 	}
3869 	else
3870 	{
3871 		disableCheckPartTracker();
3872 	}
3873 	setCheck(hUpdatesPage, IDC_CHECK_PART_TRACKER,
3874 		ldPrefs->getCheckPartTracker());
3875 	setupProxy();
3876 }
3877 
selectPrefSet(const ucstring & prefSet,bool force)3878 void LDViewPreferences::selectPrefSet(const ucstring& prefSet, bool force)
3879 {
3880 	if (!prefSet.empty())
3881 	{
3882 		listBoxSelectString(hPrefSetsList, prefSet);
3883 		doPrefSetSelected(force);
3884 	}
3885 	else
3886 	{
3887 		char *savedSession =
3888 			TCUserDefaults::getSavedSessionNameFromKey(PREFERENCE_SET_KEY);
3889 
3890 		if (savedSession && savedSession[0])
3891 		{
3892 			ucstring ucSavedSession;
3893 			utf8toucstring(ucSavedSession, savedSession);
3894 			selectPrefSet(ucSavedSession, force);
3895 		}
3896 		else
3897 		{
3898 			selectPrefSet(DEFAULT_PREF_SET, force);
3899 		}
3900 		delete savedSession;
3901 	}
3902 }
3903 
setupPrefSetsList(void)3904 void LDViewPreferences::setupPrefSetsList(void)
3905 {
3906 	TCStringArray *sessionNames = TCUserDefaults::getAllSessionNames();
3907 	int i;
3908 	int count = sessionNames->getCount();
3909 
3910 	hPrefSetsList = GetDlgItem(hPrefSetsPage, IDC_PREFSETS_LIST);
3911 	listBoxAddString(hPrefSetsList, DEFAULT_PREF_SET);
3912 	for (i = 0; i < count; i++)
3913 	{
3914 		ucstring ucSessionName;
3915 		utf8toucstring(ucSessionName, sessionNames->stringAtIndex(i));
3916 		listBoxAddString(hPrefSetsList, ucSessionName);
3917 	}
3918 	selectPrefSet();
3919 	sessionNames->release();
3920 }
3921 
setupPrefSetsPage(void)3922 void LDViewPreferences::setupPrefSetsPage(void)
3923 {
3924 	hPrefSetsPage = hwndArray->pointerAtIndex(prefSetsPageNumber);
3925 	hDeletePrefSetButton = GetDlgItem(hPrefSetsPage, IDC_DELETE_PREF_SET);
3926 	hNewPrefSetButton = GetDlgItem(hPrefSetsPage, IDC_NEW_PREF_SET);
3927 	hPrefSetHotKeyButton = GetDlgItem(hPrefSetsPage, IDC_PREF_SET_HOT_KEY);
3928 	setupPrefSetsList();
3929 }
3930 
setupAntialiasing(void)3931 void LDViewPreferences::setupAntialiasing(void)
3932 {
3933 	TCIntArray *fsaaModes = LDVExtensionsSetup::getFSAAModes();
3934 	UCCHAR modeString[1024];
3935 
3936 	// Remove all items from FSAA combo box list.
3937 	CUIDialog::comboResetContent(hGeneralPage, IDC_FSAA_COMBO);
3938 	// Add "None" to FSAA combo box list as only item.
3939 	CUIDialog::comboAddString(hGeneralPage, IDC_FSAA_COMBO, ls(_UC("FsaaNone")));
3940 	// Select "None", just in case something else doesn't get selected later.
3941 	CUIDialog::comboSetCurSel(hGeneralPage, IDC_FSAA_COMBO, 0);
3942 	// The following array should always exist, even if it is empty, but check
3943 	// just to be sure.
3944 	if (fsaaModes)
3945 	{
3946 		int i;
3947 		int count = fsaaModes->getCount();
3948 
3949 		// Note that fsaaModes contains a sorted array of unique FSAA factors.
3950 		for (i = 0; i < count; i++)
3951 		{
3952 			int value = (*fsaaModes)[i];
3953 
3954 			sucprintf(modeString, COUNT_OF(modeString),
3955 				ls(_UC("FsaaNx")), value);
3956 			CUIDialog::comboAddString(hGeneralPage, IDC_FSAA_COMBO, modeString);
3957 			// nVidia hardare supports Quincunx and 9-box pattern, so add an
3958 			// "Enhanced" item to the list if the extension is supported and
3959 			// the current factor is 2 or 4.
3960 			if ((value == 2 || value == 4) &&
3961 				TREGLExtensions::haveNvMultisampleFilterHintExtension())
3962 			{
3963 				sucprintf(modeString, COUNT_OF(modeString),
3964 					ls(_UC("FsaaNx")), value);
3965 				ucstrcat(modeString, _UC(" "));
3966 				ucstrcat(modeString, ls(_UC("FsaaEnhanced")));
3967 				CUIDialog::comboAddString(hGeneralPage, IDC_FSAA_COMBO, modeString);
3968 			}
3969 		}
3970 	}
3971 	if (ldPrefs->getFsaaMode())
3972 	{
3973 		sucprintf(modeString, COUNT_OF(modeString),
3974 			ls(_UC("FsaaNx")), getFSAAFactor());
3975 		if (getUseNvMultisampleFilter())
3976 		{
3977 			ucstrcat(modeString, _UC(" "));
3978 			ucstrcat(modeString, ls(_UC("FsaaEnhanced")));
3979 		}
3980 		if (CUIDialog::comboSelectString(hGeneralPage, IDC_FSAA_COMBO, 0,
3981 			modeString) == CB_ERR)
3982 		{
3983 			// We didn't find the selected mode, so reset to none.
3984 			ldPrefs->setFsaaMode(0);
3985 		}
3986 	}
3987 	setCheck(hGeneralPage, IDC_LINE_AA, ldPrefs->getLineSmoothing());
3988 }
3989 
doApply(void)3990 bool LDViewPreferences::doApply(void)
3991 {
3992 	applyChanges();
3993 	checkAbandon = true;
3994 	return true;
3995 }
3996 
clear(void)3997 void LDViewPreferences::clear(void)
3998 {
3999 	if (hBackgroundColorBitmap)
4000 	{
4001 		DeleteObject(hBackgroundColorBitmap);
4002 		hBackgroundColorBitmap = NULL;
4003 	}
4004 	if (hDefaultColorBitmap)
4005 	{
4006 		DeleteObject(hDefaultColorBitmap);
4007 		hDefaultColorBitmap = NULL;
4008 	}
4009 	if (hButtonColorDC)
4010 	{
4011 		DeleteDC(hButtonColorDC);
4012 		hButtonColorDC = NULL;
4013 	}
4014 	hGeneralPage = NULL;
4015 	hGeometryPage = NULL;
4016 	hEffectsPage = NULL;
4017 	hPrimitivesPage = NULL;
4018 	hUpdatesPage = NULL;
4019 	hPrefSetsPage = NULL;
4020 	CUIPropertySheet::clear();
4021 }
4022 
doNewPrefSetInit(HWND,HWND hNewPrefSetField)4023 BOOL LDViewPreferences::doNewPrefSetInit(HWND /*hDlg*/, HWND hNewPrefSetField)
4024 {
4025 	SendMessage(hNewPrefSetField, EM_LIMITTEXT, 32, 0);
4026 	return TRUE;
4027 }
4028 
doHotKeyInit(HWND hDlg,HWND)4029 BOOL LDViewPreferences::doHotKeyInit(HWND hDlg, HWND /*hHotKeyCombo*/)
4030 {
4031 	int i;
4032 	ucstring prefSetName = getSelectedPrefSet();
4033 
4034 	if (!prefSetName.empty())
4035 	{
4036 		windowSetText(hDlg, prefSetName);
4037 	}
4038 	else
4039 	{
4040 		windowSetText(hDlg, _UC("???"));
4041 	}
4042 	CUIDialog::comboAddString(hDlg, IDC_HOTKEY_COMBO, ls(_UC("<None>")));
4043 	for (i = 1; i <= 10; i++)
4044 	{
4045 		UCCHAR numString[5];
4046 
4047 		sucprintf(numString, COUNT_OF(numString), _UC("%d"), i % 10);
4048 		CUIDialog::comboAddString(hDlg, IDC_HOTKEY_COMBO, numString);
4049 	}
4050 	CUIDialog::comboSetCurSel(hDlg, IDC_HOTKEY_COMBO, hotKeyIndex);
4051 	return TRUE;
4052 }
4053 
handleDpiChange(void)4054 bool LDViewPreferences::handleDpiChange(void)
4055 {
4056 	if (!lightAngleButtons.empty())
4057 	{
4058 		setupLightAngleButtons();
4059 	}
4060 	if (hGeneralPage != NULL)
4061 	{
4062 		setupBackgroundColorButton();
4063 		setupDefaultColorButton();
4064 	}
4065 	return true;
4066 }
4067 
doDialogInit(HWND hDlg,HWND hFocusWindow,LPARAM lParam)4068 BOOL LDViewPreferences::doDialogInit(
4069 	HWND hDlg,
4070 	HWND hFocusWindow,
4071 	LPARAM lParam)
4072 {
4073 	CUIPropertySheet::doDialogInit(hDlg, hFocusWindow, lParam);
4074 	HWND hNewPrefSetField = NULL;
4075 	HWND hHotKeyCombo = NULL;
4076 
4077 	hNewPrefSetField = GetDlgItem(hDlg, IDC_NEW_PREF_SET_FIELD);
4078 	if (hNewPrefSetField)
4079 	{
4080 		return doNewPrefSetInit(hDlg, hNewPrefSetField);
4081 	}
4082 	hHotKeyCombo = GetDlgItem(hDlg, IDC_HOTKEY_COMBO);
4083 	if (hHotKeyCombo)
4084 	{
4085 		return doHotKeyInit(hDlg, hHotKeyCombo);
4086 	}
4087 	return TRUE;
4088 }
4089 
shouldSetActive(int index)4090 bool LDViewPreferences::shouldSetActive(int index)
4091 {
4092 	if (applyEnabledArray->itemAtIndex(prefSetsPageNumber) &&
4093 		index != prefSetsPageNumber)
4094 	{
4095 		if (!setActiveWarned)
4096 		{
4097 			setActiveWarned = true;
4098 			messageBoxUC(hWindow,
4099 				ls(_UC("PrefSetApplyBeforeLeave")),
4100 				ls(_UC("Error")), MB_OK | MB_ICONWARNING);
4101 		}
4102 		return false;
4103 	}
4104 	setActiveWarned = false;
4105 	return true;
4106 }
4107 
getFSAAFactor(void)4108 int LDViewPreferences::getFSAAFactor(void)
4109 {
4110 	int fsaaMode = ldPrefs->getFsaaMode();
4111 
4112 	if (fsaaMode && LDVExtensionsSetup::haveMultisampleExtension())
4113 	{
4114 		if (fsaaMode <= 5)
4115 		{
4116 			return fsaaMode & 0x6; // Mask off bottom bit
4117 		}
4118 		else
4119 		{
4120 			return fsaaMode >> 3;
4121 		}
4122 	}
4123 	else
4124 	{
4125 		return 0;
4126 	}
4127 }
4128 
getUseNvMultisampleFilter(void)4129 bool LDViewPreferences::getUseNvMultisampleFilter(void)
4130 {
4131 	int fsaaMode = ldPrefs->getFsaaMode();
4132 
4133 	if ((fsaaMode & 0x1) &&
4134 		TREGLExtensions::haveNvMultisampleFilterHintExtension())
4135 	{
4136 		return true;
4137 	}
4138 	else
4139 	{
4140 		return false;
4141 	}
4142 }
doDrawIconPushButton(HWND hWnd,HTHEME hTheme,LPDRAWITEMSTRUCT drawItemStruct)4143 BOOL LDViewPreferences::doDrawIconPushButton(
4144 	HWND hWnd, HTHEME hTheme, LPDRAWITEMSTRUCT drawItemStruct)
4145 {
4146 	HDC hDrawItemDC = drawItemStruct->hDC;
4147 	bool bIsPressed = (drawItemStruct->itemState & ODS_SELECTED) != 0;
4148 	bool bIsFocused = (drawItemStruct->itemState & ODS_FOCUS) != 0;
4149 	bool bDrawFocusRect = (drawItemStruct->itemState & ODS_NOFOCUSRECT) == 0;
4150 	bool bIsDisabled = (drawItemStruct->itemState & ODS_DISABLED) != 0;
4151 	bool bIsChecked = checkStates[hWnd];
4152 	RECT itemRect = drawItemStruct->rcItem;
4153 	HICON hIcon;
4154 
4155 	SetBkMode(hDrawItemDC, TRANSPARENT);
4156 	// Prepare draw... paint button background
4157 	if (CUIThemes::isThemeLibLoaded() && hTheme)
4158 	{
4159 		DWORD state;
4160 
4161 		if (bIsPressed)
4162 		{
4163 			state = PBS_PRESSED;
4164 		}
4165 		else if (!bIsDisabled)
4166 		{
4167 			if (hMouseOverButton == hWnd)
4168 			{
4169 				state = PBS_HOT;
4170 			}
4171 			else
4172 			{
4173 				if (bIsChecked)
4174 				{
4175 					state = PBS_PRESSED;
4176 				}
4177 				else
4178 				{
4179 					state = PBS_NORMAL;
4180 				}
4181 			}
4182 		}
4183 		else
4184 		{
4185 			state = PBS_DISABLED;
4186 		}
4187 		CUIThemes::drawThemeBackground(hTheme, hDrawItemDC, BP_PUSHBUTTON, state,
4188 			&itemRect, NULL);
4189 	}
4190 	else
4191 	{
4192 		if (bIsFocused)
4193 		{
4194 			HBRUSH br = CreateSolidBrush(RGB(0,0,0));
4195 			FrameRect(hDrawItemDC, &itemRect, br);
4196 			InflateRect(&itemRect, -1, -1);
4197 			DeleteObject(br);
4198 		} // if
4199 
4200 		COLORREF crColor = GetSysColor(COLOR_BTNFACE);
4201 
4202 		HBRUSH	brBackground = CreateSolidBrush(crColor);
4203 
4204 		FillRect(hDrawItemDC, &itemRect, brBackground);
4205 
4206 		DeleteObject(brBackground);
4207 
4208 		// Draw pressed button
4209 		if (bIsPressed)
4210 		{
4211 			HBRUSH brBtnShadow = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
4212 			FrameRect(hDrawItemDC, &itemRect, brBtnShadow);
4213 			DeleteObject(brBtnShadow);
4214 		}
4215 
4216 		else // ...else draw non pressed button
4217 		{
4218 			UINT uState = DFCS_BUTTONPUSH |
4219                   ((hMouseOverButton == hWnd) ? DFCS_HOT : 0) |
4220                   ((bIsPressed) ? DFCS_PUSHED : 0);
4221 
4222 			DrawFrameControl(hDrawItemDC, &itemRect, DFC_BUTTON, uState);
4223 		} // else
4224 	}
4225 
4226 	// Draw the focus rect
4227 	if (bIsFocused && bDrawFocusRect)
4228 	{
4229 		RECT focusRect = itemRect;
4230 
4231 		InflateRect(&focusRect, -3, -3);
4232 		DrawFocusRect(hDrawItemDC, &focusRect);
4233 	}
4234 
4235 	// Draw the icon
4236 	hIcon = buttonGetIcon(hWnd);
4237 	if (hIcon)
4238 	{
4239 		ICONINFO iconInfo;
4240 
4241 		//if (GetBitmapDimensionEx(hBitmap, &bitmapSize))
4242 		if (GetIconInfo(hIcon, &iconInfo))
4243 		{
4244 			SIZE iconSize;
4245 			RECT clientRect;
4246 			RECT contentRect;
4247 			int lwidth;
4248 			int lheight;
4249 			BITMAPINFO bmi;
4250 
4251 			memset(&bmi, 0, sizeof(bmi));
4252 			bmi.bmiHeader.biSize = sizeof (bmi.bmiHeader);
4253 			if (GetDIBits(hDrawItemDC, iconInfo.hbmColor, 0, 0, NULL, &bmi,
4254 				DIB_RGB_COLORS))
4255 			{
4256 				iconSize.cx = bmi.bmiHeader.biWidth;
4257 				iconSize.cy = bmi.bmiHeader.biHeight;
4258 			}
4259 			else
4260 			{
4261 				iconSize.cx = 32;
4262 				iconSize.cy = 32;
4263 			}
4264 			GetClientRect(hWnd, &clientRect);
4265 			if (CUIThemes::isThemeLibLoaded() && hTheme)
4266 			{
4267 				CUIThemes::getThemeBackgroundContentRect(hTheme, NULL,
4268 					BP_PUSHBUTTON, PBS_HOT, &clientRect, &contentRect);
4269 			}
4270 			else
4271 			{
4272 				contentRect = clientRect;
4273 			}
4274 			lwidth = contentRect.right - contentRect.left;
4275 			lheight = contentRect.bottom - contentRect.top;
4276 			if (bIsDisabled)
4277 			{
4278 				HBITMAP hOldBitmap;
4279 				int dstX, dstY, srcX, srcY;
4280 				COLORREF shadowColor;
4281 				COLORREF highlightColor;
4282 				HBRUSH hHighlightBrush;
4283 				HBRUSH hShadowBrush;
4284 				HANDLE hOldBrush;
4285 				HBITMAP hInvMask = CreateBitmap(iconSize.cx, iconSize.cy, 1, 1,
4286 					NULL);
4287 				HDC hTempDC = CreateCompatibleDC(hDrawItemDC);
4288 
4289 				CUIThemes::getThemeColor(hTheme, BP_CHECKBOX,
4290 					CBS_CHECKEDDISABLED, TMT_TEXTCOLOR, &shadowColor);
4291 				CUIThemes::getThemeColor(hTheme, BP_PUSHBUTTON, PBS_NORMAL,
4292 					TMT_EDGEHIGHLIGHTCOLOR, &highlightColor);
4293 				hShadowBrush = CreateSolidBrush(shadowColor);
4294 				hHighlightBrush = CreateSolidBrush(highlightColor);
4295 				SelectObject(hTempDC, iconInfo.hbmMask);
4296 				hOldBitmap = (HBITMAP)SelectObject(hButtonColorDC, hInvMask);
4297 				BitBlt(hButtonColorDC, 0, 0, iconSize.cx, iconSize.cy, hTempDC,
4298 					0, 0, NOTSRCCOPY);
4299 				if (iconSize.cx > lwidth)
4300 				{
4301 					dstX = contentRect.left;
4302 					srcX = (iconSize.cx - lwidth) / 2;
4303 				}
4304 				else
4305 				{
4306 					dstX = contentRect.left + (lwidth - iconSize.cx) / 2;
4307 					lwidth = iconSize.cx;
4308 					srcX = 0;
4309 				}
4310 				if (iconSize.cy > lheight)
4311 				{
4312 					dstY = contentRect.top;
4313 					srcY = (iconSize.cy - lwidth) / 2;
4314 				}
4315 				else
4316 				{
4317 					dstY = contentRect.top + (lheight - iconSize.cy) / 2;
4318 					lheight = iconSize.cy;
4319 					srcY = 0;
4320 				}
4321 				hOldBrush = SelectObject(hDrawItemDC, hHighlightBrush);
4322 				// The raster op we're using is somewhat voodoo magic.  However,
4323 				// it means DSPDxax, according to this page here:
4324 				//
4325 				// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pantdraw_6n77.asp
4326 				//
4327 				// In any event DSPDxax means:
4328 				// dst XOR src AND pat XOR dst
4329 				// Where pat is the current brush in the destination DC.
4330 				// What that means is that everywhere that the source is white,
4331 				// the destination ends up filled with its brush.  Everywhere
4332 				// the source is black (1-bit bitmap), the destination remains
4333 				// unchanged.
4334 				BitBlt(hDrawItemDC, dstX + 1, dstY + 1, lwidth, lheight, hButtonColorDC,
4335 					srcX, srcY, 0x00E20746L);
4336 				SelectObject(hDrawItemDC, hShadowBrush);
4337 				BitBlt(hDrawItemDC, dstX, dstY, lwidth, lheight, hButtonColorDC,
4338 					srcX, srcY, 0x00E20746L);
4339 				SelectObject(hDrawItemDC, hOldBrush);
4340 				SelectObject(hButtonColorDC, hOldBitmap);
4341 				DeleteDC(hTempDC);
4342 				DeleteObject(hHighlightBrush);
4343 				DeleteObject(hShadowBrush);
4344 				DeleteObject(hInvMask);
4345 			}
4346 			else
4347 			{
4348 				int dstX = contentRect.left + (lwidth - iconSize.cx) / 2;
4349 				int dstY = contentRect.top + (lheight - iconSize.cy) / 2;
4350 
4351 				if (bIsChecked)
4352 				{
4353 					dstX++;
4354 					dstY++;
4355 				}
4356 				DrawIconEx(hDrawItemDC, dstX, dstY, hIcon, iconSize.cx, iconSize.cy,
4357 					0, NULL, DI_NORMAL);
4358 				//DrawIcon(hDrawItemDC, dstX, dstY, hIcon);
4359 			}
4360 		}
4361 	}
4362 	return TRUE;
4363 }
4364 
doDrawGroupCheckBox(HWND hWnd,HTHEME hTheme,LPDRAWITEMSTRUCT drawItemStruct)4365 BOOL LDViewPreferences::doDrawGroupCheckBox(HWND hWnd, HTHEME hTheme,
4366 											LPDRAWITEMSTRUCT drawItemStruct)
4367 {
4368 	HDC hDrawItemDC = drawItemStruct->hDC;
4369 	bool bIsPressed = (drawItemStruct->itemState & ODS_SELECTED) != 0;
4370 	bool bIsFocused = (drawItemStruct->itemState & ODS_FOCUS) != 0;
4371 	bool bDrawFocusRect = (drawItemStruct->itemState & ODS_NOFOCUSRECT) == 0;
4372 	bool bIsDisabled = (drawItemStruct->itemState & ODS_DISABLED) != 0;
4373 	bool bIsChecked = checkStates[hWnd];
4374 	bool bHidePrefix =
4375 		(SendMessage(hWnd, WM_QUERYUISTATE, 0, 0) & UISF_HIDEACCEL) != 0;
4376 	RECT itemRect = drawItemStruct->rcItem;
4377 	ucstring title;
4378 
4379 	windowGetText(hWnd, title);
4380 	SetBkMode(hDrawItemDC, TRANSPARENT);
4381 	// Prepare draw... paint button background
4382 	if (CUIThemes::isThemeLibLoaded() && hTheme)
4383 	{
4384 		DWORD state;
4385 		DWORD textFlags = DT_LEFT;
4386 		SIZE boxSize;
4387 		RECT boxRect = itemRect;
4388 		RECT textRect;
4389 
4390 		if (bIsPressed)
4391 		{
4392 			if (bIsChecked)
4393 			{
4394 				state = CBS_CHECKEDPRESSED;
4395 			}
4396 			else
4397 			{
4398 				state = CBS_UNCHECKEDPRESSED;
4399 			}
4400 		}
4401 		else if (!bIsDisabled)
4402 		{
4403 			if (hMouseOverButton == hWnd)
4404 			{
4405 				if (bIsChecked)
4406 				{
4407 					state = CBS_CHECKEDHOT;
4408 				}
4409 				else
4410 				{
4411 					state = CBS_UNCHECKEDHOT;
4412 				}
4413 			}
4414 			else
4415 			{
4416 				if (bIsChecked)
4417 				{
4418 					state = CBS_CHECKEDNORMAL;
4419 				}
4420 				else
4421 				{
4422 					state = CBS_UNCHECKEDNORMAL;
4423 				}
4424 			}
4425 		}
4426 		else
4427 		{
4428 			state = CBS_UNCHECKEDDISABLED;
4429 		}
4430 		if (bHidePrefix)
4431 		{
4432 			textFlags |= DT_HIDEPREFIX;
4433 		}
4434 		CUIThemes::getThemePartSize(hTheme, hDrawItemDC, BP_CHECKBOX, state, NULL,
4435 			TS_TRUE, &boxSize);
4436 		boxRect.right = itemRect.left + boxSize.cx;
4437 		CUIThemes::drawThemeParentBackground(hWnd, hDrawItemDC, &itemRect);
4438 		CUIThemes::drawThemeBackground(hTheme, hDrawItemDC, BP_CHECKBOX, state,
4439 			&boxRect, NULL);
4440 		CUIThemes::getThemeTextExtent(hTheme, hDrawItemDC, BP_CHECKBOX, state,
4441 			title.c_str(), -1, textFlags, &itemRect, &textRect);
4442 		OffsetRect(&textRect, boxSize.cx + 3, 1);
4443 		// Draw the focus rect
4444 		if (bIsFocused && bDrawFocusRect)
4445 		{
4446 			RECT focusRect = textRect;
4447 
4448 			InflateRect(&focusRect, 1, 1);
4449 			DrawFocusRect(hDrawItemDC, &focusRect);
4450 		}
4451 		// All this so that we can draw the text in the font and color of the
4452 		// group box text instead of the check box text.  Here's where we do
4453 		// that.
4454 		if (bIsDisabled)
4455 		{
4456 			CUIThemes::drawThemeText(hTheme, hDrawItemDC, BP_CHECKBOX, CBS_DISABLED,
4457 				title.c_str(), -1, textFlags, NULL, &textRect);
4458 		}
4459 		else
4460 		{
4461 			CUIThemes::drawThemeText(hTheme, hDrawItemDC, BP_GROUPBOX, GBS_NORMAL,
4462 				title.c_str(), -1, textFlags, NULL, &textRect);
4463 		}
4464 	}
4465 	return TRUE;
4466 }
4467 
doDrawColorButton(HWND hDlg,HWND hWnd,HTHEME hTheme,LPDRAWITEMSTRUCT drawItemStruct)4468 BOOL LDViewPreferences::doDrawColorButton(HWND hDlg, HWND hWnd, HTHEME hTheme,
4469 										  LPDRAWITEMSTRUCT drawItemStruct)
4470 {
4471 	HDC hDrawItemDC = drawItemStruct->hDC;
4472 	bool bIsPressed = (drawItemStruct->itemState & ODS_SELECTED) != 0;
4473 	bool bIsFocused = (drawItemStruct->itemState & ODS_FOCUS) != 0;
4474 	bool bDrawFocusRect = (drawItemStruct->itemState & ODS_NOFOCUSRECT) == 0;
4475 	RECT itemRect = drawItemStruct->rcItem;
4476 	HBITMAP hBitmap;
4477 
4478 	SetBkMode(hDrawItemDC, TRANSPARENT);
4479 	// Prepare draw... paint button background
4480 	if (CUIThemes::isThemeLibLoaded() && hTheme)
4481 	{
4482 		DWORD state = (bIsPressed) ? PBS_PRESSED : PBS_NORMAL;
4483 
4484 		if (state == PBS_NORMAL)
4485 		{
4486 			if (bIsFocused)
4487 			{
4488 				state = PBS_DEFAULTED;
4489 			}
4490 			if (hMouseOverButton == hWnd)
4491 			{
4492 				state = PBS_HOT;
4493 			}
4494 		}
4495 		CUIThemes::drawThemeBackground(hTheme, hDrawItemDC, BP_PUSHBUTTON, state,
4496 			&itemRect, NULL);
4497 	}
4498 	else
4499 	{
4500 		if (bIsFocused)
4501 		{
4502 			HBRUSH br = CreateSolidBrush(RGB(0,0,0));
4503 			FrameRect(hDrawItemDC, &itemRect, br);
4504 			InflateRect(&itemRect, -1, -1);
4505 			DeleteObject(br);
4506 		} // if
4507 
4508 		COLORREF crColor = GetSysColor(COLOR_BTNFACE);
4509 
4510 		HBRUSH	brBackground = CreateSolidBrush(crColor);
4511 
4512 		FillRect(hDrawItemDC, &itemRect, brBackground);
4513 
4514 		DeleteObject(brBackground);
4515 
4516 		// Draw pressed button
4517 		if (bIsPressed)
4518 		{
4519 			HBRUSH brBtnShadow = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
4520 			FrameRect(hDrawItemDC, &itemRect, brBtnShadow);
4521 			DeleteObject(brBtnShadow);
4522 		}
4523 
4524 		else // ...else draw non pressed button
4525 		{
4526 			UINT uState = DFCS_BUTTONPUSH |
4527                   ((hMouseOverButton == hWnd) ? DFCS_HOT : 0) |
4528                   ((bIsPressed) ? DFCS_PUSHED : 0);
4529 
4530 			DrawFrameControl(hDrawItemDC, &itemRect, DFC_BUTTON, uState);
4531 		} // else
4532 	}
4533 
4534 	// Draw the focus rect
4535 	if (bIsFocused && bDrawFocusRect)
4536 	{
4537 		RECT focusRect = itemRect;
4538 
4539 		InflateRect(&focusRect, -3, -3);
4540 		DrawFocusRect(hDrawItemDC, &focusRect);
4541 	}
4542 
4543 	// Draw the bitmap
4544 	hBitmap = CUIDialog::buttonGetBitmap(hDlg, drawItemStruct->CtlID);
4545 	if (hBitmap)
4546 	{
4547 		SIZE bitmapSize;
4548 
4549 		if (GetBitmapDimensionEx(hBitmap, &bitmapSize))
4550 		{
4551 			HBITMAP hOldBitmap = (HBITMAP)SelectObject(hButtonColorDC,
4552 				hBitmap);
4553 			RECT clientRect;
4554 			RECT contentRect;
4555 			int lwidth;
4556 			int lheight;
4557 
4558 			GetClientRect(hWnd, &clientRect);
4559 			if (CUIThemes::isThemeLibLoaded() && hTheme)
4560 			{
4561 				CUIThemes::getThemeBackgroundContentRect(hTheme, NULL,
4562 					BP_PUSHBUTTON, PBS_HOT, &clientRect, &contentRect);
4563 			}
4564 			else
4565 			{
4566 				contentRect = clientRect;
4567 			}
4568 			lwidth = contentRect.right - contentRect.left;
4569 			lheight = contentRect.bottom - contentRect.top;
4570 			BitBlt(hDrawItemDC, contentRect.left + (lwidth - bitmapSize.cx) / 2,
4571 				contentRect.top + (lheight - bitmapSize.cy) / 2, bitmapSize.cx,
4572 				bitmapSize.cy, hButtonColorDC, 0, 0, SRCCOPY);
4573 			SelectObject(hButtonColorDC, hOldBitmap);
4574 		}
4575 	}
4576 	return TRUE;
4577 }
4578 
doDrawItem(HWND hDlg,int itemId,LPDRAWITEMSTRUCT drawItemStruct)4579 BOOL LDViewPreferences::doDrawItem(HWND hDlg, int itemId,
4580 								   LPDRAWITEMSTRUCT drawItemStruct)
4581 {
4582 	HWND hWnd = GetDlgItem(hDlg, itemId);
4583 
4584 	if (itemId == IDC_DEFAULT_COLOR || itemId == IDC_BACKGROUND_COLOR)
4585 	{
4586 		return doDrawColorButton(hDlg, hWnd, hButtonTheme, drawItemStruct);
4587 	}
4588 	else
4589 	{
4590 		switch (itemId)
4591 		{
4592 		case IDC_WIREFRAME:
4593 		case IDC_BFC:
4594 		case IDC_HIGHLIGHTS:
4595 		case IDC_LIGHTING:
4596 		case IDC_STEREO:
4597 		case IDC_CUTAWAY:
4598 		case IDC_PRIMITIVE_SUBSTITUTION:
4599 			return doDrawGroupCheckBox(hWnd, hButtonTheme, drawItemStruct);
4600 			break;
4601 		default:
4602 			return doDrawIconPushButton(hWnd, hButtonTheme, drawItemStruct);
4603 			break;
4604 		}
4605 	}
4606 	return FALSE;
4607 }
4608 
dialogProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)4609 INT_PTR LDViewPreferences::dialogProc(
4610 	HWND hDlg,
4611 	UINT message,
4612 	WPARAM wParam,
4613 	LPARAM lParam)
4614 {
4615 	switch (message)
4616 	{
4617 	case WM_MOUSEMOVE:
4618 		if (CUIThemes::isThemeLibLoaded())
4619 		{
4620 			if (hMouseOverButton)
4621 			{
4622 				InvalidateRect(hMouseOverButton, NULL, TRUE);
4623 				hMouseOverButton = NULL;
4624 			}
4625 		}
4626 		break;
4627 	case WM_DRAWITEM:
4628 		return doDrawItem(hDlg, (int)wParam, (LPDRAWITEMSTRUCT)lParam);
4629 		break;
4630 	}
4631 	return CUIPropertySheet::dialogProc(hDlg, message, wParam, lParam);
4632 }
4633 
getMinFov(void)4634 TCFloat LDViewPreferences::getMinFov(void)
4635 {
4636 	return 0.1f;
4637 }
4638 
getMaxFov(void)4639 TCFloat LDViewPreferences::getMaxFov(void)
4640 {
4641 	return 90.0f;
4642 }
4643 
checkLightVector(void)4644 void LDViewPreferences::checkLightVector(void)
4645 {
4646 	if (hEffectsPage)
4647 	{
4648 		LDPreferences::LightDirection selectedDirection =
4649 			getSelectedLightDirection();
4650 		LDPreferences::LightDirection lightDirection =
4651 			ldPrefs->getLightDirection();
4652 
4653 		if (selectedDirection != lightDirection)
4654 		{
4655 			int lightDirButton =
4656 				lightDirIndexToId[(int)lightDirection - 1];
4657 
4658 			uncheckLightDirections();
4659 			if ((int)selectedDirection > 0)
4660 			{
4661 				InvalidateRect(lightAngleButtons[(int)selectedDirection - 1], NULL,
4662 					TRUE);
4663 			}
4664 			if (lightDirButton != 0)
4665 			{
4666 				checkStates[GetDlgItem(hEffectsPage, lightDirButton)] = true;
4667 				InvalidateRect(lightAngleButtons[(int)lightDirection - 1], NULL,
4668 					TRUE);
4669 			}
4670 		}
4671 	}
4672 }
4673