[shared] Move OutputExpressionView & ScrollableOuputExpression view to shared/ with new name:

ScrollableExactApproximateExpressionsView (for future implementation of solver
solution page)
This commit is contained in:
Émilie Feral
2018-05-30 09:57:43 +02:00
parent ace75e6ead
commit cfb891d7bd
10 changed files with 143 additions and 168 deletions

View File

@@ -9,9 +9,7 @@ app_objs += $(addprefix apps/calculation/,\
expression_field.o\
history_view_cell.o\
history_controller.o\
output_expressions_view.o\
scrollable_expression_view.o\
scrollable_output_expressions_view.o\
selectable_table_view.o\
)

View File

@@ -3,6 +3,8 @@
#include "../apps_container.h"
#include <assert.h>
using namespace Shared;
namespace Calculation {
HistoryController::HistoryController(Responder * parentResponder, CalculationStore * calculationStore) :
@@ -47,8 +49,8 @@ bool HistoryController::handleEvent(Ion::Events::Event event) {
if (subviewType == HistoryViewCell::SubviewType::Input) {
editController->insertTextBody(calculation->inputText());
} else {
OutputExpressionsView::SubviewType outputSubviewType = selectedCell->outputView()->selectedSubviewType();
if (outputSubviewType == OutputExpressionsView::SubviewType::ExactOutput) {
ScrollableExactApproximateExpressionsView::SubviewType outputSubviewType = selectedCell->outputView()->selectedSubviewType();
if (outputSubviewType == ScrollableExactApproximateExpressionsView::SubviewType::ExactOutput) {
editController->insertTextBody(calculation->exactOutputText());
} else {
editController->insertTextBody(calculation->approximateOutputText());
@@ -102,8 +104,8 @@ bool HistoryController::handleEvent(Ion::Events::Event event) {
if (subviewType == HistoryViewCell::SubviewType::Input) {
Clipboard::sharedClipboard()->store(calculation->inputText());
} else {
OutputExpressionsView::SubviewType outputSubviewType = selectedCell->outputView()->selectedSubviewType();
if (outputSubviewType == OutputExpressionsView::SubviewType::ExactOutput) {
ScrollableExactApproximateExpressionsView::SubviewType outputSubviewType = selectedCell->outputView()->selectedSubviewType();
if (outputSubviewType == ScrollableExactApproximateExpressionsView::SubviewType::ExactOutput) {
Clipboard::sharedClipboard()->store(calculation->exactOutputText());
} else {
Clipboard::sharedClipboard()->store(calculation->approximateOutputText());

View File

@@ -33,32 +33,32 @@ HistoryViewCell::~HistoryViewCell() {
}
}
OutputExpressionsView * HistoryViewCell::outputView() {
return m_scrollableOutputView.outputView();
Shared::ScrollableExactApproximateExpressionsView * HistoryViewCell::outputView() {
return &m_scrollableOutputView;
}
void HistoryViewCell::setEven(bool even) {
EvenOddCell::setEven(even);
m_inputView.setBackgroundColor(backgroundColor());
m_scrollableOutputView.outputView()->setEven(even);
m_scrollableOutputView.evenOddCell()->setEven(even);
}
void HistoryViewCell::setHighlighted(bool highlight) {
m_highlighted = highlight;
m_inputView.setBackgroundColor(backgroundColor());
m_scrollableOutputView.outputView()->setHighlighted(false);
m_scrollableOutputView.evenOddCell()->setHighlighted(false);
if (isHighlighted()) {
if (m_selectedSubviewType == SubviewType::Input) {
m_inputView.setBackgroundColor(Palette::Select);
} else {
m_scrollableOutputView.outputView()->setHighlighted(true);
m_scrollableOutputView.evenOddCell()->setHighlighted(true);
}
}
reloadScroll();
}
void HistoryViewCell::reloadCell() {
m_scrollableOutputView.outputView()->reloadCell();
m_scrollableOutputView.evenOddCell()->reloadCell();
layoutSubviews();
reloadScroll();
}
@@ -107,9 +107,9 @@ void HistoryViewCell::setCalculation(Calculation * calculation) {
m_inputLayout = calculation->createInputLayout();
m_inputView.setExpressionLayout(m_inputLayout);
App * calculationApp = (App *)app();
/* Both output expressions have to be updated at the same time. The
* outputView points to deleted layouts and a call to
* outputView()->layoutSubviews() is going to fail. */
/* Both output expressions have to be updated at the same time. Otherwise,
* when updating one layout, if the second one still points to a deleted
* layout, calling to layoutSubviews() would fail. */
if (m_exactOutputLayout) {
delete m_exactOutputLayout;
m_exactOutputLayout = nullptr;
@@ -122,9 +122,9 @@ void HistoryViewCell::setCalculation(Calculation * calculation) {
}
m_approximateOutputLayout = calculation->createApproximateOutputLayout(calculationApp->localContext());
Poincare::ExpressionLayout * outputExpressions[2] = {m_approximateOutputLayout, m_exactOutputLayout};
m_scrollableOutputView.outputView()->setExpressions(outputExpressions);
m_scrollableOutputView.setExpressions(outputExpressions);
I18n::Message equalMessage = calculation->exactAndApproximateDisplayedOutputsAreEqual(calculationApp->localContext()) == Calculation::EqualSign::Equal ? I18n::Message::Equal : I18n::Message::AlmostEqual;
m_scrollableOutputView.outputView()->setEqualMessage(equalMessage);
m_scrollableOutputView.setEqualMessage(equalMessage);
}
void HistoryViewCell::didBecomeFirstResponder() {

View File

@@ -4,7 +4,7 @@
#include <escher.h>
#include "calculation.h"
#include "scrollable_expression_view.h"
#include "scrollable_output_expressions_view.h"
#include "../shared/scrollable_exact_approximate_expressions_view.h"
namespace Calculation {
@@ -33,14 +33,14 @@ public:
constexpr static KDCoordinate k_digitVerticalMargin = 5;
SubviewType selectedSubviewType();
void setSelectedSubviewType(HistoryViewCell::SubviewType subviewType);
OutputExpressionsView * outputView();
Shared::ScrollableExactApproximateExpressionsView * outputView();
private:
constexpr static KDCoordinate k_resultWidth = 80;
Poincare::ExpressionLayout * m_inputLayout;
Poincare::ExpressionLayout * m_exactOutputLayout;
Poincare::ExpressionLayout * m_approximateOutputLayout;
ScrollableExpressionView m_inputView;
ScrollableOutputExpressionsView m_scrollableOutputView;
Shared::ScrollableExactApproximateExpressionsView m_scrollableOutputView;
SubviewType m_selectedSubviewType;
};

View File

@@ -1,41 +0,0 @@
#ifndef CALCULATION_OUTPUT_EXPRESSIONS_VIEW_H
#define CALCULATION_OUTPUT_EXPRESSIONS_VIEW_H
#include <escher.h>
namespace Calculation {
class OutputExpressionsView : public EvenOddCell, public Responder {
public:
enum class SubviewType {
ExactOutput,
ApproximativeOutput
};
OutputExpressionsView(Responder * parentResponder);
void setExpressions(Poincare::ExpressionLayout ** expressionsLayout);
void setEqualMessage(I18n::Message equalSignMessage);
KDColor backgroundColor() const override;
void setHighlighted(bool highlight) override;
Responder * responder() override {
return this;
}
void reloadCell() override;
KDSize minimalSizeForOptimalDisplay() const override;
void didBecomeFirstResponder() override;
bool handleEvent(Ion::Events::Event event) override;
SubviewType selectedSubviewType();
void setSelectedSubviewType(SubviewType subviewType);
private:
int numberOfSubviews() const override;
View * subviewAtIndex(int index) override;
void layoutSubviews() override;
constexpr static KDCoordinate k_digitHorizontalMargin = 10;
ExpressionView m_approximateExpressionView;
MessageTextView m_approximateSign;
ExpressionView m_exactExpressionView;
SubviewType m_selectedSubviewType;
};
}
#endif

View File

@@ -1,29 +0,0 @@
#include "scrollable_output_expressions_view.h"
#include <assert.h>
using namespace Poincare;
namespace Calculation {
ScrollableOutputExpressionsView::ScrollableOutputExpressionsView(Responder * parentResponder) :
ScrollableView(parentResponder, &m_outputView, this),
m_outputView(this)
{
}
OutputExpressionsView * ScrollableOutputExpressionsView::outputView() {
return &m_outputView;
}
void ScrollableOutputExpressionsView::didBecomeFirstResponder() {
app()->setFirstResponder(&m_outputView);
}
KDSize ScrollableOutputExpressionsView::minimalSizeForOptimalDisplay() const {
return m_outputView.minimalSizeForOptimalDisplay();
}
KDPoint ScrollableOutputExpressionsView::manualScrollingOffset() const {
return m_manualScrollingOffset;
}
}

View File

@@ -1,22 +0,0 @@
#ifndef CALCULATION_SCROLLABLE_OUTPUT_EXPRESSIONS_VIEW_H
#define CALCULATION_SCROLLABLE_OUTPUT_EXPRESSIONS_VIEW_H
#include <escher.h>
#include "output_expressions_view.h"
namespace Calculation {
class ScrollableOutputExpressionsView : public ScrollableView, public ScrollViewDataSource {
public:
ScrollableOutputExpressionsView(Responder * parentResponder);
OutputExpressionsView * outputView();
void didBecomeFirstResponder() override;
KDSize minimalSizeForOptimalDisplay() const override;
KDPoint manualScrollingOffset() const;
private:
OutputExpressionsView m_outputView;
};
}
#endif

View File

@@ -39,6 +39,7 @@ app_objs += $(addprefix apps/shared/,\
range_parameter_controller.o\
regular_table_view_data_source.o\
round_cursor_view.o\
scrollable_exact_approximate_expressions_view.o\
simple_interactive_curve_view_controller.o\
expression_layout_field_delegate.o\
store_controller.o\

View File

@@ -1,31 +1,24 @@
#include "output_expressions_view.h"
#include "scrollable_output_expressions_view.h"
#include "scrollable_exact_approximate_expressions_view.h"
#include "../i18n.h"
#include <assert.h>
using namespace Poincare;
namespace Calculation {
namespace Shared {
OutputExpressionsView::OutputExpressionsView(Responder * parentResponder) :
Responder(parentResponder),
ScrollableExactApproximateExpressionsView::ContentCell::ContentCell() :
m_approximateExpressionView(),
m_approximateSign(KDText::FontSize::Large, I18n::Message::AlmostEqual, 0.5f, 0.5f, Palette::GreyVeryDark),
m_exactExpressionView(),
m_selectedSubviewType(OutputExpressionsView::SubviewType::ExactOutput)
m_selectedSubviewType((SubviewType)0)
{
}
void OutputExpressionsView::setExpressions(ExpressionLayout ** expressionsLayout) {
m_approximateExpressionView.setExpressionLayout(expressionsLayout[0]);
m_exactExpressionView.setExpressionLayout(expressionsLayout[1]);
layoutSubviews();
KDColor ScrollableExactApproximateExpressionsView::ContentCell::backgroundColor() const {
KDColor background = m_even ? Palette::WallScreen : KDColorWhite;
return background;
}
void OutputExpressionsView::setEqualMessage(I18n::Message equalSignMessage) {
m_approximateSign.setMessage(equalSignMessage);
}
void OutputExpressionsView::setHighlighted(bool highlight) {
void ScrollableExactApproximateExpressionsView::ContentCell::setHighlighted(bool highlight) {
// Do not call HighlightCell::setHighlighted to avoid marking all cell as dirty
m_highlighted = highlight;
m_exactExpressionView.setBackgroundColor(backgroundColor());
@@ -39,12 +32,7 @@ void OutputExpressionsView::setHighlighted(bool highlight) {
}
}
KDColor OutputExpressionsView::backgroundColor() const {
KDColor background = m_even ? Palette::WallScreen : KDColorWhite;
return background;
}
void OutputExpressionsView::reloadCell() {
void ScrollableExactApproximateExpressionsView::ContentCell::reloadCell() {
setHighlighted(isHighlighted());
m_approximateSign.setBackgroundColor(backgroundColor());
if (numberOfSubviews() == 1) {
@@ -55,7 +43,7 @@ void OutputExpressionsView::reloadCell() {
layoutSubviews();
}
KDSize OutputExpressionsView::minimalSizeForOptimalDisplay() const {
KDSize ScrollableExactApproximateExpressionsView::ContentCell::minimalSizeForOptimalDisplay() const {
KDSize approximateExpressionSize = m_approximateExpressionView.minimalSizeForOptimalDisplay();
if (numberOfSubviews() == 1) {
return approximateExpressionSize;
@@ -68,54 +56,24 @@ KDSize OutputExpressionsView::minimalSizeForOptimalDisplay() const {
return KDSize(exactExpressionSize.width()+approximateSignSize.width()+approximateExpressionSize.width()+2*k_digitHorizontalMargin, height);
}
void OutputExpressionsView::didBecomeFirstResponder() {
if (numberOfSubviews() == 1) {
setSelectedSubviewType(SubviewType::ApproximativeOutput);
} else {
setSelectedSubviewType(SubviewType::ExactOutput);
}
}
bool OutputExpressionsView::handleEvent(Ion::Events::Event event) {
if (numberOfSubviews() == 1) {
return false;
}
ScrollableOutputExpressionsView * scrollResponder = static_cast<ScrollableOutputExpressionsView *>(parentResponder());
KDCoordinate offset = scrollResponder->manualScrollingOffset().x();
bool rightExpressionIsVisible = minimalSizeForOptimalDisplay().width() - m_approximateExpressionView.minimalSizeForOptimalDisplay().width() - offset < scrollResponder->bounds().width()
;
bool leftExpressionIsVisible = m_exactExpressionView.minimalSizeForOptimalDisplay().width() - offset < scrollResponder->bounds().width();
if ((event == Ion::Events::Right && m_selectedSubviewType == SubviewType::ExactOutput && rightExpressionIsVisible) ||
(event == Ion::Events::Left && m_selectedSubviewType == SubviewType::ApproximativeOutput && leftExpressionIsVisible)) {
SubviewType otherSubviewType = m_selectedSubviewType == SubviewType::ExactOutput ? SubviewType::ApproximativeOutput : SubviewType::ExactOutput;
setSelectedSubviewType(otherSubviewType);
return true;
}
return false;
}
OutputExpressionsView::SubviewType OutputExpressionsView::selectedSubviewType() {
return m_selectedSubviewType;
}
void OutputExpressionsView::setSelectedSubviewType(OutputExpressionsView::SubviewType subviewType) {
void ScrollableExactApproximateExpressionsView::ContentCell::setSelectedSubviewType(ScrollableExactApproximateExpressionsView::SubviewType subviewType) {
m_selectedSubviewType = subviewType;
setHighlighted(isHighlighted());
}
int OutputExpressionsView::numberOfSubviews() const {
int ScrollableExactApproximateExpressionsView::ContentCell::numberOfSubviews() const {
if (m_exactExpressionView.expressionLayout() != nullptr) {
return 3;
}
return 1;
}
View * OutputExpressionsView::subviewAtIndex(int index) {
View * ScrollableExactApproximateExpressionsView::ContentCell::subviewAtIndex(int index) {
View * views[3] = {&m_approximateExpressionView, &m_approximateSign, &m_exactExpressionView};
return views[index];
}
void OutputExpressionsView::layoutSubviews() {
void ScrollableExactApproximateExpressionsView::ContentCell::layoutSubviews() {
KDCoordinate height = bounds().height();
KDSize approximateExpressionSize = m_approximateExpressionView.minimalSizeForOptimalDisplay();
if (numberOfSubviews() == 1) {
@@ -132,4 +90,47 @@ void OutputExpressionsView::layoutSubviews() {
m_approximateSign.setFrame(KDRect(k_digitHorizontalMargin+exactExpressionSize.width(), baseline-approximateSignSize.height()/2, approximateSignSize));
}
ScrollableExactApproximateExpressionsView::ScrollableExactApproximateExpressionsView(Responder * parentResponder) :
ScrollableView(parentResponder, &m_contentCell, this),
m_contentCell()
{
}
void ScrollableExactApproximateExpressionsView::setExpressions(ExpressionLayout ** expressionsLayout) {
m_contentCell.approximateExpressionView()->setExpressionLayout(expressionsLayout[0]);
m_contentCell.exactExpressionView()->setExpressionLayout(expressionsLayout[1]);
m_contentCell.layoutSubviews();
}
void ScrollableExactApproximateExpressionsView::setEqualMessage(I18n::Message equalSignMessage) {
m_contentCell.approximateSign()->setMessage(equalSignMessage);
}
void ScrollableExactApproximateExpressionsView::didBecomeFirstResponder() {
if (m_contentCell.exactExpressionView()->expressionLayout() == nullptr) {
setSelectedSubviewType(SubviewType::ApproximativeOutput);
} else {
setSelectedSubviewType(SubviewType::ExactOutput);
}
}
bool ScrollableExactApproximateExpressionsView::handleEvent(Ion::Events::Event event) {
if (m_contentCell.exactExpressionView()->expressionLayout() == nullptr) {
return ScrollableView::handleEvent(event);
}
bool rightExpressionIsVisible = minimalSizeForOptimalDisplay().width() - m_contentCell.approximateExpressionView()->minimalSizeForOptimalDisplay().width() - m_manualScrollingOffset.x() < bounds().width()
;
bool leftExpressionIsVisible = m_contentCell.exactExpressionView()->minimalSizeForOptimalDisplay().width() - m_manualScrollingOffset.x() < bounds().width();
if ((event == Ion::Events::Right && selectedSubviewType() == SubviewType::ExactOutput && rightExpressionIsVisible) ||
(event == Ion::Events::Left && selectedSubviewType() == SubviewType::ApproximativeOutput && leftExpressionIsVisible)) {
SubviewType otherSubviewType = selectedSubviewType() == SubviewType::ExactOutput ? SubviewType::ApproximativeOutput : SubviewType::ExactOutput;
setSelectedSubviewType(otherSubviewType);
return true;
}
return ScrollableView::handleEvent(event);
}
KDSize ScrollableExactApproximateExpressionsView::minimalSizeForOptimalDisplay() const {
return m_contentCell.minimalSizeForOptimalDisplay();
}
}

View File

@@ -0,0 +1,65 @@
#ifndef SHARED_SCROLLABLE_EXACT_APPROXIMATE_EXPRESSIONS_VIEW_H
#define SHARED_SCROLLABLE_EXACT_APPROXIMATE_EXPRESSIONS_VIEW_H
#include <escher.h>
namespace Shared {
class ScrollableExactApproximateExpressionsView : public ScrollableView, public ScrollViewDataSource {
public:
enum class SubviewType {
ExactOutput,
ApproximativeOutput
};
ScrollableExactApproximateExpressionsView(Responder * parentResponder);
::EvenOddCell * evenOddCell() {
return &m_contentCell;
}
void setExpressions(Poincare::ExpressionLayout ** expressionsLayout);
void setEqualMessage(I18n::Message equalSignMessage);
SubviewType selectedSubviewType() {
return m_contentCell.selectedSubviewType();
}
void setSelectedSubviewType(SubviewType subviewType) {
m_contentCell.setSelectedSubviewType(subviewType);
}
void didBecomeFirstResponder() override;
bool handleEvent(Ion::Events::Event event) override;
KDSize minimalSizeForOptimalDisplay() const override;
private:
class ContentCell : public ::EvenOddCell {
public:
ContentCell();
KDColor backgroundColor() const override;
void setHighlighted(bool highlight) override;
void reloadCell() override;
KDSize minimalSizeForOptimalDisplay() const override;
ExpressionView * approximateExpressionView() {
return &m_approximateExpressionView;
}
ExpressionView * exactExpressionView() {
return &m_exactExpressionView;
}
MessageTextView * approximateSign() {
return &m_approximateSign;
}
SubviewType selectedSubviewType() {
return m_selectedSubviewType;
}
void setSelectedSubviewType(SubviewType subviewType);
void layoutSubviews() override;
int numberOfSubviews() const override;
private:
View * subviewAtIndex(int index) override;
constexpr static KDCoordinate k_digitHorizontalMargin = 10;
ExpressionView m_approximateExpressionView;
MessageTextView m_approximateSign;
ExpressionView m_exactExpressionView;
SubviewType m_selectedSubviewType;
};
ContentCell m_contentCell;
};
}
#endif