mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[apps/variable_box] Prepare for Code::VariableBox factorization
This commit is contained in:
@@ -34,10 +34,11 @@ apps_src += $(addprefix apps/,\
|
||||
lock_view.cpp \
|
||||
main.cpp \
|
||||
math_toolbox.cpp \
|
||||
math_variable_box_controller.cpp \
|
||||
math_variable_box_empty_controller.cpp \
|
||||
shift_alpha_lock_view.cpp \
|
||||
suspend_timer.cpp \
|
||||
title_bar_view.cpp \
|
||||
variable_box_controller.cpp \
|
||||
variable_box_empty_controller.cpp \
|
||||
)
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ MathToolbox * AppsContainer::mathToolbox() {
|
||||
return &m_mathToolbox;
|
||||
}
|
||||
|
||||
VariableBoxController * AppsContainer::variableBoxController() {
|
||||
MathVariableBoxController * AppsContainer::variableBoxController() {
|
||||
return &m_variableBoxController;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "apps_window.h"
|
||||
#include "empty_battery_window.h"
|
||||
#include "math_toolbox.h"
|
||||
#include "variable_box_controller.h"
|
||||
#include "math_variable_box_controller.h"
|
||||
#include "exam_pop_up_controller.h"
|
||||
#include "exam_pop_up_controller_delegate.h"
|
||||
#include "battery_timer.h"
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
void reset();
|
||||
Poincare::Context * globalContext();
|
||||
MathToolbox * mathToolbox();
|
||||
VariableBoxController * variableBoxController();
|
||||
MathVariableBoxController * variableBoxController();
|
||||
void suspend(bool checkIfOnOffKeyReleased = false);
|
||||
bool dispatchEvent(Ion::Events::Event event) override;
|
||||
bool switchTo(App::Snapshot * snapshot) override;
|
||||
@@ -70,7 +70,7 @@ private:
|
||||
EmptyBatteryWindow m_emptyBatteryWindow;
|
||||
Shared::GlobalContext m_globalContext;
|
||||
MathToolbox m_mathToolbox;
|
||||
VariableBoxController m_variableBoxController;
|
||||
MathVariableBoxController m_variableBoxController;
|
||||
ExamPopUpController m_examPopUpController;
|
||||
OnBoarding::PopUpController m_promptController;
|
||||
BatteryTimer m_batteryTimer;
|
||||
|
||||
@@ -77,9 +77,9 @@ CodePoint App::XNT() {
|
||||
}
|
||||
|
||||
NestedMenuController * App::variableBoxForInputEventHandler(InputEventHandler * textInput) {
|
||||
VariableBoxController * varBox = AppsContainer::sharedAppsContainer()->variableBoxController();
|
||||
MathVariableBoxController * varBox = AppsContainer::sharedAppsContainer()->variableBoxController();
|
||||
varBox->setSender(textInput);
|
||||
varBox->lockDeleteEvent(VariableBoxController::Page::Function);
|
||||
varBox->lockDeleteEvent(MathVariableBoxController::Page::Function);
|
||||
return varBox;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "variable_box_controller.h"
|
||||
#include "math_variable_box_controller.h"
|
||||
#include "shared/global_context.h"
|
||||
#include "shared/continuous_function.h"
|
||||
#include <escher/metric.h>
|
||||
@@ -14,7 +14,7 @@ using namespace Poincare;
|
||||
using namespace Shared;
|
||||
using namespace Ion;
|
||||
|
||||
VariableBoxController::VariableBoxController() :
|
||||
MathVariableBoxController::MathVariableBoxController() :
|
||||
AlternateEmptyNestedMenuController(I18n::Message::Variables),
|
||||
m_currentPage(Page::RootMenu),
|
||||
m_lockPageDelete(Page::RootMenu),
|
||||
@@ -25,20 +25,20 @@ VariableBoxController::VariableBoxController() :
|
||||
}
|
||||
}
|
||||
|
||||
void VariableBoxController::viewWillAppear() {
|
||||
void MathVariableBoxController::viewWillAppear() {
|
||||
assert(m_currentPage == Page::RootMenu);
|
||||
AlternateEmptyNestedMenuController::viewWillAppear();
|
||||
}
|
||||
|
||||
void VariableBoxController::viewDidDisappear() {
|
||||
void MathVariableBoxController::viewDidDisappear() {
|
||||
AlternateEmptyNestedMenuController::viewDidDisappear();
|
||||
|
||||
/* NestedMenuController::viewDidDisappear might need cell heights, which would
|
||||
* use the VariableBoxController cell heights memoization. We thus reset the
|
||||
* VariableBoxController layouts only after calling the parent's
|
||||
* use the MathVariableBoxController cell heights memoization. We thus reset the
|
||||
* MathVariableBoxController layouts only after calling the parent's
|
||||
* viewDidDisappear. */
|
||||
|
||||
// Tidy the layouts displayed in the VariableBoxController to clean TreePool
|
||||
// Tidy the layouts displayed in the MathVariableBoxController to clean TreePool
|
||||
for (int i = 0; i < k_maxNumberOfDisplayedRows; i++) {
|
||||
m_leafCells[i].setLayout(Layout());
|
||||
m_leafCells[i].setAccessoryLayout(Layout());
|
||||
@@ -49,7 +49,7 @@ void VariableBoxController::viewDidDisappear() {
|
||||
setPage(Page::RootMenu);
|
||||
}
|
||||
|
||||
bool VariableBoxController::handleEvent(Ion::Events::Event event) {
|
||||
bool MathVariableBoxController::handleEvent(Ion::Events::Event event) {
|
||||
/* We do not want to handle backspace event if:
|
||||
* - On the root menu page
|
||||
* The deletion on the current page is locked
|
||||
@@ -68,7 +68,7 @@ bool VariableBoxController::handleEvent(Ion::Events::Event event) {
|
||||
return AlternateEmptyNestedMenuController::handleEvent(event);
|
||||
}
|
||||
|
||||
int VariableBoxController::numberOfRows() const {
|
||||
int MathVariableBoxController::numberOfRows() const {
|
||||
switch (m_currentPage) {
|
||||
case Page::RootMenu:
|
||||
return k_numberOfMenuRows;
|
||||
@@ -81,7 +81,7 @@ int VariableBoxController::numberOfRows() const {
|
||||
}
|
||||
}
|
||||
|
||||
int VariableBoxController::reusableCellCount(int type) {
|
||||
int MathVariableBoxController::reusableCellCount(int type) {
|
||||
assert(type < 2);
|
||||
if (type == 0) {
|
||||
return k_maxNumberOfDisplayedRows;
|
||||
@@ -89,7 +89,7 @@ int VariableBoxController::reusableCellCount(int type) {
|
||||
return k_numberOfMenuRows;
|
||||
}
|
||||
|
||||
void VariableBoxController::willDisplayCellForIndex(HighlightCell * cell, int index) {
|
||||
void MathVariableBoxController::willDisplayCellForIndex(HighlightCell * cell, int index) {
|
||||
if (m_currentPage == Page::RootMenu) {
|
||||
I18n::Message label = nodeLabelAtIndex(index);
|
||||
MessageTableCell * myCell = (MessageTableCell *)cell;
|
||||
@@ -119,7 +119,7 @@ void VariableBoxController::willDisplayCellForIndex(HighlightCell * cell, int in
|
||||
myCell->reloadCell();
|
||||
}
|
||||
|
||||
KDCoordinate VariableBoxController::rowHeight(int index) {
|
||||
KDCoordinate MathVariableBoxController::rowHeight(int index) {
|
||||
if (m_currentPage != Page::RootMenu) {
|
||||
Layout layoutR = expressionLayoutForRecord(recordAtIndex(index), index);
|
||||
if (!layoutR.isUninitialized()) {
|
||||
@@ -129,34 +129,34 @@ KDCoordinate VariableBoxController::rowHeight(int index) {
|
||||
return AlternateEmptyNestedMenuController::rowHeight(index);
|
||||
}
|
||||
|
||||
int VariableBoxController::typeAtLocation(int i, int j) {
|
||||
int MathVariableBoxController::typeAtLocation(int i, int j) {
|
||||
if (m_currentPage == Page::RootMenu) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ExpressionTableCellWithExpression * VariableBoxController::leafCellAtIndex(int index) {
|
||||
ExpressionTableCellWithExpression * MathVariableBoxController::leafCellAtIndex(int index) {
|
||||
assert(index >= 0 && index < k_maxNumberOfDisplayedRows);
|
||||
return &m_leafCells[index];
|
||||
}
|
||||
|
||||
MessageTableCellWithChevron * VariableBoxController::nodeCellAtIndex(int index) {
|
||||
MessageTableCellWithChevron * MathVariableBoxController::nodeCellAtIndex(int index) {
|
||||
assert(index >= 0 && index < k_numberOfMenuRows);
|
||||
return &m_nodeCells[index];
|
||||
}
|
||||
|
||||
VariableBoxController::Page VariableBoxController::pageAtIndex(int index) {
|
||||
MathVariableBoxController::Page MathVariableBoxController::pageAtIndex(int index) {
|
||||
Page pages[2] = {Page::Expression, Page::Function};
|
||||
return pages[index];
|
||||
}
|
||||
|
||||
void VariableBoxController::setPage(Page page) {
|
||||
void MathVariableBoxController::setPage(Page page) {
|
||||
m_currentPage = page;
|
||||
resetMemoization();
|
||||
}
|
||||
|
||||
bool VariableBoxController::selectSubMenu(int selectedRow) {
|
||||
bool MathVariableBoxController::selectSubMenu(int selectedRow) {
|
||||
m_selectableTableView.deselectTable();
|
||||
setPage(pageAtIndex(selectedRow));
|
||||
bool selectSubMenu = AlternateEmptyNestedMenuController::selectSubMenu(selectedRow);
|
||||
@@ -166,7 +166,7 @@ bool VariableBoxController::selectSubMenu(int selectedRow) {
|
||||
return selectSubMenu;
|
||||
}
|
||||
|
||||
bool VariableBoxController::returnToPreviousMenu() {
|
||||
bool MathVariableBoxController::returnToPreviousMenu() {
|
||||
if (isDisplayingEmptyController()) {
|
||||
pop();
|
||||
} else {
|
||||
@@ -176,7 +176,7 @@ bool VariableBoxController::returnToPreviousMenu() {
|
||||
return AlternateEmptyNestedMenuController::returnToPreviousMenu();
|
||||
}
|
||||
|
||||
bool VariableBoxController::selectLeaf(int selectedRow) {
|
||||
bool MathVariableBoxController::selectLeaf(int selectedRow) {
|
||||
if (isDisplayingEmptyController()) {
|
||||
/* We do not want to handle OK/EXE events in that case. */
|
||||
return false;
|
||||
@@ -210,13 +210,13 @@ bool VariableBoxController::selectLeaf(int selectedRow) {
|
||||
return true;
|
||||
}
|
||||
|
||||
I18n::Message VariableBoxController::nodeLabelAtIndex(int index) {
|
||||
I18n::Message MathVariableBoxController::nodeLabelAtIndex(int index) {
|
||||
assert(m_currentPage == Page::RootMenu);
|
||||
I18n::Message labels[2] = {I18n::Message::Expressions, I18n::Message::Functions};
|
||||
return labels[index];
|
||||
}
|
||||
|
||||
Layout VariableBoxController::expressionLayoutForRecord(Storage::Record record, int index) {
|
||||
Layout MathVariableBoxController::expressionLayoutForRecord(Storage::Record record, int index) {
|
||||
assert(m_currentPage != Page::RootMenu);
|
||||
assert(index >= 0);
|
||||
if (index >= m_firstMemoizedLayoutIndex+k_maxNumberOfDisplayedRows || index < m_firstMemoizedLayoutIndex) {
|
||||
@@ -246,30 +246,30 @@ Layout VariableBoxController::expressionLayoutForRecord(Storage::Record record,
|
||||
return m_layouts[index-m_firstMemoizedLayoutIndex];
|
||||
}
|
||||
|
||||
const char * VariableBoxController::extension() const {
|
||||
const char * MathVariableBoxController::extension() const {
|
||||
assert(m_currentPage != Page::RootMenu);
|
||||
return m_currentPage == Page::Function ? Ion::Storage::funcExtension : Ion::Storage::expExtension;
|
||||
}
|
||||
|
||||
Storage::Record VariableBoxController::recordAtIndex(int rowIndex) {
|
||||
Storage::Record MathVariableBoxController::recordAtIndex(int rowIndex) {
|
||||
assert(m_currentPage != Page::RootMenu);
|
||||
assert(!Storage::sharedStorage()->recordWithExtensionAtIndex(extension(), rowIndex).isNull());
|
||||
return Storage::sharedStorage()->recordWithExtensionAtIndex(extension(), rowIndex);
|
||||
}
|
||||
|
||||
ViewController * VariableBoxController::emptyViewController() {
|
||||
m_emptyViewController.setType((VariableBoxEmptyController::Type)m_currentPage);
|
||||
ViewController * MathVariableBoxController::emptyViewController() {
|
||||
m_emptyViewController.setType((MathVariableBoxEmptyController::Type)m_currentPage);
|
||||
return &m_emptyViewController;
|
||||
}
|
||||
|
||||
void VariableBoxController::resetMemoization() {
|
||||
void MathVariableBoxController::resetMemoization() {
|
||||
for (int i = 0; i < k_maxNumberOfDisplayedRows; i++) {
|
||||
m_layouts[i] = Layout();
|
||||
}
|
||||
m_firstMemoizedLayoutIndex = 0;
|
||||
}
|
||||
|
||||
void VariableBoxController::destroyRecordAtRowIndex(int rowIndex) {
|
||||
void MathVariableBoxController::destroyRecordAtRowIndex(int rowIndex) {
|
||||
// Destroy the record
|
||||
recordAtIndex(rowIndex).destroy();
|
||||
// Shift the memoization if needed
|
||||
@@ -1,15 +1,13 @@
|
||||
#ifndef APPS_VARIABLE_BOX_CONTROLLER_H
|
||||
#define APPS_VARIABLE_BOX_CONTROLLER_H
|
||||
|
||||
#define MATRIX_VARIABLES 1
|
||||
#ifndef APPS_MATH_VARIABLE_BOX_CONTROLLER_H
|
||||
#define APPS_MATH_VARIABLE_BOX_CONTROLLER_H
|
||||
|
||||
#include "alternate_empty_nested_menu_controller.h"
|
||||
#include "variable_box_empty_controller.h"
|
||||
#include "math_variable_box_empty_controller.h"
|
||||
#include <apps/i18n.h>
|
||||
|
||||
class VariableBoxController : public AlternateEmptyNestedMenuController {
|
||||
class MathVariableBoxController : public AlternateEmptyNestedMenuController {
|
||||
public:
|
||||
VariableBoxController();
|
||||
MathVariableBoxController();
|
||||
|
||||
// View Controller
|
||||
void viewWillAppear() override;
|
||||
@@ -32,6 +30,7 @@ public:
|
||||
Function = 2
|
||||
};
|
||||
void lockDeleteEvent(Page page) { m_lockPageDelete = page; }
|
||||
|
||||
private:
|
||||
constexpr static int k_maxNumberOfDisplayedRows = (Ion::Display::Height - Metric::TitleBarHeight - Metric::PopUpTopMargin - Metric::StackTitleHeight) / Metric::ToolboxRowHeight + 2; // (240 - 18 - 50 - 20) / 40 = 3.8; the 0.8 cell can be above and below so we add +2 to get 5
|
||||
constexpr static int k_numberOfMenuRows = 2;
|
||||
@@ -55,7 +54,7 @@ private:
|
||||
Page m_lockPageDelete;
|
||||
ExpressionTableCellWithExpression m_leafCells[k_maxNumberOfDisplayedRows];
|
||||
MessageTableCellWithChevron m_nodeCells[k_numberOfMenuRows];
|
||||
VariableBoxEmptyController m_emptyViewController;
|
||||
MathVariableBoxEmptyController m_emptyViewController;
|
||||
// Layout memoization
|
||||
// TODO: make a helper doing the RingMemoizationOfConsecutiveObjets to factorize this code and ExpressionModelStore code
|
||||
int m_firstMemoizedLayoutIndex;
|
||||
53
apps/math_variable_box_empty_controller.cpp
Normal file
53
apps/math_variable_box_empty_controller.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#include "math_variable_box_empty_controller.h"
|
||||
#include <poincare/layout_helper.h>
|
||||
#include <apps/i18n.h>
|
||||
#include <assert.h>
|
||||
|
||||
MathVariableBoxEmptyController::MathVariableBoxEmptyView::MathVariableBoxEmptyView() :
|
||||
VariableBoxEmptyView(),
|
||||
m_layoutExample(0.5f, 0.5f, KDColorBlack, Palette::WallScreen)
|
||||
{
|
||||
initMessageViews();
|
||||
}
|
||||
|
||||
void MathVariableBoxEmptyController::MathVariableBoxEmptyView::setLayout(Poincare::Layout layout) {
|
||||
m_layoutExample.setLayout(layout);
|
||||
}
|
||||
|
||||
void MathVariableBoxEmptyController::viewDidDisappear() {
|
||||
m_view.setLayout(Poincare::Layout());
|
||||
}
|
||||
|
||||
void MathVariableBoxEmptyController::setType(Type type) {
|
||||
I18n::Message messages[MathVariableBoxEmptyView::k_numberOfMessages] = {
|
||||
I18n::Message::Default,
|
||||
I18n::Message::Default,
|
||||
I18n::Message::Default,
|
||||
I18n::Message::EnableCharacters
|
||||
};
|
||||
Poincare::Layout layout;
|
||||
switch (type) {
|
||||
case Type::Expressions:
|
||||
{
|
||||
messages[0] = I18n::Message::EmptyExpressionBox0;
|
||||
messages[1] = I18n::Message::EmptyExpressionBox1;
|
||||
messages[2] = I18n::Message::EmptyExpressionBox2;
|
||||
const char * storeExpression = "3→A";
|
||||
layout = Poincare::LayoutHelper::String(storeExpression, strlen(storeExpression), MathVariableBoxEmptyView::k_font);
|
||||
break;
|
||||
}
|
||||
case Type::Functions:
|
||||
{
|
||||
messages[0] = I18n::Message::EmptyFunctionBox0;
|
||||
messages[1] = I18n::Message::EmptyFunctionBox1;
|
||||
messages[2] = I18n::Message::EmptyFunctionBox2;
|
||||
const char * storeFunction = "3+x→f(x)";
|
||||
layout = Poincare::LayoutHelper::String(storeFunction, strlen(storeFunction), MathVariableBoxEmptyView::k_font);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
m_view.setMessages(messages);
|
||||
m_view.setLayout(layout);
|
||||
}
|
||||
41
apps/math_variable_box_empty_controller.h
Normal file
41
apps/math_variable_box_empty_controller.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef APPS_MATH_VARIABLE_BOX_EMPTY_CONTROLLER_H
|
||||
#define APPS_MATH_VARIABLE_BOX_EMPTY_CONTROLLER_H
|
||||
|
||||
#include <poincare/layout.h>
|
||||
#include "variable_box_empty_controller.h"
|
||||
|
||||
class MathVariableBoxEmptyController : public VariableBoxEmptyController {
|
||||
public:
|
||||
MathVariableBoxEmptyController() :
|
||||
VariableBoxEmptyController(),
|
||||
m_view()
|
||||
{}
|
||||
enum class Type {
|
||||
None = 0,
|
||||
Expressions = 1,
|
||||
Functions = 2
|
||||
};
|
||||
void setType(Type type);
|
||||
// View Controller
|
||||
View * view() override { return &m_view; }
|
||||
void viewDidDisappear() override;
|
||||
private:
|
||||
class MathVariableBoxEmptyView : public VariableBoxEmptyView {
|
||||
public:
|
||||
constexpr static int k_numberOfMessages = 4;
|
||||
MathVariableBoxEmptyView();
|
||||
void setLayout(Poincare::Layout layout);
|
||||
private:
|
||||
int numberOfMessageTextViews() const override { return k_numberOfMessages; }
|
||||
MessageTextView * messageTextViewAtIndex(int index) override {
|
||||
assert(index >= 0 && index < k_numberOfMessages);
|
||||
return &m_messages[index];
|
||||
}
|
||||
ExpressionView * expressionView() override { return &m_layoutExample; }
|
||||
MessageTextView m_messages[k_numberOfMessages];
|
||||
ExpressionView m_layoutExample;
|
||||
};
|
||||
MathVariableBoxEmptyView m_view;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -20,9 +20,9 @@ Toolbox * InputEventHandlerDelegateApp::toolboxForInputEventHandler(InputEventHa
|
||||
}
|
||||
|
||||
NestedMenuController * InputEventHandlerDelegateApp::variableBoxForInputEventHandler(InputEventHandler * textInput) {
|
||||
VariableBoxController * varBox = AppsContainer::sharedAppsContainer()->variableBoxController();
|
||||
MathVariableBoxController * varBox = AppsContainer::sharedAppsContainer()->variableBoxController();
|
||||
varBox->setSender(textInput);
|
||||
varBox->lockDeleteEvent(VariableBoxController::Page::RootMenu);
|
||||
varBox->lockDeleteEvent(MathVariableBoxController::Page::RootMenu);
|
||||
return varBox;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,29 +3,28 @@
|
||||
#include <apps/i18n.h>
|
||||
#include <assert.h>
|
||||
|
||||
using namespace Poincare;
|
||||
using namespace Ion;
|
||||
|
||||
VariableBoxEmptyController::VariableBoxEmptyView::VariableBoxEmptyView() :
|
||||
m_layoutExample(0.5f, 0.5f, KDColorBlack, Palette::WallScreen)
|
||||
{
|
||||
for (int i = 0; i < k_numberOfMessages; i++) {
|
||||
m_messages[i].setFont(k_font);
|
||||
m_messages[i].setAlignment(0.5f, 0.5f);
|
||||
m_messages[i].setBackgroundColor(Palette::WallScreen);
|
||||
}
|
||||
m_messages[0].setAlignment(0.5f,1.0f);
|
||||
m_messages[k_numberOfMessages-1].setAlignment(0.5f,0.0f);
|
||||
}
|
||||
|
||||
void VariableBoxEmptyController::VariableBoxEmptyView::setMessages(I18n::Message * message) {
|
||||
for (int i = 0; i < k_numberOfMessages; i++) {
|
||||
m_messages[i].setMessage(message[i]);
|
||||
// VariableBoxEmptyController::VariableBoxEmptyView
|
||||
void VariableBoxEmptyController::VariableBoxEmptyView::initMessageViews() {
|
||||
const int numberOfMessageViews = numberOfMessageTextViews();
|
||||
for (int i = 0; i < numberOfMessageViews; i++) {
|
||||
MessageTextView * message = messageTextViewAtIndex(i);
|
||||
message->setFont(k_font);
|
||||
message->setBackgroundColor(Palette::WallScreen);
|
||||
float verticalAlignment = 0.5f;
|
||||
if (i == 0) {
|
||||
verticalAlignment = 1.0f;
|
||||
} else if (i == numberOfMessageViews - 1) {
|
||||
verticalAlignment = 0.0f;
|
||||
}
|
||||
message->setAlignment(0.5f, verticalAlignment);
|
||||
}
|
||||
}
|
||||
|
||||
void VariableBoxEmptyController::VariableBoxEmptyView::setLayout(Poincare::Layout layout) {
|
||||
m_layoutExample.setLayout(layout);
|
||||
void VariableBoxEmptyController::VariableBoxEmptyView::setMessages(I18n::Message * message) {
|
||||
const int numberOfMessageViews = numberOfMessageTextViews();
|
||||
for (int i = 0; i < numberOfMessageViews; i++) {
|
||||
messageTextViewAtIndex(i)->setMessage(message[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void VariableBoxEmptyController::VariableBoxEmptyView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
@@ -33,76 +32,48 @@ void VariableBoxEmptyController::VariableBoxEmptyView::drawRect(KDContext * ctx,
|
||||
}
|
||||
|
||||
int VariableBoxEmptyController::VariableBoxEmptyView::numberOfSubviews() const {
|
||||
return k_numberOfMessages+1;
|
||||
return numberOfMessageTextViews() + hasExpressionView();
|
||||
}
|
||||
|
||||
View * VariableBoxEmptyController::VariableBoxEmptyView::subviewAtIndex(int index) {
|
||||
if (index == k_layoutRowIndex) {
|
||||
return &m_layoutExample;
|
||||
if (hasExpressionView()) {
|
||||
if (index == k_expressionViewRowIndex) {
|
||||
return expressionView();
|
||||
}
|
||||
return messageTextViewAtIndex(index + (index < k_expressionViewRowIndex ? 0 : -1));
|
||||
}
|
||||
if (index < k_layoutRowIndex) {
|
||||
return &m_messages[index];
|
||||
}
|
||||
return &m_messages[index-1];
|
||||
return messageTextViewAtIndex(index);
|
||||
}
|
||||
|
||||
void VariableBoxEmptyController::VariableBoxEmptyView::layoutSubviews(bool force) {
|
||||
KDCoordinate width = bounds().width() - 2*k_separatorThickness;
|
||||
KDCoordinate height = bounds().height() - 2*k_separatorThickness;
|
||||
const int numberOfMessageViews = numberOfMessageTextViews();
|
||||
const bool hasExpression = hasExpressionView();
|
||||
KDCoordinate width = bounds().width() - 2 * k_separatorThickness;
|
||||
KDCoordinate height = bounds().height() - 2 * k_separatorThickness;
|
||||
KDCoordinate textHeight = k_font->glyphSize().height();
|
||||
KDCoordinate layoutHeight = m_layoutExample.minimalSizeForOptimalDisplay().height();
|
||||
KDCoordinate margin = (height - k_numberOfMessages*textHeight-layoutHeight)/2;
|
||||
m_layoutExample.setFrame(KDRect(k_separatorThickness, k_separatorThickness+margin+k_layoutRowIndex*textHeight, width, layoutHeight), force);
|
||||
KDCoordinate layoutHeight = hasExpression ? expressionView()->minimalSizeForOptimalDisplay().height() : 0;
|
||||
KDCoordinate margin = (height - numberOfMessageViews * textHeight - layoutHeight) / 2;
|
||||
if (hasExpression) {
|
||||
expressionView()->setFrame(KDRect(
|
||||
k_separatorThickness,
|
||||
k_separatorThickness + margin + k_expressionViewRowIndex * textHeight,
|
||||
width,
|
||||
layoutHeight),
|
||||
force);
|
||||
}
|
||||
KDCoordinate currentHeight = k_separatorThickness;
|
||||
for (uint8_t i = 0; i < k_numberOfMessages; i++) {
|
||||
if (i == k_layoutRowIndex) {
|
||||
for (uint8_t i = 0; i < numberOfMessageViews; i++) {
|
||||
if (hasExpression && i == k_expressionViewRowIndex) {
|
||||
currentHeight += layoutHeight;
|
||||
}
|
||||
KDCoordinate h = i == 0 || i == k_numberOfMessages - 1 ? textHeight+margin : textHeight;
|
||||
m_messages[i].setFrame(KDRect(k_separatorThickness, currentHeight, width, h), force);
|
||||
KDCoordinate h = (i == 0 || i == numberOfMessageViews - 1) ? textHeight + margin : textHeight;
|
||||
messageTextViewAtIndex(i)->setFrame(KDRect(k_separatorThickness, currentHeight, width, h), force);
|
||||
currentHeight += h;
|
||||
}
|
||||
}
|
||||
|
||||
VariableBoxEmptyController::VariableBoxEmptyController() :
|
||||
ViewController(nullptr),
|
||||
m_view()
|
||||
{
|
||||
}
|
||||
// VariableBoxEmptyController
|
||||
|
||||
View * VariableBoxEmptyController::view() {
|
||||
return &m_view;
|
||||
}
|
||||
|
||||
void VariableBoxEmptyController::viewDidDisappear() {
|
||||
m_view.setLayout(Layout());
|
||||
}
|
||||
|
||||
void VariableBoxEmptyController::setType(Type type) {
|
||||
I18n::Message messages[VariableBoxEmptyView::k_numberOfMessages] = {I18n::Message::Default, I18n::Message::Default, I18n::Message::Default, I18n::Message::EnableCharacters};
|
||||
Layout layout;
|
||||
switch (type) {
|
||||
case Type::Expressions:
|
||||
{
|
||||
messages[0] = I18n::Message::EmptyExpressionBox0;
|
||||
messages[1] = I18n::Message::EmptyExpressionBox1;
|
||||
messages[2] = I18n::Message::EmptyExpressionBox2;
|
||||
const char * storeExpression = "3→A";
|
||||
layout = LayoutHelper::String(storeExpression, strlen(storeExpression), VariableBoxEmptyView::k_font);
|
||||
break;
|
||||
}
|
||||
case Type::Functions:
|
||||
{
|
||||
messages[0] = I18n::Message::EmptyFunctionBox0;
|
||||
messages[1] = I18n::Message::EmptyFunctionBox1;
|
||||
messages[2] = I18n::Message::EmptyFunctionBox2;
|
||||
const char * storeFunction = "3+x→f(x)";
|
||||
layout = LayoutHelper::String(storeFunction, strlen(storeFunction), VariableBoxEmptyView::k_font);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
m_view.setMessages(messages);
|
||||
m_view.setLayout(layout);
|
||||
void VariableBoxEmptyController::setMessages(I18n::Message * messages) {
|
||||
static_cast<VariableBoxEmptyView *>(view())->setMessages(messages);
|
||||
}
|
||||
|
||||
@@ -9,36 +9,29 @@
|
||||
|
||||
class VariableBoxEmptyController : public ViewController {
|
||||
public:
|
||||
VariableBoxEmptyController();
|
||||
enum class Type {
|
||||
None = 0,
|
||||
Expressions = 1,
|
||||
Functions = 2
|
||||
};
|
||||
VariableBoxEmptyController() : ViewController(nullptr) {}
|
||||
void setMessages(I18n::Message * messages);
|
||||
// View Controller
|
||||
View * view() override;
|
||||
DisplayParameter displayParameter() override { return DisplayParameter::DoNotShowOwnTitle; }
|
||||
void viewDidDisappear() override;
|
||||
|
||||
void setType(Type type);
|
||||
private:
|
||||
protected:
|
||||
class VariableBoxEmptyView : public View, public Bordered {
|
||||
public:
|
||||
static constexpr const KDFont * k_font = KDFont::SmallFont;
|
||||
VariableBoxEmptyView();
|
||||
constexpr static const KDFont * k_font = KDFont::SmallFont;
|
||||
void initMessageViews();
|
||||
void setMessages(I18n::Message * message);
|
||||
void setLayout(Poincare::Layout layout);
|
||||
void drawRect(KDContext * ctx, KDRect rect) const override;
|
||||
constexpr static int k_numberOfMessages = 4;
|
||||
private:
|
||||
constexpr static int k_expressionViewRowIndex = 2;
|
||||
int numberOfSubviews() const override;
|
||||
View * subviewAtIndex(int index) override;
|
||||
void layoutSubviews(bool force = false) override;
|
||||
constexpr static int k_layoutRowIndex = 2;
|
||||
MessageTextView m_messages[k_numberOfMessages];
|
||||
ExpressionView m_layoutExample;
|
||||
virtual int numberOfMessageTextViews() const = 0;
|
||||
virtual MessageTextView * messageTextViewAtIndex(int index) = 0;
|
||||
bool hasExpressionView() const {
|
||||
return const_cast<VariableBoxEmptyView *>(this)->expressionView() != nullptr;
|
||||
}
|
||||
virtual ExpressionView * expressionView() { return nullptr; }
|
||||
};
|
||||
VariableBoxEmptyView m_view;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user