]>
Commit | Line | Data |
---|---|---|
c801d85f KB |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: treectrl.cpp | |
f135ff73 | 3 | // Purpose: generic tree control implementation |
c801d85f KB |
4 | // Author: Robert Roebling |
5 | // Created: 01/02/97 | |
f135ff73 | 6 | // Modified: 22/10/98 - almost total rewrite, simpler interface (VZ) |
389cdc7a | 7 | // Id: $Id$ |
c801d85f | 8 | // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem |
29d87bba | 9 | // Licence: wxWindows licence |
c801d85f KB |
10 | ///////////////////////////////////////////////////////////////////////////// |
11 | ||
f135ff73 VZ |
12 | // ============================================================================= |
13 | // declarations | |
14 | // ============================================================================= | |
15 | ||
16 | // ----------------------------------------------------------------------------- | |
17 | // headers | |
18 | // ----------------------------------------------------------------------------- | |
19 | ||
c801d85f | 20 | #ifdef __GNUG__ |
f135ff73 | 21 | #pragma implementation "treectrl.h" |
c801d85f KB |
22 | #endif |
23 | ||
24 | #include "wx/treectrl.h" | |
25 | #include "wx/settings.h" | |
389cdc7a | 26 | #include "wx/log.h" |
f135ff73 VZ |
27 | #include "wx/intl.h" |
28 | #include "wx/dynarray.h" | |
29 | #include "wx/dcclient.h" | |
c801d85f | 30 | |
f135ff73 VZ |
31 | // ----------------------------------------------------------------------------- |
32 | // array types | |
33 | // ----------------------------------------------------------------------------- | |
c801d85f | 34 | |
f135ff73 | 35 | WX_DEFINE_ARRAY(wxGenericTreeItem *, wxArrayTreeItems); |
c801d85f | 36 | |
f135ff73 VZ |
37 | // ----------------------------------------------------------------------------- |
38 | // private classes | |
39 | // ----------------------------------------------------------------------------- | |
40 | ||
41 | // a tree item | |
42 | class WXDLLEXPORT wxGenericTreeItem | |
c801d85f | 43 | { |
f135ff73 VZ |
44 | public: |
45 | // ctors & dtor | |
46 | wxGenericTreeItem() { m_data = NULL; } | |
47 | wxGenericTreeItem( wxGenericTreeItem *parent, | |
48 | const wxString& text, | |
49 | wxDC& dc, | |
50 | int image, int selImage, | |
51 | wxTreeItemData *data ); | |
52 | ||
53 | inline ~wxGenericTreeItem(); | |
54 | ||
55 | // trivial accessors | |
56 | wxArrayTreeItems& GetChildren() { return m_children; } | |
57 | ||
58 | const wxString& GetText() const { return m_text; } | |
59 | int GetImage() const { return m_image; } | |
60 | int GetSelectedImage() const { return m_selImage; } | |
61 | wxTreeItemData *GetData() const { return m_data; } | |
62 | ||
63 | void SetText( const wxString &text, wxDC& dc ); | |
64 | void SetImage(int image) { m_image = image; } | |
65 | void SetSelectedImage(int image) { m_selImage = image; } | |
66 | void SetData(wxTreeItemData *data) { m_data = data; } | |
67 | ||
68 | void SetHasPlus(bool has = TRUE) { m_hasPlus = has; } | |
69 | ||
70 | int GetX() const { return m_x; } | |
71 | int GetY() const { return m_y; } | |
72 | ||
73 | void SetHeight(int h) { m_height = h; } | |
74 | ||
75 | void SetX(int x) { m_x = x; } | |
76 | void SetY(int y) { m_y = y; } | |
77 | ||
78 | wxGenericTreeItem *GetParent() const { return m_parent; } | |
c801d85f | 79 | |
f135ff73 VZ |
80 | // operations |
81 | void Reset(); | |
82 | ||
83 | // get count of all children (and grand children and ...) of this item | |
84 | size_t GetTotalNumberOfChildren() const; | |
85 | ||
86 | void Insert(wxGenericTreeItem *child, size_t index) | |
87 | { m_children.Insert(child, index); } | |
88 | ||
89 | void SetCross( int x, int y ); | |
90 | void GetSize( int &x, int &y ); | |
91 | ||
92 | // return the item at given position (or NULL if no item), onButton is TRUE | |
93 | // if the point belongs to the item's button, otherwise it lies on the | |
94 | // button's label | |
95 | wxGenericTreeItem *HitTest( const wxPoint& point, bool &onButton ); | |
96 | ||
97 | void Expand() { m_isCollapsed = FALSE; } | |
98 | void Collapse() { m_isCollapsed = TRUE; } | |
99 | ||
100 | void SetHilight( bool set = TRUE ) { m_hasHilight = set; } | |
101 | ||
102 | // status inquiries | |
103 | bool HasChildren() const { return !m_children.IsEmpty(); } | |
104 | bool HasHilight() const { return m_hasHilight; } | |
105 | bool IsExpanded() const { return !m_isCollapsed; } | |
106 | bool HasPlus() const { return m_hasPlus || HasChildren(); } | |
107 | ||
108 | private: | |
109 | wxString m_text; | |
110 | ||
111 | int m_image, | |
112 | m_selImage; | |
113 | ||
114 | wxTreeItemData *m_data; | |
115 | ||
116 | // @@ probably should use bitfields to save size | |
117 | bool m_isCollapsed, | |
118 | m_hasHilight, // same as focused | |
119 | m_hasPlus; // used for item which doesn't have | |
120 | // children but still has a [+] button | |
121 | ||
122 | int m_x, m_y; | |
123 | long m_height, m_width; | |
124 | int m_xCross, m_yCross; | |
125 | int m_level; | |
126 | wxArrayTreeItems m_children; | |
127 | wxGenericTreeItem *m_parent; | |
128 | }; | |
129 | ||
130 | // ============================================================================= | |
131 | // implementation | |
132 | // ============================================================================= | |
133 | ||
134 | // ----------------------------------------------------------------------------- | |
c801d85f | 135 | // wxTreeEvent |
f135ff73 | 136 | // ----------------------------------------------------------------------------- |
c801d85f | 137 | |
f135ff73 | 138 | IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent, wxCommandEvent) |
c801d85f | 139 | |
f135ff73 VZ |
140 | wxTreeEvent::wxTreeEvent( wxEventType commandType, int id ) |
141 | : wxCommandEvent( commandType, id ) | |
c801d85f KB |
142 | { |
143 | m_code = 0; | |
f135ff73 | 144 | m_itemOld = (wxGenericTreeItem *)NULL; |
edaa81ae | 145 | } |
c801d85f | 146 | |
f135ff73 | 147 | // ----------------------------------------------------------------------------- |
c801d85f | 148 | // wxGenericTreeItem |
f135ff73 | 149 | // ----------------------------------------------------------------------------- |
c801d85f | 150 | |
f135ff73 VZ |
151 | wxGenericTreeItem::wxGenericTreeItem(wxGenericTreeItem *parent, |
152 | const wxString& text, | |
153 | wxDC& dc, | |
154 | int image, int selImage, | |
155 | wxTreeItemData *data) | |
156 | : m_text(text) | |
c801d85f | 157 | { |
f135ff73 VZ |
158 | m_image = image; |
159 | m_selImage = selImage; | |
160 | m_data = data; | |
161 | m_x = m_y = 0; | |
162 | m_xCross = m_yCross = 0; | |
163 | ||
164 | m_level = 0; | |
165 | ||
166 | m_isCollapsed = TRUE; | |
c801d85f | 167 | m_hasHilight = FALSE; |
c801d85f | 168 | |
c801d85f | 169 | m_parent = parent; |
f135ff73 VZ |
170 | |
171 | dc.GetTextExtent( m_text, &m_width, &m_height ); | |
edaa81ae | 172 | } |
c801d85f | 173 | |
f135ff73 | 174 | wxGenericTreeItem::~wxGenericTreeItem() |
c801d85f | 175 | { |
f135ff73 VZ |
176 | delete m_data; |
177 | ||
178 | size_t count = m_children.Count(); | |
179 | for ( size_t n = 0; n < count; n++ ) | |
180 | delete m_children[n]; | |
edaa81ae | 181 | } |
c801d85f | 182 | |
f135ff73 | 183 | void wxGenericTreeItem::SetText( const wxString &text, wxDC& dc ) |
c801d85f KB |
184 | { |
185 | m_text = text; | |
f135ff73 VZ |
186 | |
187 | dc.GetTextExtent( m_text, &m_width, &m_height ); | |
edaa81ae | 188 | } |
c801d85f | 189 | |
74bedbeb | 190 | void wxGenericTreeItem::Reset() |
c801d85f | 191 | { |
f135ff73 VZ |
192 | m_text.Empty(); |
193 | m_image = | |
194 | m_selImage = -1; | |
195 | m_data = NULL; | |
196 | m_x = m_y = | |
197 | m_height = m_width = 0; | |
198 | m_xCross = | |
c801d85f | 199 | m_yCross = 0; |
74bedbeb | 200 | |
f135ff73 | 201 | m_level = 0; |
c801d85f | 202 | |
f135ff73 VZ |
203 | m_children.Empty(); |
204 | m_isCollapsed = TRUE; | |
c801d85f | 205 | |
f135ff73 | 206 | m_parent = (wxGenericTreeItem *)NULL; |
edaa81ae | 207 | } |
c801d85f | 208 | |
f135ff73 | 209 | size_t wxGenericTreeItem::GetTotalNumberOfChildren() const |
c801d85f | 210 | { |
f135ff73 VZ |
211 | size_t count = m_children.Count(); |
212 | size_t total = count; | |
213 | for ( size_t n = 0; n < count; n++ ) | |
c801d85f | 214 | { |
f135ff73 | 215 | total += m_children[n]->GetTotalNumberOfChildren(); |
edaa81ae | 216 | } |
c801d85f | 217 | |
f135ff73 | 218 | return total; |
edaa81ae | 219 | } |
c801d85f KB |
220 | |
221 | void wxGenericTreeItem::SetCross( int x, int y ) | |
222 | { | |
223 | m_xCross = x; | |
224 | m_yCross = y; | |
edaa81ae | 225 | } |
c801d85f KB |
226 | |
227 | void wxGenericTreeItem::GetSize( int &x, int &y ) | |
228 | { | |
f135ff73 VZ |
229 | // FIXME what does this all mean?? |
230 | if ( y < m_y + 10 ) y = m_y +10; | |
c801d85f KB |
231 | int width = m_x + m_width; |
232 | if (width > x) x = width; | |
f135ff73 VZ |
233 | |
234 | size_t count = m_children.Count(); | |
235 | for ( size_t n = 0; n < count; n++ ) | |
c801d85f | 236 | { |
f135ff73 | 237 | m_children[n]->GetSize( x, y ); |
edaa81ae RR |
238 | } |
239 | } | |
c801d85f | 240 | |
f135ff73 VZ |
241 | wxGenericTreeItem *wxGenericTreeItem::HitTest( const wxPoint& point, |
242 | bool &onButton ) | |
c801d85f | 243 | { |
f135ff73 | 244 | if ((point.y > m_y) && (point.y < m_y + m_height)) |
c801d85f | 245 | { |
f135ff73 VZ |
246 | // FIXME why +5? |
247 | if ((point.x > m_xCross-5) && (point.x < m_xCross+5) && | |
248 | (point.y > m_yCross-5) && (point.y < m_yCross+5) && | |
f9f950fc | 249 | (IsExpanded() || HasPlus())) |
c801d85f | 250 | { |
f135ff73 VZ |
251 | onButton = TRUE; |
252 | return this; | |
edaa81ae | 253 | } |
f135ff73 | 254 | |
c801d85f KB |
255 | if ((point.x > m_x) && (point.x < m_x+m_width)) |
256 | { | |
f135ff73 VZ |
257 | onButton = FALSE; |
258 | return this; | |
edaa81ae | 259 | } |
c801d85f KB |
260 | } |
261 | else | |
262 | { | |
e2414cbe | 263 | if (!m_isCollapsed) |
c801d85f | 264 | { |
f135ff73 VZ |
265 | size_t count = m_children.Count(); |
266 | for ( size_t n = 0; n < count; n++ ) | |
e2414cbe | 267 | { |
f135ff73 VZ |
268 | wxGenericTreeItem *res = m_children[n]->HitTest( point, onButton ); |
269 | if ( res != NULL ) | |
270 | return res; | |
edaa81ae RR |
271 | } |
272 | } | |
273 | } | |
f135ff73 VZ |
274 | |
275 | return NULL; | |
edaa81ae | 276 | } |
c801d85f | 277 | |
f135ff73 VZ |
278 | // ----------------------------------------------------------------------------- |
279 | // wxTreeCtrl implementation | |
280 | // ----------------------------------------------------------------------------- | |
281 | ||
282 | IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxScrolledWindow) | |
283 | ||
284 | BEGIN_EVENT_TABLE(wxTreeCtrl,wxScrolledWindow) | |
285 | EVT_PAINT (wxTreeCtrl::OnPaint) | |
286 | EVT_MOUSE_EVENTS (wxTreeCtrl::OnMouse) | |
287 | EVT_CHAR (wxTreeCtrl::OnChar) | |
288 | EVT_SET_FOCUS (wxTreeCtrl::OnSetFocus) | |
289 | EVT_KILL_FOCUS (wxTreeCtrl::OnKillFocus) | |
290 | END_EVENT_TABLE() | |
291 | ||
292 | // ----------------------------------------------------------------------------- | |
293 | // construction/destruction | |
294 | // ----------------------------------------------------------------------------- | |
295 | void wxTreeCtrl::Init() | |
c801d85f | 296 | { |
f135ff73 VZ |
297 | m_current = |
298 | m_anchor = (wxGenericTreeItem *) NULL; | |
299 | m_hasFocus = FALSE; | |
300 | ||
301 | m_xScroll = 0; | |
302 | m_yScroll = 0; | |
303 | m_lineHeight = 10; | |
304 | m_indent = 15; | |
305 | ||
306 | m_hilightBrush = new wxBrush | |
307 | ( | |
308 | wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT), | |
309 | wxSOLID | |
310 | ); | |
311 | ||
312 | m_imageListNormal = | |
313 | m_imageListState = (wxImageList *) NULL; | |
edaa81ae | 314 | } |
c801d85f | 315 | |
f135ff73 VZ |
316 | bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id, |
317 | const wxPoint& pos, const wxSize& size, | |
318 | long style, const wxString& name ) | |
c801d85f | 319 | { |
f135ff73 VZ |
320 | Init(); |
321 | ||
322 | wxScrolledWindow::Create( parent, id, pos, size, style, name ); | |
323 | ||
324 | SetBackgroundColour( *wxWHITE ); | |
325 | m_dottedPen = wxPen( *wxBLACK, 0, 0 ); | |
326 | ||
327 | return TRUE; | |
edaa81ae | 328 | } |
c801d85f | 329 | |
f135ff73 | 330 | wxTreeCtrl::~wxTreeCtrl() |
c801d85f | 331 | { |
f135ff73 VZ |
332 | wxDELETE( m_hilightBrush ); |
333 | wxDELETE( m_anchor ); | |
edaa81ae | 334 | } |
c801d85f | 335 | |
f135ff73 VZ |
336 | // ----------------------------------------------------------------------------- |
337 | // accessors | |
338 | // ----------------------------------------------------------------------------- | |
339 | ||
340 | size_t wxTreeCtrl::GetCount() const | |
c801d85f | 341 | { |
f135ff73 | 342 | return m_anchor == NULL ? 0u : m_anchor->GetTotalNumberOfChildren(); |
edaa81ae | 343 | } |
c801d85f | 344 | |
f135ff73 | 345 | void wxTreeCtrl::SetIndent(unsigned int indent) |
c801d85f | 346 | { |
f135ff73 VZ |
347 | m_indent = indent; |
348 | Refresh(); | |
349 | } | |
74bedbeb | 350 | |
f135ff73 VZ |
351 | // ----------------------------------------------------------------------------- |
352 | // functions to work with tree items | |
353 | // ----------------------------------------------------------------------------- | |
74bedbeb | 354 | |
f135ff73 VZ |
355 | wxString wxTreeCtrl::GetItemText(const wxTreeItemId& item) const |
356 | { | |
357 | return item.m_pItem->GetText(); | |
edaa81ae | 358 | } |
74bedbeb | 359 | |
f135ff73 | 360 | int wxTreeCtrl::GetItemImage(const wxTreeItemId& item) const |
74bedbeb | 361 | { |
f135ff73 | 362 | return item.m_pItem->GetImage(); |
edaa81ae | 363 | } |
c801d85f | 364 | |
f135ff73 | 365 | int wxTreeCtrl::GetItemSelectedImage(const wxTreeItemId& item) const |
c801d85f | 366 | { |
f135ff73 | 367 | return item.m_pItem->GetSelectedImage(); |
edaa81ae | 368 | } |
c801d85f | 369 | |
f135ff73 | 370 | wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const |
c801d85f | 371 | { |
f135ff73 | 372 | return item.m_pItem->GetData(); |
edaa81ae | 373 | } |
c801d85f | 374 | |
f135ff73 VZ |
375 | void wxTreeCtrl::SetItemText(const wxTreeItemId& item, const wxString& text) |
376 | { | |
377 | wxClientDC dc(this); | |
de646ed1 | 378 | item.m_pItem->SetText(text, dc); |
f135ff73 | 379 | } |
c801d85f | 380 | |
f135ff73 VZ |
381 | void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image) |
382 | { | |
de646ed1 | 383 | item.m_pItem->SetImage(image); |
f135ff73 | 384 | } |
c801d85f | 385 | |
f135ff73 | 386 | void wxTreeCtrl::SetItemSelectedImage(const wxTreeItemId& item, int image) |
c801d85f | 387 | { |
de646ed1 | 388 | item.m_pItem->SetSelectedImage(image); |
edaa81ae | 389 | } |
c801d85f | 390 | |
f135ff73 | 391 | void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data) |
c801d85f | 392 | { |
de646ed1 | 393 | item.m_pItem->SetData(data); |
edaa81ae | 394 | } |
c801d85f | 395 | |
f135ff73 | 396 | void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has) |
c801d85f | 397 | { |
f135ff73 | 398 | item.m_pItem->SetHasPlus(has); |
edaa81ae | 399 | } |
c801d85f | 400 | |
f135ff73 VZ |
401 | // ----------------------------------------------------------------------------- |
402 | // item status inquiries | |
403 | // ----------------------------------------------------------------------------- | |
404 | ||
405 | bool wxTreeCtrl::IsVisible(const wxTreeItemId& item) const | |
c801d85f | 406 | { |
f135ff73 VZ |
407 | wxFAIL_MSG("not implemented"); |
408 | ||
c801d85f | 409 | return TRUE; |
edaa81ae | 410 | } |
c801d85f | 411 | |
f135ff73 | 412 | bool wxTreeCtrl::ItemHasChildren(const wxTreeItemId& item) const |
c801d85f | 413 | { |
f135ff73 | 414 | return !item.m_pItem->GetChildren().IsEmpty(); |
edaa81ae | 415 | } |
c801d85f | 416 | |
f135ff73 | 417 | bool wxTreeCtrl::IsExpanded(const wxTreeItemId& item) const |
c801d85f | 418 | { |
f135ff73 VZ |
419 | return item.m_pItem->IsExpanded(); |
420 | } | |
29d87bba | 421 | |
f135ff73 VZ |
422 | bool wxTreeCtrl::IsSelected(const wxTreeItemId& item) const |
423 | { | |
424 | return item.m_pItem->HasHilight(); | |
425 | } | |
29d87bba | 426 | |
f135ff73 VZ |
427 | // ----------------------------------------------------------------------------- |
428 | // navigation | |
429 | // ----------------------------------------------------------------------------- | |
29d87bba | 430 | |
f135ff73 VZ |
431 | wxTreeItemId wxTreeCtrl::GetParent(const wxTreeItemId& item) const |
432 | { | |
433 | wxCHECK_MSG( item.IsOk(), NULL, "invalid tree item" ); | |
389cdc7a | 434 | |
f135ff73 VZ |
435 | return item.m_pItem->GetParent(); |
436 | } | |
29d87bba | 437 | |
f135ff73 VZ |
438 | wxTreeItemId wxTreeCtrl::GetFirstChild(const wxTreeItemId& item, long& cookie) const |
439 | { | |
440 | wxCHECK_MSG( item.IsOk(), NULL, "invalid tree item" ); | |
29d87bba | 441 | |
f135ff73 VZ |
442 | cookie = 0; |
443 | return GetNextChild(item, cookie); | |
444 | } | |
29d87bba | 445 | |
f135ff73 VZ |
446 | wxTreeItemId wxTreeCtrl::GetNextChild(const wxTreeItemId& item, long& cookie) const |
447 | { | |
448 | wxCHECK_MSG( item.IsOk(), NULL, "invalid tree item" ); | |
29d87bba | 449 | |
f135ff73 VZ |
450 | return item.m_pItem->GetChildren().Item(cookie++); |
451 | } | |
29d87bba | 452 | |
f135ff73 VZ |
453 | wxTreeItemId wxTreeCtrl::GetNextSibling(const wxTreeItemId& item) const |
454 | { | |
455 | wxCHECK_MSG( item.IsOk(), NULL, "invalid tree item" ); | |
456 | ||
457 | wxGenericTreeItem *i = item.m_pItem; | |
458 | wxGenericTreeItem *parent = i->GetParent(); | |
459 | if ( parent == NULL ) | |
460 | { | |
461 | // root item doesn't have any siblings | |
462 | return NULL; | |
edaa81ae | 463 | } |
f135ff73 VZ |
464 | |
465 | wxArrayTreeItems& siblings = parent->GetChildren(); | |
466 | int index = siblings.Index(i); | |
467 | wxASSERT( index != NOT_FOUND ); // I'm not a child of my parent? | |
29d87bba | 468 | |
f135ff73 | 469 | size_t n = (size_t)(index + 1); |
de646ed1 | 470 | return n == siblings.Count() ? (wxGenericTreeItem*)NULL : siblings[n]; |
edaa81ae | 471 | } |
c801d85f | 472 | |
f135ff73 | 473 | wxTreeItemId wxTreeCtrl::GetPrevSibling(const wxTreeItemId& item) const |
c801d85f | 474 | { |
f135ff73 VZ |
475 | wxCHECK_MSG( item.IsOk(), NULL, "invalid tree item" ); |
476 | ||
477 | wxGenericTreeItem *i = item.m_pItem; | |
478 | wxGenericTreeItem *parent = i->GetParent(); | |
479 | if ( parent == NULL ) | |
c801d85f | 480 | { |
f135ff73 VZ |
481 | // root item doesn't have any siblings |
482 | return NULL; | |
edaa81ae | 483 | } |
f135ff73 VZ |
484 | |
485 | wxArrayTreeItems& siblings = parent->GetChildren(); | |
486 | int index = siblings.Index(i); | |
487 | wxASSERT( index != NOT_FOUND ); // I'm not a child of my parent? | |
29d87bba | 488 | |
de646ed1 | 489 | return index == 0 ? (wxGenericTreeItem*)NULL : siblings[(size_t)(index - 1)]; |
f135ff73 | 490 | } |
389cdc7a | 491 | |
f135ff73 VZ |
492 | wxTreeItemId wxTreeCtrl::GetFirstVisibleItem() const |
493 | { | |
494 | wxFAIL_MSG("not implemented"); | |
29d87bba | 495 | |
f135ff73 VZ |
496 | return NULL; |
497 | } | |
29d87bba | 498 | |
f135ff73 VZ |
499 | wxTreeItemId wxTreeCtrl::GetNextVisible(const wxTreeItemId& item) const |
500 | { | |
501 | wxCHECK_MSG( item.IsOk(), NULL, "invalid tree item" ); | |
29d87bba | 502 | |
f135ff73 | 503 | wxFAIL_MSG("not implemented"); |
29d87bba | 504 | |
f135ff73 VZ |
505 | return NULL; |
506 | } | |
29d87bba | 507 | |
f135ff73 VZ |
508 | wxTreeItemId wxTreeCtrl::GetPrevVisible(const wxTreeItemId& item) const |
509 | { | |
510 | wxCHECK_MSG( item.IsOk(), NULL, "invalid tree item" ); | |
29d87bba | 511 | |
f135ff73 | 512 | wxFAIL_MSG("not implemented"); |
29d87bba | 513 | |
f135ff73 | 514 | return NULL; |
edaa81ae | 515 | } |
c801d85f | 516 | |
f135ff73 VZ |
517 | // ----------------------------------------------------------------------------- |
518 | // operations | |
519 | // ----------------------------------------------------------------------------- | |
520 | ||
521 | wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parentId, | |
522 | size_t previous, | |
523 | const wxString& text, | |
524 | int image, int selImage, | |
525 | wxTreeItemData *data) | |
c801d85f | 526 | { |
f135ff73 VZ |
527 | wxGenericTreeItem *parent = parentId.m_pItem; |
528 | if ( !parent ) | |
529 | { | |
530 | // should we give a warning here? | |
531 | return AddRoot(text, image, selImage, data); | |
532 | } | |
533 | ||
534 | wxClientDC dc(this); | |
535 | wxGenericTreeItem *item = new wxGenericTreeItem(parent, | |
536 | text, dc, | |
537 | image, selImage, | |
538 | data); | |
74bedbeb | 539 | |
f135ff73 | 540 | if ( data != NULL ) |
c801d85f | 541 | { |
f135ff73 VZ |
542 | data->m_pItem = item; |
543 | } | |
74bedbeb | 544 | |
f135ff73 | 545 | parent->Insert( item, previous ); |
29d87bba | 546 | |
f135ff73 | 547 | CalculatePositions(); |
389cdc7a | 548 | |
f135ff73 VZ |
549 | int cw, ch; |
550 | GetClientSize( &cw, &ch ); | |
74bedbeb | 551 | |
f135ff73 | 552 | PrepareDC( dc ); |
74bedbeb | 553 | |
f135ff73 VZ |
554 | wxRectangle rect; |
555 | rect.x = dc.LogicalToDeviceX( 0 ); | |
556 | rect.y = 0; | |
557 | rect.width = 10000; // @@@ not very elegant... | |
d4c99d6f | 558 | rect.height = ch; |
74bedbeb | 559 | |
f135ff73 VZ |
560 | if ( previous != 0 ) |
561 | { | |
562 | rect.y = dc.LogicalToDeviceY( parent->GetChildren().Item(previous)->GetY() ); | |
563 | } | |
564 | else // it's the 1st child | |
565 | { | |
566 | rect.y = dc.LogicalToDeviceY( parent->GetY() ); | |
567 | } | |
c801d85f | 568 | |
f135ff73 | 569 | AdjustMyScrollbars(); |
389cdc7a | 570 | |
f135ff73 VZ |
571 | if ( rect.height > 0 ) |
572 | Refresh( FALSE, &rect ); | |
389cdc7a | 573 | |
f135ff73 | 574 | return item; |
4c681997 RR |
575 | } |
576 | ||
f135ff73 VZ |
577 | wxTreeItemId wxTreeCtrl::AddRoot(const wxString& text, |
578 | int image, int selImage, | |
579 | wxTreeItemData *data) | |
4c681997 | 580 | { |
f135ff73 | 581 | wxCHECK_MSG( !m_anchor, NULL, "tree can have only one root" ); |
389cdc7a | 582 | |
f135ff73 VZ |
583 | wxClientDC dc(this); |
584 | m_anchor = new wxGenericTreeItem((wxGenericTreeItem *)NULL, text, dc, | |
585 | image, selImage, data); | |
586 | if ( data != NULL ) | |
587 | { | |
588 | data->m_pItem = m_anchor; | |
589 | } | |
389cdc7a | 590 | |
f135ff73 | 591 | AdjustMyScrollbars(); |
a32dd690 | 592 | Refresh(); |
a32dd690 | 593 | |
f135ff73 | 594 | return m_anchor; |
edaa81ae | 595 | } |
c801d85f | 596 | |
f135ff73 VZ |
597 | wxTreeItemId wxTreeCtrl::PrependItem(const wxTreeItemId& parent, |
598 | const wxString& text, | |
599 | int image, int selImage, | |
600 | wxTreeItemData *data) | |
c801d85f | 601 | { |
f135ff73 | 602 | return DoInsertItem(parent, 0u, text, image, selImage, data); |
edaa81ae | 603 | } |
c801d85f | 604 | |
f135ff73 VZ |
605 | wxTreeItemId wxTreeCtrl::InsertItem(const wxTreeItemId& parentId, |
606 | const wxTreeItemId& idPrevious, | |
607 | const wxString& text, | |
608 | int image, int selImage, | |
609 | wxTreeItemData *data) | |
c801d85f | 610 | { |
f135ff73 VZ |
611 | wxGenericTreeItem *parent = parentId.m_pItem; |
612 | if ( !parent ) | |
613 | { | |
614 | // should we give a warning here? | |
615 | return AddRoot(text, image, selImage, data); | |
616 | } | |
c801d85f | 617 | |
f135ff73 VZ |
618 | int index = parent->GetChildren().Index(idPrevious.m_pItem); |
619 | wxASSERT_MSG( index != NOT_FOUND, | |
620 | "previous item in wxTreeCtrl::InsertItem() is not a sibling" ); | |
621 | return DoInsertItem(parentId, (size_t)index, text, image, selImage, data); | |
edaa81ae | 622 | } |
c801d85f | 623 | |
f135ff73 VZ |
624 | wxTreeItemId wxTreeCtrl::AppendItem(const wxTreeItemId& parentId, |
625 | const wxString& text, | |
626 | int image, int selImage, | |
627 | wxTreeItemData *data) | |
74bedbeb | 628 | { |
f135ff73 VZ |
629 | wxGenericTreeItem *parent = parentId.m_pItem; |
630 | if ( !parent ) | |
631 | { | |
632 | // should we give a warning here? | |
633 | return AddRoot(text, image, selImage, data); | |
634 | } | |
635 | ||
636 | return DoInsertItem(parent, parent->GetChildren().Count(), text, | |
637 | image, selImage, data); | |
74bedbeb VZ |
638 | } |
639 | ||
f135ff73 | 640 | void wxTreeCtrl::Delete(const wxTreeItemId& itemId) |
c801d85f | 641 | { |
f135ff73 VZ |
642 | wxGenericTreeItem *item = itemId.m_pItem; |
643 | ||
644 | delete item; | |
645 | ||
646 | Refresh(); | |
edaa81ae | 647 | } |
c801d85f | 648 | |
f135ff73 | 649 | void wxTreeCtrl::DeleteAllItems() |
c801d85f | 650 | { |
f135ff73 VZ |
651 | if ( m_anchor ) |
652 | { | |
653 | delete m_anchor; | |
654 | m_anchor = NULL; | |
655 | ||
656 | Refresh(); | |
657 | } | |
edaa81ae RR |
658 | } |
659 | ||
f135ff73 | 660 | void wxTreeCtrl::Expand(const wxTreeItemId& itemId) |
edaa81ae | 661 | { |
f135ff73 VZ |
662 | wxGenericTreeItem *item = itemId.m_pItem; |
663 | ||
664 | if ( item->IsExpanded() ) | |
665 | return; | |
666 | ||
667 | wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_EXPANDING, GetId() ); | |
668 | event.m_item = item; | |
669 | event.SetEventObject( this ); | |
670 | if ( ProcessEvent( event ) && event.m_code ) | |
671 | { | |
672 | // cancelled by program | |
673 | return; | |
674 | } | |
675 | ||
676 | item->Expand(); | |
677 | ||
678 | RefreshSubtree(item); | |
679 | ||
680 | event.SetEventType(wxEVT_COMMAND_TREE_ITEM_EXPANDED); | |
681 | ProcessEvent( event ); | |
edaa81ae RR |
682 | } |
683 | ||
f135ff73 | 684 | void wxTreeCtrl::Collapse(const wxTreeItemId& itemId) |
edaa81ae | 685 | { |
f135ff73 VZ |
686 | wxGenericTreeItem *item = itemId.m_pItem; |
687 | ||
688 | if ( !item->IsExpanded() ) | |
689 | return; | |
690 | ||
691 | wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_COLLAPSING, GetId() ); | |
692 | event.m_item = item; | |
693 | event.SetEventObject( this ); | |
694 | if ( ProcessEvent( event ) && event.m_code ) | |
edaa81ae | 695 | { |
f135ff73 VZ |
696 | // cancelled by program |
697 | return; | |
698 | } | |
699 | ||
700 | item->Collapse(); | |
701 | ||
702 | wxArrayTreeItems& children = item->GetChildren(); | |
703 | size_t count = children.Count(); | |
704 | for ( size_t n = 0; n < count; n++ ) | |
705 | { | |
706 | Collapse(children[n]); | |
edaa81ae | 707 | } |
f135ff73 VZ |
708 | |
709 | CalculatePositions(); | |
710 | ||
711 | RefreshSubtree(item); | |
712 | ||
713 | event.SetEventType(wxEVT_COMMAND_TREE_ITEM_COLLAPSED); | |
714 | ProcessEvent( event ); | |
edaa81ae | 715 | } |
c801d85f | 716 | |
f135ff73 | 717 | void wxTreeCtrl::CollapseAndReset(const wxTreeItemId& item) |
c801d85f | 718 | { |
f135ff73 VZ |
719 | Collapse(item); |
720 | Delete(item); | |
edaa81ae | 721 | } |
c801d85f | 722 | |
f135ff73 | 723 | void wxTreeCtrl::Toggle(const wxTreeItemId& itemId) |
c801d85f | 724 | { |
f135ff73 | 725 | wxGenericTreeItem *item = itemId.m_pItem; |
389cdc7a | 726 | |
f135ff73 VZ |
727 | if ( item->IsExpanded() ) |
728 | Collapse(itemId); | |
729 | else | |
730 | Expand(itemId); | |
731 | } | |
389cdc7a | 732 | |
f135ff73 VZ |
733 | void wxTreeCtrl::Unselect() |
734 | { | |
735 | if ( m_current ) | |
736 | { | |
737 | m_current->SetHilight( FALSE ); | |
738 | RefreshLine( m_current ); | |
739 | } | |
edaa81ae | 740 | } |
c801d85f | 741 | |
f135ff73 | 742 | void wxTreeCtrl::SelectItem(const wxTreeItemId& itemId) |
389cdc7a | 743 | { |
f135ff73 VZ |
744 | wxGenericTreeItem *item = itemId.m_pItem; |
745 | ||
746 | if ( m_current != item ) | |
389cdc7a | 747 | { |
f135ff73 VZ |
748 | wxTreeEvent event( wxEVT_COMMAND_TREE_SEL_CHANGING, GetId() ); |
749 | event.m_item = item; | |
750 | event.m_itemOld = m_current; | |
751 | event.SetEventObject( this ); | |
752 | if ( ProcessEvent( event ) && event.WasVetoed() ) | |
753 | return; | |
754 | ||
755 | if ( m_current ) | |
389cdc7a VZ |
756 | { |
757 | m_current->SetHilight( FALSE ); | |
758 | RefreshLine( m_current ); | |
edaa81ae | 759 | } |
f135ff73 | 760 | |
389cdc7a VZ |
761 | m_current = item; |
762 | m_current->SetHilight( TRUE ); | |
763 | RefreshLine( m_current ); | |
764 | ||
f135ff73 VZ |
765 | event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGED); |
766 | ProcessEvent( event ); | |
389cdc7a VZ |
767 | } |
768 | } | |
769 | ||
f135ff73 | 770 | void wxTreeCtrl::EnsureVisible(const wxTreeItemId& item) |
c801d85f | 771 | { |
f135ff73 | 772 | wxFAIL_MSG("not implemented"); |
edaa81ae | 773 | } |
c801d85f | 774 | |
f135ff73 | 775 | void wxTreeCtrl::ScrollTo(const wxTreeItemId& item) |
c801d85f | 776 | { |
f135ff73 | 777 | wxFAIL_MSG("not implemented"); |
edaa81ae | 778 | } |
c801d85f | 779 | |
f135ff73 VZ |
780 | wxTextCtrl *wxTreeCtrl::EditLabel(const wxTreeItemId& item, |
781 | wxClassInfo* textCtrlClass) | |
c801d85f | 782 | { |
f135ff73 | 783 | wxFAIL_MSG("not implemented"); |
c801d85f | 784 | |
f135ff73 | 785 | return NULL; |
edaa81ae | 786 | } |
c801d85f | 787 | |
f135ff73 | 788 | wxTextCtrl *wxTreeCtrl::GetEditControl() const |
c801d85f | 789 | { |
f135ff73 | 790 | wxFAIL_MSG("not implemented"); |
c801d85f | 791 | |
f135ff73 | 792 | return NULL; |
edaa81ae | 793 | } |
c801d85f | 794 | |
f135ff73 | 795 | void wxTreeCtrl::EndEditLabel(const wxTreeItemId& item, bool discardChanges) |
74bedbeb | 796 | { |
f135ff73 | 797 | wxFAIL_MSG("not implemented"); |
74bedbeb VZ |
798 | } |
799 | ||
f135ff73 VZ |
800 | void wxTreeCtrl::SortChildren(const wxTreeItemId& item, |
801 | wxTreeItemCmpFunc *cmpFunction) | |
edaa81ae | 802 | { |
f135ff73 | 803 | wxFAIL_MSG("not implemented"); |
edaa81ae RR |
804 | } |
805 | ||
f135ff73 VZ |
806 | // ----------------------------------------------------------------------------- |
807 | // images are not currently supported, but we still provide stubs for these | |
808 | // functions | |
809 | // ----------------------------------------------------------------------------- | |
810 | wxImageList *wxTreeCtrl::GetImageList() const | |
edaa81ae | 811 | { |
f135ff73 | 812 | return m_imageListNormal; |
edaa81ae RR |
813 | } |
814 | ||
f135ff73 | 815 | wxImageList *wxTreeCtrl::GetStateImageList() const |
c801d85f | 816 | { |
f135ff73 | 817 | return m_imageListState; |
edaa81ae | 818 | } |
c801d85f | 819 | |
f135ff73 | 820 | void wxTreeCtrl::SetImageList(wxImageList *imageList) |
e2414cbe | 821 | { |
f135ff73 | 822 | m_imageListNormal = imageList; |
edaa81ae | 823 | } |
e2414cbe | 824 | |
f135ff73 | 825 | void wxTreeCtrl::SetStateImageList(wxImageList *imageList) |
e2414cbe | 826 | { |
f135ff73 | 827 | m_imageListState = imageList; |
edaa81ae | 828 | } |
e2414cbe | 829 | |
f135ff73 VZ |
830 | // ----------------------------------------------------------------------------- |
831 | // helpers | |
832 | // ----------------------------------------------------------------------------- | |
74bedbeb | 833 | void wxTreeCtrl::AdjustMyScrollbars() |
c801d85f KB |
834 | { |
835 | if (m_anchor) | |
836 | { | |
837 | int x = 0; | |
838 | int y = 0; | |
839 | m_anchor->GetSize( x, y ); | |
840 | y += 2*m_lineHeight; | |
841 | int x_pos = GetScrollPos( wxHORIZONTAL ); | |
842 | int y_pos = GetScrollPos( wxVERTICAL ); | |
843 | SetScrollbars( 10, 10, x/10, y/10, x_pos, y_pos ); | |
844 | } | |
845 | else | |
846 | { | |
847 | SetScrollbars( 0, 0, 0, 0 ); | |
edaa81ae RR |
848 | } |
849 | } | |
c801d85f | 850 | |
16c1f7f3 | 851 | void wxTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxDC &dc, int level, int &y ) |
c801d85f | 852 | { |
4c681997 | 853 | int horizX = level*m_indent; |
389cdc7a | 854 | |
f135ff73 VZ |
855 | item->SetX( horizX+33 ); |
856 | item->SetY( y-m_lineHeight/3 ); | |
857 | item->SetHeight( m_lineHeight ); | |
389cdc7a | 858 | |
4c681997 RR |
859 | item->SetCross( horizX+15, y ); |
860 | ||
c801d85f | 861 | int oldY = y; |
389cdc7a | 862 | |
d4c99d6f | 863 | int exposed_x = dc.LogicalToDeviceX( 0 ); |
f135ff73 | 864 | int exposed_y = dc.LogicalToDeviceY( item->GetY()-2 ); |
d4c99d6f RR |
865 | |
866 | if (IsExposed( exposed_x, exposed_y, 1000, m_lineHeight+4 )) | |
c801d85f | 867 | { |
4c681997 RR |
868 | int startX = horizX; |
869 | int endX = horizX + 10; | |
29d87bba | 870 | |
4c681997 | 871 | if (!item->HasChildren()) endX += 20; |
d4c99d6f | 872 | |
389cdc7a | 873 | dc.DrawLine( startX, y, endX, y ); |
29d87bba | 874 | |
f135ff73 VZ |
875 | if (item->HasPlus()) |
876 | { | |
877 | dc.DrawLine( horizX+20, y, horizX+30, y ); | |
878 | dc.SetPen( *wxGREY_PEN ); | |
879 | dc.DrawRectangle( horizX+10, y-4, 11, 9 ); | |
880 | dc.SetPen( *wxBLACK_PEN ); | |
881 | dc.DrawLine( horizX+13, y, horizX+18, y ); | |
882 | ||
883 | if (!item->IsExpanded()) | |
884 | dc.DrawLine( horizX+15, y-2, horizX+15, y+3 ); | |
885 | } | |
c801d85f | 886 | |
f135ff73 VZ |
887 | if (item->HasHilight()) |
888 | { | |
889 | dc.SetTextForeground( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) ); | |
890 | dc.SetBrush( *m_hilightBrush ); | |
891 | long tw, th; | |
892 | dc.GetTextExtent( item->GetText(), &tw, &th ); | |
893 | if (m_hasFocus) | |
c801d85f | 894 | { |
29d87bba | 895 | dc.SetPen( *wxBLACK_PEN ); |
f135ff73 | 896 | dc.DrawRectangle( item->GetX()-2, item->GetY()-2, tw+4, th+4 ); |
29d87bba VZ |
897 | } |
898 | else | |
4c681997 | 899 | { |
389cdc7a | 900 | dc.SetPen( *wxTRANSPARENT_PEN ); |
f135ff73 | 901 | dc.DrawRectangle( item->GetX()-2, item->GetY()-2, tw+4, th+4 ); |
edaa81ae | 902 | } |
f135ff73 VZ |
903 | dc.DrawText( item->GetText(), item->GetX(), item->GetY() ); |
904 | ||
905 | dc.SetPen( *wxBLACK_PEN ); | |
906 | dc.SetTextForeground( *wxBLACK ); | |
907 | dc.SetBrush( *wxWHITE_BRUSH ); | |
908 | } | |
909 | else | |
910 | { | |
911 | dc.SetBrush( *wxWHITE_BRUSH ); | |
912 | dc.SetPen( *wxTRANSPARENT_PEN ); | |
913 | long tw, th; | |
914 | dc.GetTextExtent( item->GetText(), &tw, &th ); | |
915 | dc.DrawRectangle( item->GetX()-2, item->GetY()-2, tw+4, th+4 ); | |
916 | dc.DrawText( item->GetText(), item->GetX(), item->GetY() ); | |
917 | dc.SetPen( *wxBLACK_PEN ); | |
918 | } | |
edaa81ae | 919 | } |
4c681997 | 920 | |
f135ff73 VZ |
921 | if ( !item->IsExpanded() ) |
922 | return; | |
e2414cbe | 923 | |
389cdc7a VZ |
924 | int semiOldY = y; |
925 | ||
f135ff73 VZ |
926 | wxArrayTreeItems& children = item->GetChildren(); |
927 | size_t count = children.Count(); | |
928 | for ( size_t n = 0; n < count; n++ ) | |
4c681997 | 929 | { |
c801d85f | 930 | y += m_lineHeight; |
e2414cbe | 931 | semiOldY = y; |
389cdc7a | 932 | |
f135ff73 | 933 | PaintLevel( children[n], dc, level+1, y ); |
edaa81ae | 934 | } |
4c681997 | 935 | |
e2414cbe | 936 | dc.DrawLine( horizX+15, oldY+5, horizX+15, semiOldY ); |
4c681997 | 937 | } |
c801d85f | 938 | |
f135ff73 VZ |
939 | // ----------------------------------------------------------------------------- |
940 | // wxWindows callbacks | |
941 | // ----------------------------------------------------------------------------- | |
942 | ||
c801d85f KB |
943 | void wxTreeCtrl::OnPaint( const wxPaintEvent &WXUNUSED(event) ) |
944 | { | |
f135ff73 VZ |
945 | if ( !m_anchor ) |
946 | return; | |
c801d85f | 947 | |
d4c99d6f RR |
948 | wxPaintDC dc(this); |
949 | PrepareDC( dc ); | |
29d87bba | 950 | |
d4c99d6f | 951 | dc.SetFont( wxSystemSettings::GetSystemFont( wxSYS_SYSTEM_FONT ) ); |
29d87bba | 952 | |
d4c99d6f RR |
953 | dc.SetPen( m_dottedPen ); |
954 | m_lineHeight = (int)(dc.GetCharHeight() + 4); | |
29d87bba | 955 | |
c801d85f | 956 | int y = m_lineHeight / 2 + 2; |
d4c99d6f | 957 | PaintLevel( m_anchor, dc, 0, y ); |
edaa81ae | 958 | } |
c801d85f KB |
959 | |
960 | void wxTreeCtrl::OnSetFocus( const wxFocusEvent &WXUNUSED(event) ) | |
961 | { | |
962 | m_hasFocus = TRUE; | |
f135ff73 VZ |
963 | if ( m_current ) |
964 | RefreshLine( m_current ); | |
edaa81ae | 965 | } |
c801d85f KB |
966 | |
967 | void wxTreeCtrl::OnKillFocus( const wxFocusEvent &WXUNUSED(event) ) | |
968 | { | |
969 | m_hasFocus = FALSE; | |
f135ff73 VZ |
970 | if ( m_current ) |
971 | RefreshLine( m_current ); | |
edaa81ae | 972 | } |
c801d85f KB |
973 | |
974 | void wxTreeCtrl::OnChar( wxKeyEvent &event ) | |
975 | { | |
f135ff73 | 976 | // TODO process '+', '-' (expand/collapse branch) and cursor keys |
c801d85f | 977 | event.Skip(); |
edaa81ae | 978 | } |
c801d85f KB |
979 | |
980 | void wxTreeCtrl::OnMouse( const wxMouseEvent &event ) | |
981 | { | |
f135ff73 VZ |
982 | if ( !(event.LeftDown() || event.LeftDClick()) ) |
983 | return; | |
984 | ||
985 | if ( !m_anchor ) | |
986 | return; | |
29d87bba | 987 | |
c801d85f KB |
988 | wxClientDC dc(this); |
989 | PrepareDC(dc); | |
990 | long x = dc.DeviceToLogicalX( (long)event.GetX() ); | |
991 | long y = dc.DeviceToLogicalY( (long)event.GetY() ); | |
29d87bba | 992 | |
f135ff73 VZ |
993 | bool onButton = FALSE; |
994 | wxGenericTreeItem *item = m_anchor->HitTest( wxPoint(x,y), onButton ); | |
995 | if ( item == NULL ) | |
29d87bba | 996 | return; |
29d87bba | 997 | |
389cdc7a | 998 | SelectItem(item); |
29d87bba | 999 | |
f135ff73 VZ |
1000 | if ( event.LeftDClick() ) |
1001 | { | |
1002 | wxTreeEvent event( wxEVT_COMMAND_TREE_KEY_DOWN, GetId() ); | |
1003 | event.m_item = item; | |
1004 | event.m_code = 0; | |
1005 | event.SetEventObject( this ); | |
1006 | ProcessEvent( event ); | |
1007 | } | |
29d87bba | 1008 | |
f135ff73 | 1009 | if ( onButton ) |
c801d85f | 1010 | { |
f135ff73 | 1011 | Toggle( item ); |
edaa81ae RR |
1012 | } |
1013 | } | |
c801d85f | 1014 | |
f135ff73 VZ |
1015 | // ----------------------------------------------------------------------------- |
1016 | // ----------------------------------------------------------------------------- | |
1017 | void wxTreeCtrl::CalculateLevel( wxGenericTreeItem *item, | |
1018 | wxDC &dc, | |
1019 | int level, | |
1020 | int &y ) | |
c801d85f | 1021 | { |
4c681997 | 1022 | int horizX = level*m_indent; |
389cdc7a | 1023 | |
f135ff73 VZ |
1024 | item->SetX( horizX+33 ); |
1025 | item->SetY( y-m_lineHeight/3-2 ); | |
1026 | item->SetHeight( m_lineHeight ); | |
4c681997 | 1027 | |
f135ff73 VZ |
1028 | if ( item->IsExpanded() ) |
1029 | return; | |
389cdc7a | 1030 | |
f135ff73 VZ |
1031 | wxArrayTreeItems& children = item->GetChildren(); |
1032 | size_t count = children.Count(); | |
1033 | for ( size_t n = 0; n < count; n++ ) | |
c801d85f | 1034 | { |
c801d85f | 1035 | y += m_lineHeight; |
f135ff73 | 1036 | CalculateLevel( children[n], dc, level+1, y ); |
edaa81ae RR |
1037 | } |
1038 | } | |
c801d85f | 1039 | |
74bedbeb | 1040 | void wxTreeCtrl::CalculatePositions() |
c801d85f | 1041 | { |
f135ff73 | 1042 | if ( !m_anchor ) |
29d87bba VZ |
1043 | return; |
1044 | ||
c801d85f KB |
1045 | wxClientDC dc(this); |
1046 | PrepareDC( dc ); | |
29d87bba | 1047 | |
c801d85f | 1048 | dc.SetFont( wxSystemSettings::GetSystemFont( wxSYS_SYSTEM_FONT ) ); |
29d87bba | 1049 | |
c801d85f KB |
1050 | dc.SetPen( m_dottedPen ); |
1051 | m_lineHeight = (int)(dc.GetCharHeight() + 4); | |
29d87bba | 1052 | |
c801d85f KB |
1053 | int y = m_lineHeight / 2 + 2; |
1054 | CalculateLevel( m_anchor, dc, 0, y ); | |
edaa81ae | 1055 | } |
c801d85f | 1056 | |
f135ff73 | 1057 | void wxTreeCtrl::RefreshSubtree(wxGenericTreeItem *item) |
c801d85f | 1058 | { |
f135ff73 VZ |
1059 | wxClientDC dc(this); |
1060 | PrepareDC(dc); | |
1061 | ||
1062 | int cw = 0; | |
1063 | int ch = 0; | |
1064 | GetClientSize( &cw, &ch ); | |
1065 | ||
1066 | wxRect rect; | |
1067 | rect.x = dc.LogicalToDeviceX( 0 ); | |
1068 | rect.width = cw; | |
1069 | rect.y = dc.LogicalToDeviceY( item->GetY() ); | |
1070 | rect.height = ch; | |
1071 | ||
1072 | Refresh( TRUE, &rect ); | |
1073 | ||
1074 | AdjustMyScrollbars(); | |
edaa81ae | 1075 | } |
c801d85f KB |
1076 | |
1077 | void wxTreeCtrl::RefreshLine( wxGenericTreeItem *item ) | |
1078 | { | |
c801d85f KB |
1079 | wxClientDC dc(this); |
1080 | PrepareDC( dc ); | |
f135ff73 | 1081 | |
c801d85f | 1082 | wxRect rect; |
f135ff73 VZ |
1083 | rect.x = dc.LogicalToDeviceX( item->GetX() - 2 ); |
1084 | rect.y = dc.LogicalToDeviceY( item->GetY() - 2 ); | |
c801d85f | 1085 | rect.width = 1000; |
f135ff73 VZ |
1086 | rect.height = dc.GetCharHeight() + 6; |
1087 | ||
c801d85f | 1088 | Refresh( TRUE, &rect ); |
edaa81ae | 1089 | } |
c801d85f | 1090 |