Compare commits

...

55 commits

Author SHA1 Message Date
Max Friedrich 63e032d8ec
Merge fb03cf6386 into a2356f2f4a 2024-10-03 10:32:54 +02:00
Max Friedrich fb03cf6386
Merge branch 'main' into simple-calculator 2024-10-03 10:32:51 +02:00
NeroBurner a2356f2f4a
MusicService: add missing includes for TickType_t and xTaskGetTickCount (#2130)
Some checks failed
CI / build-firmware (push) Successful in 10m55s
CI / build-simulator (push) Failing after 3s
CI / get-base-ref-size (push) Has been skipped
CI / Compare build size (push) Has been skipped
Add `FreeRTOS.h` include for the directly used data type `TickType_t` in the header
and the function `xTaskGetTickCount` from FreeRTOS's `task.h`
2024-09-29 21:10:32 +02:00
NeroBurner 3db4e012ce
Remove unused pointer to DisplayApp member variables (#2125)
Some checks failed
CI / build-firmware (push) Successful in 10m10s
CI / build-simulator (push) Failing after 3s
CI / get-base-ref-size (push) Has been skipped
CI / Compare build size (push) Has been skipped
In the screens that use `DisplayApp *app` and pass it to a child item,
or use the reference just in the constructor. Afterwards the `app`
member is not used. So remove it from the private member variables.

Completely remove `app` parameter from `SettingDisplay` constructor as
it is unused.
2024-09-29 19:39:14 +02:00
Max Friedrich eb160eecb3
Remove const
Because it is redundant
2024-09-03 03:03:32 +02:00
minacode dcacb9ca5c add constexpr 2024-09-01 22:00:10 +02:00
minacode 0d54f1e776 add const
I dont 100% understand, how it works, but this seems to reduce the amount of needed memory, such that we do not have to reduce the size in the FreeRTOS config.
2024-08-31 18:14:13 +02:00
Max Friedrich 46efadb20c
Merge branch 'main' into simple-calculator 2024-08-31 00:43:19 +02:00
minacode accd666517 remove TODO 2024-07-16 15:40:08 +02:00
minacode d2c178eddf add missing icon 2024-07-16 15:39:54 +02:00
minacode 0f65f4827e set heap size to 39 2024-07-16 15:39:34 +02:00
minacode ab7ceb9cfb implement new CMake interface 2024-07-16 14:58:13 +02:00
minacode b734baf47b reduce heap size 2024-07-16 14:57:05 +02:00
minacode 10346ef4d6 fix build and format warnings 2024-07-16 14:57:05 +02:00
minacode e6099835fb update to optional apps
This commit updates the codebase to use the new interface for compile-time optional apps.
2024-07-16 14:57:05 +02:00
minacode d356c400e9 lower maximum number size and number of digits
This is necessary to ensure correct calculations. Themaximum int64 has 19 digits. Therefore, 18 digits are safe to use. But in order to calculate exact multiplication we need twice the number of digits after the comma, so I decided to go with 12 digits before the comman and 3 after it.
2024-07-16 14:57:05 +02:00
Max Friedrich 25022004a0 only remove the operator if the value is zero
Co-authored-by: SuIông N. <Boteium@users.noreply.github.com>
2024-07-16 14:57:05 +02:00
minacode a3a557fb99 fixed display of negative numbers smaller than 0 2024-07-16 14:57:05 +02:00
minacode 44d1d7d4b6 format 2024-07-16 14:57:05 +02:00
minacode 19eb8a95cb fix after rebase 2024-07-16 14:57:05 +02:00
minacode f116a3e2bd changes 2024-07-16 14:57:05 +02:00
minacode 041369b88e fixed negative number input
Instead of always adding the new digit it now gets multipled with a sign, based on whether value is negative or not. Thus, the addition becomes a subtraction for negative numbers.
2024-07-16 14:57:05 +02:00
minacode 4a74e49f43 format 2024-07-16 14:57:05 +02:00
Finlay Davidson edf99905f4 Remove power operation in calculator app
Also shuffles bottom row around a bit, and adds a unary minus button.
Also fixes issue where the colours on the operator buttons aren't wiped
when the backspace button is pressed.
2024-07-16 14:57:05 +02:00
minacode 89c6c2f684 add better colors 2024-07-16 14:57:05 +02:00
minacode 4cd0ec79df removed swiping 2024-07-16 14:57:05 +02:00
minacode e98cd49958 checked buttons cleanup 2024-07-16 14:57:05 +02:00
minacode 25cd03ebf7 add power operation toggle 2024-07-16 14:57:05 +02:00
minacode d4ea28c128 format and tidy 2024-07-16 14:57:05 +02:00
minacode c36ad92eb8 format 2024-07-16 14:57:05 +02:00
minacode b9ede114bf reset value after copy to result 2024-07-16 14:57:05 +02:00
minacode 477ad1e840 fixed various issues 2024-07-16 14:57:05 +02:00
minacode 852c1de622 save changes 2024-07-16 14:57:05 +02:00
minacode 5433363f01 format 2024-07-16 14:57:05 +02:00
minacode b64787ac6d colored current button 2024-07-16 14:57:05 +02:00
minacode 0048a8b2b5 fix backspace for zeros 2024-07-16 14:57:05 +02:00
minacode 4096da4952 fix offset bug from backspace 2024-07-16 14:57:05 +02:00
minacode 3fce445420 format 2024-07-16 14:57:05 +02:00
minacode 7a7ffca49c WIP: = repeats calculation 2024-07-16 14:57:05 +02:00
minacode e46a1ca712 add backspace button 2024-07-16 14:57:03 +02:00
minacode 8c10adc890 set value bounds and checks 2024-07-16 14:55:58 +02:00
minacode 64fb4f92cc WIP: refactored the prints 2024-07-16 14:55:58 +02:00
minacode 0957bdcb43 fixed crashes 2024-07-16 14:55:58 +02:00
minacode 37b0842f92 change float to double 2024-07-16 14:55:58 +02:00
minacode 21e2427c62 changed long int to int64_t 2024-07-16 14:55:58 +02:00
minacode cacf107c11 format 2024-07-16 14:55:58 +02:00
minacode 5af0a3410d fixed number displays 2024-07-16 14:55:58 +02:00
minacode fed59f18fa make buttons bigger 2024-07-16 14:55:58 +02:00
minacode 7e7aa6c04e fixes and cleanup 2024-07-16 14:55:58 +02:00
minacode f2e6e835a4 added calculator symbol 2024-07-16 14:55:57 +02:00
minacode 9d4ad4e619 added pow with floats 2024-07-16 14:53:12 +02:00
minacode 1aec3afdfa added fixed point numbers, pow is still broken 2024-07-16 14:53:12 +02:00
minacode ba9d4772ff add offset 2024-07-16 14:53:12 +02:00
Max Friedrich e0cd8f60de Fix comparison 2024-07-16 14:53:12 +02:00
minacode 1770866d5e add int calculator 2024-07-16 14:53:08 +02:00
18 changed files with 495 additions and 15 deletions

View file

@ -380,6 +380,7 @@ list(APPEND SOURCE_FILES
displayapp/screens/Metronome.cpp
displayapp/screens/Motion.cpp
displayapp/screens/Weather.cpp
displayapp/screens/Calculator.cpp
displayapp/screens/FirmwareValidation.cpp
displayapp/screens/ApplicationList.cpp
displayapp/screens/Notifications.cpp

View file

@ -18,6 +18,8 @@
#include "components/ble/MusicService.h"
#include "components/ble/NimbleController.h"
#include <cstring>
#include <FreeRTOS.h>
#include <task.h>
namespace {
// 0000yyxx-78fc-48fe-8e23-433b3a1942d0

View file

@ -25,6 +25,7 @@
#include <host/ble_uuid.h>
#undef max
#undef min
#include <FreeRTOS.h>
namespace Pinetime {
namespace Controllers {

View file

@ -30,6 +30,7 @@
#include "displayapp/screens/Weather.h"
#include "displayapp/screens/PassKey.h"
#include "displayapp/screens/Error.h"
#include "displayapp/screens/Calculator.h"
#include "drivers/Cst816s.h"
#include "drivers/St7789.h"
@ -582,7 +583,7 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio
currentScreen = std::make_unique<Screens::SettingWakeUp>(settingsController);
break;
case Apps::SettingDisplay:
currentScreen = std::make_unique<Screens::SettingDisplay>(this, settingsController);
currentScreen = std::make_unique<Screens::SettingDisplay>(settingsController);
break;
case Apps::SettingSteps:
currentScreen = std::make_unique<Screens::SettingSteps>(settingsController);

View file

@ -26,6 +26,7 @@ namespace Pinetime {
StopWatch,
Metronome,
Motion,
Calculator,
Steps,
Dice,
Weather,

View file

@ -13,6 +13,7 @@ else ()
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Dice")
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Metronome")
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Navigation")
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Calculator")
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Weather")
#set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Motion")
set(USERAPP_TYPES "${DEFAULT_USER_APP_TYPES}" CACHE STRING "List of user apps to build into the firmware")

View file

@ -7,7 +7,7 @@
},
{
"file": "FontAwesome5-Solid+Brands+Regular.woff",
"range": "0xf294, 0xf242, 0xf54b, 0xf21e, 0xf1e6, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024, 0xf252, 0xf569, 0xf06e, 0xf015, 0xf00c, 0xf0f3, 0xf522, 0xf743"
"range": "0xf294, 0xf242, 0xf54b, 0xf21e, 0xf1e6, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024, 0xf252, 0xf569, 0xf201, 0xf06e, 0xf015, 0xf00c, 0xf1ec, 0xf743, 0xf55a, 0xf0f3"
}
],
"bpp": 1,

View file

@ -0,0 +1,398 @@
#include <cmath>
#include <cinttypes>
#include <libraries/log/nrf_log.h>
#include "Calculator.h"
#include "displayapp/InfiniTimeTheme.h"
#include "Symbols.h"
using namespace Pinetime::Applications::Screens;
static void eventHandler(lv_obj_t* obj, lv_event_t event) {
auto app = static_cast<Calculator*>(obj->user_data);
app->OnButtonEvent(obj, event);
}
Calculator::~Calculator() {
lv_obj_clean(lv_scr_act());
}
constexpr char* const buttonMap[] = {
"7", "8", "9", Symbols::backspace, "\n", "4", "5", "6", "+ -", "\n", "1", "2", "3", "* /", "\n", "0", ".", "(-)", "=", ""};
Calculator::Calculator() {
resultLabel = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_long_mode(resultLabel, LV_LABEL_LONG_CROP);
lv_label_set_align(resultLabel, LV_LABEL_ALIGN_RIGHT);
lv_label_set_text_fmt(resultLabel, "%" PRId64, result);
lv_obj_set_size(resultLabel, 200, 20);
lv_obj_set_pos(resultLabel, 10, 5);
valueLabel = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_long_mode(valueLabel, LV_LABEL_LONG_CROP);
lv_label_set_align(valueLabel, LV_LABEL_ALIGN_RIGHT);
lv_label_set_text_fmt(valueLabel, "%" PRId64, value);
lv_obj_set_size(valueLabel, 200, 20);
lv_obj_set_pos(valueLabel, 10, 35);
buttonMatrix = lv_btnmatrix_create(lv_scr_act(), nullptr);
buttonMatrix->user_data = this;
lv_obj_set_event_cb(buttonMatrix, eventHandler);
lv_btnmatrix_set_map(buttonMatrix, const_cast<const char**>(buttonMap));
lv_btnmatrix_set_one_check(buttonMatrix, true);
lv_obj_set_size(buttonMatrix, 238, 180);
lv_obj_set_style_local_bg_color(buttonMatrix, LV_BTNMATRIX_PART_BTN, LV_STATE_DEFAULT, Colors::bgAlt);
lv_obj_set_style_local_pad_inner(buttonMatrix, LV_BTNMATRIX_PART_BG, LV_STATE_DEFAULT, 1);
lv_obj_set_style_local_pad_top(buttonMatrix, LV_BTNMATRIX_PART_BG, LV_STATE_DEFAULT, 1);
lv_obj_set_style_local_pad_bottom(buttonMatrix, LV_BTNMATRIX_PART_BG, LV_STATE_DEFAULT, 1);
lv_obj_set_style_local_pad_left(buttonMatrix, LV_BTNMATRIX_PART_BG, LV_STATE_DEFAULT, 1);
lv_obj_set_style_local_pad_right(buttonMatrix, LV_BTNMATRIX_PART_BG, LV_STATE_DEFAULT, 1);
lv_obj_align(buttonMatrix, nullptr, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
lv_obj_set_style_local_bg_opa(buttonMatrix, LV_BTNMATRIX_PART_BTN, LV_STATE_CHECKED, LV_OPA_COVER);
lv_obj_set_style_local_bg_grad_stop(buttonMatrix, LV_BTNMATRIX_PART_BTN, LV_STATE_CHECKED, 128);
lv_obj_set_style_local_bg_main_stop(buttonMatrix, LV_BTNMATRIX_PART_BTN, LV_STATE_CHECKED, 128);
}
void Calculator::OnButtonEvent(lv_obj_t* obj, lv_event_t event) {
if ((obj == buttonMatrix) && (event == LV_EVENT_PRESSED)) {
HandleInput();
}
}
void Calculator::HandleInput() {
const char* buttonText = lv_btnmatrix_get_active_btn_text(buttonMatrix);
if (buttonText == nullptr) {
return;
}
if ((equalSignPressed && (*buttonText != '=')) || (error != Error::None)) {
ResetInput();
UpdateOperation();
}
// we only compare the first char because it is enough
switch (*buttonText) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': {
// *buttonText is the first char in buttonText
// "- '0'" results in the int value of the char
auto digit = (*buttonText) - '0';
auto sign = (value < 0) ? -1 : 1;
// if this is true, we already pressed the . button
if (offset < FIXED_POINT_OFFSET) {
value += sign * offset * digit;
offset /= 10;
} else if (value <= MAX_VALUE / 10) {
value *= 10;
value += sign * offset * digit;
}
NRF_LOG_INFO(". offset: %" PRId64, offset);
NRF_LOG_INFO(". value: %" PRId64, value);
NRF_LOG_INFO(". result: %" PRId64, result);
} break;
// unary minus
case '(':
value = -value;
NRF_LOG_INFO(". offset: %" PRId64, offset);
NRF_LOG_INFO(". value: %" PRId64, value);
NRF_LOG_INFO(". result: %" PRId64, result);
break;
case '.':
if (offset == FIXED_POINT_OFFSET) {
offset /= 10;
}
NRF_LOG_INFO(". offset: %" PRId64, offset);
NRF_LOG_INFO(". value: %" PRId64, value);
NRF_LOG_INFO(". result: %" PRId64, result);
break;
// for every operator we:
// - eval the current operator if value > FIXED_POINT_OFFSET
// - then set the new operator
// - + and - as well as * and / cycle on the same button
case '+':
if (value != 0) {
Eval();
ResetInput();
}
switch (operation) {
case '+':
operation = '-';
break;
case '-':
operation = ' ';
break;
default:
operation = '+';
break;
}
UpdateOperation();
break;
case '*':
if (value != 0) {
Eval();
ResetInput();
}
switch (operation) {
case '*':
operation = '/';
break;
case '/':
operation = ' ';
break;
default:
operation = '*';
break;
}
UpdateOperation();
break;
// this is a little hacky because it matches only the first char
case Symbols::backspace[0]:
if (value != 0) {
// delete one value digit
if (offset < FIXED_POINT_OFFSET) {
if (offset == 0) {
offset = 1;
} else {
offset *= 10;
}
} else {
value /= 10;
}
if (offset < FIXED_POINT_OFFSET) {
value -= value % (10 * offset);
} else {
value -= value % offset;
}
} else if (offset < FIXED_POINT_OFFSET) {
if (offset == 0) {
offset = 1;
} else {
offset *= 10;
}
} else {
// reset the result
result = 0;
}
NRF_LOG_INFO(". offset: %" PRId64, offset);
NRF_LOG_INFO(". value: %" PRId64, value);
NRF_LOG_INFO(". result: %" PRId64, result);
if (value == 0) {
operation = ' ';
UpdateOperation();
}
break;
case '=':
equalSignPressed = true;
Eval();
// If the operation is ' ' then we move the value to the result.
// We reset the input after this.
// This seems more convenient.
if (operation == ' ') {
ResetInput();
}
NRF_LOG_INFO(". offset: %" PRId64, offset);
NRF_LOG_INFO(". value: %" PRId64, value);
NRF_LOG_INFO(". result: %" PRId64, result);
break;
}
UpdateValueLabel();
UpdateResultLabel();
}
void Calculator::UpdateOperation() const {
switch (operation) {
case '+':
lv_obj_set_style_local_bg_grad_dir(buttonMatrix, LV_BTNMATRIX_PART_BTN, LV_STATE_CHECKED, LV_GRAD_DIR_HOR);
lv_obj_set_style_local_bg_color(buttonMatrix, LV_BTNMATRIX_PART_BTN, LV_STATE_CHECKED, Colors::deepOrange);
lv_obj_set_style_local_bg_grad_color(buttonMatrix, LV_BTNMATRIX_PART_BTN, LV_STATE_CHECKED, Colors::bgAlt);
lv_btnmatrix_set_btn_ctrl(buttonMatrix, 7, LV_BTNMATRIX_CTRL_CHECK_STATE);
break;
case '-':
lv_obj_set_style_local_bg_grad_dir(buttonMatrix, LV_BTNMATRIX_PART_BTN, LV_STATE_CHECKED, LV_GRAD_DIR_HOR);
lv_obj_set_style_local_bg_color(buttonMatrix, LV_BTNMATRIX_PART_BTN, LV_STATE_CHECKED, Colors::bgAlt);
lv_obj_set_style_local_bg_grad_color(buttonMatrix, LV_BTNMATRIX_PART_BTN, LV_STATE_CHECKED, Colors::deepOrange);
lv_btnmatrix_set_btn_ctrl(buttonMatrix, 7, LV_BTNMATRIX_CTRL_CHECK_STATE);
break;
case '*':
lv_obj_set_style_local_bg_grad_dir(buttonMatrix, LV_BTNMATRIX_PART_BTN, LV_STATE_CHECKED, LV_GRAD_DIR_HOR);
lv_obj_set_style_local_bg_color(buttonMatrix, LV_BTNMATRIX_PART_BTN, LV_STATE_CHECKED, Colors::deepOrange);
lv_obj_set_style_local_bg_grad_color(buttonMatrix, LV_BTNMATRIX_PART_BTN, LV_STATE_CHECKED, Colors::bgAlt);
lv_btnmatrix_set_btn_ctrl(buttonMatrix, 11, LV_BTNMATRIX_CTRL_CHECK_STATE);
break;
case '/':
lv_obj_set_style_local_bg_grad_dir(buttonMatrix, LV_BTNMATRIX_PART_BTN, LV_STATE_CHECKED, LV_GRAD_DIR_HOR);
lv_obj_set_style_local_bg_color(buttonMatrix, LV_BTNMATRIX_PART_BTN, LV_STATE_CHECKED, Colors::bgAlt);
lv_obj_set_style_local_bg_grad_color(buttonMatrix, LV_BTNMATRIX_PART_BTN, LV_STATE_CHECKED, Colors::deepOrange);
lv_btnmatrix_set_btn_ctrl(buttonMatrix, 11, LV_BTNMATRIX_CTRL_CHECK_STATE);
break;
default:
lv_btnmatrix_clear_btn_ctrl_all(buttonMatrix, LV_BTNMATRIX_CTRL_CHECK_STATE);
break;
}
}
void Calculator::ResetInput() {
value = 0;
offset = FIXED_POINT_OFFSET;
operation = ' ';
equalSignPressed = false;
error = Error::None;
}
void Calculator::UpdateResultLabel() const {
int64_t integer = result / FIXED_POINT_OFFSET;
int64_t remainder = result % FIXED_POINT_OFFSET;
bool negative = (remainder < 0);
if (remainder == 0) {
lv_label_set_text_fmt(resultLabel, "%" PRId64, integer);
return;
}
if (remainder < 0) {
remainder = -remainder;
}
uint8_t min_width = N_DECIMALS;
// cut "0"-digits on the right
while ((remainder > 0) && (remainder % 10 == 0)) {
remainder /= 10;
min_width--;
}
if ((integer == 0) && negative) {
lv_label_set_text_fmt(resultLabel, "-0.%0*" PRId64, min_width, remainder);
} else {
lv_label_set_text_fmt(resultLabel, "%" PRId64 ".%0*" PRId64, integer, min_width, remainder);
}
}
void Calculator::UpdateValueLabel() {
switch (error) {
case Error::TooLarge:
lv_label_set_text_static(valueLabel, "too large");
break;
case Error::ZeroDivision:
lv_label_set_text_static(valueLabel, "zero division");
break;
case Error::None:
default: {
int64_t integer = value / FIXED_POINT_OFFSET;
int64_t remainder = value % FIXED_POINT_OFFSET;
bool negative = (remainder < 0);
int64_t printRemainder = remainder < 0 ? -remainder : remainder;
uint8_t min_width = 0;
int64_t tmp_offset = offset;
if (tmp_offset == 0) {
tmp_offset = 1;
min_width = 1;
}
while (tmp_offset < FIXED_POINT_OFFSET) {
tmp_offset *= 10;
min_width++;
}
min_width--;
for (uint8_t i = min_width; i < N_DECIMALS; i++) {
printRemainder /= 10;
}
if ((integer == 0) && negative) {
lv_label_set_text_fmt(valueLabel, "-0.%0*" PRId64, min_width, printRemainder);
} else if (offset == FIXED_POINT_OFFSET) {
lv_label_set_text_fmt(valueLabel, "%" PRId64, integer);
} else if ((offset == (FIXED_POINT_OFFSET / 10)) && (remainder == 0)) {
lv_label_set_text_fmt(valueLabel, "%" PRId64 ".", integer);
} else {
lv_label_set_text_fmt(valueLabel, "%" PRId64 ".%0*" PRId64, integer, min_width, printRemainder);
}
} break;
}
}
// update the result based on value and operation
void Calculator::Eval() {
switch (operation) {
case ' ':
result = value;
break;
case '+':
// check for overflow
if (((result > 0) && (value > (MAX_VALUE - result))) || ((result < 0) && (value < (MIN_VALUE - result)))) {
error = Error::TooLarge;
break;
}
result += value;
break;
case '-':
// check for overflow
if (((result < 0) && (value > (MAX_VALUE + result))) || ((result > 0) && (value < (MIN_VALUE + result)))) {
error = Error::TooLarge;
break;
}
result -= value;
break;
case '*':
// check for overflow
// while dividing we eliminate the fixed point offset
// therefore we have to multiply it again for the comparison with value
// we also assume here that MAX_VALUE == -MIN_VALUE
if ((result != 0) && (std::abs(value) > (FIXED_POINT_OFFSET * (MAX_VALUE / std::abs(result))))) {
error = Error::TooLarge;
break;
}
result *= value;
// fixed point offset was multiplied too
result /= FIXED_POINT_OFFSET;
break;
case '/':
// check for zero division
if (value == 0) {
error = Error::ZeroDivision;
break;
}
// fixed point offset will be divided too
result *= FIXED_POINT_OFFSET;
result /= value;
break;
default:
break;
}
}

View file

@ -0,0 +1,81 @@
#pragma once
#include "displayapp/screens/Screen.h"
#include "displayapp/apps/Apps.h"
#include "displayapp/Controllers.h"
#include "Symbols.h"
namespace {
int64_t constexpr powi(int64_t base, uint8_t exponent) {
int64_t value = 1;
while (exponent) {
value *= base;
exponent--;
}
return value;
}
}
namespace Pinetime {
namespace Applications {
namespace Screens {
class Calculator : public Screen {
public:
~Calculator() override;
Calculator();
void OnButtonEvent(lv_obj_t* obj, lv_event_t event);
private:
lv_obj_t* buttonMatrix {};
lv_obj_t* valueLabel {};
lv_obj_t* resultLabel {};
void Eval();
void ResetInput();
void HandleInput();
void UpdateValueLabel();
void UpdateResultLabel() const;
void UpdateOperation() const;
// change this if you want to change the number of decimals
static constexpr uint8_t N_DECIMALS = 3;
// this is the constant default offset
static constexpr int64_t FIXED_POINT_OFFSET = powi(10, N_DECIMALS);
// this is the current offset, may wary after pressing '.'
int64_t offset = FIXED_POINT_OFFSET;
// the screen can show 12 chars
// but two are needed for '.' and '-'
static constexpr uint8_t MAX_DIGITS = 12;
static constexpr int64_t MAX_VALUE = powi(10, MAX_DIGITS) - 1;
// this is assumed in the multiplication overflow!
static constexpr int64_t MIN_VALUE = -MAX_VALUE;
int64_t value = 0;
int64_t result = 0;
char operation = ' ';
bool equalSignPressed = false;
enum Error {
TooLarge,
ZeroDivision,
None,
};
Error error = Error::None;
};
}
template <>
struct AppTraits<Apps::Calculator> {
static constexpr Apps app = Apps::Calculator;
static constexpr const char* icon = Screens::Symbols::calculator;
static Screens::Screen* Create(AppControllers& /* controllers */) {
return new Screens::Calculator();
};
};
}
}

View file

@ -39,6 +39,8 @@ namespace Pinetime {
static constexpr const char* eye = "\xEF\x81\xAE";
static constexpr const char* home = "\xEF\x80\x95";
static constexpr const char* sleep = "\xEE\xBD\x84";
static constexpr const char* calculator = "\xEF\x87\xAC";
static constexpr const char* backspace = "\xEF\x95\x9A";
// fontawesome_weathericons.c
// static constexpr const char* sun = "\xEF\x86\x85";

View file

@ -40,8 +40,7 @@ SystemInfo::SystemInfo(Pinetime::Applications::DisplayApp* app,
Pinetime::Controllers::MotionController& motionController,
const Pinetime::Drivers::Cst816S& touchPanel,
const Pinetime::Drivers::SpiNorFlash& spiNorFlash)
: app {app},
dateTimeController {dateTimeController},
: dateTimeController {dateTimeController},
batteryController {batteryController},
brightnessController {brightnessController},
bleController {bleController},

View file

@ -35,7 +35,6 @@ namespace Pinetime {
bool OnTouchEvent(TouchEvents event) override;
private:
DisplayApp* app;
Pinetime::Controllers::DateTime& dateTimeController;
const Pinetime::Controllers::Battery& batteryController;
Pinetime::Controllers::BrightnessController& brightnessController;

View file

@ -24,8 +24,7 @@ namespace {
constexpr std::array<uint16_t, 6> SettingDisplay::options;
SettingDisplay::SettingDisplay(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController)
: app {app}, settingsController {settingsController} {
SettingDisplay::SettingDisplay(Pinetime::Controllers::Settings& settingsController) : settingsController {settingsController} {
lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr);

View file

@ -14,14 +14,13 @@ namespace Pinetime {
class SettingDisplay : public Screen {
public:
SettingDisplay(DisplayApp* app, Pinetime::Controllers::Settings& settingsController);
SettingDisplay(Pinetime::Controllers::Settings& settingsController);
~SettingDisplay() override;
void UpdateSelected(lv_obj_t* object, lv_event_t event);
void ToggleAlwaysOn();
private:
DisplayApp* app;
static constexpr std::array<uint16_t, 6> options = {5000, 7000, 10000, 15000, 20000, 30000};
Controllers::Settings& settingsController;

View file

@ -15,8 +15,7 @@ bool SettingSetDateTime::OnTouchEvent(Pinetime::Applications::TouchEvents event)
SettingSetDateTime::SettingSetDateTime(Pinetime::Applications::DisplayApp* app,
Pinetime::Controllers::DateTime& dateTimeController,
Pinetime::Controllers::Settings& settingsController)
: app {app},
dateTimeController {dateTimeController},
: dateTimeController {dateTimeController},
settingsController {settingsController},
screens {app,
0,

View file

@ -20,7 +20,6 @@ namespace Pinetime {
void Quit();
private:
DisplayApp* app;
Controllers::DateTime& dateTimeController;
Controllers::Settings& settingsController;

View file

@ -54,8 +54,7 @@ SettingWatchFace::SettingWatchFace(Pinetime::Applications::DisplayApp* app,
std::array<Screens::SettingWatchFace::Item, UserWatchFaceTypes::Count>&& watchfaceItems,
Pinetime::Controllers::Settings& settingsController,
Pinetime::Controllers::FS& filesystem)
: app {app},
watchfaceItems {std::move(watchfaceItems)},
: watchfaceItems {std::move(watchfaceItems)},
settingsController {settingsController},
filesystem {filesystem},
screens {app, 0, CreateScreenList(), Screens::ScreenListModes::UpDown} {

View file

@ -34,7 +34,6 @@ namespace Pinetime {
bool OnTouchEvent(TouchEvents event) override;
private:
DisplayApp* app;
auto CreateScreenList() const;
std::unique_ptr<Screen> CreateScreen(unsigned int screenNum) const;