Merge pull request #91 from Brod8362/simdisplay
Improve UI for the status window
This commit is contained in:
commit
80cacdd97a
6 changed files with 107 additions and 18 deletions
|
@ -325,6 +325,10 @@ endif()
|
||||||
|
|
||||||
target_include_directories(infinisim PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/gif-h")
|
target_include_directories(infinisim PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/gif-h")
|
||||||
|
|
||||||
|
# embedd background image for the status window to use
|
||||||
|
add_subdirectory(img)
|
||||||
|
add_dependencies(infinisim infinisim_img_background)
|
||||||
|
|
||||||
install(TARGETS infinisim DESTINATION bin)
|
install(TARGETS infinisim DESTINATION bin)
|
||||||
|
|
||||||
# helper library to manipulate littlefs raw image
|
# helper library to manipulate littlefs raw image
|
||||||
|
|
26
img/CMakeLists.txt
Normal file
26
img/CMakeLists.txt
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
message(STATUS "folder img: converting background.bmp to C file to include in binary")
|
||||||
|
|
||||||
|
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12)
|
||||||
|
# FindPython3 module introduces with CMake 3.12
|
||||||
|
# https://cmake.org/cmake/help/latest/module/FindPython3.html
|
||||||
|
find_package(Python3 REQUIRED)
|
||||||
|
else()
|
||||||
|
set(Python3_EXECUTABLE "python")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(bmp_file ${CMAKE_CURRENT_SOURCE_DIR}/sim_background.bmp)
|
||||||
|
set(out_file ${CMAKE_CURRENT_BINARY_DIR}/sim_background.h)
|
||||||
|
# call python script to convert image to c file
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${out_file}
|
||||||
|
COMMAND "${Python3_EXECUTABLE}" ${CMAKE_CURRENT_SOURCE_DIR}/convert_bmp_to_header.py
|
||||||
|
${bmp_file}
|
||||||
|
--var-name "SIM_BACKGROUND"
|
||||||
|
--output ${out_file}
|
||||||
|
DEPENDS ${bmp_file}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
)
|
||||||
|
# add target that can be added as dependency to infinisim target to trigger creation of C-file
|
||||||
|
add_custom_target(infinisim_img_background
|
||||||
|
DEPENDS ${out_file}
|
||||||
|
)
|
21
img/convert_bmp_to_header.py
Executable file
21
img/convert_bmp_to_header.py
Executable file
|
@ -0,0 +1,21 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
|
||||||
|
parser.add_argument("bmp",
|
||||||
|
help="Path to bmp to convert to C header file")
|
||||||
|
parser.add_argument("--var-name",
|
||||||
|
help="name of the variable to make the bmp data available",
|
||||||
|
default="IMAGE_DATA")
|
||||||
|
parser.add_argument("-o", "--output",
|
||||||
|
help="Path where to create C header file",
|
||||||
|
required=True)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
with open(args.output, "w", encoding="utf-8") as f:
|
||||||
|
# conversion script based on:
|
||||||
|
# https://stackoverflow.com/questions/18422123/sdl-embed-image-inside-program-executable
|
||||||
|
f.write("static const unsigned char {:s}[] = {{{:s}}};".format(
|
||||||
|
args.var_name,
|
||||||
|
",".join(str(b) for b in open(args.bmp, "rb").read())))
|
BIN
img/sim_background.bmp
Normal file
BIN
img/sim_background.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 225 KiB |
BIN
img/sim_background.xcf
Normal file
BIN
img/sim_background.xcf
Normal file
Binary file not shown.
74
main.cpp
74
main.cpp
|
@ -69,6 +69,8 @@
|
||||||
#endif
|
#endif
|
||||||
#include <gif.h>
|
#include <gif.h>
|
||||||
|
|
||||||
|
#include "img/sim_background.h" // provides variable SIM_BACKGROUND
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
*********************/
|
*********************/
|
||||||
|
@ -426,6 +428,18 @@ public:
|
||||||
init_NRF_WDT();
|
init_NRF_WDT();
|
||||||
init_NRF_POWER();
|
init_NRF_POWER();
|
||||||
|
|
||||||
|
// Attempt to load background BMP from memory for the status display window
|
||||||
|
const size_t SIM_BACKGROUND_size = sizeof(SIM_BACKGROUND);
|
||||||
|
SDL_RWops *rw = SDL_RWFromMem((void*)SIM_BACKGROUND, SIM_BACKGROUND_size);
|
||||||
|
SDL_Surface* simDisplayBgRaw = SDL_LoadBMP_RW(rw, 1);
|
||||||
|
if (simDisplayBgRaw == NULL) {
|
||||||
|
printf("Failed to load sim background image: %s\n", SDL_GetError());
|
||||||
|
} else {
|
||||||
|
// convert the loaded image into a texture
|
||||||
|
simDisplayTexture = SDL_CreateTextureFromSurface(renderer, simDisplayBgRaw);
|
||||||
|
SDL_FreeSurface(simDisplayBgRaw);
|
||||||
|
simDisplayBgRaw = NULL;
|
||||||
|
}
|
||||||
motorController.Init();
|
motorController.Init();
|
||||||
settingsController.Init();
|
settingsController.Init();
|
||||||
|
|
||||||
|
@ -444,6 +458,9 @@ public:
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
~Framework(){
|
~Framework(){
|
||||||
|
if (simDisplayTexture != NULL) {
|
||||||
|
SDL_DestroyTexture(simDisplayTexture);
|
||||||
|
}
|
||||||
SDL_DestroyRenderer(renderer);
|
SDL_DestroyRenderer(renderer);
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
@ -486,6 +503,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void refresh() {
|
void refresh() {
|
||||||
|
// left edge for all "bubbles" (circles)
|
||||||
|
constexpr const int bubbleLeftEdge = 65;
|
||||||
// always refresh the LVGL screen
|
// always refresh the LVGL screen
|
||||||
this->refresh_screen();
|
this->refresh_screen();
|
||||||
|
|
||||||
|
@ -494,9 +513,13 @@ public:
|
||||||
}
|
}
|
||||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(renderer);
|
||||||
|
// Render the background if it was able to be loaded
|
||||||
|
if (simDisplayTexture != NULL) {
|
||||||
|
SDL_RenderCopy(renderer, simDisplayTexture, NULL, NULL);
|
||||||
|
}
|
||||||
{ // motorController.motor_is_running
|
{ // motorController.motor_is_running
|
||||||
constexpr const int center_x = 45;
|
constexpr const int center_x = bubbleLeftEdge;
|
||||||
constexpr const int center_y = 15;
|
constexpr const int center_y = 216;
|
||||||
bool motor_is_running = nrf_gpio_pin_read(Pinetime::PinMap::Motor);
|
bool motor_is_running = nrf_gpio_pin_read(Pinetime::PinMap::Motor);
|
||||||
if (motor_is_running) {
|
if (motor_is_running) {
|
||||||
draw_circle_red(center_x, center_y, 15);
|
draw_circle_red(center_x, center_y, 15);
|
||||||
|
@ -505,8 +528,8 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{ // ble.motor_is_running
|
{ // ble.motor_is_running
|
||||||
constexpr const int center_x = 75;
|
constexpr const int center_x = bubbleLeftEdge;
|
||||||
constexpr const int center_y = 15;
|
constexpr const int center_y = 24;
|
||||||
if (bleController.IsConnected()) {
|
if (bleController.IsConnected()) {
|
||||||
draw_circle_blue(center_x, center_y, 15);
|
draw_circle_blue(center_x, center_y, 15);
|
||||||
} else {
|
} else {
|
||||||
|
@ -514,18 +537,31 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// batteryController.percentRemaining
|
// batteryController.percentRemaining
|
||||||
for (uint8_t percent=0; percent<=10; percent++) {
|
{
|
||||||
const int center_x = 15+15*percent;
|
const int center_x = bubbleLeftEdge;
|
||||||
const int center_y = 60;
|
const int center_y = 164;
|
||||||
if (batteryController.percentRemaining < percent*10) {
|
const int max_bar_length = 150;
|
||||||
draw_circle_grey(center_x, center_y, 15);
|
const int filled_bar_length = max_bar_length * (batteryController.percentRemaining/100.0);
|
||||||
} else {
|
const int rect_height = 14;
|
||||||
draw_circle_green(center_x, center_y, 15);
|
SDL_Rect rect {
|
||||||
}
|
.x = center_x - rect_height/2,
|
||||||
|
.y = center_y,
|
||||||
|
.w = max_bar_length,
|
||||||
|
.h = rect_height
|
||||||
|
};
|
||||||
|
SDL_SetRenderDrawColor(renderer, 128, 128, 128, 255);
|
||||||
|
SDL_RenderDrawRect(renderer, &rect);
|
||||||
|
|
||||||
|
rect.w = filled_bar_length;
|
||||||
|
rect.h++;
|
||||||
|
rect.h-=2;
|
||||||
|
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
|
||||||
|
SDL_RenderFillRect(renderer, &rect);
|
||||||
|
//set color and new x pos, draw again
|
||||||
}
|
}
|
||||||
{ // batteryController.isCharging
|
{ // batteryController.isCharging
|
||||||
constexpr const int center_x = 15;
|
constexpr const int center_x = bubbleLeftEdge;
|
||||||
constexpr const int center_y = 90;
|
constexpr const int center_y = 120;
|
||||||
if (batteryController.isCharging) {
|
if (batteryController.isCharging) {
|
||||||
draw_circle_yellow(center_x, center_y, 15);
|
draw_circle_yellow(center_x, center_y, 15);
|
||||||
} else
|
} else
|
||||||
|
@ -534,7 +570,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{ // brightnessController.Level
|
{ // brightnessController.Level
|
||||||
constexpr const int center_y = 15;
|
constexpr const int center_y = 72;
|
||||||
const Pinetime::Controllers::BrightnessController::Levels level = brightnessController.Level();
|
const Pinetime::Controllers::BrightnessController::Levels level = brightnessController.Level();
|
||||||
uint8_t level_idx = 0;
|
uint8_t level_idx = 0;
|
||||||
if (level == Pinetime::Controllers::BrightnessController::Levels::Low)
|
if (level == Pinetime::Controllers::BrightnessController::Levels::Low)
|
||||||
|
@ -548,11 +584,12 @@ public:
|
||||||
level_idx = 3;
|
level_idx = 3;
|
||||||
}
|
}
|
||||||
for (uint8_t i=0; i<4; i++) {
|
for (uint8_t i=0; i<4; i++) {
|
||||||
const int center_x = 115+15*i;
|
const int bubble_size = (i*2) + 5;
|
||||||
|
const int center_x = bubbleLeftEdge + ((bubble_size+10) * i) - 5;
|
||||||
if (i <= level_idx) {
|
if (i <= level_idx) {
|
||||||
draw_circle_white(center_x, center_y, 15);
|
draw_circle_white(center_x, center_y, bubble_size);
|
||||||
} else {
|
} else {
|
||||||
draw_circle_grey(center_x, center_y, 15);
|
draw_circle_grey(center_x, center_y, bubble_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -943,6 +980,7 @@ private:
|
||||||
int width; // Width of the window
|
int width; // Width of the window
|
||||||
SDL_Renderer *renderer = NULL; // Pointer for the renderer
|
SDL_Renderer *renderer = NULL; // Pointer for the renderer
|
||||||
SDL_Window *window = NULL; // Pointer for the window
|
SDL_Window *window = NULL; // Pointer for the window
|
||||||
|
SDL_Texture* simDisplayTexture = NULL; // Background for the sim status window
|
||||||
|
|
||||||
bool left_release_sent = true; // make sure to send one mouse button release event
|
bool left_release_sent = true; // make sure to send one mouse button release event
|
||||||
bool right_last_state = false; // varable used to send message only on changing state
|
bool right_last_state = false; // varable used to send message only on changing state
|
||||||
|
|
Loading…
Reference in a new issue