1 #include "ModelTreeDialog.h"
2 #include "ModelWindow.h"
3 #include "Resource.h"
4 #include <TCFoundation/mystring.h>
5 #include <TCFoundation/TCLocalStrings.h>
6 #include <TCFoundation/TCAlertManager.h>
7 #include <LDLoader/LDLMainModel.h>
8 #include <LDLib/LDModelTree.h>
9 #include <LDLib/LDUserDefaultsKeys.h>
10 #include <CUI/CUIWindowResizer.h>
11 #include <CUI/CUIColorButton.h>
12 #include <CommCtrl.h>
13
14 #if defined(_MSC_VER) && _MSC_VER >= 1400 && defined(_DEBUG)
15 #define new DEBUG_CLIENTBLOCK
16 #endif // _DEBUG
17
18 #define SEARCH_TIMER 1
19
ModelTreeDialog(HINSTANCE hInstance,HWND hParentWindow)20 ModelTreeDialog::ModelTreeDialog(HINSTANCE hInstance, HWND hParentWindow):
21 CUIDialog(hInstance, hParentWindow),
22 m_modelWindow(NULL),
23 m_model(NULL),
24 m_modelTree(NULL),
25 m_resizer(NULL),
26 m_optionsShown(true),
27 m_highlight(TCUserDefaults::boolForKey(MODEL_TREE_HIGHLIGHT_KEY, false, false)),
28 m_clearing(false)
29 {
30 COLORREF defHighlightColor = RGB(160, 224, 255);
31 long highlightColor =
32 TCUserDefaults::longForKey(MODEL_TREE_HIGHLIGHT_COLOR_KEY,
33 defHighlightColor, false);
34 LongVector customColors;
35
36 customColors = TCUserDefaults::longVectorForKey(MODEL_TREE_CUST_COLORS_KEY,
37 customColors, false);
38 if (customColors.size() == 0)
39 {
40 // Put the default highlight color into the list of custom colors.
41 customColors.resize(16);
42 customColors[0] = defHighlightColor;
43 TCUserDefaults::setLongVectorForKey(customColors,
44 MODEL_TREE_CUST_COLORS_KEY, false);
45 }
46 m_highlightR = GetRValue(highlightColor);
47 m_highlightG = GetGValue(highlightColor);
48 m_highlightB = GetBValue(highlightColor);
49 TCAlertManager::registerHandler(ModelWindow::alertClass(), this,
50 (TCAlertCallback)&ModelTreeDialog::modelAlertCallback);
51 }
52
~ModelTreeDialog(void)53 ModelTreeDialog::~ModelTreeDialog(void)
54 {
55 }
56
dealloc(void)57 void ModelTreeDialog::dealloc(void)
58 {
59 TCAlertManager::unregisterHandler(this);
60 if (hWindow)
61 {
62 DestroyWindow(hWindow);
63 }
64 TCObject::release(m_colorButton);
65 TCObject::release(m_modelWindow);
66 TCObject::release(m_modelTree);
67 TCObject::release(m_model);
68 TCObject::release(m_resizer);
69 CUIDialog::dealloc();
70 }
71
setModel(LDLMainModel * model)72 void ModelTreeDialog::setModel(LDLMainModel *model)
73 {
74 if (model != m_model)
75 {
76 clearTreeView();
77 TCObject::release(m_model);
78 TCObject::release(m_modelTree);
79 m_modelTree = NULL;
80 m_model = model;
81 TCObject::retain(m_model);
82 }
83 }
84
modelAlertCallback(TCAlert * alert)85 void ModelTreeDialog::modelAlertCallback(TCAlert *alert)
86 {
87 if (alert->getSender() == m_modelWindow)
88 {
89 if (ucstrcmp(alert->getMessageUC(), _UC("ModelLoaded")) == 0)
90 {
91 setModel(m_modelWindow->getModelViewer()->getMainModel());
92 fillTreeView();
93 }
94 else if (ucstrcmp(alert->getMessageUC(), _UC("ModelLoadCanceled")) == 0)
95 {
96 setModel(NULL);
97 fillTreeView();
98 }
99 }
100 }
101
setModelWindow(ModelWindow * modelWindow)102 void ModelTreeDialog::setModelWindow(ModelWindow *modelWindow)
103 {
104 if (modelWindow != m_modelWindow)
105 {
106 if (m_modelWindow)
107 {
108 m_modelWindow->release();
109 }
110 m_modelWindow = modelWindow;
111 TCObject::retain(m_modelWindow);
112 }
113 setModel(m_modelWindow->getModelViewer()->getMainModel());
114 }
115
show(ModelWindow * modelWindow,HWND hParentWnd)116 void ModelTreeDialog::show(ModelWindow *modelWindow, HWND hParentWnd /*= NULL*/)
117 {
118 setModelWindow(modelWindow);
119 if (hWindow == NULL)
120 {
121 createDialog(IDD_MODELTREE, hParentWnd);
122 }
123 ShowWindow(hWindow, SW_SHOW);
124 fillTreeView();
125 }
126
doTreeItemExpanding(LPNMTREEVIEW notification)127 LRESULT ModelTreeDialog::doTreeItemExpanding(LPNMTREEVIEW notification)
128 {
129 if (notification->action == TVE_EXPAND)
130 {
131 LDModelTree *tree = (LDModelTree *)notification->itemNew.lParam;
132
133 if (!tree->getViewPopulated())
134 {
135 addChildren(notification->itemNew.hItem, tree);
136 tree->setViewPopulated(true);
137 }
138 return 0;
139 }
140 return 1;
141 }
142
highlightItem(HTREEITEM hItem)143 void ModelTreeDialog::highlightItem(HTREEITEM hItem)
144 {
145 LDModelTree *tree = getItemTree(hItem);
146
147 if (tree != NULL)
148 {
149 m_modelWindow->getModelViewer()->setHighlightColor(m_highlightR,
150 m_highlightG, m_highlightB, false);
151 m_modelWindow->getModelViewer()->setHighlightPaths(
152 tree->getTreePath());
153 m_searchPath = tree->getTreePath();
154 }
155 else
156 {
157 m_modelWindow->getModelViewer()->setHighlightPaths("");
158 m_searchPath = "";
159 }
160 }
161
doTreeSelChanged(LPNMTREEVIEW notification)162 LRESULT ModelTreeDialog::doTreeSelChanged(LPNMTREEVIEW notification)
163 {
164 if (!m_clearing)
165 {
166 if (m_highlight)
167 {
168 highlightItem(notification->itemNew.hItem);
169 }
170 updateStatusText();
171 }
172 return 1; // Ignored
173 }
174
doHighlightColorChanged(void)175 LRESULT ModelTreeDialog::doHighlightColorChanged(void)
176 {
177 LDrawModelViewer *modelViewer = m_modelWindow->getModelViewer();
178 m_colorButton->getColor(m_highlightR, m_highlightG, m_highlightB);
179 modelViewer->setHighlightColor(m_highlightR, m_highlightG, m_highlightB);
180 TCUserDefaults::setLongForKey(RGB(m_highlightR, m_highlightG, m_highlightB),
181 MODEL_TREE_HIGHLIGHT_COLOR_KEY, false);
182 return 0;
183 }
184
doNotify(int controlId,LPNMHDR notification)185 LRESULT ModelTreeDialog::doNotify(int controlId, LPNMHDR notification)
186 {
187 if (controlId == IDC_MODEL_TREE)
188 {
189 switch (notification->code)
190 {
191 case TVN_ITEMEXPANDINGUC:
192 return doTreeItemExpanding((LPNMTREEVIEW)notification);
193 case TVN_KEYDOWN:
194 return doTreeKeyDown((LPNMTVKEYDOWN)notification);
195 case TVN_SELCHANGEDUC:
196 return doTreeSelChanged((LPNMTREEVIEW)notification);
197 case NM_CUSTOMDRAW:
198 return doTreeCustomDraw((LPNMTVCUSTOMDRAW)notification);
199 }
200 }
201 else if (controlId == IDC_HIGHLIGHT_COLOR)
202 {
203 if (notification->code == CCBN_COLOR_CHANGED)
204 {
205 return doHighlightColorChanged();
206 }
207 }
208 return 1;
209 }
210
addChildren(HTREEITEM parent,const LDModelTree * tree)211 void ModelTreeDialog::addChildren(HTREEITEM parent, const LDModelTree *tree)
212 {
213 if (tree != NULL && tree->hasChildren(true))
214 {
215 const LDModelTreeArray *lchildren = tree->getChildren(true);
216 int count = lchildren->getCount();
217
218 for (int i = 0; i < count; i++)
219 {
220 const LDModelTree *child = (*lchildren)[i];
221 addLine(parent, child);
222 }
223 }
224 }
225
addLine(HTREEITEM parent,const LDModelTree * tree)226 HTREEITEM ModelTreeDialog::addLine(HTREEITEM parent, const LDModelTree *tree)
227 {
228 TVINSERTSTRUCTUC insertStruct;
229 TVITEMEXUC item;
230 HTREEITEM hNewItem;
231
232 memset(&item, 0, sizeof(item));
233 item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_CHILDREN;
234 item.cChildren = tree->getNumChildren(true);
235 item.pszText = copyString(tree->getTextUC().c_str());
236 item.lParam = (LPARAM)tree;
237 insertStruct.hParent = parent;
238 insertStruct.hInsertAfter = TVI_LAST;
239 insertStruct.itemex = item;
240 hNewItem = (HTREEITEM)::SendMessage(m_hTreeView, TVM_INSERTITEMUC, 0,
241 (LPARAM)&insertStruct);
242 delete item.pszText;
243 return hNewItem;
244 }
245
updateLineChecks(void)246 void ModelTreeDialog::updateLineChecks(void)
247 {
248 for (int i = LDLLineTypeComment; i <= LDLLineTypeUnknown; i++)
249 {
250 LDLLineType lineType = (LDLLineType)i;
251 bool checked = false;
252 BOOL enabled = m_model != NULL;
253
254 if (m_modelTree)
255 {
256 checked = m_modelTree->getShowLineType(lineType);
257 }
258 checkSet(m_checkIds[lineType], checked);
259 EnableWindow(m_lineChecks[i], enabled);
260 }
261 }
262
doLineCheck(UINT checkId,LDLLineType lineType)263 LRESULT ModelTreeDialog::doLineCheck(UINT checkId, LDLLineType lineType)
264 {
265 if (m_modelTree)
266 {
267 m_modelTree->setShowLineType(lineType, checkGet(checkId));
268 refreshTreeView();
269 }
270 return 0;
271 }
272
doHighlightCheck(void)273 LRESULT ModelTreeDialog::doHighlightCheck(void)
274 {
275 m_highlight = checkGet(IDC_HIGHLIGHT);
276 if (m_highlight)
277 {
278 highlightItem(TreeView_GetSelection(m_hTreeView));
279 }
280 else
281 {
282 m_modelWindow->getModelViewer()->setHighlightPaths("");
283 }
284 TCUserDefaults::setBoolForKey(m_highlight, MODEL_TREE_HIGHLIGHT_KEY, false);
285 return 0;
286 }
287
getItemTree(HTREEITEM hItem)288 LDModelTree* ModelTreeDialog::getItemTree(HTREEITEM hItem)
289 {
290 if (!hItem)
291 {
292 return NULL;
293 }
294 TVITEMEX item;
295
296 memset(&item, 0, sizeof(item));
297 item.mask = TVIF_PARAM;
298 item.hItem = hItem;
299 if (TreeView_GetItem(m_hTreeView, &item))
300 {
301 return (LDModelTree *)item.lParam;
302 }
303 return NULL;
304 }
305
doSearch(LDModelTree::SearchMode mode,bool updateFocus)306 LRESULT ModelTreeDialog::doSearch(LDModelTree::SearchMode mode, bool updateFocus)
307 {
308 ucstring searchString;
309 windowGetText(IDC_SEARCH, searchString);
310 std::string pathString = m_searchPath;
311 if (m_modelTree->search(searchString, pathString, mode))
312 {
313 selectFromHighlightPath(pathString);
314 if (updateFocus)
315 {
316 SetFocus(GetDlgItem(hWindow, IDC_MODEL_TREE));
317 }
318 }
319 else
320 {
321 TreeView_SelectItem(m_hTreeView, NULL);
322 }
323 return 0;
324 }
325
doTimer(UINT_PTR timerID)326 LRESULT ModelTreeDialog::doTimer(UINT_PTR timerID)
327 {
328 switch (timerID)
329 {
330 case SEARCH_TIMER:
331 killTimer(SEARCH_TIMER);
332 doSearch(LDModelTree::SearchMode::SMType, false);
333 break;
334 }
335 return 0;
336 }
337
doSearchChange(void)338 LRESULT ModelTreeDialog::doSearchChange(void)
339 {
340 killTimer(SEARCH_TIMER);
341 setTimer(SEARCH_TIMER, 500);
342 return 0;
343 }
344
doCommand(int notifyCode,int commandId,HWND control)345 LRESULT ModelTreeDialog::doCommand(
346 int notifyCode,
347 int commandId,
348 HWND control)
349 {
350 switch (commandId)
351 {
352 case IDC_OPTIONS:
353 return doToggleOptions();
354 case IDC_HIGHLIGHT:
355 return doHighlightCheck();
356 case IDC_PREV:
357 return doSearch(LDModelTree::SearchMode::SMPrevious, true);
358 case IDC_NEXT:
359 return doSearch(LDModelTree::SearchMode::SMNext, true);
360 case IDC_SEARCH:
361 if (notifyCode == EN_CHANGE)
362 {
363 return doSearchChange();
364 }
365 break;
366 case IDOK:
367 if (GetFocus() == GetDlgItem(hWindow, IDC_SEARCH))
368 {
369 killTimer(SEARCH_TIMER);
370 return doSearch(LDModelTree::SearchMode::SMType, true);
371 }
372 break;
373 default:
374 {
375 UIntLineTypeMap::const_iterator it = m_checkLineTypes.find(commandId);
376
377 if (it != m_checkLineTypes.end())
378 {
379 return doLineCheck(it->first, it->second);
380 }
381 }
382 break;
383 }
384 return CUIDialog::doCommand(notifyCode, commandId, control);
385 }
386
clearTreeView(void)387 void ModelTreeDialog::clearTreeView(void)
388 {
389 m_clearing = true;
390 SendMessage(m_hTreeView, WM_SETREDRAW, FALSE, 0);
391 TreeView_DeleteAllItems(m_hTreeView);
392 SendMessage(m_hTreeView, WM_SETREDRAW, TRUE, 0);
393 TreeView_SelectItem(m_hTreeView, NULL);
394 m_clearing = false;
395 updateStatusText();
396 }
397
getChild(HTREEITEM hParent,int index)398 HTREEITEM ModelTreeDialog::getChild(HTREEITEM hParent, int index)
399 {
400 HTREEITEM hItem;
401
402 hItem = TreeView_GetChild(m_hTreeView, hParent);
403 for (int i = 1; i <= index; i++)
404 {
405 hItem = TreeView_GetNextSibling(m_hTreeView, hItem);
406 }
407 return hItem;
408 }
409
selectFromHighlightPath(std::string path)410 void ModelTreeDialog::selectFromHighlightPath(std::string path)
411 {
412 HTREEITEM hItem = NULL;
413
414 path = m_modelTree->adjustHighlightPath(path);
415 while (path.size() > 0)
416 {
417 int lineNumber = atoi(&path[1]) - 1;
418
419 hItem = getChild(hItem, lineNumber);
420 if (hItem != NULL)
421 {
422 size_t index = path.find('/', 1);
423 if (index < path.size())
424 {
425 TreeView_Expand(m_hTreeView, hItem, TVE_EXPAND);
426 path = path.substr(index);
427 }
428 else
429 {
430 LDModelTree *tree = getItemTree(hItem);
431 if (tree != NULL)
432 {
433 m_searchPath = tree->getTreePath();
434 }
435 TreeView_SelectItem(m_hTreeView, hItem);
436 path = "";
437 }
438 }
439 else
440 {
441 return;
442 }
443 }
444 }
445
refreshTreeView(void)446 void ModelTreeDialog::refreshTreeView(void)
447 {
448 // The following has to be a copy, because the selection triggers the
449 // list to disappear out from under us.
450 StringList paths = m_modelWindow->getModelViewer()->getHighlightPaths();
451
452 clearTreeView();
453 SendMessage(m_hTreeView, WM_SETREDRAW, FALSE, 0);
454 addChildren(NULL, m_modelTree);
455 SendMessage(m_hTreeView, WM_SETREDRAW, TRUE, 0);
456 RedrawWindow(m_hTreeView, NULL, NULL, RDW_INVALIDATE);
457 if (m_modelTree != NULL)
458 {
459 for (StringList::const_iterator it = paths.begin(); it != paths.end();
460 it++)
461 {
462 selectFromHighlightPath(*it);
463 }
464 }
465 }
466
fillTreeView(void)467 void ModelTreeDialog::fillTreeView(void)
468 {
469 if (m_modelTree == NULL && IsWindowVisible(hWindow))
470 {
471 if (m_model)
472 {
473 m_modelTree = new LDModelTree(m_model);
474 }
475 updateLineChecks();
476 refreshTreeView();
477 }
478 }
479
setupLineCheck(UINT checkId,LDLLineType lineType)480 void ModelTreeDialog::setupLineCheck(UINT checkId, LDLLineType lineType)
481 {
482 m_lineChecks[lineType] = GetDlgItem(hWindow, checkId);
483 m_checkLineTypes[checkId] = lineType;
484 m_checkIds[lineType] = checkId;
485 m_resizer->addSubWindow(checkId, CUIFloatLeft | CUIFloatBottom);
486 }
487
adjustWindow(int widthDelta)488 void ModelTreeDialog::adjustWindow(int widthDelta)
489 {
490 WINDOWPLACEMENT wp;
491 int showCommand;
492
493 if (widthDelta > 0)
494 {
495 showCommand = SW_SHOW;
496 }
497 else
498 {
499 showCommand = SW_HIDE;
500 }
501 minWidth += widthDelta;
502 GetWindowPlacement(hWindow, &wp);
503 m_resizer->setOriginalWidth(m_resizer->getOriginalWidth() + widthDelta);
504 if (wp.showCmd == SW_MAXIMIZE)
505 {
506 RECT clientRect;
507
508 GetClientRect(hWindow, &clientRect);
509 m_resizer->resize(clientRect.right - clientRect.left,
510 clientRect.bottom - clientRect.top);
511 }
512 else
513 {
514 RECT windowRect;
515
516 GetWindowRect(hWindow, &windowRect);
517 windowRect.right += widthDelta;
518 MoveWindow(hWindow, windowRect.left, windowRect.top,
519 windowRect.right - windowRect.left,
520 windowRect.bottom - windowRect.top, TRUE);
521 }
522 for (size_t i = 0; i < m_lineChecks.size(); i++)
523 {
524 ShowWindow(m_lineChecks[i], showCommand);
525 }
526 //positionResizeGrip(m_hResizeGrip);
527 }
528
swapWindowText(UCCHAR oldChar,UCCHAR newChar)529 void ModelTreeDialog::swapWindowText(UCCHAR oldChar, UCCHAR newChar)
530 {
531 ucstring text;
532
533 windowGetText(IDC_OPTIONS, text);
534 replaceStringCharacter(&text[0], oldChar, newChar);
535 windowSetText(IDC_OPTIONS, text);
536 }
537
hideOptions(void)538 void ModelTreeDialog::hideOptions(void)
539 {
540 adjustWindow(-m_optionsDelta);
541 swapWindowText('<', '>');
542 m_optionsShown = false;
543 }
544
showOptions(void)545 void ModelTreeDialog::showOptions(void)
546 {
547 adjustWindow(m_optionsDelta);
548 swapWindowText('>', '<');
549 m_optionsShown = true;
550 }
551
doToggleOptions(void)552 LRESULT ModelTreeDialog::doToggleOptions(void)
553 {
554 if (m_optionsShown)
555 {
556 hideOptions();
557 }
558 else
559 {
560 showOptions();
561 }
562 TCUserDefaults::setBoolForKey(m_optionsShown, MODEL_TREE_OPTIONS_SHOWN_KEY,
563 false);
564 return 0;
565 }
566
addToolToTooltip(int controlId,const ucstring & tooltipText)567 void ModelTreeDialog::addToolToTooltip(int controlId, const ucstring& tooltipText)
568 {
569 HWND hControl = GetDlgItem(hWindow, controlId);
570 TOOLINFOUC ti;
571
572 memset(&ti, 0, sizeof(ti));
573 ti.cbSize = sizeof(ti);
574 ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
575 ti.hwnd = hWindow;
576 ti.uId = (UINT_PTR)hControl;
577 ucstring tooltipTextCopy = tooltipText;
578 ti.lpszText = &tooltipTextCopy[0];
579 ::SendMessage(m_hTooltip, TTM_ADDTOOL, 0, (LPARAM)&ti);
580 }
581
doInitDialog(HWND hKbControl)582 BOOL ModelTreeDialog::doInitDialog(HWND hKbControl)
583 {
584 RECT optionsRect;
585 RECT clientRect;
586
587 m_colorButton = new CUIColorButton(GetDlgItem(hWindow,
588 IDC_HIGHLIGHT_COLOR), MODEL_TREE_CUST_COLORS_KEY, m_highlightR,
589 m_highlightG, m_highlightB);
590 setIcon(IDI_APP_ICON);
591 m_hTreeView = GetDlgItem(hWindow, IDC_MODEL_TREE);
592
593 m_hTooltip = CUIWindow::createWindowExUC(0, TOOLTIPS_CLASSUC,
594 NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP /*| TTS_BALLOON*/,
595 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
596 hWindow, NULL, hInstance, NULL);
597 SetWindowPos(m_hTooltip, HWND_TOPMOST, 0, 0, 0, 0,
598 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
599 if (haveWindowsVistaOrLater())
600 {
601 std::wstring magnifier;
602 if (haveWindows7OrLater())
603 {
604 // Windows 7 is the first version to support emojis.
605 // Note: EM_SETCUEBANNER always expects Unicode, so having a hard-coded Unicode
606 // magnifier works as long as the Windows version support emojis.
607 magnifier = L"\U0001F50D ";
608 }
609 std::wstring cue = magnifier + ls(L"Search");
610 SendDlgItemMessage(hWindow, IDC_SEARCH, EM_SETCUEBANNER, TRUE, (LPARAM)cue.c_str());
611 }
612 addToolToTooltip(IDC_PREV, ls(_UC("Previous")));
613 addToolToTooltip(IDC_NEXT, ls(_UC("Next")));
614
615 m_resizer = new CUIWindowResizer;
616 m_resizer->setHWindow(hWindow);
617 m_resizer->addSubWindow(IDC_SEARCH, CUISizeHorizontal | CUIFloatBottom);
618 m_resizer->addSubWindow(IDC_PREV, CUIFloatLeft | CUIFloatBottom);
619 m_resizer->addSubWindow(IDC_NEXT, CUIFloatLeft | CUIFloatBottom);
620 m_resizer->addSubWindow(IDC_MODEL_TREE,
621 CUISizeHorizontal | CUISizeVertical);
622 m_resizer->addSubWindow(IDC_SHOW_BOX, CUIFloatLeft | CUIFloatBottom);
623 m_resizer->addSubWindow(IDC_OPTIONS, CUIFloatLeft | CUIFloatTop);
624 m_resizer->addSubWindow(IDC_HIGHLIGHT, CUIFloatRight | CUIFloatTop);
625 m_resizer->addSubWindow(IDC_HIGHLIGHT_COLOR, CUIFloatRight | CUIFloatTop);
626 m_lineChecks.resize(LDLLineTypeUnknown + 1);
627 setupLineCheck(IDC_COMMENT, LDLLineTypeComment);
628 setupLineCheck(IDC_MODEL, LDLLineTypeModel);
629 setupLineCheck(IDC_LINE, LDLLineTypeLine);
630 setupLineCheck(IDC_TRIANGLE, LDLLineTypeTriangle);
631 setupLineCheck(IDC_QUAD, LDLLineTypeQuad);
632 setupLineCheck(IDC_CONDITIONAL, LDLLineTypeConditionalLine);
633 setupLineCheck(IDC_EMPTY, LDLLineTypeEmpty);
634 setupLineCheck(IDC_UNKNOWN, LDLLineTypeUnknown);
635 GetWindowRect(GetDlgItem(hWindow, IDC_SHOW_BOX), &optionsRect);
636 screenToClient(hWindow, &optionsRect);
637 GetClientRect(hWindow, &clientRect);
638 m_optionsDelta = clientRect.right - optionsRect.left;
639 setMinSize(clientRect.right, clientRect.bottom, true);
640 if (!TCUserDefaults::boolForKey(MODEL_TREE_OPTIONS_SHOWN_KEY, true, false))
641 {
642 hideOptions();
643 }
644 checkSet(IDC_HIGHLIGHT, m_highlight);
645 initStatusBar();
646 setAutosaveName("ModelTreeDialog");
647 return CUIDialog::doInitDialog(hKbControl);
648 }
649
updateStatusText(void)650 void ModelTreeDialog::updateStatusText(void)
651 {
652 HTREEITEM hItem = TreeView_GetSelection(m_hTreeView);
653 LDModelTree *tree = getItemTree(hItem);
654
655 if (tree != NULL)
656 {
657 statusBarSetText(m_hStatus, 0, tree->getStatusText());
658 return;
659 }
660 statusBarSetText(m_hStatus, 0, ls(_UC("NoSelection")));
661 }
662
initStatusBar(void)663 void ModelTreeDialog::initStatusBar(void)
664 {
665 int parts[] = {-1};
666
667 m_hStatus = ::CreateWindow(STATUSCLASSNAME, _UC(""),
668 WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 10, 10, hWindow, NULL,
669 hInstance, 0);
670 statusBarSetParts(m_hStatus, 1, parts);
671 updateStatusText();
672 }
673
doClose(void)674 LRESULT ModelTreeDialog::doClose(void)
675 {
676 if (m_highlight)
677 {
678 m_modelWindow->getModelViewer()->setHighlightPaths("");
679 }
680 showWindow(SW_HIDE);
681 return 0;
682 }
683
doSize(WPARAM sizeType,int newWidth,int newHeight)684 LRESULT ModelTreeDialog::doSize(WPARAM sizeType, int newWidth, int newHeight)
685 {
686 if (sizeType != SIZE_MINIMIZED)
687 {
688 m_resizer->resize(newWidth, newHeight);
689 //positionResizeGrip(m_hResizeGrip, newWidth, newHeight);
690 SendMessage(m_hStatus, WM_SIZE, sizeType,
691 MAKELPARAM(newWidth, newHeight));
692 }
693 return CUIDialog::doSize(sizeType, newWidth, newHeight);
694 }
695
doTreeCustomDraw(LPNMTVCUSTOMDRAW notification)696 LRESULT ModelTreeDialog::doTreeCustomDraw(LPNMTVCUSTOMDRAW notification)
697 {
698 if (notification->nmcd.dwDrawStage == CDDS_PREPAINT)
699 {
700 SetWindowLongPtr(hWindow, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW);
701 return TRUE;
702 }
703 else if (notification->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
704 {
705 LDModelTree *itemTree = (LDModelTree *)notification->nmcd.lItemlParam;
706
707 if (itemTree)
708 {
709 TCByte r, g, b;
710
711 if ((notification->nmcd.uItemState & CDIS_SELECTED) == 0 &&
712 itemTree->getTextRGB(r, g, b))
713 {
714 notification->clrText = RGB(r, g, b);
715 }
716 SetWindowLongPtr(hWindow, DWLP_MSGRESULT, CDRF_DODEFAULT);
717 return TRUE;
718 }
719 }
720 return FALSE;
721 }
722
doTreeKeyDown(LPNMTVKEYDOWN notification)723 LRESULT ModelTreeDialog::doTreeKeyDown(LPNMTVKEYDOWN notification)
724 {
725 if (notification->wVKey == 'C' && (GetKeyState(VK_CONTROL) & 0x8000))
726 {
727 if (doTreeCopy())
728 {
729 return 0;
730 }
731 }
732 return 1;
733 }
734
doTreeCopy(void)735 BOOL ModelTreeDialog::doTreeCopy(void)
736 {
737 HTREEITEM hItem = TreeView_GetSelection(m_hTreeView);
738 LDModelTree *tree = getItemTree(hItem);
739
740 if (tree != NULL)
741 {
742 std::string text = tree->getText();
743
744 if (tree->getLineType() == LDLLineTypeEmpty)
745 {
746 text = "";
747 }
748 text += "\r\n";
749 if (copyToClipboard(text.c_str()))
750 {
751 SetWindowLongPtr(hWindow, DWLP_MSGRESULT, TRUE);
752 return TRUE;
753 }
754 }
755 return FALSE;
756 }
757
doOK(void)758 void ModelTreeDialog::doOK(void)
759 {
760 // Don't do anything.
761 }
762