2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
26 ===========================================================================
29 #include "../../idlib/precompiled.h"
32 #include "../../sys/win32/rc/guied_resource.h"
36 #define GENAV_ITEMHEIGHT 22
38 rvGENavigator::rvGENavigator ( )
44 mVisibleIconDisabled = NULL;
45 mScriptsLightIcon = NULL;
52 Creates the navigator window
55 bool rvGENavigator::Create ( HWND parent, bool visible )
58 memset ( &wndClass, 0, sizeof(wndClass) );
59 wndClass.cbSize = sizeof(WNDCLASSEX);
60 wndClass.lpszClassName = "GUIEDITOR_NAVIGATOR_CLASS";
61 wndClass.lpfnWndProc = rvGENavigator::WndProc;
62 wndClass.hbrBackground = (HBRUSH)GetStockObject( LTGRAY_BRUSH );;
63 wndClass.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW);
64 wndClass.lpszMenuName = NULL;
65 wndClass.hInstance = win32.hInstance;
66 RegisterClassEx ( &wndClass );
68 mVisibleIcon = (HICON)LoadImage ( win32.hInstance, MAKEINTRESOURCE(IDI_GUIED_NAV_VISIBLE), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS );
69 mScriptsIcon = (HICON)LoadImage ( win32.hInstance, MAKEINTRESOURCE(IDI_GUIED_NAV_SCRIPTS), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR );
70 mScriptsLightIcon = (HICON)LoadImage ( win32.hInstance, MAKEINTRESOURCE(IDI_GUIED_NAV_SCRIPTSHI), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR );
71 mVisibleIconDisabled = (HICON)LoadImage ( win32.hInstance, MAKEINTRESOURCE(IDI_GUIED_NAV_VISIBLEDISABLED), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS );
72 mExpandIcon = (HICON)LoadImage ( win32.hInstance, MAKEINTRESOURCE(IDI_GUIED_NAV_EXPAND), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS );
73 mCollapseIcon = (HICON)LoadImage ( win32.hInstance, MAKEINTRESOURCE(IDI_GUIED_NAV_COLLAPSE), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS );
75 mWnd = CreateWindowEx ( WS_EX_TOOLWINDOW,
76 "GUIEDITOR_NAVIGATOR_CLASS",
78 WS_SYSMENU|WS_THICKFRAME|WS_CAPTION|WS_POPUP|WS_OVERLAPPED|WS_BORDER|WS_CLIPSIBLINGS|WS_CHILD,
90 if ( !gApp.GetOptions().GetWindowPlacement ( "navigator", mWnd ) )
95 GetWindowRect ( parent, &rParent );
96 GetWindowRect ( mWnd, &rNav );
97 SetWindowPos ( mWnd, NULL,
98 rParent.right - 10 - (rNav.right-rNav.left),
99 rParent.bottom - 10 - (rNav.bottom-rNav.top),
101 SWP_NOZORDER|SWP_NOSIZE );
113 Draws a 3d rectangle using the given brushes
116 void Draw3dRect ( HDC hDC, RECT* rect, HBRUSH topLeft, HBRUSH bottomRight )
120 SetRect ( &rOut, rect->left, rect->top, rect->right - 1, rect->top + 1 );
121 FillRect ( hDC,&rOut, topLeft );
123 SetRect ( &rOut, rect->left, rect->top, rect->left + 1, rect->bottom );
124 FillRect( hDC,&rOut, topLeft );
126 SetRect ( &rOut, rect->right, rect->top, rect->right -1, rect->bottom );
127 FillRect( hDC,&rOut, bottomRight );
129 SetRect ( &rOut, rect->left, rect->bottom, rect->right, rect->bottom - 1 );
130 FillRect( hDC,&rOut, bottomRight );
135 rvGENavigator::WndProc
140 LRESULT CALLBACK rvGENavigator::WndProc ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
142 rvGENavigator* nav = (rvGENavigator*) GetWindowLong ( hWnd, GWL_USERDATA );
146 case WM_INITMENUPOPUP:
147 return SendMessage ( gApp.GetMDIFrame ( ), msg, wParam, lParam );
150 common->ActivateTool( LOWORD( wParam ) != WA_INACTIVE );
157 gApp.GetOptions().SetWindowPlacement ( "navigator", hWnd );
161 gApp.GetOptions().SetNavigatorVisible ( false );
167 DRAWITEMSTRUCT* dis = (DRAWITEMSTRUCT*) lParam;
168 idWindow* window = (idWindow*)dis->itemData;
172 rvGEWindowWrapper* wrapper = rvGEWindowWrapper::GetWrapper ( window );
173 idStr name = window->GetName();
178 idWindow* parent = window;
181 while ( parent = parent->GetParent ( ) )
183 if ( rvGEWindowWrapper::GetWrapper ( parent )->IsHidden ( ) )
191 CopyRect ( &rDraw, &dis->rcItem );
192 rDraw.right = rDraw.left + GENAV_ITEMHEIGHT;
196 FrameRect ( dis->hDC, &rDraw, (HBRUSH)GetStockObject ( BLACK_BRUSH ) );
199 FillRect ( dis->hDC, &rDraw, GetSysColorBrush ( COLOR_3DFACE ) );
201 Draw3dRect ( dis->hDC, &rDraw, GetSysColorBrush ( COLOR_3DHILIGHT ), GetSysColorBrush ( COLOR_3DSHADOW ) );
203 InflateRect ( &rDraw, -3, -3 );
204 Draw3dRect ( dis->hDC, &rDraw, GetSysColorBrush ( COLOR_3DSHADOW ), GetSysColorBrush ( COLOR_3DHILIGHT ) );
206 if ( !wrapper->IsHidden ( ) )
208 DrawIconEx ( dis->hDC, rDraw.left, rDraw.top, disabled?nav->mVisibleIconDisabled:nav->mVisibleIcon, 16, 16,0, NULL, DI_NORMAL );
211 CopyRect ( &rDraw, &dis->rcItem );
212 rDraw.left += GENAV_ITEMHEIGHT;
215 if ( dis->itemState & ODS_SELECTED )
217 FillRect ( dis->hDC, &rDraw, GetSysColorBrush ( COLOR_HIGHLIGHT ) );
221 FillRect ( dis->hDC, &rDraw, GetSysColorBrush ( COLOR_WINDOW ) );
224 if ( wrapper->CanHaveChildren ( ) && window->GetChildCount ( ) )
226 if ( wrapper->IsExpanded ( ) )
228 DrawIconEx ( dis->hDC, rDraw.left + offset, rDraw.top + 3, nav->mCollapseIcon, 16, 16,0, NULL, DI_NORMAL );
232 DrawIconEx ( dis->hDC, rDraw.left + offset, rDraw.top + 3, nav->mExpandIcon, 16, 16,0, NULL, DI_NORMAL );
236 HPEN pen = CreatePen ( PS_SOLID, 1, GetSysColor ( COLOR_3DSHADOW ) );
237 HPEN oldpen = (HPEN)SelectObject ( dis->hDC, pen );
238 MoveToEx ( dis->hDC, rDraw.left, dis->rcItem.top, NULL );
239 LineTo ( dis->hDC, dis->rcItem.right, dis->rcItem.top );
240 MoveToEx ( dis->hDC, rDraw.left, dis->rcItem.bottom, NULL );
241 LineTo ( dis->hDC, dis->rcItem.right, dis->rcItem.bottom);
242 SelectObject ( dis->hDC, oldpen );
243 DeleteObject ( pen );
245 rDraw.left += offset;
248 int colorIndex = ( (dis->itemState & ODS_SELECTED ) ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT );
249 SetTextColor ( dis->hDC, GetSysColor ( colorIndex ) );
250 DrawText ( dis->hDC, name, name.Length(), &rDraw, DT_LEFT|DT_VCENTER|DT_SINGLELINE );
252 if ( wrapper->GetVariableDict().GetNumKeyVals ( ) || wrapper->GetScriptDict().GetNumKeyVals ( ) )
254 DrawIconEx ( dis->hDC, dis->rcItem.right - 16, (dis->rcItem.bottom+dis->rcItem.top)/2-6, (dis->itemState & ODS_SELECTED)?nav->mScriptsLightIcon:nav->mScriptsIcon, 13, 13,0, NULL, DI_NORMAL );
263 MEASUREITEMSTRUCT* mis = (MEASUREITEMSTRUCT*) lParam;
264 mis->itemHeight = 22;
273 // Attach the class to the window first
274 cs = (LPCREATESTRUCT) lParam;
275 nav = (rvGENavigator*) cs->lpCreateParams;
276 SetWindowLong ( hWnd, GWL_USERDATA, (LONG)nav );
278 // Create the List view
279 nav->mTree = CreateWindowEx ( 0, "SysListView32", "", WS_VSCROLL|WS_CHILD|WS_VISIBLE|LVS_REPORT|LVS_OWNERDRAWFIXED|LVS_NOCOLUMNHEADER|LVS_SHOWSELALWAYS, 0, 0, 0, 0, hWnd, (HMENU)IDC_GUIED_WINDOWTREE, win32.hInstance, 0 );
280 ListView_SetExtendedListViewStyle ( nav->mTree, LVS_EX_FULLROWSELECT );
281 ListView_SetBkColor ( nav->mTree, GetSysColor ( COLOR_3DFACE ) );
282 ListView_SetTextBkColor ( nav->mTree, GetSysColor ( COLOR_3DFACE ) );
283 nav->mListWndProc = (WNDPROC)GetWindowLong ( nav->mTree, GWL_WNDPROC );
284 SetWindowLong ( nav->mTree, GWL_USERDATA, (LONG)nav );
285 SetWindowLong ( nav->mTree, GWL_WNDPROC, (LONG)ListWndProc );
287 // Insert the only column
289 ListView_InsertColumn ( nav->mTree, 0, &col );
297 MoveWindow ( nav->mTree, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE );
298 GetClientRect ( nav->mTree, &rClient );
299 ListView_SetColumnWidth ( nav->mTree, 0, rClient.right-rClient.left-1 );
304 return gApp.ToolWindowActivate ( gApp.GetMDIFrame(), msg, wParam, lParam );
310 nh = (LPNMHDR) lParam;
317 DWORD dwpos = GetMessagePos();
319 info.pt.x = LOWORD(dwpos);
320 info.pt.y = HIWORD(dwpos);
321 MapWindowPoints(HWND_DESKTOP, nh->hwndFrom, &info.pt, 1);
322 int index = ListView_HitTest ( nav->mTree, &info );
327 ListView_GetItemRect ( nav->mTree, index, &rItem, LVIR_BOUNDS );
329 item.mask = LVIF_PARAM;
331 ListView_GetItem ( nav->mTree, &item );
332 idWindow* window = (idWindow*)item.lParam;
333 rvGEWindowWrapper* wrapper = rvGEWindowWrapper::GetWrapper(window);
335 offset = wrapper->GetDepth ( ) * 10 + 1;
337 if ( info.pt.x < GENAV_ITEMHEIGHT )
339 if ( !rvGEWindowWrapper::GetWrapper(window)->IsHidden ( ) )
341 nav->mWorkspace->HideWindow ( window );
345 nav->mWorkspace->UnhideWindow ( window );
348 else if ( info.pt.x > GENAV_ITEMHEIGHT + offset && info.pt.x < GENAV_ITEMHEIGHT + offset + 16 )
350 if ( wrapper->CanHaveChildren ( ) && window->GetChildCount ( ) )
352 if ( wrapper->IsExpanded ( ) )
354 wrapper->Collapse ( );
364 else if ( nh->code == NM_DBLCLK )
366 SendMessage ( gApp.GetMDIFrame ( ), WM_COMMAND, MAKELONG(ID_GUIED_ITEM_PROPERTIES,0), 0 );
375 DWORD dwpos = GetMessagePos();
377 info.pt.x = LOWORD(dwpos);
378 info.pt.y = HIWORD(dwpos);
379 MapWindowPoints(HWND_DESKTOP, nh->hwndFrom, &info.pt, 1);
380 int index = ListView_HitTest ( nav->mTree, &info );
384 ClientToScreen ( hWnd, &info.pt );
385 HMENU menu = GetSubMenu ( LoadMenu ( gApp.GetInstance(), MAKEINTRESOURCE(IDR_GUIED_ITEM_POPUP) ), 0 );
386 TrackPopupMenu ( menu, TPM_RIGHTBUTTON|TPM_LEFTALIGN, info.pt.x, info.pt.y, 0, gApp.GetMDIFrame ( ), NULL );
387 DestroyMenu ( menu );
393 case LVN_ITEMCHANGED:
395 NMLISTVIEW* nml = (NMLISTVIEW*) nh;
396 if ( (nml->uNewState & LVIS_SELECTED) != (nml->uOldState & LVIS_SELECTED) )
399 item.iItem = nml->iItem;
400 item.mask = LVIF_PARAM;
401 ListView_GetItem ( nav->mTree, &item );
403 if ( nml->uNewState & LVIS_SELECTED )
405 nav->mWorkspace->GetSelectionMgr().Add ( (idWindow*)item.lParam, false );
409 nav->mWorkspace->GetSelectionMgr().Remove ( (idWindow*)item.lParam );
420 return DefWindowProc ( hWnd, msg, wParam, lParam );
425 rvGENavigator::ListWndProc
427 Window Procedure for the embedded list control
430 LRESULT CALLBACK rvGENavigator::ListWndProc ( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
432 rvGENavigator* nav = (rvGENavigator*) GetWindowLong ( hWnd, GWL_USERDATA );
440 if ( nav->mWorkspace )
442 return SendMessage ( nav->mWorkspace->GetWindow(), msg, wParam, lParam );
447 return CallWindowProc ( nav->mListWndProc, hWnd, msg, wParam, lParam );
452 rvGENavigator::AddWindow
454 Adds a new window to the navigator
457 void rvGENavigator::AddWindow ( idWindow* window )
461 rvGEWindowWrapper* wrapper;
463 wrapper = rvGEWindowWrapper::GetWrapper ( window );
465 // Dont add deleted windows
466 if ( !wrapper || wrapper->IsDeleted ( ) )
471 // Insert the window into the tree
472 ZeroMemory ( &item, sizeof(item) );
473 item.mask = LVIF_PARAM|LVIF_STATE|LVIF_IMAGE;
474 item.iItem = ListView_GetItemCount ( mTree );
475 item.lParam = (LONG) window;
477 item.state = rvGEWindowWrapper::GetWrapper(window)->IsSelected ()? LVIS_SELECTED:0;
478 item.stateMask = LVIS_SELECTED;
479 ListView_InsertItem ( mTree, &item );
481 if ( item.state & LVIS_SELECTED )
483 ListView_EnsureVisible ( mTree, item.iItem, false );
486 // Dont continue if not expanded.
487 if ( !wrapper->IsExpanded ( ) )
492 // Insert all the child windows into the tree
493 for ( index = 0; index < wrapper->GetChildCount(); index ++ )
495 AddWindow ( wrapper->GetChild(index) );
501 rvGENavigator::SetWorkspace
503 Sets a new workspace for the navigator window
506 void rvGENavigator::SetWorkspace ( rvGEWorkspace* workspace )
508 mWorkspace = workspace;
515 rvGENavigator::Update
517 Updates the contents of the navigator window from the current workspace
520 void rvGENavigator::Update ( void )
522 // Clear the list first
523 ListView_DeleteAllItems ( mTree );
525 // Add starting with the desktop window
528 AddWindow ( mWorkspace->GetInterface ( )->GetDesktop ( ) );
531 // For some reason the horizontal scrollbar wants to show up initially after an update
532 // so this forces it not to
534 GetClientRect ( mTree, &rClient );
535 ListView_SetColumnWidth ( mTree, 0, rClient.right-rClient.left-1 );
540 rvGENavigator::UpdateSelection
542 Updates the currently selected items
545 void rvGENavigator::UpdateSelections ( void )
547 int count = ListView_GetItemCount ( mTree );
550 for ( i = 0; i < count; i++ )
554 rvGEWindowWrapper* wrapper;
557 item.mask = LVIF_PARAM;
558 ListView_GetItem ( mTree, &item );
559 window = (idWindow*) item.lParam;
560 wrapper = rvGEWindowWrapper::GetWrapper ( window );
562 ListView_SetItemState ( mTree, i, wrapper->IsSelected ( )?LVIS_SELECTED:0, LVIS_SELECTED );
564 if ( wrapper->IsSelected ( ) )
566 ListView_EnsureVisible ( mTree, i, false );
573 rvGENavigator::Refresh
575 Repaints the navigator window
578 void rvGENavigator::Refresh ( void )
580 InvalidateRect ( mTree, NULL, FALSE );
581 // UpdateWindow ( mTree );
588 Shows and hides the navigator window
591 void rvGENavigator::Show ( bool visible )
593 gApp.GetOptions().SetNavigatorVisible ( visible );
594 ShowWindow ( mWnd, visible?SW_SHOW:SW_HIDE );