diff options
author | David Walter Seikel | 2014-01-13 19:47:58 +1000 |
---|---|---|
committer | David Walter Seikel | 2014-01-13 19:47:58 +1000 |
commit | f9158592e1478b2013afc7041d9ed041cf2d2f4a (patch) | |
tree | b16e389d7988700e21b4c9741044cefa536dcbae /libraries/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.cpp | |
parent | Libraries readme updated with change markers and more of the Irrlicht changes. (diff) | |
download | SledjHamr-f9158592e1478b2013afc7041d9ed041cf2d2f4a.zip SledjHamr-f9158592e1478b2013afc7041d9ed041cf2d2f4a.tar.gz SledjHamr-f9158592e1478b2013afc7041d9ed041cf2d2f4a.tar.bz2 SledjHamr-f9158592e1478b2013afc7041d9ed041cf2d2f4a.tar.xz |
Update Irrlicht to 1.8.1. Include actual change markers this time. lol
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.cpp | 1101 |
1 files changed, 1101 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.cpp b/libraries/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.cpp new file mode 100644 index 0000000..779b8cd --- /dev/null +++ b/libraries/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.cpp | |||
@@ -0,0 +1,1101 @@ | |||
1 | // This file is part of the "Irrlicht Engine". | ||
2 | // written by Reinhard Ostermeier, reinhard@nospam.r-ostermeier.de | ||
3 | // expaned by burningwater | ||
4 | |||
5 | #include "CGUITreeView.h" | ||
6 | |||
7 | #ifdef _IRR_COMPILE_WITH_GUI_ | ||
8 | |||
9 | #include "IGUISkin.h" | ||
10 | #include "IGUIEnvironment.h" | ||
11 | #include "IVideoDriver.h" | ||
12 | #include "IGUIFont.h" | ||
13 | #include "CGUIScrollBar.h" | ||
14 | #include "os.h" | ||
15 | |||
16 | namespace irr | ||
17 | { | ||
18 | namespace gui | ||
19 | { | ||
20 | |||
21 | CGUITreeViewNode::CGUITreeViewNode( CGUITreeView* owner, CGUITreeViewNode* parent ) | ||
22 | : Owner(owner), Parent(parent), ImageIndex(-1), SelectedImageIndex(-1), | ||
23 | Data(0), Data2(0), Expanded(false) | ||
24 | { | ||
25 | #ifdef _DEBUG | ||
26 | setDebugName( "CGUITreeView" ); | ||
27 | #endif | ||
28 | } | ||
29 | |||
30 | CGUITreeViewNode::~CGUITreeViewNode() | ||
31 | { | ||
32 | if( Owner && this == Owner->getSelected() ) | ||
33 | { | ||
34 | setSelected( false ); | ||
35 | } | ||
36 | |||
37 | clearChildren(); | ||
38 | |||
39 | if( Data2 ) | ||
40 | { | ||
41 | Data2->drop(); | ||
42 | } | ||
43 | } | ||
44 | |||
45 | IGUITreeView* CGUITreeViewNode::getOwner() const | ||
46 | { | ||
47 | return Owner; | ||
48 | } | ||
49 | |||
50 | IGUITreeViewNode* CGUITreeViewNode::getParent() const | ||
51 | { | ||
52 | return Parent; | ||
53 | } | ||
54 | |||
55 | void CGUITreeViewNode::setText( const wchar_t* text ) | ||
56 | { | ||
57 | Text = text; | ||
58 | } | ||
59 | |||
60 | void CGUITreeViewNode::setIcon( const wchar_t* icon ) | ||
61 | { | ||
62 | Icon = icon; | ||
63 | } | ||
64 | |||
65 | void CGUITreeViewNode::clearChildren() | ||
66 | { | ||
67 | core::list<CGUITreeViewNode*>::Iterator it; | ||
68 | |||
69 | for( it = Children.begin(); it != Children.end(); it++ ) | ||
70 | { | ||
71 | ( *it )->drop(); | ||
72 | } | ||
73 | Children.clear(); | ||
74 | } | ||
75 | |||
76 | IGUITreeViewNode* CGUITreeViewNode::addChildBack( | ||
77 | const wchar_t* text, | ||
78 | const wchar_t* icon /*= 0*/, | ||
79 | s32 imageIndex /*= -1*/, | ||
80 | s32 selectedImageIndex /*= -1*/, | ||
81 | void* data /*= 0*/, | ||
82 | IReferenceCounted* data2 /*= 0*/ ) | ||
83 | { | ||
84 | CGUITreeViewNode* newChild = new CGUITreeViewNode( Owner, this ); | ||
85 | |||
86 | Children.push_back( newChild ); | ||
87 | newChild->Text = text; | ||
88 | newChild->Icon = icon; | ||
89 | newChild->ImageIndex = imageIndex; | ||
90 | newChild->SelectedImageIndex = selectedImageIndex; | ||
91 | newChild->Data = data; | ||
92 | newChild->Data2 = data2; | ||
93 | if( data2 ) | ||
94 | { | ||
95 | data2->grab(); | ||
96 | } | ||
97 | return newChild; | ||
98 | } | ||
99 | |||
100 | IGUITreeViewNode* CGUITreeViewNode::addChildFront( | ||
101 | const wchar_t* text, | ||
102 | const wchar_t* icon /*= 0*/, | ||
103 | s32 imageIndex /*= -1*/, | ||
104 | s32 selectedImageIndex /*= -1*/, | ||
105 | void* data /*= 0*/, | ||
106 | IReferenceCounted* data2 /*= 0*/ ) | ||
107 | { | ||
108 | CGUITreeViewNode* newChild = new CGUITreeViewNode( Owner, this ); | ||
109 | |||
110 | Children.push_front( newChild ); | ||
111 | newChild->Text = text; | ||
112 | newChild->Icon = icon; | ||
113 | newChild->ImageIndex = imageIndex; | ||
114 | newChild->SelectedImageIndex = selectedImageIndex; | ||
115 | newChild->Data = data; | ||
116 | newChild->Data2 = data2; | ||
117 | if( data2 ) | ||
118 | { | ||
119 | data2->grab(); | ||
120 | } | ||
121 | return newChild; | ||
122 | } | ||
123 | |||
124 | IGUITreeViewNode* CGUITreeViewNode::insertChildAfter( | ||
125 | IGUITreeViewNode* other, | ||
126 | const wchar_t* text, | ||
127 | const wchar_t* icon /*= 0*/, | ||
128 | s32 imageIndex /*= -1*/, | ||
129 | s32 selectedImageIndex /*= -1*/, | ||
130 | void* data /*= 0*/, | ||
131 | IReferenceCounted* data2/* = 0*/ ) | ||
132 | { | ||
133 | core::list<CGUITreeViewNode*>::Iterator itOther; | ||
134 | CGUITreeViewNode* newChild = 0; | ||
135 | |||
136 | for( itOther = Children.begin(); itOther != Children.end(); itOther++ ) | ||
137 | { | ||
138 | if( other == *itOther ) | ||
139 | { | ||
140 | newChild = new CGUITreeViewNode( Owner, this ); | ||
141 | newChild->Text = text; | ||
142 | newChild->Icon = icon; | ||
143 | newChild->ImageIndex = imageIndex; | ||
144 | newChild->SelectedImageIndex = selectedImageIndex; | ||
145 | newChild->Data = data; | ||
146 | newChild->Data2 = data2; | ||
147 | if( data2 ) | ||
148 | { | ||
149 | data2->grab(); | ||
150 | } | ||
151 | Children.insert_after( itOther, newChild ); | ||
152 | break; | ||
153 | } | ||
154 | } | ||
155 | return newChild; | ||
156 | } | ||
157 | |||
158 | IGUITreeViewNode* CGUITreeViewNode::insertChildBefore( | ||
159 | IGUITreeViewNode* other, | ||
160 | const wchar_t* text, | ||
161 | const wchar_t* icon /*= 0*/, | ||
162 | s32 imageIndex /*= -1*/, | ||
163 | s32 selectedImageIndex /*= -1*/, | ||
164 | void* data /*= 0*/, | ||
165 | IReferenceCounted* data2/* = 0*/ ) | ||
166 | { | ||
167 | core::list<CGUITreeViewNode*>::Iterator itOther; | ||
168 | CGUITreeViewNode* newChild = 0; | ||
169 | |||
170 | for( itOther = Children.begin(); itOther != Children.end(); itOther++ ) | ||
171 | { | ||
172 | if( other == *itOther ) | ||
173 | { | ||
174 | newChild = new CGUITreeViewNode( Owner, this ); | ||
175 | newChild->Text = text; | ||
176 | newChild->Icon = icon; | ||
177 | newChild->ImageIndex = imageIndex; | ||
178 | newChild->SelectedImageIndex = selectedImageIndex; | ||
179 | newChild->Data = data; | ||
180 | newChild->Data2 = data2; | ||
181 | if( data2 ) | ||
182 | { | ||
183 | data2->grab(); | ||
184 | } | ||
185 | Children.insert_before( itOther, newChild ); | ||
186 | break; | ||
187 | } | ||
188 | } | ||
189 | return newChild; | ||
190 | } | ||
191 | |||
192 | IGUITreeViewNode* CGUITreeViewNode::getFirstChild() const | ||
193 | { | ||
194 | if( Children.empty() ) | ||
195 | { | ||
196 | return 0; | ||
197 | } | ||
198 | else | ||
199 | { | ||
200 | return *( Children.begin() ); | ||
201 | } | ||
202 | } | ||
203 | |||
204 | IGUITreeViewNode* CGUITreeViewNode::getLastChild() const | ||
205 | { | ||
206 | if( Children.empty() ) | ||
207 | { | ||
208 | return 0; | ||
209 | } | ||
210 | else | ||
211 | { | ||
212 | return *( Children.getLast() ); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | IGUITreeViewNode* CGUITreeViewNode::getPrevSibling() const | ||
217 | { | ||
218 | core::list<CGUITreeViewNode*>::Iterator itThis; | ||
219 | core::list<CGUITreeViewNode*>::Iterator itOther; | ||
220 | CGUITreeViewNode* other = 0; | ||
221 | |||
222 | if( Parent ) | ||
223 | { | ||
224 | for( itThis = Parent->Children.begin(); itThis != Parent->Children.end(); itThis++ ) | ||
225 | { | ||
226 | if( this == *itThis ) | ||
227 | { | ||
228 | if( itThis != Parent->Children.begin() ) | ||
229 | { | ||
230 | other = *itOther; | ||
231 | } | ||
232 | break; | ||
233 | } | ||
234 | itOther = itThis; | ||
235 | } | ||
236 | } | ||
237 | return other; | ||
238 | } | ||
239 | |||
240 | IGUITreeViewNode* CGUITreeViewNode::getNextSibling() const | ||
241 | { | ||
242 | core::list<CGUITreeViewNode*>::Iterator itThis; | ||
243 | CGUITreeViewNode* other = 0; | ||
244 | |||
245 | if( Parent ) | ||
246 | { | ||
247 | for( itThis = Parent->Children.begin(); itThis != Parent->Children.end(); itThis++ ) | ||
248 | { | ||
249 | if( this == *itThis ) | ||
250 | { | ||
251 | if( itThis != Parent->Children.getLast() ) | ||
252 | { | ||
253 | other = *( ++itThis ); | ||
254 | } | ||
255 | break; | ||
256 | } | ||
257 | } | ||
258 | } | ||
259 | return other; | ||
260 | } | ||
261 | |||
262 | IGUITreeViewNode* CGUITreeViewNode::getNextVisible() const | ||
263 | { | ||
264 | IGUITreeViewNode* next = 0; | ||
265 | IGUITreeViewNode* node = 0; | ||
266 | |||
267 | node = const_cast<CGUITreeViewNode*>( this ); | ||
268 | |||
269 | if( node->getExpanded() && node->hasChildren() ) | ||
270 | { | ||
271 | next = node->getFirstChild(); | ||
272 | } | ||
273 | else | ||
274 | { | ||
275 | next = node->getNextSibling(); | ||
276 | } | ||
277 | while( !next && node->getParent() ) | ||
278 | { | ||
279 | next = node->getParent()->getNextSibling(); | ||
280 | if( !next ) | ||
281 | { | ||
282 | node = node->getParent(); | ||
283 | } | ||
284 | } | ||
285 | |||
286 | return next; | ||
287 | } | ||
288 | |||
289 | bool CGUITreeViewNode::deleteChild( IGUITreeViewNode* child ) | ||
290 | { | ||
291 | core::list<CGUITreeViewNode*>::Iterator itChild; | ||
292 | bool deleted = false; | ||
293 | |||
294 | for( itChild = Children.begin(); itChild != Children.end(); itChild++ ) | ||
295 | { | ||
296 | if( child == *itChild ) | ||
297 | { | ||
298 | child->drop(); | ||
299 | Children.erase( itChild ); | ||
300 | deleted = true; | ||
301 | break; | ||
302 | } | ||
303 | } | ||
304 | return deleted; | ||
305 | } | ||
306 | |||
307 | bool CGUITreeViewNode::moveChildUp( IGUITreeViewNode* child ) | ||
308 | { | ||
309 | core::list<CGUITreeViewNode*>::Iterator itChild; | ||
310 | core::list<CGUITreeViewNode*>::Iterator itOther; | ||
311 | CGUITreeViewNode* nodeTmp; | ||
312 | bool moved = false; | ||
313 | |||
314 | for( itChild = Children.begin(); itChild != Children.end(); itChild++ ) | ||
315 | { | ||
316 | if( child == *itChild ) | ||
317 | { | ||
318 | if( itChild != Children.begin() ) | ||
319 | { | ||
320 | nodeTmp = *itChild; | ||
321 | *itChild = *itOther; | ||
322 | *itOther = nodeTmp; | ||
323 | moved = true; | ||
324 | } | ||
325 | break; | ||
326 | } | ||
327 | itOther = itChild; | ||
328 | } | ||
329 | return moved; | ||
330 | } | ||
331 | |||
332 | bool CGUITreeViewNode::moveChildDown( IGUITreeViewNode* child ) | ||
333 | { | ||
334 | core::list<CGUITreeViewNode*>::Iterator itChild; | ||
335 | core::list<CGUITreeViewNode*>::Iterator itOther; | ||
336 | CGUITreeViewNode* nodeTmp; | ||
337 | bool moved = false; | ||
338 | |||
339 | for( itChild = Children.begin(); itChild != Children.end(); itChild++ ) | ||
340 | { | ||
341 | if( child == *itChild ) | ||
342 | { | ||
343 | if( itChild != Children.getLast() ) | ||
344 | { | ||
345 | itOther = itChild; | ||
346 | ++itOther; | ||
347 | nodeTmp = *itChild; | ||
348 | *itChild = *itOther; | ||
349 | *itOther = nodeTmp; | ||
350 | moved = true; | ||
351 | } | ||
352 | break; | ||
353 | } | ||
354 | } | ||
355 | return moved; | ||
356 | } | ||
357 | |||
358 | void CGUITreeViewNode::setExpanded( bool expanded ) | ||
359 | { | ||
360 | Expanded = expanded; | ||
361 | } | ||
362 | |||
363 | void CGUITreeViewNode::setSelected( bool selected ) | ||
364 | { | ||
365 | if( Owner ) | ||
366 | { | ||
367 | if( selected ) | ||
368 | { | ||
369 | Owner->Selected = this; | ||
370 | } | ||
371 | else | ||
372 | { | ||
373 | if( Owner->Selected == this ) | ||
374 | { | ||
375 | Owner->Selected = 0; | ||
376 | } | ||
377 | } | ||
378 | } | ||
379 | } | ||
380 | |||
381 | bool CGUITreeViewNode::getSelected() const | ||
382 | { | ||
383 | if( Owner ) | ||
384 | { | ||
385 | return Owner->Selected == (IGUITreeViewNode*)this; | ||
386 | } | ||
387 | else | ||
388 | { | ||
389 | return false; | ||
390 | } | ||
391 | } | ||
392 | |||
393 | bool CGUITreeViewNode::isRoot() const | ||
394 | { | ||
395 | return ( Owner && ( this == Owner->Root ) ); | ||
396 | } | ||
397 | |||
398 | s32 CGUITreeViewNode::getLevel() const | ||
399 | { | ||
400 | if( Parent ) | ||
401 | { | ||
402 | return Parent->getLevel() + 1; | ||
403 | } | ||
404 | else | ||
405 | { | ||
406 | return 0; | ||
407 | } | ||
408 | } | ||
409 | |||
410 | bool CGUITreeViewNode::isVisible() const | ||
411 | { | ||
412 | if( Parent ) | ||
413 | { | ||
414 | return Parent->getExpanded() && Parent->isVisible(); | ||
415 | } | ||
416 | else | ||
417 | { | ||
418 | return true; | ||
419 | } | ||
420 | } | ||
421 | |||
422 | |||
423 | //! constructor | ||
424 | CGUITreeView::CGUITreeView(IGUIEnvironment* environment, IGUIElement* parent, | ||
425 | s32 id, core::rect<s32> rectangle, bool clip, | ||
426 | bool drawBack,bool scrollBarVertical, bool scrollBarHorizontal) | ||
427 | : IGUITreeView( environment, parent, id, rectangle ), | ||
428 | Root(0), Selected(0), | ||
429 | ItemHeight( 0 ), | ||
430 | IndentWidth( 0 ), | ||
431 | TotalItemHeight( 0 ), | ||
432 | TotalItemWidth ( 0 ), | ||
433 | Font( 0 ), | ||
434 | IconFont( 0 ), | ||
435 | ScrollBarH( 0 ), | ||
436 | ScrollBarV( 0 ), | ||
437 | ImageList( 0 ), | ||
438 | LastEventNode( 0 ), | ||
439 | LinesVisible( true ), | ||
440 | Selecting( false ), | ||
441 | Clip( clip ), | ||
442 | DrawBack( drawBack ), | ||
443 | ImageLeftOfIcon( true ) | ||
444 | { | ||
445 | #ifdef _DEBUG | ||
446 | setDebugName( "CGUITreeView" ); | ||
447 | #endif | ||
448 | |||
449 | IGUISkin* skin = Environment->getSkin(); | ||
450 | s32 s = skin->getSize( EGDS_SCROLLBAR_SIZE ); | ||
451 | |||
452 | if ( scrollBarVertical ) | ||
453 | { | ||
454 | ScrollBarV = new CGUIScrollBar( false, Environment, this, 0, | ||
455 | core::rect<s32>( RelativeRect.getWidth() - s, | ||
456 | 0, | ||
457 | RelativeRect.getWidth(), | ||
458 | RelativeRect.getHeight() - (scrollBarHorizontal ? s : 0 ) | ||
459 | ), | ||
460 | !clip ); | ||
461 | ScrollBarV->drop(); | ||
462 | |||
463 | ScrollBarV->setSubElement(true); | ||
464 | ScrollBarV->setPos( 0 ); | ||
465 | ScrollBarV->grab(); | ||
466 | } | ||
467 | |||
468 | if ( scrollBarHorizontal ) | ||
469 | { | ||
470 | ScrollBarH = new CGUIScrollBar( true, Environment, this, 1, | ||
471 | core::rect<s32>( 0, RelativeRect.getHeight() - s, RelativeRect.getWidth() - s, RelativeRect.getHeight() ), | ||
472 | !clip ); | ||
473 | ScrollBarH->drop(); | ||
474 | |||
475 | ScrollBarH->setSubElement(true); | ||
476 | ScrollBarH->setPos( 0 ); | ||
477 | ScrollBarH->grab(); | ||
478 | } | ||
479 | |||
480 | Root = new CGUITreeViewNode( this, 0 ); | ||
481 | Root->Expanded = true; | ||
482 | |||
483 | recalculateItemHeight(); | ||
484 | } | ||
485 | |||
486 | |||
487 | //! destructor | ||
488 | CGUITreeView::~CGUITreeView() | ||
489 | { | ||
490 | if( ScrollBarV ) | ||
491 | { | ||
492 | ScrollBarV->drop(); | ||
493 | } | ||
494 | |||
495 | if( ScrollBarH ) | ||
496 | { | ||
497 | ScrollBarH->drop(); | ||
498 | } | ||
499 | |||
500 | if( Font ) | ||
501 | { | ||
502 | Font->drop(); | ||
503 | } | ||
504 | |||
505 | if( IconFont ) | ||
506 | { | ||
507 | IconFont->drop(); | ||
508 | } | ||
509 | |||
510 | if( ImageList ) | ||
511 | { | ||
512 | ImageList->drop(); | ||
513 | } | ||
514 | |||
515 | if( Root ) | ||
516 | { | ||
517 | Root->drop(); | ||
518 | } | ||
519 | } | ||
520 | |||
521 | void CGUITreeView::recalculateItemHeight() | ||
522 | { | ||
523 | IGUISkin* skin = Environment->getSkin(); | ||
524 | IGUITreeViewNode* node; | ||
525 | |||
526 | if( Font != skin->getFont() ) | ||
527 | { | ||
528 | if( Font ) | ||
529 | { | ||
530 | Font->drop(); | ||
531 | } | ||
532 | |||
533 | Font = skin->getFont(); | ||
534 | ItemHeight = 0; | ||
535 | |||
536 | if( Font ) | ||
537 | { | ||
538 | ItemHeight = Font->getDimension( L"A" ).Height + 4; | ||
539 | Font->grab(); | ||
540 | } | ||
541 | |||
542 | if( IconFont ) | ||
543 | { | ||
544 | s32 height = IconFont->getDimension( L" " ).Height; | ||
545 | if( height > ItemHeight ) | ||
546 | { | ||
547 | ItemHeight = height; | ||
548 | } | ||
549 | } | ||
550 | if( ImageList ) | ||
551 | { | ||
552 | if( ImageList->getImageSize().Height + 1 > ItemHeight ) | ||
553 | { | ||
554 | ItemHeight = ImageList->getImageSize().Height + 1; | ||
555 | } | ||
556 | } | ||
557 | } | ||
558 | |||
559 | IndentWidth = ItemHeight; | ||
560 | if( IndentWidth < 9 ) | ||
561 | { | ||
562 | IndentWidth = 9; | ||
563 | } | ||
564 | else if( IndentWidth > 15 ) | ||
565 | { | ||
566 | IndentWidth = 15; | ||
567 | } | ||
568 | else | ||
569 | { | ||
570 | if( ( ( IndentWidth >> 1 ) << 1 ) - IndentWidth == 0 ) | ||
571 | { | ||
572 | --IndentWidth; | ||
573 | } | ||
574 | } | ||
575 | |||
576 | TotalItemHeight = 0; | ||
577 | TotalItemWidth = AbsoluteRect.getWidth() * 2; | ||
578 | node = Root->getFirstChild(); | ||
579 | while( node ) | ||
580 | { | ||
581 | TotalItemHeight += ItemHeight; | ||
582 | node = node->getNextVisible(); | ||
583 | } | ||
584 | |||
585 | if ( ScrollBarV ) | ||
586 | ScrollBarV->setMax( core::max_(0,TotalItemHeight - AbsoluteRect.getHeight()) ); | ||
587 | |||
588 | if ( ScrollBarH ) | ||
589 | ScrollBarH->setMax( core::max_(0, TotalItemWidth - AbsoluteRect.getWidth()) ); | ||
590 | |||
591 | } | ||
592 | |||
593 | //! called if an event happened. | ||
594 | bool CGUITreeView::OnEvent( const SEvent &event ) | ||
595 | { | ||
596 | if ( isEnabled() ) | ||
597 | { | ||
598 | switch( event.EventType ) | ||
599 | { | ||
600 | case EET_GUI_EVENT: | ||
601 | switch( event.GUIEvent.EventType ) | ||
602 | { | ||
603 | case gui::EGET_SCROLL_BAR_CHANGED: | ||
604 | if( event.GUIEvent.Caller == ScrollBarV || event.GUIEvent.Caller == ScrollBarH ) | ||
605 | { | ||
606 | //s32 pos = ( ( gui::IGUIScrollBar* )event.GUIEvent.Caller )->getPos(); | ||
607 | return true; | ||
608 | } | ||
609 | break; | ||
610 | case gui::EGET_ELEMENT_FOCUS_LOST: | ||
611 | { | ||
612 | Selecting = false; | ||
613 | return false; | ||
614 | } | ||
615 | break; | ||
616 | default: | ||
617 | break; | ||
618 | } | ||
619 | break; | ||
620 | case EET_MOUSE_INPUT_EVENT: | ||
621 | { | ||
622 | core::position2d<s32> p( event.MouseInput.X, event.MouseInput.Y ); | ||
623 | |||
624 | switch( event.MouseInput.Event ) | ||
625 | { | ||
626 | case EMIE_MOUSE_WHEEL: | ||
627 | if ( ScrollBarV ) | ||
628 | ScrollBarV->setPos( ScrollBarV->getPos() + (event.MouseInput.Wheel < 0 ? -1 : 1) * -10 ); | ||
629 | return true; | ||
630 | break; | ||
631 | |||
632 | case EMIE_LMOUSE_PRESSED_DOWN: | ||
633 | |||
634 | if (Environment->hasFocus(this) && !AbsoluteClippingRect.isPointInside(p) ) | ||
635 | { | ||
636 | Environment->removeFocus(this); | ||
637 | return false; | ||
638 | } | ||
639 | |||
640 | if( Environment->hasFocus( this ) && | ||
641 | ( ( ScrollBarV && ScrollBarV->getAbsolutePosition().isPointInside( p ) && ScrollBarV->OnEvent( event ) ) || | ||
642 | ( ScrollBarH && ScrollBarH->getAbsolutePosition().isPointInside( p ) && ScrollBarH->OnEvent( event ) ) | ||
643 | ) | ||
644 | ) | ||
645 | { | ||
646 | return true; | ||
647 | } | ||
648 | |||
649 | Selecting = true; | ||
650 | Environment->setFocus( this ); | ||
651 | return true; | ||
652 | break; | ||
653 | |||
654 | case EMIE_LMOUSE_LEFT_UP: | ||
655 | if( Environment->hasFocus( this ) && | ||
656 | ( ( ScrollBarV && ScrollBarV->getAbsolutePosition().isPointInside( p ) && ScrollBarV->OnEvent( event ) ) || | ||
657 | ( ScrollBarH && ScrollBarH->getAbsolutePosition().isPointInside( p ) && ScrollBarH->OnEvent( event ) ) | ||
658 | ) | ||
659 | ) | ||
660 | { | ||
661 | return true; | ||
662 | } | ||
663 | |||
664 | Selecting = false; | ||
665 | Environment->removeFocus( this ); | ||
666 | mouseAction( event.MouseInput.X, event.MouseInput.Y ); | ||
667 | return true; | ||
668 | break; | ||
669 | |||
670 | case EMIE_MOUSE_MOVED: | ||
671 | if( Selecting ) | ||
672 | { | ||
673 | if( getAbsolutePosition().isPointInside( p ) ) | ||
674 | { | ||
675 | mouseAction( event.MouseInput.X, event.MouseInput.Y, true ); | ||
676 | return true; | ||
677 | } | ||
678 | } | ||
679 | break; | ||
680 | default: | ||
681 | break; | ||
682 | } | ||
683 | } | ||
684 | break; | ||
685 | default: | ||
686 | break; | ||
687 | } | ||
688 | } | ||
689 | |||
690 | return Parent ? Parent->OnEvent( event ) : false; | ||
691 | } | ||
692 | |||
693 | /*! | ||
694 | */ | ||
695 | void CGUITreeView::mouseAction( s32 xpos, s32 ypos, bool onlyHover /*= false*/ ) | ||
696 | { | ||
697 | IGUITreeViewNode* oldSelected = Selected; | ||
698 | IGUITreeViewNode* hitNode = 0; | ||
699 | s32 selIdx=-1; | ||
700 | s32 n; | ||
701 | IGUITreeViewNode* node; | ||
702 | SEvent event; | ||
703 | |||
704 | event.EventType = EET_GUI_EVENT; | ||
705 | event.GUIEvent.Caller = this; | ||
706 | event.GUIEvent.Element = 0; | ||
707 | |||
708 | xpos -= AbsoluteRect.UpperLeftCorner.X; | ||
709 | ypos -= AbsoluteRect.UpperLeftCorner.Y; | ||
710 | |||
711 | // find new selected item. | ||
712 | if( ItemHeight != 0 && ScrollBarV ) | ||
713 | { | ||
714 | selIdx = ( ( ypos - 1 ) + ScrollBarV->getPos() ) / ItemHeight; | ||
715 | } | ||
716 | |||
717 | hitNode = 0; | ||
718 | node = Root->getFirstChild(); | ||
719 | n = 0; | ||
720 | while( node ) | ||
721 | { | ||
722 | if( selIdx == n ) | ||
723 | { | ||
724 | hitNode = node; | ||
725 | break; | ||
726 | } | ||
727 | node = node->getNextVisible(); | ||
728 | ++n; | ||
729 | } | ||
730 | |||
731 | if( hitNode && xpos > hitNode->getLevel() * IndentWidth ) | ||
732 | { | ||
733 | Selected = hitNode; | ||
734 | } | ||
735 | |||
736 | if( hitNode && !onlyHover | ||
737 | && xpos < hitNode->getLevel() * IndentWidth | ||
738 | && xpos > ( hitNode->getLevel() - 1 ) * IndentWidth | ||
739 | && hitNode->hasChildren() ) | ||
740 | { | ||
741 | hitNode->setExpanded( !hitNode->getExpanded() ); | ||
742 | |||
743 | // post expand/collaps news | ||
744 | if( hitNode->getExpanded() ) | ||
745 | { | ||
746 | event.GUIEvent.EventType = EGET_TREEVIEW_NODE_EXPAND; | ||
747 | } | ||
748 | else | ||
749 | { | ||
750 | event.GUIEvent.EventType = EGET_TREEVIEW_NODE_COLLAPS; | ||
751 | } | ||
752 | LastEventNode = hitNode; | ||
753 | Parent->OnEvent( event ); | ||
754 | LastEventNode = 0; | ||
755 | } | ||
756 | |||
757 | if( Selected && !Selected->isVisible() ) | ||
758 | { | ||
759 | Selected = 0; | ||
760 | } | ||
761 | |||
762 | // post selection news | ||
763 | |||
764 | if( Parent && !onlyHover && Selected != oldSelected ) | ||
765 | { | ||
766 | if( oldSelected ) | ||
767 | { | ||
768 | event.GUIEvent.EventType = EGET_TREEVIEW_NODE_DESELECT; | ||
769 | LastEventNode = oldSelected; | ||
770 | Parent->OnEvent( event ); | ||
771 | LastEventNode = 0; | ||
772 | } | ||
773 | if( Selected ) | ||
774 | { | ||
775 | event.GUIEvent.EventType = EGET_TREEVIEW_NODE_SELECT; | ||
776 | LastEventNode = Selected; | ||
777 | Parent->OnEvent( event ); | ||
778 | LastEventNode = 0; | ||
779 | } | ||
780 | } | ||
781 | } | ||
782 | |||
783 | |||
784 | //! draws the element and its children | ||
785 | void CGUITreeView::draw() | ||
786 | { | ||
787 | if( !IsVisible ) | ||
788 | { | ||
789 | return; | ||
790 | } | ||
791 | |||
792 | recalculateItemHeight(); // if the font changed | ||
793 | |||
794 | IGUISkin* skin = Environment->getSkin(); | ||
795 | irr::video::IVideoDriver* driver = Environment->getVideoDriver(); | ||
796 | |||
797 | core::rect<s32>* clipRect = 0; | ||
798 | if( Clip ) | ||
799 | { | ||
800 | clipRect = &AbsoluteClippingRect; | ||
801 | } | ||
802 | |||
803 | // draw background | ||
804 | core::rect<s32> frameRect( AbsoluteRect ); | ||
805 | |||
806 | if( DrawBack ) | ||
807 | { | ||
808 | driver->draw2DRectangle( skin->getColor( EGDC_3D_HIGH_LIGHT ), frameRect, | ||
809 | clipRect ); | ||
810 | } | ||
811 | |||
812 | // draw the border | ||
813 | frameRect.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y + 1; | ||
814 | driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), frameRect, | ||
815 | clipRect ); | ||
816 | |||
817 | frameRect.LowerRightCorner.Y = AbsoluteRect.LowerRightCorner.Y; | ||
818 | frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + 1; | ||
819 | driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), frameRect, | ||
820 | clipRect ); | ||
821 | |||
822 | frameRect = AbsoluteRect; | ||
823 | frameRect.UpperLeftCorner.X = frameRect.LowerRightCorner.X - 1; | ||
824 | driver->draw2DRectangle( skin->getColor( EGDC_3D_HIGH_LIGHT ), frameRect, | ||
825 | clipRect ); | ||
826 | |||
827 | frameRect = AbsoluteRect; | ||
828 | frameRect.UpperLeftCorner.Y = AbsoluteRect.LowerRightCorner.Y - 1; | ||
829 | frameRect.LowerRightCorner.Y = AbsoluteRect.LowerRightCorner.Y; | ||
830 | driver->draw2DRectangle( skin->getColor( EGDC_3D_HIGH_LIGHT ), frameRect, | ||
831 | clipRect ); | ||
832 | |||
833 | |||
834 | // draw items | ||
835 | |||
836 | core::rect<s32> clientClip( AbsoluteRect ); | ||
837 | clientClip.UpperLeftCorner.Y += 1; | ||
838 | clientClip.UpperLeftCorner.X += 1; | ||
839 | clientClip.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X; | ||
840 | clientClip.LowerRightCorner.Y -= 1; | ||
841 | |||
842 | if ( ScrollBarV ) | ||
843 | clientClip.LowerRightCorner.X -= skin->getSize( EGDS_SCROLLBAR_SIZE ); | ||
844 | if ( ScrollBarH ) | ||
845 | clientClip.LowerRightCorner.Y -= skin->getSize( EGDS_SCROLLBAR_SIZE ); | ||
846 | |||
847 | if( clipRect ) | ||
848 | { | ||
849 | clientClip.clipAgainst( *clipRect ); | ||
850 | } | ||
851 | |||
852 | frameRect = AbsoluteRect; | ||
853 | frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize( EGDS_SCROLLBAR_SIZE ); | ||
854 | frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight; | ||
855 | |||
856 | if ( ScrollBarV ) | ||
857 | { | ||
858 | frameRect.UpperLeftCorner.Y -= ScrollBarV->getPos(); | ||
859 | frameRect.LowerRightCorner.Y -= ScrollBarV->getPos(); | ||
860 | } | ||
861 | |||
862 | if ( ScrollBarH ) | ||
863 | { | ||
864 | frameRect.UpperLeftCorner.X -= ScrollBarH->getPos(); | ||
865 | frameRect.LowerRightCorner.X -= ScrollBarH->getPos(); | ||
866 | } | ||
867 | |||
868 | IGUITreeViewNode* node = Root->getFirstChild(); | ||
869 | while( node ) | ||
870 | { | ||
871 | frameRect.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X + 1 + node->getLevel() * IndentWidth; | ||
872 | |||
873 | if( frameRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.Y | ||
874 | && frameRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y ) | ||
875 | { | ||
876 | if( node == Selected ) | ||
877 | { | ||
878 | driver->draw2DRectangle( skin->getColor( EGDC_HIGH_LIGHT ), frameRect, &clientClip ); | ||
879 | } | ||
880 | |||
881 | if( node->hasChildren() ) | ||
882 | { | ||
883 | core::rect<s32> rc; | ||
884 | core::rect<s32> expanderRect; | ||
885 | |||
886 | expanderRect.UpperLeftCorner.X = frameRect.UpperLeftCorner.X - IndentWidth + 2; | ||
887 | expanderRect.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y + ( ( frameRect.getHeight() - ( IndentWidth - 4 ) ) >> 1 ); | ||
888 | expanderRect.LowerRightCorner.X = expanderRect.UpperLeftCorner.X + IndentWidth - 4; | ||
889 | expanderRect.LowerRightCorner.Y = expanderRect.UpperLeftCorner.Y + IndentWidth - 4; | ||
890 | |||
891 | // box upper line | ||
892 | rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X; | ||
893 | rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y; | ||
894 | rc.LowerRightCorner.X = expanderRect.LowerRightCorner.X; | ||
895 | rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + 1; | ||
896 | driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc, | ||
897 | clipRect ); | ||
898 | |||
899 | // box left line | ||
900 | rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X; | ||
901 | rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y; | ||
902 | rc.LowerRightCorner.X = rc.UpperLeftCorner.X + 1; | ||
903 | rc.LowerRightCorner.Y = expanderRect.LowerRightCorner.Y; | ||
904 | driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc, | ||
905 | clipRect ); | ||
906 | |||
907 | // box right line | ||
908 | rc.UpperLeftCorner.X = expanderRect.LowerRightCorner.X - 1; | ||
909 | rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y; | ||
910 | rc.LowerRightCorner.X = rc.UpperLeftCorner.X + 1; | ||
911 | rc.LowerRightCorner.Y = expanderRect.LowerRightCorner.Y; | ||
912 | driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc, | ||
913 | clipRect ); | ||
914 | |||
915 | // box bottom line | ||
916 | rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X; | ||
917 | rc.UpperLeftCorner.Y = expanderRect.LowerRightCorner.Y - 1; | ||
918 | rc.LowerRightCorner.X = expanderRect.LowerRightCorner.X; | ||
919 | rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + 1; | ||
920 | driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc, | ||
921 | clipRect ); | ||
922 | |||
923 | // horizontal '-' line | ||
924 | rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X + 2; | ||
925 | rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y + ( expanderRect.getHeight() >> 1 ); | ||
926 | rc.LowerRightCorner.X = rc.UpperLeftCorner.X + expanderRect.getWidth() - 4; | ||
927 | rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + 1; | ||
928 | driver->draw2DRectangle( skin->getColor( EGDC_BUTTON_TEXT ), rc, | ||
929 | clipRect ); | ||
930 | |||
931 | if( !node->getExpanded() ) | ||
932 | { | ||
933 | // vertical '+' line | ||
934 | rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X + ( expanderRect.getWidth() >> 1 ); | ||
935 | rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y + 2; | ||
936 | rc.LowerRightCorner.X = rc.UpperLeftCorner.X + 1; | ||
937 | rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + expanderRect.getHeight() - 4; | ||
938 | driver->draw2DRectangle( skin->getColor( EGDC_BUTTON_TEXT ), rc, | ||
939 | clipRect ); | ||
940 | } | ||
941 | } | ||
942 | |||
943 | core::rect<s32> textRect = frameRect; | ||
944 | |||
945 | if( Font ) | ||
946 | { | ||
947 | EGUI_DEFAULT_COLOR textCol = EGDC_GRAY_TEXT; | ||
948 | if ( isEnabled() ) | ||
949 | textCol = ( node == Selected ) ? EGDC_HIGH_LIGHT_TEXT : EGDC_BUTTON_TEXT; | ||
950 | |||
951 | s32 iconWidth = 0; | ||
952 | for( s32 n = 0; n < 2; ++n ) | ||
953 | { | ||
954 | s32 index = node->getImageIndex(); | ||
955 | if( ( ImageList && index >= 0 ) | ||
956 | && ( ( ImageLeftOfIcon && n == 0 ) | ||
957 | || ( !ImageLeftOfIcon && n == 1 ) ) ) | ||
958 | { | ||
959 | index = node->getSelectedImageIndex(); | ||
960 | if( node != Selected || index < 0 ) | ||
961 | { | ||
962 | index = node->getImageIndex(); | ||
963 | } | ||
964 | ImageList->draw( | ||
965 | index, | ||
966 | core::position2d<s32>( | ||
967 | textRect.UpperLeftCorner.X, | ||
968 | textRect.UpperLeftCorner.Y + ( ( textRect.getHeight() - ImageList->getImageSize().Height ) >> 1 ) ), | ||
969 | &clientClip ); | ||
970 | iconWidth += ImageList->getImageSize().Width + 3; | ||
971 | textRect.UpperLeftCorner.X += ImageList->getImageSize().Width + 3; | ||
972 | } | ||
973 | else if( ( IconFont && reinterpret_cast<CGUITreeViewNode*>( node )->Icon.size() ) | ||
974 | && ( ( ImageLeftOfIcon && n == 1 ) | ||
975 | || ( !ImageLeftOfIcon && n == 0 ) ) ) | ||
976 | { | ||
977 | IconFont->draw( node->getIcon(), textRect, skin->getColor(textCol), false, true, &clientClip ); | ||
978 | iconWidth += IconFont->getDimension( node->getIcon() ).Width + 3; | ||
979 | textRect.UpperLeftCorner.X += IconFont->getDimension( node->getIcon() ).Width + 3; | ||
980 | } | ||
981 | } | ||
982 | |||
983 | Font->draw( node->getText(), textRect, skin->getColor(textCol), false, true, &clientClip ); | ||
984 | |||
985 | textRect.UpperLeftCorner.X -= iconWidth; | ||
986 | } | ||
987 | |||
988 | // draw the lines if neccessary | ||
989 | if( LinesVisible ) | ||
990 | { | ||
991 | core::rect<s32> rc; | ||
992 | |||
993 | // horizontal line | ||
994 | rc.UpperLeftCorner.X = frameRect.UpperLeftCorner.X - IndentWidth - ( IndentWidth >> 1 ) - 1; | ||
995 | rc.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y + ( ( frameRect.getHeight() ) >> 1 ); | ||
996 | if( node->hasChildren() ) | ||
997 | { | ||
998 | rc.LowerRightCorner.X = frameRect.UpperLeftCorner.X - IndentWidth; | ||
999 | } | ||
1000 | else | ||
1001 | { | ||
1002 | rc.LowerRightCorner.X = frameRect.UpperLeftCorner.X - 2; | ||
1003 | } | ||
1004 | rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + 1; | ||
1005 | driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc, | ||
1006 | clipRect ); | ||
1007 | |||
1008 | if( node->getParent() != Root ) | ||
1009 | { | ||
1010 | // vertical line | ||
1011 | if( node == node->getParent()->getFirstChild() ) | ||
1012 | { | ||
1013 | rc.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y - ( ( frameRect.getHeight() - IndentWidth ) >> 1 ); | ||
1014 | } | ||
1015 | else | ||
1016 | { | ||
1017 | rc.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y - ( frameRect.getHeight() >> 1 ); | ||
1018 | } | ||
1019 | rc.LowerRightCorner.X = rc.UpperLeftCorner.X + 1; | ||
1020 | driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc, | ||
1021 | clipRect ); | ||
1022 | |||
1023 | // the vertical lines of all parents | ||
1024 | IGUITreeViewNode* nodeTmp = node->getParent(); | ||
1025 | rc.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y - ( frameRect.getHeight() >> 1 ); | ||
1026 | for( s32 n = 0; n < node->getLevel() - 2; ++n ) | ||
1027 | { | ||
1028 | rc.UpperLeftCorner.X -= IndentWidth; | ||
1029 | rc.LowerRightCorner.X -= IndentWidth; | ||
1030 | if( nodeTmp != nodeTmp->getParent()->getLastChild() ) | ||
1031 | { | ||
1032 | driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc, | ||
1033 | clipRect ); | ||
1034 | } | ||
1035 | nodeTmp = nodeTmp->getParent(); | ||
1036 | } | ||
1037 | } | ||
1038 | } | ||
1039 | } | ||
1040 | |||
1041 | frameRect.UpperLeftCorner.Y += ItemHeight; | ||
1042 | frameRect.LowerRightCorner.Y += ItemHeight; | ||
1043 | |||
1044 | node = node->getNextVisible(); | ||
1045 | } | ||
1046 | |||
1047 | IGUIElement::draw(); | ||
1048 | } | ||
1049 | |||
1050 | //! Sets the font which should be used as icon font. This font is set to the Irrlicht engine | ||
1051 | //! built-in-font by default. Icons can be displayed in front of every list item. | ||
1052 | //! An icon is a string, displayed with the icon font. When using the build-in-font of the | ||
1053 | //! Irrlicht engine as icon font, the icon strings defined in GUIIcons.h can be used. | ||
1054 | void CGUITreeView::setIconFont( IGUIFont* font ) | ||
1055 | { | ||
1056 | s32 height; | ||
1057 | |||
1058 | if ( font ) | ||
1059 | font->grab(); | ||
1060 | if ( IconFont ) | ||
1061 | { | ||
1062 | IconFont->drop(); | ||
1063 | } | ||
1064 | |||
1065 | IconFont = font; | ||
1066 | if( IconFont ) | ||
1067 | { | ||
1068 | height = IconFont->getDimension( L" " ).Height; | ||
1069 | if( height > ItemHeight ) | ||
1070 | { | ||
1071 | ItemHeight = height; | ||
1072 | } | ||
1073 | } | ||
1074 | } | ||
1075 | |||
1076 | //! Sets the image list which should be used for the image and selected image of every node. | ||
1077 | //! The default is 0 (no images). | ||
1078 | void CGUITreeView::setImageList( IGUIImageList* imageList ) | ||
1079 | { | ||
1080 | if (imageList ) | ||
1081 | imageList->grab(); | ||
1082 | if( ImageList ) | ||
1083 | { | ||
1084 | ImageList->drop(); | ||
1085 | } | ||
1086 | |||
1087 | ImageList = imageList; | ||
1088 | if( ImageList ) | ||
1089 | { | ||
1090 | if( ImageList->getImageSize().Height + 1 > ItemHeight ) | ||
1091 | { | ||
1092 | ItemHeight = ImageList->getImageSize().Height + 1; | ||
1093 | } | ||
1094 | } | ||
1095 | } | ||
1096 | |||
1097 | } // end namespace gui | ||
1098 | } // end namespace irr | ||
1099 | |||
1100 | |||
1101 | #endif // _IRR_COMPILE_WITH_GUI_ | ||