diff options
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CGUITable.cpp')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CGUITable.cpp | 1256 |
1 files changed, 0 insertions, 1256 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CGUITable.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CGUITable.cpp deleted file mode 100644 index 5b2bdba..0000000 --- a/libraries/irrlicht-1.8/source/Irrlicht/CGUITable.cpp +++ /dev/null | |||
@@ -1,1256 +0,0 @@ | |||
1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt | ||
2 | // This file is part of the "Irrlicht Engine". | ||
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | ||
4 | |||
5 | // 07.10.2005 - Multicolor-Listbox added by A. Buschhueter (Acki) | ||
6 | // A_Buschhueter@gmx.de | ||
7 | |||
8 | #include "CGUITable.h" | ||
9 | #ifdef _IRR_COMPILE_WITH_GUI_ | ||
10 | |||
11 | #include "IGUISkin.h" | ||
12 | #include "IGUIEnvironment.h" | ||
13 | #include "IVideoDriver.h" | ||
14 | #include "IGUIFont.h" | ||
15 | #include "CGUIScrollBar.h" | ||
16 | #include "os.h" | ||
17 | |||
18 | #define ARROW_PAD 15 | ||
19 | |||
20 | namespace irr | ||
21 | { | ||
22 | namespace gui | ||
23 | { | ||
24 | |||
25 | //! constructor | ||
26 | CGUITable::CGUITable(IGUIEnvironment* environment, IGUIElement* parent, | ||
27 | s32 id, const core::rect<s32>& rectangle, bool clip, | ||
28 | bool drawBack, bool moveOverSelect) | ||
29 | : IGUITable(environment, parent, id, rectangle), Font(0), | ||
30 | VerticalScrollBar(0), HorizontalScrollBar(0), | ||
31 | Clip(clip), DrawBack(drawBack), MoveOverSelect(moveOverSelect), | ||
32 | Selecting(false), CurrentResizedColumn(-1), ResizeStart(0), ResizableColumns(true), | ||
33 | ItemHeight(0), TotalItemHeight(0), TotalItemWidth(0), Selected(-1), | ||
34 | CellHeightPadding(2), CellWidthPadding(5), ActiveTab(-1), | ||
35 | CurrentOrdering(EGOM_NONE), DrawFlags(EGTDF_ROWS | EGTDF_COLUMNS | EGTDF_ACTIVE_ROW ) | ||
36 | { | ||
37 | #ifdef _DEBUG | ||
38 | setDebugName("CGUITable"); | ||
39 | #endif | ||
40 | |||
41 | VerticalScrollBar = Environment->addScrollBar(false, core::rect<s32>(0, 0, 100, 100), this, -1); | ||
42 | if (VerticalScrollBar) | ||
43 | { | ||
44 | VerticalScrollBar->grab(); | ||
45 | VerticalScrollBar->setNotClipped(false); | ||
46 | VerticalScrollBar->setSubElement(true); | ||
47 | } | ||
48 | |||
49 | HorizontalScrollBar = Environment->addScrollBar(true, core::rect<s32>(0, 0, 100, 100), this, -1); | ||
50 | if ( HorizontalScrollBar ) | ||
51 | { | ||
52 | HorizontalScrollBar->grab(); | ||
53 | HorizontalScrollBar->setNotClipped(false); | ||
54 | HorizontalScrollBar->setSubElement(true); | ||
55 | } | ||
56 | |||
57 | refreshControls(); | ||
58 | } | ||
59 | |||
60 | |||
61 | //! destructor | ||
62 | CGUITable::~CGUITable() | ||
63 | { | ||
64 | if (VerticalScrollBar) | ||
65 | VerticalScrollBar->drop(); | ||
66 | if ( HorizontalScrollBar ) | ||
67 | HorizontalScrollBar->drop(); | ||
68 | |||
69 | if (Font) | ||
70 | Font->drop(); | ||
71 | } | ||
72 | |||
73 | |||
74 | void CGUITable::addColumn(const wchar_t* caption, s32 columnIndex) | ||
75 | { | ||
76 | Column tabHeader; | ||
77 | tabHeader.Name = caption; | ||
78 | tabHeader.Width = Font->getDimension(caption).Width + (CellWidthPadding * 2) + ARROW_PAD; | ||
79 | tabHeader.OrderingMode = EGCO_NONE; | ||
80 | |||
81 | if ( columnIndex < 0 || columnIndex >= (s32)Columns.size() ) | ||
82 | { | ||
83 | Columns.push_back(tabHeader); | ||
84 | for ( u32 i=0; i < Rows.size(); ++i ) | ||
85 | { | ||
86 | Cell cell; | ||
87 | Rows[i].Items.push_back(cell); | ||
88 | } | ||
89 | } | ||
90 | else | ||
91 | { | ||
92 | Columns.insert(tabHeader, columnIndex); | ||
93 | for ( u32 i=0; i < Rows.size(); ++i ) | ||
94 | { | ||
95 | Cell cell; | ||
96 | Rows[i].Items.insert(cell, columnIndex); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | if (ActiveTab == -1) | ||
101 | ActiveTab = 0; | ||
102 | |||
103 | recalculateWidths(); | ||
104 | } | ||
105 | |||
106 | |||
107 | //! remove a column from the table | ||
108 | void CGUITable::removeColumn(u32 columnIndex) | ||
109 | { | ||
110 | if ( columnIndex < Columns.size() ) | ||
111 | { | ||
112 | Columns.erase(columnIndex); | ||
113 | for ( u32 i=0; i < Rows.size(); ++i ) | ||
114 | { | ||
115 | Rows[i].Items.erase(columnIndex); | ||
116 | } | ||
117 | } | ||
118 | if ( (s32)columnIndex <= ActiveTab ) | ||
119 | ActiveTab = Columns.size() ? 0 : -1; | ||
120 | |||
121 | recalculateWidths(); | ||
122 | } | ||
123 | |||
124 | |||
125 | s32 CGUITable::getColumnCount() const | ||
126 | { | ||
127 | return Columns.size(); | ||
128 | } | ||
129 | |||
130 | |||
131 | s32 CGUITable::getRowCount() const | ||
132 | { | ||
133 | return Rows.size(); | ||
134 | } | ||
135 | |||
136 | |||
137 | bool CGUITable::setActiveColumn(s32 idx, bool doOrder ) | ||
138 | { | ||
139 | if (idx < 0 || idx >= (s32)Columns.size()) | ||
140 | return false; | ||
141 | |||
142 | bool changed = (ActiveTab != idx); | ||
143 | |||
144 | ActiveTab = idx; | ||
145 | if ( ActiveTab < 0 ) | ||
146 | return false; | ||
147 | |||
148 | if ( doOrder ) | ||
149 | { | ||
150 | switch ( Columns[idx].OrderingMode ) | ||
151 | { | ||
152 | case EGCO_NONE: | ||
153 | CurrentOrdering = EGOM_NONE; | ||
154 | break; | ||
155 | |||
156 | case EGCO_CUSTOM: | ||
157 | CurrentOrdering = EGOM_NONE; | ||
158 | if (Parent) | ||
159 | { | ||
160 | SEvent event; | ||
161 | event.EventType = EET_GUI_EVENT; | ||
162 | event.GUIEvent.Caller = this; | ||
163 | event.GUIEvent.Element = 0; | ||
164 | event.GUIEvent.EventType = EGET_TABLE_HEADER_CHANGED; | ||
165 | Parent->OnEvent(event); | ||
166 | } | ||
167 | |||
168 | break; | ||
169 | |||
170 | case EGCO_ASCENDING: | ||
171 | CurrentOrdering = EGOM_ASCENDING; | ||
172 | break; | ||
173 | |||
174 | case EGCO_DESCENDING: | ||
175 | CurrentOrdering = EGOM_DESCENDING; | ||
176 | break; | ||
177 | |||
178 | case EGCO_FLIP_ASCENDING_DESCENDING: | ||
179 | CurrentOrdering = EGOM_ASCENDING == CurrentOrdering ? EGOM_DESCENDING : EGOM_ASCENDING; | ||
180 | break; | ||
181 | default: | ||
182 | CurrentOrdering = EGOM_NONE; | ||
183 | } | ||
184 | |||
185 | orderRows(getActiveColumn(), CurrentOrdering); | ||
186 | } | ||
187 | |||
188 | if (changed) | ||
189 | { | ||
190 | SEvent event; | ||
191 | event.EventType = EET_GUI_EVENT; | ||
192 | event.GUIEvent.Caller = this; | ||
193 | event.GUIEvent.Element = 0; | ||
194 | event.GUIEvent.EventType = EGET_TABLE_HEADER_CHANGED; | ||
195 | Parent->OnEvent(event); | ||
196 | } | ||
197 | |||
198 | return true; | ||
199 | } | ||
200 | |||
201 | |||
202 | s32 CGUITable::getActiveColumn() const | ||
203 | { | ||
204 | return ActiveTab; | ||
205 | } | ||
206 | |||
207 | |||
208 | EGUI_ORDERING_MODE CGUITable::getActiveColumnOrdering() const | ||
209 | { | ||
210 | return CurrentOrdering; | ||
211 | } | ||
212 | |||
213 | |||
214 | void CGUITable::setColumnWidth(u32 columnIndex, u32 width) | ||
215 | { | ||
216 | if ( columnIndex < Columns.size() ) | ||
217 | { | ||
218 | const u32 MIN_WIDTH = Font->getDimension(Columns[columnIndex].Name.c_str() ).Width + (CellWidthPadding * 2); | ||
219 | if ( width < MIN_WIDTH ) | ||
220 | width = MIN_WIDTH; | ||
221 | |||
222 | Columns[columnIndex].Width = width; | ||
223 | |||
224 | for ( u32 i=0; i < Rows.size(); ++i ) | ||
225 | { | ||
226 | breakText( Rows[i].Items[columnIndex].Text, Rows[i].Items[columnIndex].BrokenText, Columns[columnIndex].Width ); | ||
227 | } | ||
228 | } | ||
229 | recalculateWidths(); | ||
230 | } | ||
231 | |||
232 | //! Get the width of a column | ||
233 | u32 CGUITable::getColumnWidth(u32 columnIndex) const | ||
234 | { | ||
235 | if ( columnIndex >= Columns.size() ) | ||
236 | return 0; | ||
237 | |||
238 | return Columns[columnIndex].Width; | ||
239 | } | ||
240 | |||
241 | void CGUITable::setResizableColumns(bool resizable) | ||
242 | { | ||
243 | ResizableColumns = resizable; | ||
244 | } | ||
245 | |||
246 | |||
247 | bool CGUITable::hasResizableColumns() const | ||
248 | { | ||
249 | return ResizableColumns; | ||
250 | } | ||
251 | |||
252 | |||
253 | u32 CGUITable::addRow(u32 rowIndex) | ||
254 | { | ||
255 | if ( rowIndex > Rows.size() ) | ||
256 | { | ||
257 | rowIndex = Rows.size(); | ||
258 | } | ||
259 | |||
260 | Row row; | ||
261 | |||
262 | if ( rowIndex == Rows.size() ) | ||
263 | Rows.push_back(row); | ||
264 | else | ||
265 | Rows.insert(row, rowIndex); | ||
266 | |||
267 | Rows[rowIndex].Items.reallocate(Columns.size()); | ||
268 | for ( u32 i = 0 ; i < Columns.size() ; ++i ) | ||
269 | { | ||
270 | Rows[rowIndex].Items.push_back(Cell()); | ||
271 | } | ||
272 | |||
273 | recalculateHeights(); | ||
274 | return rowIndex; | ||
275 | } | ||
276 | |||
277 | |||
278 | void CGUITable::removeRow(u32 rowIndex) | ||
279 | { | ||
280 | if ( rowIndex > Rows.size() ) | ||
281 | return; | ||
282 | |||
283 | Rows.erase( rowIndex ); | ||
284 | |||
285 | if ( !(Selected < s32(Rows.size())) ) | ||
286 | Selected = Rows.size() - 1; | ||
287 | |||
288 | recalculateHeights(); | ||
289 | } | ||
290 | |||
291 | |||
292 | //! adds an list item, returns id of item | ||
293 | void CGUITable::setCellText(u32 rowIndex, u32 columnIndex, const core::stringw& text) | ||
294 | { | ||
295 | if ( rowIndex < Rows.size() && columnIndex < Columns.size() ) | ||
296 | { | ||
297 | Rows[rowIndex].Items[columnIndex].Text = text; | ||
298 | breakText( Rows[rowIndex].Items[columnIndex].Text, Rows[rowIndex].Items[columnIndex].BrokenText, Columns[columnIndex].Width ); | ||
299 | |||
300 | IGUISkin* skin = Environment->getSkin(); | ||
301 | if ( skin ) | ||
302 | Rows[rowIndex].Items[columnIndex].Color = skin->getColor(EGDC_BUTTON_TEXT); | ||
303 | } | ||
304 | } | ||
305 | |||
306 | void CGUITable::setCellText(u32 rowIndex, u32 columnIndex, const core::stringw& text, video::SColor color) | ||
307 | { | ||
308 | if ( rowIndex < Rows.size() && columnIndex < Columns.size() ) | ||
309 | { | ||
310 | Rows[rowIndex].Items[columnIndex].Text = text; | ||
311 | breakText( Rows[rowIndex].Items[columnIndex].Text, Rows[rowIndex].Items[columnIndex].BrokenText, Columns[columnIndex].Width ); | ||
312 | Rows[rowIndex].Items[columnIndex].Color = color; | ||
313 | Rows[rowIndex].Items[columnIndex].IsOverrideColor = true; | ||
314 | } | ||
315 | } | ||
316 | |||
317 | |||
318 | void CGUITable::setCellColor(u32 rowIndex, u32 columnIndex, video::SColor color) | ||
319 | { | ||
320 | if ( rowIndex < Rows.size() && columnIndex < Columns.size() ) | ||
321 | { | ||
322 | Rows[rowIndex].Items[columnIndex].Color = color; | ||
323 | Rows[rowIndex].Items[columnIndex].IsOverrideColor = true; | ||
324 | } | ||
325 | } | ||
326 | |||
327 | |||
328 | void CGUITable::setCellData(u32 rowIndex, u32 columnIndex, void *data) | ||
329 | { | ||
330 | if ( rowIndex < Rows.size() && columnIndex < Columns.size() ) | ||
331 | { | ||
332 | Rows[rowIndex].Items[columnIndex].Data = data; | ||
333 | } | ||
334 | } | ||
335 | |||
336 | |||
337 | const wchar_t* CGUITable::getCellText(u32 rowIndex, u32 columnIndex ) const | ||
338 | { | ||
339 | if ( rowIndex < Rows.size() && columnIndex < Columns.size() ) | ||
340 | { | ||
341 | return Rows[rowIndex].Items[columnIndex].Text.c_str(); | ||
342 | } | ||
343 | |||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | |||
348 | void* CGUITable::getCellData(u32 rowIndex, u32 columnIndex ) const | ||
349 | { | ||
350 | if ( rowIndex < Rows.size() && columnIndex < Columns.size() ) | ||
351 | { | ||
352 | return Rows[rowIndex].Items[columnIndex].Data; | ||
353 | } | ||
354 | |||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | |||
359 | //! clears the list | ||
360 | void CGUITable::clear() | ||
361 | { | ||
362 | Selected = -1; | ||
363 | Rows.clear(); | ||
364 | Columns.clear(); | ||
365 | |||
366 | if (VerticalScrollBar) | ||
367 | VerticalScrollBar->setPos(0); | ||
368 | if ( HorizontalScrollBar ) | ||
369 | HorizontalScrollBar->setPos(0); | ||
370 | |||
371 | recalculateHeights(); | ||
372 | recalculateWidths(); | ||
373 | } | ||
374 | |||
375 | |||
376 | void CGUITable::clearRows() | ||
377 | { | ||
378 | Selected = -1; | ||
379 | Rows.clear(); | ||
380 | |||
381 | if (VerticalScrollBar) | ||
382 | VerticalScrollBar->setPos(0); | ||
383 | |||
384 | recalculateHeights(); | ||
385 | } | ||
386 | |||
387 | |||
388 | /*! | ||
389 | */ | ||
390 | s32 CGUITable::getSelected() const | ||
391 | { | ||
392 | return Selected; | ||
393 | } | ||
394 | |||
395 | //! set wich row is currently selected | ||
396 | void CGUITable::setSelected( s32 index ) | ||
397 | { | ||
398 | Selected = -1; | ||
399 | if ( index >= 0 && index < (s32) Rows.size() ) | ||
400 | Selected = index; | ||
401 | } | ||
402 | |||
403 | |||
404 | void CGUITable::recalculateWidths() | ||
405 | { | ||
406 | TotalItemWidth=0; | ||
407 | for ( u32 i=0; i < Columns.size(); ++i ) | ||
408 | { | ||
409 | TotalItemWidth += Columns[i].Width; | ||
410 | } | ||
411 | checkScrollbars(); | ||
412 | } | ||
413 | |||
414 | |||
415 | void CGUITable::recalculateHeights() | ||
416 | { | ||
417 | TotalItemHeight = 0; | ||
418 | IGUISkin* skin = Environment->getSkin(); | ||
419 | if (Font != skin->getFont()) | ||
420 | { | ||
421 | if (Font) | ||
422 | Font->drop(); | ||
423 | |||
424 | Font = skin->getFont(); | ||
425 | |||
426 | ItemHeight = 0; | ||
427 | |||
428 | if(Font) | ||
429 | { | ||
430 | ItemHeight = Font->getDimension(L"A").Height + (CellHeightPadding * 2); | ||
431 | Font->grab(); | ||
432 | } | ||
433 | } | ||
434 | TotalItemHeight = ItemHeight * Rows.size(); // header is not counted, because we only want items | ||
435 | checkScrollbars(); | ||
436 | } | ||
437 | |||
438 | |||
439 | // automatic enabled/disabling and resizing of scrollbars | ||
440 | void CGUITable::checkScrollbars() | ||
441 | { | ||
442 | IGUISkin* skin = Environment->getSkin(); | ||
443 | if ( !HorizontalScrollBar || !VerticalScrollBar || !skin) | ||
444 | return; | ||
445 | |||
446 | s32 scrollBarSize = skin->getSize(EGDS_SCROLLBAR_SIZE); | ||
447 | bool wasHorizontalScrollBarVisible = HorizontalScrollBar->isVisible(); | ||
448 | bool wasVerticalScrollBarVisible = VerticalScrollBar->isVisible(); | ||
449 | HorizontalScrollBar->setVisible(false); | ||
450 | VerticalScrollBar->setVisible(false); | ||
451 | |||
452 | // CAREFUL: near identical calculations for tableRect and clientClip are also done in draw | ||
453 | // area of table used for drawing without scrollbars | ||
454 | core::rect<s32> tableRect(AbsoluteRect); | ||
455 | tableRect.UpperLeftCorner.X += 1; | ||
456 | tableRect.UpperLeftCorner.Y += 1; | ||
457 | s32 headerBottom = tableRect.UpperLeftCorner.Y + ItemHeight; | ||
458 | |||
459 | // area of for the items (without header and without scrollbars) | ||
460 | core::rect<s32> clientClip(tableRect); | ||
461 | clientClip.UpperLeftCorner.Y = headerBottom + 1; | ||
462 | |||
463 | // needs horizontal scroll be visible? | ||
464 | if( TotalItemWidth > clientClip.getWidth() ) | ||
465 | { | ||
466 | clientClip.LowerRightCorner.Y -= scrollBarSize; | ||
467 | HorizontalScrollBar->setVisible(true); | ||
468 | HorizontalScrollBar->setMax(core::max_(0,TotalItemWidth - clientClip.getWidth())); | ||
469 | } | ||
470 | |||
471 | // needs vertical scroll be visible? | ||
472 | if( TotalItemHeight > clientClip.getHeight() ) | ||
473 | { | ||
474 | clientClip.LowerRightCorner.X -= scrollBarSize; | ||
475 | VerticalScrollBar->setVisible(true); | ||
476 | VerticalScrollBar->setMax(core::max_(0,TotalItemHeight - clientClip.getHeight())); | ||
477 | |||
478 | // check horizontal again because we have now smaller clientClip | ||
479 | if ( !HorizontalScrollBar->isVisible() ) | ||
480 | { | ||
481 | if( TotalItemWidth > clientClip.getWidth() ) | ||
482 | { | ||
483 | clientClip.LowerRightCorner.Y -= scrollBarSize; | ||
484 | HorizontalScrollBar->setVisible(true); | ||
485 | HorizontalScrollBar->setMax(core::max_(0,TotalItemWidth - clientClip.getWidth())); | ||
486 | } | ||
487 | } | ||
488 | } | ||
489 | |||
490 | // find the correct size for the vertical scrollbar | ||
491 | if ( VerticalScrollBar->isVisible() ) | ||
492 | { | ||
493 | if (!wasVerticalScrollBarVisible ) | ||
494 | VerticalScrollBar->setPos(0); | ||
495 | |||
496 | if ( HorizontalScrollBar->isVisible() ) | ||
497 | { | ||
498 | VerticalScrollBar->setRelativePosition( | ||
499 | core::rect<s32>(RelativeRect.getWidth() - scrollBarSize, 1, | ||
500 | RelativeRect.getWidth()-1, RelativeRect.getHeight()-(1+scrollBarSize) ) ); | ||
501 | } | ||
502 | else | ||
503 | { | ||
504 | VerticalScrollBar->setRelativePosition( | ||
505 | core::rect<s32>(RelativeRect.getWidth() - scrollBarSize, 1, | ||
506 | RelativeRect.getWidth()-1, RelativeRect.getHeight()-1) ); | ||
507 | } | ||
508 | } | ||
509 | |||
510 | // find the correct size for the horizontal scrollbar | ||
511 | if ( HorizontalScrollBar->isVisible() ) | ||
512 | { | ||
513 | if ( !wasHorizontalScrollBarVisible ) | ||
514 | HorizontalScrollBar->setPos(0); | ||
515 | |||
516 | if ( VerticalScrollBar->isVisible() ) | ||
517 | { | ||
518 | HorizontalScrollBar->setRelativePosition( core::rect<s32>(1, RelativeRect.getHeight() - scrollBarSize, RelativeRect.getWidth()-(1+scrollBarSize), RelativeRect.getHeight()-1) ); | ||
519 | } | ||
520 | else | ||
521 | { | ||
522 | HorizontalScrollBar->setRelativePosition( core::rect<s32>(1, RelativeRect.getHeight() - scrollBarSize, RelativeRect.getWidth()-1, RelativeRect.getHeight()-1) ); | ||
523 | } | ||
524 | } | ||
525 | } | ||
526 | |||
527 | |||
528 | void CGUITable::refreshControls() | ||
529 | { | ||
530 | updateAbsolutePosition(); | ||
531 | |||
532 | if ( VerticalScrollBar ) | ||
533 | VerticalScrollBar->setVisible(false); | ||
534 | |||
535 | if ( HorizontalScrollBar ) | ||
536 | HorizontalScrollBar->setVisible(false); | ||
537 | |||
538 | recalculateHeights(); | ||
539 | recalculateWidths(); | ||
540 | } | ||
541 | |||
542 | |||
543 | //! called if an event happened. | ||
544 | bool CGUITable::OnEvent(const SEvent &event) | ||
545 | { | ||
546 | if (isEnabled()) | ||
547 | { | ||
548 | |||
549 | switch(event.EventType) | ||
550 | { | ||
551 | case EET_GUI_EVENT: | ||
552 | switch(event.GUIEvent.EventType) | ||
553 | { | ||
554 | case gui::EGET_SCROLL_BAR_CHANGED: | ||
555 | if (event.GUIEvent.Caller == VerticalScrollBar) | ||
556 | { | ||
557 | // current position will get read out in draw | ||
558 | return true; | ||
559 | } | ||
560 | if (event.GUIEvent.Caller == HorizontalScrollBar) | ||
561 | { | ||
562 | // current position will get read out in draw | ||
563 | return true; | ||
564 | } | ||
565 | break; | ||
566 | case gui::EGET_ELEMENT_FOCUS_LOST: | ||
567 | { | ||
568 | CurrentResizedColumn = -1; | ||
569 | Selecting = false; | ||
570 | } | ||
571 | break; | ||
572 | default: | ||
573 | break; | ||
574 | } | ||
575 | break; | ||
576 | case EET_MOUSE_INPUT_EVENT: | ||
577 | { | ||
578 | if ( !isEnabled() ) | ||
579 | return false; | ||
580 | |||
581 | core::position2d<s32> p(event.MouseInput.X, event.MouseInput.Y); | ||
582 | |||
583 | switch(event.MouseInput.Event) | ||
584 | { | ||
585 | case EMIE_MOUSE_WHEEL: | ||
586 | VerticalScrollBar->setPos(VerticalScrollBar->getPos() + (event.MouseInput.Wheel < 0 ? -1 : 1)*-10); | ||
587 | return true; | ||
588 | |||
589 | case EMIE_LMOUSE_PRESSED_DOWN: | ||
590 | |||
591 | if (Environment->hasFocus(this) && | ||
592 | VerticalScrollBar->isVisible() && | ||
593 | VerticalScrollBar->getAbsolutePosition().isPointInside(p) && | ||
594 | VerticalScrollBar->OnEvent(event)) | ||
595 | return true; | ||
596 | |||
597 | if (Environment->hasFocus(this) && | ||
598 | HorizontalScrollBar->isVisible() && | ||
599 | HorizontalScrollBar->getAbsolutePosition().isPointInside(p) && | ||
600 | HorizontalScrollBar->OnEvent(event)) | ||
601 | return true; | ||
602 | |||
603 | if ( dragColumnStart( event.MouseInput.X, event.MouseInput.Y ) ) | ||
604 | { | ||
605 | Environment->setFocus(this); | ||
606 | return true; | ||
607 | } | ||
608 | |||
609 | if ( selectColumnHeader( event.MouseInput.X, event.MouseInput.Y ) ) | ||
610 | return true; | ||
611 | |||
612 | Selecting = true; | ||
613 | Environment->setFocus(this); | ||
614 | return true; | ||
615 | |||
616 | case EMIE_LMOUSE_LEFT_UP: | ||
617 | |||
618 | CurrentResizedColumn = -1; | ||
619 | Selecting = false; | ||
620 | if (!getAbsolutePosition().isPointInside(p)) | ||
621 | { | ||
622 | Environment->removeFocus(this); | ||
623 | } | ||
624 | |||
625 | if (Environment->hasFocus(this) && | ||
626 | VerticalScrollBar->isVisible() && | ||
627 | VerticalScrollBar->getAbsolutePosition().isPointInside(p) && | ||
628 | VerticalScrollBar->OnEvent(event)) | ||
629 | { | ||
630 | return true; | ||
631 | } | ||
632 | |||
633 | if (Environment->hasFocus(this) && | ||
634 | HorizontalScrollBar->isVisible() && | ||
635 | HorizontalScrollBar->getAbsolutePosition().isPointInside(p) && | ||
636 | HorizontalScrollBar->OnEvent(event)) | ||
637 | { | ||
638 | return true; | ||
639 | } | ||
640 | |||
641 | selectNew(event.MouseInput.Y); | ||
642 | return true; | ||
643 | |||
644 | case EMIE_MOUSE_MOVED: | ||
645 | if ( CurrentResizedColumn >= 0 ) | ||
646 | { | ||
647 | if ( dragColumnUpdate(event.MouseInput.X) ) | ||
648 | { | ||
649 | return true; | ||
650 | } | ||
651 | } | ||
652 | if (Selecting || MoveOverSelect) | ||
653 | { | ||
654 | if (getAbsolutePosition().isPointInside(p)) | ||
655 | { | ||
656 | selectNew(event.MouseInput.Y); | ||
657 | return true; | ||
658 | } | ||
659 | } | ||
660 | break; | ||
661 | default: | ||
662 | break; | ||
663 | } | ||
664 | } | ||
665 | break; | ||
666 | default: | ||
667 | break; | ||
668 | } | ||
669 | } | ||
670 | |||
671 | return IGUIElement::OnEvent(event); | ||
672 | } | ||
673 | |||
674 | |||
675 | void CGUITable::setColumnOrdering(u32 columnIndex, EGUI_COLUMN_ORDERING mode) | ||
676 | { | ||
677 | if ( columnIndex < Columns.size() ) | ||
678 | Columns[columnIndex].OrderingMode = mode; | ||
679 | } | ||
680 | |||
681 | |||
682 | void CGUITable::swapRows(u32 rowIndexA, u32 rowIndexB) | ||
683 | { | ||
684 | if ( rowIndexA >= Rows.size() ) | ||
685 | return; | ||
686 | |||
687 | if ( rowIndexB >= Rows.size() ) | ||
688 | return; | ||
689 | |||
690 | Row swap = Rows[rowIndexA]; | ||
691 | Rows[rowIndexA] = Rows[rowIndexB]; | ||
692 | Rows[rowIndexB] = swap; | ||
693 | |||
694 | if ( Selected == s32(rowIndexA) ) | ||
695 | Selected = rowIndexB; | ||
696 | else if( Selected == s32(rowIndexB) ) | ||
697 | Selected = rowIndexA; | ||
698 | |||
699 | } | ||
700 | |||
701 | |||
702 | bool CGUITable::dragColumnStart(s32 xpos, s32 ypos) | ||
703 | { | ||
704 | if ( !ResizableColumns ) | ||
705 | return false; | ||
706 | |||
707 | if ( ypos > ( AbsoluteRect.UpperLeftCorner.Y + ItemHeight ) ) | ||
708 | return false; | ||
709 | |||
710 | const s32 CLICK_AREA = 12; // to left and right of line which can be dragged | ||
711 | s32 pos = AbsoluteRect.UpperLeftCorner.X+1; | ||
712 | |||
713 | if ( HorizontalScrollBar && HorizontalScrollBar->isVisible() ) | ||
714 | pos -= HorizontalScrollBar->getPos(); | ||
715 | |||
716 | pos += TotalItemWidth; | ||
717 | |||
718 | // have to search from the right as otherwise lines could no longer be resized when a column width is 0 | ||
719 | for ( s32 i = (s32)Columns.size()-1; i >= 0 ; --i ) | ||
720 | { | ||
721 | u32 colWidth = Columns[i].Width; | ||
722 | |||
723 | if ( xpos >= (pos - CLICK_AREA) && xpos < ( pos + CLICK_AREA ) ) | ||
724 | { | ||
725 | CurrentResizedColumn = i; | ||
726 | ResizeStart = xpos; | ||
727 | return true; | ||
728 | } | ||
729 | |||
730 | pos -= colWidth; | ||
731 | } | ||
732 | |||
733 | return false; | ||
734 | } | ||
735 | |||
736 | |||
737 | bool CGUITable::dragColumnUpdate(s32 xpos) | ||
738 | { | ||
739 | if ( !ResizableColumns || CurrentResizedColumn < 0 || CurrentResizedColumn >= s32(Columns.size()) ) | ||
740 | { | ||
741 | CurrentResizedColumn = -1; | ||
742 | return false; | ||
743 | } | ||
744 | |||
745 | s32 width = s32(Columns[CurrentResizedColumn].Width) + (xpos-ResizeStart); | ||
746 | if ( width < 0 ) | ||
747 | width = 0; | ||
748 | setColumnWidth(CurrentResizedColumn, u32(width)); | ||
749 | ResizeStart = xpos; | ||
750 | |||
751 | return false; | ||
752 | } | ||
753 | |||
754 | |||
755 | bool CGUITable::selectColumnHeader(s32 xpos, s32 ypos) | ||
756 | { | ||
757 | if ( ypos > ( AbsoluteRect.UpperLeftCorner.Y + ItemHeight ) ) | ||
758 | return false; | ||
759 | |||
760 | s32 pos = AbsoluteRect.UpperLeftCorner.X+1; | ||
761 | |||
762 | if ( HorizontalScrollBar && HorizontalScrollBar->isVisible() ) | ||
763 | pos -= HorizontalScrollBar->getPos(); | ||
764 | |||
765 | for ( u32 i = 0 ; i < Columns.size() ; ++i ) | ||
766 | { | ||
767 | u32 colWidth = Columns[i].Width; | ||
768 | |||
769 | if ( xpos >= pos && xpos < ( pos + s32(colWidth) ) ) | ||
770 | { | ||
771 | setActiveColumn( i, true ); | ||
772 | |||
773 | return true; | ||
774 | } | ||
775 | |||
776 | pos += colWidth; | ||
777 | } | ||
778 | |||
779 | return false; | ||
780 | } | ||
781 | |||
782 | |||
783 | void CGUITable::orderRows(s32 columnIndex, EGUI_ORDERING_MODE mode) | ||
784 | { | ||
785 | Row swap; | ||
786 | |||
787 | if ( columnIndex == -1 ) | ||
788 | columnIndex = getActiveColumn(); | ||
789 | if ( columnIndex < 0 ) | ||
790 | return; | ||
791 | |||
792 | if ( mode == EGOM_ASCENDING ) | ||
793 | { | ||
794 | for ( s32 i = 0 ; i < s32(Rows.size()) - 1 ; ++i ) | ||
795 | { | ||
796 | for ( s32 j = 0 ; j < s32(Rows.size()) - i - 1 ; ++j ) | ||
797 | { | ||
798 | if ( Rows[j+1].Items[columnIndex].Text < Rows[j].Items[columnIndex].Text ) | ||
799 | { | ||
800 | swap = Rows[j]; | ||
801 | Rows[j] = Rows[j+1]; | ||
802 | Rows[j+1] = swap; | ||
803 | |||
804 | if ( Selected == j ) | ||
805 | Selected = j+1; | ||
806 | else if( Selected == j+1 ) | ||
807 | Selected = j; | ||
808 | } | ||
809 | } | ||
810 | } | ||
811 | } | ||
812 | else if ( mode == EGOM_DESCENDING ) | ||
813 | { | ||
814 | for ( s32 i = 0 ; i < s32(Rows.size()) - 1 ; ++i ) | ||
815 | { | ||
816 | for ( s32 j = 0 ; j < s32(Rows.size()) - i - 1 ; ++j ) | ||
817 | { | ||
818 | if ( Rows[j].Items[columnIndex].Text < Rows[j+1].Items[columnIndex].Text) | ||
819 | { | ||
820 | swap = Rows[j]; | ||
821 | Rows[j] = Rows[j+1]; | ||
822 | Rows[j+1] = swap; | ||
823 | |||
824 | if ( Selected == j ) | ||
825 | Selected = j+1; | ||
826 | else if( Selected == j+1 ) | ||
827 | Selected = j; | ||
828 | } | ||
829 | } | ||
830 | } | ||
831 | } | ||
832 | } | ||
833 | |||
834 | |||
835 | void CGUITable::selectNew(s32 ypos, bool onlyHover) | ||
836 | { | ||
837 | IGUISkin* skin = Environment->getSkin(); | ||
838 | if (!skin) | ||
839 | return; | ||
840 | |||
841 | s32 oldSelected = Selected; | ||
842 | |||
843 | if ( ypos < ( AbsoluteRect.UpperLeftCorner.Y + ItemHeight ) ) | ||
844 | return; | ||
845 | |||
846 | // find new selected item. | ||
847 | if (ItemHeight!=0) | ||
848 | Selected = ((ypos - AbsoluteRect.UpperLeftCorner.Y - ItemHeight - 1) + VerticalScrollBar->getPos()) / ItemHeight; | ||
849 | |||
850 | if (Selected >= (s32)Rows.size()) | ||
851 | Selected = Rows.size() - 1; | ||
852 | else if (Selected<0) | ||
853 | Selected = 0; | ||
854 | |||
855 | // post the news | ||
856 | if (Parent && !onlyHover) | ||
857 | { | ||
858 | SEvent event; | ||
859 | event.EventType = EET_GUI_EVENT; | ||
860 | event.GUIEvent.Caller = this; | ||
861 | event.GUIEvent.Element = 0; | ||
862 | event.GUIEvent.EventType = (Selected != oldSelected) ? EGET_TABLE_CHANGED : EGET_TABLE_SELECTED_AGAIN; | ||
863 | Parent->OnEvent(event); | ||
864 | } | ||
865 | } | ||
866 | |||
867 | |||
868 | //! draws the element and its children | ||
869 | void CGUITable::draw() | ||
870 | { | ||
871 | if (!IsVisible) | ||
872 | return; | ||
873 | |||
874 | irr::video::IVideoDriver* driver = Environment->getVideoDriver(); | ||
875 | |||
876 | IGUISkin* skin = Environment->getSkin(); | ||
877 | if (!skin) | ||
878 | return; | ||
879 | |||
880 | IGUIFont* font = skin->getFont(); | ||
881 | if (!font) | ||
882 | return; | ||
883 | |||
884 | // CAREFUL: near identical calculations for tableRect and clientClip are also done in checkScrollbars and selectColumnHeader | ||
885 | // Area of table used for drawing without scrollbars | ||
886 | core::rect<s32> tableRect(AbsoluteRect); | ||
887 | tableRect.UpperLeftCorner.X += 1; | ||
888 | tableRect.UpperLeftCorner.Y += 1; | ||
889 | if ( VerticalScrollBar && VerticalScrollBar->isVisible() ) | ||
890 | tableRect.LowerRightCorner.X -= skin->getSize(EGDS_SCROLLBAR_SIZE); | ||
891 | if ( HorizontalScrollBar && HorizontalScrollBar->isVisible() ) | ||
892 | tableRect.LowerRightCorner.Y -= skin->getSize(EGDS_SCROLLBAR_SIZE); | ||
893 | |||
894 | s32 headerBottom = tableRect.UpperLeftCorner.Y + ItemHeight; | ||
895 | |||
896 | // area of for the items (without header and without scrollbars) | ||
897 | core::rect<s32> clientClip(tableRect); | ||
898 | clientClip.UpperLeftCorner.Y = headerBottom + 1; | ||
899 | clientClip.clipAgainst(AbsoluteClippingRect); | ||
900 | |||
901 | // draw background for whole element | ||
902 | skin->draw3DSunkenPane(this, skin->getColor(EGDC_3D_HIGH_LIGHT), true, DrawBack, AbsoluteRect, &AbsoluteClippingRect); | ||
903 | |||
904 | // scrolledTableClient is the area where the table items would be if it could be drawn completely | ||
905 | core::rect<s32> scrolledTableClient(tableRect); | ||
906 | scrolledTableClient.UpperLeftCorner.Y = headerBottom + 1; | ||
907 | scrolledTableClient.LowerRightCorner.Y = scrolledTableClient.UpperLeftCorner.Y + TotalItemHeight; | ||
908 | scrolledTableClient.LowerRightCorner.X = scrolledTableClient.UpperLeftCorner.X + TotalItemWidth; | ||
909 | if ( VerticalScrollBar && VerticalScrollBar->isVisible() ) | ||
910 | { | ||
911 | scrolledTableClient.UpperLeftCorner.Y -= VerticalScrollBar->getPos(); | ||
912 | scrolledTableClient.LowerRightCorner.Y -= VerticalScrollBar->getPos(); | ||
913 | } | ||
914 | if ( HorizontalScrollBar && HorizontalScrollBar->isVisible() ) | ||
915 | { | ||
916 | scrolledTableClient.UpperLeftCorner.X -= HorizontalScrollBar->getPos(); | ||
917 | scrolledTableClient.LowerRightCorner.X -= HorizontalScrollBar->getPos(); | ||
918 | } | ||
919 | |||
920 | // rowRect is around the scrolled row | ||
921 | core::rect<s32> rowRect(scrolledTableClient); | ||
922 | rowRect.LowerRightCorner.Y = rowRect.UpperLeftCorner.Y + ItemHeight; | ||
923 | |||
924 | u32 pos; | ||
925 | for ( u32 i = 0 ; i < Rows.size() ; ++i ) | ||
926 | { | ||
927 | if (rowRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.Y && | ||
928 | rowRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y) | ||
929 | { | ||
930 | // draw row seperator | ||
931 | if ( DrawFlags & EGTDF_ROWS ) | ||
932 | { | ||
933 | core::rect<s32> lineRect(rowRect); | ||
934 | lineRect.UpperLeftCorner.Y = lineRect.LowerRightCorner.Y - 1; | ||
935 | driver->draw2DRectangle(skin->getColor(EGDC_3D_SHADOW), lineRect, &clientClip); | ||
936 | } | ||
937 | |||
938 | core::rect<s32> textRect(rowRect); | ||
939 | pos = rowRect.UpperLeftCorner.X; | ||
940 | |||
941 | // draw selected row background highlighted | ||
942 | if ((s32)i == Selected && DrawFlags & EGTDF_ACTIVE_ROW ) | ||
943 | driver->draw2DRectangle(skin->getColor(EGDC_HIGH_LIGHT), rowRect, &clientClip); | ||
944 | |||
945 | for ( u32 j = 0 ; j < Columns.size() ; ++j ) | ||
946 | { | ||
947 | textRect.UpperLeftCorner.X = pos + CellWidthPadding; | ||
948 | textRect.LowerRightCorner.X = pos + Columns[j].Width - CellWidthPadding; | ||
949 | |||
950 | // draw item text | ||
951 | if ((s32)i == Selected) | ||
952 | { | ||
953 | font->draw(Rows[i].Items[j].BrokenText.c_str(), textRect, skin->getColor(isEnabled() ? EGDC_HIGH_LIGHT_TEXT : EGDC_GRAY_TEXT), false, true, &clientClip); | ||
954 | } | ||
955 | else | ||
956 | { | ||
957 | if ( !Rows[i].Items[j].IsOverrideColor ) // skin-colors can change | ||
958 | Rows[i].Items[j].Color = skin->getColor(EGDC_BUTTON_TEXT); | ||
959 | font->draw(Rows[i].Items[j].BrokenText.c_str(), textRect, isEnabled() ? Rows[i].Items[j].Color : skin->getColor(EGDC_GRAY_TEXT), false, true, &clientClip); | ||
960 | } | ||
961 | |||
962 | pos += Columns[j].Width; | ||
963 | } | ||
964 | } | ||
965 | |||
966 | rowRect.UpperLeftCorner.Y += ItemHeight; | ||
967 | rowRect.LowerRightCorner.Y += ItemHeight; | ||
968 | } | ||
969 | |||
970 | core::rect<s32> columnSeparator(clientClip); | ||
971 | pos = scrolledTableClient.UpperLeftCorner.X; | ||
972 | |||
973 | core::rect<s32> tableClip(tableRect); | ||
974 | tableClip.clipAgainst(AbsoluteClippingRect); | ||
975 | |||
976 | for (u32 i = 0 ; i < Columns.size() ; ++i ) | ||
977 | { | ||
978 | const wchar_t* text = Columns[i].Name.c_str(); | ||
979 | u32 colWidth = Columns[i].Width; | ||
980 | |||
981 | //core::dimension2d<s32 > dim = font->getDimension(text); | ||
982 | |||
983 | core::rect<s32> columnrect(pos, tableRect.UpperLeftCorner.Y, pos + colWidth, headerBottom); | ||
984 | |||
985 | // draw column background | ||
986 | skin->draw3DButtonPaneStandard(this, columnrect, &tableClip); | ||
987 | |||
988 | // draw column seperator | ||
989 | if ( DrawFlags & EGTDF_COLUMNS ) | ||
990 | { | ||
991 | columnSeparator.UpperLeftCorner.X = pos; | ||
992 | columnSeparator.LowerRightCorner.X = pos + 1; | ||
993 | driver->draw2DRectangle(skin->getColor(EGDC_3D_SHADOW), columnSeparator, &tableClip); | ||
994 | } | ||
995 | |||
996 | // draw header column text | ||
997 | columnrect.UpperLeftCorner.X += CellWidthPadding; | ||
998 | font->draw(text, columnrect, skin->getColor( isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), false, true, &tableClip); | ||
999 | |||
1000 | // draw icon for active column tab | ||
1001 | if ( (s32)i == ActiveTab ) | ||
1002 | { | ||
1003 | if ( CurrentOrdering == EGOM_ASCENDING ) | ||
1004 | { | ||
1005 | columnrect.UpperLeftCorner.X = columnrect.LowerRightCorner.X - CellWidthPadding - ARROW_PAD / 2 + 2; | ||
1006 | columnrect.UpperLeftCorner.Y += 7; | ||
1007 | skin->drawIcon(this,EGDI_CURSOR_UP,columnrect.UpperLeftCorner,0,0,false,&tableClip); | ||
1008 | } | ||
1009 | else | ||
1010 | { | ||
1011 | columnrect.UpperLeftCorner.X = columnrect.LowerRightCorner.X - CellWidthPadding - ARROW_PAD / 2 + 2; | ||
1012 | columnrect.UpperLeftCorner.Y += 7; | ||
1013 | skin->drawIcon(this,EGDI_CURSOR_DOWN,columnrect.UpperLeftCorner,0,0,false,&tableClip); | ||
1014 | } | ||
1015 | } | ||
1016 | |||
1017 | pos += colWidth; | ||
1018 | } | ||
1019 | |||
1020 | // fill up header background up to the right side | ||
1021 | core::rect<s32> columnrect(pos, tableRect.UpperLeftCorner.Y, tableRect.LowerRightCorner.X , headerBottom); | ||
1022 | skin->draw3DButtonPaneStandard(this, columnrect, &tableClip); | ||
1023 | |||
1024 | IGUIElement::draw(); | ||
1025 | } | ||
1026 | |||
1027 | |||
1028 | void CGUITable::breakText(const core::stringw& text, core::stringw& brokenText, u32 cellWidth) | ||
1029 | { | ||
1030 | IGUISkin* skin = Environment->getSkin(); | ||
1031 | |||
1032 | if (!skin) | ||
1033 | return; | ||
1034 | |||
1035 | if (!Font) | ||
1036 | return; | ||
1037 | |||
1038 | IGUIFont* font = skin->getFont(); | ||
1039 | if (!font) | ||
1040 | return; | ||
1041 | |||
1042 | core::stringw line, lineDots; | ||
1043 | wchar_t c[2]; | ||
1044 | c[1] = L'\0'; | ||
1045 | |||
1046 | const u32 maxLength = cellWidth - (CellWidthPadding * 2); | ||
1047 | const u32 maxLengthDots = cellWidth - (CellWidthPadding * 2) - font->getDimension(L"...").Width; | ||
1048 | const u32 size = text.size(); | ||
1049 | u32 pos = 0; | ||
1050 | |||
1051 | u32 i; | ||
1052 | |||
1053 | for (i=0; i<size; ++i) | ||
1054 | { | ||
1055 | c[0] = text[i]; | ||
1056 | |||
1057 | if (c[0] == L'\n') | ||
1058 | break; | ||
1059 | |||
1060 | pos += font->getDimension(c).Width; | ||
1061 | if ( pos > maxLength ) | ||
1062 | break; | ||
1063 | |||
1064 | if ( font->getDimension( (line + c).c_str() ).Width > maxLengthDots ) | ||
1065 | lineDots = line; | ||
1066 | |||
1067 | line += c[0]; | ||
1068 | } | ||
1069 | |||
1070 | if ( i < size ) | ||
1071 | brokenText = lineDots + L"..."; | ||
1072 | else | ||
1073 | brokenText = line; | ||
1074 | } | ||
1075 | |||
1076 | |||
1077 | //! Set some flags influencing the layout of the table | ||
1078 | void CGUITable::setDrawFlags(s32 flags) | ||
1079 | { | ||
1080 | DrawFlags = flags; | ||
1081 | } | ||
1082 | |||
1083 | |||
1084 | //! Get the flags which influence the layout of the table | ||
1085 | s32 CGUITable::getDrawFlags() const | ||
1086 | { | ||
1087 | return DrawFlags; | ||
1088 | } | ||
1089 | |||
1090 | |||
1091 | //! Writes attributes of the element. | ||
1092 | void CGUITable::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const | ||
1093 | { | ||
1094 | IGUITable::serializeAttributes(out, options); | ||
1095 | |||
1096 | out->addInt("ColumnCount", Columns.size()); | ||
1097 | u32 i; | ||
1098 | for (i=0;i<Columns.size(); ++i) | ||
1099 | { | ||
1100 | core::stringc label; | ||
1101 | |||
1102 | label = "Column"; label += i; label += "name"; | ||
1103 | out->addString(label.c_str(), Columns[i].Name.c_str() ); | ||
1104 | label = "Column"; label += i; label += "width"; | ||
1105 | out->addInt(label.c_str(), Columns[i].Width ); | ||
1106 | label = "Column"; label += i; label += "OrderingMode"; | ||
1107 | out->addEnum(label.c_str(), Columns[i].OrderingMode, GUIColumnOrderingNames); | ||
1108 | } | ||
1109 | |||
1110 | out->addInt("RowCount", Rows.size()); | ||
1111 | for (i=0;i<Rows.size(); ++i) | ||
1112 | { | ||
1113 | core::stringc label; | ||
1114 | |||
1115 | // Height currently not used and could be recalculated anyway | ||
1116 | //label = "Row"; label += i; label += "height"; | ||
1117 | //out->addInt(label.c_str(), Rows[i].Height ); | ||
1118 | |||
1119 | //label = "Row"; label += i; label += "ItemCount"; | ||
1120 | //out->addInt(label.c_str(), Rows[i].Items.size()); | ||
1121 | u32 c; | ||
1122 | for ( c=0; c < Rows[i].Items.size(); ++c ) | ||
1123 | { | ||
1124 | label = "Row"; label += i; label += "cell"; label += c; label += "text"; | ||
1125 | out->addString(label.c_str(), Rows[i].Items[c].Text.c_str() ); | ||
1126 | // core::stringw BrokenText; // can be recalculated | ||
1127 | label = "Row"; label += i; label += "cell"; label += c; label += "color"; | ||
1128 | out->addColor(label.c_str(), Rows[i].Items[c].Color ); | ||
1129 | label = "Row"; label += i; label += "cell"; label += c; label += "IsOverrideColor"; | ||
1130 | out->addColor(label.c_str(), Rows[i].Items[c].IsOverrideColor ); | ||
1131 | // void *data; // can't be serialized | ||
1132 | } | ||
1133 | } | ||
1134 | |||
1135 | // s32 ItemHeight; // can be calculated | ||
1136 | // TotalItemHeight // calculated | ||
1137 | // TotalItemWidth // calculated | ||
1138 | // gui::IGUIFont* Font; // font is just the current font from environment | ||
1139 | // gui::IGUIScrollBar* VerticalScrollBar; // not serialized | ||
1140 | // gui::IGUIScrollBar* HorizontalScrollBar; // not serialized | ||
1141 | |||
1142 | out->addBool ("Clip", Clip); | ||
1143 | out->addBool ("DrawBack", DrawBack); | ||
1144 | out->addBool ("MoveOverSelect", MoveOverSelect); | ||
1145 | |||
1146 | // s32 CurrentResizedColumn; // runtime info - depends on user action | ||
1147 | out->addBool ("ResizableColumns", ResizableColumns); | ||
1148 | |||
1149 | // s32 Selected; // runtime info - depends on user action | ||
1150 | out->addInt("CellWidthPadding", CellWidthPadding ); | ||
1151 | out->addInt("CellHeightPadding", CellHeightPadding ); | ||
1152 | // s32 ActiveTab; // runtime info - depends on user action | ||
1153 | // bool Selecting; // runtime info - depends on user action | ||
1154 | out->addEnum("CurrentOrdering", CurrentOrdering, GUIOrderingModeNames); | ||
1155 | out->addInt("DrawFlags", DrawFlags); | ||
1156 | } | ||
1157 | |||
1158 | |||
1159 | //! Reads attributes of the element | ||
1160 | void CGUITable::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) | ||
1161 | { | ||
1162 | IGUITable::deserializeAttributes(in, options); | ||
1163 | |||
1164 | Columns.clear(); | ||
1165 | u32 columnCount = in->getAttributeAsInt("ColumnCount"); | ||
1166 | u32 i; | ||
1167 | for (i=0;i<columnCount; ++i) | ||
1168 | { | ||
1169 | core::stringc label; | ||
1170 | Column column; | ||
1171 | |||
1172 | label = "Column"; label += i; label += "name"; | ||
1173 | column.Name = core::stringw(in->getAttributeAsString(label.c_str()).c_str()); | ||
1174 | label = "Column"; label += i; label += "width"; | ||
1175 | column.Width = in->getAttributeAsInt(label.c_str()); | ||
1176 | label = "Column"; label += i; label += "OrderingMode"; | ||
1177 | |||
1178 | column.OrderingMode = EGCO_NONE; | ||
1179 | s32 co = in->getAttributeAsEnumeration(label.c_str(), GUIColumnOrderingNames); | ||
1180 | if (co > 0) | ||
1181 | column.OrderingMode = EGUI_COLUMN_ORDERING(co); | ||
1182 | |||
1183 | Columns.push_back(column); | ||
1184 | } | ||
1185 | |||
1186 | Rows.clear(); | ||
1187 | u32 rowCount = in->getAttributeAsInt("RowCount"); | ||
1188 | for (i=0; i<rowCount; ++i) | ||
1189 | { | ||
1190 | core::stringc label; | ||
1191 | |||
1192 | Row row; | ||
1193 | |||
1194 | // Height currently not used and could be recalculated anyway | ||
1195 | //label = "Row"; label += i; label += "height"; | ||
1196 | //row.Height = in->getAttributeAsInt(label.c_str() ); | ||
1197 | |||
1198 | Rows.push_back(row); | ||
1199 | |||
1200 | //label = "Row"; label += i; label += "ItemCount"; | ||
1201 | //u32 itemCount = in->getAttributeAsInt(label.c_str()); | ||
1202 | u32 c; | ||
1203 | for ( c=0; c < columnCount; ++c ) | ||
1204 | { | ||
1205 | Cell cell; | ||
1206 | |||
1207 | label = "Row"; label += i; label += "cell"; label += c; label += "text"; | ||
1208 | cell.Text = core::stringw(in->getAttributeAsString(label.c_str()).c_str()); | ||
1209 | breakText( cell.Text, cell.BrokenText, Columns[c].Width ); | ||
1210 | label = "Row"; label += i; label += "cell"; label += c; label += "color"; | ||
1211 | cell.Color = in->getAttributeAsColor(label.c_str()); | ||
1212 | label = "Row"; label += i; label += "cell"; label += c; label += "IsOverrideColor"; | ||
1213 | cell.IsOverrideColor = in->getAttributeAsBool(label.c_str()); | ||
1214 | |||
1215 | cell.Data = NULL; | ||
1216 | |||
1217 | Rows[Rows.size()-1].Items.push_back(cell); | ||
1218 | } | ||
1219 | } | ||
1220 | |||
1221 | ItemHeight = 0; // calculated | ||
1222 | TotalItemHeight = 0; // calculated | ||
1223 | TotalItemWidth = 0; // calculated | ||
1224 | |||
1225 | // force font recalculation | ||
1226 | if ( Font ) | ||
1227 | { | ||
1228 | Font->drop(); | ||
1229 | Font = 0; | ||
1230 | } | ||
1231 | |||
1232 | Clip = in->getAttributeAsBool("Clip"); | ||
1233 | DrawBack = in->getAttributeAsBool("DrawBack"); | ||
1234 | MoveOverSelect = in->getAttributeAsBool("MoveOverSelect"); | ||
1235 | |||
1236 | CurrentResizedColumn = -1; | ||
1237 | ResizeStart = 0; | ||
1238 | ResizableColumns = in->getAttributeAsBool("ResizableColumns"); | ||
1239 | |||
1240 | Selected = -1; | ||
1241 | CellWidthPadding = in->getAttributeAsInt("CellWidthPadding"); | ||
1242 | CellHeightPadding = in->getAttributeAsInt("CellHeightPadding"); | ||
1243 | ActiveTab = -1; | ||
1244 | Selecting = false; | ||
1245 | |||
1246 | CurrentOrdering = (EGUI_ORDERING_MODE) in->getAttributeAsEnumeration("CurrentOrdering", GUIOrderingModeNames); | ||
1247 | DrawFlags = in->getAttributeAsInt("DrawFlags"); | ||
1248 | |||
1249 | refreshControls(); | ||
1250 | } | ||
1251 | |||
1252 | } // end namespace gui | ||
1253 | } // end namespace irr | ||
1254 | |||
1255 | #endif | ||
1256 | |||