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