#include <netedit/GNEApplicationWindow.h>
#include <netedit/GNEViewNet.h>
#include <netedit/GNEViewParent.h>
#include <netedit/elements/GNEAttributeCarrier.h>
#include <utils/foxtools/MFXLabelTooltip.h>
#include <utils/foxtools/MFXMenuButtonTooltip.h>
#include <utils/foxtools/MFXTextFieldIcon.h>
#include <utils/gui/div/GUIDesigns.h>
#include <utils/gui/images/GUIIconSubSys.h>
#include <utils/gui/windows/GUIAppEnum.h>
#include "GNETLSTable.h"
#define EXTRAMARGIN 1
#define DEFAULTWIDTH 190
FXDEFMAP(GNETLSTable) GNETLSTableMap[] = {
FXMAPFUNC(MID_MBTTIP_FOCUS, 0, GNETLSTable::onFocusRow),
FXMAPFUNC(MID_MBTTIP_SELECTED, 0, GNETLSTable::onCmdAddPhasePressed),
FXMAPFUNC(SEL_FOCUSIN, MID_GNE_TLSTABLE_TEXTFIELD, GNETLSTable::onFocusRow),
FXMAPFUNC(SEL_COMMAND, MID_GNE_TLSTABLE_TEXTFIELD, GNETLSTable::onCmdEditRow),
FXMAPFUNC(SEL_KEYPRESS, MID_GNE_TLSTABLE_TEXTFIELD, GNETLSTable::onCmdKeyPress),
FXMAPFUNC(SEL_COMMAND, MID_GNE_TLSTABLE_ADDPHASE, GNETLSTable::onCmdAddPhase),
FXMAPFUNC(SEL_COMMAND, MID_GNE_TLSTABLE_COPYPHASE, GNETLSTable::onCmdDuplicatePhase),
FXMAPFUNC(SEL_COMMAND, MID_GNE_TLSTABLE_ADDPHASEALLRED, GNETLSTable::onCmdAddPhaseAllRed),
FXMAPFUNC(SEL_COMMAND, MID_GNE_TLSTABLE_ADDPHASEALLYELLOW, GNETLSTable::onCmdAddPhaseAllYellow),
FXMAPFUNC(SEL_COMMAND, MID_GNE_TLSTABLE_ADDPHASEALLGREEN, GNETLSTable::onCmdAddPhaseAllGreen),
FXMAPFUNC(SEL_COMMAND, MID_GNE_TLSTABLE_ADDPHASEALLGREENPRIORITY, GNETLSTable::onCmdAddPhaseAllGreenPriority),
FXMAPFUNC(SEL_COMMAND, MID_GNE_TLSTABLE_REMOVEPHASE, GNETLSTable::onCmdRemovePhase),
FXMAPFUNC(SEL_KEYPRESS, MID_GNE_TLSTABLE_TEXTFIELD, GNETLSTable::onCmdKeyPress),
FXMAPFUNC(SEL_COMMAND, MID_GNE_TLSTABLE_MOVEUPPHASE, GNETLSTable::onCmdMoveUpPhase),
FXMAPFUNC(SEL_KEYPRESS, MID_GNE_TLSTABLE_TEXTFIELD, GNETLSTable::onCmdKeyPress),
FXMAPFUNC(SEL_COMMAND, MID_GNE_TLSTABLE_MOVEDOWNPHASE, GNETLSTable::onCmdMoveDownPhase),
FXMAPFUNC(SEL_KEYPRESS, MID_GNE_TLSTABLE_TEXTFIELD, GNETLSTable::onCmdKeyPress),
};
FXIMPLEMENT(GNETLSTable, FXHorizontalFrame, GNETLSTableMap, ARRAYNUMBER(GNETLSTableMap))
GNETLSTable::GNETLSTable(GNETLSEditorFrame::TLSPhases* TLSPhasesParent) :
FXHorizontalFrame(TLSPhasesParent->getCollapsableFrame(), GUIDesignAuxiliarFrameFixedWidth(0)),
myProgramFont(new FXFont(getApp(), "Courier New", 10)),
myIndexFont(new FXFont(getApp(), "Segoe UI", 9)),
myIndexSelectedFont(new FXFont(getApp(), "Segoe UI", 9, FXFont::Bold)),
myTLSPhasesParent(TLSPhasesParent) {
recalcTableWidth();
}
GNETLSTable::~GNETLSTable() {
delete myProgramFont;
delete myIndexFont;
delete myIndexSelectedFont;
}
void
GNETLSTable::enable() {
for (const auto& row : myRows) {
for (const auto& cell : row->getCells()) {
cell->enable();
}
}
FXHorizontalFrame::enable();
}
void
GNETLSTable::disable() {
for (const auto& row : myRows) {
for (const auto& cell : row->getCells()) {
cell->disable();
}
}
FXHorizontalFrame::disable();
}
GNETLSEditorFrame::TLSPhases*
GNETLSTable::getTLSPhasesParent() const {
return myTLSPhasesParent;
}
void
GNETLSTable::recalcTableWidth() {
int minimumTableWidth = 0;
Column* nameColumn = nullptr;
for (const auto& column : myColumns) {
if (column->getType() == 'm') {
nameColumn = column;
} else {
const auto minimunColWidth = column->getColumnMinimumWidth();
column->setColumnWidth(minimunColWidth);
minimumTableWidth += minimunColWidth;
}
}
if (nameColumn) {
const int minimumColNameWidth = nameColumn->getColumnMinimumWidth();
const int scrollBarWidth = myTLSPhasesParent->getTLSEditorParent()->getScrollBarWidth();
const auto frameAreaWidth = myTLSPhasesParent->getTLSEditorParent()->getViewNet()->getViewParent()->getFrameAreaWidth() - 30;
if ((frameAreaWidth - (minimumTableWidth + minimumColNameWidth + scrollBarWidth)) > 0) {
nameColumn->setColumnWidth(frameAreaWidth - minimumTableWidth - scrollBarWidth);
setWidth(frameAreaWidth);
} else {
nameColumn->setColumnWidth(minimumColNameWidth);
setWidth(minimumTableWidth + minimumColNameWidth);
}
} else if (minimumTableWidth > 0) {
setWidth(minimumTableWidth);
} else {
setWidth(DEFAULTWIDTH);
}
}
void
GNETLSTable::clearTable() {
for (const auto& row : myRows) {
delete row;
}
for (const auto& column : myColumns) {
delete column;
}
myRows.clear();
myColumns.clear();
}
void
GNETLSTable::setTableSize(const std::string& columnsType, const int numberRow) {
clearTable();
for (int i = 0; i < (FXint)columnsType.size(); i++) {
myColumns.push_back(new Column(this, i, columnsType.at(i)));
}
for (int i = 0; i < numberRow; i++) {
myRows.push_back(new Row(this));
}
if (myRows.size() == 1) {
myRows.front()->disableButtons();
}
}
void
GNETLSTable::setItemText(FXint row, FXint column, const std::string& text) {
if ((row >= 0) && (row < (FXint)myRows.size()) &&
(column >= 0) && (column < (FXint)myColumns.size())) {
myRows.at(row)->setText(column, text);
if (myColumns.at(column)->getType() == 'u') {
updateAccumulatedDuration();
}
} else {
throw ProcessError(TL("Invalid row or column"));
}
}
std::string
GNETLSTable::getItemText(const int row, const int column) const {
if ((row >= 0) && (row < (FXint)myRows.size()) &&
(column >= 0) && (column < (FXint)myColumns.size())) {
return myRows.at(row)->getText(column);
}
throw ProcessError(TL("Invalid row or column"));
}
int
GNETLSTable::getNumRows() const {
return (int)myRows.size();
}
int
GNETLSTable::getCurrentSelectedRow() const {
return myCurrentSelectedRow;
}
void
GNETLSTable::selectRow(const int row) {
if ((row >= 0) && (row < (FXint)myRows.size())) {
myCurrentSelectedRow = row;
updateIndexLabel();
} else {
throw ProcessError(TL("Invalid row"));
}
}
void
GNETLSTable::setColumnLabelTop(const int column, const std::string& text, const std::string& tooltip) {
if ((column >= 0) && (column < (int)myColumns.size())) {
myColumns.at(column)->setColumnLabelTop(text, tooltip);
} else {
throw ProcessError(TL("Invalid column"));
}
}
void
GNETLSTable::setColumnLabelBot(const int column, const std::string& text) {
if ((column >= 0) && (column < (int)myColumns.size())) {
myColumns.at(column)->setColumnLabelBot(text);
} else {
throw ProcessError(TL("Invalid column"));
}
}
long
GNETLSTable::testTable(const InternalTestStep::TLSTableTest* tableTest) {
if (tableTest->row >= (int)myRows.size()) {
throw ProcessError(TL("Invalid row in table test"));
} else if (tableTest->column >= (int)myColumns.size()) {
throw ProcessError(TL("Invalid column in table test"));
} else {
Cell* cell = myRows.at(tableTest->row)->getCells().at(tableTest->column);
if (tableTest->sel == MID_GNE_TLSTABLE_ADDPHASE) {
return onCmdAddPhase(cell->getAddPhaseButton(), 0, nullptr);
} else if (tableTest->sel == MID_GNE_TLSTABLE_COPYPHASE) {
return onCmdDuplicatePhase(cell->getDuplicatePhaseButton(), 0, nullptr);
} else if (tableTest->sel == MID_GNE_TLSTABLE_ADDPHASEALLRED) {
return onCmdAddPhaseAllRed(cell->getAddAllRedPhaseButton(), 0, nullptr);
} else if (tableTest->sel == MID_GNE_TLSTABLE_ADDPHASEALLYELLOW) {
return onCmdAddPhaseAllYellow(cell->getAddAllYellowPhaseButton(), 0, nullptr);
} else if (tableTest->sel == MID_GNE_TLSTABLE_ADDPHASEALLGREEN) {
return onCmdAddPhaseAllGreen(cell->getAddAllGreenPhaseButton(), 0, nullptr);
} else if (tableTest->sel == MID_GNE_TLSTABLE_ADDPHASEALLGREENPRIORITY) {
return onCmdAddPhaseAllGreenPriority(cell->getAddAllGreenPriorityPhaseButton(), 0, nullptr);
} else if (tableTest->sel == MID_GNE_TLSTABLE_REMOVEPHASE) {
return onCmdRemovePhase(cell->getButton(), 0, nullptr);
} else if (tableTest->sel == MID_GNE_TLSTABLE_MOVEUPPHASE) {
return onCmdMoveUpPhase(cell->getButton(), 0, nullptr);
} else if (tableTest->sel == MID_GNE_TLSTABLE_MOVEDOWNPHASE) {
return onCmdMoveDownPhase(cell->getButton(), 0, nullptr);
} else if (tableTest->sel == MID_GNE_TLSTABLE_TEXTFIELD) {
cell->getTextField()->setText(tableTest->text.c_str(), TRUE);
return 1;
} else {
throw ProcessError(TL("Unknown operation in table test"));
}
}
}
long
GNETLSTable::onFocusRow(FXObject* sender, FXSelector, void*) {
int selectedRow = -1;
for (int rowIndex = 0; rowIndex < (int)myRows.size(); rowIndex++) {
for (const auto& cell : myRows.at(rowIndex)->getCells()) {
if ((cell->getTextField() == sender) || (cell->getAddButton() == sender)) {
selectedRow = rowIndex;
}
}
}
updateIndexLabel();
if (myCurrentSelectedRow != selectedRow) {
myCurrentSelectedRow = selectedRow;
updateIndexLabel();
}
return 0;
}
long
GNETLSTable::onCmdAddPhasePressed(FXObject* sender, FXSelector, void*) {
for (int columnIndex = 0; columnIndex < (int)myColumns.size(); columnIndex++) {
for (int rowIndex = 0; rowIndex < (int)myRows.size(); rowIndex++) {
if (myRows.at(rowIndex)->getCells().at(columnIndex)->getAddButton() == sender) {
myRows.at(rowIndex)->getCells().at(columnIndex)->getAddPhaseButton()->setFocus();
return 1;
}
}
}
return 0;
}
long
GNETLSTable::onCmdEditRow(FXObject* sender, FXSelector, void*) {
for (int columnIndex = 0; columnIndex < (int)myColumns.size(); columnIndex++) {
for (int rowIndex = 0; rowIndex < (int)myRows.size(); rowIndex++) {
const auto textField = myRows.at(rowIndex)->getCells().at(columnIndex)->getTextField();
if (textField == sender) {
if (myTLSPhasesParent->changePhaseValue(columnIndex, rowIndex, textField->getText().text())) {
textField->setTextColor(GUIDesignTextColorBlack);
textField->killFocus();
myTLSPhasesParent->getTLSEditorParent()->update();
} else {
textField->setTextColor(GUIDesignTextColorRed);
}
return 1;
}
}
}
return 0;
}
long
GNETLSTable::onCmdKeyPress(FXObject* sender, FXSelector sel, void* ptr) {
FXEvent* eventInfo = (FXEvent*)ptr;
if (eventInfo->code == 65362) {
if (myCurrentSelectedRow > 0) {
myCurrentSelectedRow -= 1;
} else {
myCurrentSelectedRow = ((int)myRows.size() - 1);
}
updateIndexLabel();
moveFocus();
return 1;
} else if (eventInfo->code == 65364) {
if (myCurrentSelectedRow < ((int)myRows.size() - 1)) {
myCurrentSelectedRow += 1;
} else {
myCurrentSelectedRow = 0;
}
updateIndexLabel();
moveFocus();
return 1;
} else {
return sender->handle(sender, sel, ptr);
}
}
long
GNETLSTable::onCmdAddPhase(FXObject* sender, FXSelector, void*) {
for (int indexRow = 0; indexRow < (int)myRows.size(); indexRow++) {
for (const auto& cell : myRows.at(indexRow)->getCells()) {
if (cell->getAddPhaseButton() == sender) {
cell->hideMenuButtonPopup();
myTLSPhasesParent->addPhase(indexRow);
return 0;
}
}
}
return 0;
}
long
GNETLSTable::onCmdDuplicatePhase(FXObject* sender, FXSelector, void*) {
for (int indexRow = 0; indexRow < (int)myRows.size(); indexRow++) {
for (const auto& cell : myRows.at(indexRow)->getCells()) {
if (cell->getDuplicatePhaseButton() == sender) {
cell->hideMenuButtonPopup();
myTLSPhasesParent->duplicatePhase(indexRow);
return 0;
}
}
}
return 0;
}
long
GNETLSTable::onCmdAddPhaseAllRed(FXObject* sender, FXSelector, void*) {
for (int indexRow = 0; indexRow < (int)myRows.size(); indexRow++) {
for (const auto& cell : myRows.at(indexRow)->getCells()) {
if (cell->getAddAllRedPhaseButton() == sender) {
cell->hideMenuButtonPopup();
myTLSPhasesParent->addPhase(indexRow, 'r');
return 0;
}
}
}
return 0;
}
long
GNETLSTable::onCmdAddPhaseAllYellow(FXObject* sender, FXSelector, void*) {
for (int indexRow = 0; indexRow < (int)myRows.size(); indexRow++) {
for (const auto& cell : myRows.at(indexRow)->getCells()) {
if (cell->getAddAllYellowPhaseButton() == sender) {
cell->hideMenuButtonPopup();
myTLSPhasesParent->addPhase(indexRow, 'y');
return 0;
}
}
}
return 0;
}
long
GNETLSTable::onCmdAddPhaseAllGreen(FXObject* sender, FXSelector, void*) {
for (int indexRow = 0; indexRow < (int)myRows.size(); indexRow++) {
for (const auto& cell : myRows.at(indexRow)->getCells()) {
if (cell->getAddAllGreenPhaseButton() == sender) {
cell->hideMenuButtonPopup();
myTLSPhasesParent->addPhase(indexRow, 'g');
return 0;
}
}
}
return 0;
}
long
GNETLSTable::onCmdAddPhaseAllGreenPriority(FXObject* sender, FXSelector, void*) {
for (int indexRow = 0; indexRow < (int)myRows.size(); indexRow++) {
for (const auto& cell : myRows.at(indexRow)->getCells()) {
if (cell->getAddAllGreenPriorityPhaseButton() == sender) {
cell->hideMenuButtonPopup();
myTLSPhasesParent->addPhase(indexRow, 'G');
return 0;
}
}
}
return 0;
}
long
GNETLSTable::onCmdRemovePhase(FXObject* sender, FXSelector, void*) {
for (int indexRow = 0; indexRow < (int)myRows.size(); indexRow++) {
for (const auto& cell : myRows.at(indexRow)->getCells()) {
if (cell->getButton() == sender) {
myTLSPhasesParent->removePhase(indexRow);
return 0;
}
}
}
return 0;
}
long
GNETLSTable::onCmdMoveUpPhase(FXObject* sender, FXSelector, void*) {
for (int indexRow = 0; indexRow < (int)myRows.size(); indexRow++) {
for (const auto& cell : myRows.at(indexRow)->getCells()) {
if (cell->getButton() == sender) {
myTLSPhasesParent->movePhaseUp(indexRow);
return 0;
}
}
}
return 0;
}
long
GNETLSTable::onCmdMoveDownPhase(FXObject* sender, FXSelector, void*) {
for (int indexRow = 0; indexRow < (int)myRows.size(); indexRow++) {
for (const auto& cell : myRows.at(indexRow)->getCells()) {
if (cell->getButton() == sender) {
myTLSPhasesParent->movePhaseDown(indexRow);
return 0;
}
}
}
return 0;
}
void
GNETLSTable::updateIndexLabel() {
for (int rowIndex = 0; rowIndex < (int)myRows.size(); rowIndex++) {
for (const auto& cell : myRows.at(rowIndex)->getCells()) {
if (cell->getIndexLabel()) {
if (myCurrentSelectedRow == rowIndex) {
cell->showIndexLabelBold();
} else {
cell->showIndexLabelNormal();
}
}
}
}
myTLSPhasesParent->updateTLSColoring();
}
void
GNETLSTable::updateAccumulatedDuration() {
int durationCol = -1;
for (int i = 0; i < (int)myColumns.size(); i++) {
if (myColumns.at(i)->getType() == 'u') {
durationCol = i;
}
}
if (durationCol != -1) {
std::vector<double> durations;
for (const auto& row : myRows) {
durations.push_back(row->getCells().at(durationCol)->getDoubleValue());
}
for (int i = 1; i < (int)durations.size(); i++) {
durations.at(i) += durations.at(i - 1);
}
for (int i = 0; i < (int)myRows.size(); i++) {
myRows.at(i)->getCells().at(durationCol)->setTooltip(TL("Accumulated: ") + toString(durations.at(i)));
}
}
}
bool
GNETLSTable::moveFocus() {
for (int rowIndex = 0; rowIndex < (int)myRows.size(); rowIndex++) {
for (int cellIndex = 0; cellIndex < (int)myRows.at(rowIndex)->getCells().size(); cellIndex++) {
if (myRows.at(rowIndex)->getCells().at(cellIndex)->hasFocus()) {
myRows.at(myCurrentSelectedRow)->getCells().at(cellIndex)->setFocus();
return true;
}
}
}
return false;
}
GNETLSTable::Cell::Cell(GNETLSTable* TLSTable, MFXTextFieldIcon* textField, int col, int row) :
myTLSTable(TLSTable),
myTextField(textField),
myCol(col),
myRow(row) {
textField->create();
}
GNETLSTable::Cell::Cell(GNETLSTable* TLSTable, FXLabel* indexLabel, FXLabel* indexLabelBold, int col, int row) :
myTLSTable(TLSTable),
myIndexLabel(indexLabel),
myIndexLabelBold(indexLabelBold),
myCol(col),
myRow(row) {
indexLabel->create();
indexLabelBold->create();
indexLabelBold->hide();
indexLabelBold->setBackColor(FXRGBA(210, 233, 255, 255));
}
GNETLSTable::Cell::Cell(GNETLSTable* TLSTable, MFXButtonTooltip* button, int col, int row) :
myTLSTable(TLSTable),
myButton(button),
myCol(col),
myRow(row) {
button->create();
}
GNETLSTable::Cell::Cell(GNETLSTable* TLSTable, int col, int row) :
myTLSTable(TLSTable),
myCol(col),
myRow(row) {
myMenuButtonPopup = new FXPopup(TLSTable->myColumns.at(col)->getVerticalCellFrame(), POPUP_HORIZONTAL);
myAddButton = new MFXMenuButtonTooltip(TLSTable->myColumns.at(col)->getVerticalCellFrame(),
myTLSTable->getTLSPhasesParent()->getTLSEditorParent()->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu(),
(std::string("\t") + TL("Add phase") + std::string("\t") + TL("Add new phase.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::ADD), myMenuButtonPopup, TLSTable, GUIDesignTLSTableCheckableButtonIcon);
myAddPhaseButton = new MFXButtonTooltip(myMenuButtonPopup,
myTLSTable->getTLSPhasesParent()->getTLSEditorParent()->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu(),
(std::string("\t") + TL("Default phase") + std::string("\t") + TL("Add default phase.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::TLSPHASEDEFAULT), TLSTable, MID_GNE_TLSTABLE_ADDPHASE, GUIDesignButtonIcon);
myDuplicatePhaseButton = new MFXButtonTooltip(myMenuButtonPopup,
myTLSTable->getTLSPhasesParent()->getTLSEditorParent()->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu(),
(std::string("\t") + TL("Duplicate phase") + std::string("\t") + TL("Duplicate this phase.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::TLSPHASECOPY), TLSTable, MID_GNE_TLSTABLE_COPYPHASE, GUIDesignButtonIcon);
myAddAllRedButton = new MFXButtonTooltip(myMenuButtonPopup,
myTLSTable->getTLSPhasesParent()->getTLSEditorParent()->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu(),
(std::string("\t") + TL("Red phase") + std::string("\t") + TL("Add red phase.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::TLSPHASEALLRED), TLSTable, MID_GNE_TLSTABLE_ADDPHASEALLRED, GUIDesignButtonIcon);
myAddAllYellowButton = new MFXButtonTooltip(myMenuButtonPopup,
myTLSTable->getTLSPhasesParent()->getTLSEditorParent()->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu(),
(std::string("\t") + TL("Yellow phase") + std::string("\t") + TL("Add yellow phase.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::TLSPHASEALLYELLOW), TLSTable, MID_GNE_TLSTABLE_ADDPHASEALLYELLOW, GUIDesignButtonIcon);
myAddAllGreenButton = new MFXButtonTooltip(myMenuButtonPopup,
myTLSTable->getTLSPhasesParent()->getTLSEditorParent()->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu(),
(std::string("\t") + TL("Green phase") + std::string("\t") + TL("Add green phase.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::TLSPHASEALLGREEN), TLSTable, MID_GNE_TLSTABLE_ADDPHASEALLGREEN, GUIDesignButtonIcon);
myAddAllGreenPriorityButton = new MFXButtonTooltip(myMenuButtonPopup,
myTLSTable->getTLSPhasesParent()->getTLSEditorParent()->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu(),
(std::string("\t") + TL("Green priority phase") + std::string("\t") + TL("Add green priority phase.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::TLSPHASEALLGREENPRIORITY), TLSTable, MID_GNE_TLSTABLE_ADDPHASEALLGREENPRIORITY, GUIDesignButtonIcon);
myMenuButtonPopup->create();
myAddButton->create();
myAddPhaseButton->create();
myDuplicatePhaseButton->create();
myAddAllRedButton->create();
myAddAllYellowButton->create();
myAddAllGreenButton->create();
myAddAllGreenPriorityButton->create();
myAddPhaseButton->setBackColor(FXRGBA(210, 233, 255, 255));
myDuplicatePhaseButton->setBackColor(FXRGBA(210, 233, 255, 255));
myAddAllRedButton->setBackColor(FXRGBA(255, 213, 213, 255));
myAddAllYellowButton->setBackColor(FXRGBA(253, 255, 206, 255));
myAddAllGreenButton->setBackColor(FXRGBA(240, 255, 205, 255));
myAddAllGreenPriorityButton->setBackColor(FXRGBA(240, 255, 205, 255));
}
GNETLSTable::Cell::~Cell() {
if (myTextField) {
delete myTextField;
}
if (myIndexLabel) {
delete myIndexLabel;
}
if (myIndexLabelBold) {
delete myIndexLabelBold;
}
if (myButton) {
delete myButton;
}
if (myAddButton) {
delete myAddButton;
}
if (myAddPhaseButton) {
delete myAddPhaseButton;
}
if (myDuplicatePhaseButton) {
delete myDuplicatePhaseButton;
}
if (myAddAllRedButton) {
delete myAddAllRedButton;
}
if (myAddAllYellowButton) {
delete myAddAllYellowButton;
}
if (myAddAllGreenButton) {
delete myAddAllGreenButton;
}
if (myAddAllGreenPriorityButton) {
delete myAddAllGreenPriorityButton;
}
if (myMenuButtonPopup) {
delete myMenuButtonPopup;
}
}
void
GNETLSTable::Cell::enable() {
if (myTextField) {
myTextField->enable();
}
if (myIndexLabel) {
myIndexLabel->enable();
}
if (myIndexLabelBold) {
myIndexLabelBold->enable();
}
if (myButton && !myDisableButton) {
myButton->enable();
}
if (myAddButton) {
myAddButton->enable();
}
if (myAddPhaseButton) {
myAddPhaseButton->enable();
}
if (myDuplicatePhaseButton) {
myDuplicatePhaseButton->enable();
}
if (myAddAllRedButton) {
myAddAllRedButton->enable();
}
if (myAddAllYellowButton) {
myAddAllYellowButton->enable();
}
if (myAddAllGreenButton) {
myAddAllGreenButton->enable();
}
if (myAddAllGreenPriorityButton) {
myAddAllGreenPriorityButton->enable();
}
if (myMenuButtonPopup) {
myMenuButtonPopup->enable();
}
}
void
GNETLSTable::Cell::disable() {
if (myTextField) {
myTextField->disable();
}
if (myIndexLabel) {
myIndexLabel->disable();
}
if (myIndexLabelBold) {
myIndexLabelBold->disable();
}
if (myButton && !myDisableButton) {
myButton->disable();
}
if (myAddButton) {
myAddButton->disable();
}
if (myAddPhaseButton) {
myAddPhaseButton->disable();
}
if (myDuplicatePhaseButton) {
myDuplicatePhaseButton->disable();
}
if (myAddAllRedButton) {
myAddAllRedButton->disable();
}
if (myAddAllYellowButton) {
myAddAllYellowButton->disable();
}
if (myAddAllGreenButton) {
myAddAllGreenButton->disable();
}
if (myAddAllGreenPriorityButton) {
myAddAllGreenPriorityButton->disable();
}
if (myMenuButtonPopup) {
myMenuButtonPopup->disable();
}
}
bool
GNETLSTable::Cell::hasFocus() const {
if (myTextField && myTextField->hasFocus()) {
return true;
} else if (myButton && myButton->hasFocus()) {
return true;
} else if (myAddButton && myAddButton->hasFocus()) {
return true;
} else if (myAddPhaseButton && myAddPhaseButton->hasFocus()) {
return true;
} else if (myDuplicatePhaseButton && myDuplicatePhaseButton->hasFocus()) {
return true;
} else if (myAddAllRedButton && myAddAllRedButton->hasFocus()) {
return true;
} else if (myAddAllYellowButton && myAddAllYellowButton->hasFocus()) {
return true;
} else if (myAddAllGreenButton && myAddAllGreenButton->hasFocus()) {
return true;
} else if (myAddAllGreenPriorityButton && myAddAllGreenPriorityButton->hasFocus()) {
return true;
} else {
return false;
}
}
void
GNETLSTable::Cell::setFocus() {
if (myTextField) {
myTextField->setFocus();
} else if (myButton) {
myButton->setFocus();
} else if (myAddButton) {
myAddButton->setFocus();
} else if (myAddPhaseButton) {
myAddPhaseButton->setFocus();
} else if (myDuplicatePhaseButton) {
myDuplicatePhaseButton->setFocus();
} else if (myAddAllRedButton) {
myAddAllRedButton->setFocus();
} else if (myAddAllYellowButton) {
myAddAllYellowButton->setFocus();
} else if (myAddAllGreenButton) {
myAddAllGreenButton->setFocus();
} else if (myAddAllGreenPriorityButton) {
myAddAllGreenPriorityButton->setFocus();
}
}
double
GNETLSTable::Cell::getDoubleValue() const {
if (myTextField->getText().empty()) {
return 0;
} else if (!GNEAttributeCarrier::canParse<double>(myTextField->getText().text())) {
throw ProcessError(TL("Cannot be parsed to double"));
} else {
return GNEAttributeCarrier::parse<double>(myTextField->getText().text());
}
}
void
GNETLSTable::Cell::setTooltip(const std::string& toolTip) {
if (myTextField) {
myTextField->setToolTipText(toolTip.c_str());
} else {
throw ProcessError(TL("Tooltips only for TextFields"));
}
}
MFXTextFieldIcon*
GNETLSTable::Cell::getTextField() const {
return myTextField;
}
FXLabel*
GNETLSTable::Cell::getIndexLabel() const {
return myIndexLabel;
}
MFXMenuButtonTooltip*
GNETLSTable::Cell::getAddButton() const {
return myAddButton;
}
MFXButtonTooltip*
GNETLSTable::Cell::getButton() {
return myButton;
}
MFXButtonTooltip*
GNETLSTable::Cell::getAddPhaseButton() {
return myAddPhaseButton;
}
MFXButtonTooltip*
GNETLSTable::Cell::getDuplicatePhaseButton() {
return myDuplicatePhaseButton;
}
MFXButtonTooltip*
GNETLSTable::Cell::getAddAllRedPhaseButton() {
return myAddAllRedButton;
}
MFXButtonTooltip*
GNETLSTable::Cell::getAddAllYellowPhaseButton() {
return myAddAllYellowButton;
}
MFXButtonTooltip*
GNETLSTable::Cell::getAddAllGreenPhaseButton() {
return myAddAllGreenButton;
}
MFXButtonTooltip*
GNETLSTable::Cell::getAddAllGreenPriorityPhaseButton() {
return myAddAllGreenPriorityButton;
}
void
GNETLSTable::Cell::showIndexLabelNormal() {
myIndexLabel->show();
myIndexLabelBold->hide();
myIndexLabel->recalc();
myIndexLabelBold->recalc();
}
void
GNETLSTable::Cell::showIndexLabelBold() {
myIndexLabel->hide();
myIndexLabelBold->show();
myIndexLabel->recalc();
myIndexLabelBold->recalc();
}
int
GNETLSTable::Cell::getCol() const {
return myCol;
}
int
GNETLSTable::Cell::getRow() const {
return myRow;
}
char
GNETLSTable::Cell::getType() const {
return myTLSTable->myColumns.at(myCol)->getType();
}
void
GNETLSTable::Cell::hideMenuButtonPopup() {
if (myMenuButtonPopup) {
myMenuButtonPopup->popdown();
}
}
void
GNETLSTable::Cell::disableButton() {
if (myButton) {
myButton->disable();
myDisableButton = true;
}
}
GNETLSTable::Cell::Cell() :
myCol(-1),
myRow(-1) {
}
GNETLSTable::Column::Column(GNETLSTable* table, const int index, const char type) :
myTable(table),
myIndex(index),
myType(type) {
myVerticalFrame = new FXVerticalFrame(table, GUIDesignAuxiliarFrameFixedWidth(0));
switch (myType) {
case 's':
case 'i':
case 'd':
case 't':
case 'b':
myTopLabel = new MFXLabelTooltip(myVerticalFrame,
table->getTLSPhasesParent()->getTLSEditorParent()->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu(),
"", nullptr, GUIDesignLabelFixed(0));
break;
default:
myTopLabel = new MFXLabelTooltip(myVerticalFrame,
table->getTLSPhasesParent()->getTLSEditorParent()->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu(),
"", nullptr, GUIDesignLabelThickedFixed(0));
break;
}
myVerticalCellFrame = new FXVerticalFrame(myVerticalFrame, GUIDesignAuxiliarFrameFixedWidth(0));
switch (myType) {
case 's':
myBotLabel = new FXLabel(myVerticalFrame, "", GUIIconSubSys::getIcon(GUIIcon::SUM), GUIDesignLabelThickedFixed(0));
break;
case 'u':
case 'p':
myBotLabel = new FXLabel(myVerticalFrame, "", nullptr, GUIDesignLabelThickedFixed(0));
break;
default:
myBotLabel = new FXLabel(myVerticalFrame, "", nullptr, GUIDesignLabelFixed(0));
break;
}
myVerticalFrame->create();
myTopLabel->create();
myVerticalCellFrame->create();
myBotLabel->create();
}
GNETLSTable::Column::~Column() {
delete myVerticalFrame;
}
FXVerticalFrame*
GNETLSTable::Column::getVerticalCellFrame() const {
return myVerticalCellFrame;
}
char
GNETLSTable::Column::getType() const {
return myType;
}
FXString
GNETLSTable::Column::getColumnLabelTop() const {
return myTopLabel->getText();
}
void
GNETLSTable::Column::setColumnLabelTop(const std::string& text, const std::string& tooltip) {
myTopLabel->setText(text.c_str());
myTopLabel->setTipText(tooltip.c_str());
}
void
GNETLSTable::Column::setColumnLabelBot(const std::string& text) {
myBotLabel->setText(text.c_str());
}
int
GNETLSTable::Column::getColumnMinimumWidth() {
int columnWidth = 0;
if (myType == 's') {
columnWidth = 30;
} else if (isTextFieldColumn()) {
columnWidth = myTopLabel->getFont()->getTextWidth(myTopLabel->getText().text(), myTopLabel->getText().length() + EXTRAMARGIN);
for (const auto& row : myTable->myRows) {
const auto textField = row->getCells().at(myIndex)->getTextField();
const auto textFieldWidth = textField->getFont()->getTextWidth(textField->getText().text(), textField->getText().length() + EXTRAMARGIN);
if (textFieldWidth > columnWidth) {
columnWidth = textFieldWidth;
}
}
const auto botLabelWidth = myBotLabel->getFont()->getTextWidth(myBotLabel->getText().text(), myBotLabel->getText().length() + EXTRAMARGIN);
if (botLabelWidth > columnWidth) {
columnWidth = botLabelWidth;
}
} else {
columnWidth = GUIDesignHeight;
}
return columnWidth;
}
void
GNETLSTable::Column::setColumnWidth(const int colWidth) {
if (isTextFieldColumn()) {
for (const auto& row : myTable->myRows) {
row->getCells().at(myIndex)->getTextField()->setWidth(colWidth);
}
}
myVerticalFrame->setWidth(colWidth);
myTopLabel->setWidth(colWidth);
myVerticalCellFrame->setWidth(colWidth);
myBotLabel->setWidth(colWidth);
}
bool
GNETLSTable::Column::isTextFieldColumn() const {
return ((myType == 'u') || (myType == 'f') || (myType == 'p') || (myType == 'm') || (myType == '-'));
}
GNETLSTable::Column::Column() :
myIndex(0),
myType('-') {}
GNETLSTable::Row::Row(GNETLSTable* table) :
myTable(table) {
const auto staticTooltipMenu = table->getTLSPhasesParent()->getTLSEditorParent()->getViewNet()->getViewParent()->getGNEAppWindows()->getStaticTooltipMenu();
for (int columnIndex = 0; columnIndex < (FXint)table->myColumns.size(); columnIndex++) {
const int numCells = (int)myCells.size();
switch (table->myColumns.at(columnIndex)->getType()) {
case ('s'): {
auto indexLabel = new FXLabel(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
toString(myTable->myRows.size()).c_str(), nullptr, GUIDesignLabelThickedFixed(30));
auto indexLabelBold = new FXLabel(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
toString(myTable->myRows.size()).c_str(), nullptr, GUIDesignLabelThickedFixed(30));
indexLabel->setFont(myTable->myIndexFont);
indexLabelBold->setFont(myTable->myIndexSelectedFont);
myCells.push_back(new Cell(table, indexLabel, indexLabelBold, columnIndex, numCells));
break;
}
case ('u'):
case ('f'):
case ('m'):
case ('-'): {
auto textField = new MFXTextFieldIcon(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
staticTooltipMenu, GUIIcon::EMPTY, table,
MID_GNE_TLSTABLE_TEXTFIELD, GUIDesignTextFieldTLSTable);
myCells.push_back(new Cell(table, textField, columnIndex, numCells));
break;
}
case ('p'): {
auto textField = new MFXTextFieldIcon(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
staticTooltipMenu, GUIIcon::EMPTY, table,
MID_GNE_TLSTABLE_TEXTFIELD, GUIDesignTextFieldTLSTable);
textField->setFont(myTable->myProgramFont);
myCells.push_back(new Cell(table, textField, columnIndex, numCells));
break;
}
case ('i'): {
myCells.push_back(new Cell(table, columnIndex, numCells));
break;
}
case ('d'): {
auto button = new MFXButtonTooltip(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
staticTooltipMenu, (std::string("\t") + TL("Delete phase") + std::string("\t") + TL("Delete this phase.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::REMOVE), table, MID_GNE_TLSTABLE_REMOVEPHASE, GUIDesignButtonIcon);
myCells.push_back(new Cell(table, button, columnIndex, numCells));
break;
}
case ('t'): {
auto button = new MFXButtonTooltip(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
staticTooltipMenu, (std::string("\t") + TL("Move phase up") + std::string("\t") + TL("Move this phase up.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::ARROW_UP), table, MID_GNE_TLSTABLE_MOVEUPPHASE, GUIDesignButtonIcon);
myCells.push_back(new Cell(table, button, columnIndex, numCells));
break;
}
case ('b'): {
auto button = new MFXButtonTooltip(table->myColumns.at(columnIndex)->getVerticalCellFrame(),
staticTooltipMenu, (std::string("\t") + TL("Move phase down") + std::string("\t") + TL("Move this phase down.")).c_str(),
GUIIconSubSys::getIcon(GUIIcon::ARROW_DOWN), table, MID_GNE_TLSTABLE_MOVEDOWNPHASE, GUIDesignButtonIcon);
myCells.push_back(new Cell(table, button, columnIndex, numCells));
break;
}
default:
throw ProcessError("Invalid Cell type");
}
}
}
GNETLSTable::Row::~Row() {
for (const auto& cell : myCells) {
delete cell;
}
}
std::string
GNETLSTable::Row::getText(int index) const {
if (myCells.at(index)->getTextField()) {
return myCells.at(index)->getTextField()->getText().text();
} else {
throw ProcessError("Cell doesn't have a textField");
}
}
void
GNETLSTable::Row::setText(int index, const std::string& text) const {
myCells.at(index)->getTextField()->setText(text.c_str());
}
const std::vector<GNETLSTable::Cell*>&
GNETLSTable::Row::getCells() const {
return myCells;
}
void
GNETLSTable::Row::disableButtons() {
for (const auto& cell : myCells) {
if ((cell->getType() == 'd') || (cell->getType() == 'b') || (cell->getType() == 't')) {
cell->disableButton();
}
}
}
GNETLSTable::Row::Row() {}