Compare commits
No commits in common. "0a97a07da0a342c586abde6533fe22b049c050a2" and "938978f5d4449ba45db2a3751052472608b28f56" have entirely different histories.
0a97a07da0
...
938978f5d4
@ -1,4 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.18)
|
||||||
|
|
||||||
project("FT22 Steering Wheel Display")
|
project("FT22 Steering Wheel Display")
|
||||||
|
|
||||||
@ -60,9 +60,6 @@ add_executable(
|
|||||||
src/AMI.cpp
|
src/AMI.cpp
|
||||||
src/widgets.cpp
|
src/widgets.cpp
|
||||||
src/util.cpp
|
src/util.cpp
|
||||||
src/DriverView.cpp
|
|
||||||
src/BaseDataSource.cpp
|
|
||||||
src/DemoDataSource.cpp
|
|
||||||
)
|
)
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
stw-display PUBLIC
|
stw-display PUBLIC
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include "AMI.h"
|
#include "AMI.h"
|
||||||
#include "AppState.h"
|
#include "AppState.h"
|
||||||
#include "DriverView.h"
|
|
||||||
#include "MissionSelect.h"
|
#include "MissionSelect.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
|
||||||
@ -45,7 +44,6 @@ private:
|
|||||||
std::unique_ptr<AppState> state;
|
std::unique_ptr<AppState> state;
|
||||||
std::unique_ptr<MissionSelect> mission_select;
|
std::unique_ptr<MissionSelect> mission_select;
|
||||||
std::unique_ptr<AMI> ami;
|
std::unique_ptr<AMI> ami;
|
||||||
std::unique_ptr<DriverView> driver_view;
|
|
||||||
|
|
||||||
bool running;
|
bool running;
|
||||||
|
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "DemoDataSource.h"
|
|
||||||
|
|
||||||
#include <fmt/ostream.h>
|
#include <fmt/ostream.h>
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
@ -34,7 +32,6 @@ public:
|
|||||||
|
|
||||||
AppView get_view() const;
|
AppView get_view() const;
|
||||||
Mission get_mission() const;
|
Mission get_mission() const;
|
||||||
DemoDataSource get_data_source() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void unmarshal_mission_select(uint8_t* data);
|
void unmarshal_mission_select(uint8_t* data);
|
||||||
@ -48,7 +45,6 @@ private:
|
|||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
friend class KeyboardHandler;
|
friend class KeyboardHandler;
|
||||||
DemoDataSource data_source;
|
|
||||||
#endif // !NDEBUG
|
#endif // !NDEBUG
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
class BaseDataSource {
|
|
||||||
public:
|
|
||||||
double get_speed(); // in km/h
|
|
||||||
double get_brake_balance(); // 0.0 - 1.0
|
|
||||||
double get_hv_voltage(); // in V
|
|
||||||
double get_hv_voltage_ratio(); // 0.0 - 1.0
|
|
||||||
double get_lv_voltage(); // in V
|
|
||||||
double get_battery_temperature(); // in °C
|
|
||||||
double get_throttle_ratio(); // 0.0 - 1.0
|
|
||||||
double get_brake_pressure_front_bar(); // in bar
|
|
||||||
double get_brake_pressure_rear_bar(); // in bar
|
|
||||||
|
|
||||||
bool brake_balance_change_is_recent(); // true if the last change was less
|
|
||||||
// than 1 second ago
|
|
||||||
|
|
||||||
virtual void poll() = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void set_brake_balance(double value);
|
|
||||||
|
|
||||||
double speed;
|
|
||||||
double brake_balance;
|
|
||||||
double hv_voltage;
|
|
||||||
double hv_voltage_ratio;
|
|
||||||
double lv_voltage;
|
|
||||||
double battery_temperature;
|
|
||||||
double throttle_ratio;
|
|
||||||
double brake_pressure_front_bar;
|
|
||||||
double brake_pressure_rear_bar;
|
|
||||||
|
|
||||||
int time_of_last_brake_balance_change;
|
|
||||||
};
|
|
@ -1,13 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "BaseDataSource.h"
|
|
||||||
|
|
||||||
class DemoDataSource final : public BaseDataSource {
|
|
||||||
public:
|
|
||||||
DemoDataSource();
|
|
||||||
~DemoDataSource();
|
|
||||||
|
|
||||||
void poll() override;
|
|
||||||
void bump_brake_balance_up();
|
|
||||||
void bump_brake_balance_down();
|
|
||||||
};
|
|
@ -1,30 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "View.h"
|
|
||||||
#include "defines.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "widgets.h"
|
|
||||||
|
|
||||||
class DriverView final : public View {
|
|
||||||
public:
|
|
||||||
DriverView(SDL_Renderer* renderer);
|
|
||||||
~DriverView();
|
|
||||||
|
|
||||||
void draw(const AppState& state) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
TTF_Font* font_large;
|
|
||||||
TTF_Font* font_detail;
|
|
||||||
TTF_Font* font_tiny;
|
|
||||||
TTF_Font* font_giant;
|
|
||||||
TTF_Font* font_medium;
|
|
||||||
std::unique_ptr<TextWidget> speed_widget;
|
|
||||||
std::unique_ptr<TextWidget> speed_hint_widget;
|
|
||||||
|
|
||||||
std::unique_ptr<TextWidget> brake_balance_widget;
|
|
||||||
std::unique_ptr<TextWidget> brake_balance_hint_widget;
|
|
||||||
|
|
||||||
std::unique_ptr<TextWidget> general_info_widget;
|
|
||||||
|
|
||||||
std::unique_ptr<TextWidget> focus_widget;
|
|
||||||
std::unique_ptr<TextWidget> focus_hint_widget;
|
|
||||||
};
|
|
@ -79,13 +79,12 @@ public:
|
|||||||
~TextWidget();
|
~TextWidget();
|
||||||
|
|
||||||
void update_text(const std::string& new_text);
|
void update_text(const std::string& new_text);
|
||||||
void set_wrap_width(int width);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TTF_Font* font;
|
TTF_Font* font;
|
||||||
|
|
||||||
std::string text;
|
std::string text;
|
||||||
int wrap_width = -1; // -1 means no wrapping (default behavior)
|
|
||||||
SDL_Texture* generate_text(const std::string& text);
|
SDL_Texture* generate_text(const std::string& text);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
81
src/App.cpp
81
src/App.cpp
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
#include "AMI.h"
|
#include "AMI.h"
|
||||||
#include "AppState.h"
|
#include "AppState.h"
|
||||||
#include "DemoDataSource.h"
|
|
||||||
#include "DriverView.h"
|
|
||||||
#include "MissionSelect.h"
|
#include "MissionSelect.h"
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
|
|
||||||
@ -17,7 +15,6 @@
|
|||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@ -63,11 +60,6 @@ void App::init_state() {
|
|||||||
int App::run() {
|
int App::run() {
|
||||||
mission_select = std::make_unique<MissionSelect>(renderer);
|
mission_select = std::make_unique<MissionSelect>(renderer);
|
||||||
ami = std::make_unique<AMI>(renderer);
|
ami = std::make_unique<AMI>(renderer);
|
||||||
driver_view = std::make_unique<DriverView>(renderer);
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
std::cout << "Change brake balance with W (+) and S (-)" << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
running = true;
|
running = true;
|
||||||
|
|
||||||
@ -118,9 +110,6 @@ void App::render() {
|
|||||||
case AppView::AMI:
|
case AppView::AMI:
|
||||||
ami->draw(*state);
|
ami->draw(*state);
|
||||||
break;
|
break;
|
||||||
case AppView::DRIVER:
|
|
||||||
driver_view->draw(*state);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error(fmt::format("Unknown view: {}", view));
|
throw std::runtime_error(fmt::format("Unknown view: {}", view));
|
||||||
}
|
}
|
||||||
@ -149,51 +138,39 @@ SDLManager::~SDLManager() {
|
|||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Handle key presses
|
|
||||||
*/
|
|
||||||
void KeyboardHandler::handle_keyup(const SDL_Event& ev, AppState& state) {
|
void KeyboardHandler::handle_keyup(const SDL_Event& ev, AppState& state) {
|
||||||
auto pressed_key = ev.key.keysym.sym;
|
switch (ev.key.keysym.sym) {
|
||||||
|
case SDLK_DOWN:
|
||||||
// we are in the first screen (mission select)
|
case SDLK_RIGHT:
|
||||||
if (state.view == AppView::MISSION_SELECT) {
|
|
||||||
|
|
||||||
// handle change selected mission
|
|
||||||
if (pressed_key == SDLK_DOWN || pressed_key == SDLK_RIGHT) {
|
|
||||||
auto new_mission = static_cast<int>(state.mission) + 1;
|
|
||||||
if (new_mission > 7) {
|
|
||||||
new_mission = 1;
|
|
||||||
}
|
|
||||||
state.mission = static_cast<Mission>(new_mission);
|
|
||||||
} else if (pressed_key == SDLK_UP || pressed_key == SDLK_LEFT) {
|
|
||||||
auto new_mission = static_cast<int>(state.mission) - 1;
|
|
||||||
if (new_mission < 1) {
|
|
||||||
new_mission = 7;
|
|
||||||
}
|
|
||||||
state.mission = static_cast<Mission>(new_mission);
|
|
||||||
|
|
||||||
// commit mission selection
|
|
||||||
} else if (pressed_key == SDLK_RETURN) {
|
|
||||||
|
|
||||||
if (state.mission == Mission::MANUAL) {
|
if (state.mission == Mission::MANUAL) {
|
||||||
state.view = AppView::DRIVER;
|
state.mission = Mission::ACCELERATION;
|
||||||
} else {
|
} else {
|
||||||
|
state.mission = static_cast<Mission>(static_cast<int>(state.mission) + 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDLK_UP:
|
||||||
|
case SDLK_LEFT:
|
||||||
|
if (state.mission == Mission::NONE ||
|
||||||
|
state.mission == Mission::ACCELERATION) {
|
||||||
|
state.mission = Mission::MANUAL;
|
||||||
|
} else {
|
||||||
|
state.mission = static_cast<Mission>(static_cast<int>(state.mission) - 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDLK_RETURN:
|
||||||
|
case SDLK_KP_ENTER:
|
||||||
|
switch (state.view) {
|
||||||
|
case AppView::MISSION_SELECT:
|
||||||
state.view = AppView::AMI;
|
state.view = AppView::AMI;
|
||||||
|
break;
|
||||||
|
case AppView::AMI:
|
||||||
|
case AppView::DRIVER:
|
||||||
|
case AppView::TESTING:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error(fmt::format("Unknown view: {}", state.view));
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
}
|
// We can just ignore other keypresses, so no need for a default clause
|
||||||
|
|
||||||
// go back to mission select
|
|
||||||
if (state.view == AppView::AMI || state.view == AppView::DRIVER) {
|
|
||||||
if (pressed_key == SDLK_ESCAPE) {
|
|
||||||
state.view = AppView::MISSION_SELECT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle mock brake balance change
|
|
||||||
if (pressed_key == SDLK_w) {
|
|
||||||
state.data_source.bump_brake_balance_up();
|
|
||||||
} else if (pressed_key == SDLK_s) {
|
|
||||||
state.data_source.bump_brake_balance_down();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -76,7 +76,6 @@ AppState::~AppState() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AppState::poll() {
|
void AppState::poll() {
|
||||||
data_source.poll();
|
|
||||||
if (!i2c_dev_file) {
|
if (!i2c_dev_file) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -114,5 +113,3 @@ void AppState::unmarshal_ami(uint8_t* data) {
|
|||||||
mission = static_cast<Mission>(data[1]);
|
mission = static_cast<Mission>(data[1]);
|
||||||
spdlog::info("Mission after poll: {}", mission);
|
spdlog::info("Mission after poll: {}", mission);
|
||||||
}
|
}
|
||||||
|
|
||||||
DemoDataSource AppState::get_data_source() const { return data_source; }
|
|
@ -1,35 +0,0 @@
|
|||||||
#include "BaseDataSource.h"
|
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
double BaseDataSource::get_speed() { return speed; }
|
|
||||||
|
|
||||||
double BaseDataSource::get_brake_balance() { return brake_balance; }
|
|
||||||
|
|
||||||
double BaseDataSource::get_hv_voltage() { return hv_voltage; }
|
|
||||||
|
|
||||||
double BaseDataSource::get_hv_voltage_ratio() { return hv_voltage_ratio; }
|
|
||||||
|
|
||||||
double BaseDataSource::get_lv_voltage() { return lv_voltage; }
|
|
||||||
|
|
||||||
double BaseDataSource::get_battery_temperature() { return battery_temperature; }
|
|
||||||
|
|
||||||
double BaseDataSource::get_throttle_ratio() { return throttle_ratio; }
|
|
||||||
|
|
||||||
double BaseDataSource::get_brake_pressure_front_bar() {
|
|
||||||
return brake_pressure_front_bar;
|
|
||||||
}
|
|
||||||
|
|
||||||
double BaseDataSource::get_brake_pressure_rear_bar() {
|
|
||||||
return brake_pressure_rear_bar;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseDataSource::set_brake_balance(double value) {
|
|
||||||
brake_balance = value;
|
|
||||||
time_of_last_brake_balance_change = SDL_GetTicks();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BaseDataSource::brake_balance_change_is_recent() {
|
|
||||||
|
|
||||||
return time_of_last_brake_balance_change != 0 &&
|
|
||||||
SDL_GetTicks() - time_of_last_brake_balance_change < 500;
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
#include "DemoDataSource.h"
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include <iostream>
|
|
||||||
DemoDataSource::DemoDataSource() {
|
|
||||||
brake_balance = 0.5;
|
|
||||||
|
|
||||||
lv_voltage = 13.1;
|
|
||||||
battery_temperature = 20.1;
|
|
||||||
throttle_ratio = 0.01;
|
|
||||||
brake_pressure_front_bar = 1;
|
|
||||||
brake_pressure_rear_bar = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
DemoDataSource::~DemoDataSource() {}
|
|
||||||
|
|
||||||
void DemoDataSource::poll() {
|
|
||||||
int min_voltage = 150;
|
|
||||||
int max_voltage = 480;
|
|
||||||
static int count = 0;
|
|
||||||
count++;
|
|
||||||
hv_voltage = 220.1 + std::cos(count / 1000.0 + 2) * 50;
|
|
||||||
hv_voltage_ratio = (hv_voltage - min_voltage) / (max_voltage - min_voltage);
|
|
||||||
speed = 10 + std::sin(count / 100.0) * 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DemoDataSource::bump_brake_balance_up() {
|
|
||||||
set_brake_balance(brake_balance + 0.01);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DemoDataSource::bump_brake_balance_down() {
|
|
||||||
set_brake_balance(brake_balance - 0.01);
|
|
||||||
}
|
|
@ -1,131 +0,0 @@
|
|||||||
#include "DriverView.h"
|
|
||||||
|
|
||||||
#include "DemoDataSource.h"
|
|
||||||
#include "defines.h"
|
|
||||||
|
|
||||||
#include <fmt/format.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#define LARGE_FONT_SIZE_POINTS 170
|
|
||||||
#define GIANT_FONT_SIZE_POINTS 250
|
|
||||||
#define MEDIUM_FONT_SIZE_POINTS 50
|
|
||||||
#define SOC_BAR_HEIGHT 80
|
|
||||||
#define SPEED_TEXT_X 22
|
|
||||||
#define SPEED_TEXT_Y 50
|
|
||||||
|
|
||||||
DriverView::DriverView(SDL_Renderer* renderer)
|
|
||||||
: View{renderer}, font_large{util::load_font("resources/Avenir-Book.ttf",
|
|
||||||
LARGE_FONT_SIZE_POINTS)},
|
|
||||||
font_detail{util::load_font("resources/Avenir-Book.ttf", 20)},
|
|
||||||
font_tiny{util::load_font("resources/Avenir-Book.ttf", 15)},
|
|
||||||
font_giant{
|
|
||||||
util::load_font("resources/Avenir-Book.ttf", GIANT_FONT_SIZE_POINTS)},
|
|
||||||
font_medium{util::load_font("resources/Avenir-Book.ttf",
|
|
||||||
MEDIUM_FONT_SIZE_POINTS)} {
|
|
||||||
speed_widget = std::make_unique<TextWidget>(renderer, font_large, "");
|
|
||||||
speed_widget->set_position(SPEED_TEXT_X, SPEED_TEXT_Y);
|
|
||||||
speed_widget->set_alignment(Alignment::CENTER, Alignment::TOP);
|
|
||||||
|
|
||||||
speed_hint_widget = std::make_unique<TextWidget>(renderer, font_tiny, "SPD");
|
|
||||||
speed_hint_widget->set_position(20, 210);
|
|
||||||
speed_hint_widget->set_alignment(Alignment::CENTER, Alignment::TOP);
|
|
||||||
|
|
||||||
brake_balance_widget = std::make_unique<TextWidget>(renderer, font_large, "");
|
|
||||||
brake_balance_widget->set_position(SPEED_TEXT_X + SCREEN_WIDTH / 2,
|
|
||||||
SPEED_TEXT_Y);
|
|
||||||
brake_balance_widget->set_alignment(Alignment::CENTER, Alignment::TOP);
|
|
||||||
brake_balance_hint_widget =
|
|
||||||
std::make_unique<TextWidget>(renderer, font_tiny, "BB");
|
|
||||||
brake_balance_hint_widget->set_position(20 + SCREEN_WIDTH / 2, 210);
|
|
||||||
brake_balance_hint_widget->set_alignment(Alignment::CENTER, Alignment::TOP);
|
|
||||||
|
|
||||||
general_info_widget = std::make_unique<TextWidget>(renderer, font_detail, "");
|
|
||||||
general_info_widget->set_position(SPEED_TEXT_X, SPEED_TEXT_Y + 200);
|
|
||||||
general_info_widget->set_alignment(Alignment::LEFT, Alignment::TOP);
|
|
||||||
general_info_widget->set_wrap_width(SCREEN_WIDTH - 50);
|
|
||||||
|
|
||||||
focus_widget = std::make_unique<TextWidget>(renderer, font_giant, "");
|
|
||||||
focus_widget->set_position(120, 50);
|
|
||||||
focus_widget->set_alignment(Alignment::LEFT, Alignment::TOP);
|
|
||||||
focus_hint_widget = std::make_unique<TextWidget>(renderer, font_medium, "");
|
|
||||||
focus_hint_widget->set_position(120, 30);
|
|
||||||
// focus_hint_widget->set_alignment(Alignment::CENTER, Alignment::CENTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
DriverView::~DriverView() {
|
|
||||||
|
|
||||||
TTF_CloseFont(font_medium);
|
|
||||||
TTF_CloseFont(font_large);
|
|
||||||
TTF_CloseFont(font_detail);
|
|
||||||
TTF_CloseFont(font_tiny);
|
|
||||||
TTF_CloseFont(font_giant);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DriverView::draw(const AppState& state) {
|
|
||||||
auto ds = state.get_data_source();
|
|
||||||
auto hv_ratio = ds.get_hv_voltage_ratio();
|
|
||||||
SDL_Rect rect;
|
|
||||||
rect.x = 0;
|
|
||||||
rect.y = 0;
|
|
||||||
rect.w = SCREEN_WIDTH;
|
|
||||||
rect.h = SCREEN_HEIGHT;
|
|
||||||
|
|
||||||
static auto hv_low = false;
|
|
||||||
// hysteresis for the hv voltage low
|
|
||||||
if (hv_ratio < 0.15) {
|
|
||||||
hv_low = true;
|
|
||||||
} else if (hv_ratio > 0.2) {
|
|
||||||
hv_low = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int red = hv_low ? 0xa0 : 0x30;
|
|
||||||
SDL_SetRenderDrawColor(renderer, red, 0x30, 0x30, 255);
|
|
||||||
SDL_RenderFillRect(renderer, &rect);
|
|
||||||
|
|
||||||
auto brake_balance_text = fmt::format("{:.0f}", ds.get_brake_balance() * 100);
|
|
||||||
|
|
||||||
if (ds.brake_balance_change_is_recent()) {
|
|
||||||
SDL_SetRenderDrawColor(renderer, 255, 69, 100, 255);
|
|
||||||
SDL_RenderFillRect(renderer, &rect);
|
|
||||||
focus_widget->update_text(brake_balance_text);
|
|
||||||
focus_widget->draw();
|
|
||||||
focus_hint_widget->update_text("BBAL");
|
|
||||||
focus_hint_widget->draw();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
rect.w = SCREEN_WIDTH * hv_ratio;
|
|
||||||
rect.h = SOC_BAR_HEIGHT;
|
|
||||||
SDL_SetRenderDrawColor(renderer, 76, 255, 0, 255);
|
|
||||||
SDL_RenderFillRect(renderer, &rect);
|
|
||||||
|
|
||||||
speed_widget->update_text(fmt::format("{:02.0f}", ds.get_speed()));
|
|
||||||
speed_widget->draw();
|
|
||||||
speed_hint_widget->draw();
|
|
||||||
|
|
||||||
brake_balance_widget->update_text(brake_balance_text);
|
|
||||||
|
|
||||||
brake_balance_widget->draw();
|
|
||||||
brake_balance_hint_widget->draw();
|
|
||||||
|
|
||||||
// draw rectangles around the speed and brake balance widgets
|
|
||||||
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 255);
|
|
||||||
rect.x = 0;
|
|
||||||
rect.y = SOC_BAR_HEIGHT;
|
|
||||||
rect.w = SCREEN_WIDTH / 2;
|
|
||||||
rect.h = 150;
|
|
||||||
SDL_RenderDrawRect(renderer, &rect);
|
|
||||||
rect.x = SCREEN_WIDTH / 2;
|
|
||||||
SDL_RenderDrawRect(renderer, &rect);
|
|
||||||
|
|
||||||
auto general_string = fmt::format(
|
|
||||||
"HV: {:.0f}V | LV: {:.1f}V | B_TEMP: {:.1f}C\nAPPS: {:.0f}% | BPF: "
|
|
||||||
"{:.0f} bar | BPR: {:.0f} bar",
|
|
||||||
ds.get_hv_voltage(), ds.get_lv_voltage(), ds.get_battery_temperature(),
|
|
||||||
ds.get_throttle_ratio() * 100, ds.get_brake_pressure_front_bar(),
|
|
||||||
ds.get_brake_pressure_rear_bar());
|
|
||||||
|
|
||||||
general_info_widget->update_text(general_string);
|
|
||||||
general_info_widget->draw();
|
|
||||||
}
|
|
@ -1,7 +1,6 @@
|
|||||||
#include "MissionSelect.h"
|
#include "MissionSelect.h"
|
||||||
|
|
||||||
#include "AppState.h"
|
#include "AppState.h"
|
||||||
#include "DriverView.h"
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -167,13 +167,8 @@ void TextWidget::update_text(const std::string& new_text) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SDL_Texture* TextWidget::generate_text(const std::string& text) {
|
SDL_Texture* TextWidget::generate_text(const std::string& text) {
|
||||||
SDL_Surface* surf;
|
SDL_Surface* surf =
|
||||||
if (wrap_width == -1) {
|
TTF_RenderText_Solid(font, text.c_str(), {0xFF, 0xFF, 0XFF, 0xFF});
|
||||||
surf = TTF_RenderText_Blended(font, text.c_str(), {0xFF, 0xFF, 0XFF, 0xFF});
|
|
||||||
} else {
|
|
||||||
surf = TTF_RenderText_Blended_Wrapped(font, text.c_str(),
|
|
||||||
{0xFF, 0xFF, 0XFF, 0xFF}, wrap_width);
|
|
||||||
}
|
|
||||||
if (surf == nullptr) {
|
if (surf == nullptr) {
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
fmt::format("Unable to render text surface: {}", TTF_GetError()));
|
fmt::format("Unable to render text surface: {}", TTF_GetError()));
|
||||||
@ -186,8 +181,6 @@ SDL_Texture* TextWidget::generate_text(const std::string& text) {
|
|||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextWidget::set_wrap_width(int width) { wrap_width = width; }
|
|
||||||
|
|
||||||
ListWidget::ListWidget(SDL_Renderer* renderer, int element_height,
|
ListWidget::ListWidget(SDL_Renderer* renderer, int element_height,
|
||||||
Alignment element_alignment)
|
Alignment element_alignment)
|
||||||
: Widget{renderer}, element_height{element_height},
|
: Widget{renderer}, element_height{element_height},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user