Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/foxtools/MFXDecalsTable.cpp
193674 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2026 German Aerospace Center (DLR) and others.
4
// This program and the accompanying materials are made available under the
5
// terms of the Eclipse Public License 2.0 which is available at
6
// https://www.eclipse.org/legal/epl-2.0/
7
// This Source Code may also be made available under the following Secondary
8
// Licenses when the conditions for such availability set forth in the Eclipse
9
// Public License 2.0 are satisfied: GNU General Public License, version 2
10
// or later which is available at
11
// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
/****************************************************************************/
14
/// @file MFXDecalsTable.cpp
15
/// @author Pablo Alvarez Lopez
16
/// @date Feb 2023
17
///
18
// Table used for show and edit decal values
19
/****************************************************************************/
20
#include <config.h>
21
22
#include <utils/gui/div/GUIDesigns.h>
23
#include <utils/gui/images/GUIIconSubSys.h>
24
#include <utils/gui/windows/GUIAppEnum.h>
25
#include <utils/gui/windows/GUIDialog_ViewSettings.h>
26
#include <utils/gui/windows/GUIGlChildWindow.h>
27
#include <utils/gui/windows/GUIMainWindow.h>
28
29
#include "MFXDecalsTable.h"
30
31
32
#define EXTRAMARGIN 4
33
34
#define MAXROWS 100
35
36
// ===========================================================================
37
// FOX callback mapping
38
// ===========================================================================
39
40
FXDEFMAP(MFXDecalsTable) MFXDecalsTableMap[] = {
41
FXMAPFUNC(MID_MBTTIP_FOCUS, 0, MFXDecalsTable::onFocusRow),
42
FXMAPFUNC(SEL_FOCUSIN, MID_DECALSTABLE_TEXTFIELD, MFXDecalsTable::onFocusRow),
43
FXMAPFUNC(SEL_KEYPRESS, MID_DECALSTABLE_TEXTFIELD, MFXDecalsTable::onCmdKeyPress),
44
FXMAPFUNC(SEL_COMMAND, MID_DECALSTABLE_TEXTFIELD, MFXDecalsTable::onCmdEditRowString),
45
FXMAPFUNC(SEL_COMMAND, MID_DECALSTABLE_SPINNER, MFXDecalsTable::onCmdEditRowSpinner),
46
FXMAPFUNC(SEL_COMMAND, MID_DECALSTABLE_CHECKBOX, MFXDecalsTable::onCmdEditRowCheckBox),
47
FXMAPFUNC(SEL_COMMAND, MID_DECALSTABLE_OPEN, MFXDecalsTable::onCmdOpenDecal),
48
FXMAPFUNC(SEL_COMMAND, MID_DECALSTABLE_ADD, MFXDecalsTable::onCmdAddRow),
49
FXMAPFUNC(SEL_UPDATE, MID_DECALSTABLE_ADD, MFXDecalsTable::onUpdAddRow),
50
FXMAPFUNC(SEL_COMMAND, MID_DECALSTABLE_REMOVE, MFXDecalsTable::onCmdRemoveRow),
51
};
52
53
// Object implementation
54
FXIMPLEMENT(MFXDecalsTable, FXVerticalFrame, MFXDecalsTableMap, ARRAYNUMBER(MFXDecalsTableMap))
55
56
// ===========================================================================
57
// method definitions
58
// ===========================================================================
59
60
// ---------------------------------------------------------------------------
61
// MFXDecalsTable - public methods
62
// ---------------------------------------------------------------------------
63
64
MFXDecalsTable::MFXDecalsTable(GUIDialog_ViewSettings* dialogViewSettingsParent, FXComposite* parent) :
65
FXVerticalFrame(parent, GUIDesignAuxiliarFrameFixHeight),
66
myIndexFont(new FXFont(getApp(), "Segoe UI", 9)),
67
myIndexSelectedFont(new FXFont(getApp(), "Segoe UI", 9, FXFont::Bold)),
68
myDialogViewSettings(dialogViewSettingsParent) {
69
// create vertical frame for rows
70
myColumnsFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarFrame);
71
// create add button
72
myAddButton = GUIDesigns::buildFXButton(this, "", TL("Add decal"), TL("Add decal."),
73
GUIIconSubSys::getIcon(GUIIcon::ADD), this, MID_DECALSTABLE_ADD, GUIDesignButtonIcon);
74
}
75
76
77
MFXDecalsTable::~MFXDecalsTable() {
78
// delete fonts
79
delete myIndexFont;
80
delete myIndexSelectedFont;
81
}
82
83
84
void
85
MFXDecalsTable::clearTable() {
86
// clear rows (always before columns, because delete row delete also all cells)
87
for (const auto& row : myRows) {
88
delete row;
89
}
90
// clear columns
91
for (const auto& column : myColumns) {
92
delete column;
93
}
94
// drop rows and columns
95
myRows.clear();
96
myColumns.clear();
97
}
98
99
100
void
101
MFXDecalsTable::fillTable() {
102
// first clear table
103
clearTable();
104
// get decals
105
const auto decals = myDialogViewSettings->getSUMOAbstractView()->getDecals();
106
// create columns
107
std::string columnsType = "ibfppppppcd";
108
for (int i = 0; i < (FXint)columnsType.size(); i++) {
109
myColumns.push_back(new Column(this, i, columnsType.at(i)));
110
}
111
// get num decals
112
const int numDecals = decals.size() < MAXROWS ? (int)decals.size() : MAXROWS;
113
// create rows
114
for (int i = 0; i < numDecals; i++) {
115
// get decal
116
const auto& decal = decals.at(i);
117
// create row
118
auto row = new Row(this);
119
// fill cells
120
row->getCells().at(2)->getTextField()->setText(decal.filename.c_str());
121
row->getCells().at(3)->getSpinner()->setValue(decal.centerX);
122
row->getCells().at(4)->getSpinner()->setValue(decal.centerY);
123
row->getCells().at(5)->getSpinner()->setValue(decal.width);
124
row->getCells().at(6)->getSpinner()->setValue(decal.height);
125
row->getCells().at(7)->getSpinner()->setValue(decal.rot);
126
row->getCells().at(8)->getSpinner()->setValue(decal.layer);
127
if (decal.screenRelative) {
128
row->getCells().at(9)->getCheckButton()->setCheck(true);
129
row->getCells().at(9)->getCheckButton()->setText("true");
130
} else {
131
row->getCells().at(9)->getCheckButton()->setCheck(false);
132
row->getCells().at(9)->getCheckButton()->setText("false");
133
}
134
myRows.push_back(row);
135
}
136
// set headers
137
myColumns.at(2)->setColumnLabel("filename", "");
138
myColumns.at(3)->setColumnLabel("centerX", "");
139
myColumns.at(4)->setColumnLabel("centerY", "");
140
myColumns.at(5)->setColumnLabel("width", "");
141
myColumns.at(6)->setColumnLabel("height", "");
142
myColumns.at(7)->setColumnLabel("rotation", "");
143
myColumns.at(8)->setColumnLabel("layer", "");
144
myColumns.at(9)->setColumnLabel("sRel", "screen relative");
145
// adjust height (header + rows + add button)
146
setHeight((numDecals + 2) * GUIDesignHeight);
147
// call create to create all row's elements
148
create();
149
}
150
151
152
void
153
MFXDecalsTable::setItemText(FXint row, FXint column, const std::string& text) {
154
if ((row >= 0) && (row < (FXint)myRows.size()) &&
155
(column >= 0) && (column < (FXint)myColumns.size())) {
156
myRows.at(row)->setText(column, text);
157
} else {
158
throw ProcessError(TL("Invalid row or column"));
159
}
160
}
161
162
163
std::string
164
MFXDecalsTable::getItemText(const int row, const int column) const {
165
if ((row >= 0) && (row < (FXint)myRows.size()) &&
166
(column >= 0) && (column < (FXint)myColumns.size())) {
167
return myRows.at(row)->getText(column);
168
}
169
throw ProcessError(TL("Invalid row or column"));
170
}
171
172
173
int
174
MFXDecalsTable::getNumRows() const {
175
return (int)myRows.size();
176
}
177
178
179
int
180
MFXDecalsTable::getCurrentSelectedRow() const {
181
return myCurrentSelectedRow;
182
}
183
184
185
void
186
MFXDecalsTable::selectRow(const int row) {
187
if ((row >= 0) && (row < (FXint)myRows.size())) {
188
// update current selected row
189
myCurrentSelectedRow = row;
190
// update index label
191
updateIndexLabel();
192
} else {
193
throw ProcessError(TL("Invalid row"));
194
}
195
}
196
197
198
void
199
MFXDecalsTable::setColumnLabel(const int column, const std::string& text, const std::string& tooltip) {
200
if ((column >= 0) && (column < (int)myColumns.size())) {
201
myColumns.at(column)->setColumnLabel(text, tooltip);
202
} else {
203
throw ProcessError(TL("Invalid column"));
204
}
205
}
206
207
208
long
209
MFXDecalsTable::onFocusRow(FXObject* sender, FXSelector, void*) {
210
int selectedRow = -1;
211
// search selected text field
212
for (int rowIndex = 0; rowIndex < (int)myRows.size(); rowIndex++) {
213
// iterate over every cell
214
for (const auto& cell : myRows.at(rowIndex)->getCells()) {
215
if ((cell->getTextField() == sender) || (cell->getButton() == sender)) {
216
selectedRow = rowIndex;
217
}
218
}
219
}
220
// update index label
221
updateIndexLabel();
222
// set new row
223
if (myCurrentSelectedRow != selectedRow) {
224
myCurrentSelectedRow = selectedRow;
225
updateIndexLabel();
226
}
227
return 0;
228
}
229
230
231
long
232
MFXDecalsTable::onCmdKeyPress(FXObject* sender, FXSelector sel, void* ptr) {
233
// get FXEvent
234
FXEvent* eventInfo = (FXEvent*)ptr;
235
// check code
236
if (eventInfo->code == 65362) {
237
// move up
238
if (myCurrentSelectedRow > 0) {
239
myCurrentSelectedRow -= 1;
240
} else {
241
// we're in the first, then select last
242
myCurrentSelectedRow = ((int)myRows.size() - 1);
243
}
244
// update index label
245
updateIndexLabel();
246
// move focus
247
moveFocus();
248
return 1;
249
} else if (eventInfo->code == 65364) {
250
// move down
251
if (myCurrentSelectedRow < ((int)myRows.size() - 1)) {
252
myCurrentSelectedRow += 1;
253
} else {
254
// we're in the last, then select first
255
myCurrentSelectedRow = 0;
256
}
257
// update index label
258
updateIndexLabel();
259
// move focus
260
moveFocus();
261
return 1;
262
} else {
263
// continue handling key pres
264
return sender->handle(sender, sel, ptr);
265
}
266
}
267
268
269
long
270
MFXDecalsTable::onCmdEditRowString(FXObject* sender, FXSelector, void*) {
271
// get decals
272
auto& decals = myDialogViewSettings->getSUMOAbstractView()->getDecals();
273
// get value
274
const std::string value = dynamic_cast<FXTextField*>(sender)->getText().text();
275
// set filename
276
for (int rowIndex = 0; rowIndex < (int)myRows.size(); rowIndex++) {
277
// continue depending of string
278
if (myRows.at(rowIndex)->getCells().at(2)->getTextField() == sender) {
279
decals.at(rowIndex).filename = value;
280
}
281
}
282
// update view
283
myDialogViewSettings->getSUMOAbstractView()->update();
284
return 1;
285
}
286
287
288
long
289
MFXDecalsTable::onCmdEditRowSpinner(FXObject* sender, FXSelector, void*) {
290
// get decals
291
auto& decals = myDialogViewSettings->getSUMOAbstractView()->getDecals();
292
// get value
293
const auto value = dynamic_cast<FXRealSpinner*>(sender)->getValue();
294
// set filename
295
for (int rowIndex = 0; rowIndex < (int)myRows.size(); rowIndex++) {
296
if (myRows.at(rowIndex)->getCells().at(3)->getSpinner() == sender) {
297
decals.at(rowIndex).centerX = value;
298
} else if (myRows.at(rowIndex)->getCells().at(4)->getSpinner() == sender) {
299
decals.at(rowIndex).centerY = value;
300
} else if (myRows.at(rowIndex)->getCells().at(5)->getSpinner() == sender) {
301
decals.at(rowIndex).width = value;
302
} else if (myRows.at(rowIndex)->getCells().at(6)->getSpinner() == sender) {
303
decals.at(rowIndex).height = value;
304
} else if (myRows.at(rowIndex)->getCells().at(7)->getSpinner() == sender) {
305
decals.at(rowIndex).rot = value;
306
} else if (myRows.at(rowIndex)->getCells().at(8)->getSpinner() == sender) {
307
decals.at(rowIndex).layer = value;
308
}
309
}
310
// update view
311
myDialogViewSettings->getSUMOAbstractView()->update();
312
return 1;
313
}
314
315
316
long
317
MFXDecalsTable::onCmdEditRowCheckBox(FXObject* sender, FXSelector, void*) {
318
// get decals
319
auto& decals = myDialogViewSettings->getSUMOAbstractView()->getDecals();
320
// get check buton
321
auto checkButton = dynamic_cast<FXCheckButton*>(sender);
322
// update text
323
checkButton->setText((checkButton->getCheck() == TRUE) ? "true" : "false");
324
// set filename
325
for (int rowIndex = 0; rowIndex < (int)myRows.size(); rowIndex++) {
326
if (myRows.at(rowIndex)->getCells().at(9)->getCheckButton() == sender) {
327
decals.at(rowIndex).screenRelative = (checkButton->getCheck() == TRUE) ? true : false;
328
}
329
}
330
// update view
331
myDialogViewSettings->getSUMOAbstractView()->update();
332
return 1;
333
}
334
335
336
long
337
MFXDecalsTable::onCmdOpenDecal(FXObject* sender, FXSelector, void*) {
338
// configure open dialog
339
FXFileDialog opendialog(this, TL("Open decal"));
340
// select existing file
341
opendialog.setSelectMode(SELECTFILE_EXISTING);
342
// set icon and pattern list
343
opendialog.setIcon(GUIIconSubSys::getIcon(GUIIcon::OPEN));
344
opendialog.setPatternList(SUMOXMLDefinitions::ImageFileExtensions.getMultilineString().c_str());
345
// set current folder
346
if (gCurrentFolder.length() != 0) {
347
opendialog.setDirectory(gCurrentFolder);
348
}
349
// open dialog
350
opendialog.execute();
351
// check if file exist
352
if (!opendialog.getFilename().empty()) {
353
// get decals
354
auto& decals = myDialogViewSettings->getSUMOAbstractView()->getDecals();
355
// set filename
356
for (int rowIndex = 0; rowIndex < (int)myRows.size(); rowIndex++) {
357
if (myRows.at(rowIndex)->getCells().at(1)->getButton() == sender) {
358
// set text in filename
359
myRows.at(rowIndex)->getCells().at(2)->getTextField()->setText(opendialog.getFilename());
360
// update filename in decal
361
decals.at(rowIndex).filename = opendialog.getFilename().text();
362
// update view
363
myDialogViewSettings->getSUMOAbstractView()->update();
364
return 1;
365
}
366
}
367
}
368
return 1;
369
}
370
371
372
long
373
MFXDecalsTable::onCmdAddRow(FXObject*, FXSelector, void*) {
374
// add a new decal
375
myDialogViewSettings->getSUMOAbstractView()->getDecals().push_back(GUISUMOAbstractView::Decal());
376
// refill table
377
fillTable();
378
return 1;
379
}
380
381
382
long
383
MFXDecalsTable::onUpdAddRow(FXObject* sender, FXSelector, void* ptr) {
384
if (myDialogViewSettings->getSUMOAbstractView()->getDecals().size() < MAXROWS) {
385
return sender->handle(this, FXSEL(SEL_COMMAND, ID_ENABLE), ptr);
386
} else {
387
return sender->handle(this, FXSEL(SEL_COMMAND, ID_DISABLE), ptr);
388
}
389
}
390
391
392
long
393
MFXDecalsTable::onCmdRemoveRow(FXObject* sender, FXSelector, void*) {
394
// get decals
395
auto& decals = myDialogViewSettings->getSUMOAbstractView()->getDecals();
396
// search row
397
for (int rowIndex = 0; rowIndex < (int)myRows.size(); rowIndex++) {
398
if (myRows.at(rowIndex)->getCells().back()->getButton() == sender) {
399
// remove row
400
decals.erase(decals.begin() + rowIndex);
401
// update view
402
myDialogViewSettings->getSUMOAbstractView()->update();
403
// refill table
404
fillTable();
405
return 1;
406
}
407
}
408
return 1;
409
}
410
411
412
void
413
MFXDecalsTable::updateIndexLabel() {
414
// update radio buttons checks
415
for (int rowIndex = 0; rowIndex < (int)myRows.size(); rowIndex++) {
416
// iterate over every cell
417
for (const auto& cell : myRows.at(rowIndex)->getCells()) {
418
if (cell->getIndexLabel()) {
419
if (myCurrentSelectedRow == rowIndex) {
420
cell->showIndexLabelBold();
421
} else {
422
cell->showIndexLabelNormal();
423
}
424
}
425
}
426
}
427
}
428
429
430
bool
431
MFXDecalsTable::moveFocus() {
432
// first find focus
433
// update radio buttons checks
434
for (int rowIndex = 0; rowIndex < (int)myRows.size(); rowIndex++) {
435
for (int cellIndex = 0; cellIndex < (int)myRows.at(rowIndex)->getCells().size(); cellIndex++) {
436
if (myRows.at(rowIndex)->getCells().at(cellIndex)->hasFocus()) {
437
// set focus in current row
438
myRows.at(myCurrentSelectedRow)->getCells().at(cellIndex)->setFocus();
439
return true;
440
}
441
}
442
}
443
return false;
444
}
445
446
// ---------------------------------------------------------------------------
447
// MFXDecalsTable::Cell - methods
448
// ---------------------------------------------------------------------------
449
450
MFXDecalsTable::Cell::Cell(MFXDecalsTable* decalsTable, FXTextField* textField, int col, int row) :
451
myDecalsTable(decalsTable),
452
myTextField(textField),
453
myCol(col),
454
myRow(row) {
455
}
456
457
458
MFXDecalsTable::Cell::Cell(MFXDecalsTable* decalsTable, FXLabel* indexLabel, FXLabel* indexLabelBold, int col, int row) :
459
myDecalsTable(decalsTable),
460
myIndexLabel(indexLabel),
461
myIndexLabelBold(indexLabelBold),
462
myCol(col),
463
myRow(row) {
464
// hide bold and set background
465
indexLabelBold->hide();
466
indexLabelBold->setBackColor(FXRGBA(210, 233, 255, 255));
467
}
468
469
470
MFXDecalsTable::Cell::Cell(MFXDecalsTable* decalsTable, FXButton* button, int col, int row) :
471
myDecalsTable(decalsTable),
472
myButton(button),
473
myCol(col),
474
myRow(row) {
475
}
476
477
478
MFXDecalsTable::Cell::Cell(MFXDecalsTable* decalsTable, FXCheckButton* checkButton, int col, int row) :
479
myDecalsTable(decalsTable),
480
myCheckButton(checkButton),
481
myCol(col),
482
myRow(row) {
483
}
484
485
486
MFXDecalsTable::Cell::Cell(MFXDecalsTable* decalsTable, FXRealSpinner* spinner, int col, int row) :
487
myDecalsTable(decalsTable),
488
mySpinner(spinner),
489
myCol(col),
490
myRow(row) {
491
}
492
493
494
MFXDecalsTable::Cell::~Cell() {
495
// delete all elements
496
if (myTextField) {
497
delete myTextField;
498
}
499
if (myIndexLabel) {
500
delete myIndexLabel;
501
}
502
if (myIndexLabelBold) {
503
delete myIndexLabelBold;
504
}
505
if (myButton) {
506
delete myButton;
507
}
508
if (myCheckButton) {
509
delete myCheckButton;
510
}
511
}
512
513
514
bool
515
MFXDecalsTable::Cell::hasFocus() const {
516
// check if one of the cell elements has the focus
517
if (myTextField && myTextField->hasFocus()) {
518
return true;
519
} else if (myButton && myButton->hasFocus()) {
520
return true;
521
} else if (myCheckButton && myCheckButton->hasFocus()) {
522
return true;
523
} else {
524
return false;
525
}
526
}
527
528
529
void
530
MFXDecalsTable::Cell::setFocus() {
531
// set focus
532
if (myTextField) {
533
myTextField->setFocus();
534
} else if (myButton) {
535
myButton->setFocus();
536
} else if (myCheckButton) {
537
myCheckButton->setFocus();
538
}
539
}
540
541
542
FXTextField*
543
MFXDecalsTable::Cell::getTextField() const {
544
return myTextField;
545
}
546
547
548
FXLabel*
549
MFXDecalsTable::Cell::getIndexLabel() const {
550
return myIndexLabel;
551
}
552
553
554
FXButton*
555
MFXDecalsTable::Cell::getButton() {
556
return myButton;
557
}
558
559
560
FXCheckButton*
561
MFXDecalsTable::Cell::getCheckButton() {
562
return myCheckButton;
563
}
564
565
566
FXRealSpinner*
567
MFXDecalsTable::Cell::getSpinner() {
568
return mySpinner;
569
}
570
571
572
void
573
MFXDecalsTable::Cell::showIndexLabelNormal() {
574
myIndexLabel->show();
575
myIndexLabelBold->hide();
576
// recalc both
577
myIndexLabel->recalc();
578
myIndexLabelBold->recalc();
579
}
580
581
582
void
583
MFXDecalsTable::Cell::showIndexLabelBold() {
584
myIndexLabel->hide();
585
myIndexLabelBold->show();
586
// recalc both
587
myIndexLabel->recalc();
588
myIndexLabelBold->recalc();
589
}
590
591
592
int
593
MFXDecalsTable::Cell::getCol() const {
594
return myCol;
595
}
596
597
598
int
599
MFXDecalsTable::Cell::getRow() const {
600
return myRow;
601
}
602
603
604
char
605
MFXDecalsTable::Cell::getType() const {
606
return myDecalsTable->myColumns.at(myCol)->getType();
607
}
608
609
610
MFXDecalsTable::Cell::Cell() :
611
myCol(-1),
612
myRow(-1) {
613
}
614
615
// ---------------------------------------------------------------------------
616
// MFXDecalsTable::Column - methods
617
// ---------------------------------------------------------------------------
618
619
MFXDecalsTable::Column::Column(MFXDecalsTable* table, const int index, const char type) :
620
myTable(table),
621
myIndex(index),
622
myType(type) {
623
// get static tooltip
624
auto staticTooltip = table->myDialogViewSettings->getSUMOAbstractView()->getGUIGlChildWindow()->getGUIMainWindowParent()->getStaticTooltipMenu();
625
// create vertical frame
626
if (myType == 'f') {
627
myVerticalFrame = new FXVerticalFrame(table->myColumnsFrame, GUIDesignAuxiliarFrame);
628
} else {
629
myVerticalFrame = new FXVerticalFrame(table->myColumnsFrame, GUIDesignAuxiliarFrameFixedWidth(100));
630
}
631
// create top label
632
switch (myType) {
633
case ('f'): {
634
// ticked label extended
635
myTopLabel = new MFXLabelTooltip(myVerticalFrame, staticTooltip, "", nullptr, GUIDesignLabelThick(JUSTIFY_NORMAL));
636
break;
637
}
638
case ('p'):
639
case ('s'): {
640
// ticked label fixed
641
myTopLabel = new MFXLabelTooltip(myVerticalFrame, staticTooltip, "", nullptr, GUIDesignLabelThickedFixed(0));
642
break;
643
}
644
case ('c'): {
645
// ticked label for checkbox
646
myTopLabel = new MFXLabelTooltip(myVerticalFrame, staticTooltip, "", nullptr, GUIDesignLabelThickedFixed(30));
647
break;
648
}
649
case ('i'): {
650
// ticked label for index
651
myTopLabel = new MFXLabelTooltip(myVerticalFrame, staticTooltip, "", nullptr, GUIDesignLabelFixed(30));
652
break;
653
}
654
default: {
655
// empty label (for buttons)
656
myTopLabel = new MFXLabelTooltip(myVerticalFrame, staticTooltip, "", nullptr, GUIDesignLabelFixed(0));
657
break;
658
}
659
}
660
// create vertical frame for cells
661
if (myType == 'f') {
662
myVerticalCellFrame = new FXVerticalFrame(myVerticalFrame, GUIDesignAuxiliarFrame);
663
} else {
664
myVerticalCellFrame = new FXVerticalFrame(myVerticalFrame, GUIDesignAuxiliarFrameFixedWidth(100));
665
}
666
// create elements
667
myVerticalFrame->create();
668
myTopLabel->create();
669
myVerticalCellFrame->create();
670
// adjust column width
671
adjustColumnWidth();
672
}
673
674
675
MFXDecalsTable::Column::~Column() {
676
// delete vertical frame (this also delete all childrens)
677
delete myVerticalFrame;
678
}
679
680
681
FXVerticalFrame*
682
MFXDecalsTable::Column::getVerticalCellFrame() const {
683
return myVerticalCellFrame;
684
}
685
686
687
char
688
MFXDecalsTable::Column::getType() const {
689
return myType;
690
}
691
692
693
FXString
694
MFXDecalsTable::Column::getColumnLabel() const {
695
return myTopLabel->getText();
696
}
697
698
699
void
700
MFXDecalsTable::Column::setColumnLabel(const std::string& text, const std::string& tooltip) {
701
myTopLabel->setText(text.c_str());
702
myTopLabel->setTipText(tooltip.c_str());
703
// adjust column width
704
adjustColumnWidth();
705
}
706
707
708
void
709
MFXDecalsTable::Column::adjustColumnWidth() {
710
// filename always extended
711
if (myType != 'f') {
712
// declare columnWidth
713
int columnWidth = GUIDesignHeight;
714
// adjust depending of label
715
if ((myType == 's') || (myType == 'p') || (myType == 'c')) {
716
// calculate top label width
717
columnWidth = myTopLabel->getFont()->getTextWidth(myTopLabel->getText().text(), myTopLabel->getText().length() + EXTRAMARGIN);
718
}
719
// adjust width in all rows
720
for (const auto& row : myTable->myRows) {
721
if (row->getCells().at(myIndex)->getTextField()) {
722
row->getCells().at(myIndex)->getTextField()->setWidth(columnWidth);
723
} else if (row->getCells().at(myIndex)->getButton()) {
724
row->getCells().at(myIndex)->getButton()->setWidth(columnWidth);
725
} else if (row->getCells().at(myIndex)->getSpinner()) {
726
row->getCells().at(myIndex)->getSpinner()->setWidth(columnWidth);
727
}
728
}
729
// adjust labels and vertical frames
730
myVerticalFrame->setWidth(columnWidth);
731
myTopLabel->setWidth(columnWidth);
732
myVerticalCellFrame->setWidth(columnWidth);
733
}
734
}
735
736
737
MFXDecalsTable::Column::Column() :
738
myIndex(0),
739
myType('-') {}
740
741
// ---------------------------------------------------------------------------
742
// MFXDecalsTable::Row - methods
743
// ---------------------------------------------------------------------------
744
745
MFXDecalsTable::Row::Row(MFXDecalsTable* table) :
746
myTable(table) {
747
// build textFields
748
for (int columnIndex = 0; columnIndex < (FXint)table->myColumns.size(); columnIndex++) {
749
// get number of cells
750
const int numCells = (int)myCells.size();
751
// continue depending of type
752
switch (table->myColumns.at(columnIndex)->getType()) {
753
case ('f'): {
754
// create textField for filenames
755
auto textField = new FXTextField(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
756
GUIDesignTextFieldNCol, table, MID_DECALSTABLE_TEXTFIELD, GUIDesignTextField);
757
myCells.push_back(new Cell(table, textField, columnIndex, numCells));
758
break;
759
}
760
case ('s'): {
761
// create textField for textfiedl real values
762
auto textField = new FXTextField(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
763
GUIDesignTextFieldNCol, table, MID_DECALSTABLE_TEXTFIELD, GUIDesignTextFieldFixedRestricted(0, TEXTFIELD_REAL));
764
myCells.push_back(new Cell(table, textField, columnIndex, numCells));
765
break;
766
}
767
case ('p'): {
768
// create spinner for real values
769
auto spinner = new FXRealSpinner(table->myColumns.at(columnIndex)->getVerticalCellFrame(), GUIDesignTextFieldNCol,
770
table, MID_DECALSTABLE_SPINNER, GUIDesignSpinDialDecalsTable);
771
myCells.push_back(new Cell(table, spinner, columnIndex, numCells));
772
break;
773
}
774
case ('i'): {
775
// create labels for index
776
auto indexLabel = new FXLabel(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
777
toString(myTable->myRows.size()).c_str(), nullptr, GUIDesignLabelThickedFixed(30));
778
auto indexLabelBold = new FXLabel(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
779
toString(myTable->myRows.size()).c_str(), nullptr, GUIDesignLabelThickedFixed(30));
780
// set fonts
781
indexLabel->setFont(myTable->myIndexFont);
782
indexLabelBold->setFont(myTable->myIndexSelectedFont);
783
myCells.push_back(new Cell(table, indexLabel, indexLabelBold, columnIndex, numCells));
784
break;
785
}
786
case ('c'): {
787
// create checkbox for
788
auto checkableButton = new FXCheckButton(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
789
"false", table, MID_DECALSTABLE_CHECKBOX, GUIDesignMFXCheckableButton);
790
myCells.push_back(new Cell(table, checkableButton, columnIndex, numCells));
791
break;
792
}
793
case ('b'): {
794
// create button for open decal
795
auto button = GUIDesigns::buildFXButton(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
796
"", TL("Open decal"), TL("Open decal."),
797
GUIIconSubSys::getIcon(GUIIcon::OPEN), table, MID_DECALSTABLE_OPEN, GUIDesignButtonIcon);
798
myCells.push_back(new Cell(table, button, columnIndex, numCells));
799
break;
800
}
801
case ('d'): {
802
// create button for delete decal
803
auto button = GUIDesigns::buildFXButton(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
804
"", TL("Remove decal"), TL("Remove decal."),
805
GUIIconSubSys::getIcon(GUIIcon::REMOVE), table, MID_DECALSTABLE_REMOVE, GUIDesignButtonIcon);
806
myCells.push_back(new Cell(table, button, columnIndex, numCells));
807
break;
808
}
809
default:
810
throw ProcessError("Invalid Cell type");
811
}
812
}
813
}
814
815
816
MFXDecalsTable::Row::~Row() {
817
// delete all cells
818
for (const auto& cell : myCells) {
819
delete cell;
820
}
821
}
822
823
824
std::string
825
MFXDecalsTable::Row::getText(int index) const {
826
if (myCells.at(index)->getTextField()) {
827
return myCells.at(index)->getTextField()->getText().text();
828
} else {
829
throw ProcessError("Cell doesn't have a textField");
830
}
831
}
832
833
834
void
835
MFXDecalsTable::Row::setText(int index, const std::string& text) const {
836
// set text
837
myCells.at(index)->getTextField()->setText(text.c_str());
838
}
839
840
841
const std::vector<MFXDecalsTable::Cell*>&
842
MFXDecalsTable::Row::getCells() const {
843
return myCells;
844
}
845
846
847
MFXDecalsTable::Row::Row() {}
848
849
/****************************************************************************/
850
851