Files
MuditaOS/module-apps/application-desktop/windows/PinLockWindow.cpp
Adam f5f27d642f EGD-2955 EGD-3588 Timers fully refactored & updated (#721)
* Timers now are Application thread safe
* Timers now have consistent API independend of Application (no more c style timers)
* Timers can have either: callback or override onTimer() method - this
  way we can create more complicated timers or just use existing ones
* gui::Timer added via adapter class GuiTimer to decouple sys::Timer
  with gui::Timer
* Fixed race in wrapper
* Updated docs
* fixed using std and cpp_freertos and DataReceivedHandler hidden in Application.hpp
2020-10-02 14:04:57 +02:00

171 lines
5.7 KiB
C++

/*
* @file PinLockWindow.cpp
* @author Robert Borzecki (robert.borzecki@mudita.com)
* @date 19 cze 2019
* @brief
* @copyright Copyright (C) 2019 mudita.com
* @details
*/
// application manager
#include "InputEvent.hpp"
#include "service-appmgr/ApplicationManager.hpp"
// module-gui
#include "gui/widgets/BottomBar.hpp"
#include "PinLockWindow.hpp"
#include "application-desktop/ApplicationDesktop.hpp"
#include "application-desktop/data/LockPhoneData.hpp"
#include "ScreenLockBox.hpp"
#include "SimLockBox.hpp"
#include "PukLockBox.hpp"
#include <application-phonebook/ApplicationPhonebook.hpp>
namespace gui
{
PinLockWindow::PinLockWindow(app::Application *app, const std::string &window_name, PinLock &lock)
: PinLockBaseWindow(app, window_name, lock), this_window_name(window_name)
{
buildInterface();
}
void PinLockWindow::rebuild()
{
// find which widget has focus
destroyInterface();
buildInterface();
// set state
focusItem = nullptr;
setVisibleState(lock.getState());
}
void PinLockWindow::buildInterface()
{
AppWindow::buildInterface();
PinLockBaseWindow::build();
buildPinLockBox();
LockBox->buildLockBox(lock.getPinSize());
}
void PinLockWindow::destroyInterface()
{
erase();
invalidate();
}
void PinLockWindow::invalidate() noexcept
{
titleLabel = nullptr;
lockImage = nullptr;
infoImage = nullptr;
infoText = nullptr;
pinLabel = nullptr;
pinLabels.clear();
}
void PinLockWindow::setVisibleState(const PinLock::State state)
{
if (state == PinLock::State::EnterPin) {
LockBox->setVisibleStateEnterPin();
}
else if (state == PinLock::State::VerifiedPin) {
LockBox->setVisibleStateVerifiedPin();
}
else if (state == PinLock::State::InvalidPin) {
LockBox->setVisibleStateInvalidPin();
}
else if (state == PinLock::State::Blocked) {
LockBox->setVisibleStateBlocked();
}
application->refreshWindow(RefreshModes::GUI_REFRESH_FAST);
}
void PinLockWindow::onBeforeShow(ShowMode mode, SwitchData *data)
{
if (auto lockData = dynamic_cast<LockPhoneData *>(data)) {
lockTimeoutApplication = lockData->getPreviousApplication();
}
if (lock.unlock()) {
setVisibleState(PinLock::State::VerifiedPin);
application->switchWindow(gui::name::window::main_window);
}
setVisibleState(lock.getState());
}
bool PinLockWindow::onInput(const InputEvent &inputEvent)
{
auto state = lock.getState();
if (!inputEvent.isShortPress() || state == PinLock::State::VerifiedPin) {
return AppWindow::onInput(inputEvent);
}
// accept only LF, enter, RF, #, and numeric values;
if (inputEvent.keyCode == KeyCode::KEY_LF && bottomBar->isActive(BottomBar::Side::LEFT)) {
sapm::ApplicationManager::messageSwitchApplication(
application, app::name_phonebook, gui::window::name::ice_contacts, nullptr);
return true;
}
else if (inputEvent.keyCode == KeyCode::KEY_RF && bottomBar->isActive(BottomBar::Side::RIGHT)) {
if (state == PinLock::State::EnterPin) {
lock.clearAttempt();
clearPinLabels();
}
else if (state == PinLock::State::InvalidPin) {
LockBox->setVisibleStateInvalidPin();
lock.consumeInvalidPinState();
}
application->switchWindow(gui::name::window::main_window);
return true;
}
else if (inputEvent.keyCode == KeyCode::KEY_PND) {
if (state == PinLock::State::EnterPin) {
lock.popChar();
LockBox->popChar(lock.getCharCount());
return true;
}
}
else if (0 <= gui::toNumeric(inputEvent.keyCode) && gui::toNumeric(inputEvent.keyCode) <= 9) {
if (state == PinLock::State::EnterPin && lock.canPut()) {
LockBox->putChar(lock.getCharCount());
lock.putNextChar(gui::toNumeric(inputEvent.keyCode));
if (lock.getLockType() == PinLock::LockType::Screen) {
lock.verifyPin();
}
else if (!lock.canPut()) {
bottomBar->setActive(BottomBar::Side::CENTER, true);
}
return true;
}
}
else if (inputEvent.keyCode == KeyCode::KEY_ENTER && bottomBar->isActive(BottomBar::Side::CENTER)) {
if (state == PinLock::State::InvalidPin) {
lock.consumeInvalidPinState();
application->switchWindow(this_window_name);
}
else if (state == PinLock::State::EnterPin) {
lock.verifyPin();
}
else if (state == PinLock::State::Blocked) {
application->switchWindow(gui::name::window::main_window);
}
return true;
}
// check if any of the lower inheritance onInput methods catch the event
return AppWindow::onInput(inputEvent);
}
void PinLockWindow::buildPinLockBox()
{
auto lockType = lock.getLockType();
if (lockType == PinLock::LockType::Screen) {
LockBox = std::make_unique<ScreenLockBox>(this);
}
else if (lockType == PinLock::LockType::PUK) {
LockBox = std::make_unique<PukLockBox>(this);
}
else if (lockType == PinLock::LockType::SIM) {
LockBox = std::make_unique<SimLockBox>(this);
}
assert(LockBox != nullptr);
}
} /* namespace gui */