Files
MuditaOS/module-apps/application-calculator/windows/CalculatorMainWindow.cpp
jimmorrisson 14918dc4f9 [EGD-4925] Change new filesystem handling implementation in module-gui. (#1193)
Due to vfs deprecation there is need to remove all vfs calls from code. This PR covers module gui. There are some modifications in other modules included which are necessary because of build system issues.
2020-12-16 15:23:11 +01:00

168 lines
7.4 KiB
C++

// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "CalculatorMainWindow.hpp"
#include "application-calculator/widgets/CalculatorStyle.hpp"
#include "application-calculator/data/CalculatorUtility.hpp"
#include <i18n/i18n.hpp>
namespace gui
{
CalculatorMainWindow::CalculatorMainWindow(app::Application *app, std::string name) : AppWindow(app, name)
{
buildInterface();
}
void CalculatorMainWindow::buildInterface()
{
AppWindow::buildInterface();
setTitle(utils::localize.get("app_calculator_title_main"));
bottomBar->setActive(gui::BottomBar::Side::CENTER, true);
bottomBar->setActive(gui::BottomBar::Side::RIGHT, true);
bottomBar->setActive(gui::BottomBar::Side::LEFT, true);
bottomBar->setText(gui::BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
bottomBar->setText(gui::BottomBar::Side::CENTER, utils::localize.get(style::calculator::equals));
bottomBar->setText(gui::BottomBar::Side::LEFT, utils::localize.get(style::calculator::decimal_separator));
bottomBar->setFont(BottomBar::Side::LEFT, style::window::font::largelight);
mathOperationInput = new gui::Text(this,
style::calculator::window::input_margin,
style::calculator::window::input_offset_top,
style::calculator::window::input_width,
style::calculator::window::input_height);
mathOperationInput->setEdges(gui::RectangleEdge::Bottom);
mathOperationInput->setAlignment(
gui::Alignment(gui::Alignment::Horizontal::Right, gui::Alignment::Vertical::Center));
mathOperationInput->setFont(style::window::font::supersizemelight);
mathOperationInput->setInputMode(new InputMode({InputMode::digit}));
mathOperationInput->setPenFocusWidth(style::window::default_border_focus_w);
mathOperationInput->setPenWidth(style::window::default_border_rect_no_focus);
mathOperationInput->setEditMode(gui::EditMode::Edit);
mathBox = new gui::MathOperationsBox(this,
style::calculator::window::math_box_offset_top,
style::window::default_body_width,
style::calculator::window::math_box_height,
style::calculator::window::math_box_cell_width,
style::calculator::window::math_box_cell_height);
addWidget(mathBox);
setFocusItem(mathOperationInput);
applyInputCallback();
}
void CalculatorMainWindow::applyInputCallback()
{
mathOperationInput->inputCallback = [&](Item &item, const InputEvent &event) {
if (clearInput) {
mathOperationInput->clear();
clearInput = false;
}
if (!event.isShortPress()) {
return false;
}
auto lastChar = mathOperationInput->getText()[mathOperationInput->getText().length() - 1];
bool lastCharIsSymbol = isSymbol(lastChar);
if (event.keyCode == gui::KeyCode::KEY_UP) {
writeEquation(lastCharIsSymbol, style::calculator::symbols::strings::plus);
return true;
}
if (event.keyCode == gui::KeyCode::KEY_DOWN) {
if (lastChar != style::calculator::symbols::codes::minus) {
writeEquation(lastCharIsSymbol, style::calculator::symbols::strings::minus);
}
return true;
}
if (event.keyCode == gui::KeyCode::KEY_LEFT) {
writeEquation(lastCharIsSymbol, style::calculator::symbols::strings::multiplication);
return true;
}
if (event.keyCode == gui::KeyCode::KEY_RIGHT) {
writeEquation(lastCharIsSymbol, style::calculator::symbols::strings::division);
return true;
}
if (event.keyCode == gui::KeyCode::KEY_LF) {
if (!isPreviousNumberDecimal()) {
writeEquation(lastCharIsSymbol, utils::localize.get("app_calculator_decimal_separator"));
}
return true;
}
return false;
};
}
bool CalculatorMainWindow::isSymbol(uint32_t character)
{
return character == style::calculator::symbols::codes::plus ||
character == style::calculator::symbols::codes::minus ||
character == style::calculator::symbols::codes::division ||
character == style::calculator::symbols::codes::multiplication ||
character == style::calculator::symbols::codes::comma ||
character == style::calculator::symbols::codes::full_stop;
}
void CalculatorMainWindow::writeEquation(bool lastCharIsSymbol, const UTF8 &symbol)
{
if (!mathOperationInput->getText().empty()) {
if (lastCharIsSymbol && symbol != style::calculator::symbols::strings::minus) {
mathOperationInput->setRichText(
std::string(mathOperationInput->getText()).erase(mathOperationInput->getText().length() - 1) +
symbol.c_str());
}
else {
mathOperationInput->setRichText(mathOperationInput->getText() + symbol);
}
}
else if (symbol == style::calculator::symbols::strings::minus) {
mathOperationInput->setRichText(mathOperationInput->getText() + symbol);
}
}
bool CalculatorMainWindow::isPreviousNumberDecimal()
{
if (!mathOperationInput->getText().empty()) {
std::vector<int> symbolsIndexes;
auto input = std::string(mathOperationInput->getText()).erase(mathOperationInput->getText().length() - 1);
symbolsIndexes.push_back(input.find_last_of(style::calculator::symbols::strings::minus));
symbolsIndexes.push_back(input.find_last_of(style::calculator::symbols::strings::plus));
symbolsIndexes.push_back(input.find_last_of(style::calculator::symbols::strings::division));
symbolsIndexes.push_back(input.find_last_of(style::calculator::symbols::strings::multiplication));
auto it = std::max_element(symbolsIndexes.begin(), symbolsIndexes.end());
std::string lastNumber;
if (*it == -1) {
lastNumber = input.substr(0, std::string::npos);
}
else {
lastNumber = input.substr(*it, std::string::npos);
}
return lastNumber.find(utils::localize.get("app_calculator_decimal_separator")) != std::string::npos;
}
return false;
}
bool CalculatorMainWindow::onInput(const gui::InputEvent &inputEvent)
{
if (AppWindow::onInput(inputEvent)) {
return true;
}
if (!inputEvent.isShortPress()) {
return false;
}
if (inputEvent.keyCode == gui::KeyCode::KEY_ENTER) {
auto result = Calculator().calculate(std::string(mathOperationInput->getText()));
mathOperationInput->setRichText(result.value);
clearInput = result.isError;
return true;
}
return false;
}
} // namespace gui