[on_boarding]

Change-Id: Ia1dd18c27bb9d5f727f6c90d2579c85556f17e86
This commit is contained in:
Émilie Feral
2017-05-11 17:50:23 +02:00
parent 2cd86a839a
commit 998733db62
18 changed files with 414 additions and 5 deletions

View File

@@ -2,6 +2,7 @@ include apps/calculation/Makefile
include apps/graph/Makefile
include apps/home/Makefile
include apps/hardware_test/Makefile
include apps/on_boarding/Makefile
include apps/probability/Makefile
include apps/regression/Makefile
include apps/sequence/Makefile

View File

@@ -20,6 +20,7 @@ AppsContainer::AppsContainer() :
m_USBTimer(USBTimer(this)),
m_suspendTimer(SuspendTimer(this)),
m_backlightDimmingTimer(BacklightDimmingTimer()),
m_onBoardingApp(new OnBoarding::App(this)),
m_homeApp(new Home::App(this)),
m_graphApp(new Graph::App(this, &m_globalContext)),
m_probabilityApp(new Probability::App(this)),
@@ -36,6 +37,8 @@ AppsContainer::AppsContainer() :
}
AppsContainer::~AppsContainer() {
delete m_onBoardingApp;
m_onBoardingApp = nullptr;
delete m_homeApp;
m_homeApp = nullptr;
delete m_graphApp;
@@ -66,6 +69,9 @@ int AppsContainer::numberOfApps() {
}
App * AppsContainer::appAtIndex(int index) {
if (index == -1) {
return m_onBoardingApp;
}
App * apps[] = {
m_homeApp,
m_calculationApp,
@@ -143,11 +149,14 @@ bool AppsContainer::dispatchEvent(Ion::Events::Event event) {
bool alphaLockWantsRedraw = m_window.updateAlphaLock();
// Home and Power buttons are not sent to apps. We handle them straight away.
if (event == Ion::Events::Home && activeApp() != m_hardwareTestApp) {
if (event == Ion::Events::Home && activeApp() != m_hardwareTestApp && activeApp() != m_onBoardingApp) {
switchTo(appAtIndex(0));
return true;
}
if (event == Ion::Events::OnOff && activeApp() != m_hardwareTestApp) {
if (activeApp() == m_onBoardingApp) {
m_onBoardingApp->reinitOnBoarding();
}
suspend(true);
return true;
}
@@ -164,7 +173,7 @@ bool AppsContainer::dispatchEvent(Ion::Events::Event event) {
}
void AppsContainer::switchTo(App * app) {
if (app == hardwareTestApp()) {
if (app == hardwareTestApp() || app == m_onBoardingApp) {
m_window.hideTitleBarView(true);
} else {
m_window.hideTitleBarView(false);
@@ -173,6 +182,9 @@ void AppsContainer::switchTo(App * app) {
m_window.setTitle(app->upperName());
}
Container::switchTo(app);
if (activeApp() == m_onBoardingApp) {
m_onBoardingApp->reinitOnBoarding();
}
}
void AppsContainer::updateBatteryState() {
@@ -206,12 +218,16 @@ void AppsContainer::reloadTitleBar() {
m_window.reloadTitleBar();
}
void AppsContainer::windowRedraw() {
m_window.redraw();
}
Window * AppsContainer::window() {
return &m_window;
}
int AppsContainer::numberOfTimers() {
return 4+(GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::Activate);
return 4+(GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::Activate) + (m_onBoardingApp->hasTimer());
}
Timer * AppsContainer::timerAtIndex(int i) {
@@ -225,6 +241,10 @@ Timer * AppsContainer::timerAtIndex(int i) {
case 3:
return &m_backlightDimmingTimer;
case 4:
if (m_onBoardingApp->hasTimer() == 1) {
return m_onBoardingApp->timer();
}
case 5:
return &m_ledTimer;
default:
assert(false);

View File

@@ -6,6 +6,7 @@
#include "probability/app.h"
#include "calculation/app.h"
#include "hardware_test/app.h"
#include "on_boarding/app.h"
#include "regression/app.h"
#include "sequence/app.h"
#include "settings/app.h"
@@ -57,6 +58,7 @@ public:
void displayExamModePopUp(bool activate, bool forceRedrawWindow);
void shutdownDueToLowBattery();
void reloadTitleBar();
void windowRedraw();
private:
Window * window() override;
int numberOfTimers() override;
@@ -76,6 +78,7 @@ private:
USBTimer m_USBTimer;
SuspendTimer m_suspendTimer;
BacklightDimmingTimer m_backlightDimmingTimer;
OnBoarding::App * m_onBoardingApp;
Home::App * m_homeApp;
Graph::App * m_graphApp;
Probability::App * m_probabilityApp;

View File

@@ -17,7 +17,7 @@ constexpr static char deviationFrenchDefinition[] = {Ion::Charset::SmallSigma, '
constexpr static char deviationEnglishDefinition[] = {Ion::Charset::SmallSigma, ':', ' ', 'S', 't', 'a', 'n', 'd', 'a', 'r', 'd', ' ','d','e', 'v', 'i', 'a', 't','i','o','n', 0};
constexpr static char deviationSpanishDefinition[] = {Ion::Charset::SmallSigma, ' ', ':', ' ', 'D', 'e','s','v','i','a','c','i','o','n',' ','t','i','p','i','c','a',0};
const char * messages[211][3] {
const char * messages[217][3] {
{"Attention", "Warning", "Cuidado"},
{"Valider", "Confirm", "Confirmar"},
{"Annuler", "Cancel", "Cancelar"},
@@ -264,6 +264,14 @@ const char * messages[211][3] {
{"sci/", "sci/", "sci/"},
{"Version du logiciel", "Software version", "Version de software"},
{"Numero serie", "Serial number", "Numero serie"},
/* On boarding */
{"MISE A JOUR DISPONIBLE", "UPDATE AVAILABLE", "ACTUALIZACION DISPONIBLE"},
{"Des ameliorations importantes existent", "There are important upgrades", "Hay mejoras importantes"},
{"pour votre calculatrice.", "for your calculator.", "para su calculadora."},
{"Connectez-vous depuis votre ordinateur", "Browse our page from your computer", "Visita nuestra pagina desde su ordenador"},
{"www.numworks.com/update", "www.numworks.com/update", "www.numworks.com/update"},
{"Passer", "Skip", "Saltar"},
};
const char sxy[4] = {Ion::Charset::CapitalSigma, 'x', 'y', 0};

View File

@@ -238,6 +238,14 @@ namespace I18n {
SoftwareVersion,
SerialNumber,
/* On boarding */
UpdateAvailable,
UpdateMessage1,
UpdateMessage2,
UpdateMessage3,
UpdateMessage4,
Skip,
/* UNIVERSAL MESSAGES */
Default = 0x8000,
Alpha,

View File

@@ -3,7 +3,7 @@
AppsContainer container;
void ion_app() {
container.switchTo(container.appAtIndex(0));
container.switchTo(container.appAtIndex(-1));
container.run();
container.switchTo(nullptr);
}

10
apps/on_boarding/Makefile Normal file
View File

@@ -0,0 +1,10 @@
app_objs += $(addprefix apps/on_boarding/,\
app.o\
language_controller.o\
logo_controller.o\
logo_view.o\
update_controller.o\
)
app_images += apps/on_boarding/logo_icon.png

24
apps/on_boarding/app.cpp Normal file
View File

@@ -0,0 +1,24 @@
#include "app.h"
namespace OnBoarding {
App::App(Container * container) :
::App(container, &m_languageController),
m_languageController(&m_modalViewController, &m_logoController),
m_logoController()
{
}
void App::reinitOnBoarding() {
m_languageController.reinitOnBoarding();
}
bool App::hasTimer() {
return firstResponder() == &m_logoController;
}
Timer * App::timer() {
return &m_logoController;
}
}

23
apps/on_boarding/app.h Normal file
View File

@@ -0,0 +1,23 @@
#ifndef ON_BOARDING_APP_H
#define ON_BOARDING_APP_H
#include <escher.h>
#include "language_controller.h"
#include "logo_controller.h"
namespace OnBoarding {
class App : public ::App {
public:
App(Container * container);
void reinitOnBoarding();
bool hasTimer();
Timer * timer();
private:
LanguageController m_languageController;
LogoController m_logoController;
};
}
#endif

View File

@@ -0,0 +1,63 @@
#include "language_controller.h"
#include "../global_preferences.h"
#include "../apps_container.h"
namespace OnBoarding {
LanguageController::LanguageController(Responder * parentResponder, LogoController * logoController) :
ViewController(parentResponder),
m_logoController(logoController),
m_cells{MessageTableCell(I18n::Message::Default, KDText::FontSize::Large), MessageTableCell(I18n::Message::Default, KDText::FontSize::Large), MessageTableCell(I18n::Message::Default, KDText::FontSize::Large)},
m_selectableTableView(SelectableTableView(this, this, 0, 1, (Ion::Display::Height - I18n::NumberOfLanguages*Metric::ParameterCellHeight)/2, Metric::CommonRightMargin, 0, Metric::CommonLeftMargin, this))
{
}
View * LanguageController::view() {
return &m_selectableTableView;
}
void LanguageController::reinitOnBoarding() {
m_selectableTableView.deselectTable();
selectCellAtLocation(0, 0);
app()->displayModalViewController(m_logoController, 0.5f, 0.5f);
}
void LanguageController::didBecomeFirstResponder() {
app()->setFirstResponder(&m_selectableTableView);
}
bool LanguageController::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::OK || event == Ion::Events::EXE) {
GlobalPreferences::sharedGlobalPreferences()->setLanguage((I18n::Language)(selectedRow()+1));
app()->displayModalViewController(&m_updateController, 0.5f, 0.5f);
return true;
}
if (event == Ion::Events::Back) {
return true;
}
return false;
}
int LanguageController::numberOfRows() {
return I18n::NumberOfLanguages;
}
KDCoordinate LanguageController::cellHeight() {
return Metric::ParameterCellHeight;
}
HighlightCell * LanguageController::reusableCell(int index) {
return &m_cells[index];
}
int LanguageController::reusableCellCount() {
return I18n::NumberOfLanguages;
}
void LanguageController::willDisplayCellForIndex(HighlightCell * cell, int index) {
MessageTableCell * myCell = (MessageTableCell *) cell;
I18n::Message languages[I18n::NumberOfLanguages] = {I18n::Message::French, I18n::Message::English, I18n::Message::Spanish};
myCell->setMessage(languages[index]);
}
}

View File

@@ -0,0 +1,34 @@
#ifndef ON_BOARDING_LANGUAGE_CONTROLLER_H
#define ON_BOARDING_LANGUAGE_CONTROLLER_H
#include <escher.h>
#include "../i18n.h"
#include "logo_controller.h"
#include "update_controller.h"
namespace OnBoarding {
class LanguageController : public ViewController, public SimpleListViewDataSource, public SelectableTableViewDelegate {
public:
LanguageController(Responder * parentResponder, LogoController * logoController);
View * view() override;
void reinitOnBoarding();
void didBecomeFirstResponder() override;
bool handleEvent(Ion::Events::Event event) override;
int numberOfRows() override;
KDCoordinate cellHeight() override;
HighlightCell * reusableCell(int index) override;
int reusableCellCount() override;
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
private:
LogoController * m_logoController;
UpdateController m_updateController;
MessageTableCell m_cells[I18n::NumberOfLanguages];
SelectableTableView m_selectableTableView;
};
}
#endif

View File

@@ -0,0 +1,24 @@
#include "logo_controller.h"
#include "logo_icon.h"
#include "../apps_container.h"
namespace OnBoarding {
LogoController::LogoController() :
ViewController(nullptr),
Timer(10),
m_logoView()
{
}
View * LogoController::view() {
return &m_logoView;
}
void LogoController::fire() {
app()->dismissModalViewController();
AppsContainer * appsContainer = (AppsContainer *)app()->container();
appsContainer->windowRedraw();
}
}

View File

@@ -0,0 +1,21 @@
#ifndef APPS_LOGO_CONTROLLER_H
#define APPS_LOGO_CONTROLLER_H
#include <escher.h>
#include "logo_view.h"
namespace OnBoarding {
class LogoController : public ViewController, public Timer {
public:
LogoController();
View * view() override;
private:
void fire() override;
LogoView m_logoView;
};
}
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -0,0 +1,30 @@
#include "logo_view.h"
#include "logo_icon.h"
#include <assert.h>
namespace OnBoarding {
LogoView::LogoView() :
View()
{
m_logoView.setImage(ImageStore::LogoIcon);
}
void LogoView::drawRect(KDContext * ctx, KDRect rect) const {
ctx->fillRect(bounds(), KDColorWhite);
}
int LogoView::numberOfSubviews() const {
return 1;
}
View * LogoView::subviewAtIndex(int index) {
assert(index == 0);
return &m_logoView;
}
void LogoView::layoutSubviews() {
m_logoView.setFrame(KDRect((Ion::Display::Width - ImageStore::LogoIcon->width())/2, (Ion::Display::Height - ImageStore::LogoIcon->height())/2, ImageStore::LogoIcon->width(), ImageStore::LogoIcon->height()));
}
}

View File

@@ -0,0 +1,22 @@
#ifndef APPS_LOGO_VIEW_H
#define APPS_LOGO_VIEW_H
#include <escher.h>
namespace OnBoarding {
class LogoView : public View {
public:
LogoView();
void drawRect(KDContext * ctx, KDRect rect) const override;
private:
int numberOfSubviews() const override;
View * subviewAtIndex(int index) override;
void layoutSubviews() override;
ImageView m_logoView;
};
}
#endif

View File

@@ -0,0 +1,79 @@
#include "update_controller.h"
#include "../apps_container.h"
#include <assert.h>
UpdateController::UpdateController() :
ViewController(nullptr),
m_contentView()
{
}
View * UpdateController::view() {
return &m_contentView;
}
bool UpdateController::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::OK || event == Ion::Events::EXE) {
app()->dismissModalViewController();
AppsContainer * appsContainer = (AppsContainer *)app()->container();
appsContainer->switchTo(appsContainer->appAtIndex(0));
return true;
}
return false;
}
UpdateController::ContentView::ContentView() :
m_titleTextView(MessageTextView(KDText::FontSize::Large, I18n::Message::UpdateAvailable, 0.5f, 0.5f)),
m_messageTextView1(MessageTextView(KDText::FontSize::Small, I18n::Message::UpdateMessage1, 0.5f, 0.5f)),
m_messageTextView2(MessageTextView(KDText::FontSize::Small, I18n::Message::UpdateMessage2, 0.5f, 0.5f)),
m_messageTextView3(MessageTextView(KDText::FontSize::Small, I18n::Message::UpdateMessage3, 0.5f, 0.5f)),
m_messageTextView4(MessageTextView(KDText::FontSize::Small, I18n::Message::UpdateMessage4, 0.5f, 0.5f, Palette::YellowDark)),
m_skipView(MessageTextView(KDText::FontSize::Small, I18n::Message::Skip, 1.0f, 0.5)),
m_okView()
{
}
void UpdateController::ContentView::drawRect(KDContext * ctx, KDRect rect) const {
ctx->fillRect(bounds(), KDColorWhite);
}
int UpdateController::ContentView::numberOfSubviews() const {
return 7;
}
View * UpdateController::ContentView::subviewAtIndex(int index) {
switch (index) {
case 0:
return &m_titleTextView;
case 1:
return &m_messageTextView1;
case 2:
return &m_messageTextView2;
case 3:
return &m_messageTextView3;
case 4:
return &m_messageTextView4;
case 5:
return &m_skipView;
case 6:
return &m_okView;
default:
assert(false);
return nullptr;
}
}
void UpdateController::ContentView::layoutSubviews() {
KDCoordinate height = bounds().height();
KDCoordinate width = bounds().width();
KDCoordinate titleHeight = m_titleTextView.minimalSizeForOptimalDisplay().height();
KDCoordinate textHeight = KDText::stringSize(" ", KDText::FontSize::Small).height();
m_titleTextView.setFrame(KDRect(0, k_titleMargin, width, titleHeight));
m_messageTextView1.setFrame(KDRect(0, k_paragraphHeight, width, textHeight));
m_messageTextView2.setFrame(KDRect(0, k_paragraphHeight+textHeight, width, textHeight));
m_messageTextView3.setFrame(KDRect(0, k_paragraphHeight+2*textHeight+k_paragraphMargin, width, textHeight));
m_messageTextView4.setFrame(KDRect(0, k_paragraphHeight+3*textHeight+k_paragraphMargin, width, textHeight));
KDSize okSize = m_okView.minimalSizeForOptimalDisplay();
m_skipView.setFrame(KDRect(0, height-k_bottomMargin-textHeight, width-okSize.width()-k_okMargin-k_skipMargin, textHeight));
m_okView.setFrame(KDRect(width - okSize.width()-k_okMargin, height-okSize.height()-k_okMargin, okSize));
}

View File

@@ -0,0 +1,39 @@
#ifndef ON_BOARDING_UPDATE_CONTROLLER_H
#define ON_BOARDING_UPDATE_CONTROLLER_H
#include <escher.h>
#include "../shared/ok_view.h"
class UpdateController : public ViewController {
public:
UpdateController();
View * view() override;
bool handleEvent(Ion::Events::Event event) override;
private:
class ContentView : public View {
public:
ContentView();
void drawRect(KDContext * ctx, KDRect rect) const override;
private:
constexpr static KDCoordinate k_titleMargin = 40;
constexpr static KDCoordinate k_paragraphHeight = 100;
constexpr static KDCoordinate k_paragraphMargin = 13;
constexpr static KDCoordinate k_bottomMargin = 13;
constexpr static KDCoordinate k_okMargin = 10;
constexpr static KDCoordinate k_skipMargin = 4;
int numberOfSubviews() const override;
View * subviewAtIndex(int index) override;
void layoutSubviews() override;
MessageTextView m_titleTextView;
MessageTextView m_messageTextView1;
MessageTextView m_messageTextView2;
MessageTextView m_messageTextView3;
MessageTextView m_messageTextView4;
MessageTextView m_skipView;
Shared::OkView m_okView;
};
ContentView m_contentView;
};
#endif