doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CPathTreeCtrl.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
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.
13 
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.
18 
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/>.
21 
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.
23 
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.
25 
26 ===========================================================================
27 */
28 
29 #include "../../idlib/precompiled.h"
30 #pragma hdrstop
31 
32 #include "CPathTreeCtrl.h"
33 
34 
35 /*
36 ================
37 CPathTreeCtrl::CPathTreeCtrl
38 ================
39 */
41 }
42 
43 /*
44 ================
45 CPathTreeCtrl::~CPathTreeCtrl
46 ================
47 */
49 }
50 
51 /*
52 ================
53 CPathTreeCtrl::PreSubclassWindow
54 ================
55 */
57  CTreeCtrl::PreSubclassWindow();
58  EnableToolTips( TRUE );
59 }
60 
61 /*
62 ================
63 CPathTreeCtrl::FindItem
64 
65 Find the given path in the tree.
66 ================
67 */
68 HTREEITEM CPathTreeCtrl::FindItem( const idStr &pathName ) {
69  int lastSlash;
70  idStr path, tmpPath, itemName;
71  HTREEITEM item, parentItem;
72 
73  parentItem = NULL;
74  item = GetRootItem();
75 
76  lastSlash = pathName.Last( '/' );
77 
78  while( item && lastSlash > path.Length() ) {
79  itemName = GetItemText( item );
80  tmpPath = path + itemName;
81  if ( pathName.Icmpn( tmpPath, tmpPath.Length() ) == 0 ) {
82  parentItem = item;
83  item = GetChildItem( item );
84  path = tmpPath + "/";
85  } else {
86  item = GetNextSiblingItem( item );
87  }
88  }
89 
90  for ( item = GetChildItem( parentItem ); item; item = GetNextSiblingItem( item ) ) {
91  itemName = GetItemText( item );
92  if ( pathName.Icmp( path + itemName ) == 0 ) {
93  return item;
94  }
95  }
96 
97  return NULL;
98 }
99 
100 /*
101 ================
102 CPathTreeCtrl::InsertPathIntoTree
103 
104 Inserts a new item going from the root down the tree only creating paths where necessary.
105 This is slow and should only be used to insert single items.
106 ================
107 */
108 HTREEITEM CPathTreeCtrl::InsertPathIntoTree( const idStr &pathName, const int id ) {
109  int lastSlash;
110  idStr path, tmpPath, itemName;
111  HTREEITEM item, parentItem;
112 
113  parentItem = NULL;
114  item = GetRootItem();
115 
116  lastSlash = pathName.Last( '/' );
117 
118  while( item && lastSlash > path.Length() ) {
119  itemName = GetItemText( item );
120  tmpPath = path + itemName;
121  if ( pathName.Icmpn( tmpPath, tmpPath.Length() ) == 0 ) {
122  parentItem = item;
123  item = GetChildItem( item );
124  path = tmpPath + "/";
125  } else {
126  item = GetNextSiblingItem( item );
127  }
128  }
129 
130  while( lastSlash > path.Length() ) {
131  pathName.Mid( path.Length(), pathName.Length(), tmpPath );
132  tmpPath.Left( tmpPath.Find( '/' ), itemName );
133  parentItem = InsertItem( itemName, parentItem );
134  path += itemName + "/";
135  }
136 
137  pathName.Mid( path.Length(), pathName.Length(), itemName );
138  item = InsertItem( itemName, parentItem, TVI_SORT );
139  SetItemData( item, id );
140 
141  return item;
142 }
143 
144 /*
145 ================
146 CPathTreeCtrl::AddPathToTree
147 
148 Adds a new item to the tree.
149 Assumes new paths after the current stack path do not yet exist.
150 ================
151 */
152 HTREEITEM CPathTreeCtrl::AddPathToTree( const idStr &pathName, const int id, idPathTreeStack &stack ) {
153  int lastSlash;
154  idStr itemName, tmpPath;
155  HTREEITEM item;
156 
157  lastSlash = pathName.Last( '/' );
158 
159  while( stack.Num() > 1 ) {
160  if ( pathName.Icmpn( stack.TopName(), stack.TopNameLength() ) == 0 ) {
161  break;
162  }
163  stack.Pop();
164  }
165 
166  while( lastSlash > stack.TopNameLength() ) {
167  pathName.Mid( stack.TopNameLength(), pathName.Length(), tmpPath );
168  tmpPath.Left( tmpPath.Find( '/' ), itemName );
169  item = InsertItem( itemName, stack.TopItem() );
170  stack.Push( item, itemName );
171  }
172 
173  pathName.Mid( stack.TopNameLength(), pathName.Length(), itemName );
174  item = InsertItem( itemName, stack.TopItem() );
175  SetItemData( item, id );
176 
177  return item;
178 }
179 
180 /*
181 ================
182 CPathTreeCtrl::SearchTree
183 
184 Search the three using the search string.
185 Adds the matched tree items to the result tree.
186 Returns the number of items added to the result tree.
187 ================
188 */
190  idPathTreeStack stack, searchStack;
191  HTREEITEM item, child;
192  idStr name;
193  int id, numItems;
194 
195  numItems = 0;
196  result.DeleteAllItems();
197  stack.PushRoot( NULL );
198 
199  item = GetRootItem();
200  searchStack.PushRoot( item );
201  id = 0;
202 
203  while( searchStack.Num() > 0 ) {
204 
205  for ( child = GetChildItem( item ); child; child = GetChildItem( child ) ) {
206  searchStack.Push( item, GetItemText( item ) );
207  item = child;
208  }
209 
210  name = searchStack.TopName();
211  name += GetItemText( item );
212  id = GetItemData( item );
213 
214  if ( compare( data, item, name ) ) {
215  result.AddPathToTree( name, id, stack );
216  numItems++;
217  }
218 
219  for ( item = GetNextSiblingItem( item ); item == NULL; ) {
220  item = GetNextSiblingItem( searchStack.TopItem() );
221  searchStack.Pop();
222  if ( searchStack.Num() <= 0 ) {
223  return numItems;
224  }
225  }
226  }
227 
228  return numItems;
229 }
230 
231 BEGIN_MESSAGE_MAP(CPathTreeCtrl,CTreeCtrl)
232  //{{AFX_MSG_MAP(CPathTreeCtrl)
233  ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
234  ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
235  ON_WM_MOUSEMOVE()
236  //}}AFX_MSG_MAP
237 END_MESSAGE_MAP()
238 
239 /*
240 ================
241 CPathTreeCtrl::OnToolHitTest
242 ================
243 */
244 int CPathTreeCtrl::OnToolHitTest( CPoint point, TOOLINFO * pTI ) const {
245  RECT rect;
246 
247  UINT nFlags;
248  HTREEITEM hitem = HitTest( point, &nFlags );
249  if( nFlags & TVHT_ONITEM ) {
250  GetItemRect( hitem, &rect, TRUE );
251  pTI->hwnd = m_hWnd;
252  pTI->uId = (UINT)hitem;
253  pTI->lpszText = LPSTR_TEXTCALLBACK;
254  pTI->rect = rect;
255  return pTI->uId;
256  }
257  return -1;
258 }
259 
260 /*
261 ================
262 CPathTreeCtrl::OnToolTipText
263 ================
264 */
265 BOOL CPathTreeCtrl::OnToolTipText( UINT id, NMHDR * pNMHDR, LRESULT * pResult ) {
266  // need to handle both ANSI and UNICODE versions of the message
267  TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
268  TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
269 
270  UINT nID = pNMHDR->idFrom;
271 
272  *pResult = 0;
273 
274  // Do not process the message from built in tooltip
275  if( nID == (UINT)m_hWnd &&
276  (( pNMHDR->code == TTN_NEEDTEXTA && pTTTA->uFlags & TTF_IDISHWND ) ||
277  ( pNMHDR->code == TTN_NEEDTEXTW && pTTTW->uFlags & TTF_IDISHWND ) ) ) {
278  return FALSE;
279  }
280 
281  CString toolTip = "?";
282 
283  // Get the mouse position
284  const MSG* pMessage;
285  CPoint pt;
286  pMessage = GetCurrentMessage();
287  ASSERT ( pMessage );
288  pt = pMessage->pt;
289  ScreenToClient( &pt );
290 
291  // get the tree item
292  UINT nFlags;
293  HTREEITEM hitem = HitTest( pt, &nFlags );
294 
295  if( nFlags & TVHT_ONITEM ) {
296  // relay message to parent
297  pTTTA->hdr.hwndFrom = GetSafeHwnd();
298  pTTTA->hdr.idFrom = (UINT) hitem;
299  if ( GetParent()->SendMessage( WM_NOTIFY, ( TTN_NEEDTEXT << 16 ) | GetDlgCtrlID(), (LPARAM)pTTTA ) == FALSE ) {
300  return FALSE;
301  }
302  }
303 
304  return TRUE; // message was handled
305 }
HTREEITEM FindItem(const idStr &pathName)
int Num(void) const
Definition: CPathTreeCtrl.h:50
CONST PIXELFORMATDESCRIPTOR UINT
Definition: win_qgl.cpp:47
int Length(void) const
Definition: Str.h:702
afx_msg BOOL OnToolTipText(UINT id, NMHDR *pNMHDR, LRESULT *pResult)
const char * Left(int len, idStr &result) const
Definition: Str.h:892
void Pop(void)
Definition: CPathTreeCtrl.h:46
bool(* treeItemCompare_t)(void *data, HTREEITEM item, const char *name)
Definition: CPathTreeCtrl.h:72
#define BOOL
Definition: mprintf.c:71
Boolean result
int Icmp(const char *text) const
Definition: Str.h:667
int Icmpn(const char *text, int n) const
Definition: Str.h:672
void Push(HTREEITEM item, const char *name)
Definition: CPathTreeCtrl.h:65
int SearchTree(treeItemCompare_t compare, void *data, CPathTreeCtrl &result)
#define NULL
Definition: Lib.h:88
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:2853
virtual void PreSubclassWindow()
const char * path
Definition: sws.c:117
int Find(const char c, int start=0, int end=-1) const
Definition: Str.h:874
HTREEITEM InsertPathIntoTree(const idStr &pathName, const int id)
HTREEITEM AddPathToTree(const idStr &pathName, const int id, idPathTreeStack &stack)
const char * Mid(int start, int len, idStr &result) const
Definition: Str.cpp:603
void PushRoot(HTREEITEM root)
Definition: CPathTreeCtrl.h:58
GLuint id
Definition: glext.h:3103
MFnDagNode * GetParent(MFnDagNode *joint)
Definition: maya_main.cpp:350
int Last(const char c) const
Definition: Str.cpp:452
const GLcharARB * name
Definition: glext.h:3629
Definition: Str.h:116
#define FALSE
Definition: mprintf.c:70
#define TRUE
Definition: mprintf.c:69
const char * TopName(void) const
Definition: CPathTreeCtrl.h:48
int TopNameLength(void) const
Definition: CPathTreeCtrl.h:49
HTREEITEM TopItem(void) const
Definition: CPathTreeCtrl.h:47