From 0b2a58117745858765e6e3bbdac4dbef14cc1379 Mon Sep 17 00:00:00 2001 From: Laury Date: Fri, 24 Jun 2022 22:35:36 +0200 Subject: [PATCH] [escher] Rework of timers and bigger text in toolboxes --- apps/apps_container.cpp | 14 ++--- apps/apps_container.h | 2 - .../unit_list_controller.cpp | 2 +- .../additional_outputs/unit_list_controller.h | 2 +- apps/code/app.h | 2 +- apps/code/python_toolbox.cpp | 58 ++++++++--------- apps/code/python_toolbox.h | 14 +++-- apps/code/script_parameter_controller.h | 8 +-- apps/code/variable_box_controller.cpp | 2 +- apps/code/variable_box_controller.h | 2 +- .../calculation_parameter_controller.cpp | 2 +- .../graph/calculation_parameter_controller.h | 4 +- apps/graph/graph/curve_parameter_controller.h | 2 +- apps/graph/list/list_parameter_controller.h | 2 +- .../values/derivative_parameter_controller.h | 4 +- ...interval_parameter_selector_controller.cpp | 2 +- .../interval_parameter_selector_controller.h | 2 +- apps/math_toolbox.cpp | 8 ++- apps/math_toolbox.h | 8 +-- apps/math_variable_box_controller.cpp | 4 +- apps/math_variable_box_controller.h | 4 +- apps/on_boarding/app.cpp | 10 +-- apps/on_boarding/app.h | 3 - apps/on_boarding/logo_controller.cpp | 2 +- apps/reader/list_book_controller.cpp | 2 +- apps/reader/list_book_controller.h | 2 +- apps/regression/graph_options_controller.cpp | 2 +- apps/regression/graph_options_controller.h | 2 +- .../graph/curve_parameter_controller.h | 2 +- apps/settings/main_controller.cpp | 2 +- .../sub_menu/exam_mode_controller.cpp | 2 +- apps/settings/sub_menu/exam_mode_controller.h | 2 +- .../sub_menu/generic_sub_controller.cpp | 2 +- apps/shared/color_cell.h | 2 +- .../function_curve_parameter_controller.h | 2 +- apps/shared/list_parameter_controller.h | 2 +- apps/shared/localization_controller.cpp | 4 +- apps/shared/localization_controller.h | 2 +- apps/shared/store_parameter_controller.h | 2 +- .../values_function_parameter_controller.h | 2 +- apps/shared/values_parameter_controller.cpp | 2 +- apps/shared/values_parameter_controller.h | 6 +- .../equation_models_parameter_controller.h | 2 +- escher/Makefile | 2 + escher/include/escher.h | 3 + escher/include/escher/animated.h | 11 ++++ escher/include/escher/animation_timer.h | 25 ++++++++ escher/include/escher/app.h | 2 - escher/include/escher/container.h | 4 -- escher/include/escher/message_table_cell.h | 4 +- .../escher/message_table_cell_with_buffer.h | 2 +- .../escher/message_table_cell_with_chevron.h | 3 +- ...ssage_table_cell_with_chevron_and_buffer.h | 2 +- ...e_table_cell_with_chevron_and_expression.h | 2 +- ...sage_table_cell_with_chevron_and_message.h | 2 +- .../message_table_cell_with_editable_text.h | 2 +- .../message_table_cell_with_expression.h | 2 +- .../escher/message_table_cell_with_gauge.h | 2 +- .../escher/message_table_cell_with_message.h | 5 +- .../escher/message_table_cell_with_switch.h | 2 +- escher/include/escher/run_loop.h | 5 +- .../escher/slideable_message_text_view.h | 26 ++++++++ escher/include/escher/timer.h | 15 +++-- escher/include/escher/toolbox.h | 4 +- escher/include/escher/toolbox_message_tree.h | 22 +++++-- escher/src/animation_timer.cpp | 15 +++++ escher/src/container.cpp | 20 ------ escher/src/message_table_cell.cpp | 40 +++++++++--- .../src/message_table_cell_with_chevron.cpp | 18 +++++- .../src/message_table_cell_with_message.cpp | 33 ++++++---- escher/src/run_loop.cpp | 44 +++++++++---- escher/src/slideable_message_text_view.cpp | 63 +++++++++++++++++++ escher/src/toolbox.cpp | 9 +-- kandinsky/src/font.cpp | 19 ++++-- 74 files changed, 407 insertions(+), 208 deletions(-) create mode 100644 escher/include/escher/animated.h create mode 100644 escher/include/escher/animation_timer.h create mode 100644 escher/include/escher/slideable_message_text_view.h create mode 100644 escher/src/animation_timer.cpp create mode 100644 escher/src/slideable_message_text_view.cpp diff --git a/apps/apps_container.cpp b/apps/apps_container.cpp index f464b07c1..336b9e989 100644 --- a/apps/apps_container.cpp +++ b/apps/apps_container.cpp @@ -58,6 +58,11 @@ AppsContainer::AppsContainer() : Poincare::Expression::SetCircuitBreaker(AppsContainer::poincareCircuitBreaker); // #endif Ion::Storage::sharedStorage()->setDelegate(this); + + addTimer(&m_batteryTimer); + addTimer(&m_suspendTimer); + addTimer(&m_backlightDimmingTimer); + addTimer(&m_clockTimer); } bool AppsContainer::poincareCircuitBreaker() { @@ -458,15 +463,6 @@ Window * AppsContainer::window() { return &m_window; } -int AppsContainer::numberOfContainerTimers() { - return 4; -} - -Timer * AppsContainer::containerTimerAtIndex(int i) { - Timer * timers[4] = {&m_batteryTimer, &m_suspendTimer, &m_backlightDimmingTimer, &m_clockTimer}; - return timers[i]; -} - void AppsContainer::resetShiftAlphaStatus() { Ion::Events::setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::Default); updateAlphaLock(); diff --git a/apps/apps_container.h b/apps/apps_container.h index f52d50b6c..a8fca78dd 100644 --- a/apps/apps_container.h +++ b/apps/apps_container.h @@ -59,8 +59,6 @@ protected: Home::App::Snapshot * homeAppSnapshot() { return &m_homeSnapshot; } private: Window * window() override; - int numberOfContainerTimers() override; - Timer * containerTimerAtIndex(int i) override; bool processEvent(Ion::Events::Event event); void resetShiftAlphaStatus(); bool updateAlphaLock(); diff --git a/apps/calculation/additional_outputs/unit_list_controller.cpp b/apps/calculation/additional_outputs/unit_list_controller.cpp index 31583c369..41ac6d8f2 100644 --- a/apps/calculation/additional_outputs/unit_list_controller.cpp +++ b/apps/calculation/additional_outputs/unit_list_controller.cpp @@ -112,7 +112,7 @@ int UnitListController::numberOfRows() const { void UnitListController::willDisplayCellForIndex(HighlightCell * cell, int index) { if (index == 0) { - MessageTableCell * messageTableCell = (MessageTableCell *)cell; + MessageTableCell<> * messageTableCell = (MessageTableCell<> *)cell; messageTableCell->setMessage(m_dimensionMessage); } else { ExpressionsListController::willDisplayCellForIndex(cell, index - 1); diff --git a/apps/calculation/additional_outputs/unit_list_controller.h b/apps/calculation/additional_outputs/unit_list_controller.h index 477656b33..fb351ec32 100644 --- a/apps/calculation/additional_outputs/unit_list_controller.h +++ b/apps/calculation/additional_outputs/unit_list_controller.h @@ -23,7 +23,7 @@ public: private: I18n::Message messageAtIndex(int index) override; I18n::Message m_dimensionMessage; - MessageTableCell m_dimensionCell; + MessageTableCell<> m_dimensionCell; }; } diff --git a/apps/code/app.h b/apps/code/app.h index 4e2ffc9ae..67494d3f3 100644 --- a/apps/code/app.h +++ b/apps/code/app.h @@ -75,7 +75,7 @@ public: VariableBoxController * variableBoxController() { return &m_variableBoxController; } - static constexpr int k_pythonHeapSize = 70000; + static constexpr int k_pythonHeapSize = 69500; private: /* Python delegate: diff --git a/apps/code/python_toolbox.cpp b/apps/code/python_toolbox.cpp index d6cc65dba..b4525591d 100644 --- a/apps/code/python_toolbox.cpp +++ b/apps/code/python_toolbox.cpp @@ -10,22 +10,22 @@ extern "C" { namespace Code { const ToolboxMessageTree forLoopChildren[] = { - ToolboxMessageTree::Leaf(I18n::Message::ForInRange1ArgLoopWithArg, I18n::Message::Default, false, I18n::Message::ForInRange1ArgLoop), - ToolboxMessageTree::Leaf(I18n::Message::ForInRange2ArgsLoopWithArg, I18n::Message::Default, false, I18n::Message::ForInRange2ArgsLoop), - ToolboxMessageTree::Leaf(I18n::Message::ForInRange3ArgsLoopWithArg, I18n::Message::Default, false, I18n::Message::ForInRange3ArgsLoop), - ToolboxMessageTree::Leaf(I18n::Message::ForInListLoopWithArg, I18n::Message::Default, false, I18n::Message::ForInListLoop) + ToolboxMessageTree::Leaf(I18n::Message::ForInRange1ArgLoopWithArg, I18n::Message::Default, false, I18n::Message::ForInRange1ArgLoop, true, 2), + ToolboxMessageTree::Leaf(I18n::Message::ForInRange2ArgsLoopWithArg, I18n::Message::Default, false, I18n::Message::ForInRange2ArgsLoop, true, 2), + ToolboxMessageTree::Leaf(I18n::Message::ForInRange3ArgsLoopWithArg, I18n::Message::Default, false, I18n::Message::ForInRange3ArgsLoop, true, 2), + ToolboxMessageTree::Leaf(I18n::Message::ForInListLoopWithArg, I18n::Message::Default, false, I18n::Message::ForInListLoop, true, 2) }; const ToolboxMessageTree ifStatementChildren[] = { - ToolboxMessageTree::Leaf(I18n::Message::IfElseStatementWithArg, I18n::Message::Default, false, I18n::Message::IfElseStatement), - ToolboxMessageTree::Leaf(I18n::Message::IfThenStatementWithArg, I18n::Message::Default, false, I18n::Message::IfThenStatement), - ToolboxMessageTree::Leaf(I18n::Message::IfElifElseStatementWithArg, I18n::Message::Default, false, I18n::Message::IfElifElseStatement), - ToolboxMessageTree::Leaf(I18n::Message::IfAndIfElseStatementWithArg, I18n::Message::Default, false, I18n::Message::IfAndIfElseStatement), - ToolboxMessageTree::Leaf(I18n::Message::IfOrIfElseStatementWithArg, I18n::Message::Default, false, I18n::Message::IfOrIfElseStatement) + ToolboxMessageTree::Leaf(I18n::Message::IfElseStatementWithArg, I18n::Message::Default, false, I18n::Message::IfElseStatement, true, 4), + ToolboxMessageTree::Leaf(I18n::Message::IfThenStatementWithArg, I18n::Message::Default, false, I18n::Message::IfThenStatement, true, 2), + ToolboxMessageTree::Leaf(I18n::Message::IfElifElseStatementWithArg, I18n::Message::Default, false, I18n::Message::IfElifElseStatement, true, 6), + ToolboxMessageTree::Leaf(I18n::Message::IfAndIfElseStatementWithArg, I18n::Message::Default, false, I18n::Message::IfAndIfElseStatement, true, 4), + ToolboxMessageTree::Leaf(I18n::Message::IfOrIfElseStatementWithArg, I18n::Message::Default, false, I18n::Message::IfOrIfElseStatement, true, 4) }; const ToolboxMessageTree whileLoopChildren[] = { - ToolboxMessageTree::Leaf(I18n::Message::WhileLoopWithArg, I18n::Message::Default, false, I18n::Message::WhileLoop) + ToolboxMessageTree::Leaf(I18n::Message::WhileLoopWithArg, I18n::Message::Default, false, I18n::Message::WhileLoop, true, 2) }; const ToolboxMessageTree conditionsChildren[] = { @@ -683,10 +683,10 @@ const ToolboxMessageTree fileChildren[] { }; const ToolboxMessageTree exceptionsChildren[] = { - ToolboxMessageTree::Leaf(I18n::Message::TryExcept1ErrorWithArg, I18n::Message::Default, false, I18n::Message::TryExcept1Error), - ToolboxMessageTree::Leaf(I18n::Message::TryExcept1ErrorElseWithArg, I18n::Message::Default, false, I18n::Message::TryExcept1ErrorElse), - ToolboxMessageTree::Leaf(I18n::Message::TryExcept2ErrorWithArg, I18n::Message::Default, false, I18n::Message::TryExcept2Error), - ToolboxMessageTree::Leaf(I18n::Message::WithInstructionWithArg, I18n::Message::Default, false, I18n::Message::WithInstruction), + ToolboxMessageTree::Leaf(I18n::Message::TryExcept1ErrorWithArg, I18n::Message::Default, false, I18n::Message::TryExcept1Error, true, 4), + ToolboxMessageTree::Leaf(I18n::Message::TryExcept1ErrorElseWithArg, I18n::Message::Default, false, I18n::Message::TryExcept1ErrorElse, true, 6), + ToolboxMessageTree::Leaf(I18n::Message::TryExcept2ErrorWithArg, I18n::Message::Default, false, I18n::Message::TryExcept2Error, true, 4), + ToolboxMessageTree::Leaf(I18n::Message::WithInstructionWithArg, I18n::Message::Default, false, I18n::Message::WithInstruction, true, 2), }; const ToolboxMessageTree menu[] = { @@ -704,6 +704,10 @@ const ToolboxMessageTree toolboxModel = ToolboxMessageTree::Node(I18n::Message:: PythonToolbox::PythonToolbox() : Toolbox(nullptr, rootModel()->label()) { + for (int i=0; i < k_maxNumberOfDisplayedRows; i++) { + m_leafCells[i].setMessageFont(KDFont::LargeFont); + m_nodeCells[i].setMessageFont(KDFont::LargeFont); + } } const ToolboxMessageTree * PythonToolbox::moduleChildren(const char * name, int * numberOfNodes) const { @@ -734,19 +738,17 @@ bool PythonToolbox::handleEvent(Ion::Events::Event event) { return false; } +void PythonToolbox::willDisplayCellForIndex(HighlightCell * cell, int index) { + Toolbox::willDisplayCellForIndex(cell, index); + const ToolboxMessageTree * messageTree = static_cast(m_messageTreeModel->childAtIndex(index)); + MessageTableCell * myCell = static_cast *>(cell); + myCell->setMessageFont(messageTree->isMultiLine() ? KDFont::SmallFont : KDFont::LargeFont); +} + KDCoordinate PythonToolbox::rowHeight(int j) { - if (typeAtLocation(0, j) == Toolbox::LeafCellType && (m_messageTreeModel->label() == I18n::Message::IfStatementMenu || m_messageTreeModel->label() == I18n::Message::Exceptions)) { - /* To get the exact height needed for each cell, we have to compute its - * text size, which means scan the text char by char to look for '\n' - * chars. This is very costly and ruins the speed performance when - * scrolling at the bottom of a long table: to compute a position on the - * kth row, we call cumulatedHeightFromIndex(k), which calls rowHeight k - * times. - * We thus decided to compute the real height only for the ifStatement - * children of the toolbox, which is the only menu that has special height - * rows. */ - const ToolboxMessageTree * messageTree = static_cast(m_messageTreeModel->childAtIndex(j)); - return k_font->stringSize(I18n::translate(messageTree->label())).height() + 2*Metric::TableCellVerticalMargin + (messageTree->text() == I18n::Message::Default ? 0 : Toolbox::rowHeight(j)); + const ToolboxMessageTree * messageTree = static_cast(m_messageTreeModel->childAtIndex(j)); + if (messageTree->isMultiLine()) { + return k_fontForMultiLine->glyphSize().height() * messageTree->numberOfLines() + 2*Metric::TableCellVerticalMargin + (messageTree->text() == I18n::Message::Default ? 0 : Toolbox::rowHeight(j)); } return Toolbox::rowHeight(j); } @@ -791,12 +793,12 @@ const ToolboxMessageTree * PythonToolbox::rootModel() const { return &toolboxModel; } -MessageTableCellWithMessage * PythonToolbox::leafCellAtIndex(int index) { +MessageTableCellWithMessage * PythonToolbox::leafCellAtIndex(int index) { assert(index >= 0 && index < k_maxNumberOfDisplayedRows); return &m_leafCells[index]; } -MessageTableCellWithChevron* PythonToolbox::nodeCellAtIndex(int index) { +MessageTableCellWithChevron * PythonToolbox::nodeCellAtIndex(int index) { assert(index >= 0 && index < k_maxNumberOfDisplayedRows); return &m_nodeCells[index]; } diff --git a/apps/code/python_toolbox.h b/apps/code/python_toolbox.h index 4252b1f16..c641536a4 100644 --- a/apps/code/python_toolbox.h +++ b/apps/code/python_toolbox.h @@ -18,23 +18,27 @@ public: // Toolbox bool handleEvent(Ion::Events::Event event) override; const ToolboxMessageTree * rootModel() const override; + + // ListViewDataSource + void willDisplayCellForIndex(HighlightCell * cell, int index) override; + protected: KDCoordinate rowHeight(int j) override; bool selectLeaf(int selectedRow, bool quitToolbox) override; bool selectSubMenu(int selectedRow) override; - MessageTableCellWithMessage * leafCellAtIndex(int index) override; - MessageTableCellWithChevron* nodeCellAtIndex(int index) override; + MessageTableCellWithMessage * leafCellAtIndex(int index) override; + MessageTableCellWithChevron * nodeCellAtIndex(int index) override; int maxNumberOfDisplayedRows() override; bool canStayInMenu() override { return true; } constexpr static int k_maxNumberOfDisplayedRows = 13; // = 240/(13+2*3) // 13 = minimal string height size // 3 = vertical margins private: - constexpr static const KDFont * k_font = KDFont::SmallFont; + constexpr static const KDFont * k_fontForMultiLine = KDFont::SmallFont; void scrollToLetter(char letter); void scrollToAndSelectChild(int i); - MessageTableCellWithMessage m_leafCells[k_maxNumberOfDisplayedRows]; - MessageTableCellWithChevron m_nodeCells[k_maxNumberOfDisplayedRows]; + MessageTableCellWithMessage m_leafCells[k_maxNumberOfDisplayedRows]; + MessageTableCellWithChevron m_nodeCells[k_maxNumberOfDisplayedRows]; ToolboxIonKeys m_ionKeys; }; diff --git a/apps/code/script_parameter_controller.h b/apps/code/script_parameter_controller.h index e7065e733..193879b68 100644 --- a/apps/code/script_parameter_controller.h +++ b/apps/code/script_parameter_controller.h @@ -34,11 +34,11 @@ private: constexpr static int k_totalNumberOfCell = 6; StackViewController * stackViewController(); I18n::Message m_pageTitle; - MessageTableCell m_executeScript; - MessageTableCell m_renameScript; + MessageTableCell<> m_executeScript; + MessageTableCell<> m_renameScript; MessageTableCellWithSwitch m_autoImportScript; - MessageTableCell m_deleteScript; - MessageTableCell m_duplicateScript; + MessageTableCell<> m_deleteScript; + MessageTableCell<> m_duplicateScript; MessageTableCellWithBuffer m_size; void GetScriptSize(MessageTableCellWithBuffer* myCell); SelectableTableView m_selectableTableView; diff --git a/apps/code/variable_box_controller.cpp b/apps/code/variable_box_controller.cpp index 31604b671..fcaf42bc5 100644 --- a/apps/code/variable_box_controller.cpp +++ b/apps/code/variable_box_controller.cpp @@ -128,7 +128,7 @@ void VariableBoxController::willDisplayCellForIndex(HighlightCell * cell, int in I18n::Message::BuiltinsAndKeywords, I18n::Message::ImportedModulesAndScripts }; - static_cast(cell)->setMessage(subtitleMessages[(int)cellOrigin]); + static_cast *>(cell)->setMessage(subtitleMessages[(int)cellOrigin]); } void VariableBoxController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) { diff --git a/apps/code/variable_box_controller.h b/apps/code/variable_box_controller.h index eb25b0544..1a5a525eb 100644 --- a/apps/code/variable_box_controller.h +++ b/apps/code/variable_box_controller.h @@ -104,7 +104,7 @@ private: ScriptNode m_builtinNodes[k_totalBuiltinNodesCount]; ScriptNode m_importedNodes[k_maxScriptNodesCount]; ScriptNodeCell m_itemCells[k_maxNumberOfDisplayedItems]; - MessageTableCell m_subtitleCells[k_scriptOriginsCount]; + MessageTableCell<> m_subtitleCells[k_scriptOriginsCount]; ScriptStore * m_scriptStore; size_t m_currentScriptNodesCount; size_t m_builtinNodesCount; diff --git a/apps/graph/graph/calculation_parameter_controller.cpp b/apps/graph/graph/calculation_parameter_controller.cpp index 93f98086f..3e7266662 100644 --- a/apps/graph/graph/calculation_parameter_controller.cpp +++ b/apps/graph/graph/calculation_parameter_controller.cpp @@ -109,7 +109,7 @@ void CalculationParameterController::willDisplayCellForIndex(HighlightCell * cel assert(index >= 0 && index <= numberOfRows()); if (cell != &m_preimageCell) { I18n::Message titles[] = {I18n::Message::Intersection, I18n::Message::Maximum, I18n::Message::Minimum, I18n::Message::Zeros, I18n::Message::Tangent, I18n::Message::Integral}; - static_cast(cell)->setMessage(titles[index - 1 + !shouldDisplayIntersection()]); + static_cast *>(cell)->setMessage(titles[index - 1 + !shouldDisplayIntersection()]); } } diff --git a/apps/graph/graph/calculation_parameter_controller.h b/apps/graph/graph/calculation_parameter_controller.h index ffb38e691..0297b5b38 100644 --- a/apps/graph/graph/calculation_parameter_controller.h +++ b/apps/graph/graph/calculation_parameter_controller.h @@ -32,9 +32,9 @@ public: void setRecord(Ion::Storage::Record record); private: bool shouldDisplayIntersection() const; - MessageTableCellWithChevron m_preimageCell; + MessageTableCellWithChevron<> m_preimageCell; constexpr static int k_totalNumberOfReusableCells = 6; - MessageTableCell m_cells[k_totalNumberOfReusableCells]; + MessageTableCell<> m_cells[k_totalNumberOfReusableCells]; SelectableTableView m_selectableTableView; Ion::Storage::Record m_record; PreimageParameterController m_preimageParameterController; diff --git a/apps/graph/graph/curve_parameter_controller.h b/apps/graph/graph/curve_parameter_controller.h index d5a587af1..a14e32956 100644 --- a/apps/graph/graph/curve_parameter_controller.h +++ b/apps/graph/graph/curve_parameter_controller.h @@ -25,7 +25,7 @@ private: Shared::FunctionGoToParameterController * goToParameterController() override; Shared::FunctionGoToParameterController m_goToParameterController; GraphController * m_graphController; - MessageTableCellWithChevron m_calculationCell; + MessageTableCellWithChevron<> m_calculationCell; MessageTableCellWithSwitch m_derivativeCell; CalculationParameterController m_calculationParameterController; }; diff --git a/apps/graph/list/list_parameter_controller.h b/apps/graph/list/list_parameter_controller.h index 31c311ba4..2246ab866 100644 --- a/apps/graph/list/list_parameter_controller.h +++ b/apps/graph/list/list_parameter_controller.h @@ -28,7 +28,7 @@ private: MessageTableCellWithChevronAndBuffer m_functionDomain; TypeParameterController m_typeParameterController; DomainParameterController m_domainParameterController; - MessageTableCell m_renameCell; + MessageTableCell<> m_renameCell; }; } diff --git a/apps/graph/values/derivative_parameter_controller.h b/apps/graph/values/derivative_parameter_controller.h index 10d64bec0..2c353a1d9 100644 --- a/apps/graph/values/derivative_parameter_controller.h +++ b/apps/graph/values/derivative_parameter_controller.h @@ -33,9 +33,9 @@ private: #endif constexpr static int k_maxNumberOfCharsInTitle = Shared::Function::k_maxNameWithArgumentSize + 1; // +1 for the ' of the derivative char m_pageTitle[k_maxNumberOfCharsInTitle]; - MessageTableCell m_hideColumn; + MessageTableCell<> m_hideColumn; #if COPY_COLUMN - MessageTableCellWithChevron m_copyColumn; + MessageTableCellWithChevron<> m_copyColumn; #endif SelectableTableView m_selectableTableView; Ion::Storage::Record m_record; diff --git a/apps/graph/values/interval_parameter_selector_controller.cpp b/apps/graph/values/interval_parameter_selector_controller.cpp index 80cd68f74..7707c83ed 100644 --- a/apps/graph/values/interval_parameter_selector_controller.cpp +++ b/apps/graph/values/interval_parameter_selector_controller.cpp @@ -69,7 +69,7 @@ int IntervalParameterSelectorController::reusableCellCount() const { void IntervalParameterSelectorController::willDisplayCellForIndex(HighlightCell * cell, int index) { assert(0 <= index && index < numberOfRows()); Shared::ContinuousFunction::PlotType plotType = plotTypeAtRow(index); - static_cast(cell)->setMessage(messageForType(plotType)); + static_cast *>(cell)->setMessage(messageForType(plotType)); } Shared::ContinuousFunction::PlotType IntervalParameterSelectorController::plotTypeAtRow(int j) const { diff --git a/apps/graph/values/interval_parameter_selector_controller.h b/apps/graph/values/interval_parameter_selector_controller.h index eef6e1b6a..a37e714ad 100644 --- a/apps/graph/values/interval_parameter_selector_controller.h +++ b/apps/graph/values/interval_parameter_selector_controller.h @@ -24,7 +24,7 @@ public: private: Shared::ContinuousFunction::PlotType plotTypeAtRow(int j) const; I18n::Message messageForType(Shared::ContinuousFunction::PlotType plotType); - MessageTableCellWithChevron m_intervalParameterCell[Shared::ContinuousFunction::k_numberOfPlotTypes]; + MessageTableCellWithChevron<> m_intervalParameterCell[Shared::ContinuousFunction::k_numberOfPlotTypes]; SelectableTableView m_selectableTableView; }; diff --git a/apps/math_toolbox.cpp b/apps/math_toolbox.cpp index 1ff78b681..0cb24ab13 100644 --- a/apps/math_toolbox.cpp +++ b/apps/math_toolbox.cpp @@ -875,6 +875,10 @@ const ToolboxMessageTree toolboxModel = ToolboxMessageTree::Node(I18n::Message:: MathToolbox::MathToolbox() : Toolbox(nullptr, rootModel()->label()) { + for (int i=0; i < k_maxNumberOfDisplayedRows; i++) { + m_leafCells[i].setMessageFont(KDFont::LargeFont); + m_nodeCells[i].setMessageFont(KDFont::LargeFont); + } } bool MathToolbox::selectLeaf(int selectedRow, bool quitToolbox) { @@ -900,12 +904,12 @@ const ToolboxMessageTree * MathToolbox::rootModel() const { return &toolboxModel; } -MessageTableCellWithMessage * MathToolbox::leafCellAtIndex(int index) { +MessageTableCellWithMessage * MathToolbox::leafCellAtIndex(int index) { assert(index >= 0 && index < k_maxNumberOfDisplayedRows); return &m_leafCells[index]; } -MessageTableCellWithChevron* MathToolbox::nodeCellAtIndex(int index) { +MessageTableCellWithChevron * MathToolbox::nodeCellAtIndex(int index) { assert(index >= 0 && index < k_maxNumberOfDisplayedRows); return &m_nodeCells[index]; } diff --git a/apps/math_toolbox.h b/apps/math_toolbox.h index b883bf182..936cf42c9 100644 --- a/apps/math_toolbox.h +++ b/apps/math_toolbox.h @@ -10,15 +10,15 @@ public: const ToolboxMessageTree * rootModel() const override; protected: bool selectLeaf(int selectedRow, bool quitToolbox) override; - MessageTableCellWithMessage * leafCellAtIndex(int index) override; - MessageTableCellWithChevron* nodeCellAtIndex(int index) override; + MessageTableCellWithMessage * leafCellAtIndex(int index) override; + MessageTableCellWithChevron * nodeCellAtIndex(int index) override; int maxNumberOfDisplayedRows() override; constexpr static int k_maxNumberOfDisplayedRows = 6; // = 240/40 private: int indexAfterFork() const override; - MessageTableCellWithMessage m_leafCells[k_maxNumberOfDisplayedRows]; - MessageTableCellWithChevron m_nodeCells[k_maxNumberOfDisplayedRows]; + MessageTableCellWithMessage m_leafCells[k_maxNumberOfDisplayedRows]; + MessageTableCellWithChevron m_nodeCells[k_maxNumberOfDisplayedRows]; }; #endif diff --git a/apps/math_variable_box_controller.cpp b/apps/math_variable_box_controller.cpp index 28f179e26..fb39e3b39 100644 --- a/apps/math_variable_box_controller.cpp +++ b/apps/math_variable_box_controller.cpp @@ -98,7 +98,7 @@ int MathVariableBoxController::reusableCellCount(int type) { void MathVariableBoxController::willDisplayCellForIndex(HighlightCell * cell, int index) { if (m_currentPage == Page::RootMenu) { I18n::Message label = nodeLabelAtIndex(index); - MessageTableCell * myCell = (MessageTableCell *)cell; + MessageTableCell<> * myCell = (MessageTableCell<> *)cell; myCell->setMessage(label); myCell->reloadCell(); return; @@ -158,7 +158,7 @@ ExpressionTableCellWithExpression * MathVariableBoxController::leafCellAtIndex(i return &m_leafCells[index]; } -MessageTableCellWithChevron * MathVariableBoxController::nodeCellAtIndex(int index) { +MessageTableCellWithChevron<> * MathVariableBoxController::nodeCellAtIndex(int index) { assert(index >= 0 && index < k_numberOfMenuRows); return &m_nodeCells[index]; } diff --git a/apps/math_variable_box_controller.h b/apps/math_variable_box_controller.h index 6fe80f576..cf2f2fb0b 100644 --- a/apps/math_variable_box_controller.h +++ b/apps/math_variable_box_controller.h @@ -37,7 +37,7 @@ private: constexpr static int k_numberOfMenuRows = 3; constexpr static KDCoordinate k_leafMargin = 20; ExpressionTableCellWithExpression * leafCellAtIndex(int index) override; - MessageTableCellWithChevron * nodeCellAtIndex(int index) override; + MessageTableCellWithChevron<> * nodeCellAtIndex(int index) override; Page pageAtIndex(int index); void setPage(Page page); bool selectSubMenu(int selectedRow) override; @@ -53,7 +53,7 @@ private: Page m_currentPage; Page m_lockPageDelete; ExpressionTableCellWithExpression m_leafCells[k_maxNumberOfDisplayedRows]; - MessageTableCellWithChevron m_nodeCells[k_numberOfMenuRows]; + MessageTableCellWithChevron<> m_nodeCells[k_numberOfMenuRows]; MathVariableBoxEmptyController m_emptyViewController; // Layout memoization // TODO: make a helper doing the RingMemoizationOfConsecutiveObjets to factorize this code and ExpressionModelStore code diff --git a/apps/on_boarding/app.cpp b/apps/on_boarding/app.cpp index 3e914f7d9..59f83fc2f 100644 --- a/apps/on_boarding/app.cpp +++ b/apps/on_boarding/app.cpp @@ -18,15 +18,7 @@ App::App(Snapshot * snapshot) : m_localizationController(&m_modalViewController, Metric::CommonTopMargin, LocalizationController::Mode::Language), m_logoController() { -} - -int App::numberOfTimers() { - return firstResponder() == &m_logoController; -} - -Timer * App::timerAtIndex(int i) { - assert(i == 0); - return &m_logoController; + AppsContainer::sharedAppsContainer()->addTimer(&m_logoController); } bool App::processEvent(Ion::Events::Event e) { diff --git a/apps/on_boarding/app.h b/apps/on_boarding/app.h index d9dbe43a4..38233c5bd 100644 --- a/apps/on_boarding/app.h +++ b/apps/on_boarding/app.h @@ -15,9 +15,6 @@ public: App * unpack(Container * container) override; Descriptor * descriptor() override; }; - - int numberOfTimers() override; - Timer * timerAtIndex(int i) override; bool processEvent(Ion::Events::Event) override; void didBecomeActive(Window * window) override; private: diff --git a/apps/on_boarding/logo_controller.cpp b/apps/on_boarding/logo_controller.cpp index 13df87e4d..0597bfcdf 100644 --- a/apps/on_boarding/logo_controller.cpp +++ b/apps/on_boarding/logo_controller.cpp @@ -17,6 +17,7 @@ LogoController::LogoController() : bool LogoController::fire() { Container::activeApp()->dismissModalViewController(); + AppsContainer::sharedAppsContainer()->removeTimer(this); return true; } @@ -41,7 +42,6 @@ void LogoController::viewWillAppear() { if (!backlightInitialized) { Ion::Backlight::init(); } - ViewController::viewWillAppear(); } void LogoController::viewDidDisappear() { diff --git a/apps/reader/list_book_controller.cpp b/apps/reader/list_book_controller.cpp index 445811a9e..8dbf7aa3b 100644 --- a/apps/reader/list_book_controller.cpp +++ b/apps/reader/list_book_controller.cpp @@ -37,7 +37,7 @@ int ListBookController::reusableCellCount() const { } void ListBookController::willDisplayCellForIndex(HighlightCell * cell, int index) { - MessageTableCell* myTextCell = static_cast(cell); + MessageTableCell<> * myTextCell = static_cast *>(cell); MessageTextView* textView = static_cast(myTextCell->labelView()); textView->setText(m_files[index].name); myTextCell->setMessageFont(KDFont::LargeFont); //TODO set cell font at building ? diff --git a/apps/reader/list_book_controller.h b/apps/reader/list_book_controller.h index 13cacd2b7..3250b173f 100644 --- a/apps/reader/list_book_controller.h +++ b/apps/reader/list_book_controller.h @@ -34,7 +34,7 @@ private: int m_txtFilesNumber; int m_urtFilesNumber; static const int k_cellsNumber = 6; - MessageTableCellWithChevron m_cells[k_cellsNumber]; + MessageTableCellWithChevron<> m_cells[k_cellsNumber]; ReadBookController m_readBookController; }; diff --git a/apps/regression/graph_options_controller.cpp b/apps/regression/graph_options_controller.cpp index 83d80db43..70770ae05 100644 --- a/apps/regression/graph_options_controller.cpp +++ b/apps/regression/graph_options_controller.cpp @@ -118,7 +118,7 @@ void GraphOptionsController::willDisplayCellForIndex(HighlightCell * cell, int i return; } assert(index >=0 && index < k_numberOfParameterCells); - MessageTableCellWithChevron * myCell = (MessageTableCellWithChevron *)cell; + MessageTableCellWithChevron<> * myCell = (MessageTableCellWithChevron<> *)cell; I18n::Message titles[k_numberOfParameterCells] = {I18n::Message::XPrediction, I18n::Message::YPrediction}; myCell->setMessage(titles[index]); } diff --git a/apps/regression/graph_options_controller.h b/apps/regression/graph_options_controller.h index 69ec697bf..202c4d2f8 100644 --- a/apps/regression/graph_options_controller.h +++ b/apps/regression/graph_options_controller.h @@ -32,7 +32,7 @@ private: constexpr static int k_regressionCellType = 0; constexpr static int k_parameterCelltype = 1; constexpr static int k_numberOfParameterCells = 2; - MessageTableCellWithChevron m_parameterCells[k_numberOfParameterCells]; + MessageTableCellWithChevron<> m_parameterCells[k_numberOfParameterCells]; MessageTableCellWithChevronAndExpression m_changeRegressionCell; SelectableTableView m_selectableTableView; GoToParameterController m_goToParameterController; diff --git a/apps/sequence/graph/curve_parameter_controller.h b/apps/sequence/graph/curve_parameter_controller.h index 7d47f1f6d..c47af5a3d 100644 --- a/apps/sequence/graph/curve_parameter_controller.h +++ b/apps/sequence/graph/curve_parameter_controller.h @@ -20,7 +20,7 @@ private: constexpr static int k_totalNumberOfCells = 2; GoToParameterController * goToParameterController() override; GoToParameterController m_goToParameterController; - MessageTableCell m_sumCell; + MessageTableCell<> m_sumCell; GraphController * m_graphController; }; diff --git a/apps/settings/main_controller.cpp b/apps/settings/main_controller.cpp index 61eb08f13..4b590b45f 100644 --- a/apps/settings/main_controller.cpp +++ b/apps/settings/main_controller.cpp @@ -175,7 +175,7 @@ void MainController::willDisplayCellForIndex(HighlightCell * cell, int index) { myGauge->setLevel((float)globalPreferences->brightnessLevel()/(float)Ion::Backlight::MaxBrightness); return; } - MessageTableCell * myCell = (MessageTableCell *)cell; + MessageTableCell<> * myCell = (MessageTableCell<> *)cell; myCell->setMessage(title); if (model()->childAtIndex(index)->label() == I18n::Message::Language) { int index = (int)(globalPreferences->language()); diff --git a/apps/settings/sub_menu/exam_mode_controller.cpp b/apps/settings/sub_menu/exam_mode_controller.cpp index 33a853eaa..9fd322321 100644 --- a/apps/settings/sub_menu/exam_mode_controller.cpp +++ b/apps/settings/sub_menu/exam_mode_controller.cpp @@ -88,7 +88,7 @@ void ExamModeController::willDisplayCellForIndex(HighlightCell * cell, int index I18n::Message thisLabel = m_messageTreeModel->childAtIndex(index)->label(); if (GlobalPreferences::sharedGlobalPreferences()->isInExamMode() && (thisLabel == I18n::Message::ActivateExamMode || thisLabel == I18n::Message::ExamModeActive)) { - MessageTableCell * myCell = (MessageTableCell *)cell; + MessageTableCell<> * myCell = (MessageTableCell<> *)cell; myCell->setMessage(I18n::Message::ExamModeActive); } if (thisLabel == I18n::Message::ExamModeMode) { diff --git a/apps/settings/sub_menu/exam_mode_controller.h b/apps/settings/sub_menu/exam_mode_controller.h index e7abb1b12..ebdfb2195 100644 --- a/apps/settings/sub_menu/exam_mode_controller.h +++ b/apps/settings/sub_menu/exam_mode_controller.h @@ -27,7 +27,7 @@ private: GlobalPreferences::ExamMode examMode(); static constexpr int k_maxNumberOfCells = 4; SelectableViewWithMessages m_contentView; - MessageTableCell m_cell[k_maxNumberOfCells]; + MessageTableCell<> m_cell[k_maxNumberOfCells]; PreferencesController m_ledController; PreferencesController m_examModeModeController; MessageTableCellWithChevronAndMessage m_examModeCell; diff --git a/apps/settings/sub_menu/generic_sub_controller.cpp b/apps/settings/sub_menu/generic_sub_controller.cpp index 5286743d1..25c5d15fa 100644 --- a/apps/settings/sub_menu/generic_sub_controller.cpp +++ b/apps/settings/sub_menu/generic_sub_controller.cpp @@ -75,7 +75,7 @@ int GenericSubController::typeAtLocation(int i, int j) { } void GenericSubController::willDisplayCellForIndex(HighlightCell * cell, int index) { - MessageTableCell * myCell = (MessageTableCell *)cell; + MessageTableCell<> * myCell = (MessageTableCell<> *)cell; myCell->setMessage(m_messageTreeModel->childAtIndex(index)->label()); } diff --git a/apps/shared/color_cell.h b/apps/shared/color_cell.h index e9d5e4b66..1951cd680 100644 --- a/apps/shared/color_cell.h +++ b/apps/shared/color_cell.h @@ -6,7 +6,7 @@ namespace Shared { -class MessageTableCellWithColor : public MessageTableCell { +class MessageTableCellWithColor : public MessageTableCell<> { public: MessageTableCellWithColor(); View * accessoryView() const override; diff --git a/apps/shared/function_curve_parameter_controller.h b/apps/shared/function_curve_parameter_controller.h index 96e866844..a720e2e9d 100644 --- a/apps/shared/function_curve_parameter_controller.h +++ b/apps/shared/function_curve_parameter_controller.h @@ -16,7 +16,7 @@ public: void setRecord(Ion::Storage::Record record) { m_record = record; } protected: bool handleGotoSelection(); - MessageTableCellWithChevron m_goToCell; + MessageTableCellWithChevron<> m_goToCell; SelectableTableView m_selectableTableView; Ion::Storage::Record m_record; private: diff --git a/apps/shared/list_parameter_controller.h b/apps/shared/list_parameter_controller.h index e7ffb0fc6..d948073bb 100644 --- a/apps/shared/list_parameter_controller.h +++ b/apps/shared/list_parameter_controller.h @@ -41,7 +41,7 @@ protected: private: MessageTableCellWithChevronAndMessage m_colorCell; MessageTableCellWithSwitch m_enableCell; - MessageTableCell m_deleteCell; + MessageTableCell<> m_deleteCell; ColorParameterController m_colorParameterController; }; diff --git a/apps/shared/localization_controller.cpp b/apps/shared/localization_controller.cpp index b300e84f2..b1476aa3d 100644 --- a/apps/shared/localization_controller.cpp +++ b/apps/shared/localization_controller.cpp @@ -191,10 +191,10 @@ bool LocalizationController::handleEvent(Ion::Events::Event event) { void LocalizationController::willDisplayCellForIndex(HighlightCell * cell, int index) { if (mode() == Mode::Language) { - static_cast(cell)->setMessage(I18n::LanguageNames[index]); + static_cast *>(cell)->setMessage(I18n::LanguageNames[index]); return; } assert(mode() == Mode::Country); - static_cast(cell)->setMessage(I18n::CountryNames[static_cast(CountryAtIndex(index))]); + static_cast *>(cell)->setMessage(I18n::CountryNames[static_cast(CountryAtIndex(index))]); } } diff --git a/apps/shared/localization_controller.h b/apps/shared/localization_controller.h index 327d3ef5d..ddc8c1d08 100644 --- a/apps/shared/localization_controller.h +++ b/apps/shared/localization_controller.h @@ -71,7 +71,7 @@ protected: private: static constexpr int k_numberOfCells = I18n::NumberOfLanguages > I18n::NumberOfCountries ? I18n::NumberOfLanguages : I18n::NumberOfCountries; - MessageTableCell m_cells[k_numberOfCells]; + MessageTableCell<> m_cells[k_numberOfCells]; Mode m_mode; }; diff --git a/apps/shared/store_parameter_controller.h b/apps/shared/store_parameter_controller.h index efc8c6f12..4302efcc8 100644 --- a/apps/shared/store_parameter_controller.h +++ b/apps/shared/store_parameter_controller.h @@ -41,7 +41,7 @@ protected: private: virtual I18n::Message sortMessage() { return m_xColumnSelected ? I18n::Message::SortValues : I18n::Message::SortSizes; } constexpr static int k_totalNumberOfCell = 3; - MessageTableCell m_cells[k_totalNumberOfCell]; + MessageTableCell<> m_cells[k_totalNumberOfCell]; StoreController * m_storeController; bool m_xColumnSelected; }; diff --git a/apps/shared/values_function_parameter_controller.h b/apps/shared/values_function_parameter_controller.h index f43653123..940b76984 100644 --- a/apps/shared/values_function_parameter_controller.h +++ b/apps/shared/values_function_parameter_controller.h @@ -29,7 +29,7 @@ public: int reusableCellCount() const override { return 1; } void setRecord(Ion::Storage::Record record) { m_record = record; } protected: - MessageTableCellWithChevron m_copyColumn; + MessageTableCellWithChevron<> m_copyColumn; SelectableTableView m_selectableTableView; Ion::Storage::Record m_record; private: diff --git a/apps/shared/values_parameter_controller.cpp b/apps/shared/values_parameter_controller.cpp index 272808ae9..edfeeb9f3 100644 --- a/apps/shared/values_parameter_controller.cpp +++ b/apps/shared/values_parameter_controller.cpp @@ -24,7 +24,7 @@ View * ValuesParameterController::view() { } void ValuesParameterController::willDisplayCellForIndex(HighlightCell * cell, int index) { - MessageTableCell * myCell = (MessageTableCell *)cell; + MessageTableCell<> * myCell = (MessageTableCell<> *)cell; #if COPY_COLUMN I18n::Message labels[k_totalNumberOfCell] = {I18n::Message::ClearColumn, I18n::Message::CopyColumnInList, I18n::Message::IntervalSet}; #else diff --git a/apps/shared/values_parameter_controller.h b/apps/shared/values_parameter_controller.h index 5cc842f72..777d1d205 100644 --- a/apps/shared/values_parameter_controller.h +++ b/apps/shared/values_parameter_controller.h @@ -21,13 +21,13 @@ public: private: #if COPY_COLUMN constexpr static int k_totalNumberOfCell = 3; - MessageTableCellWithChevron m_copyColumn; + MessageTableCellWithChevron<> m_copyColumn; #else constexpr static int k_totalNumberOfCell = 2; #endif I18n::Message m_pageTitle; - MessageTableCell m_deleteColumn; - MessageTableCellWithChevron m_setInterval; + MessageTableCell<> m_deleteColumn; + MessageTableCellWithChevron<> m_setInterval; SelectableTableView m_selectableTableView; }; diff --git a/apps/solver/equation_models_parameter_controller.h b/apps/solver/equation_models_parameter_controller.h index bb6812cb1..3eb88b5c3 100644 --- a/apps/solver/equation_models_parameter_controller.h +++ b/apps/solver/equation_models_parameter_controller.h @@ -30,7 +30,7 @@ private: }; StackViewController * stackController() const; constexpr static int k_numberOfExpressionCells = k_numberOfModels-1; - MessageTableCell m_emptyModelCell; + MessageTableCell<> m_emptyModelCell; ExpressionTableCell m_modelCells[k_numberOfExpressionCells]; Poincare::Layout m_layouts[k_numberOfExpressionCells]; SelectableTableView m_selectableTableView; diff --git a/escher/Makefile b/escher/Makefile index a8bb8491c..ca371fd33 100644 --- a/escher/Makefile +++ b/escher/Makefile @@ -21,6 +21,7 @@ endif escher_src += $(addprefix escher/src/,\ alternate_empty_view_controller.cpp \ + animation_timer.cpp \ app.cpp \ background_view.cpp \ bank_view_controller.cpp \ @@ -84,6 +85,7 @@ escher_src += $(addprefix escher/src/,\ selectable_table_view.cpp \ simple_list_view_data_source.cpp \ simple_table_view_data_source.cpp \ + slideable_message_text_view.cpp \ solid_color_view.cpp \ stack_view.cpp \ stack_view_controller.cpp \ diff --git a/escher/include/escher.h b/escher/include/escher.h index 62ceb7e1a..bce7b8a22 100644 --- a/escher/include/escher.h +++ b/escher/include/escher.h @@ -3,6 +3,8 @@ #include #include +#include +#include #include #include #include @@ -66,6 +68,7 @@ #include #include #include +#include #include #include #include diff --git a/escher/include/escher/animated.h b/escher/include/escher/animated.h new file mode 100644 index 000000000..ca92b4e3e --- /dev/null +++ b/escher/include/escher/animated.h @@ -0,0 +1,11 @@ +#ifndef APPS_ANIMATED_H +#define APPS_ANIMATED_H + +class Animated { +public: + virtual void willStartAnimation() {}; + virtual void didStopAnimation() {}; + virtual void animate() = 0; +}; + +#endif diff --git a/escher/include/escher/animation_timer.h b/escher/include/escher/animation_timer.h new file mode 100644 index 000000000..9bb1b1f1b --- /dev/null +++ b/escher/include/escher/animation_timer.h @@ -0,0 +1,25 @@ +#ifndef APPS_ANIMATION_TIMER_H +#define APPS_ANIMATION_TIMER_H + +#include +#include +#include + +class AnimationTimer : public Timer { +public: + AnimationTimer(): + Timer(1), + m_animated(nullptr) + {} + void setAnimated(Animated * animated); + void removeAnimated(Animated * animated=nullptr); +private: + bool fire() override { + assert(m_animated); + m_animated->animate(); + return true; + } + Animated * m_animated; +}; + +#endif diff --git a/escher/include/escher/app.h b/escher/include/escher/app.h index ab146713a..ce3883bef 100644 --- a/escher/include/escher/app.h +++ b/escher/include/escher/app.h @@ -69,8 +69,6 @@ public: virtual void didBecomeActive(Window * window); virtual void willBecomeInactive(); View * modalView(); - virtual int numberOfTimers() { return 0; } - virtual Timer * timerAtIndex(int i) { assert(false); return nullptr; } virtual Poincare::Context * localContext() { return nullptr; } protected: App(Snapshot * snapshot, ViewController * rootViewController, I18n::Message warningMessage = (I18n::Message)0) : diff --git a/escher/include/escher/container.h b/escher/include/escher/container.h index 0070adb02..02dbcd1a9 100644 --- a/escher/include/escher/container.h +++ b/escher/include/escher/container.h @@ -36,10 +36,6 @@ protected: static App * s_activeApp; private: void step(); - int numberOfTimers() override; - Timer * timerAtIndex(int i) override; - virtual int numberOfContainerTimers(); - virtual Timer * containerTimerAtIndex(int i); }; #endif diff --git a/escher/include/escher/message_table_cell.h b/escher/include/escher/message_table_cell.h index c43985d6d..65638e851 100644 --- a/escher/include/escher/message_table_cell.h +++ b/escher/include/escher/message_table_cell.h @@ -2,9 +2,11 @@ #define ESCHER_MESSAGE_TABLE_CELL_H #include +#include #include #include +template class MessageTableCell : public TableCell { public: MessageTableCell(I18n::Message label = (I18n::Message)0, const KDFont * font = KDFont::SmallFont, Layout layout = Layout::HorizontalLeftOverlap); @@ -17,7 +19,7 @@ public: protected: KDColor backgroundColor() const override { return m_backgroundColor; } private: - MessageTextView m_messageTextView; + T m_messageTextView; KDColor m_backgroundColor; }; diff --git a/escher/include/escher/message_table_cell_with_buffer.h b/escher/include/escher/message_table_cell_with_buffer.h index 64866cce2..2b40e26be 100644 --- a/escher/include/escher/message_table_cell_with_buffer.h +++ b/escher/include/escher/message_table_cell_with_buffer.h @@ -4,7 +4,7 @@ #include #include -class MessageTableCellWithBuffer : public MessageTableCell { +class MessageTableCellWithBuffer : public MessageTableCell<> { public: MessageTableCellWithBuffer(I18n::Message message = (I18n::Message)0, const KDFont * font = KDFont::SmallFont, const KDFont * accessoryFont = KDFont::LargeFont, KDColor accessoryTextColor = Palette::PrimaryText); View * accessoryView() const override; diff --git a/escher/include/escher/message_table_cell_with_chevron.h b/escher/include/escher/message_table_cell_with_chevron.h index 2611346d4..d29b68ea6 100644 --- a/escher/include/escher/message_table_cell_with_chevron.h +++ b/escher/include/escher/message_table_cell_with_chevron.h @@ -4,7 +4,8 @@ #include #include -class MessageTableCellWithChevron : public MessageTableCell { +template +class MessageTableCellWithChevron : public MessageTableCell { public: MessageTableCellWithChevron(I18n::Message message = (I18n::Message)0, const KDFont * font = KDFont::SmallFont); View * accessoryView() const override; diff --git a/escher/include/escher/message_table_cell_with_chevron_and_buffer.h b/escher/include/escher/message_table_cell_with_chevron_and_buffer.h index 86657ba92..1f952076c 100644 --- a/escher/include/escher/message_table_cell_with_chevron_and_buffer.h +++ b/escher/include/escher/message_table_cell_with_chevron_and_buffer.h @@ -4,7 +4,7 @@ #include #include -class MessageTableCellWithChevronAndBuffer : public MessageTableCellWithChevron { +class MessageTableCellWithChevronAndBuffer : public MessageTableCellWithChevron<> { public: MessageTableCellWithChevronAndBuffer(const KDFont * labelFont = KDFont::SmallFont, const KDFont * subAccessoryFont = KDFont::SmallFont); View * subAccessoryView() const override; diff --git a/escher/include/escher/message_table_cell_with_chevron_and_expression.h b/escher/include/escher/message_table_cell_with_chevron_and_expression.h index f94cac89b..72b4f2059 100644 --- a/escher/include/escher/message_table_cell_with_chevron_and_expression.h +++ b/escher/include/escher/message_table_cell_with_chevron_and_expression.h @@ -4,7 +4,7 @@ #include #include -class MessageTableCellWithChevronAndExpression : public MessageTableCellWithChevron { +class MessageTableCellWithChevronAndExpression : public MessageTableCellWithChevron<> { public: MessageTableCellWithChevronAndExpression(I18n::Message message = (I18n::Message)0, const KDFont * font = KDFont::SmallFont); View * subAccessoryView() const override; diff --git a/escher/include/escher/message_table_cell_with_chevron_and_message.h b/escher/include/escher/message_table_cell_with_chevron_and_message.h index 976dc69ad..041b49df3 100644 --- a/escher/include/escher/message_table_cell_with_chevron_and_message.h +++ b/escher/include/escher/message_table_cell_with_chevron_and_message.h @@ -3,7 +3,7 @@ #include -class MessageTableCellWithChevronAndMessage : public MessageTableCellWithChevron { +class MessageTableCellWithChevronAndMessage : public MessageTableCellWithChevron<> { public: MessageTableCellWithChevronAndMessage(const KDFont * labelFont = KDFont::SmallFont, const KDFont * contentFont = KDFont::SmallFont); View * subAccessoryView() const override; diff --git a/escher/include/escher/message_table_cell_with_editable_text.h b/escher/include/escher/message_table_cell_with_editable_text.h index 54e0e19c6..ceb16e7ea 100644 --- a/escher/include/escher/message_table_cell_with_editable_text.h +++ b/escher/include/escher/message_table_cell_with_editable_text.h @@ -6,7 +6,7 @@ #include #include -class MessageTableCellWithEditableText : public Responder, public MessageTableCell { +class MessageTableCellWithEditableText : public Responder, public MessageTableCell<> { public: MessageTableCellWithEditableText(Responder * parentResponder = nullptr, InputEventHandlerDelegate * inputEventHandlerDelegate = nullptr, TextFieldDelegate * textFieldDelegate = nullptr, I18n::Message message = (I18n::Message)0); View * accessoryView() const override; diff --git a/escher/include/escher/message_table_cell_with_expression.h b/escher/include/escher/message_table_cell_with_expression.h index f9704eb22..c5778393a 100644 --- a/escher/include/escher/message_table_cell_with_expression.h +++ b/escher/include/escher/message_table_cell_with_expression.h @@ -4,7 +4,7 @@ #include #include -class MessageTableCellWithExpression : public MessageTableCell { +class MessageTableCellWithExpression : public MessageTableCell<> { public: MessageTableCellWithExpression(I18n::Message message = (I18n::Message)0, const KDFont * font = KDFont::LargeFont); View * accessoryView() const override; diff --git a/escher/include/escher/message_table_cell_with_gauge.h b/escher/include/escher/message_table_cell_with_gauge.h index 8dfddf599..527ce948e 100644 --- a/escher/include/escher/message_table_cell_with_gauge.h +++ b/escher/include/escher/message_table_cell_with_gauge.h @@ -4,7 +4,7 @@ #include #include -class MessageTableCellWithGauge : public MessageTableCell { +class MessageTableCellWithGauge : public MessageTableCell<> { public: MessageTableCellWithGauge(I18n::Message message = (I18n::Message)0, const KDFont * font = KDFont::SmallFont); View * accessoryView() const override; diff --git a/escher/include/escher/message_table_cell_with_message.h b/escher/include/escher/message_table_cell_with_message.h index 02257f96e..243b3be92 100644 --- a/escher/include/escher/message_table_cell_with_message.h +++ b/escher/include/escher/message_table_cell_with_message.h @@ -3,9 +3,10 @@ #include -class MessageTableCellWithMessage : public MessageTableCell { +template +class MessageTableCellWithMessage : public MessageTableCell { public: - MessageTableCellWithMessage(I18n::Message message = (I18n::Message)0, Layout layout = Layout::Vertical); + MessageTableCellWithMessage(I18n::Message message = (I18n::Message)0, TableCell::Layout layout = TableCell::Layout::Vertical); View * accessoryView() const override; void setHighlighted(bool highlight) override; void setAccessoryMessage(I18n::Message textBody); diff --git a/escher/include/escher/message_table_cell_with_switch.h b/escher/include/escher/message_table_cell_with_switch.h index 78e27ef07..1a334872a 100644 --- a/escher/include/escher/message_table_cell_with_switch.h +++ b/escher/include/escher/message_table_cell_with_switch.h @@ -4,7 +4,7 @@ #include #include -class MessageTableCellWithSwitch : public MessageTableCell { +class MessageTableCellWithSwitch : public MessageTableCell<> { public: MessageTableCellWithSwitch(I18n::Message message = (I18n::Message)0, const KDFont * font = KDFont::SmallFont); View * accessoryView() const override; diff --git a/escher/include/escher/run_loop.h b/escher/include/escher/run_loop.h index 2ef4b9207..26ddc0ad6 100644 --- a/escher/include/escher/run_loop.h +++ b/escher/include/escher/run_loop.h @@ -9,13 +9,14 @@ public: RunLoop(); void run(); void runWhile(bool (*callback)(void * ctx), void * ctx); + void addTimer(Timer * timer); + void removeTimer(Timer * timer); protected: virtual bool dispatchEvent(Ion::Events::Event e) = 0; - virtual int numberOfTimers(); - virtual Timer * timerAtIndex(int i); private: bool step(); int m_time; + Timer * m_firstTimer; }; #endif diff --git a/escher/include/escher/slideable_message_text_view.h b/escher/include/escher/slideable_message_text_view.h new file mode 100644 index 000000000..fa9ae4e56 --- /dev/null +++ b/escher/include/escher/slideable_message_text_view.h @@ -0,0 +1,26 @@ + +#ifndef ESCHER_SLIDEABLE_MESSAGE_TEXT_VIEW_H +#define ESCHER_SLIDEABLE_MESSAGE_TEXT_VIEW_H + +#include +#include + +class SlideableMessageTextView : public MessageTextView, public Animated { +public: + SlideableMessageTextView(const KDFont * font = KDFont::LargeFont, I18n::Message message = (I18n::Message)0, float horizontalAlignment = 0.0f, float verticalAlignment = 0.0f, + KDColor textColor = Palette::PrimaryText, KDColor backgroundColor = Palette::ListCellBackground); + void willStartAnimation() override; + void didStopAnimation() override; + void animate() override; + + /* TextView */ + void drawRect(KDContext * ctx, KDRect rect) const override; + +private: + static constexpr uint8_t k_numberOfSpaces = 3; + KDCoordinate m_textOffset; + bool m_goingLeft; // true if we are going left, false if we are going right + bool m_paused; +}; + +#endif diff --git a/escher/include/escher/timer.h b/escher/include/escher/timer.h index 94ed476c4..7c9f4cb16 100644 --- a/escher/include/escher/timer.h +++ b/escher/include/escher/timer.h @@ -3,25 +3,24 @@ #include -/* Timers we'll need - * - Blink cursor timer - * - Dim Screen timer - * - Power down timer - * - Watchdog timer ? - * - Battery level timer - * - LED blink timer +/** + * A timer that can be used to schedule events. + * We organize timers in a linked list. */ - class Timer { public: static constexpr int TickDuration = 300; // In Miliseconds Timer(uint32_t period); // Period is in ticks bool tick(); void reset(uint32_t NewPeriod = -1); + void setNext(Timer * next) { m_next = next; } + Timer * next() { return m_next; } protected: virtual bool fire() = 0; uint32_t m_period; uint32_t m_numberOfTicksBeforeFire; +private: + Timer * m_next; }; #endif diff --git a/escher/include/escher/toolbox.h b/escher/include/escher/toolbox.h index f128f54eb..9a9ff0964 100644 --- a/escher/include/escher/toolbox.h +++ b/escher/include/escher/toolbox.h @@ -28,8 +28,8 @@ protected: /* indexAfterFork is called when a fork-node is encountered to choose which * of its children should be selected, based on external context. */ virtual int indexAfterFork() const { assert(false); return 0; }; - MessageTableCellWithMessage * leafCellAtIndex(int index) override = 0; - MessageTableCellWithChevron * nodeCellAtIndex(int index) override = 0; + MessageTableCellWithMessage * leafCellAtIndex(int index) override = 0; + MessageTableCellWithChevron * nodeCellAtIndex(int index) override = 0; mutable const ToolboxMessageTree * m_messageTreeModel; /* m_messageTreeModel points at the messageTree of the tree (describing the * whole model) where we are located. It enables to know which rows are leaves diff --git a/escher/include/escher/toolbox_message_tree.h b/escher/include/escher/toolbox_message_tree.h index ba8ac5005..f99db1062 100644 --- a/escher/include/escher/toolbox_message_tree.h +++ b/escher/include/escher/toolbox_message_tree.h @@ -5,14 +5,16 @@ class ToolboxMessageTree : public MessageTree { public: - constexpr static ToolboxMessageTree Leaf(I18n::Message label, I18n::Message text = (I18n::Message)0, bool stripInsertedText = true, I18n::Message insertedText = (I18n::Message)0) { + constexpr static ToolboxMessageTree Leaf(I18n::Message label, I18n::Message text = (I18n::Message)0, bool stripInsertedText = true, I18n::Message insertedText = (I18n::Message)0, bool multiLine = false, uint8_t numberOfLines = 1) { return ToolboxMessageTree( label, text, (insertedText == (I18n::Message)0) ? label : insertedText, static_cast(0), 0, - stripInsertedText); + stripInsertedText, + multiLine, + numberOfLines); }; template constexpr static ToolboxMessageTree Node(I18n::Message label, const ToolboxMessageTree (&children)[N], bool fork = false) { @@ -41,22 +43,28 @@ public: I18n::Message insertedText() const { return m_insertedText; } bool stripInsertedText() const { return m_stripInsertedText; } bool isFork() const { return numberOfChildren() < 0; } + bool isMultiLine() const { return m_multiLine; } + uint8_t numberOfLines() const { return m_numberOfLines; } private: - constexpr ToolboxMessageTree(I18n::Message label, I18n::Message text, I18n::Message insertedText, const ToolboxMessageTree * children, int numberOfChildren, bool stripInsertedText) : + constexpr ToolboxMessageTree(I18n::Message label, I18n::Message text, I18n::Message insertedText, const ToolboxMessageTree * children, int numberOfChildren, bool stripInsertedText, bool multiLine = false, uint8_t numberOfLines = 1) : MessageTree(label, numberOfChildren), m_children(children), m_text(text), m_insertedText(insertedText), m_stripInsertedText(stripInsertedText), - m_childrenConsecutive(true) + m_childrenConsecutive(true), + m_multiLine(multiLine), + m_numberOfLines(numberOfLines) {} - constexpr ToolboxMessageTree(I18n::Message label, I18n::Message text, I18n::Message insertedText, const ToolboxMessageTree ** children, int numberOfChildren, bool stripInsertedText) : + constexpr ToolboxMessageTree(I18n::Message label, I18n::Message text, I18n::Message insertedText, const ToolboxMessageTree ** children, int numberOfChildren, bool stripInsertedText, bool multiLine = false, uint8_t numberOfLines = 1) : MessageTree(label, numberOfChildren), m_children(children), m_text(text), m_insertedText(insertedText), m_stripInsertedText(stripInsertedText), - m_childrenConsecutive(false) + m_childrenConsecutive(false), + m_multiLine(multiLine), + m_numberOfLines(numberOfLines) {} union Children { @@ -71,6 +79,8 @@ private: I18n::Message m_insertedText; bool m_stripInsertedText; const bool m_childrenConsecutive; + bool m_multiLine; + uint8_t m_numberOfLines; }; #endif diff --git a/escher/src/animation_timer.cpp b/escher/src/animation_timer.cpp new file mode 100644 index 000000000..2dd2b898e --- /dev/null +++ b/escher/src/animation_timer.cpp @@ -0,0 +1,15 @@ +#include +#include + + +void AnimationTimer::setAnimated(Animated * animated) { + m_animated = animated; + AppsContainer::sharedAppsContainer()->addTimer(this); +} + +void AnimationTimer::removeAnimated(Animated * animated) { + if (m_animated == animated || animated == nullptr) { + m_animated = nullptr; + AppsContainer::sharedAppsContainer()->removeTimer(this); + } +} diff --git a/escher/src/container.cpp b/escher/src/container.cpp index a307e4cfc..731ad5d0f 100644 --- a/escher/src/container.cpp +++ b/escher/src/container.cpp @@ -55,23 +55,3 @@ void Container::run() { window()->redraw(); RunLoop::run(); } - -int Container::numberOfTimers() { - return s_activeApp->numberOfTimers() + numberOfContainerTimers(); -} - -Timer * Container::timerAtIndex(int i) { - if (i < s_activeApp->numberOfTimers()) { - return s_activeApp->timerAtIndex(i); - } - return containerTimerAtIndex(i-s_activeApp->numberOfTimers()); -} - -int Container::numberOfContainerTimers() { - return 0; -} - -Timer * Container::containerTimerAtIndex(int i) { - assert(false); - return nullptr; -} diff --git a/escher/src/message_table_cell.cpp b/escher/src/message_table_cell.cpp index 648ef9068..af52d0098 100644 --- a/escher/src/message_table_cell.cpp +++ b/escher/src/message_table_cell.cpp @@ -1,39 +1,65 @@ #include #include +#include #include -MessageTableCell::MessageTableCell(I18n::Message label, const KDFont * font, Layout layout) : +template +MessageTableCell::MessageTableCell(I18n::Message label, const KDFont * font, Layout layout) : TableCell(layout), m_messageTextView(font, label, 0, 0.5, Palette::PrimaryText, Palette::ListCellBackground), m_backgroundColor(KDColorWhite) { } -View * MessageTableCell::labelView() const { +template +View * MessageTableCell::labelView() const { return (View *)&m_messageTextView; } -void MessageTableCell::setHighlighted(bool highlight) { +template<> +void MessageTableCell::setHighlighted(bool highlight) { + HighlightCell::setHighlighted(highlight); + KDColor backgroundColor = highlight? Palette::ListCellBackgroundSelected : Palette::ListCellBackground; + m_messageTextView.setBackgroundColor(backgroundColor); + static AnimationTimer s_animationTimer = AnimationTimer(); + if (highlight) { + m_messageTextView.willStartAnimation(); + s_animationTimer.setAnimated(&m_messageTextView); + } else { + s_animationTimer.removeAnimated(&m_messageTextView); + m_messageTextView.didStopAnimation(); + } +} + +template<> +void MessageTableCell::setHighlighted(bool highlight) { HighlightCell::setHighlighted(highlight); KDColor backgroundColor = highlight? Palette::ListCellBackgroundSelected : Palette::ListCellBackground; m_messageTextView.setBackgroundColor(backgroundColor); } -void MessageTableCell::setMessage(I18n::Message text) { +template +void MessageTableCell::setMessage(I18n::Message text) { m_messageTextView.setMessage(text); layoutSubviews(); } -void MessageTableCell::setTextColor(KDColor color) { +template +void MessageTableCell::setTextColor(KDColor color) { m_messageTextView.setTextColor(color); } -void MessageTableCell::setMessageFont(const KDFont * font) { +template +void MessageTableCell::setMessageFont(const KDFont * font) { m_messageTextView.setFont(font); layoutSubviews(); } -void MessageTableCell::setBackgroundColor(KDColor color) { +template +void MessageTableCell::setBackgroundColor(KDColor color) { m_backgroundColor = color; m_messageTextView.setBackgroundColor(color); } + +template class MessageTableCell; +template class MessageTableCell; diff --git a/escher/src/message_table_cell_with_chevron.cpp b/escher/src/message_table_cell_with_chevron.cpp index 0f80c8034..9711d2f79 100644 --- a/escher/src/message_table_cell_with_chevron.cpp +++ b/escher/src/message_table_cell_with_chevron.cpp @@ -1,12 +1,24 @@ #include -MessageTableCellWithChevron::MessageTableCellWithChevron(I18n::Message message, const KDFont * font) : - MessageTableCell(message, font), +template<> +MessageTableCellWithChevron::MessageTableCellWithChevron(I18n::Message message, const KDFont * font) : + MessageTableCell(message, font), m_accessoryView() { } -View * MessageTableCellWithChevron::accessoryView() const { +template<> +MessageTableCellWithChevron::MessageTableCellWithChevron(I18n::Message message, const KDFont * font) : + MessageTableCell(message, font,TableCell::Layout::HorizontalRightOverlap), + m_accessoryView() +{ +} + +template +View * MessageTableCellWithChevron::accessoryView() const { return (View *)&m_accessoryView; } +template class MessageTableCellWithChevron; +template class MessageTableCellWithChevron; + diff --git a/escher/src/message_table_cell_with_message.cpp b/escher/src/message_table_cell_with_message.cpp index 16cfd3c6e..5c3d43aa4 100644 --- a/escher/src/message_table_cell_with_message.cpp +++ b/escher/src/message_table_cell_with_message.cpp @@ -2,38 +2,47 @@ #include #include -MessageTableCellWithMessage::MessageTableCellWithMessage(I18n::Message message, Layout layout) : - MessageTableCell(message, KDFont::SmallFont, layout), +template +MessageTableCellWithMessage::MessageTableCellWithMessage(I18n::Message message, TableCell::Layout layout) : + MessageTableCell(message, KDFont::SmallFont, layout), m_accessoryView(KDFont::SmallFont, (I18n::Message)0, 0.0f, 0.5f) { - if (layout != Layout::Vertical) { + if (layout != TableCell::Layout::Vertical) { m_accessoryView.setAlignment(1.0f, 0.5f); } } -void MessageTableCellWithMessage::setAccessoryMessage(I18n::Message textBody) { +template +void MessageTableCellWithMessage::setAccessoryMessage(I18n::Message textBody) { m_accessoryView.setMessage(textBody); - reloadCell(); + this->reloadCell(); } -View * MessageTableCellWithMessage::accessoryView() const { +template +View * MessageTableCellWithMessage::accessoryView() const { if (strlen(m_accessoryView.text()) == 0) { return nullptr; } return (View *)&m_accessoryView; } -void MessageTableCellWithMessage::setHighlighted(bool highlight) { - MessageTableCell::setHighlighted(highlight); - KDColor backgroundColor = isHighlighted()? Palette::ListCellBackgroundSelected : Palette::ListCellBackground; +template +void MessageTableCellWithMessage::setHighlighted(bool highlight) { + MessageTableCell::setHighlighted(highlight); + KDColor backgroundColor = this->isHighlighted()? Palette::ListCellBackgroundSelected : Palette::ListCellBackground; m_accessoryView.setBackgroundColor(backgroundColor); } -void MessageTableCellWithMessage::setTextColor(KDColor color) { +template +void MessageTableCellWithMessage::setTextColor(KDColor color) { m_accessoryView.setTextColor(color); - MessageTableCell::setTextColor(color); + MessageTableCell::setTextColor(color); } -void MessageTableCellWithMessage::setAccessoryTextColor(KDColor color) { +template +void MessageTableCellWithMessage::setAccessoryTextColor(KDColor color) { m_accessoryView.setTextColor(color); } + +template class MessageTableCellWithMessage; +template class MessageTableCellWithMessage; diff --git a/escher/src/run_loop.cpp b/escher/src/run_loop.cpp index f5d8c3b97..bc2f02a09 100644 --- a/escher/src/run_loop.cpp +++ b/escher/src/run_loop.cpp @@ -3,16 +3,9 @@ #include RunLoop::RunLoop() : - m_time(0) { -} - -int RunLoop::numberOfTimers() { - return 0; -} - -Timer * RunLoop::timerAtIndex(int i) { - assert(false); - return nullptr; + m_time(0), + m_firstTimer(nullptr) +{ } void RunLoop::run() { @@ -45,11 +38,12 @@ bool RunLoop::step() { if (m_time >= Timer::TickDuration) { m_time -= Timer::TickDuration; - for (int i=0; itick()) { dispatchEvent(Ion::Events::TimerFire); } + timer = timer->next(); } } @@ -65,7 +59,7 @@ bool RunLoop::step() { #endif if (event != Ion::Events::None) { -#if !PLATFORM_DEVICE +#if !PLATFORM_DEVICEdidStopAnimation if (event == Ion::Events::ExternalText && !KDFont::CanBeWrittenWithGlyphs(event.text())) { return true; } @@ -75,3 +69,27 @@ bool RunLoop::step() { return event != Ion::Events::Termination; } + +void RunLoop::addTimer(Timer * timer) { + if (m_firstTimer == nullptr) { + m_firstTimer = timer; + } else { + Timer * actual = m_firstTimer; + while (actual->next()) { + actual = actual->next(); + } + actual->setNext(timer); + } +} + +void RunLoop::removeTimer(Timer * timer) { + if (m_firstTimer == timer) { + m_firstTimer = timer->next(); + } else { + Timer * actual = m_firstTimer; + while (actual->next() != timer) { + actual = actual->next(); + } + actual->setNext(timer->next()); + } +} diff --git a/escher/src/slideable_message_text_view.cpp b/escher/src/slideable_message_text_view.cpp new file mode 100644 index 000000000..f55b3f22a --- /dev/null +++ b/escher/src/slideable_message_text_view.cpp @@ -0,0 +1,63 @@ +#include +#include + +SlideableMessageTextView::SlideableMessageTextView(const KDFont * font, I18n::Message message, float horizontalAlignment, float verticalAlignment, KDColor textColor, KDColor backgroundColor) : + MessageTextView(font, message, horizontalAlignment, verticalAlignment, textColor, backgroundColor), + m_textOffset(0) +{ + +} + +void SlideableMessageTextView::willStartAnimation() { + m_textOffset = 0; + m_goingLeft = true; + m_paused = true; +} + +void SlideableMessageTextView::didStopAnimation() { + m_textOffset = 0; +} + +void SlideableMessageTextView::animate() { + if (m_paused) { + m_paused = false; + return; + } + + if (text() == nullptr) { + return; + } + + KDSize textSize = m_font->stringSize(text()); + + if (textSize.width() <= bounds().width()) { + return; + } + + KDCoordinate glyphWidth = m_font->glyphSize().width(); + m_textOffset += glyphWidth * (m_goingLeft ? -1 : 1); + + if (m_goingLeft && textSize.width() + m_textOffset < bounds().width()) { + m_goingLeft = false; + m_textOffset = bounds().width() - textSize.width(); + m_paused = true; + } else if (!m_goingLeft && m_textOffset > 0) { + m_goingLeft = true; + m_textOffset = 0; + m_paused = true; + } + + markRectAsDirty(bounds()); +} + +void SlideableMessageTextView::drawRect(KDContext * ctx, KDRect rect) const { + if (text() == nullptr) { + return; + } + KDSize textSize = m_font->stringSize(text()); + KDPoint origin( + m_horizontalAlignment * (m_frame.width() - textSize.width()) + m_textOffset, + m_verticalAlignment * (m_frame.height() - textSize.height())); + ctx->fillRect(bounds(), m_backgroundColor); + ctx->drawString(text(), origin, m_font, m_textColor, m_backgroundColor); +} diff --git a/escher/src/toolbox.cpp b/escher/src/toolbox.cpp index 29f22a041..14bc47014 100644 --- a/escher/src/toolbox.cpp +++ b/escher/src/toolbox.cpp @@ -27,15 +27,16 @@ int Toolbox::reusableCellCount(int type) { void Toolbox::willDisplayCellForIndex(HighlightCell * cell, int index) { ToolboxMessageTree * messageTree = (ToolboxMessageTree *)m_messageTreeModel->childAtIndex(index); if (messageTree->numberOfChildren() == 0) { - MessageTableCellWithMessage * myCell = (MessageTableCellWithMessage *)cell; + MessageTableCellWithMessage * myCell = (MessageTableCellWithMessage *)cell; myCell->setMessage(messageTree->label()); myCell->setAccessoryMessage(messageTree->text()); myCell->setAccessoryTextColor(Palette::SecondaryText); return; + } else { + MessageTableCell<> * myCell = (MessageTableCell<> *)cell; + myCell->setMessage(messageTree->label()); + myCell->reloadCell(); } - MessageTableCell * myCell = (MessageTableCell *)cell; - myCell->setMessage(messageTree->label()); - myCell->reloadCell(); } int Toolbox::typeAtLocation(int i, int j) { diff --git a/kandinsky/src/font.cpp b/kandinsky/src/font.cpp index 67d39383b..7889fde81 100644 --- a/kandinsky/src/font.cpp +++ b/kandinsky/src/font.cpp @@ -5,6 +5,7 @@ extern "C" { #include #include #include +#include constexpr static int k_tabCharacterWidth = 4; @@ -12,24 +13,30 @@ KDSize KDFont::stringSizeUntil(const char * text, const char * limit) const { if (text == nullptr || (limit != nullptr && text >= limit)) { return KDSizeZero; } - KDSize stringSize = KDSize(0, m_glyphSize.height()); + KDSize stringSize = KDSize(0, 0); + KDSize lineSize = KDSize(0, m_glyphSize.height()); UTF8Decoder decoder(text); const char * currentStringPosition = decoder.stringPosition(); CodePoint codePoint = decoder.nextCodePoint(); while (codePoint != UCodePointNull && (limit == nullptr || currentStringPosition < limit)) { - KDSize cSize = KDSize(m_glyphSize.width(), 0); + KDCoordinate codePointWidth = m_glyphSize.width(); if (codePoint == UCodePointLineFeed) { - cSize = KDSize(0, m_glyphSize.height()); + KDCoordinate width = std::max(lineSize.width(), stringSize.width()); + stringSize = KDSize(width, stringSize.height() + m_glyphSize.height()); + lineSize = KDSize(0, m_glyphSize.height()); + codePointWidth = 0; } else if (codePoint == UCodePointTabulation) { - cSize = KDSize(k_tabCharacterWidth * m_glyphSize.width(), 0); + codePointWidth = k_tabCharacterWidth * m_glyphSize.width(); } else if (codePoint.isCombining()) { - cSize = KDSizeZero; + codePointWidth = 0; } - stringSize = KDSize(stringSize.width() + cSize.width(), stringSize.height() + cSize.height()); + lineSize = KDSize(lineSize.width() + codePointWidth, lineSize.height()); currentStringPosition = decoder.stringPosition(); codePoint = decoder.nextCodePoint(); } + KDCoordinate width = std::max(lineSize.width(), stringSize.width()); + stringSize = KDSize(width, stringSize.height() + m_glyphSize.height()); assert(stringSize.width() >= 0 && stringSize.height() >= 0); return stringSize; }