#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 "vehicle.h" #include #include 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 == 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 { virtual void execute(Drawable &item) override { DriverViewStatusItem &statusItem = static_cast(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(roundf(temps.brake_fl)); brakeTempFR.setTemp(roundf(temps.brake_fr)); brakeTempRL.setTemp(roundf(temps.brake_rl)); brakeTempRR.setTemp(roundf(temps.brake_rr)); invTempL.setTemp(roundf(temps.inv_l)); invTempR.setTemp(roundf(temps.inv_r)); motorTempL.setTemp(roundf(temps.mot_l)); motorTempR.setTemp(roundf(temps.mot_r)); batTempL.setTemp(roundf(temps.bat_l)); batTempR.setTemp(roundf(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(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(selectedFieldType)); field.setSelected(false); fieldTypes[selectedField] = static_cast(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); } }