Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNETLSTable.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2024 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/****************************************************************************/
18// Table used in GNETLSFrame for editing TLS programs
19/****************************************************************************/
20#include <config.h>
21
22#include "GNETLSTable.h"
23
24#include <netedit/GNEViewNet.h>
33
34
35#define EXTRAMARGIN 1
36#define DEFAULTWIDTH 190
37
38// ===========================================================================
39// FOX callback mapping
40// ===========================================================================
41
42FXDEFMAP(GNETLSTable) GNETLSTableMap[] = {
45 // text fields
49 // add phase buttons
56 // remove phase button
59 // move up phase button
62 // move down phase button
65};
66
67// Object implementation
68FXIMPLEMENT(GNETLSTable, FXHorizontalFrame, GNETLSTableMap, ARRAYNUMBER(GNETLSTableMap))
69
70// ===========================================================================
71// method definitions
72// ===========================================================================
73
74// ---------------------------------------------------------------------------
75// GNETLSTable - public methods
76// ---------------------------------------------------------------------------
77
78GNETLSTable::GNETLSTable(GNETLSEditorFrame::TLSPhases* TLSPhasesParent) :
79 FXHorizontalFrame(TLSPhasesParent->getCollapsableFrame(), GUIDesignAuxiliarFrameFixWidth),
80 myProgramFont(new FXFont(getApp(), "Courier New", 10)),
81 myIndexFont(new FXFont(getApp(), "Segoe UI", 9)),
82 myIndexSelectedFont(new FXFont(getApp(), "Segoe UI", 9, FXFont::Bold)),
83 myTLSPhasesParent(TLSPhasesParent) {
84 // set default width
85 recalcTableWidth();
86}
87
88
90 // delete fonts
91 delete myProgramFont;
92 delete myIndexFont;
94}
95
96
97void
99 // enable all cells
100 for (const auto& row : myRows) {
101 for (const auto& cell : row->getCells()) {
102 cell->enable();
103 }
104 }
105 // enable horizontal frame
106 FXHorizontalFrame::enable();
107}
108
109
110void
112 // disable all cells
113 for (const auto& row : myRows) {
114 for (const auto& cell : row->getCells()) {
115 cell->disable();
116 }
117 }
118 // disable horizontal frame
119 FXHorizontalFrame::disable();
120}
121
122
127
128
129void
131 // get minimum width of all elements
132 int minimumTableWidth = 0;
133 // get pointer to name column
134 Column* nameColumn = nullptr;
135 // iterate over all columns
136 for (const auto& column : myColumns) {
137 // check if this is the name column
138 if (column->getType() == 'm') {
139 // save column
140 nameColumn = column;
141 } else {
142 // get minimum column width
143 const auto minimunColWidth = column->getColumnMinimumWidth();
144 // set columnwidth
145 column->setColumnWidth(minimunColWidth);
146 // update minimum table width
147 minimumTableWidth += minimunColWidth;
148 }
149 }
150 // adjust name column
151 if (nameColumn) {
152 // get column name width
153 const int minimumColNameWidth = nameColumn->getColumnMinimumWidth();
154 // get scrollBar width
155 const int scrollBarWidth = myTLSPhasesParent->getTLSEditorParent()->getScrollBarWidth();
156 // get frame area width - padding (30, constant, 15 left, 15 right)
157 const auto frameAreaWidth = myTLSPhasesParent->getTLSEditorParent()->getViewNet()->getViewParent()->getFrameAreaWidth() - 30;
158 // continue depending of minimum table width
159 if ((frameAreaWidth - (minimumTableWidth + minimumColNameWidth + scrollBarWidth)) > 0) {
160 nameColumn->setColumnWidth(frameAreaWidth - minimumTableWidth - scrollBarWidth);
161 setWidth(frameAreaWidth);
162 } else {
163 nameColumn->setColumnWidth(minimumColNameWidth);
164 setWidth(minimumTableWidth + minimumColNameWidth);
165 }
166 } else if (minimumTableWidth > 0) {
167 setWidth(minimumTableWidth);
168 } else {
169 setWidth(DEFAULTWIDTH);
170 }
171}
172
173
174void
176 // clear rows (always before columns, because delete row delete also all cells)
177 for (const auto& row : myRows) {
178 delete row;
179 }
180 // clear columns
181 for (const auto& column : myColumns) {
182 delete column;
183 }
184 // drop rows and columns
185 myRows.clear();
186 myColumns.clear();
187}
188
189
190void
191GNETLSTable::setTableSize(const std::string& columnsType, const int numberRow) {
192 // first clear table
193 clearTable();
194 // create columns
195 for (int i = 0; i < (FXint)columnsType.size(); i++) {
196 myColumns.push_back(new Column(this, i, columnsType.at(i)));
197 }
198 // create rows
199 for (int i = 0; i < numberRow; i++) {
200 myRows.push_back(new Row(this));
201 }
202 // if we have only a row, disable remove and move buttons
203 if (myRows.size() == 1) {
204 myRows.front()->disableButtons();
205 }
206}
207
208
209void
210GNETLSTable::setItemText(FXint row, FXint column, const std::string& text) {
211 if ((row >= 0) && (row < (FXint)myRows.size()) &&
212 (column >= 0) && (column < (FXint)myColumns.size())) {
213 myRows.at(row)->setText(column, text);
214 // check if update accumulated duration
215 if (myColumns.at(column)->getType() == 'u') {
217 }
218 } else {
219 throw ProcessError(TL("Invalid row or column"));
220 }
221}
222
223
224std::string
225GNETLSTable::getItemText(const int row, const int column) const {
226 if ((row >= 0) && (row < (FXint)myRows.size()) &&
227 (column >= 0) && (column < (FXint)myColumns.size())) {
228 return myRows.at(row)->getText(column);
229 }
230 throw ProcessError(TL("Invalid row or column"));
231}
232
233
234int
236 return (int)myRows.size();
237}
238
239
240int
244
245
246void
248 if ((row >= 0) && (row < (FXint)myRows.size())) {
249 // update current selected row
251 // update index label
253 } else {
254 throw ProcessError(TL("Invalid row"));
255 }
256}
257
258
259void
260GNETLSTable::setColumnLabelTop(const int column, const std::string& text, const std::string& tooltip) {
261 if ((column >= 0) && (column < (int)myColumns.size())) {
262 myColumns.at(column)->setColumnLabelTop(text, tooltip);
263 } else {
264 throw ProcessError(TL("Invalid column"));
265 }
266}
267
268
269void
270GNETLSTable::setColumnLabelBot(const int column, const std::string& text) {
271 if ((column >= 0) && (column < (int)myColumns.size())) {
272 myColumns.at(column)->setColumnLabelBot(text);
273 } else {
274 throw ProcessError(TL("Invalid column"));
275 }
276}
277
278
279long
280GNETLSTable::onFocusRow(FXObject* sender, FXSelector, void*) {
281 int selectedRow = -1;
282 // search selected text field
283 for (int rowIndex = 0; rowIndex < (int)myRows.size(); rowIndex++) {
284 // iterate over every cell
285 for (const auto& cell : myRows.at(rowIndex)->getCells()) {
286 if ((cell->getTextField() == sender) || (cell->getAddButton() == sender)) {
287 selectedRow = rowIndex;
288 }
289 }
290 }
291 // update index label
293 // set new row
294 if (myCurrentSelectedRow != selectedRow) {
295 myCurrentSelectedRow = selectedRow;
297 }
298 return 0;
299}
300
301
302long
303GNETLSTable::onCmdAddPhasePressed(FXObject* sender, FXSelector, void*) {
304 // search selected add button
305 for (int columnIndex = 0; columnIndex < (int)myColumns.size(); columnIndex++) {
306 for (int rowIndex = 0; rowIndex < (int)myRows.size(); rowIndex++) {
307 if (myRows.at(rowIndex)->getCells().at(columnIndex)->getAddButton() == sender) {
308 myRows.at(rowIndex)->getCells().at(columnIndex)->getAddPhaseButton()->setFocus();
309 return 1;
310 }
311 }
312 }
313 // nothing to focus
314 return 0;
315}
316
317
318long
319GNETLSTable::onCmdEditRow(FXObject* sender, FXSelector, void*) {
320 // search selected text field
321 for (int columnIndex = 0; columnIndex < (int)myColumns.size(); columnIndex++) {
322 for (int rowIndex = 0; rowIndex < (int)myRows.size(); rowIndex++) {
323 // get text field
324 const auto textField = myRows.at(rowIndex)->getCells().at(columnIndex)->getTextField();
325 if (textField == sender) {
326 // edit value and change value depending of result
327 if (myTLSPhasesParent->changePhaseValue(columnIndex, rowIndex, textField->getText().text())) {
328 WRITE_DEBUG(("Valid " + myColumns.at(columnIndex)->getColumnLabelTop()).text());
329 textField->setTextColor(FXRGB(0, 0, 0));
330 textField->killFocus();
332 } else {
333 WRITE_DEBUG(("Invalid " + myColumns.at(columnIndex)->getColumnLabelTop()).text());
334 textField->setTextColor(FXRGB(255, 0, 0));
335 }
336 return 1;
337 }
338 }
339 }
340 // nothing to edit
341 return 0;
342}
343
344
345long
346GNETLSTable::onCmdKeyPress(FXObject* sender, FXSelector sel, void* ptr) {
347 // get FXEvent
348 FXEvent* eventInfo = (FXEvent*)ptr;
349 // check code
350 if (eventInfo->code == 65362) {
351 // move up
352 if (myCurrentSelectedRow > 0) {
354 } else {
355 // we're in the first, then select last
356 myCurrentSelectedRow = ((int)myRows.size() - 1);
357 }
358 // update index label
360 // move focus
361 moveFocus();
362 return 1;
363 } else if (eventInfo->code == 65364) {
364 // move down
365 if (myCurrentSelectedRow < ((int)myRows.size() - 1)) {
367 } else {
368 // we're in the last, then select first
370 }
371 // update index label
373 // move focus
374 moveFocus();
375 return 1;
376 } else {
377 // continue handling key pres
378 return sender->handle(sender, sel, ptr);
379 }
380}
381
382
383long
384GNETLSTable::onCmdAddPhase(FXObject* sender, FXSelector, void*) {
385 WRITE_DEBUG("Add default phase");
386 // search selected text field
387 for (int indexRow = 0; indexRow < (int)myRows.size(); indexRow++) {
388 // iterate over every cell
389 for (const auto& cell : myRows.at(indexRow)->getCells()) {
390 if (cell->getAddPhaseButton() == sender) {
391 // hide popup
392 cell->hideMenuButtonPopup();
393 // add row
394 myTLSPhasesParent->addPhase(indexRow);
395 // stop
396 return 0;
397 }
398 }
399 }
400 return 0;
401}
402
403
404long
405GNETLSTable::onCmdDuplicatePhase(FXObject* sender, FXSelector, void*) {
406 WRITE_DEBUG("Duplicate phase");
407 // search selected text field
408 for (int indexRow = 0; indexRow < (int)myRows.size(); indexRow++) {
409 // iterate over every cell
410 for (const auto& cell : myRows.at(indexRow)->getCells()) {
411 if (cell->getDuplicatePhaseButton() == sender) {
412 // hide popup
413 cell->hideMenuButtonPopup();
414 // duplicate row
416 // stop
417 return 0;
418 }
419 }
420 }
421 return 0;
422}
423
424
425long
426GNETLSTable::onCmdAddPhaseAllRed(FXObject* sender, FXSelector, void*) {
427 WRITE_DEBUG("Add red phase");
428 // search selected text field
429 for (int indexRow = 0; indexRow < (int)myRows.size(); indexRow++) {
430 // iterate over every cell
431 for (const auto& cell : myRows.at(indexRow)->getCells()) {
432 if (cell->getAddAllRedPhaseButton() == sender) {
433 // hide popup
434 cell->hideMenuButtonPopup();
435 // add row
436 myTLSPhasesParent->addPhase(indexRow, 'r');
437 // stop
438 return 0;
439 }
440 }
441 }
442 return 0;
443}
444
445
446long
447GNETLSTable::onCmdAddPhaseAllYellow(FXObject* sender, FXSelector, void*) {
448 WRITE_DEBUG("Add yellow phase");
449 // search selected text field
450 for (int indexRow = 0; indexRow < (int)myRows.size(); indexRow++) {
451 // iterate over every cell
452 for (const auto& cell : myRows.at(indexRow)->getCells()) {
453 if (cell->getAddAllYellowPhaseButton() == sender) {
454 // hide popup
455 cell->hideMenuButtonPopup();
456 // add row
457 myTLSPhasesParent->addPhase(indexRow, 'y');
458 // stop
459 return 0;
460 }
461 }
462 }
463 return 0;
464}
465
466
467long
468GNETLSTable::onCmdAddPhaseAllGreen(FXObject* sender, FXSelector, void*) {
469 WRITE_DEBUG("Add green phase");
470 // search selected text field
471 for (int indexRow = 0; indexRow < (int)myRows.size(); indexRow++) {
472 // iterate over every cell
473 for (const auto& cell : myRows.at(indexRow)->getCells()) {
474 if (cell->getAddAllGreenPhaseButton() == sender) {
475 // hide popup
476 cell->hideMenuButtonPopup();
477 // add row
478 myTLSPhasesParent->addPhase(indexRow, 'g');
479 // stop
480 return 0;
481 }
482 }
483 }
484 return 0;
485}
486
487
488long
489GNETLSTable::onCmdAddPhaseAllGreenPriority(FXObject* sender, FXSelector, void*) {
490 WRITE_DEBUG("Add green priority phase");
491 // search selected text field
492 for (int indexRow = 0; indexRow < (int)myRows.size(); indexRow++) {
493 // iterate over every cell
494 for (const auto& cell : myRows.at(indexRow)->getCells()) {
495 if (cell->getAddAllGreenPriorityPhaseButton() == sender) {
496 // hide popup
497 cell->hideMenuButtonPopup();
498 // add row
499 myTLSPhasesParent->addPhase(indexRow, 'G');
500 // stop
501 return 0;
502 }
503 }
504 }
505 return 0;
506}
507
508
509long
510GNETLSTable::onCmdRemovePhase(FXObject* sender, FXSelector, void*) {
511 WRITE_DEBUG("Remove phase");
512 // search selected text field
513 for (int indexRow = 0; indexRow < (int)myRows.size(); indexRow++) {
514 // iterate over every cell
515 for (const auto& cell : myRows.at(indexRow)->getCells()) {
516 if (cell->getButton() == sender) {
517 // remove row
519 // stop
520 return 0;
521 }
522 }
523 }
524 return 0;
525}
526
527
528long
529GNETLSTable::onCmdMoveUpPhase(FXObject* sender, FXSelector, void*) {
530 WRITE_DEBUG("Move phase up");
531 // search selected text field
532 for (int indexRow = 0; indexRow < (int)myRows.size(); indexRow++) {
533 // iterate over every cell
534 for (const auto& cell : myRows.at(indexRow)->getCells()) {
535 if (cell->getButton() == sender) {
536 // move phase up
538 // stop
539 return 0;
540 }
541 }
542 }
543 return 0;
544}
545
546
547long
548GNETLSTable::onCmdMoveDownPhase(FXObject* sender, FXSelector, void*) {
549 WRITE_DEBUG("Move phase down");
550 // search selected text field
551 for (int indexRow = 0; indexRow < (int)myRows.size(); indexRow++) {
552 // iterate over every cell
553 for (const auto& cell : myRows.at(indexRow)->getCells()) {
554 if (cell->getButton() == sender) {
555 // move phase down
557 // stop
558 return 0;
559 }
560 }
561 }
562 return 0;
563}
564
565
566void
568 // update radio buttons checks
569 for (int rowIndex = 0; rowIndex < (int)myRows.size(); rowIndex++) {
570 // iterate over every cell
571 for (const auto& cell : myRows.at(rowIndex)->getCells()) {
572 if (cell->getIndexLabel()) {
573 if (myCurrentSelectedRow == rowIndex) {
574 cell->showIndexLabelBold();
575 } else {
576 cell->showIndexLabelNormal();
577 }
578 }
579 }
580 }
581 // update coloring
583}
584
585
586void
588 // first find the duration col
589 int durationCol = -1;
590 for (int i = 0; i < (int)myColumns.size(); i++) {
591 if (myColumns.at(i)->getType() == 'u') {
592 durationCol = i;
593 }
594 }
595 // continue depending of durationCol
596 if (durationCol != -1) {
597 // declare a int vector for saving durations
598 std::vector<double> durations;
599 // fill durations
600 for (const auto& row : myRows) {
601 durations.push_back(row->getCells().at(durationCol)->getDoubleValue());
602 }
603 // update durations
604 for (int i = 1; i < (int)durations.size(); i++) {
605 durations.at(i) += durations.at(i - 1);
606 }
607 // set tooltips in row cells
608 for (int i = 0; i < (int)myRows.size(); i++) {
609 myRows.at(i)->getCells().at(durationCol)->setTooltip(TL("Accumulated: ") + toString(durations.at(i)));
610 }
611 }
612}
613
614
615bool
617 // first find focus
618 // update radio buttons checks
619 for (int rowIndex = 0; rowIndex < (int)myRows.size(); rowIndex++) {
620 for (int cellIndex = 0; cellIndex < (int)myRows.at(rowIndex)->getCells().size(); cellIndex++) {
621 if (myRows.at(rowIndex)->getCells().at(cellIndex)->hasFocus()) {
622 // set focus in current row
623 myRows.at(myCurrentSelectedRow)->getCells().at(cellIndex)->setFocus();
624 return true;
625 }
626 }
627 }
628 return false;
629}
630
631// ---------------------------------------------------------------------------
632// GNETLSTable::Cell - methods
633// ---------------------------------------------------------------------------
634
635GNETLSTable::Cell::Cell(GNETLSTable* TLSTable, MFXTextFieldTooltip* textField, int col, int row) :
636 myTLSTable(TLSTable),
637 myTextField(textField),
638 myCol(col),
639 myRow(row) {
640 // create
641 textField->create();
642}
643
644
645GNETLSTable::Cell::Cell(GNETLSTable* TLSTable, FXLabel* indexLabel, FXLabel* indexLabelBold, int col, int row) :
646 myTLSTable(TLSTable),
647 myIndexLabel(indexLabel),
648 myIndexLabelBold(indexLabelBold),
649 myCol(col),
650 myRow(row) {
651 // create both
652 indexLabel->create();
653 indexLabelBold->create();
654 // hide bold and set background
655 indexLabelBold->hide();
656 indexLabelBold->setBackColor(FXRGBA(210, 233, 255, 255));
657}
658
659
660GNETLSTable::Cell::Cell(GNETLSTable* TLSTable, MFXButtonTooltip* button, int col, int row) :
661 myTLSTable(TLSTable),
662 myButton(button),
663 myCol(col),
664 myRow(row) {
665 // create
666 button->create();
667}
668
669
670GNETLSTable::Cell::Cell(GNETLSTable* TLSTable, int col, int row) :
671 myTLSTable(TLSTable),
672 myCol(col),
673 myRow(row) {
674 // build locator popup
675 myMenuButtonPopup = new FXPopup(TLSTable->myColumns.at(col)->getVerticalCellFrame(), POPUP_HORIZONTAL);
676 // build menu button
677 myAddButton = new MFXMenuButtonTooltip(TLSTable->myColumns.at(col)->getVerticalCellFrame(),
679 (std::string("\t") + TL("Add phase") + std::string("\t") + TL("Add new phase.")).c_str(),
681 // default phase
684 (std::string("\t") + TL("Default phase") + std::string("\t") + TL("Add default phase.")).c_str(),
686 // duplicate phase
689 (std::string("\t") + TL("Duplicate phase") + std::string("\t") + TL("Duplicate this phase.")).c_str(),
691 // red phase
694 (std::string("\t") + TL("Red phase") + std::string("\t") + TL("Add red phase.")).c_str(),
696 // yellow phase
699 (std::string("\t") + TL("Yellow phase") + std::string("\t") + TL("Add yellow phase.")).c_str(),
701 // green phase
704 (std::string("\t") + TL("Green phase") + std::string("\t") + TL("Add green phase.")).c_str(),
706 // green priority phase
709 (std::string("\t") + TL("Green priority phase") + std::string("\t") + TL("Add green priority phase.")).c_str(),
711 // create elements
712 myMenuButtonPopup->create();
713 myAddButton->create();
714 myAddPhaseButton->create();
715 myDuplicatePhaseButton->create();
716 myAddAllRedButton->create();
717 myAddAllYellowButton->create();
718 myAddAllGreenButton->create();
720 // set backgrounds
721 myAddPhaseButton->setBackColor(FXRGBA(210, 233, 255, 255));
722 myDuplicatePhaseButton->setBackColor(FXRGBA(210, 233, 255, 255));
723 myAddAllRedButton->setBackColor(FXRGBA(255, 213, 213, 255));
724 myAddAllYellowButton->setBackColor(FXRGBA(253, 255, 206, 255));
725 myAddAllGreenButton->setBackColor(FXRGBA(240, 255, 205, 255));
726 myAddAllGreenPriorityButton->setBackColor(FXRGBA(240, 255, 205, 255));
727}
728
730 // delete all elements
731 if (myTextField) {
732 delete myTextField;
733 }
734 if (myIndexLabel) {
735 delete myIndexLabel;
736 }
737 if (myIndexLabelBold) {
738 delete myIndexLabelBold;
739 }
740 if (myButton) {
741 delete myButton;
742 }
743 if (myAddButton) {
744 delete myAddButton;
745 }
746 if (myAddPhaseButton) {
747 delete myAddPhaseButton;
748 }
749 if (myDuplicatePhaseButton) {
750 delete myDuplicatePhaseButton;
751 }
752 if (myAddAllRedButton) {
753 delete myAddAllRedButton;
754 }
755 if (myAddAllYellowButton) {
756 delete myAddAllYellowButton;
757 }
758 if (myAddAllGreenButton) {
759 delete myAddAllGreenButton;
760 }
761 if (myAddAllGreenPriorityButton) {
762 delete myAddAllGreenPriorityButton;
763 }
764 if (myMenuButtonPopup) {
765 delete myMenuButtonPopup;
766 }
767}
768
769void
771 // enable all elements
772 if (myTextField) {
773 myTextField->enable();
774 }
775 if (myIndexLabel) {
776 myIndexLabel->enable();
777 }
778 if (myIndexLabelBold) {
779 myIndexLabelBold->enable();
780 }
781 if (myButton && !myDisableButton) {
782 myButton->enable();
783 }
784 if (myAddButton) {
785 myAddButton->enable();
786 }
787 if (myAddPhaseButton) {
788 myAddPhaseButton->enable();
789 }
790 if (myDuplicatePhaseButton) {
791 myDuplicatePhaseButton->enable();
792 }
793 if (myAddAllRedButton) {
794 myAddAllRedButton->enable();
795 }
796 if (myAddAllYellowButton) {
797 myAddAllYellowButton->enable();
798 }
799 if (myAddAllGreenButton) {
800 myAddAllGreenButton->enable();
801 }
802 if (myAddAllGreenPriorityButton) {
803 myAddAllGreenPriorityButton->enable();
804 }
805 if (myMenuButtonPopup) {
806 myMenuButtonPopup->enable();
807 }
808}
809
810
811void
813 // disable all elements
814 if (myTextField) {
815 myTextField->disable();
816 }
817 if (myIndexLabel) {
818 myIndexLabel->disable();
819 }
820 if (myIndexLabelBold) {
821 myIndexLabelBold->disable();
822 }
823 if (myButton && !myDisableButton) {
824 myButton->disable();
825 }
826 if (myAddButton) {
827 myAddButton->disable();
828 }
829 if (myAddPhaseButton) {
830 myAddPhaseButton->disable();
831 }
832 if (myDuplicatePhaseButton) {
833 myDuplicatePhaseButton->disable();
834 }
835 if (myAddAllRedButton) {
836 myAddAllRedButton->disable();
837 }
838 if (myAddAllYellowButton) {
839 myAddAllYellowButton->disable();
840 }
841 if (myAddAllGreenButton) {
842 myAddAllGreenButton->disable();
843 }
844 if (myAddAllGreenPriorityButton) {
845 myAddAllGreenPriorityButton->disable();
846 }
847 if (myMenuButtonPopup) {
848 myMenuButtonPopup->disable();
849 }
850}
851
852
853bool
855 // check if one of the cell elements has the focus
856 if (myTextField && myTextField->hasFocus()) {
857 return true;
858 } else if (myButton && myButton->hasFocus()) {
859 return true;
860 } else if (myAddButton && myAddButton->hasFocus()) {
861 return true;
862 } else if (myAddPhaseButton && myAddPhaseButton->hasFocus()) {
863 return true;
864 } else if (myDuplicatePhaseButton && myDuplicatePhaseButton->hasFocus()) {
865 return true;
866 } else if (myAddAllRedButton && myAddAllRedButton->hasFocus()) {
867 return true;
868 } else if (myAddAllYellowButton && myAddAllYellowButton->hasFocus()) {
869 return true;
870 } else if (myAddAllGreenButton && myAddAllGreenButton->hasFocus()) {
871 return true;
872 } else if (myAddAllGreenPriorityButton && myAddAllGreenPriorityButton->hasFocus()) {
873 return true;
874 } else {
875 return false;
876 }
877}
878
879
880void
882 // set focus
883 if (myTextField) {
884 myTextField->setFocus();
885 } else if (myButton) {
886 myButton->setFocus();
887 } else if (myAddButton) {
888 myAddButton->setFocus();
889 } else if (myAddPhaseButton) {
890 myAddPhaseButton->setFocus();
891 } else if (myDuplicatePhaseButton) {
892 myDuplicatePhaseButton->setFocus();
893 } else if (myAddAllRedButton) {
894 myAddAllRedButton->setFocus();
895 } else if (myAddAllYellowButton) {
896 myAddAllYellowButton->setFocus();
897 } else if (myAddAllGreenButton) {
898 myAddAllGreenButton->setFocus();
899 } else if (myAddAllGreenPriorityButton) {
900 myAddAllGreenPriorityButton->setFocus();
901 }
902}
903
904
905double
907 if (myTextField->getText().empty()) {
908 return 0;
909 } else if (!GNEAttributeCarrier::canParse<double>(myTextField->getText().text())) {
910 throw ProcessError(TL("Cannot be parsed to double"));
911 } else {
912 return GNEAttributeCarrier::parse<double>(myTextField->getText().text());
913 }
914}
915
916
917void
918GNETLSTable::Cell::setTooltip(const std::string& toolTip) {
919 if (myTextField) {
920 myTextField->setToolTipText(toolTip.c_str());
921 } else {
922 throw ProcessError(TL("Tooltips only for TextFields"));
923 }
924}
925
926
929 return myTextField;
930}
931
932
933FXLabel*
935 return myIndexLabel;
936}
937
938
941 return myAddButton;
942}
943
944
947 return myButton;
948}
949
950
953 return myAddPhaseButton;
954}
955
956
959 return myDuplicatePhaseButton;
960}
961
962
965 return myAddAllRedButton;
966}
967
968
971 return myAddAllYellowButton;
972}
973
974
977 return myAddAllGreenButton;
978}
979
980
983 return myAddAllGreenPriorityButton;
984}
985
986
987void
989 myIndexLabel->show();
990 myIndexLabelBold->hide();
991 // recalc both
992 myIndexLabel->recalc();
993 myIndexLabelBold->recalc();
994}
995
996
997void
999 myIndexLabel->hide();
1000 myIndexLabelBold->show();
1001 // recalc both
1002 myIndexLabel->recalc();
1003 myIndexLabelBold->recalc();
1004}
1005
1006
1007int
1009 return myCol;
1010}
1011
1012
1013int
1015 return myRow;
1016}
1017
1018
1019char
1021 return myTLSTable->myColumns.at(myCol)->getType();
1022}
1023
1024
1025void
1027 myMenuButtonPopup->popdown();
1028}
1029
1030
1031void
1033 if (myButton) {
1034 myButton->disable();
1035 myDisableButton = true;
1036 }
1037}
1038
1039
1041 myCol(-1),
1042 myRow(-1) {
1043}
1044
1045// ---------------------------------------------------------------------------
1046// GNETLSTable::Column - methods
1047// ---------------------------------------------------------------------------
1048
1049GNETLSTable::Column::Column(GNETLSTable* table, const int index, const char type) :
1050 myTable(table),
1051 myIndex(index),
1052 myType(type) {
1053 // create vertical frame
1054 myVerticalFrame = new FXVerticalFrame(table, GUIDesignAuxiliarFrameFixWidth);
1055 // create top label
1056 switch (myType) {
1057 case 's':
1058 case 'i':
1059 case 'd':
1060 case 't':
1061 case 'b':
1062 // empty label
1065 "", nullptr, GUIDesignLabelFixed(0));
1066 break;
1067 default:
1068 // ticked label
1071 "", nullptr, GUIDesignLabelThickedFixed(0));
1072 break;
1073 }
1074 // create vertical frame for cells
1076 // create bot label
1077 switch (myType) {
1078 case 's':
1079 // label with icon
1081 break;
1082 case 'u':
1083 case 'p':
1084 // ticked label
1085 myBotLabel = new FXLabel(myVerticalFrame, "", nullptr, GUIDesignLabelThickedFixed(0));
1086 break;
1087 default:
1088 // empty label
1089 myBotLabel = new FXLabel(myVerticalFrame, "", nullptr, GUIDesignLabelFixed(0));
1090 break;
1091 }
1092 // create elements
1093 myVerticalFrame->create();
1094 myTopLabel->create();
1095 myVerticalCellFrame->create();
1096 myBotLabel->create();
1097}
1098
1099
1101 // delete vertical frame (this also delete all childrens)
1102 delete myVerticalFrame;
1103}
1104
1105
1106FXVerticalFrame*
1108 return myVerticalCellFrame;
1109}
1110
1111
1112char
1114 return myType;
1115}
1116
1117
1118FXString
1120 return myTopLabel->getText();
1121}
1122
1123
1124void
1125GNETLSTable::Column::setColumnLabelTop(const std::string& text, const std::string& tooltip) {
1126 myTopLabel->setText(text.c_str());
1127 myTopLabel->setTipText(tooltip.c_str());
1128}
1129
1130
1131void
1133 myBotLabel->setText(text.c_str());
1134}
1135
1136
1137int
1139 // declare columnWidth
1140 int columnWidth = 0;
1141 // check column type
1142 if (myType == 's') {
1143 // set index column width
1144 columnWidth = 30;
1145 } else if (isTextFieldColumn()) {
1146 // calculate top label width
1147 columnWidth = myTopLabel->getFont()->getTextWidth(myTopLabel->getText().text(), myTopLabel->getText().length() + EXTRAMARGIN);
1148 // iterate over all textFields and check widths
1149 for (const auto& row : myTable->myRows) {
1150 // get text field
1151 const auto textField = row->getCells().at(myIndex)->getTextField();
1152 // get textField width
1153 const auto textFieldWidth = textField->getFont()->getTextWidth(textField->getText().text(), textField->getText().length() + EXTRAMARGIN);
1154 // compare widths
1155 if (textFieldWidth > columnWidth) {
1156 columnWidth = textFieldWidth;
1157 }
1158 }
1159 // calculate bot label width
1160 const auto botLabelWidth = myBotLabel->getFont()->getTextWidth(myBotLabel->getText().text(), myBotLabel->getText().length() + EXTRAMARGIN);
1161 if (botLabelWidth > columnWidth) {
1162 columnWidth = botLabelWidth;
1163 }
1164 } else {
1165 // is an index column, then return icon size
1166 columnWidth = GUIDesignHeight;
1167 }
1168 return columnWidth;
1169}
1170
1171
1172void
1174 // only adjust for textField columns
1175 if (isTextFieldColumn()) {
1176 for (const auto& row : myTable->myRows) {
1177 row->getCells().at(myIndex)->getTextField()->setWidth(colWidth);
1178 }
1179 }
1180 // adjust labels and vertical frames
1181 myVerticalFrame->setWidth(colWidth);
1182 myTopLabel->setWidth(colWidth);
1183 myVerticalCellFrame->setWidth(colWidth);
1184 myBotLabel->setWidth(colWidth);
1185}
1186
1187
1188bool
1190 return ((myType == 'u') || (myType == 'f') || (myType == 'p') || (myType == 'm') || (myType == '-'));
1191}
1192
1193
1195 myIndex(0),
1196 myType('-') {}
1197
1198// ---------------------------------------------------------------------------
1199// GNETLSTable::Row - methods
1200// ---------------------------------------------------------------------------
1201
1203 myTable(table) {
1204 // build textFields
1205 for (int columnIndex = 0; columnIndex < (FXint)table->myColumns.size(); columnIndex++) {
1206 // get number of cells
1207 const int numCells = (int)myCells.size();
1208 // continue depending of type
1209 switch (table->myColumns.at(columnIndex)->getType()) {
1210 case ('s'): {
1211 // create labels for index
1212 auto indexLabel = new FXLabel(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
1213 toString(myTable->myRows.size()).c_str(), nullptr, GUIDesignLabelThickedFixed(30));
1214 auto indexLabelBold = new FXLabel(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
1215 toString(myTable->myRows.size()).c_str(), nullptr, GUIDesignLabelThickedFixed(30));
1216 // set fonts
1217 indexLabel->setFont(myTable->myIndexFont);
1218 indexLabelBold->setFont(myTable->myIndexSelectedFont);
1219 myCells.push_back(new Cell(table, indexLabel, indexLabelBold, columnIndex, numCells));
1220 break;
1221 }
1222 case ('u'):
1223 case ('f'):
1224 case ('m'):
1225 case ('-'): {
1226 // create textField for values
1227 auto textField = new MFXTextFieldTooltip(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
1230 myCells.push_back(new Cell(table, textField, columnIndex, numCells));
1231 break;
1232 }
1233 case ('p'): {
1234 // create text field for program (state)
1235 auto textField = new MFXTextFieldTooltip(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
1238 // set special font
1239 textField->setFont(myTable->myProgramFont);
1240 myCells.push_back(new Cell(table, textField, columnIndex, numCells));
1241 break;
1242 }
1243 case ('i'): {
1244 // create popup for adding new phases
1245 myCells.push_back(new Cell(table, columnIndex, numCells));
1246 break;
1247 }
1248 case ('d'): {
1249 // create button for delete phase
1250 auto button = new MFXButtonTooltip(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
1252 (std::string("\t") + TL("Delete phase") + std::string("\t") + TL("Delete this phase.")).c_str(),
1254 myCells.push_back(new Cell(table, button, columnIndex, numCells));
1255 break;
1256 }
1257 case ('t'): {
1258 // create button for move up phase
1259 auto button = new MFXButtonTooltip(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
1261 (std::string("\t") + TL("Move phase up") + std::string("\t") + TL("Move this phase up.")).c_str(),
1263 myCells.push_back(new Cell(table, button, columnIndex, numCells));
1264 break;
1265 }
1266 case ('b'): {
1267 // create button for move down phase
1268 auto button = new MFXButtonTooltip(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
1270 (std::string("\t") + TL("Move phase down") + std::string("\t") + TL("Move this phase down.")).c_str(),
1272 myCells.push_back(new Cell(table, button, columnIndex, numCells));
1273 break;
1274 }
1275 default:
1276 throw ProcessError("Invalid Cell type");
1277 }
1278 }
1279}
1280
1281
1283 // delete all cells
1284 for (const auto& cell : myCells) {
1285 delete cell;
1286 }
1287}
1288
1289
1290std::string
1292 if (myCells.at(index)->getTextField()) {
1293 return myCells.at(index)->getTextField()->getText().text();
1294 } else {
1295 throw ProcessError("Cell doesn't have a textField");
1296 }
1297}
1298
1299
1300void
1301GNETLSTable::Row::setText(int index, const std::string& text) const {
1302 // set text
1303 myCells.at(index)->getTextField()->setText(text.c_str());
1304}
1305
1306
1307const std::vector<GNETLSTable::Cell*>&
1309 return myCells;
1310}
1311
1312
1313void
1315 // search move up button and disable it
1316 for (const auto& cell : myCells) {
1317 if ((cell->getType() == 'd') || (cell->getType() == 'b') || (cell->getType() == 't')) {
1318 cell->disableButton();
1319 }
1320 }
1321}
1322
1323
1325
1326/****************************************************************************/
#define EXTRAMARGIN
FXDEFMAP(GNETLSTable) GNETLSTableMap[]
#define DEFAULTWIDTH
@ MID_GNE_TLSTABLE_ADDPHASE
TLSTable button for add phase.
@ MID_GNE_TLSTABLE_COPYPHASE
TLSTable button for copy phase.
@ MID_GNE_TLSTABLE_ADDPHASEALLGREENPRIORITY
TLSTable button for add phase green priority.
@ MID_MBTTIP_SELECTED
@ MID_GNE_TLSTABLE_ADDPHASEALLYELLOW
TLSTable button for add phase yelllow.
@ MID_GNE_TLSTABLE_TEXTFIELD
TLSTable textField.
@ MID_GNE_TLSTABLE_ADDPHASEALLRED
TLSTable button for add phase red.
@ MID_GNE_TLSTABLE_MOVEDOWNPHASE
TLSTable button for move down phase.
@ MID_MBTTIP_FOCUS
callback for MFXMenuButtonTooltip
@ MID_GNE_TLSTABLE_ADDPHASEALLGREEN
TLSTable button for add phase green.
@ MID_GNE_TLSTABLE_REMOVEPHASE
TLSTable button for remove phase.
@ MID_GNE_TLSTABLE_MOVEUPPHASE
TLSTable button for move up phase.
#define GUIDesignLabelFixed(width)
label, icon before text, text centered and custom width
Definition GUIDesigns.h:252
#define GUIDesignButtonIcon
button only with icon
Definition GUIDesigns.h:97
#define GUIDesignTextFieldTLSTable
text field with min width (used in TLS table)
Definition GUIDesigns.h:77
#define GUIDesignTextFieldNCol
Num of column of text field.
Definition GUIDesigns.h:80
#define GUIDesignAuxiliarFrameFixWidth
design for auxiliar vertical frames with fixed width (used in TLSTable and DecalsTable)
Definition GUIDesigns.h:420
#define GUIDesignTLSTableCheckableButtonIcon
checkable button only with icon used in TLSTable
Definition GUIDesigns.h:115
#define GUIDesignLabelThickedFixed(width)
label thicked, icon before text, text centered and custom width
Definition GUIDesigns.h:258
@ TLSPHASEALLGREEN
@ TLSPHASEALLGREENPRIORITY
@ TLSPHASECOPY
@ TLSPHASEDEFAULT
@ TLSPHASEALLYELLOW
@ TLSPHASEALLRED
#define WRITE_DEBUG(msg)
Definition MsgHandler.h:306
#define TL(string)
Definition MsgHandler.h:315
int GUIDesignHeight
the default size for GUI elements
Definition StdDefs.cpp:35
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
int getScrollBarWidth() const
get scrollBar width (zero if is hidden)
Definition GNEFrame.cpp:174
GNEViewNet * getViewNet() const
get view net
Definition GNEFrame.cpp:150
void movePhaseDown(const int row)
move phase down
bool changePhaseValue(const int col, const int row, const std::string &value)
change phase value (state, name, next, etc.)
void movePhaseUp(const int row)
move phase up
void updateTLSColoring()
update TLS coloring
void removePhase(const int row)
delete phase
void duplicatePhase(const int row)
duplicate phase
void addPhase(const int row, const char c=' ')
add phase
GNETLSEditorFrame * getTLSEditorParent() const
get TLSEditor Parent
FOX needs this.
void showIndexLabelNormal()
show label index normal
MFXButtonTooltip * getDuplicatePhaseButton()
get duplicate phase button
MFXButtonTooltip * myAddAllGreenPriorityButton
add all green priority phase button
MFXButtonTooltip * myAddAllRedButton
add all red phase button
void enable()
Enable cell.
void showIndexLabelBold()
show label index bold
MFXButtonTooltip * getAddPhaseButton()
get add phase button
int getCol() const
column index
void setFocus()
set focus in the current cell
void setTooltip(const std::string &toolTip)
set tooltip
bool hasFocus() const
check if current cell has focus
Cell()
default constructor
GNETLSTable * myTLSTable
pointer to TLSTable parent
FXPopup * myMenuButtonPopup
popup for buttons
MFXButtonTooltip * getAddAllGreenPriorityPhaseButton()
get add all green priority phase button
MFXButtonTooltip * getAddAllYellowPhaseButton()
get add all yellow phase button
int getRow() const
row index
void disableButton()
disable button (used for delete, move up and move down)
MFXMenuButtonTooltip * myAddButton
menu button tooltip
void hideMenuButtonPopup()
hide menuButton popup
MFXTextFieldTooltip * getTextField() const
get textField
FXLabel * getIndexLabel() const
get index label
double getDoubleValue() const
get double value (only for types 'u' and 'd')
MFXButtonTooltip * getButton()
get remove, move up or move down button
MFXMenuButtonTooltip * getAddButton() const
get add button
MFXButtonTooltip * myAddAllYellowButton
add all yellow phase button
void disable()
Disable cell.
MFXButtonTooltip * getAddAllGreenPhaseButton()
get add all green phase button
char getType() const
get column type
MFXButtonTooltip * getAddAllRedPhaseButton()
get add all red phase button
MFXButtonTooltip * myDuplicatePhaseButton
duplicate phase button
MFXButtonTooltip * myAddPhaseButton
add phase button
MFXButtonTooltip * myAddAllGreenButton
add all green phase button
int getColumnMinimumWidth()
get column minimum width
const char myType
column type
FXVerticalFrame * myVerticalFrame
vertical frame
FXLabel * myBotLabel
column bot label
Column()
default constructor
FXVerticalFrame * getVerticalCellFrame() const
get vertical cell frame
FXVerticalFrame * myVerticalCellFrame
vertical frame
void setColumnLabelTop(const std::string &text, const std::string &tooltip)
set column label top
bool isTextFieldColumn() const
check if current type correspond to a textField
char getType() const
get column type
FXString getColumnLabelTop() const
get column label top
void setColumnLabelBot(const std::string &text)
set column label boit
MFXLabelTooltip * myTopLabel
column top tooltip label
void setColumnWidth(const int colWidth)
set colum width
void setText(int index, const std::string &text) const
set text
Row()
default constructor
GNETLSTable * myTable
poiner to table parent
std::vector< Cell * > myCells
list wtih cells
void disableButtons()
disable row buttons
const std::vector< Cell * > & getCells() const
get cells
std::string getText(int index) const
get text
GNETLSEditorFrame::TLSPhases * myTLSPhasesParent
@frame pointer to TLSEditorFrame phases parent
int getNumRows() const
Get number of rows.
int myCurrentSelectedRow
current selected row
long onCmdDuplicatePhase(FXObject *, FXSelector, void *)
called when a duplicate phase button is pressed
long onCmdEditRow(FXObject *, FXSelector, void *)
called when a row is modified
FXFont * myIndexSelectedFont
font for index selected
long onCmdAddPhaseAllRed(FXObject *, FXSelector, void *)
called when an add all green red phase button is pressed
long onCmdAddPhaseAllGreenPriority(FXObject *, FXSelector, void *)
called when an add all green red phase button is pressed
long onCmdAddPhase(FXObject *, FXSelector, void *)
called when an add phase button is pressed
void updateIndexLabel()
update index labels
long onFocusRow(FXObject *, FXSelector, void *)
void setColumnLabelBot(const int column, const std::string &text)
Change column bottom text.
void clearTable()
clear table
void selectRow(const int rowIndex)
Select a row.
long onCmdMoveUpPhase(FXObject *, FXSelector, void *)
called when a move up phase button is pressed
~GNETLSTable()
destructor (Called automatically)
int getCurrentSelectedRow() const
Get current selected row.
long onCmdAddPhasePressed(FXObject *, FXSelector, void *)
called when add phase button is selected
FXFont * myIndexFont
font for index
void enable()
Enable table.
long onCmdAddPhaseAllYellow(FXObject *, FXSelector, void *)
called when an add all green red phase button is pressed
std::string getItemText(const int row, const int column) const
Return cell text.
long onCmdKeyPress(FXObject *, FXSelector, void *)
called when a key is pressed
long onCmdAddPhaseAllGreen(FXObject *, FXSelector, void *)
called when an add all green red phase button is pressed
bool moveFocus()
move focus to current row
void setColumnLabelTop(const int column, const std::string &text, const std::string &tooltip="")
Change column header text.
void setItemText(FXint row, FXint column, const std::string &text)
Modify cell text.
std::vector< Row * > myRows
rows
long onCmdRemovePhase(FXObject *, FXSelector, void *)
called when a remove phase button is pressed
void updateAccumulatedDuration()
update accumulated duration();
void setTableSize(const std::string &columnsType, const int numberRow)
Set the table size to nr rows and nc columns; all existing items will be removed. Format: s -> select...
FXFont * myProgramFont
font for the phase table
void disable()
Disable table.
long onCmdMoveDownPhase(FXObject *, FXSelector, void *)
called when a move up phase button is pressed
void recalcTableWidth()
recalc width (call when all labels and contents are fill)
GNETLSEditorFrame::TLSPhases * getTLSPhasesParent() const
@frame get pointer to TLSEditorFrame phases parent
std::vector< Column * > myColumns
columns
GNEViewParent * getViewParent() const
get the net object
GNEApplicationWindow * getGNEAppWindows() const
get GNE Application Windows
int getFrameAreaWidth() const
get frame area width
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
MFXStaticToolTip * getStaticTooltipMenu() const
get static toolTip for menus