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