stw24/TouchGFX/gui/src/driverview_screen/DriverViewView.cpp

256 lines
7.9 KiB
C++

#include "gui/common/NamedField.hpp"
#include "gui/containers/DriverViewField.hpp"
#include "gui/containers/DriverViewStatusItem.hpp"
#include "gui/driverview_screen/DriverViewPresenter.hpp"
#include "texts/TextKeysAndLanguages.hpp"
#include "touchgfx/Callback.hpp"
#include "touchgfx/Drawable.hpp"
#include "touchgfx/Unicode.hpp"
#include <gui/driverview_screen/DriverViewView.hpp>
#include <cmath>
#include <cstddef>
#include "vehicle_state.h"
DriverViewView::DriverViewView()
: fieldTypes{DF_MinCellVolt, DF_Speed, DF_TSCurrent} {}
void DriverViewView::setupScreen() {
DriverViewViewBase::setupScreen();
for (size_t i = 0; i < NUM_FIELDS; i++) {
getField(i).setType(fieldTypes[i]);
}
statusTS_R2D.setType(DriverViewStatusType::TS_R2D);
statusAMS.setType(DriverViewStatusType::AMS);
statusSDC.setType(DriverViewStatusType::SDC);
statusSCS.setType(DriverViewStatusType::SCS);
statusPDU.setType(DriverViewStatusType::PDU);
statusINV.setType(DriverViewStatusType::INV);
statusLV.setType(DriverViewStatusType::LV);
fieldTypeSelection.setNumberOfItems(DataFieldType_COUNT);
// int tireThresholds[4] = {35, 40, 50, 60};
// tireTempFL.setTempThresholds(tireThresholds);
// tireTempFR.setTempThresholds(tireThresholds);
// tireTempRL.setTempThresholds(tireThresholds);
// tireTempRR.setTempThresholds(tireThresholds);
int brakeThresholds[4] = {100, 150, 200, 250};
brakeTempFL.setSmallText(true);
brakeTempFL.setTempThresholds(brakeThresholds);
brakeTempFR.setSmallText(true);
brakeTempFR.setTempThresholds(brakeThresholds);
brakeTempRL.setSmallText(true);
brakeTempRL.setTempThresholds(brakeThresholds);
brakeTempRR.setSmallText(true);
brakeTempRR.setTempThresholds(brakeThresholds);
int invThresholds[4] = {30, 40, 50, 60};
invTempL.setTempThresholds(invThresholds);
invTempR.setTempThresholds(invThresholds);
int motorThresholds[4] = {30, 45, 60, 80};
motorTempL.setTempThresholds(motorThresholds);
motorTempR.setTempThresholds(motorThresholds);
int batThresholds[4] = {30, 40, 50, 55};
batTempL.setTempThresholds(batThresholds);
batTempR.setTempThresholds(batThresholds);
}
void DriverViewView::tearDownScreen() { DriverViewViewBase::tearDownScreen(); }
void DriverViewView::fieldTypeSelectionUpdateItem(
DriverViewFieldSelection &item, int16_t itemIndex) {
item.setName(dataFieldDescs[itemIndex].title);
item.setSelected(itemIndex == (int)selectedFieldType);
}
void DriverViewView::setFieldType(size_t i, DataFieldType type) {
getField(i).setType(type);
}
void DriverViewView::updateFieldValues() {
for (size_t i = 0; i < NUM_FIELDS; i++) {
getField(i).updateValue();
}
}
class StatusItemUpdateCallback
: public touchgfx::GenericCallback<touchgfx::Drawable &> {
virtual void execute(Drawable &item) override {
DriverViewStatusItem &statusItem =
static_cast<DriverViewStatusItem &>(item);
statusItem.update();
}
virtual bool isValid() const override { return true; }
};
void DriverViewView::updateStatusItems() {
StatusItemUpdateCallback cb;
statusItems.forEachChild(&cb);
}
void DriverViewView::setTemps(const Temperatures &temps) {
brakeTempFL.setTemp(std::round(temps.brake_fl));
brakeTempFR.setTemp(std::round(temps.brake_fr));
brakeTempRL.setTemp(std::round(temps.brake_rl));
brakeTempRR.setTemp(std::round(temps.brake_rr));
invTempL.setTemp(std::round(temps.inv_l));
invTempR.setTemp(std::round(temps.inv_r));
motorTempL.setTemp(std::round(temps.mot_l));
motorTempR.setTemp(std::round(temps.mot_r));
batTempL.setTemp(std::round(temps.bat_l));
batTempR.setTemp(std::round(temps.bat_r));
}
void DriverViewView::setTSSoC(uint8_t soc) {
tsSoC.setValue(soc);
tsSoC.invalidate();
}
void DriverViewView::setProgress(bool active, DriverViewProgressType type,
float progress) {
if (active) {
switch (type) {
case DriverViewProgressType::PRECHARGE:
prechargeLabel.setVisible(true);
r2dLabel.setVisible(false);
r2dProgressLabel.setVisible(false);
progressBar.setValue(progress);
break;
case DriverViewProgressType::R2D:
const char *progText = static_cast<const char *>(get_r2dprog_text());
touchgfx::Unicode::strncpy(r2dProgBuffer, progText,
sizeof(r2dProgBuffer) /
sizeof(*r2dProgBuffer));
r2dProgressLabel.setWildcard(r2dProgBuffer);
r2dProgressLabel.setVisible(true);
r2dLabel.setVisible(true);
prechargeLabel.setVisible(false);
progress = progress - R2D_TSACTIVE;
progressBar.setValue(progress * 100 / 5);
break;
}
prechargeLabel.invalidate();
r2dProgressLabel.invalidate();
r2dLabel.invalidate();
progressBar.setVisible(true);
progressBar.invalidate();
} else if (progressBar.isVisible()) {
prechargeLabel.setVisible(false);
prechargeLabel.invalidate();
r2dLabel.setVisible(false);
r2dLabel.invalidate();
r2dProgressLabel.setVisible(false);
r2dProgressLabel.invalidate();
progressBar.setVisible(false);
progressBar.invalidate();
}
}
void DriverViewView::showAMSError() {
errorPopup.setVisible(true);
errorPopup.showAMSError();
errorPopup.invalidate();
}
void DriverViewView::clearErrorPopup() {
errorPopup.setVisible(false);
errorPopup.invalidate();
}
void DriverViewView::selectNextField() {
if (!fieldTypeSelection.isVisible()) {
fieldTypeSelection.setVisible(true);
fieldTypeSelection.invalidate();
updateSelectedField(0);
} else {
updateSelectedField((selectedField + 1) % NUM_FIELDS);
}
}
void DriverViewView::selectPrevField() {
if (!fieldTypeSelection.isVisible()) {
fieldTypeSelection.setVisible(true);
fieldTypeSelection.invalidate();
updateSelectedField(NUM_FIELDS - 1);
} else {
if (selectedField == 0) {
updateSelectedField(NUM_FIELDS - 1);
} else {
updateSelectedField(selectedField - 1);
}
}
}
void DriverViewView::selectNextFieldType() {
if (!fieldTypeSelection.isVisible()) {
return;
}
updateSelectedFieldType((selectedFieldType + 1) % DataFieldType_COUNT);
}
void DriverViewView::selectPrevFieldType() {
if (!fieldTypeSelection.isVisible()) {
return;
}
if (selectedFieldType == 0) {
updateSelectedFieldType(DataFieldType_COUNT - 1);
} else {
updateSelectedFieldType(selectedFieldType - 1);
}
}
void DriverViewView::confirmFieldType() {
if (!fieldTypeSelection.isVisible()) {
return;
}
DriverViewField &field = getField(selectedField);
presenter->setFieldType(selectedField,
static_cast<DataFieldType>(selectedFieldType));
field.setSelected(false);
fieldTypes[selectedField] = static_cast<DataFieldType>(selectedFieldType);
fieldTypeSelection.setVisible(false);
fieldTypeSelection.invalidate();
}
DriverViewField &DriverViewView::getField(size_t i) {
switch (i) {
case 0:
return field1;
case 1:
return field2;
default:
return field3;
}
}
void DriverViewView::updateSelectedField(size_t selected) {
getField(selectedField).setSelected(false);
DriverViewField &field = getField(selected);
field.setSelected(true);
fieldTypeSelection.moveTo(field.getX(), fieldTypeSelection.getY());
fieldTypeSelection.invalidate();
selectedField = selected;
updateSelectedFieldType(fieldTypes[selectedField], false);
}
void DriverViewView::updateSelectedFieldType(size_t selected, bool animate) {
size_t previousSelected = selectedFieldType;
selectedFieldType = selected;
// Trigger update of the background
fieldTypeSelection.itemChanged(previousSelected);
fieldTypeSelection.itemChanged(selectedFieldType);
int16_t steps = animate ? 2 : 0;
if (selectedFieldType == 0) {
// Just animating to 0 looks very broken when scrolling forwards. Animating
// to DataFieldType_COUNT looks good in both directions.
fieldTypeSelection.animateToItem(DataFieldType_COUNT, steps);
} else {
fieldTypeSelection.animateToItem(selectedFieldType, steps);
}
}