[apps/reg] Fix window sizing: cursor appears even with big bannerview

This commit is contained in:
Léa Saviot
2018-07-10 11:56:02 +02:00
committed by Émilie Feral
parent b9992e5eb6
commit 68d915fb3e
22 changed files with 107 additions and 51 deletions

View File

@@ -45,6 +45,10 @@ App::Descriptor * App::Snapshot::descriptor() {
return &descriptor;
}
void App::Snapshot::tidy() {
m_store.setDelegate(nullptr);
}
App::App(Container * container, Snapshot * snapshot) :
TextFieldDelegateApp(container, snapshot, &m_tabViewController),
m_calculationController(&m_calculationAlternateEmptyViewController, &m_calculationHeader, snapshot->store()),

View File

@@ -32,6 +32,7 @@ public:
uint32_t * modelVersion() { return &m_modelVersion; }
uint32_t * rangeVersion() { return &m_rangeVersion; }
private:
void tidy() override;
Store m_store;
Shared::CurveViewCursor m_cursor;
int m_graphSelectedDotIndex;

View File

@@ -1,10 +1,14 @@
#include "graph_controller.h"
#include "../apps_container.h"
#include <kandinsky/text.h>
#include <cmath>
using namespace Poincare;
using namespace Shared;
static inline float min(float x, float y) { return (x<y ? x : y); }
static inline float max(float x, float y) { return (x>y ? x : y); }
namespace Regression {
GraphController::GraphController(Responder * parentResponder, ButtonRowController * header, Store * store, CurveViewCursor * cursor, uint32_t * modelVersion, uint32_t * rangeVersion, int * selectedDotIndex, int * selectedSeriesIndex) :
@@ -23,6 +27,7 @@ GraphController::GraphController(Responder * parentResponder, ButtonRowControlle
m_modelType[i] = (Model::Type) -1;
}
m_store->setCursor(m_cursor);
m_store->setDelegate(this);
}
ViewController * GraphController::initialisationParameterController() {
@@ -230,7 +235,7 @@ void GraphController::initCursorParameters() {
double x = m_store->meanOfColumn(*m_selectedSeriesIndex, 0);
double y = m_store->meanOfColumn(*m_selectedSeriesIndex, 1);
m_cursor->moveTo(x, y);
m_store->panToMakePointVisible(x, y, k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio);
m_store->panToMakePointVisible(x, y, cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio);
*m_selectedDotIndex = m_store->numberOfPairsOfSeries(*m_selectedSeriesIndex);
}
@@ -240,13 +245,13 @@ bool GraphController::moveCursorHorizontally(int direction) {
if (dotSelected >= 0 && dotSelected < m_store->numberOfPairsOfSeries(*m_selectedSeriesIndex)) {
*m_selectedDotIndex = dotSelected;
m_cursor->moveTo(m_store->get(*m_selectedSeriesIndex, 0, *m_selectedDotIndex), m_store->get(*m_selectedSeriesIndex, 1, *m_selectedDotIndex));
m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio);
m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio);
return true;
}
if (dotSelected == m_store->numberOfPairsOfSeries(*m_selectedSeriesIndex)) {
*m_selectedDotIndex = dotSelected;
m_cursor->moveTo(m_store->meanOfColumn(*m_selectedSeriesIndex, 0), m_store->meanOfColumn(*m_selectedSeriesIndex, 1));
m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio);
m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio);
return true;
}
return false;
@@ -256,7 +261,7 @@ bool GraphController::moveCursorHorizontally(int direction) {
Poincare::Context * globContext = const_cast<AppsContainer *>(static_cast<const AppsContainer *>(app()->container()))->globalContext();
double y = m_store->yValueForXValue(*m_selectedSeriesIndex, x, globContext);
m_cursor->moveTo(x, y);
m_store->panToMakePointVisible(x, y, k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio);
m_store->panToMakePointVisible(x, y, cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio);
return true;
}
@@ -317,7 +322,7 @@ bool GraphController::moveCursorVertically(int direction) {
*m_selectedSeriesIndex = closestRegressionSeries;
selectRegressionCurve();
m_cursor->moveTo(m_cursor->x(), m_store->yValueForXValue(*m_selectedSeriesIndex, m_cursor->x(), globContext));
m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio);
m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio);
return true;
}
@@ -327,11 +332,11 @@ bool GraphController::moveCursorVertically(int direction) {
*m_selectedDotIndex = dotSelected;
if (dotSelected == m_store->numberOfPairsOfSeries(*m_selectedSeriesIndex)) {
m_cursor->moveTo(m_store->meanOfColumn(*m_selectedSeriesIndex, 0), m_store->meanOfColumn(*m_selectedSeriesIndex, 1));
m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio);
m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio);
return true;
}
m_cursor->moveTo(m_store->get(*m_selectedSeriesIndex, 0, *m_selectedDotIndex), m_store->get(*m_selectedSeriesIndex, 1, *m_selectedDotIndex));
m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio);
m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio);
return true;
}
return false;
@@ -346,7 +351,46 @@ uint32_t GraphController::rangeVersion() {
}
bool GraphController::isCursorVisible() {
return interactiveCurveViewRange()->isCursorVisible(k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio);
return interactiveCurveViewRange()->isCursorVisible(cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio);
}
float GraphController::cursorBottomMarginRatio() {
float f = (m_view.cursorView()->minimalSizeForOptimalDisplay().height()/2 + 2 + estimatedBannerHeight())/k_viewHeight;
return f;
}
float GraphController::displayTopMarginRatio() {
return 0.12f; // cursorHeight/graphViewHeight
}
float GraphController::displayBottomMarginRatio() {
float f = (m_view.cursorView()->minimalSizeForOptimalDisplay().height() + 2 + estimatedBannerHeight())/k_viewHeight;
return f;
}
float GraphController::estimatedBannerHeight() const {
if (selectedSeriesIndex() < 0) {
return KDText::charSize(KDText::FontSize::Small).height() * 3;
}
float result = KDText::charSize(KDText::FontSize::Small).height() * m_store->modelForSeries(selectedSeriesIndex())->bannerLinesCount();
return result;
}
InteractiveCurveViewRangeDelegate::Range GraphController::computeYRange(InteractiveCurveViewRange * interactiveCurveViewRange) {
float minY = FLT_MAX;
float maxY = -FLT_MAX;
for (int series = 0; series < Store::k_numberOfSeries; series++) {
for (int k = 0; k < m_store->numberOfPairsOfSeries(series); k++) {
if (m_store->xMin() <= m_store->get(series, 0, k) && m_store->get(series, 0, k) <= m_store->xMax()) {
minY = min(minY, m_store->get(series, 1, k));
maxY = max(maxY, m_store->get(series, 1, k));
}
}
}
InteractiveCurveViewRangeDelegate::Range range;
range.min = minY;
range.max = maxY;
return range;
}
}

View File

@@ -25,10 +25,9 @@ public:
void selectRegressionCurve();
int selectedSeriesIndex() const { return *m_selectedSeriesIndex; }
private:
constexpr static float k_cursorTopMarginRatio = 0.07f; // (cursorHeight/2)/graphViewHeight
constexpr static float k_cursorBottomMarginRatio = 0.3f; // (cursorHeight/2+bannerHeigh)/graphViewHeight
constexpr static int k_maxLegendLength = 16;
constexpr static int k_maxNumberOfCharacters = 50;
constexpr static float k_viewHeight = 174.0f;
Shared::CurveView * curveView() override;
Shared::InteractiveCurveViewRange * interactiveCurveViewRange() override;
bool handleEnter() override;
@@ -40,6 +39,18 @@ private:
uint32_t modelVersion() override;
uint32_t rangeVersion() override;
bool isCursorVisible() override;
// InteractiveCurveViewController
float displayTopMarginRatio() override;
float displayBottomMarginRatio() override;
float cursorTopMarginRatio() { return 0.07f; } // (cursorHeight/2) / graphViewHeight
float cursorBottomMarginRatio();
float estimatedBannerHeight() const;
// InteractiveCurveViewRangeDelegate
Shared::InteractiveCurveViewRangeDelegate::Range computeYRange(Shared::InteractiveCurveViewRange * interactiveCurveViewRange) override;
Shared::CursorView m_crossCursorView;
Shared::RoundCursorView m_roundCursorView;
BannerView m_bannerView;

View File

@@ -15,6 +15,7 @@ public:
double evaluate(double * modelCoefficients, double x) const override;
double partialDerivate(double * modelCoefficients, int derivateCoefficientIndex, double x) const override;
int numberOfCoefficients() const override { return 4; }
int bannerLinesCount() const override { return 4; }
};
}

View File

@@ -15,6 +15,7 @@ public:
double levelSet(double * modelCoefficients, double xMin, double step, double xMax, double y, Poincare::Context * context) override;
double partialDerivate(double * modelCoefficients, int derivateCoefficientIndex, double x) const override;
int numberOfCoefficients() const override { return 2; }
int bannerLinesCount() const override { return 2; }
};
}

View File

@@ -16,6 +16,7 @@ public:
virtual void fit(Store * store, int series, double * modelCoefficients, Poincare::Context * context) override;
double partialDerivate(double * modelCoefficients, int derivateCoefficientIndex, double x) const override;
int numberOfCoefficients() const override { return 2; }
int bannerLinesCount() const override { return 3; }
};
}

View File

@@ -15,6 +15,7 @@ public:
double levelSet(double * modelCoefficients, double xMin, double step, double xMax, double y, Poincare::Context * context) override;
double partialDerivate(double * modelCoefficients, int derivateCoefficientIndex, double x) const override;
int numberOfCoefficients() const override { return 2; }
int bannerLinesCount() const override { return 2; }
protected:
virtual bool dataSuitableForFit(Store * store, int series) const override;
};

View File

@@ -15,6 +15,7 @@ public:
double levelSet(double * modelCoefficients, double xMin, double step, double xMax, double y, Poincare::Context * context) override;
double partialDerivate(double * modelCoefficients, int derivateCoefficientIndex, double x) const override;
int numberOfCoefficients() const override { return 3; }
int bannerLinesCount() const override { return 3; }
};
}

View File

@@ -34,6 +34,7 @@ public:
virtual double levelSet(double * modelCoefficients, double xMin, double step, double xMax, double y, Poincare::Context * context);
virtual void fit(Store * store, int series, double * modelCoefficients, Poincare::Context * context);
virtual int numberOfCoefficients() const = 0;
virtual int bannerLinesCount() const { return 2; }
protected:
// Fit
virtual bool dataSuitableForFit(Store * store, int series) const;

View File

@@ -15,6 +15,7 @@ public:
double levelSet(double * modelCoefficients, double xMin, double step, double xMax, double y, Poincare::Context * context) override;
double partialDerivate(double * modelCoefficients, int derivateCoefficientIndex, double x) const override;
int numberOfCoefficients() const override { return 2; }
int bannerLinesCount() const override { return 2; }
protected:
virtual bool dataSuitableForFit(Store * store, int series) const override;
};

View File

@@ -15,6 +15,7 @@ public:
double evaluate(double * modelCoefficients, double x) const override;
double partialDerivate(double * modelCoefficients, int derivateCoefficientIndex, double x) const override;
int numberOfCoefficients() const override { return 3; }
int bannerLinesCount() const override { return 3; }
};
}

View File

@@ -15,6 +15,7 @@ public:
double evaluate(double * modelCoefficients, double x) const override;
double partialDerivate(double * modelCoefficients, int derivateCoefficientIndex, double x) const override;
int numberOfCoefficients() const override { return 5; }
int bannerLinesCount() const override { return 4; }
};
}

View File

@@ -15,6 +15,7 @@ public:
double evaluate(double * modelCoefficients, double x) const override;
double partialDerivate(double * modelCoefficients, int derivateCoefficientIndex, double x) const override;
int numberOfCoefficients() const override { return 4; }
int bannerLinesCount() const override { return 4; }
};
}

View File

@@ -26,7 +26,7 @@ static_assert(Model::k_numberOfModels == 9, "Number of models changed, Regressio
static_assert(Store::k_numberOfSeries == 3, "Number of series changed, Regression::Store() needs to adapt (m_seriesChecksum)");
Store::Store() :
InteractiveCurveViewRange(nullptr, this),
InteractiveCurveViewRange(nullptr),
DoublePairStore(),
m_seriesChecksum{0, 0, 0},
m_angleUnit(Poincare::Expression::AngleUnit::Default)
@@ -201,15 +201,15 @@ int Store::nextDot(int series, int direction, int dot) {
void Store::setDefault() {
float minX = FLT_MAX;
float maxX = -FLT_MAX;
for (int series = 0; series < k_numberOfSeries; series ++) {
for (int series = 0; series < k_numberOfSeries; series++) {
if (!seriesIsEmpty(series)) {
minX = min(minX, minValueOfColumn(series, 0));
maxX = max(maxX, maxValueOfColumn(series, 0));
}
}
float range = maxX - minX;
setXMin(minX - k_displayLeftMarginRatio*range);
setXMax(maxX + k_displayRightMarginRatio*range);
setXMin(minX - k_displayHorizontalMarginRatio*range);
setXMax(maxX + k_displayHorizontalMarginRatio*range);
setYAuto(true);
}
@@ -329,26 +329,4 @@ double Store::squaredCorrelationCoefficient(int series) const {
return (v0 == 0.0 || v1 == 0.0) ? 1.0 : cov*cov/(v0*v1);
}
InteractiveCurveViewRangeDelegate::Range Store::computeYRange(InteractiveCurveViewRange * interactiveCurveViewRange) {
float minY = FLT_MAX;
float maxY = -FLT_MAX;
for (int series = 0; series < k_numberOfSeries; series++) {
for (int k = 0; k < numberOfPairsOfSeries(series); k++) {
if (m_xMin <= m_data[series][0][k] && m_data[series][0][k] <= m_xMax) {
minY = min(minY, m_data[series][1][k]);
maxY = max(maxY, m_data[series][1][k]);
}
}
}
InteractiveCurveViewRangeDelegate::Range range;
range.min = minY;
range.max = maxY;
return range;
}
float Store::addMargin(float x, float range, bool isMin) {
float ratio = isMin ? -k_displayBottomMarginRatio : k_displayTopMarginRatio;
return x+ratio*range;
}
}

View File

@@ -9,7 +9,7 @@
namespace Regression {
class Store : public Shared::InteractiveCurveViewRange, public Shared::DoublePairStore, public Shared::InteractiveCurveViewRangeDelegate {
class Store : public Shared::InteractiveCurveViewRange, public Shared::DoublePairStore {
public:
Store();
~Store();
@@ -64,12 +64,7 @@ public:
double correlationCoefficient(int series) const;
double squaredCorrelationCoefficient(int series) const;
private:
constexpr static float k_displayTopMarginRatio = 0.12f;
constexpr static float k_displayRightMarginRatio = 0.05f;
constexpr static float k_displayBottomMarginRatio = 0.5f;
constexpr static float k_displayLeftMarginRatio = 0.05f;
InteractiveCurveViewRangeDelegate::Range computeYRange(InteractiveCurveViewRange * interactiveCurveViewRange) override;
float addMargin(float x, float range, bool isMin) override;
constexpr static float k_displayHorizontalMarginRatio = 0.05f;
float maxValueOfColumn(int series, int i) const;
float minValueOfColumn(int series, int i) const;
uint32_t m_seriesChecksum[k_numberOfSeries];

View File

@@ -27,7 +27,9 @@ public:
// When the main view is selected, the banner view is visible
bool isMainViewSelected() const;
void selectMainView(bool mainViewSelected);
View * cursorView() { return m_cursorView; }
void setCursorView(View * cursorView);
View * bannerView() { return m_bannerView; }
void setBannerView(View * bannerView);
void setOkView(View * okView);
void setForceOkDisplay(bool force) { m_forceOkDisplay = force; }

View File

@@ -97,11 +97,6 @@ InteractiveCurveViewRangeDelegate::Range FunctionGraphController::computeYRange(
return range;
}
float FunctionGraphController::addMargin(float x, float range, bool isMin) {
float ratio = isMin ? -k_displayBottomMarginRatio : k_displayTopMarginRatio;
return x+ratio*range;
}
void FunctionGraphController::initRangeParameters() {
interactiveCurveViewRange()->setDefault();
initCursorParameters();

View File

@@ -11,12 +11,13 @@
namespace Shared {
class FunctionGraphController : public InteractiveCurveViewController, public InteractiveCurveViewRangeDelegate, public FunctionBannerDelegate {
class FunctionGraphController : public InteractiveCurveViewController, public FunctionBannerDelegate {
public:
FunctionGraphController(Responder * parentResponder, ButtonRowController * header, InteractiveCurveViewRange * interactiveRange, CurveView * curveView, CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Poincare::Expression::AngleUnit * angleUnitVersion);
bool isEmpty() const override;
ViewController * initialisationParameterController() override;
void viewWillAppear() override;
protected:
constexpr static float k_cursorTopMarginRatio = 0.068f; // (cursorHeight/2)/graphViewHeight
constexpr static float k_cursorBottomMarginRatio = 0.15f; // (cursorHeight/2+bannerHeigh)/graphViewHeight
@@ -33,8 +34,11 @@ private:
constexpr static float k_displayTopMarginRatio = 0.09f;
constexpr static float k_displayBottomMarginRatio = 0.2f;
// InteractiveCurveViewController
float displayTopMarginRatio() override { return k_displayTopMarginRatio; }
float displayBottomMarginRatio() override { return k_displayBottomMarginRatio; }
// InteractiveCurveViewRangeDelegate
InteractiveCurveViewRangeDelegate::Range computeYRange(InteractiveCurveViewRange * interactiveCurveViewRange) override;
float addMargin(float x, float range, bool isMin) override;
void initRangeParameters() override;
void initCursorParameters() override;

View File

@@ -32,6 +32,11 @@ InteractiveCurveViewController::InteractiveCurveViewController(Responder * paren
{
}
float InteractiveCurveViewController::addMargin(float x, float range, bool isMin) {
float ratio = isMin ? -displayBottomMarginRatio() : displayTopMarginRatio();
return x+ratio*range;
}
const char * InteractiveCurveViewController::title() {
return I18n::translate(I18n::Message::GraphTab);
}

View File

@@ -9,9 +9,15 @@
namespace Shared {
class InteractiveCurveViewController : public SimpleInteractiveCurveViewController, public ButtonRowDelegate, public AlternateEmptyViewDelegate {
class InteractiveCurveViewController : public SimpleInteractiveCurveViewController, public InteractiveCurveViewRangeDelegate, public ButtonRowDelegate, public AlternateEmptyViewDelegate {
public:
InteractiveCurveViewController(Responder * parentResponder, ButtonRowController * header, InteractiveCurveViewRange * interactiveRange, CurveView * curveView, CurveViewCursor * cursor, uint32_t * modelVersion, uint32_t * rangeVersion);
// InteractiveCurveViewRangeDelegate
float addMargin(float x, float range, bool isMin) override;
virtual float displayTopMarginRatio() = 0;
virtual float displayBottomMarginRatio() = 0;
const char * title() override;
bool handleEvent(Ion::Events::Event event) override;
void didBecomeFirstResponder() override;

View File

@@ -37,6 +37,7 @@ bool InteractiveCurveViewRangeDelegate::didChangeRange(InteractiveCurveViewRange
float step = min != 0.0f ? interactiveCurveViewRange->computeGridUnit(CurveViewRange::Axis::Y, 0.0f, std::fabs(min)) : 1.0f;
max = min+step;
}
range = max - min;
interactiveCurveViewRange->setYMin(addMargin(min, range, true));
interactiveCurveViewRange->setYMax(addMargin(max, range, false));
if (std::isinf(interactiveCurveViewRange->xMin())) {