~baltix/+junk/irrlicht-test

« back to all changes in this revision

Viewing changes to source/Irrlicht/CGUITable.cpp

  • Committer: Mantas Kriaučiūnas
  • Date: 2011-07-18 13:06:25 UTC
  • Revision ID: mantas@akl.lt-20110718130625-c5pvifp61e7kj1ol
Included whole irrlicht SVN libraries to work around launchpad recipe issue with quilt, see https://answers.launchpad.net/launchpad/+question/165193

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (C) 2002-2011 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