dsrc isn't necessary for this repo
[client-tools.git] / src / external / 3rd / application / UiBuilder / WinMain.cpp
blob04454ed736c3b3708aae6a0f137c8939a9a206bc
1 #include "FirstUiBuilder.h"
3 #include "DDSCanvasGenerator.h"
4 #include "DefaultObjectPropertiesManager.h"
5 #include "DiffDialogBox.h"
6 #include "FileLocator.h"
7 #include "SetupUi.h"
8 #include "SimpleSoundCanvas.h"
9 #include "UIBuilderHistory.h"
10 #include "UIButton.h"
11 #include "UIButtonStyle.h"
12 #include "UICanvasGenerator.h"
13 #include "UICheckbox.h"
14 #include "UICheckboxStyle.h"
15 #include "UIClock.h"
16 #include "UIColorEffector.h"
17 #include "UIComboBox.h"
18 #include "UIComposite.h"
19 #include "UICursor.h"
20 #include "UICursorInterface.h"
21 #include "UICursorSet.h"
22 #include "UIData.h"
23 #include "UIDataSource.h"
24 #include "UIDataSourceContainer.h"
25 #include "UIDeformerHUD.h"
26 #include "UIDeformerRotate.h"
27 #include "UIDeformerWave.h"
28 #include "UIDirect3DPrimaryCanvas.h"
29 #include "UIDirect3dTextureCanvas.h"
30 #include "UIDropdownbox.h"
31 #include "UIDropdownboxStyle.h"
32 #include "UIEllipse.h"
33 #include "UIGrid.h"
34 #include "UIGridStyle.h"
35 #include "UIImage.h"
36 #include "UIImageStyle.h"
37 #include "UIList.h"
38 #include "UIListStyle.h"
39 #include "UIListbox.h"
40 #include "UIListboxStyle.h"
41 #include "UILoader.h"
42 #include "UILocationEffector.h"
43 #include "UIManager.h"
44 #include "UIMessage.h"
45 #include "UINamespace.h"
46 #include "UINullIMEManager.h"
47 #include "UIOpacityEffector.h"
48 #include "UIOutputStream.h"
49 #include "UIPage.h"
50 #include "UIPalette.h"
51 #include "UIPie.h"
52 #include "UIPieStyle.h"
53 #include "UIPopupMenu.h"
54 #include "UIPopupMenuStyle.h"
55 #include "UIProgressbar.h"
56 #include "UIProgressbarStyle.h"
57 #include "UIRadialMenu.h"
58 #include "UIRadialMenuStyle.h"
59 #include "UIRectangleStyle.h"
60 #include "UIRotationEffector.h"
61 #include "UIRunner.h"
62 #include "UISaver.h"
63 #include "UIScrollbar.h"
64 #include "UISizeEffector.h"
65 #include "UISliderbar.h"
66 #include "UISliderbarStyle.h"
67 #include "UISliderplane.h"
68 #include "UISliderplaneStyle.h"
69 #include "UITabSet.h"
70 #include "UITabSetStyle.h"
71 #include "UITabbedPane.h"
72 #include "UITabbedPaneStyle.h"
73 #include "UITable.h"
74 #include "UITableHeader.h"
75 #include "UITableModelDefault.h"
76 #include "UITemplate.h"
77 #include "UIText.h"
78 #include "UITextStyle.h"
79 #include "UITextStyleManager.h"
80 #include "UITextbox.h"
81 #include "UITextboxStyle.h"
82 #include "UITooltipStyle.h"
83 #include "UITreeView.h"
84 #include "UITreeViewStyle.h"
85 #include "UITypes.h"
86 #include "UIUnknown.h"
87 #include "UIUtils.h"
88 #include "UIVersion.h"
89 #include "UIVolumePage.h"
90 #include "objectinspector.h"
91 #include "resource.h"
93 #define INITGUID
94 #include "ddraw.h"
95 #include "d3d.h"
96 #undef INITGUID
98 #include <shlwapi.h>
99 #include <commctrl.h>
100 #include <sys/stat.h>
101 #include <sys/types.h>
102 #include <windowsx.h>
104 #include <list>
107 // This warning actually wants us to make code ... less readable...
108 //struct S { enum E { a }; };
109 //int i = S::E::a; // C4482
110 //int j = S::a; // OK
111 #pragma warning( disable : 4482 )
114 //----------------------------------------------------------------------
115 //-- this is a SWG hack to work with our modified STLPORT
117 enum MemoryManagerNotALeak
119 MM_notALeak
122 void * __cdecl operator new(size_t size, MemoryManagerNotALeak)
124 return operator new(size);
127 //----------------------------------------------------------------------
129 const char *gApplicationName = "UIBuilder";
130 const char *gNotImplemented = "This function is not yet implemented";
131 const char *gDefaultExtension = "ui";
132 const char *gFileFilter = "User Interface Files (.ui)\0ui_*.ui\0";
133 const char *gIncludeFileFilter = "User Interface Include Files (.inc)\0ui_*.inc\0";
134 bool g_showShaders = false;
136 HWND gObjectTree = 0;
137 HWND gTooltip = 0;
138 HWND gMainWindow = 0;
139 HHOOK gTooltipHook = 0;
141 extern HANDLE gFrameRenderingMutex;
143 UIDirect3DPrimaryCanvas *gPrimaryDisplay = 0;
144 ObjectInspector *gObjectInspector = 0;
145 DefaultObjectPropertiesManager gDefaultObjectPropertiesManager;
146 bool gVersionFilename = false;
148 UISize gOldSize(0,0);
149 UISize gInitialSize(0,0);
150 UINarrowString gFilename;
151 UINarrowString gInitialDirectory;
153 UIBaseObject::UISmartObjectList gClipboard;
155 typedef std::list<UINarrowString> MRUList;
156 MRUList gMRUList;
157 const int gMRUSize = 8;
159 extern HWND gUIWindow;
160 extern HWND gTabControlWindow;
161 extern bool gLimitFrameRate;
162 extern bool gInVisualEditingMode;
163 extern long gTriangleCount;
164 extern long gFlushCount;
165 extern long gFrameCount;
166 extern UIPage *gCurrentlySelectedPage;
167 extern UIBaseObject::UISmartObjectList gCurrentSelection;
169 // Selection highligt variables
170 extern bool gDrawHighlightRect;
171 extern UIColor gHighlightOutlineColor;
172 extern UIColor gHighlightFillColor;
174 // Grid variables
175 extern bool gDrawGrid;
176 extern bool gSnapToGrid;
177 extern unsigned long gXGridStep;
178 extern unsigned long gYGridStep;
179 extern unsigned long gGridMajorTicks;
181 extern bool gDrawCursor;
183 BOOL CALLBACK UIWindowDlgProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
184 BOOL CALLBACK GridSettingsDlgProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
185 BOOL CALLBACK HighlightSettingsDlgProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
186 BOOL CALLBACK ModificationLogDlgProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
187 BOOL CALLBACK ImportImageDlgProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
188 void SizeWindowToCurrentPageSelection( void );
189 void SetSelection( UIBaseObject *NewSelection, bool pushHistory );
190 bool RemoveFromSelection( const UIBaseObject *NewSelection);
191 void AddToSelection( UIBaseObject *ObjectToAdd, bool pushHistory );
193 HTREEITEM GetObjectInTreeControlFromHandle( HWND hTree, HTREEITEM hParentItem, UIBaseObject *o );
195 bool RenameSelectedObjectInTree( HWND hTree, const char * newName );
196 bool CloseWorkspaceFile( bool bLock = true );
199 // Undo stuff.
200 void recordUndo(UIBaseObject * const object, bool force = false);
201 void recordUndo(UIBaseObject * const object, UILowerString property, UIString oldValue, UIString newValue, bool force = false);
202 void undo();
203 void clearUndoHistory();
204 extern bool s_UndoReady;
205 extern bool volatile s_UndoQueueEmpty;
206 HMENU gMenu = NULL;
208 struct TreeItem
210 HTREEITEM mItem;
211 HTREEITEM mParent;
212 HTREEITEM mSibling;
215 typedef std::map<UIBaseObject * /*obj*/, TreeItem> TreeItemMap;
216 TreeItemMap s_TreeItemMap;
218 void addItemInfo(UIBaseObject * RootObject, HTREEITEM hItem, HTREEITEM hParent, HTREEITEM hSibling)
220 TreeItem newItem;
222 newItem.mItem = hItem;
223 newItem.mParent = hParent;
224 newItem.mSibling = hSibling;
226 s_TreeItemMap[ RootObject ] = newItem;
229 TreeItem const * getItemInfo(UIBaseObject * RootObject)
231 TreeItemMap::const_iterator itItem = s_TreeItemMap.find(RootObject);
233 if (itItem != s_TreeItemMap.end())
235 return &(itItem->second);
238 return NULL;
242 namespace
244 bool s_selectionPushOk = true;
246 typedef std::map<std::string, int> FileTimeMap;
247 FileTimeMap s_fileTimes;
249 WNDPROC mOldLabelEditWindowProc;
253 void CheckOutSelectedFile();
255 //-----------------------------------------------------------------
257 class UIBuilderLoader : public UILoader
259 public:
260 UIBuilderLoader( void ){ ReadOnlyFilesInInput = false; };
262 virtual bool LoadStringFromResource( const UINarrowString &ResourceName, UINarrowString &Out );
264 bool ReadOnlyFilesInInput;
267 //-----------------------------------------------------------------
269 bool UIBuilderLoader::LoadStringFromResource( const UINarrowString &ResourceName, UINarrowString &Out )
271 FILE *fp = fopen( ResourceName.c_str(), "rb+" );
273 if( !fp )
275 fp = fopen( ResourceName.c_str(), "rb" );
277 if( fp )
278 ReadOnlyFilesInInput = true;
279 else
280 return false;
283 struct _stat statbuf;
284 const int result = _stat (ResourceName.c_str (), &statbuf);
285 if (!result)
287 const int t = static_cast<int>(statbuf.st_mtime);
288 s_fileTimes [ResourceName] = t;
291 fseek( fp, 0, SEEK_END );
292 long len = ftell( fp );
293 fseek( fp, 0, SEEK_SET );
295 char *rawdata = new char[len];
296 fread( rawdata, len, 1, fp );
297 fclose( fp );
299 Out.assign( rawdata, len );
300 delete rawdata;
302 return true;
305 //-----------------------------------------------------------------
307 void SetMainWindowTitle( void )
309 if( gUIWindow )
311 char buffer[_MAX_PATH+1];
312 const char *filename = 0;
314 if( !gFilename.empty() )
315 filename = strrchr( gFilename.c_str(), '\\' );
317 if( filename )
318 sprintf( buffer, "[%s]", filename + 1 );
319 else
320 sprintf( buffer, "[Untitled]" );
322 SetWindowText( gUIWindow, buffer );
326 //-----------------------------------------------------------------
328 void AddTooltipFromControlID( HWND TooltipWindow, HWND ParentWindow, UINT ControlID, char *Tooltip )
330 TOOLINFO ti = {sizeof(ti)};
331 HWND hControl = GetDlgItem( ParentWindow, ControlID );
333 ti.uFlags = TTF_IDISHWND;
334 ti.hwnd = ParentWindow;
335 ti.uId = (UINT)hControl;
336 ti.hinst = GetModuleHandle(0);
337 ti.lpszText = Tooltip;
339 SendMessage( TooltipWindow, TTM_ADDTOOL, 0, (LPARAM)&ti );
343 //-----------------------------------------------------------------
345 static const char * s_drawGridKey = "drawGrid";
346 static const char * s_snapToGridKey = "snapToGrid";
347 static const char * s_drawHighlightRectKey = "drawHighlightRect";
348 static const char * s_highlightOutlineColorKey = "highlightOutlineColor";
349 static const char * s_highlightFillColorKey = "highlightFillColor";
350 static const char * s_xGridStepKey = "xGridStep";
351 static const char * s_yGridStepKey = "yGridStep";
352 static const char * s_gridMajorTicks = "gridMajorTicks";
353 static const char * s_inVisualEditingMode = "inVisualEditingMode";
354 static const char * s_showShadersKey = "showShaders";
355 static const char * s_regKey = "Software\\Sony Online Entertainment\\UIBuilder\\";
356 static const char * s_regKeyPreferences = "Software\\Sony Online Entertainment\\UIBuilder\\Preferences";
357 static const char * s_regKeyMRU = "Software\\Sony Online Entertainment\\UIBuilder\\MRUList";
359 //-----------------------------------------------------------------
361 void LoadPreferencesFromRegistry( void )
363 HKEY hKey = 0;
364 HRESULT hr;
366 hr = RegOpenKeyEx( HKEY_CURRENT_USER, s_regKeyPreferences, 0, KEY_ALL_ACCESS, &hKey );
368 if( hr == ERROR_SUCCESS )
370 //-- first load all numerics
371 DWORD dwThisIsLame;
372 DWORD dwMicrosoftSucks = sizeof (DWORD);
374 if ((hr = RegQueryValueEx( hKey, s_drawGridKey, 0, 0, reinterpret_cast<BYTE *>(&dwThisIsLame), &dwMicrosoftSucks)) == ERROR_SUCCESS)
375 gDrawGrid = dwThisIsLame != 0;
377 if ((hr = RegQueryValueEx( hKey, s_snapToGridKey, 0, 0, reinterpret_cast<BYTE *>(&dwThisIsLame), &dwMicrosoftSucks)) == ERROR_SUCCESS)
378 gSnapToGrid = dwThisIsLame != 0;
380 if ((hr = RegQueryValueEx( hKey, s_xGridStepKey, 0, 0, reinterpret_cast<BYTE *>(&dwThisIsLame), &dwMicrosoftSucks)) == ERROR_SUCCESS)
381 gXGridStep = dwThisIsLame;
383 if ((hr = RegQueryValueEx( hKey, s_yGridStepKey, 0, 0, reinterpret_cast<BYTE *>(&dwThisIsLame), &dwMicrosoftSucks)) == ERROR_SUCCESS)
384 gYGridStep = dwThisIsLame;
386 if ((hr = RegQueryValueEx( hKey, s_gridMajorTicks, 0, 0, reinterpret_cast<BYTE *>(&dwThisIsLame), &dwMicrosoftSucks)) == ERROR_SUCCESS)
387 gGridMajorTicks = dwThisIsLame;
389 if ((hr = RegQueryValueEx( hKey, s_drawHighlightRectKey, 0, 0, reinterpret_cast<BYTE *>(&dwThisIsLame), &dwMicrosoftSucks)) == ERROR_SUCCESS)
390 gDrawHighlightRect = dwThisIsLame != 0;
392 if ((hr = RegQueryValueEx( hKey, s_inVisualEditingMode, 0, 0, reinterpret_cast<BYTE *>(&dwThisIsLame), &dwMicrosoftSucks)) == ERROR_SUCCESS)
393 gInVisualEditingMode = dwThisIsLame != 0;
395 if ((hr = RegQueryValueEx( hKey, s_showShadersKey , 0, 0, reinterpret_cast<BYTE *>(&dwThisIsLame), &dwMicrosoftSucks)) == ERROR_SUCCESS)
396 g_showShaders = dwThisIsLame != 0;
398 //-- now load all strings
399 char buf[_MAX_PATH + 1];
400 dwMicrosoftSucks = sizeof( buf );
401 if ((hr = RegQueryValueEx( hKey, s_highlightOutlineColorKey, 0, 0, reinterpret_cast<BYTE *>(buf), &dwMicrosoftSucks)) == ERROR_SUCCESS)
403 UIUtils::ParseColorARGB (buf, gHighlightOutlineColor);
406 dwMicrosoftSucks = sizeof( buf );
407 if ((hr = RegQueryValueEx( hKey, s_highlightFillColorKey, 0, 0, reinterpret_cast<BYTE *>(buf), &dwMicrosoftSucks)) == ERROR_SUCCESS)
409 UIUtils::ParseColorARGB (buf, gHighlightFillColor);
412 RegCloseKey( hKey );
416 //-----------------------------------------------------------------
418 void SavePreferencesToRegistry( void )
420 HKEY hKey = 0;
421 DWORD dwAction;
422 HRESULT hr;
424 hr = RegCreateKeyEx( HKEY_CURRENT_USER, s_regKeyPreferences, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKey, &dwAction );
426 if( hr == ERROR_SUCCESS )
428 //-- first save all numerics
429 DWORD dwThisIsLame;
430 dwThisIsLame = gDrawGrid;
431 RegSetValueEx( hKey, s_drawGridKey, 0, REG_DWORD, reinterpret_cast<const BYTE*>(&dwThisIsLame), sizeof (DWORD));
433 dwThisIsLame = gSnapToGrid;
434 RegSetValueEx( hKey, s_snapToGridKey, 0, REG_DWORD, reinterpret_cast<const BYTE*>(&dwThisIsLame), sizeof (DWORD));
436 dwThisIsLame = gXGridStep;
437 RegSetValueEx( hKey, s_xGridStepKey, 0, REG_DWORD, reinterpret_cast<const BYTE*>(&dwThisIsLame), sizeof (DWORD));
439 dwThisIsLame = gYGridStep;
440 RegSetValueEx( hKey, s_yGridStepKey, 0, REG_DWORD, reinterpret_cast<const BYTE*>(&dwThisIsLame), sizeof (DWORD));
442 dwThisIsLame = gGridMajorTicks;
443 RegSetValueEx( hKey, s_gridMajorTicks, 0, REG_DWORD, reinterpret_cast<const BYTE*>(&dwThisIsLame), sizeof (DWORD));
445 dwThisIsLame = gDrawHighlightRect;
446 RegSetValueEx( hKey, s_drawHighlightRectKey, 0, REG_DWORD, reinterpret_cast<const BYTE*>(&dwThisIsLame), sizeof (DWORD));
448 dwThisIsLame = gInVisualEditingMode;
449 RegSetValueEx( hKey, s_inVisualEditingMode, 0, REG_DWORD, reinterpret_cast<const BYTE*>(&dwThisIsLame), sizeof (DWORD));
451 dwThisIsLame = g_showShaders;
452 RegSetValueEx( hKey, s_showShadersKey, 0, REG_DWORD, reinterpret_cast<const BYTE*>(&dwThisIsLame), sizeof (DWORD));
454 //-- now save all strings
455 UINarrowString colorResult;
457 UIUtils::FormatColorARGB (colorResult, gHighlightOutlineColor);
458 RegSetValueEx( hKey, s_highlightOutlineColorKey, 0, REG_SZ, reinterpret_cast<const BYTE*>(colorResult.c_str()), colorResult.length ());
460 UIUtils::FormatColorARGB (colorResult, gHighlightFillColor);
461 RegSetValueEx( hKey, s_highlightFillColorKey, 0, REG_SZ, reinterpret_cast<const BYTE*>(colorResult.c_str()), colorResult.length ());
463 RegCloseKey( hKey );
466 //-----------------------------------------------------------------
468 void LoadMRUListFromRegistry( void )
470 HKEY hKey = 0;
471 HRESULT hr;
473 hr = RegOpenKeyEx( HKEY_CURRENT_USER, s_regKeyMRU, 0, KEY_ALL_ACCESS, &hKey );
475 if( hr == ERROR_SUCCESS )
477 int CurrentFileID = 0;
479 for (;;)
481 char PathBuffer[_MAX_PATH + 1];
482 DWORD dwPathBufferSize = sizeof( PathBuffer );
483 char Buffer[128];
485 sprintf( Buffer, "MRU%d", CurrentFileID );
487 hr = RegQueryValueEx( hKey, Buffer, 0, 0, (LPBYTE)PathBuffer, &dwPathBufferSize );
489 if( hr != ERROR_SUCCESS )
490 break;
492 gMRUList.push_back( PathBuffer );
494 ++CurrentFileID;
497 RegCloseKey( hKey );
501 void SaveMRUListToRegistry( void )
503 HKEY hKey = 0;
504 DWORD dwAction;
505 HRESULT hr;
507 hr = RegCreateKeyEx( HKEY_CURRENT_USER, s_regKeyMRU, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKey, &dwAction );
509 if( hr == ERROR_SUCCESS )
511 int CurrentFileID = 0;
513 for (;;)
515 char Buffer[128];
516 sprintf( Buffer, "MRU%d", CurrentFileID );
518 hr = RegDeleteValue( hKey, Buffer );
520 if( hr != ERROR_SUCCESS )
521 break;
523 ++CurrentFileID;
526 CurrentFileID = 0;
528 for( MRUList::iterator i = gMRUList.begin(); i != gMRUList.end(); ++i )
530 char Buffer[128];
531 sprintf( Buffer, "MRU%d", CurrentFileID );
533 RegSetValueEx( hKey, Buffer, 0, REG_SZ, (LPBYTE)i->c_str(), i->size() );
534 ++CurrentFileID;
537 RegCloseKey( hKey );
541 //-----------------------------------------------------------------
543 void AddToMRUList( const char *Filename )
545 for( MRUList::iterator i = gMRUList.begin(); i != gMRUList.end(); ++i )
547 if( !_stricmp( i->c_str(), Filename ) )
549 gMRUList.erase( i );
550 break;
554 gMRUList.push_front( UINarrowString( Filename ) );
556 while( gMRUList.size() > gMRUSize )
557 gMRUList.pop_back();
560 //-----------------------------------------------------------------
562 void LoadMRUListToMenu( HMENU hMenu )
564 HMENU hFileMenu = GetSubMenu( hMenu, 0 );
565 HMENU hMRUList = 0;
566 int nItems = GetMenuItemCount( hFileMenu );
568 for( int i = 0; i < nItems; ++i )
570 char Buffer[256];
571 MENUITEMINFO mii;
573 mii.cbSize = sizeof( mii );
574 mii.fMask = MIIM_TYPE;
575 mii.dwTypeData = Buffer;
576 mii.cch = sizeof( Buffer );
578 GetMenuItemInfo( hFileMenu, i, TRUE, &mii );
580 if( !_stricmp( Buffer, "Recent &Files" ) )
582 hMRUList = GetSubMenu( hFileMenu, i );
583 break;
587 if( hMRUList )
589 int ItemCount = 1;
591 while( GetMenuItemCount( hMRUList ) > 0 )
592 DeleteMenu( hMRUList, 0, MF_BYPOSITION );
594 if( gMRUList.empty() )
595 AppendMenu( hMRUList, MF_GRAYED | MF_STRING, 0xFFFF, "(Empty)" );
596 else
598 for( MRUList::iterator i = gMRUList.begin(); i != gMRUList.end(); ++i )
600 AppendMenu( hMRUList, MF_ENABLED | MF_STRING, 0xFFFF - ItemCount, i->c_str() );
601 ++ItemCount;
606 DrawMenuBar( gMainWindow );
609 //-----------------------------------------------------------------
611 void EnableMenuItems( HMENU hMenu, UIBaseObject *SelectedObject )
613 UINT NewState;
615 if( SelectedObject )
616 NewState = MF_BYCOMMAND | MF_ENABLED;
617 else
618 NewState = MF_BYCOMMAND | MF_GRAYED;
620 EnableMenuItem( hMenu, ID_INSERT_BUTTON , NewState );
621 EnableMenuItem( hMenu, ID_INSERT_CHECKBIOX , NewState );
622 EnableMenuItem( hMenu, ID_INSERT_DATASOURCE , NewState );
623 EnableMenuItem( hMenu, ID_INSERT_DATASOURCECONTAINER , NewState );
624 EnableMenuItem( hMenu, ID_INSERT_DATAITEM , NewState );
625 EnableMenuItem( hMenu, ID_INSERT_DROPDOWNBOX , NewState );
626 EnableMenuItem( hMenu, ID_INSERT_ELLIPSE , NewState );
627 EnableMenuItem( hMenu, ID_INSERT_GRID , NewState );
628 EnableMenuItem( hMenu, ID_INSERT_IMAGE , NewState );
629 EnableMenuItem( hMenu, ID_INSERT_IMAGEFRAME , NewState );
630 EnableMenuItem( hMenu, ID_INSERT_LISTBOX , NewState );
631 EnableMenuItem( hMenu, ID_INSERT_LIST , NewState );
632 EnableMenuItem( hMenu, ID_INSERT_TREEVIEW , NewState );
633 EnableMenuItem( hMenu, ID_INSERT_COMBOBOX , NewState );
634 EnableMenuItem( hMenu, ID_INSERT_NAMESPACE , NewState );
635 EnableMenuItem( hMenu, ID_INSERT_TEXTBOX , NewState );
636 EnableMenuItem( hMenu, ID_INSERT_SCROLLBAR , NewState );
637 EnableMenuItem( hMenu, ID_INSERT_SLIDERBAR , NewState );
638 EnableMenuItem( hMenu, ID_INSERT_SLIDERPLANE , NewState );
639 EnableMenuItem( hMenu, ID_INSERT_TABSET , NewState );
640 EnableMenuItem( hMenu, ID_INSERT_TABBEDPANE , NewState );
641 EnableMenuItem( hMenu, ID_INSERT_POPUPMENU , NewState );
642 EnableMenuItem( hMenu, ID_INSERT_RADIALMENU , NewState );
643 EnableMenuItem( hMenu, ID_INSERT_VOLUMEPAGE , NewState );
644 EnableMenuItem( hMenu, ID_INSERT_CURSORSET , NewState );
645 EnableMenuItem( hMenu, ID_INSERT_TABLE , NewState );
646 EnableMenuItem( hMenu, ID_INSERT_TABLEMODELDEFAULT, NewState );
647 EnableMenuItem( hMenu, ID_INSERT_TABLEHEADER, NewState );
649 EnableMenuItem( hMenu, ID_INSERT_STATICTEXT , NewState );
650 EnableMenuItem( hMenu, ID_INSERT_TEMPLATE , NewState );
651 EnableMenuItem( hMenu, ID_INSERT_PAGE , NewState );
652 EnableMenuItem( hMenu, ID_INSERT_COMPOSITE , NewState );
653 EnableMenuItem( hMenu, ID_INSERT_PROGRESSBAR , NewState );
654 EnableMenuItem( hMenu, ID_INSERT_CURSOR , NewState );
655 EnableMenuItem( hMenu, ID_INSERT_CLOCK , NewState );
656 EnableMenuItem( hMenu, ID_INSERT_APPLICATIONOBJECT, NewState );
658 EnableMenuItem( hMenu, ID_INSERT_STYLE_BUTTON , NewState );
659 EnableMenuItem( hMenu, ID_INSERT_STYLE_CHECKBOX , NewState );
660 EnableMenuItem( hMenu, ID_INSERT_STYLE_DROPDOWNBOX, NewState );
661 EnableMenuItem( hMenu, ID_INSERT_STYLE_GRID , NewState );
662 EnableMenuItem( hMenu, ID_INSERT_STYLE_IMAGE , NewState );
663 EnableMenuItem( hMenu, ID_INSERT_STYLE_LISTBOX , NewState );
664 EnableMenuItem( hMenu, ID_INSERT_STYLE_LIST , NewState );
665 EnableMenuItem( hMenu, ID_INSERT_STYLE_TREEVIEW , NewState );
666 EnableMenuItem( hMenu, ID_INSERT_STYLE_PROGRESSBAR, NewState );
667 EnableMenuItem( hMenu, ID_INSERT_STYLE_SLIDERBAR , NewState );
668 EnableMenuItem( hMenu, ID_INSERT_STYLE_TEXT , NewState );
669 EnableMenuItem( hMenu, ID_INSERT_STYLE_TEXTBOX , NewState );
670 EnableMenuItem( hMenu, ID_INSERT_STYLE_TOOLTIP , NewState );
671 EnableMenuItem( hMenu, ID_INSERT_STYLE_RECTANGLE , NewState );
672 EnableMenuItem( hMenu, ID_INSERT_STYLE_TABSET , NewState );
673 EnableMenuItem( hMenu, ID_INSERT_STYLE_TABBEDPANE , NewState );
674 EnableMenuItem( hMenu, ID_INSERT_STYLE_POPUPMENU , NewState );
675 EnableMenuItem( hMenu, ID_INSERT_STYLE_RADIALMENU , NewState );
677 EnableMenuItem( hMenu, ID_INSERT_EFFECTOR_COLOR , NewState );
678 EnableMenuItem( hMenu, ID_INSERT_EFFECTOR_ROTATION , NewState );
679 EnableMenuItem( hMenu, ID_INSERT_EFFECTOR_LOCATION , NewState );
680 EnableMenuItem( hMenu, ID_INSERT_EFFECTOR_OPACITY , NewState );
681 EnableMenuItem( hMenu, ID_INSERT_EFFECTOR_SIZE , NewState );
682 EnableMenuItem( hMenu, ID_INSERT_DEFORMER_HUD , NewState );
683 EnableMenuItem( hMenu, ID_INSERT_DEFORMER_WAVE , NewState );
684 EnableMenuItem( hMenu, ID_INSERT_DEFORMER_ROTATE , NewState );
686 EnableMenuItem( hMenu, ID_FILE_IMPORT, NewState );
688 if( gClipboard.empty() && (GetFocus() != gObjectInspector->GetTextControl()) )
689 EnableMenuItem( hMenu, ID_EDIT_PASTE, MF_BYCOMMAND | MF_GRAYED );
690 else
691 EnableMenuItem( hMenu, ID_EDIT_PASTE, MF_BYCOMMAND | MF_ENABLED );
693 if(!SelectedObject || SelectedObject->GetChildCount () == 0)
695 EnableMenuItem( hMenu, ID_EDIT_SORT, MF_BYCOMMAND | MF_GRAYED );
697 else
699 EnableMenuItem( hMenu, ID_EDIT_SORT, MF_BYCOMMAND | MF_ENABLED );
703 UIPage *RootPage = UIManager::gUIManager().GetRootPage();
705 if( !SelectedObject || SelectedObject == RootPage )
707 EnableMenuItem( hMenu, ID_EDIT_DELETE, MF_BYCOMMAND | MF_GRAYED );
708 EnableMenuItem( hMenu, ID_EDIT_DUPLICATE, MF_BYCOMMAND | MF_GRAYED );
709 EnableMenuItem( hMenu, ID_FILE_EXPORT, MF_BYCOMMAND | MF_GRAYED );
710 EnableMenuItem( hMenu, ID_EDIT_CUT, MF_BYCOMMAND | MF_GRAYED );
711 EnableMenuItem( hMenu, ID_EDIT_COPY, MF_BYCOMMAND | MF_GRAYED );
713 else
715 EnableMenuItem( hMenu, ID_EDIT_DELETE, MF_BYCOMMAND | MF_ENABLED );
716 EnableMenuItem( hMenu, ID_EDIT_DUPLICATE, MF_BYCOMMAND | MF_ENABLED );
717 EnableMenuItem( hMenu, ID_FILE_EXPORT, MF_BYCOMMAND | MF_ENABLED );
718 EnableMenuItem( hMenu, ID_EDIT_CUT, MF_BYCOMMAND | MF_ENABLED );
719 EnableMenuItem( hMenu, ID_EDIT_COPY, MF_BYCOMMAND | MF_ENABLED );
722 if( RootPage )
724 EnableMenuItem( hMenu, ID_FILE_CLOSE, MF_BYCOMMAND | MF_ENABLED );
725 EnableMenuItem( hMenu, ID_FILE_SAVE, MF_BYCOMMAND | MF_ENABLED );
726 EnableMenuItem( hMenu, ID_FILE_SAVEAS, MF_BYCOMMAND | MF_ENABLED );
728 EnableMenuItem( hMenu, ID_VIEW_RUN, MF_BYCOMMAND | MF_ENABLED );
729 EnableMenuItem( hMenu, ID_VIEW_CURSOR, MF_BYCOMMAND | MF_ENABLED );
730 EnableMenuItem( hMenu, ID_VIEW_HIGHLIGHT, MF_BYCOMMAND | MF_ENABLED );
731 EnableMenuItem( hMenu, ID_VIEW_GRID, MF_BYCOMMAND | MF_ENABLED );
732 EnableMenuItem( hMenu, ID_VIEW_SHOWSHADERS, MF_BYCOMMAND | MF_ENABLED );
734 else
736 EnableMenuItem( hMenu, ID_FILE_CLOSE, MF_BYCOMMAND | MF_GRAYED );
737 EnableMenuItem( hMenu, ID_FILE_SAVE, MF_BYCOMMAND | MF_GRAYED );
738 EnableMenuItem( hMenu, ID_FILE_SAVEAS, MF_BYCOMMAND | MF_GRAYED );
740 EnableMenuItem( hMenu, ID_VIEW_RUN, MF_BYCOMMAND | MF_GRAYED );
741 EnableMenuItem( hMenu, ID_VIEW_CURSOR, MF_BYCOMMAND | MF_GRAYED );
742 EnableMenuItem( hMenu, ID_VIEW_HIGHLIGHT, MF_BYCOMMAND | MF_GRAYED );
743 EnableMenuItem( hMenu, ID_VIEW_GRID, MF_BYCOMMAND | MF_GRAYED );
744 EnableMenuItem( hMenu, ID_VIEW_SHOWSHADERS, MF_BYCOMMAND | MF_GRAYED );
747 if( gInVisualEditingMode )
748 CheckMenuItem( hMenu, ID_VIEW_RUN, MF_BYCOMMAND | MF_UNCHECKED );
749 else
750 CheckMenuItem( hMenu, ID_VIEW_RUN, MF_BYCOMMAND | MF_CHECKED );
752 if( gDrawCursor )
753 CheckMenuItem( hMenu, ID_VIEW_CURSOR, MF_BYCOMMAND | MF_CHECKED );
754 else
755 CheckMenuItem( hMenu, ID_VIEW_CURSOR, MF_BYCOMMAND | MF_UNCHECKED );
757 if( gDrawHighlightRect )
758 CheckMenuItem( hMenu, ID_VIEW_HIGHLIGHT, MF_BYCOMMAND | MF_CHECKED );
759 else
760 CheckMenuItem( hMenu, ID_VIEW_HIGHLIGHT, MF_BYCOMMAND | MF_UNCHECKED );
762 if( gDrawGrid )
763 CheckMenuItem( hMenu, ID_VIEW_GRID, MF_BYCOMMAND | MF_CHECKED );
764 else
765 CheckMenuItem( hMenu, ID_VIEW_GRID, MF_BYCOMMAND | MF_UNCHECKED );
767 WaitForSingleObject( gFrameRenderingMutex, INFINITE );
768 g_showShaders = gPrimaryDisplay->GetShowShaders();
769 ReleaseMutex( gFrameRenderingMutex );
771 if( g_showShaders )
772 CheckMenuItem( hMenu, ID_VIEW_SHOWSHADERS, MF_BYCOMMAND | MF_CHECKED );
773 else
774 CheckMenuItem( hMenu, ID_VIEW_SHOWSHADERS, MF_BYCOMMAND | MF_UNCHECKED );
777 //-----------------------------------------------------------------
779 void EnableHistoryButtons ()
781 EnableWindow( GetDlgItem( gMainWindow, IDC_BUTTON_BACK ), UIBuilderHistory::backValid ());
782 EnableWindow( GetDlgItem( gMainWindow, IDC_BUTTON_FORWARD ), UIBuilderHistory::forwardValid ());
783 EnableWindow( GetDlgItem( gMainWindow, IDC_BUTTON_BACK ), true);
786 //-----------------------------------------------------------------
788 void EnableButtonControls( HWND mParent, UIBaseObject *SelectedObject )
790 BOOL bEnableUp = FALSE;
791 BOOL bEnableTop = FALSE;
792 BOOL bEnableDown = FALSE;
793 BOOL bEnableBottom = FALSE;
795 if( SelectedObject )
797 UIBaseObject *ObjectParent = SelectedObject->GetParent();
799 if( ObjectParent )
801 if( ObjectParent->CanChildMove( SelectedObject, UIBaseObject::ChildMovementDirection::Up ) )
802 bEnableUp = TRUE;
803 if( ObjectParent->CanChildMove( SelectedObject, UIBaseObject::ChildMovementDirection::Top ) )
804 bEnableTop = TRUE;
805 if( ObjectParent->CanChildMove( SelectedObject, UIBaseObject::ChildMovementDirection::Down ) )
806 bEnableDown = TRUE;
807 if( ObjectParent->CanChildMove( SelectedObject, UIBaseObject::ChildMovementDirection::Bottom ) )
808 bEnableBottom = TRUE;
812 EnableWindow( GetDlgItem( mParent, IDC_UP ), bEnableUp );
813 EnableWindow( GetDlgItem( mParent, IDC_TOP ), bEnableTop );
814 EnableWindow( GetDlgItem( mParent, IDC_DOWN ), bEnableDown );
815 EnableWindow( GetDlgItem( mParent, IDC_BOTTOM ), bEnableBottom );
817 if(gCurrentSelection.size() == 2)
819 EnableMenuItem(gMenu, ID_EDIT_DIFF, MF_BYCOMMAND | MF_ENABLED);
821 else
823 EnableMenuItem(gMenu, ID_EDIT_DIFF, MF_BYCOMMAND | MF_GRAYED);
827 //-----------------------------------------------------------------
829 void ClearDefPushButtonLook( HWND hwndDlg, UINT nControlID )
831 SetWindowLong( GetDlgItem( hwndDlg, nControlID ), GWL_STYLE,
832 GetWindowLong( GetDlgItem( hwndDlg, nControlID ), GWL_STYLE ) & ~BS_DEFPUSHBUTTON );
835 //-----------------------------------------------------------------
837 LRESULT CALLBACK LabelEditWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
839 if( (uMsg == WM_CHAR) && (wParam == VK_RETURN))
841 TreeView_EndEditLabelNow(gObjectTree, false);
842 return false;
844 else if( (uMsg == WM_KEYUP) && (wParam == VK_RETURN))
846 TreeView_EndEditLabelNow(gObjectTree, false);
847 return false;
849 return CallWindowProc( mOldLabelEditWindowProc, hwnd, uMsg, wParam, lParam );
852 //-----------------------------------------------------------------
854 typedef struct
856 UINT SortCommand;
857 LPARAM hItemToSort;
858 LPARAM hReferenceItem;
859 } TreeSortParams;
861 //-----------------------------------------------------------------
863 int CALLBACK TreeSortCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
865 TreeSortParams *p = (TreeSortParams *)lParamSort;
867 switch( p->SortCommand )
869 case IDC_UP:
870 if( (lParam1 == p->hItemToSort) && (lParam2 == p->hReferenceItem) )
871 return -1;
872 else if( (lParam2 == p->hItemToSort) && (lParam1 == p->hReferenceItem) )
873 return 1;
874 else
875 return 0;
877 case IDC_TOP:
878 if( lParam1 == p->hItemToSort )
879 return -1;
880 else if( lParam2 == p->hItemToSort )
881 return 1;
882 else
883 return 0;
885 case IDC_DOWN:
886 if( (lParam1 == p->hItemToSort) && (lParam2 == p->hReferenceItem) )
887 return 1;
888 else if( (lParam2 == p->hItemToSort) && (lParam1 == p->hReferenceItem) )
889 return -1;
890 else
891 return 0;
893 case IDC_BOTTOM:
894 if( lParam1 == p->hItemToSort )
895 return 1;
896 else if( lParam2 == p->hItemToSort )
897 return -1;
898 else
899 return 0;
901 default:
902 return 0;
906 //-----------------------------------------------------------------
908 void ProcessReorderButtonEvent( HWND hTree, HTREEITEM hSelection, UINT Command )
910 if( hSelection )
912 UIBaseObject *SelectedObject;
913 UIBaseObject *ParentObject;
914 TVITEM tvi;
916 tvi.mask = TVIF_HANDLE | TVIF_PARAM;
917 tvi.hItem = hSelection;
918 TreeView_GetItem( hTree, &tvi );
920 if( !tvi.lParam )
921 return;
923 WaitForSingleObject( gFrameRenderingMutex, INFINITE );
925 SelectedObject = reinterpret_cast<UIBaseObject *>( tvi.lParam );
926 ParentObject = SelectedObject->GetParent();
928 if( ParentObject )
930 bool ReSortNeeded = false;
931 TreeSortParams tsp;
933 tsp.SortCommand = Command;
934 tsp.hItemToSort = tvi.lParam;
936 if( Command == IDC_UP )
938 if( ParentObject->MoveChild( SelectedObject, UIBaseObject::ChildMovementDirection::Up ) )
940 tvi.hItem = TreeView_GetPrevSibling( hTree, hSelection );
941 TreeView_GetItem( hTree, &tvi );
942 tsp.hReferenceItem = tvi.lParam;
943 ReSortNeeded = true;
946 else if( Command == IDC_TOP )
948 if( ParentObject->MoveChild( SelectedObject, UIBaseObject::ChildMovementDirection::Top ) )
949 ReSortNeeded = true;
951 else if( Command == IDC_DOWN )
953 if( ParentObject->MoveChild( SelectedObject, UIBaseObject::ChildMovementDirection::Down ) )
955 tvi.hItem = TreeView_GetNextSibling( hTree, hSelection );
956 TreeView_GetItem( hTree, &tvi );
957 tsp.hReferenceItem = tvi.lParam;
958 ReSortNeeded = true;
961 else if( Command == IDC_BOTTOM )
963 if( ParentObject->MoveChild( SelectedObject, UIBaseObject::ChildMovementDirection::Bottom ) )
964 ReSortNeeded = true;
967 if( ReSortNeeded )
969 TVSORTCB tvscb;
971 tvscb.hParent = TreeView_GetParent( hTree, hSelection );
972 tvscb.lParam = (LPARAM)&tsp;
973 tvscb.lpfnCompare = TreeSortCompareFunc;
975 TreeView_SortChildrenCB( hTree, &tvscb, FALSE );
976 TreeView_EnsureVisible( hTree, hSelection );
978 ReleaseMutex( gFrameRenderingMutex );
983 //-----------------------------------------------------------------
985 UIBaseObject *GetObjectFromNode( HTREEITEM hItem )
987 TVITEM tvi;
989 tvi.mask = TVIF_HANDLE | TVIF_PARAM;
990 tvi.hItem = hItem;
991 tvi.lParam = 0;
993 TreeView_GetItem( gObjectTree, &tvi );
994 return reinterpret_cast<UIBaseObject *>( tvi.lParam );
997 //-----------------------------------------------------------------
999 UIBaseObject *GetSelectedObjectInTreeControl( void )
1001 HTREEITEM hSelection = TreeView_GetSelection( gObjectTree );
1002 UIBaseObject *SelectedObject = 0;
1004 if( hSelection )
1005 SelectedObject = GetObjectFromNode( hSelection );
1007 return SelectedObject;
1010 //-----------------------------------------------------------------
1012 HTREEITEM LoadObjectStructureToTreeControl( HWND hTree, UIBaseObject * const RootObject, HTREEITEM hParent, HTREEITEM hInsertAfter)
1014 HTREEITEM hItem = 0;
1016 if( !hParent )
1017 SendMessage( hTree, WM_SETREDRAW, 0, 0 );
1019 if( !RootObject->IsA( TUICanvas ) )
1021 TVINSERTSTRUCT tvis;
1023 tvis.hParent = hParent;
1024 tvis.hInsertAfter = hInsertAfter;
1025 tvis.item.mask = TVIF_CHILDREN | TVIF_HANDLE | TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
1026 tvis.item.pszText = LPSTR_TEXTCALLBACK;
1027 tvis.item.iImage = I_IMAGECALLBACK;
1028 tvis.item.iSelectedImage = I_IMAGECALLBACK;
1029 tvis.item.cChildren = I_CHILDRENCALLBACK;
1030 tvis.item.lParam = (DWORD)RootObject;
1032 hItem = TreeView_InsertItem( hTree, &tvis );
1034 // Reverse lookup info. RLS - move this to a ! property.
1035 HTREEITEM hSibling = TreeView_GetPrevSibling(hTree, hItem);
1036 if (!hSibling)
1038 hSibling = TreeView_GetNextSibling(hTree, hItem);
1040 addItemInfo(RootObject, hItem, hParent, hSibling);
1042 UIBaseObject::UIObjectList ol;
1043 RootObject->GetChildren( ol );
1045 for( UIBaseObject::UIObjectList::const_iterator i = ol.begin(); i != ol.end(); ++i )
1047 if ((*i)->IsA (TUIWidget))
1048 if (static_cast<UIWidget *>(*i)->IsTransient ())
1049 continue;
1051 LoadObjectStructureToTreeControl( hTree, *i, hItem, TVI_LAST );
1054 if( !hParent)
1055 TreeView_Expand( hTree, hItem, TVE_EXPAND );
1058 if (!hParent)
1060 SendMessage( hTree, WM_SETREDRAW, 1, 0 );
1061 InvalidateRect( hTree, 0, TRUE );
1064 return hItem;
1067 //-----------------------------------------------------------------
1069 void LoadTopLevelObjectsToTabControl( void )
1071 UIPage *RootPage = UIManager::gUIManager().GetRootPage();
1073 TabCtrl_DeleteAllItems( gTabControlWindow );
1075 if( RootPage )
1077 int TabIndex = 0;
1078 UIBaseObject::UIObjectList TopLevelPages;
1080 RootPage->GetChildren( TopLevelPages );
1082 for( UIBaseObject::UIObjectList::iterator i = TopLevelPages.begin(); i != TopLevelPages.end(); ++i )
1084 if( (*i)->IsA( TUIPage ) )
1086 TCITEM tci;
1088 tci.mask = TCIF_PARAM | TCIF_TEXT;
1089 tci.lParam = reinterpret_cast<DWORD>( *i );
1091 if( !tci.lParam )
1092 continue;
1094 const UINarrowString &Name = (*i)->GetName();
1095 // windows bug requires const_cast here
1096 tci.pszText = const_cast<char *>( Name.c_str() );
1097 TabCtrl_InsertItem( gTabControlWindow, TabIndex, &tci );
1098 TabIndex++;
1102 if( TabIndex > 0 )
1104 TabCtrl_SetCurSel( gTabControlWindow, 0 );
1105 SizeWindowToCurrentPageSelection();
1110 //-----------------------------------------------------------------
1112 BOOL CALLBACK CreatePageDlgProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
1114 UI_UNREF (lParam);
1116 switch( uMsg )
1118 case WM_INITDIALOG:
1119 CheckRadioButton( hwndDlg, IDC_PARENT, IDC_NEWFILE, IDC_PARENT );
1120 EnableWindow( GetDlgItem( hwndDlg, IDC_PAGEFILE ), FALSE );
1121 return TRUE;
1123 case WM_CLOSE:
1124 // Equivalent to pressing cancel
1125 EndDialog( hwndDlg, 0 );
1126 return 0;
1128 case WM_COMMAND:
1129 if( LOWORD( wParam ) == IDOK )
1131 UIPage *thePage = new UIPage;
1133 if( IsDlgButtonChecked( hwndDlg, IDC_NEWFILE ) )
1135 long BufferLength = SendDlgItemMessage( hwndDlg, IDC_PAGEFILE, WM_GETTEXTLENGTH, 0, 0 ) + 1;
1136 char *Buffer = new char[BufferLength];
1138 GetDlgItemText( hwndDlg, IDC_PAGEFILE, Buffer, BufferLength );
1140 thePage->SetProperty( UIBaseObject::PropertyName::SourceFile, UIUnicode::narrowToWide( Buffer ) );
1142 EndDialog( hwndDlg, (long)thePage );
1144 else if( LOWORD( wParam ) == IDCANCEL )
1145 EndDialog( hwndDlg, 0 );
1146 else if( HIWORD( wParam ) == BN_CLICKED )
1148 if( IsDlgButtonChecked( hwndDlg, IDC_NEWFILE ) )
1149 EnableWindow( GetDlgItem( hwndDlg, IDC_PAGEFILE ), TRUE );
1150 else
1151 EnableWindow( GetDlgItem( hwndDlg, IDC_PAGEFILE ), FALSE );
1153 return 0;
1155 default:
1156 return 0;
1160 //-----------------------------------------------------------------
1162 void InsertNewUIObject( int MenuID )
1164 UIPage *RootPage = UIManager::gUIManager().GetRootPage();
1165 UIBaseObject *NewObject = 0;
1167 assert( RootPage );
1169 switch( MenuID )
1171 case ID_INSERT_BUTTON:
1172 NewObject = new UIButton;
1173 break;
1174 case ID_INSERT_CHECKBOX:
1175 NewObject = new UICheckbox;
1176 break;
1177 case ID_INSERT_DATASOURCE:
1178 NewObject = new UIDataSource;
1179 break;
1180 case ID_INSERT_DATASOURCECONTAINER:
1181 NewObject = new UIDataSourceContainer;
1182 break;
1183 case ID_INSERT_DATAITEM:
1184 NewObject = new UIData;
1185 break;
1186 case ID_INSERT_DROPDOWNBOX:
1187 NewObject = new UIDropdownbox;
1188 break;
1189 case ID_INSERT_ELLIPSE:
1190 NewObject = new UIEllipse;
1191 break;
1192 case ID_INSERT_IMAGE:
1193 NewObject = new UIImage;
1194 break;
1195 case ID_INSERT_GRID:
1196 NewObject = new UIGrid;
1197 break;
1198 case ID_INSERT_IMAGEFRAME:
1199 NewObject = reinterpret_cast<UIBaseObject *>( DialogBox( GetModuleHandle(0),
1200 MAKEINTRESOURCE(IDD_IMPORTIMAGE), gMainWindow, ImportImageDlgProc) );
1202 if( NewObject == reinterpret_cast<UIBaseObject *>( -1 ) )
1203 NewObject = 0;
1205 break;
1206 case ID_INSERT_LISTBOX:
1207 NewObject = new UIListbox;
1208 break;
1209 case ID_INSERT_LIST:
1210 NewObject = new UIList;
1211 break;
1212 case ID_INSERT_TREEVIEW:
1213 NewObject = new UITreeView;
1214 break;
1215 case ID_INSERT_PIE:
1216 NewObject = new UIPie;
1217 break;
1218 case ID_INSERT_RUNNER:
1219 NewObject = new UIRunner;
1220 break;
1221 case ID_INSERT_COMBOBOX:
1222 NewObject = new UIComboBox;
1223 break;
1224 case ID_INSERT_NAMESPACE:
1225 NewObject = new UINamespace;
1226 break;
1227 case ID_INSERT_TEXTBOX:
1228 NewObject = new UITextbox;
1229 break;
1230 case ID_INSERT_SCROLLBAR:
1231 NewObject = new UIScrollbar;
1232 break;
1233 case ID_INSERT_SLIDERBAR:
1234 NewObject = new UISliderbar;
1235 break;
1236 case ID_INSERT_SLIDERPLANE:
1237 NewObject = new UISliderplane;
1238 break;
1239 case ID_INSERT_TABSET:
1240 NewObject = new UITabSet;
1241 break;
1242 case ID_INSERT_TABBEDPANE:
1243 NewObject = new UITabbedPane;
1244 break;
1245 case ID_INSERT_POPUPMENU:
1246 NewObject = new UIPopupMenu;
1247 break;
1248 case ID_INSERT_RADIALMENU:
1249 NewObject = new UIRadialMenu;
1250 break;
1251 case ID_INSERT_CURSORSET:
1252 NewObject = new UICursorSet;
1253 break;
1254 case ID_INSERT_VOLUMEPAGE:
1255 NewObject = new UIVolumePage;
1256 break;
1257 case ID_INSERT_STATICTEXT:
1258 NewObject = new UIText;
1259 break;
1260 case ID_INSERT_TEMPLATE:
1261 NewObject = new UITemplate;
1262 break;
1263 case ID_INSERT_PAGE:
1265 NewObject = reinterpret_cast<UIBaseObject *>( DialogBox( GetModuleHandle(0),
1266 MAKEINTRESOURCE(IDD_PAGEFILE), gMainWindow, CreatePageDlgProc) );
1268 if( NewObject == reinterpret_cast<UIBaseObject *>( -1 ) )
1269 NewObject = 0;
1271 break;
1273 case ID_INSERT_COMPOSITE:
1274 NewObject = new UIComposite;
1275 break;
1276 case ID_INSERT_TABLE:
1277 NewObject = new UITable;
1278 break;
1279 case ID_INSERT_TABLEMODELDEFAULT:
1280 NewObject = new UITableModelDefault;
1281 break;
1282 case ID_INSERT_TABLEHEADER:
1283 NewObject = new UITableHeader;
1284 break;
1286 case ID_INSERT_PROGRESSBAR:
1287 NewObject = new UIProgressbar;
1288 break;
1289 case ID_INSERT_CURSOR:
1290 NewObject = new UICursor;
1291 break;
1292 case ID_INSERT_CLOCK:
1293 NewObject = new UIClock;
1294 break;
1295 case ID_INSERT_APPLICATIONOBJECT:
1296 NewObject = new UIUnknown;
1297 break;
1298 case ID_INSERT_STYLE_BUTTON:
1299 NewObject = new UIButtonStyle;
1300 break;
1301 case ID_INSERT_STYLE_CHECKBOX:
1302 NewObject = new UICheckboxStyle;
1303 break;
1304 case ID_INSERT_STYLE_GRID:
1305 NewObject = new UIGridStyle;
1306 break;
1307 case ID_INSERT_STYLE_IMAGE:
1308 NewObject = new UIImageStyle;
1309 break;
1310 case ID_INSERT_STYLE_LISTBOX:
1311 NewObject = new UIListboxStyle;
1312 break;
1313 case ID_INSERT_STYLE_LIST:
1314 NewObject = new UIListStyle;
1315 break;
1316 case ID_INSERT_STYLE_TREEVIEW:
1317 NewObject = new UITreeViewStyle;
1318 break;
1319 case ID_INSERT_STYLE_PIE:
1320 NewObject = new UIPieStyle;
1321 break;
1322 case ID_INSERT_STYLE_PALETTE:
1323 NewObject = new UIPalette;
1324 break;
1325 case ID_INSERT_STYLE_TEXTBOX:
1326 NewObject = new UITextboxStyle;
1327 break;
1328 case ID_INSERT_STYLE_TEXT:
1329 NewObject = new UITextStyle;
1330 break;
1331 case ID_INSERT_STYLE_PROGRESSBAR:
1332 NewObject = new UIProgressbarStyle;
1333 break;
1334 case ID_INSERT_STYLE_DROPDOWNBOX:
1335 NewObject = new UIDropdownboxStyle;
1336 break;
1337 case ID_INSERT_STYLE_SLIDERBAR:
1338 NewObject = new UISliderbarStyle;
1339 break;
1340 case ID_INSERT_STYLE_TOOLTIP:
1341 NewObject = new UITooltipStyle;
1342 break;
1343 case ID_INSERT_STYLE_RECTANGLE:
1344 NewObject = new UIRectangleStyle;
1345 break;
1346 case ID_INSERT_STYLE_TABSET:
1347 NewObject = new UITabSetStyle;
1348 break;
1349 case ID_INSERT_STYLE_TABBEDPANE:
1350 NewObject = new UITabbedPaneStyle;
1351 break;
1352 case ID_INSERT_STYLE_POPUPMENU:
1353 NewObject = new UIPopupMenuStyle;
1354 break;
1355 case ID_INSERT_STYLE_RADIALMENU:
1356 NewObject = new UIRadialMenuStyle;
1357 break;
1359 case ID_INSERT_EFFECTOR_COLOR:
1360 NewObject = new UIColorEffector;
1361 break;
1363 case ID_INSERT_EFFECTOR_ROTATION:
1364 NewObject = new UIRotationEffector;
1365 break;
1367 case ID_INSERT_EFFECTOR_LOCATION:
1368 NewObject = new UILocationEffector;
1369 break;
1371 case ID_INSERT_EFFECTOR_OPACITY:
1372 NewObject = new UIOpacityEffector;
1373 break;
1375 case ID_INSERT_EFFECTOR_SIZE:
1376 NewObject = new UISizeEffector;
1377 break;
1379 case ID_INSERT_DEFORMER_HUD:
1380 NewObject = new UIDeformerHUD;
1381 break;
1383 case ID_INSERT_DEFORMER_WAVE:
1384 NewObject = new UIDeformerWave;
1385 break;
1387 case ID_INSERT_DEFORMER_ROTATE:
1388 NewObject = new UIDeformerRotate;
1389 break;
1392 if( !NewObject )
1393 return;
1395 HTREEITEM hSelectedItem = TreeView_GetSelection( gObjectTree );
1396 UIBaseObject *Container = 0;
1398 if( NewObject->IsA( TUIImageFrame ) )
1400 // Special case image frames so that they automatically create a style
1401 // when they are created unless they are being inserted into a style
1403 while( hSelectedItem )
1405 UIBaseObject *o = GetObjectFromNode( hSelectedItem );
1407 if( o && o->IsA( TUIImageStyle ) )
1409 Container = o;
1410 o->AddChild( NewObject );
1411 break;
1413 hSelectedItem = TreeView_GetParent( gObjectTree, hSelectedItem );
1416 if( !Container )
1418 UIBaseObject *NewContainer = new UIImageStyle;
1420 hSelectedItem = TreeView_GetSelection( gObjectTree );
1422 while( hSelectedItem )
1424 UIBaseObject *o = GetObjectFromNode( hSelectedItem );
1426 if( o && o->AddChild( NewContainer ) )
1428 Container = o;
1429 break;
1432 hSelectedItem = TreeView_GetParent( gObjectTree, hSelectedItem );
1435 if( !Container )
1437 assert( RootPage->AddChild( NewContainer ) );
1438 Container = RootPage;
1441 // Apply default properties to the new container
1442 gDefaultObjectPropertiesManager.ApplyDefaultPropertiesToObject( NewContainer );
1444 NewContainer->AddChild( NewObject );
1446 // Apply default properties after we insert the object into the tree
1447 // so that it can correctly link to other objects
1448 gDefaultObjectPropertiesManager.ApplyDefaultPropertiesToObject( NewObject );
1450 // Switch this pointer to the created container so the right object gets loaded to the tree
1451 NewObject = NewContainer;
1454 else
1456 while( hSelectedItem )
1458 UIBaseObject *o = GetObjectFromNode( hSelectedItem );
1460 if( o && o->AddChild( NewObject ) )
1462 Container = o;
1463 break;
1466 hSelectedItem = TreeView_GetParent( gObjectTree, hSelectedItem );
1469 if( !Container )
1471 assert( RootPage->AddChild( NewObject ) );
1472 Container = RootPage;
1475 // Apply default properties after we insert the object into the tree
1476 // so that it can correctly link to other objects
1477 gDefaultObjectPropertiesManager.ApplyDefaultPropertiesToObject( NewObject );
1480 if( Container->CanChildMove( NewObject, UIBaseObject::ChildMovementDirection::Top ) )
1481 Container->MoveChild( NewObject, UIBaseObject::ChildMovementDirection::Top );
1483 if( NewObject->IsA( TUIPage ) && (NewObject->GetParent() == RootPage) )
1484 LoadTopLevelObjectsToTabControl();
1486 HTREEITEM hNewItem = LoadObjectStructureToTreeControl( gObjectTree, NewObject, hSelectedItem, TVI_FIRST );
1488 TreeView_SelectItem( gObjectTree, hNewItem );
1489 TreeView_EnsureVisible( gObjectTree, hNewItem );
1491 recordUndo(NewObject, true);
1494 //-----------------------------------------------------------------
1496 bool RenameSelectedObjectInTree( HWND hTree, const char * newName)
1498 if( !hTree )
1499 hTree = gObjectTree;
1501 if( !hTree )
1502 return false;
1504 const HTREEITEM hSelectedItem = TreeView_GetSelection( hTree );
1506 if( !hSelectedItem )
1507 return false;
1509 const UIBaseObject * const root = UIManager::gUIManager().GetRootPage();
1510 UIBaseObject * const obj = GetObjectFromNode( hSelectedItem );
1512 if( !obj || (obj == root) )
1513 return false;
1515 UIString nameVal;
1516 obj->GetProperty(UIBaseObject::PropertyName::Name, nameVal);
1517 UIString newNameVal(Unicode::narrowToWide(newName));
1518 obj->SetName(newName);
1519 recordUndo(obj, UIBaseObject::PropertyName::Name, nameVal, newNameVal, true);
1521 return true;
1524 //----------------------------------------------------------------------
1526 void SortSelectedObject ( HWND hTree)
1528 HTREEITEM hSelectedItem = TreeView_GetSelection( hTree );
1530 if( !hSelectedItem )
1531 return;
1533 HTREEITEM hPrevSelection = TreeView_GetPrevSibling( hTree, hSelectedItem );
1535 UIBaseObject * const sel = GetObjectFromNode( hSelectedItem );
1537 if (!sel || sel->GetChildCount () == 0)
1538 return;
1540 recordUndo(sel, true);
1542 typedef ui_stdmap<UILowerString, UIBaseObject *>::fwd ObjNameMap;
1543 ObjNameMap onm;
1545 UIBaseObject::UIObjectList olist;
1546 sel->GetChildren (olist);
1549 for (UIBaseObject::UIObjectList::iterator it = olist.begin (); it != olist.end (); ++it)
1551 UIBaseObject * const obj = *it;
1552 obj->Attach (0);
1553 sel->RemoveChild (obj);
1554 onm.insert (std::make_pair (UILowerString (obj->GetName ()), obj));
1558 for (ObjNameMap::iterator it = onm.begin (); it != onm.end (); ++it)
1560 UIBaseObject * const obj = (*it).second;
1561 sel->AddChild (obj);
1562 obj->Detach (0);
1565 HTREEITEM treeParent = TreeView_GetParent( hTree, hSelectedItem );
1567 TreeView_DeleteItem( hTree, hSelectedItem );
1569 WaitForSingleObject( gFrameRenderingMutex, INFINITE );
1571 if( sel->IsA( TUIPage ) && sel->GetParent () == 0)
1572 LoadTopLevelObjectsToTabControl();
1574 HTREEITEM newSelection = LoadObjectStructureToTreeControl (hTree, sel, treeParent, hPrevSelection);
1576 TreeView_SelectItem( hTree, newSelection );
1577 TreeView_Expand(hTree, newSelection, TVE_EXPAND);
1579 TreeView_EnsureVisible( hTree, newSelection );
1581 ReleaseMutex( gFrameRenderingMutex );
1584 //-----------------------------------------------------------------
1586 void DeleteSelectedObjectInTree( HWND hTree )
1588 if( !hTree )
1589 return;
1591 HTREEITEM hSelectedItem = TreeView_GetSelection( hTree );
1592 HTREEITEM hNextSelection;
1593 UIPage *RootPage = UIManager::gUIManager().GetRootPage();
1595 if( !hSelectedItem )
1596 return;
1598 UIBaseObject *theObjectToDelete = GetObjectFromNode( hSelectedItem );
1600 int allowedReferenceCount = 2; // one for the parent, one for being in the selection
1601 if(theObjectToDelete == gObjectInspector->GetObject())
1602 allowedReferenceCount++;
1604 if( !theObjectToDelete || (theObjectToDelete == RootPage) )
1605 return;
1607 //-- see if anything has an outstanding reference to this object
1608 if (theObjectToDelete->GetRefCount () > allowedReferenceCount)
1610 char buf [512];
1611 _snprintf(buf, sizeof (buf) - 1, "%s has %d extra outstanding references.\nReally delete it?", theObjectToDelete->GetName().c_str(), theObjectToDelete->GetRefCount() - allowedReferenceCount);
1612 if (MessageBox( gMainWindow, buf, gApplicationName, MB_YESNO ) != IDYES)
1613 return;
1616 recordUndo(theObjectToDelete, true);
1618 hNextSelection = TreeView_GetNextSibling( hTree, hSelectedItem );
1620 if( !hNextSelection )
1622 hNextSelection = TreeView_GetPrevSibling( hTree, hSelectedItem );
1624 //-- don't select parents
1627 RemoveFromSelection( theObjectToDelete );
1629 TreeView_DeleteItem( hTree, hSelectedItem );
1630 WaitForSingleObject( gFrameRenderingMutex, INFINITE );
1632 UIBaseObject *theParent = theObjectToDelete->GetParent();
1634 theObjectToDelete->Attach( 0 );
1636 if( theParent )
1637 theParent->RemoveChild( theObjectToDelete );
1639 if( theObjectToDelete->IsA( TUIPage ) && (theObjectToDelete->GetParent() == RootPage) )
1640 LoadTopLevelObjectsToTabControl();
1642 TreeView_SelectItem( hTree, hNextSelection );
1644 if( !hNextSelection )
1645 gObjectInspector->SetObject( 0 );
1646 else
1648 TVITEM tvi = {0};
1650 tvi.mask = TVIF_HANDLE;
1651 tvi.hItem = hNextSelection;
1653 TreeView_GetItem( hTree, &tvi );
1655 gObjectInspector->SetObject( reinterpret_cast<UIBaseObject *>( tvi.lParam ) );
1656 TreeView_EnsureVisible( hTree, hNextSelection );
1659 // Do this last
1660 theObjectToDelete->Detach(0);
1661 ReleaseMutex( gFrameRenderingMutex );
1664 //-----------------------------------------------------------------
1666 void MoveSizeDlgControl( HWND hwnd, UINT itemID, UIPoint Move, UIPoint Size )
1668 RECT rcControl;
1669 HWND hwndControl;
1671 hwndControl = GetDlgItem( hwnd, itemID );
1672 GetWindowRect( hwndControl, &rcControl );
1673 MapWindowPoints( 0, hwnd, (LPPOINT)&rcControl, 2 );
1674 MoveWindow( hwndControl, rcControl.left + Move.x, rcControl.top + Move.y,
1675 rcControl.right - rcControl.left + Size.x, rcControl.bottom - rcControl.top + Size.y, TRUE );
1676 InvalidateRect( hwndControl, 0, TRUE );
1679 //-----------------------------------------------------------------
1681 void UnloadObjects( HWND hwndDlg )
1683 if( gObjectInspector )
1684 gObjectInspector->SetObject(0);
1686 SendMessage( gObjectTree, WM_SETREDRAW, 0, 0 );
1687 TreeView_DeleteAllItems( gObjectTree );
1688 SendMessage( gObjectTree, WM_SETREDRAW, 1, 0 );
1689 InvalidateRect( gObjectTree, 0, TRUE );
1691 SendDlgItemMessage( hwndDlg, IDC_OBJECTPROPERTIES, LB_RESETCONTENT, 0, 0 );
1693 UIManager::gUIManager().SetRootPage(0);
1696 //-----------------------------------------------------------------
1698 UINT CALLBACK SaveAsHookProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
1700 UI_UNREF (lParam);
1702 switch( uMsg )
1704 case WM_INITDIALOG:
1705 if( gFilename.empty() )
1706 EnableWindow( GetDlgItem( hwndDlg, ID_SAVE_NEXT_VERSION ), FALSE );
1707 else
1708 EnableWindow( GetDlgItem( hwndDlg, ID_SAVE_NEXT_VERSION ), TRUE );
1710 break;
1712 case WM_COMMAND:
1713 if( LOWORD( wParam ) == ID_SAVE_NEXT_VERSION )
1715 HWND hParent = GetParent(hwndDlg);
1717 gVersionFilename = true;
1718 SendMessage(hParent, WM_COMMAND, IDOK, (LPARAM)GetDlgItem( hParent, IDOK ) );
1720 break;
1722 return 0;
1725 //-----------------------------------------------------------------
1727 LRESULT CALLBACK TooltipMessageHookProc(int nCode, WPARAM wParam, LPARAM lParam)
1729 if( nCode < 0 )
1730 return CallNextHookEx(gTooltipHook, nCode, wParam, lParam);
1732 switch( ((MSG *)lParam)->message)
1734 case WM_MOUSEMOVE:
1735 case WM_LBUTTONDOWN:
1736 case WM_LBUTTONUP:
1737 case WM_MBUTTONDOWN:
1738 case WM_MBUTTONUP:
1739 case WM_RBUTTONDOWN:
1740 case WM_RBUTTONUP:
1741 case WM_NCMOUSEMOVE:
1742 case WM_NCLBUTTONDOWN:
1743 case WM_NCLBUTTONUP:
1744 case WM_NCMBUTTONDOWN:
1745 case WM_NCMBUTTONUP:
1746 case WM_NCRBUTTONDOWN:
1747 case WM_NCRBUTTONUP:
1748 if (gTooltip != 0)
1749 SendMessage(gTooltip, TTM_RELAYEVENT, 0, lParam);
1750 break;
1752 return CallNextHookEx(gTooltipHook, nCode, wParam, lParam);
1755 //-----------------------------------------------------------------
1757 void RecursiveSetProperty( UIBaseObject *root, const UILowerString & PropertyName, const char *OldValue, const char *NewValue )
1759 UIString Value;
1761 if( root->GetProperty( PropertyName, Value ) )
1763 if( !_stricmp( UIUnicode::wideToNarrow (Value).c_str(), OldValue ) )
1764 root->SetProperty( PropertyName, UIUnicode::narrowToWide (NewValue) );
1766 UIBaseObject::UIObjectList Children;
1768 root->GetChildren( Children );
1770 for( UIBaseObject::UIObjectList::iterator i = Children.begin(); i != Children.end(); ++i )
1772 RecursiveSetProperty( *i, PropertyName, OldValue, NewValue );
1777 //-----------------------------------------------------------------
1779 bool SaveWorkspaceFile( bool SaveAs )
1781 char res[_MAX_PATH+1];
1782 FILE *fp = 0;
1784 WaitForSingleObject( gFrameRenderingMutex, INFINITE );
1786 UIPage * const RootPage = UIManager::gUIManager().GetRootPage();
1788 if (RootPage)
1790 int version = 0;
1791 if (RootPage->GetPropertyInteger (UIVersion::PropertyVersion, version) && version > UIVersion::ms_version)
1793 MessageBox (NULL, "WARNING: the data you are editing is a newer version than this UIBuilder.", "UIBuilder", MB_OK | MB_ICONWARNING);
1795 if (IDYES != MessageBox( 0, "Are you sure you want to overrite the newer data?", gApplicationName, MB_YESNO | MB_DEFBUTTON2 | MB_ICONWARNING ))
1797 ReleaseMutex( gFrameRenderingMutex );
1798 return false;
1803 strncpy( res, gFilename.c_str(), sizeof(res) );
1804 res[sizeof(res)-1] = '\0';
1806 if( gFilename.empty() || SaveAs )
1808 OPENFILENAME ofn = {sizeof(ofn)};
1810 ofn.lpstrInitialDir = ".";
1811 ofn.hwndOwner = gMainWindow;
1812 ofn.hInstance = GetModuleHandle(0);
1813 ofn.lpstrFilter = gFileFilter;
1814 ofn.nFilterIndex = 1;
1815 ofn.lpstrDefExt = gDefaultExtension;
1816 ofn.lpstrFile = res;
1817 ofn.nMaxFile = sizeof( res );
1818 ofn.lpstrTitle = "Save As...";
1819 ofn.Flags = OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENABLETEMPLATE;
1820 ofn.lpfnHook = SaveAsHookProc;
1821 ofn.lpTemplateName = MAKEINTRESOURCE( IDD_SAVE_AS_TEMPLATE );
1823 gVersionFilename = false;
1825 if( !GetSaveFileName( &ofn ) )
1827 ReleaseMutex( gFrameRenderingMutex );
1828 return false;
1831 if( gVersionFilename )
1833 strncpy( res, gFilename.c_str(), sizeof(res) );
1834 res[sizeof(res)-1] = '\0';
1836 int version = 0;
1838 int base = 1;
1839 char *extension = strrchr( res, '.' );
1841 if( extension )
1843 *extension = '\0';
1844 extension++;
1847 int i = 0;
1848 for( i = strlen( res ) - 1; i >= 0 && isdigit( res[i] ); --i )
1850 version += (res[i] - '0') * base;
1851 base *= 10;
1854 if( i >= 0 )
1856 if( res[i] == '_' )
1857 res[i] = '\0';
1858 else
1859 res[i+1] = '\0';
1862 for (;;)
1864 ++version;
1866 char buffer[_MAX_PATH+1];
1868 if( extension && *extension != '\0' )
1869 sprintf( buffer, "%s_%03d.%s", res, version, extension );
1870 else
1871 sprintf( buffer, "%s_%03d.%s", res, version, gDefaultExtension );
1873 fp = fopen( buffer, "rb" );
1875 if( !fp )
1877 strcpy( res, buffer );
1878 break;
1880 else
1881 fclose( fp );
1886 if (RootPage)
1888 //-- force packing
1889 RootPage->ForcePackChildren();
1891 UISaver Saver;
1892 typedef std::map<UINarrowString, UINarrowString> NarrowStringMap;
1893 NarrowStringMap Output;
1895 RecursiveSetProperty( RootPage, UIBaseObject::PropertyName::SourceFile, gFilename.c_str(), res );
1896 Saver.SaveToStringSet( Output, Output.end(), *RootPage );
1898 std::vector<std::string> messages;
1900 std::string TmpStr;
1901 UIBuilderLoader Loader;
1903 for (NarrowStringMap::iterator i = Output.begin(); i != Output.end();)
1905 const std::string & FileName = i->first.empty () ? res : i->first;
1906 const std::string & outputData = i->second;
1908 ++i;
1911 struct _stat statbuf;
1912 const int result = _stat (FileName.c_str (), &statbuf);
1913 if (!result)
1915 const int t = static_cast<int>(statbuf.st_mtime);
1916 const int oldTime = s_fileTimes [FileName];
1917 if (t > oldTime)
1919 char buf [1024];
1920 _snprintf (buf, sizeof (buf), "The file [%s] has changed on disk.", FileName.c_str ());
1921 MessageBox( gMainWindow, buf, gApplicationName, MB_OK | MB_ICONWARNING);
1922 _snprintf (buf, sizeof (buf), "Are you sure you want to save [%s]?\nThis will almost certainly clobber someone else's changes.", FileName.c_str ());
1923 if (IDYES != MessageBox( 0, buf, gApplicationName, MB_YESNO | MB_DEFBUTTON2 | MB_ICONWARNING ))
1925 continue;
1932 TmpStr.clear ();
1933 Loader.LoadStringFromResource (FileName, TmpStr);
1935 //-- don't even attempt to write unmodified files
1936 if (TmpStr == outputData)
1937 continue;
1940 FILE * fp = fopen( FileName.c_str (), "wb" );
1942 if( !fp )
1944 messages.push_back (FileName);
1946 else
1948 fwrite( outputData.data (), outputData.size(), 1, fp );
1949 fclose( fp );
1951 struct _stat statbuf;
1952 const int result = _stat (FileName.c_str (), &statbuf);
1953 if (!result)
1955 const int t = static_cast<int>(statbuf.st_mtime);
1956 s_fileTimes [FileName] = t;
1961 if (!messages.empty ())
1963 const std::string header ("Could not save objects to files:\n");
1964 int currentNumberOfFiles = 0;
1966 std::string fileNames;
1968 for (size_t i = 0; i < messages.size ();)
1970 const std::string & FileName = messages [i];
1972 ++i;
1974 fileNames += FileName;
1975 fileNames.push_back ('\n');
1977 if (++currentNumberOfFiles >= 25 || i >= messages.size ())
1979 const std::string msg = header + fileNames;
1980 MessageBox( gMainWindow, msg.c_str (), gApplicationName, MB_OK );
1981 fileNames.clear ();
1982 currentNumberOfFiles = 0;
1988 gFilename = res;
1989 SetMainWindowTitle();
1990 ReleaseMutex( gFrameRenderingMutex );
1991 return true;
1994 //-----------------------------------------------------------------
1996 bool CloseWorkspaceFile( bool bLock )
1998 if( bLock )
1999 WaitForSingleObject( gFrameRenderingMutex, INFINITE );
2001 if( UIManager::gUIManager().GetRootPage() )
2003 switch( MessageBox( 0, "Would you like to save your workspace before closing it?", gApplicationName, MB_YESNOCANCEL | MB_ICONWARNING ) )
2005 case IDYES:
2006 SaveWorkspaceFile( false );
2007 break;
2009 case IDNO:
2010 break;
2012 case IDCANCEL:
2013 if( bLock )
2014 ReleaseMutex( gFrameRenderingMutex );
2016 return false;
2019 UIBuilderHistory::remove ();
2022 gCurrentlySelectedPage = 0;
2024 if (gObjectInspector)
2025 gObjectInspector->SetObject(0);
2027 SetSelection(0, true);
2029 UnloadObjects( gMainWindow );
2030 ShowWindow( gUIWindow, SW_HIDE );
2032 if( bLock )
2033 ReleaseMutex( gFrameRenderingMutex );
2035 return true;
2038 //-----------------------------------------------------------------
2040 bool OpenWorkspaceFile( const char *Filename )
2042 char res[_MAX_PATH+1] = "";
2044 WaitForSingleObject( gFrameRenderingMutex, INFINITE );
2046 if( !Filename )
2048 OPENFILENAME ofn = {sizeof(ofn)};
2050 ofn.lpstrInitialDir = ".";
2051 ofn.hwndOwner = gMainWindow;
2052 ofn.lpstrFilter = gFileFilter;
2053 ofn.nFilterIndex = 1;
2054 ofn.lpstrDefExt = gDefaultExtension;
2055 ofn.lpstrFile = res;
2056 ofn.nMaxFile = sizeof( res );
2057 ofn.lpstrTitle = "Select a User Interface Workspace to Open";
2058 ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
2060 if( !GetOpenFileName( &ofn ) )
2062 ReleaseMutex( gFrameRenderingMutex );
2063 return false;
2066 if( !CloseWorkspaceFile(false) )
2068 ReleaseMutex( gFrameRenderingMutex );
2069 return false;
2072 Filename = res;
2074 else
2076 if( !CloseWorkspaceFile(false) )
2078 ReleaseMutex( gFrameRenderingMutex );
2079 return false;
2082 strcpy( res, Filename );
2085 UIBuilderLoader Loader;
2086 UIBaseObject::UIObjectList TopLevelObjects;
2088 char *pLastDelimitor = strrchr( res, '\\' );
2090 if( pLastDelimitor )
2091 *pLastDelimitor = '\0';
2093 SetCurrentDirectory( res );
2095 if( pLastDelimitor )
2096 *pLastDelimitor = '\\';
2098 s_fileTimes.clear ();
2100 if( !Loader.LoadFromResource( res, TopLevelObjects, true ) )
2102 GetUIOutputStream()->flush ();
2103 MessageBox( 0, "The file could not be opened, check ui.log for more information", gApplicationName, MB_OK );
2104 ReleaseMutex( gFrameRenderingMutex );
2105 return false;
2108 if( TopLevelObjects.size() > 1 )
2110 MessageBox( 0, "Error: The file contains more than one root level object", gApplicationName, MB_OK );
2111 ReleaseMutex( gFrameRenderingMutex );
2112 return false;
2115 UIBaseObject * const o = TopLevelObjects.front();
2117 UITextStyleManager::GetInstance()->Initialize(static_cast<UIPage *>(o), Loader);
2119 o->Link ();
2121 Loader.Lint ();
2123 if( o->IsA( TUIPage ) )
2124 UIManager::gUIManager().SetRootPage( static_cast< UIPage * >( o ) );
2125 else
2127 MessageBox( 0, "Error: The root level object in the file is not a page", gApplicationName, MB_OK );
2128 ReleaseMutex( gFrameRenderingMutex );
2129 return false;
2132 UIBuilderHistory::install ();
2134 // if( Loader.ReadOnlyFilesInInput )
2135 // MessageBox( NULL, "Warning, one or more of the files making up this script are read only.", "UIBuilder", MB_OK );
2137 int version = 0;
2138 if (o->GetPropertyInteger (UIVersion::PropertyVersion, version) && version > UIVersion::ms_version)
2140 MessageBox (NULL, "WARNING: the data you are editing is a newer version than this UIBuilder.", "UIBuilder", MB_OK | MB_ICONWARNING);
2142 else
2143 o->SetPropertyInteger (UIVersion::PropertyVersion, UIVersion::ms_version);
2145 LoadObjectStructureToTreeControl(gObjectTree, UIManager::gUIManager().GetRootPage(), 0, TVI_LAST);
2146 TreeView_SelectItem(gObjectTree, TreeView_GetRoot(gObjectTree) );
2147 gObjectInspector->SetObject(UIManager::gUIManager().GetRootPage());
2149 gFilename = Filename;
2150 AddToMRUList( Filename );
2151 SetMainWindowTitle();
2153 RECT rc;
2154 GetWindowRect( gMainWindow, &rc );
2155 LoadTopLevelObjectsToTabControl();
2156 SetWindowPos( gUIWindow, 0, rc.right, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
2157 ShowWindow( gUIWindow, SW_SHOWNA );
2158 ReleaseMutex( gFrameRenderingMutex );
2159 return true;
2162 //-----------------------------------------------------------------
2164 void CreateNewWorkspace( void )
2166 WaitForSingleObject( gFrameRenderingMutex, INFINITE );
2168 if (UIBuilderHistory::isInstalled())
2169 UIBuilderHistory::remove();
2171 UIBuilderHistory::install ();
2173 UnloadObjects( gMainWindow );
2175 UIPage *NewRoot = new UIPage;
2176 NewRoot->SetName( "root" );
2177 NewRoot->SetVisible( true );
2178 NewRoot->SetSize( UISize(800,600) );
2179 NewRoot->SetEnabled( true );
2181 UIManager::gUIManager().SetRootPage( NewRoot );
2183 LoadTopLevelObjectsToTabControl();
2184 TabCtrl_SetCurSel( gTabControlWindow, 0 );
2185 SizeWindowToCurrentPageSelection();
2187 RECT rc;
2188 GetWindowRect( gMainWindow, &rc );
2189 SetWindowPos( gUIWindow, 0, rc.right, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW );
2191 LoadObjectStructureToTreeControl(gObjectTree, NewRoot, 0, TVI_LAST);
2192 TreeView_SelectItem( gObjectTree, TreeView_GetRoot( gObjectTree ) );
2193 TreeView_EnsureVisible( gObjectTree, TreeView_GetRoot( gObjectTree ) );
2194 SetFocus( gObjectTree );
2195 gObjectInspector->SetObject( NewRoot );
2197 gFilename = "";
2198 SetMainWindowTitle();
2200 ReleaseMutex( gFrameRenderingMutex );
2203 //-----------------------------------------------------------------
2205 void AcceptDroppedFiles( HDROP hDrop )
2207 if( CloseWorkspaceFile() )
2209 char Filename[_MAX_PATH + 1];
2211 DragQueryFile( hDrop, 0, Filename, sizeof( Filename ) );
2212 OpenWorkspaceFile( Filename );
2214 DragFinish( hDrop );
2217 //-----------------------------------------------------------------
2219 void ImportFile( void )
2221 if( gFilename.empty() )
2223 MessageBox( 0, "You must save your workspace file before performing an import.", gApplicationName, MB_OK );
2225 if( !SaveWorkspaceFile(true) )
2226 return;
2229 char res[_MAX_PATH+1];
2230 OPENFILENAME ofn = {sizeof(ofn)};
2232 res[0] = '\0';
2233 ofn.lpstrInitialDir = ".";
2234 ofn.hwndOwner = gMainWindow;
2235 ofn.lpstrFilter = gIncludeFileFilter;
2236 ofn.nFilterIndex = 1;
2237 ofn.lpstrDefExt = gDefaultExtension;
2238 ofn.lpstrFile = res;
2239 ofn.nMaxFile = sizeof( res );
2240 ofn.lpstrTitle = "Select File To Import";
2241 ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
2243 if( !GetOpenFileName( &ofn ) )
2245 MessageBox( 0, "Could not open file", gApplicationName, MB_OK );
2246 return;
2249 char RelativePath[_MAX_PATH+1];
2251 PathRelativePathTo( RelativePath, gFilename.c_str(), 0, res, 0);
2253 if( (RelativePath[0] == '.') && (RelativePath[1] == '\\') )
2254 memmove( RelativePath, RelativePath + 2, strlen( RelativePath + 2 ) + 1 );
2256 UIBuilderLoader Loader;
2257 UIBaseObject::UIObjectList TopLevelObjects;
2259 if( !Loader.LoadFromResource( RelativePath, TopLevelObjects, true ) )
2261 MessageBox( 0, "The file could not be opened, check ui.log for more information", gApplicationName, MB_OK );
2263 while( !TopLevelObjects.empty() )
2265 TopLevelObjects.back()->Detach (0);
2266 TopLevelObjects.pop_back();
2268 return;
2271 if( Loader.ReadOnlyFilesInInput )
2272 MessageBox( NULL, "Warning, one or more of the files making up the imported script are read only.", "UIBuilder", MB_OK );
2274 HTREEITEM hParent = TreeView_GetSelection( gObjectTree );
2275 UIBaseObject *pParent = GetObjectFromNode( hParent );
2276 long ObjectsNotLoaded = 0;
2278 for( UIBaseObject::UIObjectList::iterator i = TopLevelObjects.begin(); i != TopLevelObjects.end(); ++i )
2280 if( !pParent || !pParent->AddChild( *i ) )
2282 (*i)->Detach (0);
2283 *i = 0;
2284 ++ObjectsNotLoaded;
2286 else
2288 LoadObjectStructureToTreeControl(gObjectTree, *i, hParent, TVI_LAST);
2289 TreeView_Expand(gObjectTree, hParent, TVE_EXPAND);
2293 if( ObjectsNotLoaded > 0 )
2295 char Buffer[1024];
2296 sprintf(Buffer, "%d objects were not loaded from the file because they could not be contained in the selected object", ObjectsNotLoaded );
2299 if( UIManager::gUIManager().GetRootPage() )
2300 UIManager::gUIManager().GetRootPage()->Link();
2302 LoadTopLevelObjectsToTabControl();
2303 ReleaseMutex( gFrameRenderingMutex );
2306 //-----------------------------------------------------------------
2308 void ExportSelectionToFile( void )
2310 MessageBox(NULL, gNotImplemented, gApplicationName, MB_OK );
2313 //-----------------------------------------------------------------
2315 void PurgeSelectedProperty( UIBaseObject *o, UINarrowString PropertyName )
2317 if (o)
2319 recordUndo(o, true);
2321 UIBaseObject::UIObjectList Children;
2323 o->RemoveProperty( UILowerString (PropertyName) );
2325 o->GetChildren( Children );
2327 for( UIBaseObject::UIObjectList::iterator i = Children.begin(); i != Children.end(); ++i )
2328 PurgeSelectedProperty( *i, PropertyName );
2332 //-----------------------------------------------------------------
2334 void ClearClipboard( void )
2337 gClipboard.clear();
2340 //-----------------------------------------------------------------
2342 void CopySelectedObjectInTreeToClipboard( HWND hTree )
2344 UI_UNREF (hTree);
2346 ClearClipboard();
2348 for( UIBaseObject::UISmartObjectList::iterator i = gCurrentSelection.begin(); i != gCurrentSelection.end(); ++i )
2350 if( (*i)->GetParent() )
2351 gClipboard.push_back(UIBaseObject::UIBaseObjectPointer((*i)->DuplicateObject()));
2355 //-----------------------------------------------------------------
2357 void PasteObjectFromClipboard( HWND hTree )
2359 UI_UNREF (hTree);
2361 UIBaseObject *NewParentObject = GetSelectedObjectInTreeControl();
2362 int FailedCopies = 0;
2364 if (NewParentObject)
2366 for( UIBaseObject::UISmartObjectList::reverse_iterator i = gClipboard.rbegin(); i != gClipboard.rend(); ++i )
2368 UIBaseObject::UIBaseObjectPointer NewObject((*i)->DuplicateObject());
2370 NewObject->PurgeProperty( UIBaseObject::PropertyName::SourceFile );
2372 if( NewParentObject->AddChild( NewObject ) )
2374 NewObject->Link ();
2376 if ( NewObject->IsA(TUIWidget))
2379 UI_ASOBJECT(UIWidget, NewObject)->ResetPackSizeInfo();
2380 UI_ASOBJECT(UIWidget, NewObject)->ResetPackLocationInfo();
2383 if( NewParentObject->MoveChild( NewObject, UIBaseObject::ChildMovementDirection::Top ) )
2384 LoadObjectStructureToTreeControl( gObjectTree, NewObject, TreeView_GetSelection( gObjectTree ), TVI_FIRST );
2385 else
2386 LoadObjectStructureToTreeControl( gObjectTree, NewObject, TreeView_GetSelection( gObjectTree ), TVI_LAST );
2388 else
2390 ++FailedCopies;
2395 if( FailedCopies > 0 )
2397 char buffer[1028];
2399 sprintf(buffer, "%d object%s could not be pasted because they could not be contained in the selected object.", FailedCopies, FailedCopies == 1 ? "" : "s" );
2400 MessageBox( 0, buffer, 0, MB_OK );
2404 //-----------------------------------------------------------------
2406 BOOL CALLBACK MainWindowProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
2408 switch( uMsg )
2410 case WM_INITDIALOG:
2412 HIMAGELIST hImageList;
2414 // Load MRU file list
2415 LoadMRUListFromRegistry();
2416 LoadPreferencesFromRegistry ();
2418 // Initialize globals
2419 gMainWindow = hwndDlg;
2420 gTooltip = CreateWindow( TOOLTIPS_CLASS, 0, TTS_ALWAYSTIP, 0, 0, 0, 0, 0, 0, GetModuleHandle(0), 0 );
2421 gObjectTree = GetDlgItem( hwndDlg, IDC_OBJECTSTRUCTURE );
2422 hImageList = ImageList_LoadImage( GetModuleHandle(0), MAKEINTRESOURCE(IDR_IMAGELIST), 16, 1, CLR_DEFAULT, IMAGE_BITMAP, 0 );
2424 SetMainWindowTitle();
2425 CreateDialog( GetModuleHandle(0), MAKEINTRESOURCE(IDD_UIWINDOW), gMainWindow, UIWindowDlgProc );
2427 // Set up drag and drop
2428 DragAcceptFiles( gMainWindow, TRUE );
2430 // Set up tooltips
2431 AddTooltipFromControlID( gTooltip, gMainWindow, IDC_TOP, "Move control to top of ZOrder" );
2432 AddTooltipFromControlID( gTooltip, gMainWindow, IDC_UP, "Move control up in ZOrder" );
2433 AddTooltipFromControlID( gTooltip, gMainWindow, IDC_DOWN, "Move control down in ZOrder" );
2434 AddTooltipFromControlID( gTooltip, gMainWindow, IDC_BOTTOM, "Move control to bottom of ZOrder" );
2436 AddTooltipFromControlID( gTooltip, gMainWindow, IDC_LOCK, "Lock / Unlock Control" );
2437 AddTooltipFromControlID( gTooltip, gMainWindow, IDC_ADDPROPERTY, "Add Property" );
2438 AddTooltipFromControlID( gTooltip, gMainWindow, IDC_REMOVEPROPERTY, "Remove Property" );
2440 AddTooltipFromControlID( gTooltip, gMainWindow, IDC_CHECKOUT, "Checkout source file using Perforce." );
2443 gTooltipHook = SetWindowsHookEx(WH_GETMESSAGE, TooltipMessageHookProc, (HINSTANCE) 0, GetCurrentThreadId() );
2445 TreeView_SetImageList( gObjectTree, 0, TVSIL_NORMAL );
2446 TreeView_SetImageList( gObjectTree, hImageList, TVSIL_NORMAL );
2448 gObjectInspector = new ObjectInspector( GetDlgItem( hwndDlg, IDC_OBJECTPROPERTIES ) );
2450 if( gLimitFrameRate )
2451 CheckDlgButton( hwndDlg, IDC_CAPFRAMERATE, BST_CHECKED );
2452 else
2453 CheckDlgButton( hwndDlg, IDC_CAPFRAMERATE, BST_UNCHECKED );
2455 SetTimer( hwndDlg, 0, 100, 0 );
2457 RECT rcDesktop;
2458 RECT rcWindow;
2459 RECT rcClient;
2461 SystemParametersInfo( SPI_GETWORKAREA, 0, &rcDesktop, 0 );
2462 GetWindowRect( hwndDlg, &rcWindow );
2463 GetClientRect( hwndDlg, &rcClient );
2465 gInitialSize.x = gOldSize.x = rcClient.right - rcClient.left;
2466 gInitialSize.y = gOldSize.y = rcClient.bottom - rcClient.top;
2468 SetWindowPos( gMainWindow, 0, rcDesktop.left, rcDesktop.top, rcWindow.right - rcWindow.left,
2469 rcDesktop.bottom - rcDesktop.top, SWP_NOZORDER | SWP_NOACTIVATE );
2471 SendDlgItemMessage( hwndDlg, IDC_TOP, BM_SETIMAGE, IMAGE_ICON,
2472 (LPARAM)LoadImage( GetModuleHandle(0), MAKEINTRESOURCE(IDI_TOP), IMAGE_ICON, 16, 16, 0 ) );
2473 SendDlgItemMessage( hwndDlg, IDC_UP, BM_SETIMAGE, IMAGE_ICON,
2474 (LPARAM)LoadImage( GetModuleHandle(0), MAKEINTRESOURCE(IDI_UP), IMAGE_ICON, 16, 16, 0 ) );
2475 SendDlgItemMessage( hwndDlg, IDC_DOWN, BM_SETIMAGE, IMAGE_ICON,
2476 (LPARAM)LoadImage( GetModuleHandle(0), MAKEINTRESOURCE(IDI_DOWN), IMAGE_ICON, 16, 16, 0 ) );
2477 SendDlgItemMessage( hwndDlg, IDC_BOTTOM, BM_SETIMAGE, IMAGE_ICON,
2478 (LPARAM)LoadImage( GetModuleHandle(0), MAKEINTRESOURCE(IDI_BOTTOM), IMAGE_ICON, 16, 16, 0 ) );
2480 EnableButtonControls( hwndDlg, 0 );
2482 SendDlgItemMessage( hwndDlg, IDC_ADDPROPERTY, BM_SETIMAGE, IMAGE_ICON,
2483 (LPARAM)LoadImage( GetModuleHandle(0), MAKEINTRESOURCE(IDI_ADDPROPERTY), IMAGE_ICON, 16, 16, 0 ) );
2485 SendDlgItemMessage( hwndDlg, IDC_REMOVEPROPERTY, BM_SETIMAGE, IMAGE_ICON,
2486 (LPARAM)LoadImage( GetModuleHandle(0), MAKEINTRESOURCE(IDI_REMOVEPROPERTY), IMAGE_ICON, 16, 16, 0 ) );
2488 SendDlgItemMessage( hwndDlg, IDC_LOCK, BM_SETIMAGE, IMAGE_ICON,
2489 (LPARAM)LoadImage( GetModuleHandle(0), MAKEINTRESOURCE(IDI_LOCK), IMAGE_ICON, 16, 16, 0 ) );
2491 SendDlgItemMessage( hwndDlg, IDC_CHECKOUT, BM_SETIMAGE, IMAGE_ICON,
2492 (LPARAM)LoadImage( GetModuleHandle(0), MAKEINTRESOURCE(IDI_CHECKOUT), IMAGE_ICON, 16, 16, 0 ) );
2495 SendMessage( hwndDlg, WM_SETICON, ICON_BIG,
2496 (LPARAM)LoadImage( GetModuleHandle(0), MAKEINTRESOURCE(IDI_APP), IMAGE_ICON, 32, 32, 0 ) );
2498 SendMessage( hwndDlg, WM_SETICON, ICON_SMALL,
2499 (LPARAM)LoadImage( GetModuleHandle(0), MAKEINTRESOURCE(IDI_APP), IMAGE_ICON, 16, 16, 0 ) );
2501 char DirBuff[_MAX_PATH + 1];
2502 GetCurrentDirectory( sizeof( DirBuff ), DirBuff );
2503 gInitialDirectory = DirBuff;
2505 FILE *fp = fopen("defaults.cfg", "rb");
2507 if( fp )
2509 gDefaultObjectPropertiesManager.LoadFrom( fp );
2510 fclose( fp );
2513 // searchpaths for FileLocator - jwatson
2515 FileLocator & loc = FileLocator::gFileLocator ();
2516 loc.addPath ("./");
2518 fp = fopen ("uibuilder_searchpaths.cfg", "rb");
2520 if (fp)
2522 char buf[1024];
2524 while (fgets (buf, 1024, fp))
2526 // strip newline
2527 char * ptr = strchr (buf, '\n');
2529 if (ptr)
2530 *ptr = 0;
2532 ptr = strchr (buf, '\r');
2534 if (ptr)
2535 *ptr = 0;
2537 loc.addPath (buf);
2540 fclose (fp);
2543 return 0;
2546 case WM_INITMENU:
2547 gMenu = (HMENU)wParam;
2548 LoadMRUListToMenu(gMenu);
2549 EnableMenuItems(gMenu, GetSelectedObjectInTreeControl() );
2550 return 0;
2552 case WM_DROPFILES:
2553 AcceptDroppedFiles( (HDROP)wParam );
2554 return 0;
2556 case WM_MOUSEMOVE:
2557 case WM_LBUTTONDOWN:
2558 case WM_LBUTTONUP:
2559 case WM_MBUTTONDOWN:
2560 case WM_MBUTTONUP:
2561 case WM_RBUTTONDOWN:
2562 case WM_RBUTTONUP:
2563 case WM_LBUTTONDBLCLK:
2564 case WM_MBUTTONDBLCLK:
2565 case WM_RBUTTONDBLCLK:
2567 LONG l;
2568 POINTS pt;
2569 MSG msg;
2571 l = GetMessagePos();
2572 pt = MAKEPOINTS(l);
2573 msg.hwnd = hwndDlg;
2574 msg.message = uMsg;
2575 msg.wParam = wParam;
2576 msg.lParam = lParam;
2577 msg.pt.x = pt.x;
2578 msg.pt.y = pt.y;
2579 msg.time = GetMessageTime();
2581 SendMessage( gTooltip, TTM_RELAYEVENT, 0, (LPARAM)&msg );
2582 return 0;
2585 case WM_MOVE:
2587 RECT rc;
2588 GetWindowRect( hwndDlg, &rc );
2589 SetWindowPos( gUIWindow, 0, rc.right, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
2590 return 0;
2593 case WM_SIZE:
2595 UISize NewSize;
2597 NewSize.x = LOWORD(lParam);
2598 NewSize.y = HIWORD(lParam);
2600 if( (NewSize.x == 0) || (NewSize.y == 0) )
2601 return 0;
2603 if( gOldSize.x == 0 )
2604 gInitialSize = NewSize;
2605 else
2607 UISize DeltaSize = NewSize - gOldSize;
2609 MoveSizeDlgControl( hwndDlg, IDC_PERFORMANCESTATS, UIPoint( 0, DeltaSize.y ), UIPoint(DeltaSize.x,0) );
2610 MoveSizeDlgControl( hwndDlg, IDC_FRAMERATE_LABEL, UIPoint( 0, DeltaSize.y ), UIPoint(0,0) );
2611 MoveSizeDlgControl( hwndDlg, IDC_FRAMERATE, UIPoint( 0, DeltaSize.y ), UIPoint(0,0) );
2612 MoveSizeDlgControl( hwndDlg, IDC_CAPFRAMERATE, UIPoint( 0, DeltaSize.y ), UIPoint(0,0) );
2613 MoveSizeDlgControl( hwndDlg, IDC_TRIANGLECOUNT_LABEL, UIPoint( 0, DeltaSize.y ), UIPoint(0,0) );
2614 MoveSizeDlgControl( hwndDlg, IDC_TRIANGLECOUNT, UIPoint( 0, DeltaSize.y ), UIPoint(0,0) );
2615 MoveSizeDlgControl( hwndDlg, IDC_SHOWTRIANGLES, UIPoint( 0, DeltaSize.y ), UIPoint(0,0) );
2616 MoveSizeDlgControl( hwndDlg, IDC_FLUSHCOUNT_LABEL, UIPoint( 0, DeltaSize.y ), UIPoint(0,0) );
2617 MoveSizeDlgControl( hwndDlg, IDC_FLUSHCOUNT, UIPoint( 0, DeltaSize.y ), UIPoint(0,0) );
2619 MoveSizeDlgControl( hwndDlg, IDC_OBJECTPROPERTIES, UIPoint( 0, DeltaSize.y ), UIPoint(DeltaSize.x,0) );
2620 MoveSizeDlgControl( hwndDlg, IDC_OBJECTPROPERTIES_LABEL, UIPoint( 0, DeltaSize.y ), UIPoint(0,0) );
2622 MoveSizeDlgControl( hwndDlg, IDC_OBJECTSTRUCTURE, UIPoint( 0, 0 ), UIPoint(DeltaSize.x,DeltaSize.y) );
2624 MoveSizeDlgControl( hwndDlg, IDC_BOTTOM, UIPoint( DeltaSize.x, 0 ), UIPoint(0,0) );
2625 MoveSizeDlgControl( hwndDlg, IDC_DOWN, UIPoint( DeltaSize.x, 0 ), UIPoint(0,0) );
2626 MoveSizeDlgControl( hwndDlg, IDC_UP, UIPoint( DeltaSize.x, 0 ), UIPoint(0,0) );
2627 MoveSizeDlgControl( hwndDlg, IDC_TOP, UIPoint( DeltaSize.x, 0 ), UIPoint(0,0) );
2629 MoveSizeDlgControl( hwndDlg, IDC_ADDPROPERTY, UIPoint( DeltaSize.x, DeltaSize.y ), UIPoint(0,0) );
2630 MoveSizeDlgControl( hwndDlg, IDC_REMOVEPROPERTY, UIPoint( DeltaSize.x, DeltaSize.y ), UIPoint(0,0) );
2631 MoveSizeDlgControl( hwndDlg, IDC_LOCK, UIPoint( DeltaSize.x, DeltaSize.y ), UIPoint(0,0) );
2632 MoveSizeDlgControl( hwndDlg, IDC_CHECKOUT, UIPoint( DeltaSize.x, DeltaSize.y ), UIPoint(0,0) );
2633 MoveSizeDlgControl( hwndDlg, IDC_OBJECTTYPE, UIPoint( 0, DeltaSize.y ), UIPoint(DeltaSize.x,0) );
2636 gOldSize = NewSize;
2638 RECT rc;
2639 GetWindowRect( hwndDlg, &rc );
2640 SetWindowPos( gUIWindow, 0, rc.right, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
2641 return 0;
2644 case WM_GETMINMAXINFO:
2646 LPMINMAXINFO pmmi = (LPMINMAXINFO)lParam;
2647 RECT rc;
2649 rc.left = 0;
2650 rc.top = 0;
2651 rc.right = gInitialSize.x;
2652 rc.bottom = gInitialSize.y;
2654 AdjustWindowRectEx( &rc, GetWindowLong( hwndDlg, GWL_STYLE ), TRUE, GetWindowLong( hwndDlg, GWL_EXSTYLE ) );
2655 pmmi->ptMinTrackSize.x = rc.right - rc.left;
2656 pmmi->ptMinTrackSize.y = rc.bottom - rc.top;
2657 return 0;
2660 case WM_COMMAND:
2661 if( LOWORD( wParam ) >= 0xFFFF - gMRUSize )
2663 // MRU list
2664 int ItemID = 0xFFFF - LOWORD( wParam ) - 1;
2666 MRUList::iterator i = gMRUList.begin();
2668 while( ItemID && (i != gMRUList.end()) )
2670 ++i;
2671 --ItemID;
2674 if( i != gMRUList.end() )
2676 // Make a copy of this so that we have don't erase it in AddToMRU
2677 UINarrowString ItemCopy = *i;
2678 UI_IGNORE_RETURN(OpenWorkspaceFile(ItemCopy.c_str()));
2681 return 0;
2684 switch( LOWORD( wParam ) )
2686 case IDC_SHOWTRIANGLES:
2687 if( HIWORD( wParam ) == BN_CLICKED )
2689 WaitForSingleObject( gFrameRenderingMutex, INFINITE );
2690 const bool show = SendMessage( (HWND)lParam, BM_GETSTATE, 0, 0 ) & BST_CHECKED;
2691 gPrimaryDisplay->ShowTriangles (show);
2692 UITextStyle::setEnabled (!show);
2694 ReleaseMutex( gFrameRenderingMutex );
2696 break;
2698 case ID_FILE_NEW:
2699 CreateNewWorkspace();
2700 break;
2702 case ID_FILE_OPEN:
2703 OpenWorkspaceFile( 0 );
2704 break;
2706 case ID_FILE_SAVE:
2707 SaveWorkspaceFile( false );
2708 break;
2710 case ID_FILE_SAVEAS:
2711 SaveWorkspaceFile( true );
2712 break;
2714 case ID_FILE_CLOSE:
2715 CloseWorkspaceFile();
2716 break;
2718 case ID_FILE_IMPORT:
2719 ImportFile();
2720 break;
2722 case ID_FILE_EXPORT:
2723 ExportSelectionToFile();
2724 break;
2726 case ID_FILE_EXIT:
2727 if( CloseWorkspaceFile() )
2729 EndDialog( gUIWindow, 0 );
2730 DestroyWindow( hwndDlg );
2732 break;
2734 case ID_INSERT_BUTTON:
2735 case ID_INSERT_CHECKBIOX:
2736 case ID_INSERT_DATASOURCE:
2737 case ID_INSERT_DATASOURCECONTAINER:
2738 case ID_INSERT_DATAITEM:
2739 case ID_INSERT_DROPDOWNBOX:
2740 case ID_INSERT_ELLIPSE:
2741 case ID_INSERT_IMAGE:
2742 case ID_INSERT_GRID:
2743 case ID_INSERT_IMAGEFRAME:
2744 case ID_INSERT_LISTBOX:
2745 case ID_INSERT_LIST:
2746 case ID_INSERT_TREEVIEW:
2747 case ID_INSERT_COMBOBOX:
2748 case ID_INSERT_NAMESPACE:
2749 case ID_INSERT_TEXTBOX:
2750 case ID_INSERT_SCROLLBAR:
2751 case ID_INSERT_SLIDERBAR:
2752 case ID_INSERT_SLIDERPLANE:
2753 case ID_INSERT_TABSET:
2754 case ID_INSERT_TABBEDPANE:
2755 case ID_INSERT_POPUPMENU:
2756 case ID_INSERT_RADIALMENU:
2757 case ID_INSERT_CURSORSET:
2758 case ID_INSERT_VOLUMEPAGE:
2759 case ID_INSERT_STATICTEXT:
2760 case ID_INSERT_TEMPLATE:
2761 case ID_INSERT_PAGE:
2762 case ID_INSERT_COMPOSITE:
2763 case ID_INSERT_TABLE:
2764 case ID_INSERT_TABLEMODELDEFAULT:
2765 case ID_INSERT_TABLEHEADER:
2766 case ID_INSERT_PROGRESSBAR:
2767 case ID_INSERT_CURSOR:
2768 case ID_INSERT_CLOCK:
2769 case ID_INSERT_APPLICATIONOBJECT:
2770 case ID_INSERT_STYLE_BUTTON:
2771 case ID_INSERT_STYLE_CHECKBOX:
2772 case ID_INSERT_STYLE_DROPDOWNBOX:
2773 case ID_INSERT_STYLE_GRID:
2774 case ID_INSERT_STYLE_IMAGE:
2775 case ID_INSERT_STYLE_LISTBOX:
2776 case ID_INSERT_STYLE_LIST:
2777 case ID_INSERT_STYLE_TREEVIEW:
2778 case ID_INSERT_STYLE_PROGRESSBAR:
2779 case ID_INSERT_STYLE_SLIDERBAR:
2780 case ID_INSERT_STYLE_TEXT:
2781 case ID_INSERT_STYLE_TEXTBOX:
2782 case ID_INSERT_STYLE_TOOLTIP:
2783 case ID_INSERT_STYLE_RECTANGLE:
2784 case ID_INSERT_STYLE_TABSET:
2785 case ID_INSERT_STYLE_TABBEDPANE:
2786 case ID_INSERT_STYLE_POPUPMENU:
2787 case ID_INSERT_STYLE_RADIALMENU:
2788 case ID_INSERT_EFFECTOR_COLOR:
2789 case ID_INSERT_EFFECTOR_ROTATION:
2790 case ID_INSERT_EFFECTOR_LOCATION:
2791 case ID_INSERT_EFFECTOR_OPACITY:
2792 case ID_INSERT_EFFECTOR_SIZE:
2793 case ID_INSERT_DEFORMER_HUD:
2794 case ID_INSERT_DEFORMER_WAVE:
2795 case ID_INSERT_DEFORMER_ROTATE:
2796 case ID_INSERT_PIE:
2797 case ID_INSERT_RUNNER:
2798 case ID_INSERT_STYLE_PIE:
2799 case ID_INSERT_STYLE_PALETTE:
2800 InsertNewUIObject( LOWORD( wParam ) );
2801 break;
2803 case ID_EDIT_UNDO:
2805 undo();
2806 break;
2810 case ID_EDIT_DIFF:
2812 if (gCurrentSelection.size() == 2)
2814 UIBaseObject const * const lhsObject = gCurrentSelection.front();
2815 UIBaseObject const * const rhsObject = gCurrentSelection.back();
2817 if (lhsObject && rhsObject)
2819 DiffDialogBox DiffObject;
2820 DiffObject.DiffObjects(gMainWindow, *lhsObject, *rhsObject);
2824 break;
2827 case ID_EDIT_VISIBILITY:
2829 UIBaseObject *SelectedObject = GetSelectedObjectInTreeControl();
2831 UIWidget *SelectedWidget = dynamic_cast<UIWidget *>(SelectedObject);
2832 if(SelectedWidget)
2834 SelectedWidget->SetVisible(!SelectedWidget->IsVisible());
2836 break;
2839 case ID_EDIT_RENAME:
2841 //If treeview window has focus
2842 HWND hwndFocus = GetFocus();
2844 if( hwndFocus == gObjectTree )
2846 //Get selected item. If it exists
2847 HTREEITEM hSelection = TreeView_GetSelection( gObjectTree );
2848 if(hSelection)
2850 //Begin edit on it
2851 TreeView_EditLabel(gObjectTree, hSelection);
2854 break;
2857 case ID_EDIT_DUPLICATE:
2859 UIBaseObject *SelectedObject = GetSelectedObjectInTreeControl();
2861 if( SelectedObject->GetParent() )
2863 UIBaseObject::UIBaseObjectPointer NewObject(SelectedObject->DuplicateObject());
2865 SelectedObject->GetParent()->AddChild( NewObject );
2866 NewObject->Link ();
2868 LoadObjectStructureToTreeControl( gObjectTree, NewObject, TreeView_GetParent( gObjectTree, TreeView_GetSelection( gObjectTree )), TVI_LAST );
2870 break;
2873 case ID_EDIT_COPY:
2875 HWND hwndFocus = GetFocus();
2877 if( hwndFocus == gObjectTree )
2879 CopySelectedObjectInTreeToClipboard( gObjectTree );
2881 else if( hwndFocus == gObjectInspector->GetTextControl() )
2883 SendMessage( gObjectInspector->GetTextControl(), WM_COPY, 0, 0 );
2886 break;
2888 case ID_EDIT_CUT:
2890 HWND hwndFocus = GetFocus();
2892 if( hwndFocus == gObjectTree )
2894 UIBaseObject *o = GetSelectedObjectInTreeControl();
2896 if( o && (o != UIManager::gUIManager().GetRootPage()) )
2898 CopySelectedObjectInTreeToClipboard( gObjectTree );
2899 DeleteSelectedObjectInTree( gObjectTree );
2902 else if( hwndFocus == gObjectInspector->GetTextControl() )
2904 SendMessage( gObjectInspector->GetTextControl(), WM_CUT, 0, 0 );
2907 break;
2909 case ID_EDIT_PASTE:
2911 HWND hwndFocus = GetFocus();
2913 if( hwndFocus == gObjectTree )
2915 PasteObjectFromClipboard( gObjectTree );
2917 else if( hwndFocus == gObjectInspector->GetTextControl() )
2919 SendMessage( gObjectInspector->GetTextControl(), WM_PASTE, 0, 0 );
2922 break;
2924 case ID_EDIT_SORT:
2926 UIBaseObject *o = GetSelectedObjectInTreeControl();
2928 if (o)
2930 SortSelectedObject (gObjectTree);
2932 else
2934 MessageBeep(MB_OK);
2936 break;
2938 break;
2939 case ID_EDIT_DELETE:
2941 UIBaseObject *o = GetSelectedObjectInTreeControl();
2943 if( o && (o != UIManager::gUIManager().GetRootPage()) )
2945 if( MessageBox( hwndDlg, "Are you sure you want to delete this object?", gApplicationName, MB_YESNO ) == IDYES )
2946 DeleteSelectedObjectInTree( gObjectTree );
2948 else
2950 MessageBeep(MB_OK);
2952 break;
2954 case ID_EDIT_PURGEPROPERTY:
2956 UINarrowString PropertyName;
2958 if( gObjectInspector->GetSelectedPropertyName( PropertyName ) )
2959 PurgeSelectedProperty( GetSelectedObjectInTreeControl(), PropertyName );
2961 break;
2963 case ID_VIEW_RUN:
2964 gInVisualEditingMode = !gInVisualEditingMode;
2966 if( !gInVisualEditingMode )
2967 CheckDlgButton( gUIWindow, IDC_PLAY, BST_CHECKED );
2968 else
2969 CheckDlgButton( gUIWindow, IDC_PLAY, BST_UNCHECKED );
2971 break;
2973 case ID_VIEW_CURSOR:
2974 gDrawCursor = !gDrawCursor;
2976 if( gDrawCursor )
2977 CheckDlgButton( gUIWindow, IDC_DRAWCURSOR, BST_CHECKED );
2978 else
2979 CheckDlgButton( gUIWindow, IDC_DRAWCURSOR, BST_UNCHECKED );
2981 break;
2983 case ID_VIEW_HIGHLIGHT:
2984 gDrawHighlightRect = !gDrawHighlightRect;
2986 if( gDrawHighlightRect )
2987 CheckDlgButton( gUIWindow, IDC_DRAWHIGHLIGHT, BST_CHECKED );
2988 else
2989 CheckDlgButton( gUIWindow, IDC_DRAWHIGHLIGHT, BST_UNCHECKED );
2991 break;
2993 case ID_VIEW_GRID:
2994 gDrawGrid = !gDrawGrid;
2996 if( gDrawGrid )
2997 CheckDlgButton( gUIWindow, IDC_DRAWGRID, BST_CHECKED );
2998 else
2999 CheckDlgButton( gUIWindow, IDC_DRAWGRID, BST_UNCHECKED );
3001 break;
3003 case ID_VIEW_SHOWSHADERS:
3005 WaitForSingleObject( gFrameRenderingMutex, INFINITE );
3006 g_showShaders = !gPrimaryDisplay->GetShowShaders ();
3007 gPrimaryDisplay->ShowShaders( g_showShaders);
3008 ReleaseMutex( gFrameRenderingMutex );
3010 break;
3012 case ID_VIEW_DEFAULT_PROPERTIES:
3013 gDefaultObjectPropertiesManager.DisplayEditDialog( hwndDlg );
3014 break;
3016 case ID_VIEW_GRIDSETTINGS:
3017 DialogBox( GetModuleHandle(0), MAKEINTRESOURCE(IDD_GRIDSETTINGS), hwndDlg, GridSettingsDlgProc );
3019 if( gDrawGrid )
3020 CheckDlgButton( gUIWindow, IDC_DRAWGRID, BST_CHECKED );
3021 else
3022 CheckDlgButton( gUIWindow, IDC_DRAWGRID, BST_UNCHECKED );
3024 if( gSnapToGrid )
3025 CheckDlgButton( gUIWindow, IDC_SNAPTOGRID, BST_CHECKED );
3026 else
3027 CheckDlgButton( gUIWindow, IDC_SNAPTOGRID, BST_UNCHECKED );
3028 break;
3030 case ID_VIEW_HIGHLIGHTSETTINGS:
3031 DialogBox( GetModuleHandle(0), MAKEINTRESOURCE(IDD_HIGHLIGHTSETTINGS), hwndDlg, HighlightSettingsDlgProc );
3033 if( gDrawHighlightRect )
3034 CheckDlgButton( gUIWindow, IDC_DRAWHIGHLIGHT, BST_CHECKED );
3035 else
3036 CheckDlgButton( gUIWindow, IDC_DRAWHIGHLIGHT, BST_UNCHECKED );
3037 break;
3039 case IDC_CAPFRAMERATE:
3040 gLimitFrameRate = IsDlgButtonChecked( hwndDlg, IDC_CAPFRAMERATE ) != 0;
3041 break;
3043 case IDC_TOP:
3044 case IDC_UP:
3045 case IDC_DOWN:
3046 case IDC_BOTTOM:
3048 HTREEITEM hSelectedItem = TreeView_GetSelection( gObjectTree );
3050 ProcessReorderButtonEvent( gObjectTree, hSelectedItem, LOWORD( wParam ) );
3051 SetFocus( gObjectTree );
3053 ClearDefPushButtonLook( hwndDlg, LOWORD(wParam) );
3054 EnableButtonControls( hwndDlg, GetSelectedObjectInTreeControl() );
3055 break;
3058 case IDC_BUTTON_BACK:
3060 std::string path;
3061 UIPage * const root = UIManager::gUIManager ().GetRootPage ();
3062 if (root && UIBuilderHistory::back (path))
3064 UIBaseObject * const obj = path == "/root" ? root : root->GetObjectFromPath (path.c_str ());
3066 if (obj)
3068 s_selectionPushOk = false;
3069 HTREEITEM hItemToSelect = GetObjectInTreeControlFromHandle( gObjectTree, 0, obj );
3070 TreeView_SelectItem( gObjectTree, hItemToSelect );
3072 EnableHistoryButtons ();
3075 break;
3077 case IDC_BUTTON_FORWARD:
3079 std::string path;
3080 UIPage * const root = UIManager::gUIManager ().GetRootPage ();
3081 if (root && UIBuilderHistory::forward (path))
3083 UIBaseObject * const obj = path == "/root" ? root : root->GetObjectFromPath (path.c_str ());
3085 if (obj)
3087 s_selectionPushOk = false;
3088 HTREEITEM hItemToSelect = GetObjectInTreeControlFromHandle( gObjectTree, 0, obj );
3089 TreeView_SelectItem( gObjectTree, hItemToSelect );
3091 EnableHistoryButtons ();
3094 break;
3096 case IDC_BUTTON_UP:
3098 if (!gCurrentSelection.empty ())
3100 UIBaseObject * const lastSelected = gCurrentSelection.front ();
3101 UIBaseObject * const parent = lastSelected->GetParent ();
3103 if (parent)
3105 // s_selectionPushOk = false;
3106 HTREEITEM hItemToSelect = GetObjectInTreeControlFromHandle( gObjectTree, 0, parent );
3107 TreeView_SelectItem( gObjectTree, hItemToSelect );
3111 break;
3113 case IDC_RESET:
3115 UIPalette * palette = UIPalette::GetInstance();
3116 if(palette)
3117 palette->Reset();
3119 break;
3121 case ID_HELP_MODIFICATIONLOG:
3122 DialogBox( GetModuleHandle(0), MAKEINTRESOURCE(IDD_MODIFICATION_LOG), hwndDlg, ModificationLogDlgProc );
3123 break;
3125 return 0;
3127 case WM_NOTIFY:
3129 if( wParam == IDC_OBJECTSTRUCTURE )
3131 static struct
3133 UITypeID Type;
3134 int ImageID;
3136 TypeToImageMap[] =
3138 { TUIDeformerHUD, 0 },
3139 { TUIDeformerRotate, 0 },
3140 { TUIDeformerWave, 0 },
3141 { TUIText, 2 },
3142 { TUITextbox, 3 },
3143 { TUIAnimation, 4 },
3144 { TUICheckbox, 5 },
3145 { TUIEllipse, 4 },
3146 { TUIImage, 6 },
3147 { TUIButton, 9 },
3148 { TUIProgressbar, 10 },
3149 { TUIListbox, 11 },
3150 { TUIList, 11 },
3151 { TUIComboBox, 12 },
3152 { TUIDropdownbox, 12 },
3153 { TUINamespace, 13 },
3154 { TUITooltipStyle, 17 },
3155 { TUICursor, 18 },
3156 { TUIDataSource, 19 },
3157 { TUIData, 20 },
3158 { TUITemplate, 21 },
3159 { TUIImageFrame, 23 }, // Frame is a subclass of Fragment so check for it first
3160 { TUIImageFragment, 22 },
3161 { TUITextStyle, 24 },
3162 { TUIFontCharacter, 25 },
3163 { TUIClock, 26 },
3164 { TUIGrid, 27 },
3165 { TUIUnknown, 28 },
3166 { TUISliderplane, 29 },
3167 { TUITabSet, 30 },
3168 { TUITabbedPane, 30 },
3169 { TUIRectangleStyle, 31 },
3170 { TUIPopupMenu, 32 },
3171 { TUIVolumePage, 33 },
3172 { TUIRadialMenu, 34 },
3173 { TUICursorSet, 35 },
3174 { TUITable, 36 },
3175 { TUITableModelDefault,37 },
3176 { TUIDataSourceContainer, 38 },
3177 { TUITableHeader, 39 },
3178 { TUIComposite, 40 },
3179 { TUITreeView, 41 },
3180 { TUIPie, 42 },
3181 { TUIRunner, 43 },
3182 { TUIPalette, 44 },
3183 { TUIPage, 1 }, // some items are subclasses of pages, so check for it last
3184 { TUIObject, 0 } // Last because it's the fallback
3187 LPNMHDR GenericHeader = (LPNMHDR)lParam;
3189 if( GenericHeader->code == TVN_GETDISPINFO )
3191 LPNMTVDISPINFO hdr = (LPNMTVDISPINFO)lParam;
3192 UIBaseObject *w = reinterpret_cast<UIBaseObject *>( hdr->item.lParam );
3194 if( hdr->item.mask & TVIF_IMAGE )
3196 if( w->IsA( TUIScrollbar ) )
3198 UISliderbarStyle * const pStyle = static_cast<UIScrollbar *>(w)->GetSliderbarStyle();
3200 if( pStyle )
3202 if( pStyle->GetLayout() == UIStyle::L_horizontal )
3203 hdr->item.iImage = 7;
3204 else
3205 hdr->item.iImage = 8;
3207 else
3208 hdr->item.iImage = 7;
3210 else if( w->IsA( TUISliderbar ) )
3212 UISliderbarStyle * const pStyle = static_cast<UISliderbar *>(w)->GetSliderbarStyle();
3214 if( pStyle )
3216 if( pStyle->GetLayout() == UIStyle::L_horizontal )
3217 hdr->item.iImage = 15;
3218 else
3219 hdr->item.iImage = 16;
3221 else
3222 hdr->item.iImage = 15;
3224 else
3226 for( int i = 0; i < sizeof( TypeToImageMap ) / sizeof( TypeToImageMap[0] ); ++i )
3228 if( w->IsA( TypeToImageMap[i].Type ) )
3230 hdr->item.iImage = TypeToImageMap[i].ImageID;
3231 break;
3237 if( hdr->item.mask & TVIF_SELECTEDIMAGE )
3239 if( w->IsA( TUIScrollbar ) )
3241 UISliderbarStyle * const pStyle = static_cast<UIScrollbar *>(w)->GetSliderbarStyle();
3243 if( pStyle )
3245 if( pStyle->GetLayout() == UIStyle::L_horizontal )
3246 hdr->item.iSelectedImage = 7;
3247 else
3248 hdr->item.iSelectedImage = 8;
3250 else
3251 hdr->item.iSelectedImage = 7;
3253 else if( w->IsA( TUISliderbar ) )
3255 UISliderbarStyle * const pStyle = static_cast<UISliderbar *>(w)->GetSliderbarStyle();
3257 if( pStyle )
3259 if( pStyle->GetLayout() == UIStyle::L_horizontal )
3260 hdr->item.iSelectedImage = 15;
3261 else
3262 hdr->item.iSelectedImage = 16;
3264 else
3265 hdr->item.iSelectedImage = 15;
3267 else
3269 for( int i = 0; i < sizeof( TypeToImageMap ) / sizeof( TypeToImageMap[0] ); ++i )
3271 if( w->IsA( TypeToImageMap[i].Type ) )
3273 hdr->item.iSelectedImage = TypeToImageMap[i].ImageID;
3274 break;
3280 if( hdr->item.mask & TVIF_CHILDREN )
3282 if( w->GetChildCount() > 0 )
3283 hdr->item.cChildren = 1;
3284 else
3285 hdr->item.cChildren = 0;
3288 if( hdr->item.mask & TVIF_TEXT )
3290 if( w->GetName().empty() )
3291 strncpy( hdr->item.pszText, "Unnamed Object", hdr->item.cchTextMax );
3292 else
3293 strncpy( hdr->item.pszText, w->GetName().c_str(), hdr->item.cchTextMax );
3296 else if( GenericHeader->code == TVN_SELCHANGED )
3298 LPNMTREEVIEW hdr = (LPNMTREEVIEW)lParam;
3299 UIBaseObject *SelectedObject = reinterpret_cast<UIBaseObject *>( hdr->itemNew.lParam );
3301 if( SelectedObject )
3303 if( GetAsyncKeyState( VK_SHIFT ) & 0x80000000 )
3304 AddToSelection( SelectedObject, true );
3305 else if( GetAsyncKeyState( VK_CONTROL ) & 0x80000000 )
3306 RemoveFromSelection( SelectedObject );
3307 else
3308 SetSelection( SelectedObject, s_selectionPushOk );
3310 else
3311 SetSelection( 0, true );
3313 s_selectionPushOk = true;
3315 gObjectInspector->SetObject( SelectedObject );
3316 EnableButtonControls( hwndDlg, SelectedObject );
3318 else if (GenericHeader->code == TVN_BEGINLABELEDIT)
3320 HWND hEdit = TreeView_GetEditControl(gObjectTree);
3321 DWORD style = GetWindowLong(hEdit, GWL_STYLE);
3322 style |= ES_WANTRETURN;
3323 SetWindowLong(hEdit, GWL_STYLE, style);
3325 mOldLabelEditWindowProc = (WNDPROC)GetWindowLong( hEdit, GWL_WNDPROC );
3326 SetWindowLong( hEdit, GWL_WNDPROC, (long)LabelEditWindowProc );
3328 else if (GenericHeader->code == TVN_ENDLABELEDIT )
3330 LPNMTVDISPINFO ptvdi = (LPNMTVDISPINFO) lParam;
3331 if (ptvdi->item.pszText)
3333 RenameSelectedObjectInTree( gObjectTree, ptvdi->item.pszText);
3334 return true;
3337 return false;
3339 else if( GenericHeader->code == TVN_KEYDOWN )
3341 LPNMTVKEYDOWN pKeyDown = (LPNMTVKEYDOWN)lParam;
3343 if( (pKeyDown->wVKey == VK_DELETE) || (pKeyDown->wVKey == VK_BACK) )
3344 SendMessage( hwndDlg, WM_COMMAND, ID_EDIT_DELETE, 0 );
3345 else if( (pKeyDown->wVKey != VK_UP) && (pKeyDown->wVKey != VK_DOWN) &&
3346 (pKeyDown->wVKey != VK_HOME) && (pKeyDown->wVKey != VK_END) &&
3347 (pKeyDown->wVKey != VK_NEXT) && (pKeyDown->wVKey != VK_PRIOR) &&
3348 (pKeyDown->wVKey != VK_CONTROL))
3350 MSG msg;
3352 while( PeekMessage( &msg, gObjectTree, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE ) )
3355 gObjectInspector->SendKeyDown( pKeyDown->wVKey );
3358 // Don't search in the tree!
3359 return 1;
3362 return 0;
3364 case WM_TIMER:
3366 static DWORD LastCall = GetTickCount();
3367 char s[128];
3369 sprintf( s, "%d", gTriangleCount );
3370 SetWindowText( GetDlgItem( hwndDlg, IDC_TRIANGLECOUNT ), s );
3372 sprintf( s, "%d", gFlushCount );
3373 SetWindowText( GetDlgItem( hwndDlg, IDC_FLUSHCOUNT ), s );
3375 if( (GetTickCount() - LastCall) >= 500 )
3377 sprintf( s, "%.2f", 1000.0 * (float)gFrameCount / (float)(GetTickCount() - LastCall) );
3378 SetWindowText( GetDlgItem( hwndDlg, IDC_FRAMERATE ), s );
3379 gFrameCount = 0;
3380 LastCall = GetTickCount();
3382 return 0;
3385 case WM_CLOSE:
3386 return SendMessage( hwndDlg, WM_COMMAND, ID_FILE_EXIT, 0 );
3388 case WM_DESTROY:
3390 clearUndoHistory();
3392 ClearClipboard();
3394 UnhookWindowsHookEx( gTooltipHook );
3395 gTooltipHook = 0;
3396 KillTimer( hwndDlg, 0 );
3398 delete gObjectInspector;
3399 gObjectInspector = 0;
3401 UnloadObjects( hwndDlg );
3403 SetCurrentDirectory( gInitialDirectory.c_str() );
3404 FILE *fp = fopen("defaults.cfg", "wb");
3406 if (fp == 0)
3408 MessageBox(0, "Unable to write defaults.cfg.", gApplicationName, MB_OK );
3410 else
3412 gDefaultObjectPropertiesManager.SaveTo( fp );
3413 fclose( fp );
3416 SavePreferencesToRegistry ();
3417 SaveMRUListToRegistry();
3419 PostQuitMessage(0);
3420 return 0;
3422 default:
3423 return 0;
3427 //-----------------------------------------------------------------
3429 int __stdcall WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow )
3431 UI_UNREF (hPrevInst);
3432 UI_UNREF (lpCmdLine);
3433 UI_UNREF (nCmdShow);
3435 //-- install the ui system
3436 SetupUi::Data setupUiData;
3437 SetupUi::install (setupUiData);
3439 INITCOMMONCONTROLSEX icc = {sizeof(icc), ICC_WIN95_CLASSES};
3440 InitCommonControlsEx( &icc );
3441 HACCEL theAccelerator = LoadAccelerators( hInst, MAKEINTRESOURCE( IDR_MAINACCELERATOR ) );
3443 UIStandardCanvasFactory<DDSCanvasGenerator> theDDSCanvasFactory;
3445 UIManager &theManager = UIManager::gUIManager();
3446 theManager.setUIIMEManager(new UINullIMEManager);
3448 UICursorInterfaceDefault* cursorInterface = new UICursorInterfaceDefault;
3450 theManager.SetCursorInterface (cursorInterface);
3452 FileLocator::gFileLocator ();
3454 theManager.AddCanvasFactory( &theDDSCanvasFactory );
3456 CreateDialog( hInst, MAKEINTRESOURCE( IDD_MAINWINDOW ), 0, (DLGPROC)MainWindowProc );
3458 theManager.SetSoundCanvas ( new SimpleSoundCanvas ());
3460 MSG theMessage;
3461 while( GetMessage( &theMessage, 0, 0, 0 ) )
3463 WaitForSingleObject( gFrameRenderingMutex, INFINITE );
3465 if(!TranslateAccelerator( gMainWindow, theAccelerator, &theMessage ) )
3467 if( !IsDialogMessage( gMainWindow, &theMessage ) && !IsDialogMessage( gUIWindow, &theMessage ) )
3469 TranslateMessage( &theMessage );
3470 DispatchMessage( &theMessage );
3474 ReleaseMutex( gFrameRenderingMutex );
3477 UISoundCanvas * sc = UIManager::gUIManager ().GetSoundCanvas ();
3478 UIManager::gUIManager ().SetSoundCanvas (0);
3479 delete sc;
3481 theManager.SetCursorInterface (0);
3482 delete cursorInterface;
3484 UIManager::ExplicitDestroy();
3486 FileLocator::ExplicitDestroy ();
3488 if( gPrimaryDisplay )
3490 // We better have closed all references to the display
3491 // if( gPrimaryDisplay->GetRefCount() != 1 )
3492 // MessageBox(0, "There is a handle leak: not all references to the primary display were closed.", gApplicationName, MB_OK );
3494 gPrimaryDisplay->Detach();
3495 gPrimaryDisplay = 0;
3498 //-- remove the ui system
3499 SetupUi::remove ();
3501 return theMessage.wParam;
3504 //-----------------------------------------------------------------
3506 void DeleteObjectInTree(HTREEITEM hSelectedItem)
3508 HTREEITEM hNextSelection;
3509 UIPage *RootPage = UIManager::gUIManager().GetRootPage();
3511 if( !hSelectedItem )
3512 return;
3514 UIBaseObject *theObjectToDelete = GetObjectFromNode( hSelectedItem );
3516 if( !theObjectToDelete || (theObjectToDelete == RootPage) )
3517 return;
3519 int allowedReferenceCount = 2; // one for the parent, one for being in the selection
3520 if(theObjectToDelete == gObjectInspector->GetObject())
3521 allowedReferenceCount++;
3523 //-- see if anything has an outstanding reference to this object
3524 if (theObjectToDelete->GetRefCount () > allowedReferenceCount)
3526 char buf [512];
3527 _snprintf(buf, sizeof (buf) - 1, "%s has %d extra outstanding references.\nReally delete it?", theObjectToDelete->GetName().c_str(), theObjectToDelete->GetRefCount() - allowedReferenceCount);
3528 if (MessageBox( gMainWindow, buf, gApplicationName, MB_YESNO ) != IDYES)
3529 return;
3532 hNextSelection = TreeView_GetNextSibling( gObjectTree, hSelectedItem );
3534 if( !hNextSelection )
3536 hNextSelection = TreeView_GetPrevSibling( gObjectTree, hSelectedItem );
3538 //-- don't select parents
3541 RemoveFromSelection( theObjectToDelete );
3542 allowedReferenceCount--;
3544 TreeView_DeleteItem( gObjectTree, hSelectedItem );
3545 WaitForSingleObject( gFrameRenderingMutex, INFINITE );
3547 UIBaseObject *theParent = theObjectToDelete->GetParent();
3549 theObjectToDelete->Attach( 0 );
3551 if( theParent )
3552 theParent->RemoveChild( theObjectToDelete );
3553 allowedReferenceCount--;
3555 //-- if anything has an outstanding reference to this object, relink the whole tree to be safe
3556 if (theObjectToDelete->GetRefCount () > allowedReferenceCount)
3558 //-- set the parent so we can unlink properly
3559 theObjectToDelete->SetParent (theParent);
3561 //-- don't link the root page's children from here
3562 RootPage->UIWidget::Link();
3564 if (theObjectToDelete->GetRefCount () > 1)
3566 UIBaseObject::UIObjectList olist;
3567 RootPage->GetChildren (olist);
3569 for (UIBaseObject::UIObjectList::const_iterator it = olist.begin (); it != olist.end () && theObjectToDelete->GetRefCount () > 1; ++it)
3571 UIBaseObject * const child = *it;
3572 child->Link ();
3575 theObjectToDelete->SetParent (0);
3578 if( theObjectToDelete->IsA( TUIPage ) && (theObjectToDelete->GetParent() == RootPage) )
3579 LoadTopLevelObjectsToTabControl();
3581 TreeView_SelectItem( gObjectTree, hNextSelection );
3583 if( !hNextSelection )
3584 gObjectInspector->SetObject( 0 );
3585 else
3587 TVITEM tvi = {0};
3589 tvi.mask = TVIF_HANDLE;
3590 tvi.hItem = hNextSelection;
3592 TreeView_GetItem( gObjectTree, &tvi );
3594 gObjectInspector->SetObject( reinterpret_cast<UIBaseObject *>( tvi.lParam ) );
3595 TreeView_EnsureVisible( gObjectTree, hNextSelection );
3598 // Do this last
3599 theObjectToDelete->Detach(0);
3600 ReleaseMutex( gFrameRenderingMutex );
3603 //-----------------------------------------------------------------
3605 // To make this work on delete, the parent page needs to be rebuilt.
3607 void RebuildTreeView(UIBaseObject * selectedObject)
3609 ///////////////////////////////////////
3610 // Brute force now.
3611 TreeView_DeleteAllItems(gObjectTree);
3612 LoadObjectStructureToTreeControl(gObjectTree, UIManager::gUIManager().GetRootPage(), 0, TVI_LAST);
3614 if(!selectedObject)
3615 selectedObject = gObjectInspector->GetObject();
3616 if(selectedObject)
3618 TreeItem const * const newItem = getItemInfo(selectedObject);
3619 if(newItem)
3621 TreeView_SelectItem(gObjectTree, newItem->mItem);
3622 TreeView_EnsureVisible(gObjectTree, newItem->mItem);
3623 TreeView_Expand(gObjectTree, newItem->mItem, TVE_EXPAND);
3626 gObjectInspector->SetObject(selectedObject);
3630 // Gets the currently selected file, and checks it out
3631 void CheckOutSelectedFile()
3633 UIBaseObject *obj = gObjectInspector->GetObject();
3634 if(!obj)
3635 return;
3636 UIString sourcePath;
3637 if (UIManager::gUIManager().GetRootPage() == obj)
3639 sourcePath = Unicode::narrowToWide("ui_root.ui");
3641 else
3643 obj->GetProperty(UIBaseObject::PropertyName::SourceFile, sourcePath);
3646 char cmdLine[1024];
3647 sprintf(cmdLine, "p4 edit %s\n\n", Unicode::wideToNarrow(sourcePath).c_str());
3648 system(cmdLine);