mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
Compare commits
36 Commits
upsilon-de
...
upsilon-de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
352cf39602 | ||
|
|
eed6683c74 | ||
|
|
9d5904396d | ||
|
|
7dec23dd91 | ||
|
|
e5fb5f390e | ||
|
|
e3887ca077 | ||
|
|
46a30a6061 | ||
|
|
32ccd8530c | ||
|
|
6ff8b007be | ||
|
|
0834cbd054 | ||
|
|
a138ecaa9e | ||
|
|
f8e6ee64ef | ||
|
|
5fbc7feaa1 | ||
|
|
1a2a61a43c | ||
|
|
25766967e2 | ||
|
|
52ac8e2acb | ||
|
|
8cc09405e1 | ||
|
|
efdf2a379f | ||
|
|
26496fbf00 | ||
|
|
668641ce95 | ||
|
|
72dfb76cc8 | ||
|
|
0dafa539df | ||
|
|
36c984c73b | ||
|
|
fd5fba07e5 | ||
|
|
6e6ba6a985 | ||
|
|
57078755a3 | ||
|
|
710930d8e1 | ||
|
|
5c9bccdd99 | ||
|
|
6ffb70e513 | ||
|
|
b42d4197c9 | ||
|
|
17be5934e0 | ||
|
|
18e7926500 | ||
|
|
559d5d26dd | ||
|
|
89c08acc7f | ||
|
|
04cf7bb0bf | ||
|
|
73f2a7ecac |
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Upsilon is not working like it should? Let us know!
|
||||
about: Omega is not working like it should? Let us know!
|
||||
title: ''
|
||||
labels: 'Status: Triage, Type: Bug'
|
||||
assignees: ''
|
||||
@@ -24,4 +24,4 @@ A clear and concise description of what you expected to happen.
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- Upsilon Version: [go to settings > about > Upsilon Version and type the version here]
|
||||
- Omega Version: [go to settings > about > Omega Version and type the version here]
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for Upsilon
|
||||
about: Suggest an idea for Omega
|
||||
title: ''
|
||||
labels: 'Status: Triage, Type: Feature'
|
||||
assignees: ''
|
||||
|
||||
28
.github/ISSUE_TEMPLATE/omega-beta-only---bug-report.md
vendored
Normal file
28
.github/ISSUE_TEMPLATE/omega-beta-only---bug-report.md
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
name: OMEGA BETA ONLY - Bug report
|
||||
about: Omega 1.21 is not working like it should? Let us know!
|
||||
title: "[BETA-1.21] …"
|
||||
labels: 'Status: Triage, Type: Bug'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- Omega Version: [go to settings > about > Omega Version and type the version here]
|
||||
- Discord username: ..........#....
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Problems during installation
|
||||
about: Need help to install Upsilon?
|
||||
about: Need help to install Omega?
|
||||
title: ''
|
||||
labels: 'Status: Triage, Type: Installation issue'
|
||||
assignees: ''
|
||||
@@ -16,4 +16,4 @@ Copy/paste the logs here (If you have some)
|
||||
```
|
||||
|
||||
**Environment**
|
||||
- Upsilon Version: {go to settings > about > Upsilon Version and type the version here}
|
||||
- Omega Version: {go to settings > about > Omega Version and type the version here}
|
||||
|
||||
2
.github/workflows/ci-workflow.yml
vendored
2
.github/workflows/ci-workflow.yml
vendored
@@ -140,7 +140,7 @@ jobs:
|
||||
steps:
|
||||
- uses: numworks/setup-emscripten@v1
|
||||
with:
|
||||
sdk: 1.40.1-fastcomp
|
||||
sdk: latest-upstream
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
|
||||
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -1,6 +1,6 @@
|
||||
[submodule "apps/rpn"]
|
||||
path = apps/rpn
|
||||
url = https://github.com/Lauryy06/Upsilon-RPN.git
|
||||
url = https://github.com/Omega-Numworks/Omega-RPN.git
|
||||
[submodule "apps/atomic"]
|
||||
path = apps/atomic
|
||||
url = https://github.com/Lauryy06/atomic
|
||||
|
||||
@@ -126,7 +126,7 @@ Vous aurez besoin de devkitPro et de devkitARM disponible dans votre `$PATH` (in
|
||||
```bash
|
||||
git clone --recursive https://github.com/Lauryy06/Upsilon.git
|
||||
cd Upsilon
|
||||
git checkout --recursive upsilon-dev
|
||||
git checkout --recursive omega-dev
|
||||
make PLATFORM=simulator TARGET=3ds -j
|
||||
```
|
||||
|
||||
|
||||
@@ -240,7 +240,7 @@ You need devkitPro and devkitARM installed and in your path (instructions [here]
|
||||
```bash
|
||||
git clone --recursive https://github.com/Lauryy06/Upsilon.git
|
||||
cd Upsilon
|
||||
git checkout --recursive upsilon-dev
|
||||
git checkout --recursive omega-dev
|
||||
make PLATFORM=simulator TARGET=3ds -j
|
||||
```
|
||||
You can then put epsilon.3dsx on a SD card to run it from the HBC or use 3dslink to launch it over the network:
|
||||
|
||||
Submodule apps/atomic updated: 69f7a06ba5...64f2e38ed1
@@ -75,13 +75,13 @@ void BatteryView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
assert(!m_isPlugged);
|
||||
// Low: Quite empty battery
|
||||
ctx->fillRect(KDRect(batteryInsideX, 0, 2*k_elementWidth, k_batteryHeight), Palette::BatteryLow);
|
||||
ctx->fillRect(KDRect(3*k_elementWidth+k_separatorThickness, 0, k_batteryWidth-5*k_elementWidth-2*k_separatorThickness, k_batteryHeight), KDColor::blend(Palette::Toolbar, Palette::Battery, 128));
|
||||
ctx->fillRect(KDRect(3*k_elementWidth+k_separatorThickness, 0, k_batteryWidth-5*k_elementWidth-2*k_separatorThickness, k_batteryHeight), Palette::BatteryInCharge);
|
||||
} else if (m_chargeState == Ion::Battery::Charge::SOMEWHERE_INBETWEEN) {
|
||||
assert(!m_isPlugged);
|
||||
// Middle: Half full battery
|
||||
constexpr KDCoordinate middleChargeWidth = batteryInsideWidth/2;
|
||||
ctx->fillRect(KDRect(batteryInsideX, 0, middleChargeWidth, k_batteryHeight), Palette::Battery);
|
||||
ctx->fillRect(KDRect(batteryInsideX+middleChargeWidth, 0, middleChargeWidth, k_batteryHeight), KDColor::blend(Palette::Toolbar, Palette::Battery, 128));
|
||||
ctx->fillRect(KDRect(batteryInsideX+middleChargeWidth, 0, middleChargeWidth, k_batteryHeight), Palette::BatteryInCharge);
|
||||
} else {
|
||||
assert(m_chargeState == Ion::Battery::Charge::FULL);
|
||||
// Full but not plugged: Full battery
|
||||
|
||||
@@ -29,12 +29,6 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
|
||||
|
||||
Context * context = App::app()->localContext();
|
||||
Preferences * preferences = Preferences::sharedPreferences();
|
||||
Poincare::ExpressionNode::ReductionContext reductionContext = Poincare::ExpressionNode::ReductionContext(context,
|
||||
preferences->complexFormat(), preferences->angleUnit(),
|
||||
GlobalPreferences::sharedGlobalPreferences()->unitFormat(),
|
||||
ExpressionNode::ReductionTarget::SystemForApproximation,
|
||||
ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition,
|
||||
Poincare::ExpressionNode::UnitConversion::Default);
|
||||
|
||||
PoincareHelpers::Reduce(&m_expression, context, ExpressionNode::ReductionTarget::SystemForAnalysis);
|
||||
|
||||
@@ -52,108 +46,60 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
|
||||
Expression a = polynomialCoefficients[2];
|
||||
Expression b = polynomialCoefficients[1];
|
||||
Expression c = polynomialCoefficients[0];
|
||||
|
||||
|
||||
bool aIsNotOne = !(a.type() == ExpressionNode::Type::Rational && static_cast<const Rational &>(a).isOne());
|
||||
|
||||
Expression delta = Subtraction::Builder(Power::Builder(b.clone(), Rational::Builder(2)), Multiplication::Builder(Rational::Builder(4), a.clone(), c.clone()));
|
||||
PoincareHelpers::Simplify(&delta, context, ExpressionNode::ReductionTarget::SystemForApproximation);
|
||||
|
||||
// Alpha is -b/2a, but because after we use -α, we immediately store -α=-(-b/2a)=b/2a.
|
||||
Expression minusAlpha = Division::Builder(b.clone(), Multiplication::Builder(Rational::Builder(2), a.clone()));
|
||||
PoincareHelpers::Reduce(&minusAlpha, context, ExpressionNode::ReductionTarget::SystemForApproximation);
|
||||
Expression alpha = Opposite::Builder(Division::Builder(b.clone(), Multiplication::Builder(Rational::Builder(2), a.clone())));
|
||||
PoincareHelpers::Simplify(&alpha, context, ExpressionNode::ReductionTarget::User);
|
||||
|
||||
// Same thing for β
|
||||
Expression minusBeta = Division::Builder(delta.clone(), Multiplication::Builder(Rational::Builder(4), a.clone()));
|
||||
PoincareHelpers::Reduce(&minusBeta, context, ExpressionNode::ReductionTarget::SystemForApproximation);
|
||||
|
||||
enum MultiplicationTypeForA {
|
||||
Nothing,
|
||||
Minus,
|
||||
Parenthesis,
|
||||
Normal
|
||||
};
|
||||
|
||||
MultiplicationTypeForA multiplicationTypeForA;
|
||||
|
||||
if (a.type() == ExpressionNode::Type::Rational && static_cast<const Rational &>(a).isOne()) {
|
||||
multiplicationTypeForA = MultiplicationTypeForA::Nothing;
|
||||
}
|
||||
else if(a.type() == ExpressionNode::Type::Rational && static_cast<const Rational &>(a).isMinusOne()){
|
||||
multiplicationTypeForA = MultiplicationTypeForA::Minus;
|
||||
}
|
||||
else if (a.type() == ExpressionNode::Type::Addition) {
|
||||
multiplicationTypeForA = MultiplicationTypeForA::Parenthesis;
|
||||
}
|
||||
else {
|
||||
multiplicationTypeForA = MultiplicationTypeForA::Normal;
|
||||
}
|
||||
|
||||
PoincareHelpers::Simplify(&a, context, ExpressionNode::ReductionTarget::User);
|
||||
Expression beta = Opposite::Builder(Division::Builder(delta.clone(), Multiplication::Builder(Rational::Builder(4), a.clone())));
|
||||
PoincareHelpers::Simplify(&beta, context, ExpressionNode::ReductionTarget::User);
|
||||
|
||||
/*
|
||||
* Because when can't apply reduce or simplify to keep the
|
||||
* canonized form we must beautify the expression manually
|
||||
* Because when can't apply reduce or simplify to keep the canonised
|
||||
* we must beautify the expression manually
|
||||
*/
|
||||
|
||||
Expression xMinusAlphaPowerTwo;
|
||||
Expression alpha = getOppositeIfExists(minusAlpha, &reductionContext);
|
||||
|
||||
if (alpha.isUninitialized()) {
|
||||
PoincareHelpers::Simplify(&minusAlpha, context, ExpressionNode::ReductionTarget::User);
|
||||
xMinusAlphaPowerTwo = Power::Builder(Parenthesis::Builder(Addition::Builder(Symbol::Builder("x", strlen("x")), minusAlpha)), Rational::Builder(2));
|
||||
Expression canonised;
|
||||
if (alpha.type() == ExpressionNode::Type::Opposite) {
|
||||
canonised = Addition::Builder(Symbol::Builder("x", strlen("x")), alpha.childAtIndex(0).clone());
|
||||
}
|
||||
else {
|
||||
PoincareHelpers::Simplify(&alpha, context, ExpressionNode::ReductionTarget::User);
|
||||
xMinusAlphaPowerTwo = Power::Builder(Parenthesis::Builder(Subtraction::Builder(Symbol::Builder("x", strlen("x")), alpha)), Rational::Builder(2));
|
||||
canonised = Subtraction::Builder(Symbol::Builder("x", strlen("x")), alpha.clone());
|
||||
}
|
||||
|
||||
Expression xMinusAlphaPowerTwoWithFactor;
|
||||
|
||||
switch (multiplicationTypeForA)
|
||||
{
|
||||
case MultiplicationTypeForA::Nothing:
|
||||
xMinusAlphaPowerTwoWithFactor = xMinusAlphaPowerTwo;
|
||||
break;
|
||||
case MultiplicationTypeForA::Minus:
|
||||
xMinusAlphaPowerTwoWithFactor = Multiplication::Builder(a.clone(), xMinusAlphaPowerTwo);
|
||||
break;
|
||||
case MultiplicationTypeForA::Parenthesis:
|
||||
xMinusAlphaPowerTwoWithFactor = Multiplication::Builder(Parenthesis::Builder(a.clone()), xMinusAlphaPowerTwo);
|
||||
break;
|
||||
case MultiplicationTypeForA::Normal:
|
||||
xMinusAlphaPowerTwoWithFactor = Multiplication::Builder(a.clone(), xMinusAlphaPowerTwo);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
canonised = Power::Builder(Parenthesis::Builder(canonised.clone()), Rational::Builder(2));
|
||||
if (aIsNotOne) {
|
||||
canonised = Multiplication::Builder(a.clone(), canonised.clone());
|
||||
}
|
||||
|
||||
Expression canonized;
|
||||
Expression beta = getOppositeIfExists(minusBeta, &reductionContext);
|
||||
if (beta.isUninitialized()) {
|
||||
PoincareHelpers::Simplify(&minusBeta, context, ExpressionNode::ReductionTarget::User);
|
||||
canonized = Subtraction::Builder(xMinusAlphaPowerTwoWithFactor, minusBeta);
|
||||
if (beta.type() == ExpressionNode::Type::Opposite) {
|
||||
canonised = Subtraction::Builder(canonised.clone(), beta.childAtIndex(0).clone());
|
||||
}
|
||||
else {
|
||||
PoincareHelpers::Simplify(&beta, context, ExpressionNode::ReductionTarget::User);
|
||||
canonized = Addition::Builder(xMinusAlphaPowerTwoWithFactor, beta);
|
||||
canonised = Addition::Builder(canonised.clone(), beta.clone());
|
||||
}
|
||||
|
||||
|
||||
Expression x0;
|
||||
Expression x1;
|
||||
|
||||
|
||||
if (delta.nullStatus(context) == ExpressionNode::NullStatus::Null) {
|
||||
// x0 = x1 = -b/(2a)
|
||||
x0 = Division::Builder(Opposite::Builder(b.clone()), Multiplication::Builder(Rational::Builder(2), a.clone()));
|
||||
x0 = Division::Builder(Opposite::Builder(b), Multiplication::Builder(Rational::Builder(2), a));
|
||||
m_numberOfSolutions = 1;
|
||||
PoincareHelpers::Simplify(&x0, context, ExpressionNode::ReductionTarget::SystemForApproximation);
|
||||
PoincareHelpers::Simplify(&x0, context, ExpressionNode::ReductionTarget::User);
|
||||
}
|
||||
else {
|
||||
// x0 = (-b-sqrt(delta))/(2a)
|
||||
x0 = Division::Builder(Subtraction::Builder(Opposite::Builder(b.clone()), SquareRoot::Builder(delta.clone())), Multiplication::Builder(Rational::Builder(2), a.clone()));
|
||||
// x1 = (-b+sqrt(delta))/(2a)
|
||||
x1 = Division::Builder(Addition::Builder(Opposite::Builder(b.clone()), SquareRoot::Builder(delta.clone())), Multiplication::Builder(Rational::Builder(2), a.clone()));
|
||||
x1 = Division::Builder(Addition::Builder(Opposite::Builder(b), SquareRoot::Builder(delta.clone())), Multiplication::Builder(Rational::Builder(2), a));
|
||||
m_numberOfSolutions = 2;
|
||||
PoincareHelpers::Simplify(&x0, context, ExpressionNode::ReductionTarget::SystemForApproximation);
|
||||
PoincareHelpers::Simplify(&x1, context, ExpressionNode::ReductionTarget::SystemForApproximation);
|
||||
PoincareHelpers::Simplify(&x0, context, ExpressionNode::ReductionTarget::User);
|
||||
PoincareHelpers::Simplify(&x1, context, ExpressionNode::ReductionTarget::User);
|
||||
if (x0.type() == ExpressionNode::Type::Unreal) {
|
||||
assert(x1.type() == ExpressionNode::Type::Unreal);
|
||||
m_numberOfSolutions = 0;
|
||||
@@ -163,87 +109,40 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
|
||||
Expression factorized;
|
||||
|
||||
if (m_numberOfSolutions == 2) {
|
||||
Expression firstFactor;
|
||||
Expression secondFactor;
|
||||
|
||||
Expression x0Opposite = getOppositeIfExists(x0, &reductionContext);
|
||||
if (x0Opposite.isUninitialized()) {
|
||||
PoincareHelpers::Simplify(&x0, context, ExpressionNode::ReductionTarget::User);
|
||||
firstFactor = Subtraction::Builder(Symbol::Builder("x", strlen("x")), x0);
|
||||
}
|
||||
else {
|
||||
PoincareHelpers::Simplify(&x0Opposite, context, ExpressionNode::ReductionTarget::User);
|
||||
firstFactor = Addition::Builder(Symbol::Builder("x", strlen("x")), x0Opposite);
|
||||
}
|
||||
if (x0.type() == ExpressionNode::Type::Opposite) {
|
||||
factorized = Parenthesis::Builder(Addition::Builder(Symbol::Builder("x", strlen("x")), x0.childAtIndex(0).clone()));
|
||||
}
|
||||
|
||||
Expression x1Opposite = getOppositeIfExists(x1, &reductionContext);
|
||||
if (x1Opposite.isUninitialized()) {
|
||||
PoincareHelpers::Simplify(&x1, context, ExpressionNode::ReductionTarget::User);
|
||||
secondFactor = Subtraction::Builder(Symbol::Builder("x", strlen("x")), x1);
|
||||
else {
|
||||
factorized = Parenthesis::Builder(Subtraction::Builder(Symbol::Builder("x", strlen("x")), x0.clone()));
|
||||
}
|
||||
|
||||
if (x1.type() == ExpressionNode::Type::Opposite) {
|
||||
factorized = Multiplication::Builder(factorized.clone(), Parenthesis::Builder(Addition::Builder(Symbol::Builder("x", strlen("x")), x1.childAtIndex(0).clone())));
|
||||
}
|
||||
else {
|
||||
PoincareHelpers::Simplify(&x1Opposite, context, ExpressionNode::ReductionTarget::User);
|
||||
secondFactor = Addition::Builder(Symbol::Builder("x", strlen("x")), x1Opposite);
|
||||
factorized = Multiplication::Builder(factorized.clone(), Parenthesis::Builder(Subtraction::Builder(Symbol::Builder("x", strlen("x")), x1.clone())));
|
||||
}
|
||||
|
||||
Expression solutionProduct = Multiplication::Builder(Parenthesis::Builder(firstFactor), Parenthesis::Builder(secondFactor));
|
||||
switch (multiplicationTypeForA)
|
||||
{
|
||||
case MultiplicationTypeForA::Nothing:
|
||||
factorized = solutionProduct;
|
||||
break;
|
||||
case MultiplicationTypeForA::Minus:
|
||||
factorized = Multiplication::Builder(a.clone(), solutionProduct);
|
||||
break;
|
||||
case MultiplicationTypeForA::Parenthesis:
|
||||
factorized = Multiplication::Builder(Parenthesis::Builder(a.clone()), solutionProduct);
|
||||
break;
|
||||
case MultiplicationTypeForA::Normal:
|
||||
factorized = Multiplication::Builder(a.clone(), solutionProduct);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
if (aIsNotOne) {
|
||||
factorized = Multiplication::Builder(a.clone(), factorized.clone());
|
||||
}
|
||||
}
|
||||
else if (m_numberOfSolutions == 1) {
|
||||
Expression x0Opposite = getOppositeIfExists(x0, &reductionContext);
|
||||
Expression factor;
|
||||
if (x0Opposite.isUninitialized()) {
|
||||
PoincareHelpers::Simplify(&x0, context, ExpressionNode::ReductionTarget::User);
|
||||
factor = Subtraction::Builder(Symbol::Builder("x", strlen("x")), x0);
|
||||
if (x0.type() == ExpressionNode::Type::Opposite) {
|
||||
factorized = Power::Builder(Parenthesis::Builder(Addition::Builder(Symbol::Builder("x", strlen("x")), x0.childAtIndex(0).clone())), Rational::Builder(2));
|
||||
}
|
||||
else {
|
||||
PoincareHelpers::Simplify(&x0Opposite, context, ExpressionNode::ReductionTarget::User);
|
||||
factor = Addition::Builder(Symbol::Builder("x", strlen("x")), x0Opposite);
|
||||
factorized = Power::Builder(Parenthesis::Builder(Subtraction::Builder(Symbol::Builder("x", strlen("x")), x0.clone())), Rational::Builder(2));
|
||||
}
|
||||
Expression solutionProduct = Power::Builder(Parenthesis::Builder(factor), Rational::Builder(2));
|
||||
switch (multiplicationTypeForA)
|
||||
{
|
||||
case MultiplicationTypeForA::Nothing:
|
||||
factorized = solutionProduct;
|
||||
break;
|
||||
case MultiplicationTypeForA::Minus:
|
||||
factorized = Multiplication::Builder(a.clone(), solutionProduct);
|
||||
break;
|
||||
case MultiplicationTypeForA::Parenthesis:
|
||||
factorized = Multiplication::Builder(Parenthesis::Builder(a.clone()), solutionProduct);
|
||||
break;
|
||||
case MultiplicationTypeForA::Normal:
|
||||
factorized = Multiplication::Builder(a.clone(), solutionProduct);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
|
||||
if (aIsNotOne) {
|
||||
factorized = Multiplication::Builder(a.clone(), factorized.clone());
|
||||
}
|
||||
}
|
||||
|
||||
PoincareHelpers::Simplify(&delta, context, ExpressionNode::ReductionTarget::User);
|
||||
|
||||
m_layouts[0] = PoincareHelpers::CreateLayout(canonized);
|
||||
m_layouts[0] = PoincareHelpers::CreateLayout(canonised);
|
||||
if (m_numberOfSolutions > 0) {
|
||||
m_layouts[1] = PoincareHelpers::CreateLayout(factorized);
|
||||
m_layouts[2] = PoincareHelpers::CreateLayout(delta);
|
||||
@@ -257,27 +156,6 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
|
||||
}
|
||||
}
|
||||
|
||||
Expression SecondDegreeListController::getOppositeIfExists(Expression e, Poincare::ExpressionNode::ReductionContext * reductionContext) {
|
||||
if (e.isNumber() && e.sign(reductionContext->context()) == ExpressionNode::Sign::Negative) {
|
||||
Number n = static_cast<Number&>(e);
|
||||
return std::move(n.setSign(ExpressionNode::Sign::Positive));
|
||||
}
|
||||
else if (e.type() == ExpressionNode::Type::Multiplication && e.numberOfChildren() > 0 && e.childAtIndex(0).isNumber() && e.childAtIndex(0).sign(reductionContext->context()) == ExpressionNode::Sign::Negative) {
|
||||
Multiplication m = static_cast<Multiplication&>(e);
|
||||
if (m.childAtIndex(0).type() == ExpressionNode::Type::Rational && static_cast<Rational&>(e).isMinusOne()) {
|
||||
// The negative numeral factor is -1, we just remove it
|
||||
m.removeChildAtIndexInPlace(0);
|
||||
} else {
|
||||
Expression firstChild = m.childAtIndex(0);
|
||||
Number n = static_cast<Number&>(firstChild);
|
||||
m.childAtIndex(0).setChildrenInPlace(n.setSign(ExpressionNode::Sign::Positive));
|
||||
}
|
||||
PoincareHelpers::Simplify(&m, reductionContext->context(), ExpressionNode::ReductionTarget::User);
|
||||
return std::move(m);
|
||||
}
|
||||
return Expression();
|
||||
}
|
||||
|
||||
I18n::Message SecondDegreeListController::messageAtIndex(int index) {
|
||||
if (m_numberOfSolutions > 0) {
|
||||
if (index == 0) {
|
||||
|
||||
@@ -14,7 +14,6 @@ public:
|
||||
void setExpression(Poincare::Expression e) override;
|
||||
|
||||
private:
|
||||
Poincare::Expression getOppositeIfExists(Poincare::Expression e, Poincare::ExpressionNode::ReductionContext * reductionContext);
|
||||
I18n::Message messageAtIndex(int index) override;
|
||||
int m_numberOfSolutions;
|
||||
};
|
||||
|
||||
@@ -81,7 +81,7 @@ void HistoryViewCell::reloadSubviewHighlight() {
|
||||
m_ellipsis.setHighlighted(false);
|
||||
if (isHighlighted()) {
|
||||
if (m_dataSource->selectedSubviewType() == HistoryViewCellDataSource::SubviewType::Input) {
|
||||
m_inputView.setExpressionBackgroundColor(Palette::Select);
|
||||
m_inputView.setExpressionBackgroundColor(Palette::ListCellBackgroundSelected);
|
||||
} else if (m_dataSource->selectedSubviewType() == HistoryViewCellDataSource::SubviewType::Output) {
|
||||
m_scrollableOutputView.evenOddCell()->setHighlighted(true);
|
||||
} else {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
apps += Code::App
|
||||
app_headers += apps/code/app.h
|
||||
|
||||
SFLAGS += -DHAS_CODE
|
||||
|
||||
app_code_src = $(addprefix apps/code/,\
|
||||
app.cpp \
|
||||
console_controller.cpp \
|
||||
|
||||
@@ -102,7 +102,7 @@ void EditorView::GutterView::setOffset(KDCoordinate offset) {
|
||||
|
||||
KDSize EditorView::GutterView::minimalSizeForOptimalDisplay() const {
|
||||
int numberOfChars = 2; // TODO: Could be computed
|
||||
return KDSize(2 * k_margin + numberOfChars * m_font->glyphSize().width(), 0);
|
||||
return KDSize(2 * k_margin + numberOfChars * Poincare::Preferences::sharedPreferences()->KDPythonFont()->glyphSize().width(), 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,10 +21,10 @@ void ScriptNodeCell::ScriptNodeView::drawRect(KDContext * ctx, KDRect rect) cons
|
||||
const int nodeNameLength = m_scriptNode->nameLength();
|
||||
KDSize nameSize = k_font->stringSize(nodeName, nodeNameLength);
|
||||
const KDCoordinate nodeNameY = k_topMargin;
|
||||
ctx->drawString(nodeName, KDPoint(0, nodeNameY), k_font, Palette::PrimaryText, backgroundColor, nodeNameLength);
|
||||
ctx->drawString(nodeName, KDPoint(0, nodeNameY), k_font, KDColorBlack, backgroundColor, nodeNameLength);
|
||||
// If it is needed, draw the parentheses
|
||||
if (m_scriptNode->type() == ScriptNode::Type::WithParentheses) {
|
||||
ctx->drawString(ScriptNodeCell::k_parentheses, KDPoint(nameSize.width(), nodeNameY), k_font, Palette::PrimaryText, backgroundColor);
|
||||
ctx->drawString(ScriptNodeCell::k_parentheses, KDPoint(nameSize.width(), nodeNameY), k_font, KDColorBlack, backgroundColor);
|
||||
}
|
||||
|
||||
/* If it exists, draw the source name. If it did not fit, we would have put
|
||||
|
||||
@@ -8,9 +8,11 @@ bool ScriptStore::ScriptNameIsFree(const char * baseName) {
|
||||
return ScriptBaseNamed(baseName).isNull();
|
||||
}
|
||||
|
||||
// Here we add "base" script
|
||||
ScriptStore::ScriptStore() {
|
||||
|
||||
addScriptFromTemplate(ScriptTemplate::Squares());
|
||||
addScriptFromTemplate(ScriptTemplate::Parabola());
|
||||
addScriptFromTemplate(ScriptTemplate::Mandelbrot());
|
||||
addScriptFromTemplate(ScriptTemplate::Polynomial());
|
||||
}
|
||||
|
||||
void ScriptStore::deleteAllScripts() {
|
||||
|
||||
@@ -5,9 +5,103 @@ namespace Code {
|
||||
constexpr ScriptTemplate emptyScriptTemplate(".py", "\x01" R"(from math import *
|
||||
)");
|
||||
|
||||
constexpr ScriptTemplate squaresScriptTemplate("squares.py", "\x01" R"(from math import *
|
||||
from turtle import *
|
||||
def squares(angle=0.5):
|
||||
reset()
|
||||
L=330
|
||||
speed(10)
|
||||
penup()
|
||||
goto(-L/2,-L/2)
|
||||
pendown()
|
||||
for i in range(660):
|
||||
forward(L)
|
||||
left(90+angle)
|
||||
L=L-L*sin(angle*pi/180)
|
||||
hideturtle())");
|
||||
|
||||
constexpr ScriptTemplate mandelbrotScriptTemplate("mandelbrot.py", "\x01" R"(# This script draws a Mandelbrot fractal set
|
||||
# N_iteration: degree of precision
|
||||
import kandinsky
|
||||
def mandelbrot(N_iteration):
|
||||
for x in range(320):
|
||||
for y in range(222):
|
||||
# Compute the mandelbrot sequence for the point c = (c_r, c_i) with start value z = (z_r, z_i)
|
||||
z = complex(0,0)
|
||||
# Rescale to fit the drawing screen 320x222
|
||||
c = complex(3.5*x/319-2.5, -2.5*y/221+1.25)
|
||||
i = 0
|
||||
while (i < N_iteration) and abs(z) < 2:
|
||||
i = i + 1
|
||||
z = z*z+c
|
||||
# Choose the color of the dot from the Mandelbrot sequence
|
||||
rgb = int(255*i/N_iteration)
|
||||
col = kandinsky.color(int(rgb*0.82),int(rgb*0.13),int(rgb*0.18))
|
||||
# Draw a pixel colored in 'col' at position (x,y)
|
||||
kandinsky.set_pixel(x,y,col))");
|
||||
|
||||
constexpr ScriptTemplate polynomialScriptTemplate("polynomial.py", "\x01" R"(from math import *
|
||||
# roots(a,b,c) computes the solutions of the equation a*x**2+b*x+c=0
|
||||
def roots(a,b,c):
|
||||
delta = b*b-4*a*c
|
||||
if delta == 0:
|
||||
return -b/(2*a)
|
||||
elif delta > 0:
|
||||
x_1 = (-b-sqrt(delta))/(2*a)
|
||||
x_2 = (-b+sqrt(delta))/(2*a)
|
||||
return x_1, x_2
|
||||
else:
|
||||
return None)");
|
||||
|
||||
constexpr ScriptTemplate parabolaScriptTemplate("parabola.py", "\x01" R"(from matplotlib.pyplot import *
|
||||
from math import *
|
||||
|
||||
g=9.81
|
||||
|
||||
def x(t,v_0,alpha):
|
||||
return v_0*cos(alpha)*t
|
||||
def y(t,v_0,alpha,h_0):
|
||||
return -0.5*g*t**2+v_0*sin(alpha)*t+h_0
|
||||
|
||||
def vx(v_0,alpha):
|
||||
return v_0*cos(alpha)
|
||||
def vy(t,v_0,alpha):
|
||||
return -g*t+v_0*sin(alpha)
|
||||
|
||||
def t_max(v_0,alpha,h_0):
|
||||
return (v_0*sin(alpha)+sqrt((v_0**2)*(sin(alpha)**2)+2*g*h_0))/g
|
||||
|
||||
def simulation(v_0=15,alpha=pi/4,h_0=2):
|
||||
tMax=t_max(v_0,alpha,h_0)
|
||||
accuracy=1/10**(floor(log10(tMax))-1)
|
||||
T_MAX=floor(tMax*accuracy)+1
|
||||
X=[x(t/accuracy,v_0,alpha) for t in range(T_MAX)]
|
||||
Y=[y(t/accuracy,v_0,alpha,h_0) for t in range(T_MAX)]
|
||||
VX=[vx(v_0,alpha) for t in range(T_MAX)]
|
||||
VY=[vy(t/accuracy,v_0,alpha) for t in range(T_MAX)]
|
||||
for i in range(T_MAX):
|
||||
arrow(X[i],Y[i],VX[i]/accuracy,VY[i]/accuracy)
|
||||
grid()
|
||||
show())");
|
||||
|
||||
const ScriptTemplate * ScriptTemplate::Empty() {
|
||||
return &emptyScriptTemplate;
|
||||
}
|
||||
|
||||
const ScriptTemplate * ScriptTemplate::Squares() {
|
||||
return &squaresScriptTemplate;
|
||||
}
|
||||
|
||||
const ScriptTemplate * ScriptTemplate::Mandelbrot() {
|
||||
return &mandelbrotScriptTemplate;
|
||||
}
|
||||
|
||||
const ScriptTemplate * ScriptTemplate::Polynomial() {
|
||||
return &polynomialScriptTemplate;
|
||||
}
|
||||
|
||||
const ScriptTemplate * ScriptTemplate::Parabola() {
|
||||
return ¶bolaScriptTemplate;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,10 @@ class ScriptTemplate {
|
||||
public:
|
||||
constexpr ScriptTemplate(const char * name, const char * value) : m_name(name), m_value(value) {}
|
||||
static const ScriptTemplate * Empty();
|
||||
static const ScriptTemplate * Squares();
|
||||
static const ScriptTemplate * Mandelbrot();
|
||||
static const ScriptTemplate * Polynomial();
|
||||
static const ScriptTemplate * Parabola();
|
||||
const char * name() const { return m_name; }
|
||||
const char * content() const { return m_value + Script::StatusSize(); }
|
||||
const char * value() const { return m_value; }
|
||||
|
||||
@@ -37,10 +37,10 @@ namespace Code {
|
||||
}
|
||||
|
||||
void toolboxIonKeys::toolboxIonView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
ctx->fillRect(rect, Palette::WallScreen);
|
||||
ctx->strokeRect(rect, Palette::ListCellBorder);
|
||||
ctx->drawString(I18n::translate(I18n::Message::PressAKey),KDPoint(rect.left()+80, rect.top()+20),KDFont::LargeFont,Palette::PrimaryText,Palette::WallScreen);
|
||||
|
||||
ctx->fillRect(rect, Palette::GrayBright);
|
||||
ctx->strokeRect(rect, Palette::GrayDark);
|
||||
ctx->drawString(I18n::translate(I18n::Message::PressAKey),KDPoint(rect.left()+80, rect.top()+20));
|
||||
|
||||
}
|
||||
|
||||
View * toolboxIonKeys::view(){
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
apps += Geometry::App
|
||||
app_headers += apps/geometry/app.h
|
||||
|
||||
app_geometry_src = $(addprefix apps/geometry/,\
|
||||
app.cpp \
|
||||
list/figures_controller.cpp \
|
||||
list/definition_type_controller.cpp \
|
||||
list/figure_type_controller.cpp \
|
||||
list/figure_parameters_controller.cpp \
|
||||
list/objects_controller.cpp \
|
||||
list/message_table_cell_with_selector.cpp \
|
||||
figure_store.cpp \
|
||||
graph/graph_controller.cpp \
|
||||
graph/banner_view.cpp \
|
||||
)
|
||||
|
||||
apps_src += $(app_geometry_src)
|
||||
|
||||
app_images += apps/geometry/geometry_icon.png
|
||||
|
||||
i18n_files += $(call i18n_with_universal_for,geometry/base)
|
||||
|
||||
$(eval $(call depends_on_image,apps/geometry/app.cpp,apps/geometry/geometry_icon.png))
|
||||
@@ -1,48 +0,0 @@
|
||||
#include "app.h"
|
||||
#include "geometry_icon.h"
|
||||
#include "apps/apps_container.h"
|
||||
#include "apps/i18n.h"
|
||||
|
||||
namespace Geometry
|
||||
{
|
||||
|
||||
I18n::Message App::Descriptor::name()
|
||||
{
|
||||
return I18n::Message::GeometryApp;
|
||||
}
|
||||
|
||||
I18n::Message App::Descriptor::upperName()
|
||||
{
|
||||
return I18n::Message::GeometryAppCapital;
|
||||
}
|
||||
|
||||
const Image * App::Descriptor::icon()
|
||||
{
|
||||
return ImageStore::GeometryIcon;
|
||||
}
|
||||
|
||||
App * App::Snapshot::unpack(Container * container)
|
||||
{
|
||||
return new (container->currentAppBuffer()) App(this);
|
||||
}
|
||||
|
||||
App::Descriptor * App::Snapshot::descriptor()
|
||||
{
|
||||
static Descriptor descriptor;
|
||||
return &descriptor;
|
||||
}
|
||||
|
||||
App::App(Snapshot * snapshot) :
|
||||
TextFieldDelegateApp(snapshot, &m_tabViewController),
|
||||
m_figuresController(&m_stackViewController),
|
||||
m_stackViewController(&m_tabViewController, &m_figuresController),
|
||||
m_graphController(&m_graphAlternateEmptyViewController, this, &m_graphHeader, nullptr, nullptr, nullptr),
|
||||
m_graphAlternateEmptyViewController(&m_graphHeader, &m_graphController, &m_graphController),
|
||||
m_graphHeader(&m_graphStackViewController, &m_graphAlternateEmptyViewController, &m_graphController),
|
||||
m_graphStackViewController(&m_tabViewController, &m_graphHeader),
|
||||
m_otherViewController(&m_tabViewController),
|
||||
m_tabViewController(&m_modalViewController, snapshot, &m_stackViewController, &m_graphAlternateEmptyViewController, &m_otherViewController)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
#ifndef GEOMETRY_H
|
||||
#define GEOMETRY_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "list/figures_controller.h"
|
||||
#include "graph/graph_controller.h"
|
||||
#include "other/other_view_controller.h"
|
||||
#include "../shared/text_field_delegate_app.h"
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
class App : public Shared::TextFieldDelegateApp {
|
||||
public:
|
||||
class Descriptor : public ::App::Descriptor {
|
||||
public:
|
||||
I18n::Message name() override;
|
||||
I18n::Message upperName() override;
|
||||
const Image * icon() override;
|
||||
};
|
||||
class Snapshot : public ::App::Snapshot, public TabViewDataSource {
|
||||
public:
|
||||
App * unpack(Container * container) override;
|
||||
Descriptor * descriptor() override;
|
||||
};
|
||||
private:
|
||||
App(Snapshot * snapshot);
|
||||
|
||||
FiguresController m_figuresController;
|
||||
StackViewController m_stackViewController;
|
||||
GraphController m_graphController;
|
||||
AlternateEmptyViewController m_graphAlternateEmptyViewController;
|
||||
StackViewController m_graphStackViewController;
|
||||
ButtonRowController m_graphHeader;
|
||||
OtherViewController m_otherViewController;
|
||||
TabViewController m_tabViewController;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +0,0 @@
|
||||
GeometryApp = "Geometry"
|
||||
GeometryAppCapital = "GEOMETRY"
|
||||
AddFigure = "Ajouter une figure"
|
||||
FigureType = "Type de figure"
|
||||
DefinitionType = "Définition de la figure"
|
||||
ParametersChoice = "Choix des paramètres"
|
||||
@@ -1,6 +0,0 @@
|
||||
GeometryApp = "Geometry"
|
||||
GeometryAppCapital = "GEOMETRY"
|
||||
AddFigure = "Ajouter une figure"
|
||||
FigureType = "Type de figure"
|
||||
DefinitionType = "Définition de la figure"
|
||||
ParametersChoice = "Choix des paramètres"
|
||||
@@ -1,6 +0,0 @@
|
||||
GeometryApp = "Geometry"
|
||||
GeometryAppCapital = "GEOMETRY"
|
||||
AddFigure = "Ajouter une figure"
|
||||
FigureType = "Type de figure"
|
||||
DefinitionType = "Définition de la figure"
|
||||
ParametersChoice = "Choix des paramètres"
|
||||
@@ -1,6 +0,0 @@
|
||||
GeometryApp = "Geometry"
|
||||
GeometryAppCapital = "GEOMETRY"
|
||||
AddFigure = "Ajouter une figure"
|
||||
FigureType = "Type de figure"
|
||||
DefinitionType = "Définition de la figure"
|
||||
ParametersChoice = "Choix des paramètres"
|
||||
@@ -1,6 +0,0 @@
|
||||
GeometryApp = "Geometry"
|
||||
GeometryAppCapital = "GEOMETRY"
|
||||
AddFigure = "Ajouter une figure"
|
||||
FigureType = "Type de figure"
|
||||
DefinitionType = "Définition de la figure"
|
||||
ParametersChoice = "Choix des paramètres"
|
||||
@@ -1,6 +0,0 @@
|
||||
GeometryApp = "Geometry"
|
||||
GeometryAppCapital = "GEOMETRY"
|
||||
AddFigure = "Ajouter une figure"
|
||||
FigureType = "Type de figure"
|
||||
DefinitionType = "Définition de la figure"
|
||||
ParametersChoice = "Choix des paramètres"
|
||||
@@ -1,6 +0,0 @@
|
||||
GeometryApp = "Geometry"
|
||||
GeometryAppCapital = "GEOMETRY"
|
||||
AddFigure = "Ajouter une figure"
|
||||
FigureType = "Type de figure"
|
||||
DefinitionType = "Définition de la figure"
|
||||
ParametersChoice = "Choix des paramètres"
|
||||
@@ -1,6 +0,0 @@
|
||||
GeometryApp = "Geometry"
|
||||
GeometryAppCapital = "GEOMETRY"
|
||||
AddFigure = "Ajouter une figure"
|
||||
FigureType = "Type de figure"
|
||||
DefinitionType = "Définition de la figure"
|
||||
ParametersChoice = "Choix des paramètres"
|
||||
@@ -1,24 +0,0 @@
|
||||
FiguresTab = "Figures"
|
||||
NoFigures = "Aucune figure à afficher"
|
||||
OtherTab = "TODO"
|
||||
Coordinates = "Coordonnées"
|
||||
Middle = "Milieu"
|
||||
VectorProject = "Projeté vectoriel"
|
||||
OrthogonalProject = "Projeté orthogonal"
|
||||
CartesianEquation = "Equation cartésienne"
|
||||
LinearEquation = "Equation linéaire"
|
||||
Points = "Points"
|
||||
PointAndVector = "Point et vecteur"
|
||||
Parallele = "Parallèle"
|
||||
Perpendicular = "Perpendiculaire"
|
||||
PointAndRadius = "Point et rayon"
|
||||
Diameter = "Diamètre"
|
||||
TwoPoints = "Deux points"
|
||||
Segment = "Segment"
|
||||
Angle = "Angle"
|
||||
Area = "Surface"
|
||||
Point = "Point"
|
||||
Line = "Droite"
|
||||
Circle = "Cercle"
|
||||
Vector = "Vecteur"
|
||||
Indicator = "Indicateur"
|
||||
@@ -1 +0,0 @@
|
||||
#include "figure_store.h"
|
||||
@@ -1,14 +0,0 @@
|
||||
#ifndef FIGURE__STORE__H
|
||||
#define FIGURE__STORE__H
|
||||
|
||||
#include "../shared/expression_model_store.h"
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
class FigureStore: Shared::ExpressionModelStore {
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,27 +0,0 @@
|
||||
#ifndef POINCARE_FIGURE_H
|
||||
#define POINCARE_FIGURE_H
|
||||
|
||||
#include "figure_type.h"
|
||||
|
||||
using namespace Poincare;
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
class FigureNode : public TreeNode {
|
||||
public:
|
||||
virtual size_t size() const override = 0;
|
||||
|
||||
virtual int numberOfChildren() const override { return 0; }
|
||||
|
||||
virtual FigureType type() const = 0;
|
||||
virtual FigureDefinitionType definitionType() const = 0;
|
||||
};
|
||||
|
||||
class Figure : public TreeHandle {
|
||||
public:
|
||||
Figure(const FigureNode * node) : TreeHandle(node) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,24 +0,0 @@
|
||||
#ifndef GEOMETRY_FIGURE_TYPE_H
|
||||
#define GEOMETRY_FIGURE_TYPE_H
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
enum class FigureType {
|
||||
None = 0, // Used to trigger assert in debug mode
|
||||
Expression, // It's not a real figure type but we use it to build figures like points
|
||||
|
||||
Point,
|
||||
|
||||
Line,
|
||||
Circle,
|
||||
Vector,
|
||||
Indicator
|
||||
};
|
||||
|
||||
enum class FigureDefinitionType {
|
||||
PointByCoordinates
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +0,0 @@
|
||||
#ifndef FIGURES_H
|
||||
#define FIGURES_H
|
||||
|
||||
#include "point_by_coordinates.h"
|
||||
|
||||
#endif
|
||||
@@ -1 +0,0 @@
|
||||
#include "point.h"
|
||||
@@ -1,18 +0,0 @@
|
||||
#ifndef GEOMETRY_POINT_H
|
||||
#define GEOMETRY_POINT_H
|
||||
|
||||
#include "figure.h"
|
||||
namespace Geometry {
|
||||
|
||||
class PointNode : public FigureNode {
|
||||
virtual FigureType type() const override { return FigureType::Point; }
|
||||
};
|
||||
|
||||
class Point : public Figure {
|
||||
public:
|
||||
Point(const PointNode * n) : Figure(n) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,31 +0,0 @@
|
||||
#ifndef POINT_BY_COORDINATES_H
|
||||
#define POINT_BY_COORDINATES_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include "point.h"
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
class PointByCoordinatesNode : public PointNode {
|
||||
public:
|
||||
virtual size_t size() const override { return sizeof(PointByCoordinatesNode); }
|
||||
virtual int numberOfChildren() const override { return 2; }
|
||||
virtual FigureDefinitionType definitionType() const override { return FigureDefinitionType::PointByCoordinates; }
|
||||
#if POINCARE_TREE_LOG
|
||||
void logNodeName(std::ostream & stream) const override {
|
||||
stream << "PointByCoordinates";
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class PointByCoordinates : public Figure {
|
||||
public:
|
||||
PointByCoordinates(const PointByCoordinatesNode * n) : Figure(n) {}
|
||||
static PointByCoordinates Builder(Expression x, Expression y) { return TreeHandle::FixedArityBuilder<PointByCoordinates, PointByCoordinatesNode>({x, x}); }
|
||||
static int numberOfParameters() { return 2; }
|
||||
static FigureType parameterTypeAtIndex(int i) { return FigureType::Expression; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -1,15 +0,0 @@
|
||||
#include "banner_view.h"
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
BannerView::BannerView(
|
||||
Responder * parentResponder,
|
||||
InputEventHandlerDelegate * inputEventHandlerDelegate,
|
||||
TextFieldDelegate * textFieldDelegate
|
||||
) :
|
||||
Shared::XYBannerView(parentResponder, inputEventHandlerDelegate, textFieldDelegate)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef GEOMETRY_BANNER_VIEW_H
|
||||
#define GEOMETRY_BANNER_VIEW_H
|
||||
|
||||
#include "../../shared/xy_banner_view.h"
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
class BannerView : public Shared::XYBannerView {
|
||||
public:
|
||||
BannerView(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,11 +0,0 @@
|
||||
#include "graph_controller.h"
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
GraphController::GraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, ButtonRowController * header, Shared::InteractiveCurveViewRange/*TODO -> Store*/ * store, Shared::CurveViewCursor * cursor, uint32_t * rangeVersion) :
|
||||
InteractiveCurveViewController(parentResponder, inputEventHandlerDelegate, header, store, nullptr, cursor, rangeVersion)
|
||||
{
|
||||
/* WHEREIWAS: Now i must make the app launch again without crash, by replacing the multiples nullptr that I used... */
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#ifndef GRAPH_VIEW_CONTROLLER_H
|
||||
#define GRAPH_VIEW_CONTROLLER_H
|
||||
|
||||
#include "../shared/interactive_curve_view_controller.h"
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
class GraphController : public Shared::InteractiveCurveViewController {
|
||||
public:
|
||||
GraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, ButtonRowController * header, Shared::InteractiveCurveViewRange * store, Shared::CurveViewCursor * cursor, uint32_t * rangeVersion);
|
||||
|
||||
virtual Shared::InteractiveCurveViewRange * interactiveCurveViewRange() override { return nullptr; } //TOIMPLEMENT
|
||||
virtual Shared::CurveView * curveView() override { return nullptr; } //TOIMPLEMENT
|
||||
virtual void reloadBannerView() override { } //TOIMPLEMENT
|
||||
virtual bool handleEnter() override { return false; } //TOIMPLEMENT
|
||||
virtual void initCursorParameters() override { } //TOIMPLEMENT
|
||||
virtual bool moveCursorVertically(int direction) override { return false; } //TOIMPLEMENT
|
||||
virtual uint32_t rangeVersion() override { return 0; } //TOIMPLEMENT
|
||||
virtual bool cursorMatchesModel() override { return false; } //TOIMPLEMENT
|
||||
virtual Poincare::Coordinate2D<double> xyValues(int curveIndex, double t, Poincare::Context * context) const override { return Poincare::Coordinate2D<double>(0, 0); } //TOIMPLEMENT
|
||||
virtual bool closestCurveIndexIsSuitable(int newIndex, int currentIndex) const override { return false; }
|
||||
virtual int selectedCurveIndex() const override { return 0; }
|
||||
virtual int numberOfCurves() const override { return 0; }
|
||||
|
||||
/* AlternateEmptyViewDefaultDelegate */
|
||||
virtual bool isEmpty() const override { return false; }
|
||||
virtual I18n::Message emptyMessage() override { return I18n::Message::NoFigures; }
|
||||
private:
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,147 +0,0 @@
|
||||
#include "figure_type_controller.h"
|
||||
#include "../figures/figures.h"
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
static constexpr I18n::Message sPointDefinitionsMessages[] = {
|
||||
I18n::Message::Coordinates,
|
||||
I18n::Message::Middle,
|
||||
I18n::Message::VectorProject,
|
||||
I18n::Message::OrthogonalProject
|
||||
};
|
||||
static const uint8_t sPointDefinitionsMessagesCount = sizeof(sPointDefinitionsMessages) / sizeof(I18n::Message);
|
||||
|
||||
|
||||
static constexpr I18n::Message sLineDefinitionMessages[] = {
|
||||
I18n::Message::CartesianEquation,
|
||||
I18n::Message::LinearEquation,
|
||||
I18n::Message::Points,
|
||||
I18n::Message::PointAndVector,
|
||||
I18n::Message::Parallele,
|
||||
I18n::Message::Perpendicular
|
||||
};
|
||||
static const uint8_t sLineDefinitionsMessagesCount = sizeof(sLineDefinitionMessages) / sizeof(I18n::Message);
|
||||
|
||||
|
||||
static constexpr I18n::Message sCircleDefinitionsMessages[] = {
|
||||
I18n::Message::PointAndRadius,
|
||||
I18n::Message::Diameter,
|
||||
I18n::Message::CartesianEquation,
|
||||
};
|
||||
static const uint8_t sCircleDefinitionsMessagesCount = sizeof(sCircleDefinitionsMessages) / sizeof(I18n::Message);
|
||||
|
||||
|
||||
static constexpr I18n::Message sVectorDefinitionsMessages[] = {
|
||||
I18n::Message::Coordinates,
|
||||
I18n::Message::TwoPoints
|
||||
};
|
||||
static const uint8_t sVectorDefinitionsMessagesCount = sizeof(sVectorDefinitionsMessages) / sizeof(I18n::Message);
|
||||
|
||||
|
||||
static constexpr I18n::Message sIndicatorDefinitionsMessages[] = {
|
||||
I18n::Message::Segment,
|
||||
I18n::Message::Angle,
|
||||
I18n::Message::Area,
|
||||
};
|
||||
static const uint8_t sIndicatorDefinitionsMessagesCount = sizeof(sIndicatorDefinitionsMessages) / sizeof(I18n::Message);
|
||||
|
||||
|
||||
DefinitionTypeController::DefinitionTypeController(Responder * parentResponder, FigureParametersController * parametersController):
|
||||
ViewController(parentResponder),
|
||||
m_lastSelectedRow(0),
|
||||
m_selectableTableView(this),
|
||||
m_messages(nullptr),
|
||||
m_figureType(FigureType::None),
|
||||
m_parametersController(parametersController)
|
||||
{
|
||||
for (int i = 0; i < k_numberOfCells; i ++) {
|
||||
m_cells[i].setMessageFont(KDFont::LargeFont);
|
||||
}
|
||||
}
|
||||
|
||||
void DefinitionTypeController::viewWillAppear() {
|
||||
assert(m_figureType != FigureType::None && m_messages != nullptr);
|
||||
selectRow(m_lastSelectedRow);
|
||||
m_selectableTableView.reloadData(); // We reload the cell of the table view to update their message
|
||||
}
|
||||
|
||||
void DefinitionTypeController::didBecomeFirstResponder() {
|
||||
//App::app()->snapshot()->setActivePage(App::Snapshot::Page::Distribution);
|
||||
Container::activeApp()->setFirstResponder(&m_selectableTableView);
|
||||
}
|
||||
|
||||
bool DefinitionTypeController::handleEvent(Ion::Events::Event event) {
|
||||
if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) {
|
||||
m_lastSelectedRow = selectedRow();
|
||||
StackViewController * stack = static_cast<StackViewController *>(parentResponder());
|
||||
m_parametersController->setParametersInfoFunctions(PointByCoordinates::numberOfParameters, PointByCoordinates::parameterTypeAtIndex);
|
||||
stack->push(m_parametersController);
|
||||
return true;
|
||||
}
|
||||
if (event == Ion::Events::Back) {
|
||||
StackViewController * stack = static_cast<StackViewController *>(parentResponder());
|
||||
stack->pop();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
HighlightCell * DefinitionTypeController::reusableCell(int index) {
|
||||
assert(index >= 0);
|
||||
assert(index < k_numberOfCells);
|
||||
return &m_cells[index];
|
||||
}
|
||||
|
||||
void DefinitionTypeController::willDisplayCellForIndex(HighlightCell * cell, int index) {
|
||||
MessageTableCellWithChevron * myCell = (MessageTableCellWithChevron *)cell;
|
||||
myCell->setMessage(m_messages[index]);
|
||||
}
|
||||
|
||||
int DefinitionTypeController::numberOfRows() const {
|
||||
switch (m_figureType) {
|
||||
case FigureType::Point:
|
||||
return sPointDefinitionsMessagesCount;
|
||||
break;
|
||||
case FigureType::Line:
|
||||
return sLineDefinitionsMessagesCount;
|
||||
break;
|
||||
case FigureType::Circle:
|
||||
return sCircleDefinitionsMessagesCount;
|
||||
break;
|
||||
case FigureType::Vector:
|
||||
return sVectorDefinitionsMessagesCount;
|
||||
break;
|
||||
case FigureType::Indicator:
|
||||
return sIndicatorDefinitionsMessagesCount;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void DefinitionTypeController::setFigureType(FigureType figureType) {
|
||||
m_figureType = figureType;
|
||||
switch (m_figureType) {
|
||||
case FigureType::Point:
|
||||
m_messages = sPointDefinitionsMessages;
|
||||
break;
|
||||
case FigureType::Line:
|
||||
m_messages = sLineDefinitionMessages;
|
||||
break;
|
||||
case FigureType::Circle:
|
||||
m_messages = sCircleDefinitionsMessages;
|
||||
break;
|
||||
case FigureType::Vector:
|
||||
m_messages = sVectorDefinitionsMessages;
|
||||
break;
|
||||
case FigureType::Indicator:
|
||||
m_messages = sIndicatorDefinitionsMessages;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
#ifndef GEOMETRY_DEFINITION_TYPE_CONTROLLER_H
|
||||
#define GEOMETRY_DEFINITION_TYPE_CONTROLLER_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "apps/i18n.h"
|
||||
#include "../figures/figure_type.h"
|
||||
#include "figure_parameters_controller.h"
|
||||
|
||||
namespace Geometry {
|
||||
/**
|
||||
* \brief DefinitionTypeController is a controller to choose how the figure is defined
|
||||
*/
|
||||
class DefinitionTypeController : public ViewController, public SimpleListViewDataSource, public SelectableTableViewDataSource {
|
||||
public:
|
||||
DefinitionTypeController(Responder * parentResponder, FigureParametersController * parametersController);
|
||||
|
||||
/* ViewController */
|
||||
View * view() override { return &m_selectableTableView; }
|
||||
// We want to avoid using half of the screen just for titles
|
||||
virtual DisplayParameter displayParameter() override { return DisplayParameter::DoNotShowOwnTitle; }
|
||||
const char * title() override { return I18n::translate(I18n::Message::DefinitionType); }
|
||||
|
||||
/* Responder */
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
|
||||
/* ViewController */
|
||||
void didBecomeFirstResponder() override;
|
||||
void viewWillAppear() override;
|
||||
TELEMETRY_ID("FigureType");
|
||||
|
||||
/* SelectableTableViewDataSource */
|
||||
int numberOfRows() const override;
|
||||
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
|
||||
KDCoordinate cellHeight() override { return k_cellHeight; }
|
||||
HighlightCell * reusableCell(int index) override;
|
||||
int reusableCellCount() const override { return k_numberOfCells; }
|
||||
|
||||
/* Customs methods */
|
||||
void setFigureType(FigureType type);
|
||||
private:
|
||||
constexpr static KDCoordinate k_cellHeight = Metric::ParameterCellHeight;
|
||||
constexpr static int k_numberOfCells = 6;
|
||||
int m_lastSelectedRow;
|
||||
MessageTableCellWithChevron m_cells[k_numberOfCells];
|
||||
SelectableTableView m_selectableTableView;
|
||||
const I18n::Message * m_messages;
|
||||
FigureType m_figureType;
|
||||
FigureParametersController * m_parametersController;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,114 +0,0 @@
|
||||
#include "figure_parameters_controller.h"
|
||||
#include "../app.h"
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
FigureParametersController::FigureParametersController(Responder * parentResponder):
|
||||
ViewController(parentResponder),
|
||||
m_lastSelectedRow(0),
|
||||
m_selectableTableView(this),
|
||||
m_okButton(&m_selectableTableView, I18n::Message::Ok, Invocation([](void * context, void * sender) {
|
||||
FigureParametersController * parameterController = (FigureParametersController *) context;
|
||||
parameterController->returnToMenu();
|
||||
return true;
|
||||
}, this))
|
||||
{
|
||||
for (int i = 0; i < k_choiceCells; i++) {
|
||||
m_choicesCells[i].setParentResponder(&m_selectableTableView);
|
||||
}
|
||||
for (int i = 0; i < k_textCells; i++) {
|
||||
m_textCells[i].setParentResponder(&m_selectableTableView);
|
||||
m_textCells[i].textField()->setDelegates(this, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FigureParametersController::setParametersInfoFunctions(NumberOfParametersFunction numberOfParametersFunction, TypeOfParametersAtIndexFunction typeOfParametersAtIndexFunction) {
|
||||
m_numberOfParametersFunction = numberOfParametersFunction;
|
||||
m_typeOfParametersAtIndexFunction = typeOfParametersAtIndexFunction;
|
||||
}
|
||||
|
||||
void FigureParametersController::didBecomeFirstResponder() {
|
||||
Container::activeApp()->setFirstResponder(&m_selectableTableView);
|
||||
}
|
||||
|
||||
void FigureParametersController::viewWillAppear() {
|
||||
selectRow(m_lastSelectedRow);
|
||||
}
|
||||
|
||||
void FigureParametersController::returnToMenu() {
|
||||
StackViewController * stack = static_cast<StackViewController *>(parentResponder());
|
||||
stack->pop();
|
||||
stack->pop();
|
||||
stack->pop();
|
||||
}
|
||||
|
||||
/* ListViewDataSource */
|
||||
int FigureParametersController::typeAtLocation(int i, int j) {
|
||||
if (j == m_numberOfParametersFunction()) {
|
||||
return 0; // It's equivalent to "None", so we can use it for button cell
|
||||
}
|
||||
return (int) m_typeOfParametersAtIndexFunction(j);
|
||||
}
|
||||
|
||||
int FigureParametersController::reusableCellCount(int type) {
|
||||
if (type == 0) {
|
||||
return 1;
|
||||
}
|
||||
return type == (int) FigureType::Expression ? k_textCells: k_choiceCells;
|
||||
}
|
||||
|
||||
HighlightCell * FigureParametersController::reusableCell(int index, int type) {
|
||||
if (type == 0) {
|
||||
return &m_okButton;
|
||||
}
|
||||
if (type == (int) FigureType::Expression) {
|
||||
return &m_textCells[index];
|
||||
}
|
||||
return &m_choicesCells[index];
|
||||
}
|
||||
|
||||
int FigureParametersController::numberOfRows() const {
|
||||
return m_numberOfParametersFunction() + 1;
|
||||
}
|
||||
KDCoordinate FigureParametersController::rowHeight(int j) {
|
||||
if (j == numberOfRows()-1) {
|
||||
return Metric::ParameterCellHeight+k_buttonMargin;
|
||||
}
|
||||
return Metric::ParameterCellHeight;
|
||||
}
|
||||
|
||||
KDCoordinate FigureParametersController::cumulatedHeightFromIndex(int j) {
|
||||
if (j == numberOfRows()) {
|
||||
return j*Metric::ParameterCellHeight+k_buttonMargin;
|
||||
}
|
||||
return Metric::ParameterCellHeight*j;
|
||||
}
|
||||
|
||||
int FigureParametersController::indexFromCumulatedHeight(KDCoordinate offsetY) {
|
||||
return (offsetY - 1) / Metric::ParameterCellHeight;
|
||||
}
|
||||
|
||||
void FigureParametersController::willDisplayCellForIndex(HighlightCell * cell, int index) {
|
||||
|
||||
}
|
||||
|
||||
bool FigureParametersController::textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) {
|
||||
return (event == Ion::Events::Down && selectedRow() < numberOfRows()-1)
|
||||
|| (event == Ion::Events::Up && selectedRow() > 0)
|
||||
|| TextFieldDelegate::textFieldShouldFinishEditing(textField, event);
|
||||
}
|
||||
|
||||
bool FigureParametersController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) {
|
||||
m_selectableTableView.reloadCellAtLocation(0, selectedRow());
|
||||
m_selectableTableView.reloadData();
|
||||
textField->setText(text);
|
||||
if (event == Ion::Events::EXE || event == Ion::Events::OK) {
|
||||
m_selectableTableView.selectCellAtLocation(selectedColumn(), selectedRow() + 1);
|
||||
} else {
|
||||
m_selectableTableView.handleEvent(event);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
#ifndef GEOMETRY_FIGURE_PARAMETERS_CONTROLLER_H
|
||||
#define GEOMETRY_FIGURE_PARAMETERS_CONTROLLER_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "apps/i18n.h"
|
||||
#include "message_table_cell_with_selector.h"
|
||||
#include "../figures/figure.h"
|
||||
#include "../../shared/parameter_text_field_delegate.h"
|
||||
#include "../../shared/input_event_handler_delegate.h"
|
||||
#include "../../shared/button_with_separator.h"
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
typedef int (*NumberOfParametersFunction)();
|
||||
typedef FigureType (*TypeOfParametersAtIndexFunction)(int);
|
||||
|
||||
/**
|
||||
* \brief Controller returning the parameter choosen by the user to define the figure
|
||||
*/
|
||||
class FigureParametersController : public ViewController, public ListViewDataSource, public SelectableTableViewDataSource, public Shared::ParameterTextFieldDelegate, public Shared::InputEventHandlerDelegate {
|
||||
public:
|
||||
FigureParametersController(Responder * parentResponder);
|
||||
void setParametersInfoFunctions(NumberOfParametersFunction numberOfParametersFunction, TypeOfParametersAtIndexFunction typeOfParametersAtIndexFunction);
|
||||
void returnToMenu();
|
||||
/* ViewController */
|
||||
const char * title() override { return I18n::translate(I18n::Message::ParametersChoice); }
|
||||
// We want to avoid using half of the screen just for titles
|
||||
virtual DisplayParameter displayParameter() override { return DisplayParameter::DoNotShowOwnTitle; }
|
||||
View * view() override { return &m_selectableTableView; };
|
||||
|
||||
/* Responder */
|
||||
void didBecomeFirstResponder() override;
|
||||
void viewWillAppear() override;
|
||||
|
||||
/* ListViewDataSource */
|
||||
int typeAtLocation(int i, int j) override;
|
||||
int reusableCellCount(int type) override; // TO IMPLEMENT
|
||||
HighlightCell * reusableCell(int index, int type) override;
|
||||
int numberOfRows() const override;
|
||||
KDCoordinate rowHeight(int j) override;
|
||||
KDCoordinate cumulatedHeightFromIndex(int j) override;
|
||||
int indexFromCumulatedHeight(KDCoordinate offsetY) override;
|
||||
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
|
||||
|
||||
/* InputEventHandlerDelegate */
|
||||
bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override;
|
||||
bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override;
|
||||
|
||||
private:
|
||||
SelectableTableView m_selectableTableView;
|
||||
constexpr static int k_textCells = 2;
|
||||
constexpr static int k_choiceCells = 3;
|
||||
constexpr static int k_buttonMargin = 6;
|
||||
int m_lastSelectedRow;
|
||||
MessageTableCellWithEditableText m_textCells[k_textCells];
|
||||
MessageTableCellWithSelector m_choicesCells[k_choiceCells];
|
||||
ButtonWithSeparator m_okButton;
|
||||
NumberOfParametersFunction m_numberOfParametersFunction;
|
||||
TypeOfParametersAtIndexFunction m_typeOfParametersAtIndexFunction;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,70 +0,0 @@
|
||||
#include "figure_type_controller.h"
|
||||
#include "apps/i18n.h"
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
static FigureType sTypes[] = {
|
||||
FigureType::Point,
|
||||
FigureType::Line,
|
||||
FigureType::Circle,
|
||||
FigureType::Vector,
|
||||
FigureType::Indicator
|
||||
};
|
||||
|
||||
static I18n::Message sMessages[] = {
|
||||
I18n::Message::Point,
|
||||
I18n::Message::Line,
|
||||
I18n::Message::Circle,
|
||||
I18n::Message::Vector,
|
||||
I18n::Message::Indicator
|
||||
};
|
||||
|
||||
FigureTypeController::FigureTypeController(Responder * parentResponder, DefinitionTypeController * definitionTypeController) :
|
||||
ViewController(parentResponder),
|
||||
m_lastSelectedRow(0),
|
||||
m_selectableTableView(this),
|
||||
m_definitionTypeController(definitionTypeController),
|
||||
m_messages(sMessages)
|
||||
{
|
||||
for (int i = 0; i < k_numberOfCells; i ++) {
|
||||
m_cells[i].setMessageFont(KDFont::LargeFont);
|
||||
}
|
||||
}
|
||||
|
||||
void FigureTypeController::viewWillAppear() {
|
||||
selectRow(m_lastSelectedRow);
|
||||
}
|
||||
|
||||
void FigureTypeController::didBecomeFirstResponder() {
|
||||
//App::app()->snapshot()->setActivePage(App::Snapshot::Page::Distribution);
|
||||
Container::activeApp()->setFirstResponder(&m_selectableTableView);
|
||||
}
|
||||
|
||||
bool FigureTypeController::handleEvent(Ion::Events::Event event) {
|
||||
if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) {
|
||||
m_lastSelectedRow = selectedRow();
|
||||
StackViewController * stack = static_cast<StackViewController *>(parentResponder());
|
||||
m_definitionTypeController->setFigureType(sTypes[selectedRow()]);
|
||||
stack->push(m_definitionTypeController);
|
||||
return true;
|
||||
}
|
||||
if (event == Ion::Events::Back ) {
|
||||
StackViewController * stack = static_cast<StackViewController *>(parentResponder());
|
||||
stack->pop();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
HighlightCell * FigureTypeController::reusableCell(int index) {
|
||||
assert(index >= 0);
|
||||
assert(index < k_numberOfCells);
|
||||
return &m_cells[index];
|
||||
}
|
||||
|
||||
void FigureTypeController::willDisplayCellForIndex(HighlightCell * cell, int index) {
|
||||
MessageTableCellWithChevron * myCell = (MessageTableCellWithChevron *)cell;
|
||||
myCell->setMessage(m_messages[index]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
#ifndef GEOMETRY_FIGURE_TYPE_CONTROLLER_H
|
||||
#define GEOMETRY_FIGURE_TYPE_CONTROLLER_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "definition_type_controller.h"
|
||||
|
||||
namespace Geometry {
|
||||
/**
|
||||
* \brief FigureTypeController is a controller that is used to select the type of
|
||||
* figure to be created.
|
||||
*/
|
||||
class FigureTypeController : public ViewController, public SimpleListViewDataSource, public SelectableTableViewDataSource {
|
||||
public:
|
||||
FigureTypeController(Responder * parentResponder, DefinitionTypeController * definitionController);
|
||||
|
||||
/* ViewController */
|
||||
View * view() override { return &m_selectableTableView; }
|
||||
// We want to avoid using half of the screen just for titles
|
||||
virtual DisplayParameter displayParameter() override { return DisplayParameter::DoNotShowOwnTitle; }
|
||||
const char * title() override { return I18n::translate(I18n::Message::FigureType); }
|
||||
|
||||
/* Responder */
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
void didBecomeFirstResponder() override;
|
||||
|
||||
/* ViewController */
|
||||
void viewWillAppear() override;
|
||||
TELEMETRY_ID("FigureType");
|
||||
|
||||
/* TableViewDataSource */
|
||||
int numberOfRows() const override { return k_numberOfRows; }
|
||||
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
|
||||
KDCoordinate cellHeight() override { return k_cellHeight; }
|
||||
HighlightCell * reusableCell(int index) override;
|
||||
int reusableCellCount() const override { return k_numberOfCells; }
|
||||
private:
|
||||
constexpr static KDCoordinate k_cellHeight = Metric::ParameterCellHeight;
|
||||
constexpr static int k_numberOfCells = 5;
|
||||
constexpr static int k_numberOfRows = 5;
|
||||
int m_lastSelectedRow;
|
||||
MessageTableCellWithChevron m_cells[k_numberOfCells];
|
||||
SelectableTableView m_selectableTableView;
|
||||
DefinitionTypeController * m_definitionTypeController;
|
||||
I18n::Message * m_messages;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,77 +0,0 @@
|
||||
#include "figures_controller.h"
|
||||
#include "definition_type_controller.h"
|
||||
#include <apps/i18n.h>
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
FiguresController::FiguresController(Responder * parentResponder):
|
||||
ViewController(parentResponder),
|
||||
m_selectableTableView(this, this, this, this),
|
||||
m_addFigureCell(),
|
||||
m_emptyCell(),
|
||||
m_figureTypeController(this, &m_definitionTypeController),
|
||||
m_definitionTypeController(&m_figureTypeController, &m_parametersController),
|
||||
m_parametersController(&m_definitionTypeController)
|
||||
{
|
||||
m_addFigureCell.setMessage(I18n::Message::AddFigure);
|
||||
}
|
||||
|
||||
bool FiguresController::handleEvent(Ion::Events::Event event) {
|
||||
if (event == Ion::Events::OK || event == Ion::Events::EXE) {
|
||||
if (isAddFigureRow(selectedRow())) {
|
||||
StackViewController * stack = static_cast<StackViewController *>(parentResponder());
|
||||
stack->push(&m_figureTypeController);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (event == Ion::Events::Up && selectedRow() == 0) {
|
||||
m_selectableTableView.deselectTable();
|
||||
assert(selectedRow() == -1);
|
||||
Container::activeApp()->setFirstResponder(parentResponder()->parentResponder());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FiguresController::didBecomeFirstResponder() {
|
||||
Container::activeApp()->setFirstResponder(&m_selectableTableView);
|
||||
}
|
||||
|
||||
|
||||
HighlightCell * FiguresController::reusableCell(int index, int type) {
|
||||
assert(index >= 0);
|
||||
if (type == 2) {
|
||||
return &m_emptyCell;
|
||||
}
|
||||
return &m_addFigureCell;
|
||||
}
|
||||
|
||||
void FiguresController::willDisplayCellAtLocation(HighlightCell * cell, int i, int j) {
|
||||
if (i == 0) {
|
||||
return;
|
||||
}
|
||||
EvenOddCell * myCell = (EvenOddCell *)cell;
|
||||
myCell->setEven(j%2 == 0);
|
||||
myCell->setHighlighted(i == selectedColumn() && j == selectedRow());
|
||||
myCell->reloadCell();
|
||||
}
|
||||
|
||||
bool FiguresController::isAddFigureRow(int j) {
|
||||
return j == 0;
|
||||
}
|
||||
|
||||
int FiguresController::reusableCellCount(int type) {
|
||||
if (type > 1) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FiguresController::typeAtLocation(int i, int j) {
|
||||
if (isAddFigureRow(j)) {
|
||||
return i + 2;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
#ifndef FIGURES_CONTROLLER_H
|
||||
#define FIGURES_CONTROLLER_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "figure_type_controller.h"
|
||||
|
||||
namespace Geometry
|
||||
{
|
||||
/**
|
||||
* \brief FiguresController is a controller to show the list of the figures
|
||||
*/
|
||||
class FiguresController : public ViewController, public SelectableTableViewDataSource, public SelectableTableViewDelegate, public TableViewDataSource {
|
||||
public:
|
||||
FiguresController(Responder * parentResponder);
|
||||
|
||||
/* ViewController */
|
||||
View * view() override { return &m_selectableTableView; }
|
||||
const char * title() override { return I18n::translate(I18n::Message::FiguresTab); }
|
||||
virtual DisplayParameter displayParameter() override { return DisplayParameter::DoNotShowOwnTitle; }
|
||||
/* Responder */
|
||||
bool handleEvent(Ion::Events::Event event) override; // TO IMPLEMENT
|
||||
void didBecomeFirstResponder() override;
|
||||
|
||||
/* TableView */
|
||||
int numberOfRows() const override { return 1; } // TO IMPLEMENT
|
||||
int numberOfColumns() const override { return 2; } // TO IMPLEMENT
|
||||
KDCoordinate columnWidth(int i) { return i == 0 ? 50 : 150; } // TO IMPLEMENT
|
||||
KDCoordinate rowHeight(int j) { return 50; } // TO IMPLEMENT
|
||||
HighlightCell * reusableCell(int index, int type); // TO IMPLEMENT
|
||||
void willDisplayCellAtLocation(HighlightCell * cell, int i, int j) override; // TO IMPLEMENT
|
||||
int reusableCellCount(int type);
|
||||
int typeAtLocation(int i, int j); // TO IMPLEMENT
|
||||
|
||||
private:
|
||||
/* Customs methods */
|
||||
bool isAddFigureRow(int j); // TO IMPLEMENT
|
||||
|
||||
SelectableTableView m_selectableTableView;
|
||||
EvenOddMessageTextCell m_addFigureCell;
|
||||
EvenOddCell m_emptyCell;
|
||||
FigureTypeController m_figureTypeController;
|
||||
DefinitionTypeController m_definitionTypeController;
|
||||
FigureParametersController m_parametersController;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -1,24 +0,0 @@
|
||||
#include "message_table_cell_with_selector.h"
|
||||
#include <escher/container.h>
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
MessageTableCellWithSelector::MessageTableCellWithSelector(ToolboxMessageTree * root, const KDFont * font) :
|
||||
Responder(nullptr),
|
||||
MessageTableCell((I18n::Message)0, font),
|
||||
m_objectsRoot(root),
|
||||
m_selectedMessage(nullptr),
|
||||
m_toolbox(this)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool MessageTableCellWithSelector::handleEvent(Ion::Events::Event event) {
|
||||
if (event == Ion::Events::OK || event == Ion::Events::EXE) {
|
||||
Container::activeApp()->displayModalViewController(&m_toolbox, 0.f, 0.f, Metric::PopUpTopMargin, Metric::PopUpLeftMargin, 0, Metric::PopUpRightMargin);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#ifndef ESHER_MESSAGE_TABLE_CELL_WITH_OBJECT_SELECTOR_H_
|
||||
#define ESHER_MESSAGE_TABLE_CELL_WITH_OBJECT_SELECTOR_H_
|
||||
|
||||
#include <escher/message_table_cell_with_buffer.h>
|
||||
#include <escher/toolbox_message_tree.h>
|
||||
#include "objects_controller.h"
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
class MessageTableCellWithSelector : public Responder, public MessageTableCell {
|
||||
public:
|
||||
MessageTableCellWithSelector(ToolboxMessageTree * root = nullptr, const KDFont * font = KDFont::SmallFont);
|
||||
ToolboxMessageTree * getSelectedMessage() const { return m_selectedMessage; };
|
||||
bool handleEvent(Ion::Events::Event event);
|
||||
Responder * responder() override {
|
||||
return this;
|
||||
}
|
||||
private:
|
||||
ToolboxMessageTree * m_objectsRoot;
|
||||
ToolboxMessageTree * m_selectedMessage;
|
||||
ObjectsController m_toolbox;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,35 +0,0 @@
|
||||
#include "objects_controller.h"
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
ObjectsController::ObjectsController(Responder * responder) :
|
||||
NestedMenuController(this)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int ObjectsController::numberOfRows() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ObjectsController::reusableCellCount(int type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ObjectsController::typeAtLocation(int i, int j) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ObjectsController::selectLeaf(int type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HighlightCell * ObjectsController::leafCellAtIndex(int index) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HighlightCell * ObjectsController::nodeCellAtIndex(int index) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
#ifndef GEOMETRY_OBJECTS_CONTROLLER_H
|
||||
#define GEOMETRY_OBJECTS_CONTROLLER_H
|
||||
|
||||
#include <escher/nested_menu_controller.h>
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
class ObjectsController : public NestedMenuController {
|
||||
public:
|
||||
ObjectsController(Responder * parentResponder);
|
||||
virtual int numberOfRows() const override;
|
||||
virtual int reusableCellCount(int type) override;
|
||||
virtual int typeAtLocation(int i, int j) override;
|
||||
virtual bool selectLeaf(int selectedRow) override;
|
||||
virtual HighlightCell * leafCellAtIndex(int index) override;
|
||||
virtual HighlightCell * nodeCellAtIndex(int index) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
#ifndef OTHER_VIEW_CONTROLLER_H
|
||||
#define OTHER_VIEW_CONTROLLER_H
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
class OtherViewController : public ViewController {
|
||||
public:
|
||||
OtherViewController(Responder * parentResponder):
|
||||
ViewController(parentResponder) {}
|
||||
View * view() override { return nullptr; }
|
||||
const char * title() override { return I18n::translate(I18n::Message::OtherTab); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,2 +1,2 @@
|
||||
Default,geometry,calculation,rpn,graph,code,statistics,probability,solver,atomic,sequence,regression,reader,settings
|
||||
HidePython,geometry,calculation,rpn,graph,code,statistics,probability,solver,atomic,sequence,regression,reader,settings
|
||||
Default,calculation,rpn,graph,code,statistics,probability,solver,atomic,sequence,regression,reader,settings
|
||||
HidePython,calculation,rpn,graph,code,statistics,probability,solver,atomic,sequence,regression,reader,settings
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
|
||||
MathVariableBoxEmptyController::MathVariableBoxEmptyView::MathVariableBoxEmptyView() :
|
||||
ModalViewEmptyView(),
|
||||
m_layoutExample(0.5f, 0.5f, Palette::PrimaryText, Palette::WallScreen)
|
||||
m_layoutExample(0.5f, 0.5f, KDColorBlack, Palette::WallScreen)
|
||||
{
|
||||
initMessageViews();
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
apps += Reader::App
|
||||
app_headers += apps/reader/app.h
|
||||
|
||||
SFLAGS += -DHAS_READER
|
||||
|
||||
app_sreader_src = $(addprefix apps/reader/,\
|
||||
app.cpp \
|
||||
list_book_controller.cpp \
|
||||
utility.cpp \
|
||||
read_book_controller \
|
||||
word_wrap_view.cpp \
|
||||
tex_parser.cpp \
|
||||
)
|
||||
|
||||
apps_src += $(app_sreader_src)
|
||||
|
||||
@@ -6,8 +6,10 @@ Thanks to [Gabriel79](https://github.com/Gabriel79) for the original reader app,
|
||||
# Rich text format
|
||||
Reader app supports now a rich text format :
|
||||
|
||||
* `$` around a mathematical expression **without spaces** to render it
|
||||
* `$` around a LaTeX expression to render it
|
||||
* `%` around a color-code (see below) to change the color of the text
|
||||
### LaTeX expressions
|
||||
You can read the documentation for the LaTeX Parser [here](TexParser.md).
|
||||
### Color codes :
|
||||
|code|color|
|
||||
| --:| ---:|
|
||||
|
||||
1901
apps/reader/TexParser.html
Normal file
1901
apps/reader/TexParser.html
Normal file
File diff suppressed because it is too large
Load Diff
51
apps/reader/TexParser.md
Normal file
51
apps/reader/TexParser.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# LaTeX Parser
|
||||
|
||||
In the reader app, you can read a txt file. You can also read a txt file with LaTeX expression inside of it.
|
||||
|
||||
All the symbols you can use are listed here :
|
||||
|
||||
|Command|Output||Command|Output|
|
||||
|--:|:--:|--:|--:|:--:|
|
||||
|Math|Expressions||||
|
||||
|`\frac{ab}{cd}`|$\frac{ab}{cd}$||`\sqrt[n]{x}`|$\sqrt[n]{x}$|
|
||||
|Math|Symbols|||
|
||||
|`\times`|$\times$||`\div`|$\div$|
|
||||
|`\forall`|$\forall$||`\exists`|$\exists$|
|
||||
|`\partial`|$\partial$||`\pm`|$\pm$|
|
||||
|`\infty`|$\infty$||`\approx`|$\approx$|
|
||||
|`\neq`|$\neq$||`\equiv`|$\equiv$|
|
||||
|`\leq`|$\leq$||`\geq`|$\geq$|
|
||||
|Simple|Arrows||Double|Arrows|
|
||||
|`\leftarrow`|$\leftarrow$||`\Leftarrow`|$\Leftarrow$|
|
||||
|`\rightarrow`|$\rightarrow$||`\Rightarrow`|$\Rightarrow$|
|
||||
|`\uparrow`|$\uparrow$||`\Uparrow`|$\Uparrow$|
|
||||
|`\downarrow`|$\downarrow$||`\Downarrow`|$\Downarrow$|
|
||||
|`\leftrightarrow`|$\leftrightarrow$||||
|
||||
|`\updownarrow`|$\updownarrow$||||
|
||||
|Greek Capital|Letters||Greek Small|Letters|
|
||||
|`\Alpha`|$\Alpha$||`\alpha`|$\alpha$|
|
||||
|`\Beta`|$\Beta$||`\beta`|$\beta$|
|
||||
|`\Gamma`|$\Gamma$||`\gamma`|$\gamma$|
|
||||
|`\Delta`|$\Delta$||`\delta`|$\delta$|
|
||||
|`\Epsilon`|$\Epsilon$||`\epsilon`|$\epsilon$|
|
||||
|`\Zeta`|$\Zeta$||`\zeta`|$\zeta$|
|
||||
|`\Eta`|$\Eta$||`\eta`|$\eta$|
|
||||
|`\Theta`|$\Theta$||`\theta`|$\theta$|
|
||||
|`\Iota`|$\Iota$||`\iota`|$\iota$|
|
||||
|`\Kappa`|$\Kappa$||`\kappa`|$\kappa$|
|
||||
|`\Lambda`|$\Lambda$||`\lambda`|$\lambda$|
|
||||
|`\Mu`|$\Mu$||`\mu`|$\mu$|
|
||||
|`\Nu`|$\Nu$||`\nu`|$\nu$|
|
||||
|`\Xi`|$\Xi$||`\xi`|$\xi$|
|
||||
|`\Omicron`|$\Omicron$|||
|
||||
|`\Pi`|$\Pi$||`\pi`|$\pi$|
|
||||
|`\Rho`|$\Rho$||`\rho`|$\rho$|
|
||||
|`\Sigma`|$\Sigma$||`\sigma`|$\sigma$|
|
||||
|`\Tau`|$\Tau$||`\tau`|$\tau$|
|
||||
|`\Upsilon`|$\Upsilon$||`\upsilon`|$\upsilon$|
|
||||
|`\Phi`|$\Phi$||`\phi`|$\phi$|
|
||||
|`\Chi`|$\Chi$||`\chi`|$\chi$|
|
||||
|`\Psi`|$\Psi$||`\psi`|$\psi$|
|
||||
|`\Omega`|$\Omega$||`\omega`|$\omega$|
|
||||
|
||||
|
||||
210
apps/reader/tex_parser.cpp
Normal file
210
apps/reader/tex_parser.cpp
Normal file
@@ -0,0 +1,210 @@
|
||||
#include "tex_parser.h"
|
||||
#include <ion/unicode/utf8_decoder.h>
|
||||
|
||||
namespace Reader {
|
||||
|
||||
// List of available Symbols
|
||||
static constexpr char const * k_SymbolsCommands[] = {
|
||||
"times", "div", "forall", "partial", "exists", "pm", "approx", "infty", "neq", "equiv", "leq", "geq",
|
||||
"leftarrow", "uparrow", "rightarrow", "downarrow", "leftrightarrow", "updownarrow", "Leftarrow", "Uparrow", "Rightarrow", "Downarrow",
|
||||
"Alpha", "Beta", "Gamma", "Delta", "Epsilon", "Zeta", "Eta", "Theta", "Iota", "Kappa", "Lambda",
|
||||
"Mu", "Nu", "Xi", "Omicron", "Pi", "Rho", "Sigma", "Tau", "Upsilon", "Phi", "Chi", "Psi","Omega",
|
||||
"alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa", "lambda",
|
||||
"mu", "nu", "xi", "omicron", "pi", "rho", "sigma", "tau", "upsilon", "phi", "chi", "psi", "omega",
|
||||
};
|
||||
|
||||
//List of the available Symbol's CodePoints in the same order of the Symbol's list
|
||||
static constexpr uint32_t const k_SymbolsCodePoints[] = {
|
||||
0xd7, 0xf7, 0x2200, 0x2202, 0x2203, 0xb1, 0x2248, 0x221e, 0x2260, 0x2261, 0x2264, 0x2265,
|
||||
0x2190, 0x2191, 0x2192, 0x2193, 0x2194, 0x2195, 0x21d0, 0x21d1, 0x21d2, 0x21d3,
|
||||
0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39a, 0x39b,
|
||||
0x39c, 0x39d, 0x39e, 0x39f, 0x3a0, 0x3a1, 0x3a3, 0x3a4, 0x3a5, 0x3a6, 0x3a7, 0x3a8, 0x3a9,
|
||||
0x3b1, 0x3b2, 0x3b3, 0x3b4, 0x3b5, 0x3b6, 0x3b7, 0x3b8, 0x3b9, 0x3ba, 0x3bb,
|
||||
0x3bc, 0x3bd, 0x3be, 0x3bf, 0x3c0, 0x3c1, 0x3c3, 0x3c4, 0x3c5, 0x3c6, 0x3c7, 0x3c8, 0x3c9
|
||||
};
|
||||
|
||||
// List of available Function Commands that don't require a specific handling
|
||||
static constexpr char const * k_FunctionCommands[] = {
|
||||
"arcos", "arcsin", "arctan", "arg", "cos", "cosh", "cot", "coth",
|
||||
"csc", "deg", "det", "dim", "exp", "gcd", "hom", "inf",
|
||||
"ker", "lg", "lim", "liminf", "limsup", "ln", "log", "max",
|
||||
"min", "Pr", "sec", "sin", "sinh", "sup", "tan", "tanh"
|
||||
};
|
||||
|
||||
TexParser::TexParser(const char * text, const char * endOfText) :
|
||||
m_text(text),
|
||||
m_endOfText(endOfText),
|
||||
m_hasError(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Layout TexParser::getLayout() {
|
||||
Layout layout = popText(0);
|
||||
|
||||
if (m_hasError) {
|
||||
return CodePointLayout::Builder(CodePoint(0xfffd));
|
||||
}
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
Layout TexParser::popBlock() {
|
||||
while (*m_text == ' ') {
|
||||
m_text ++;
|
||||
}
|
||||
|
||||
if (*m_text == '{') {
|
||||
m_text ++;
|
||||
return popText('}');
|
||||
}
|
||||
|
||||
if (*m_text == '\\') {
|
||||
m_text ++;
|
||||
return popCommand();
|
||||
}
|
||||
|
||||
if (m_text >= m_endOfText) {
|
||||
m_hasError = true;
|
||||
}
|
||||
|
||||
UTF8Decoder decoder(m_text);
|
||||
m_text ++;
|
||||
return CodePointLayout::Builder(decoder.nextCodePoint());
|
||||
}
|
||||
|
||||
Layout TexParser::popText(char stop) {
|
||||
HorizontalLayout layout = HorizontalLayout::Builder();
|
||||
const char * start = m_text;
|
||||
|
||||
while (m_text < m_endOfText && *m_text != stop) {
|
||||
switch (*m_text) {
|
||||
// TODO: Factorize this code
|
||||
case '\\':
|
||||
if (start != m_text) {
|
||||
layout.addOrMergeChildAtIndex(LayoutHelper::String(start, m_text - start), layout.numberOfChildren(), false);
|
||||
}
|
||||
m_text ++;
|
||||
layout.addOrMergeChildAtIndex(popCommand(), layout.numberOfChildren(), false);
|
||||
start = m_text;
|
||||
break;
|
||||
case ' ':
|
||||
if (start != m_text) {
|
||||
layout.addOrMergeChildAtIndex(LayoutHelper::String(start, m_text - start), layout.numberOfChildren(), false);
|
||||
}
|
||||
m_text ++;
|
||||
start = m_text;
|
||||
break;
|
||||
case '^':
|
||||
if (start != m_text) {
|
||||
layout.addOrMergeChildAtIndex(LayoutHelper::String(start, m_text - start), layout.numberOfChildren(), false);
|
||||
}
|
||||
m_text ++;
|
||||
layout.addOrMergeChildAtIndex(VerticalOffsetLayout::Builder(popBlock(), VerticalOffsetLayoutNode::Position::Superscript), layout.numberOfChildren(), false);
|
||||
start = m_text;
|
||||
break;
|
||||
case '_':
|
||||
if (start != m_text) {
|
||||
layout.addOrMergeChildAtIndex(LayoutHelper::String(start, m_text - start), layout.numberOfChildren(), false);
|
||||
}
|
||||
m_text ++;
|
||||
layout.addOrMergeChildAtIndex(VerticalOffsetLayout::Builder(popBlock(), VerticalOffsetLayoutNode::Position::Subscript), layout.numberOfChildren(), false);
|
||||
start = m_text;
|
||||
break;
|
||||
default:
|
||||
m_text ++;
|
||||
}
|
||||
}
|
||||
|
||||
if (start != m_text) {
|
||||
layout.addOrMergeChildAtIndex(LayoutHelper::String(start, m_text - start), layout.numberOfChildren(), false);
|
||||
}
|
||||
|
||||
m_text ++;
|
||||
|
||||
if (layout.numberOfChildren() == 1) {
|
||||
return layout.squashUnaryHierarchyInPlace();
|
||||
}
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
Layout TexParser::popCommand() {
|
||||
// TODO: Factorize this code
|
||||
if (strncmp(k_fracCommand, m_text, strlen(k_fracCommand)) == 0) {
|
||||
if (isCommandEnded(*(m_text + strlen(k_fracCommand)))) {
|
||||
m_text += strlen(k_fracCommand);
|
||||
return popFracCommand();
|
||||
}
|
||||
}
|
||||
if (strncmp(k_sqrtCommand, m_text, strlen(k_sqrtCommand)) == 0) {
|
||||
if (isCommandEnded(*(m_text + strlen(k_sqrtCommand)))) {
|
||||
m_text += strlen(k_sqrtCommand);
|
||||
return popSqrtCommand();
|
||||
}
|
||||
}
|
||||
if (strncmp(k_overrightArrowCommand, m_text, strlen(k_overrightArrowCommand)) == 0) {
|
||||
if (isCommandEnded(*(m_text + strlen(k_overrightArrowCommand)))) {
|
||||
m_text += strlen(k_overrightArrowCommand);
|
||||
return popOverrightarrowCommand();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < k_NumberOfSymbols; i++) {
|
||||
if (strncmp(k_SymbolsCommands[i], m_text, strlen(k_SymbolsCommands[i])) == 0) {
|
||||
if (isCommandEnded(*(m_text + strlen(k_SymbolsCommands[i])))) {
|
||||
m_text += strlen(k_SymbolsCommands[i]);
|
||||
return popSymbolCommand(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < k_NumberOfFunctionCommands; i++) {
|
||||
if (strncmp(k_FunctionCommands[i], m_text, strlen(k_FunctionCommands[i])) == 0) {
|
||||
if (isCommandEnded(*(m_text + strlen(k_FunctionCommands[i])))) {
|
||||
m_text += strlen(k_FunctionCommands[i]);
|
||||
return LayoutHelper::String(k_FunctionCommands[i], strlen(k_FunctionCommands[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_hasError = true;
|
||||
return LayoutHelper::String(m_text, strlen(m_text));
|
||||
}
|
||||
|
||||
// Expressions
|
||||
Layout TexParser::popFracCommand() {
|
||||
Layout numerator = popBlock();
|
||||
Layout denominator = popBlock();
|
||||
FractionLayout l = FractionLayout::Builder(numerator, denominator);
|
||||
return l;
|
||||
}
|
||||
|
||||
Layout TexParser::popSqrtCommand() {
|
||||
while (*m_text == ' ') {
|
||||
m_text ++;
|
||||
}
|
||||
if (*m_text == '[') {
|
||||
m_text ++;
|
||||
Layout rootFactor = popText(']');
|
||||
Layout belowRoot = popBlock();
|
||||
return NthRootLayout::Builder(belowRoot, rootFactor);
|
||||
}
|
||||
else {
|
||||
return NthRootLayout::Builder(popBlock());
|
||||
}
|
||||
}
|
||||
|
||||
Layout TexParser::popOverrightarrowCommand() {
|
||||
return VectorLayout::Builder(popBlock());
|
||||
}
|
||||
|
||||
Layout TexParser::popSymbolCommand(int SymbolIndex) {
|
||||
uint32_t codePoint = k_SymbolsCodePoints[SymbolIndex];
|
||||
return CodePointLayout::Builder(codePoint);
|
||||
}
|
||||
|
||||
inline bool TexParser::isCommandEnded(char c) const {
|
||||
return !(c >= 'a' && c <= 'z') && !(c >= 'A' && c <= 'Z');
|
||||
}
|
||||
}
|
||||
47
apps/reader/tex_parser.h
Normal file
47
apps/reader/tex_parser.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef __TEX_PARSER_H__
|
||||
#define __TEX_PARSER_H__
|
||||
|
||||
#include <poincare_layouts.h>
|
||||
#include <poincare/layout_helper.h>
|
||||
#include <string.h>
|
||||
|
||||
using namespace Poincare;
|
||||
|
||||
namespace Reader
|
||||
{
|
||||
/// @brief Class used in the WordWrapTextView class to parse a Tex expression
|
||||
class TexParser {
|
||||
public:
|
||||
TexParser(const char * text, const char * endOfText);
|
||||
Layout getLayout();
|
||||
private:
|
||||
Layout popBlock();
|
||||
Layout popText(char stop);
|
||||
Layout popCommand();
|
||||
|
||||
// Expressions
|
||||
Layout popFracCommand();
|
||||
Layout popSqrtCommand();
|
||||
Layout popOverrightarrowCommand();
|
||||
|
||||
//Symbols
|
||||
Layout popSymbolCommand(int SymbolIndex);
|
||||
|
||||
const char * m_text;
|
||||
const char * m_endOfText;
|
||||
bool m_hasError;
|
||||
|
||||
inline bool isCommandEnded(char c) const;
|
||||
|
||||
// Expressions that require specific handling
|
||||
static constexpr char const * k_fracCommand = "frac";
|
||||
static constexpr char const * k_sqrtCommand = "sqrt";
|
||||
static constexpr char const * k_overrightArrowCommand = "overrightarrow";
|
||||
|
||||
static constexpr int const k_NumberOfSymbols = 70;
|
||||
static constexpr int const k_NumberOfFunctionCommands = 32;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -117,7 +117,7 @@ const char * EndOfPrintableWord(const char * word, const char * end) {
|
||||
UTF8Decoder decoder(word);
|
||||
CodePoint codePoint = decoder.nextCodePoint();
|
||||
const char * result = word;
|
||||
while (codePoint != '\n' && codePoint != ' ' && codePoint != '%') {
|
||||
while (codePoint != '\n' && codePoint != ' ' && codePoint != '%' && codePoint != '$') {
|
||||
result = decoder.stringPosition();
|
||||
if (result >= end) {
|
||||
break;
|
||||
@@ -127,4 +127,21 @@ const char * EndOfPrintableWord(const char * word, const char * end) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const char * StartOfPrintableWord(const char * word, const char * start) {
|
||||
if (word == start) {
|
||||
return word;
|
||||
}
|
||||
UTF8Decoder decoder(start, word);
|
||||
CodePoint codePoint = decoder.previousCodePoint();
|
||||
const char * result = word;
|
||||
while (codePoint != '\n' && codePoint != ' ' && codePoint != '%' && codePoint != '$') {
|
||||
result = decoder.stringPosition();
|
||||
if (result >= start) {
|
||||
break;
|
||||
}
|
||||
codePoint = decoder.previousCodePoint();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,6 +12,7 @@ bool stringEndsWith(const char* str, const char* end);
|
||||
int filesWithExtension(const char* extension, External::Archive::File* files, int filesSize);
|
||||
void stringNCopy(char* dest, int max, const char* src, int len);
|
||||
const char * EndOfPrintableWord(const char * word, const char * end);
|
||||
const char * StartOfPrintableWord(const char * word, const char * start);
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
#include "word_wrap_view.h"
|
||||
#include "utility.h"
|
||||
#include "tex_parser.h"
|
||||
#include <poincare/expression.h>
|
||||
#include "../shared/poincare_helpers.h"
|
||||
#include <poincare/undefined.h>
|
||||
@@ -38,16 +39,17 @@ void WordWrapTextView::previousPage() {
|
||||
const int charWidth = m_font->glyphSize().width();
|
||||
const int charHeight = m_font->glyphSize().height();
|
||||
|
||||
const char * endOfWord = text() + m_pageOffset - 1;
|
||||
const char * startOfWord = UTF8Helper::BeginningOfWord(text(), endOfWord);
|
||||
const char * endOfFile = text() + m_length;
|
||||
const char * endOfWord = text() + m_pageOffset;
|
||||
const char * startOfWord = StartOfPrintableWord(endOfWord, text());
|
||||
|
||||
KDSize textSize = KDSizeZero;
|
||||
|
||||
KDPoint textEndPosition(m_frame.width() - k_margin, m_frame.height() - k_margin);
|
||||
|
||||
while(startOfWord>=text()) {
|
||||
startOfWord = UTF8Helper::BeginningOfWord(text(), endOfWord);
|
||||
endOfWord = UTF8Helper::EndOfWord(startOfWord);
|
||||
startOfWord = StartOfPrintableWord(endOfWord-1, text());
|
||||
//endOfWord = EndOfPrintableWord(startOfWord, endOfFile);
|
||||
|
||||
if (*startOfWord == '%') {
|
||||
if (updateTextColorBackward(startOfWord)) {
|
||||
@@ -55,20 +57,28 @@ void WordWrapTextView::previousPage() {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (*startOfWord == '$' && *(endOfWord-1) == '$') {
|
||||
const int wordMaxLength = 128;
|
||||
char word[wordMaxLength];
|
||||
stringNCopy(word, wordMaxLength, startOfWord + 1, endOfWord-startOfWord-2);
|
||||
Poincare::Expression expr = Poincare::Expression::Parse(word, nullptr);
|
||||
if (expr.isUninitialized()) {
|
||||
expr = Poincare::Undefined::Builder();
|
||||
|
||||
if (*endOfWord == '$') {
|
||||
startOfWord = endOfWord - 1;
|
||||
while (*startOfWord != '$') {
|
||||
if (startOfWord < text()) {
|
||||
break; // File isn't rightly formated
|
||||
}
|
||||
startOfWord --;
|
||||
}
|
||||
Poincare::Layout layout = Shared::PoincareHelpers::CreateLayout(expr);
|
||||
textSize = layout.layoutSize();
|
||||
|
||||
startOfWord --;
|
||||
|
||||
TexParser parser = TexParser(startOfWord + 1, endOfWord - 2);
|
||||
Poincare::Layout layout = parser.getLayout();
|
||||
textSize = layout.layoutSize();
|
||||
}
|
||||
else {
|
||||
textSize = m_font->stringSizeUntil(startOfWord, endOfWord);
|
||||
if (*startOfWord == '\\' || *(startOfWord + 1) == '$') {
|
||||
textSize = m_font->stringSizeUntil(startOfWord + 1, endOfWord);
|
||||
}
|
||||
else {
|
||||
textSize = m_font->stringSizeUntil(startOfWord, endOfWord);
|
||||
}
|
||||
}
|
||||
KDPoint textStartPosition = KDPoint(textEndPosition.x()-textSize.width(), textEndPosition.y());
|
||||
|
||||
@@ -109,7 +119,7 @@ void WordWrapTextView::previousPage() {
|
||||
m_pageOffset = 0;
|
||||
}
|
||||
else {
|
||||
m_pageOffset = UTF8Helper::EndOfWord(startOfWord) - text() + 1;
|
||||
m_pageOffset = EndOfPrintableWord(startOfWord, endOfFile) - text() + 1;
|
||||
}
|
||||
markRectAsDirty(bounds());
|
||||
}
|
||||
@@ -119,7 +129,12 @@ void WordWrapTextView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
|
||||
const char * endOfFile = text() + m_length;
|
||||
const char * startOfWord = text() + m_pageOffset;
|
||||
const char * endOfWord = EndOfPrintableWord(startOfWord, endOfFile);
|
||||
const char * endOfWord;
|
||||
|
||||
if (*startOfWord != '$') {
|
||||
endOfWord = EndOfPrintableWord(startOfWord, endOfFile);
|
||||
} // Else we don't need to update endOfWord
|
||||
|
||||
KDPoint textPosition(k_margin, k_margin);
|
||||
|
||||
const int wordMaxLength = 128;
|
||||
@@ -152,18 +167,26 @@ void WordWrapTextView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (*startOfWord == '$' && *(endOfWord-1) == '$') { // Look for expression
|
||||
stringNCopy(word, wordMaxLength, startOfWord + 1, endOfWord-startOfWord-2);
|
||||
Poincare::Expression expr = Poincare::Expression::Parse(word, nullptr);
|
||||
if (expr.isUninitialized()) {
|
||||
expr = Poincare::Undefined::Builder();
|
||||
|
||||
if (*startOfWord == '$') { // Look for expression
|
||||
endOfWord = startOfWord + 1;
|
||||
while (*endOfWord != '$') {
|
||||
if (endOfWord > endOfFile) {
|
||||
break; // If we are here, it's bad...
|
||||
}
|
||||
endOfWord ++;
|
||||
}
|
||||
layout = Shared::PoincareHelpers::CreateLayout(expr);
|
||||
endOfWord ++;
|
||||
|
||||
TexParser parser = TexParser(startOfWord + 1, endOfWord - 1);
|
||||
layout = parser.getLayout();
|
||||
textSize = layout.layoutSize();
|
||||
toDraw = ToDraw::Expression;
|
||||
}
|
||||
else {
|
||||
if (*startOfWord == '\\' || *(startOfWord + 1) == '$') {
|
||||
startOfWord ++;
|
||||
}
|
||||
textSize = m_font->stringSizeUntil(startOfWord, endOfWord);
|
||||
stringNCopy(word, wordMaxLength, startOfWord, endOfWord-startOfWord);
|
||||
toDraw = ToDraw::Text;
|
||||
@@ -222,7 +245,10 @@ void WordWrapTextView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
}
|
||||
|
||||
textPosition = nextTextPosition;
|
||||
endOfWord = EndOfPrintableWord(startOfWord+1, endOfFile);
|
||||
|
||||
if (*startOfWord != '$') {
|
||||
endOfWord = EndOfPrintableWord(startOfWord+1, endOfFile);
|
||||
} // Else we don't need to update endOfWord
|
||||
}
|
||||
|
||||
m_nextPageOffset = startOfWord - text();
|
||||
|
||||
2
apps/rpn
2
apps/rpn
Submodule apps/rpn updated: b51172c32f...67d66295b0
@@ -21,9 +21,7 @@ constexpr SettingsMessageTree s_accessibilityChildren[6] = {SettingsMessageTree(
|
||||
constexpr SettingsMessageTree s_contributorsChildren[23] = {SettingsMessageTree(I18n::Message::Developers), SettingsMessageTree(I18n::Message::QuentinGuidee), SettingsMessageTree(I18n::Message::JoachimLeFournis), SettingsMessageTree(I18n::Message::MaximeFriess), SettingsMessageTree(I18n::Message::JeanBaptisteBoric), SettingsMessageTree(I18n::Message::SandraSimmons), SettingsMessageTree(I18n::Message::David), SettingsMessageTree(I18n::Message::DamienNicolet), SettingsMessageTree(I18n::Message::EvannDreumont), SettingsMessageTree(I18n::Message::SzaboLevente), SettingsMessageTree(I18n::Message::VenceslasDuet), SettingsMessageTree(I18n::Message::CharlotteThomas), SettingsMessageTree(I18n::Message::AntoninLoubiere), SettingsMessageTree(I18n::Message::CyprienMejat), SettingsMessageTree(I18n::Message::BetaTesters), SettingsMessageTree(I18n::Message::TimeoArnouts), SettingsMessageTree(I18n::Message::JulieC), SettingsMessageTree(I18n::Message::LelahelHideux), SettingsMessageTree(I18n::Message::Madil), SettingsMessageTree(I18n::Message::HilaireLeRoux), SettingsMessageTree(I18n::Message::HectorNussbaumer), SettingsMessageTree(I18n::Message::RaphaelDyda), SettingsMessageTree(I18n::Message::ThibautC)};
|
||||
|
||||
// Code Settings
|
||||
#ifdef HAS_CODE
|
||||
constexpr SettingsMessageTree s_codeChildren[2] = {SettingsMessageTree(I18n::Message::FontSizes, s_modelFontChildren), SettingsMessageTree(I18n::Message::Autocomplete)};
|
||||
#endif
|
||||
constexpr SettingsMessageTree s_modelFontChildren[2] = {SettingsMessageTree(I18n::Message::LargeFont), SettingsMessageTree(I18n::Message::SmallFont)};
|
||||
|
||||
|
||||
|
||||
@@ -13,9 +13,7 @@ constexpr SettingsMessageTree s_modelMenu[] =
|
||||
SettingsMessageTree(I18n::Message::Language),
|
||||
SettingsMessageTree(I18n::Message::Country),
|
||||
SettingsMessageTree(I18n::Message::ExamMode, ExamModeConfiguration::s_modelExamChildren),
|
||||
#ifdef HAS_CODE
|
||||
SettingsMessageTree(I18n::Message::CodeApp, s_codeChildren),
|
||||
#endif
|
||||
SettingsMessageTree(I18n::Message::BetaPopUp),
|
||||
SettingsMessageTree(I18n::Message::About, s_modelAboutChildren),
|
||||
SettingsMessageTree(I18n::Message::Accessibility, s_accessibilityChildren)};
|
||||
|
||||
@@ -13,9 +13,7 @@ constexpr SettingsMessageTree s_modelMenu[] =
|
||||
SettingsMessageTree(I18n::Message::Language),
|
||||
SettingsMessageTree(I18n::Message::Country),
|
||||
SettingsMessageTree(I18n::Message::ExamMode, ExamModeConfiguration::s_modelExamChildren),
|
||||
#ifdef HAS_CODE
|
||||
SettingsMessageTree(I18n::Message::CodeApp, s_codeChildren),
|
||||
#endif
|
||||
SettingsMessageTree(I18n::Message::Accessibility, s_accessibilityChildren),
|
||||
SettingsMessageTree(I18n::Message::About, s_modelAboutChildren)};
|
||||
|
||||
|
||||
@@ -13,9 +13,8 @@ constexpr SettingsMessageTree s_modelMenu[] =
|
||||
SettingsMessageTree(I18n::Message::Language),
|
||||
SettingsMessageTree(I18n::Message::Country),
|
||||
SettingsMessageTree(I18n::Message::ExamMode, ExamModeConfiguration::s_modelExamChildren),
|
||||
#ifdef HAS_CODE
|
||||
SettingsMessageTree(I18n::Message::CodeApp, s_codeChildren),
|
||||
#endif SettingsMessageTree(I18n::Message::UpdatePopUp),
|
||||
SettingsMessageTree(I18n::Message::UpdatePopUp),
|
||||
SettingsMessageTree(I18n::Message::Accessibility, s_accessibilityChildren),
|
||||
SettingsMessageTree(I18n::Message::About, s_modelAboutChildren)};
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ bool AccessibilityController::handleEvent(Ion::Events::Event event) {
|
||||
int redGamma, greenGamma, blueGamma;
|
||||
KDIonContext::sharedContext()->gamma.gamma(redGamma, greenGamma, blueGamma);
|
||||
|
||||
if ((event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) && (selectedRow() <= 2)) {
|
||||
if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) {
|
||||
if (selectedRow() == 0) {
|
||||
invertEnabled = !invertEnabled;
|
||||
}
|
||||
|
||||
@@ -10,8 +10,12 @@ CodeOptionsController::CodeOptionsController(Responder * parentResponder) :
|
||||
GenericSubController(parentResponder),
|
||||
m_preferencesController(this)
|
||||
{
|
||||
m_chevronCell.setMessageFont(KDFont::LargeFont);
|
||||
m_switchCell.setMessageFont(KDFont::LargeFont);
|
||||
for (int i = 0; i < k_totalNumberOfCell; i++) {
|
||||
m_cells[i].setMessageFont(KDFont::LargeFont);
|
||||
}
|
||||
for (int i = 0; i < k_totalNumberOfSwitchCells; i++) {
|
||||
m_switchCells[i].setMessageFont(KDFont::LargeFont);
|
||||
}
|
||||
}
|
||||
|
||||
bool CodeOptionsController::handleEvent(Ion::Events::Event event) {
|
||||
@@ -40,10 +44,7 @@ bool CodeOptionsController::handleEvent(Ion::Events::Event event) {
|
||||
HighlightCell * CodeOptionsController::reusableCell(int index, int type) {
|
||||
assert(type == 0);
|
||||
assert(index >= 0 && index < k_totalNumberOfCell);
|
||||
if (index == 0) {
|
||||
return &m_chevronCell;
|
||||
}
|
||||
return &m_switchCell;
|
||||
return &m_cells[index];
|
||||
}
|
||||
|
||||
int CodeOptionsController::reusableCellCount(int type) {
|
||||
@@ -61,14 +62,11 @@ void CodeOptionsController::willDisplayCellForIndex(HighlightCell * cell, int in
|
||||
GlobalPreferences::sharedGlobalPreferences()->font() == KDFont::LargeFont
|
||||
? myTextCell->setSubtitle(I18n::Message::LargeFont)
|
||||
: myTextCell->setSubtitle(I18n::Message::SmallFont);
|
||||
}
|
||||
#ifdef HAS_CODE
|
||||
else if (thisLabel == I18n::Message::Autocomplete) {
|
||||
} else if (thisLabel == I18n::Message::Autocomplete) {
|
||||
MessageTableCellWithSwitch * mySwitchCell = (MessageTableCellWithSwitch *)cell;
|
||||
SwitchView * mySwitch = (SwitchView *)mySwitchCell->accessoryView();
|
||||
mySwitch->setState(GlobalPreferences::sharedGlobalPreferences()->autocomplete());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,10 +14,11 @@ public:
|
||||
int reusableCellCount(int type) override;
|
||||
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
|
||||
private:
|
||||
constexpr static int k_totalNumberOfCell = 2;
|
||||
constexpr static int k_totalNumberOfCell = 1;
|
||||
constexpr static int k_totalNumberOfSwitchCells = 1;
|
||||
PreferencesController m_preferencesController;
|
||||
MessageTableCellWithChevronAndMessage m_chevronCell;
|
||||
MessageTableCellWithSwitch m_switchCell;
|
||||
MessageTableCellWithChevronAndMessage m_cells[k_totalNumberOfCell];
|
||||
MessageTableCellWithSwitch m_switchCells[k_totalNumberOfCell];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -24,13 +24,13 @@ void AbstractScrollableMultipleExpressionsView::ContentCell::setHighlighted(bool
|
||||
// Do not call HighlightCell::setHighlighted to avoid marking all cell as dirty
|
||||
m_highlighted = highlight;
|
||||
KDColor defaultColor = backgroundColor();
|
||||
KDColor color = highlight && m_selectedSubviewPosition == SubviewPosition::Center ? Palette::Select : defaultColor;
|
||||
KDColor color = highlight && m_selectedSubviewPosition == SubviewPosition::Center ? Palette::ExpressionInputBackground : defaultColor;
|
||||
m_centeredExpressionView.setBackgroundColor(color);
|
||||
color = highlight && m_selectedSubviewPosition == SubviewPosition::Right ? Palette::Select : defaultColor;
|
||||
color = highlight && m_selectedSubviewPosition == SubviewPosition::Right ? Palette::ExpressionInputBackground : defaultColor;
|
||||
m_rightExpressionView.setBackgroundColor(color);
|
||||
m_approximateSign.setBackgroundColor(defaultColor);
|
||||
if (leftExpressionView()) {
|
||||
color = highlight && m_selectedSubviewPosition == SubviewPosition::Left ? Palette::Select : defaultColor;
|
||||
color = highlight && m_selectedSubviewPosition == SubviewPosition::Left ? Palette::ExpressionInputBackground : defaultColor;
|
||||
leftExpressionView()->setBackgroundColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@ EPSILON_VERSION ?= 15.5.0
|
||||
OMEGA_VERSION ?= 1.22.1
|
||||
# OMEGA_USERNAME ?= N/A
|
||||
OMEGA_STATE ?= public
|
||||
EPSILON_APPS ?= geometry calculation rpn graph code statistics probability solver atomic sequence regression reader settings external
|
||||
EPSILON_APPS ?= calculation rpn graph code statistics probability solver atomic sequence regression reader settings external
|
||||
SUBMODULES_APPS = atomic rpn
|
||||
EPSILON_I18N ?= en fr nl pt it de es hu
|
||||
EPSILON_COUNTRIES ?= WW CA DE ES FR GB IT NL PT US
|
||||
EPSILON_GETOPT ?= 0
|
||||
ESCHER_LOG_EVENTS_BINARY ?= 0
|
||||
THEME_NAME ?= upsilon_light
|
||||
THEME_NAME ?= omega_light
|
||||
THEME_REPO ?= local
|
||||
INCLUDE_ULAB ?= 1
|
||||
|
||||
@@ -45,6 +45,7 @@ $(BUILD_DIR)/flasher.verbose.$(EXE): $(call flavored_object_for,$(flasher_src),u
|
||||
$(BUILD_DIR)/flasher.verbose.flash.$(EXE): $(call flavored_object_for,$(flasher_src))
|
||||
$(BUILD_DIR)/flasher.%.$(EXE): LDFLAGS += -Lion/src/$(PLATFORM)/flasher
|
||||
$(BUILD_DIR)/flasher.%.$(EXE): LDSCRIPT = ion/src/$(PLATFORM)/shared/ram.ld
|
||||
$(BUILD_DIR)/flasher.%.$(EXE): RASTERIZER_CFLAGS += -DISBUILDINGFLASHER
|
||||
$(BUILD_DIR)/flasher.%.flash.$(EXE): LDSCRIPT = ion/src/$(PLATFORM)/$(MODEL)/internal_flash.ld
|
||||
|
||||
#TODO Do not build all apps... Put elsewhere?
|
||||
|
||||
@@ -20,7 +20,6 @@ public:
|
||||
virtual void scrollToCell(int i, int j);
|
||||
HighlightCell * cellAtLocation(int i, int j);
|
||||
void reloadCellAtLocation(int i, int j);
|
||||
void reloadVisibleCells();
|
||||
protected:
|
||||
#if ESCHER_VIEW_LOGGING
|
||||
const char * className() const override;
|
||||
@@ -35,7 +34,6 @@ protected:
|
||||
void setHorizontalCellOverlap(KDCoordinate o) { m_horizontalCellOverlap = o; }
|
||||
void setVerticalCellOverlap(KDCoordinate o) { m_verticalCellOverlap = o; }
|
||||
|
||||
void reloadVisibleCells();
|
||||
void reloadCellAtLocation(int i, int j);
|
||||
HighlightCell * cellAtLocation(int i, int j);
|
||||
TableViewDataSource * dataSource();
|
||||
|
||||
@@ -30,7 +30,7 @@ void ModalViewEmptyController::ModalViewEmptyView::setMessages(I18n::Message * m
|
||||
|
||||
void ModalViewEmptyController::ModalViewEmptyView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
ctx->fillRect(bounds(), k_backgroundColor);
|
||||
drawBorderOfRect(ctx, bounds(), Palette::ListCellBorder);
|
||||
drawBorderOfRect(ctx, bounds(), Palette::GrayBright);
|
||||
}
|
||||
|
||||
int ModalViewEmptyController::ModalViewEmptyView::numberOfSubviews() const {
|
||||
|
||||
@@ -47,7 +47,7 @@ void TableView::layoutSubviews(bool force) {
|
||||
* otherwise the table's size might be miscomputed...
|
||||
* FIXME:
|
||||
* Finally, this solution is not optimal at all since
|
||||
* layoutSubviews is called twice over m_contentView. */
|
||||
* layoutSubviews is called twice over m_contentView. */
|
||||
m_contentView.layoutSubviews(force);
|
||||
ScrollView::layoutSubviews(force);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
BasicInfo:
|
||||
Title : Upsilon
|
||||
Title : Omega
|
||||
CompanyCode : "00"
|
||||
ProductCode : CTR-E-Upsilon
|
||||
ProductCode : CTR-E-OMEGA
|
||||
Logo : Homebrew # Nintendo / Licensed / Distributed / iQue / iQueForSystem
|
||||
|
||||
RomFs:
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>Epsilon</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>io.github.upsilon.simulator</string>
|
||||
<string>io.github.omega.simulator</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
|
||||
@@ -16,7 +16,7 @@ static char* pref_path = nullptr;
|
||||
static char* file_buffer = nullptr;
|
||||
|
||||
void loadPython(Args * arguments) {
|
||||
pref_path = SDL_GetPrefPath("io.github.upsilon", "upsilon-simulator");
|
||||
pref_path = SDL_GetPrefPath("io.github.omega", "omega-simulator");
|
||||
std::string path(pref_path);
|
||||
printf("Loading from %s\n", (path + "python.dat").c_str());
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ void init(bool screen_only, bool fullscreen, bool unresizable) {
|
||||
if (screen_only) {
|
||||
sScreenOnly = true;
|
||||
sWindow = SDL_CreateWindow(
|
||||
"Upsilon",
|
||||
"Omega",
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
Ion::Display::Width, Ion::Display::Height,
|
||||
@@ -48,7 +48,7 @@ void init(bool screen_only, bool fullscreen, bool unresizable) {
|
||||
);
|
||||
} else {
|
||||
sWindow = SDL_CreateWindow(
|
||||
"Upsilon",
|
||||
"Omega",
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
458, 888,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Upsilon</title>
|
||||
<title>Omega</title>
|
||||
<style>
|
||||
#include "calculator.css"
|
||||
#include "simulator.css"
|
||||
|
||||
@@ -32,7 +32,15 @@ tests_src += $(addprefix kandinsky/test/,\
|
||||
rect.cpp\
|
||||
)
|
||||
|
||||
code_points = kandinsky/fonts/code_points.h
|
||||
ifdef ($(ISBUILDINGFLASHER))
|
||||
code_points = kandinsky/fonts/code_points.h
|
||||
else
|
||||
ifdef ($(HAS_READER))
|
||||
code_points = kandinsky/fonts/code_points_latex.h
|
||||
else
|
||||
code_points = kandinsky/fonts/code_points.h
|
||||
endif
|
||||
endif
|
||||
|
||||
RASTERIZER_CFLAGS := -std=c99 $(shell pkg-config freetype2 --cflags)
|
||||
RASTERIZER_LDFLAGS := $(shell pkg-config freetype2 --libs)
|
||||
|
||||
212
kandinsky/fonts/code_points_latex.h
Normal file
212
kandinsky/fonts/code_points_latex.h
Normal file
@@ -0,0 +1,212 @@
|
||||
#ifndef KANDINSKY_FONTS_CODE_POINTS_H
|
||||
#define KANDINSKY_FONTS_CODE_POINTS_H
|
||||
|
||||
// [0x30a].map{|i| "0x" + i.to_s(16) +", // " + [i].pack("U") + " // " + Unicode::Name.of([i].pack("U"))}.join("|")
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
/* This array lists the code points that are rasterized by rasterizer.c. We put
|
||||
* most characters from the LATIN charset, and some mathematical characters. */
|
||||
|
||||
uint32_t CodePoints[] = {
|
||||
0x20, // // SPACE
|
||||
0x21, // ! // EXCLAMATION MARK
|
||||
0x22, // " // QUOTATION MARK
|
||||
0x23, // # // NUMBER SIGN
|
||||
0x24, // $ // DOLLAR SIGN
|
||||
0x25, // % // PERCENT SIGN
|
||||
0x26, // & // AMPERSAND
|
||||
0x27, // ' // APOSTROPHE
|
||||
0x28, // ( // LEFT PARENTHESIS
|
||||
0x29, // ) // RIGHT PARENTHESIS
|
||||
0x2a, // * // ASTERISK
|
||||
0x2b, // + // PLUS SIGN
|
||||
0x2c, // , // COMMA
|
||||
0x2d, // - // HYPHEN-MINUS
|
||||
0x2e, // . // FULL STOP
|
||||
0x2f, // / // SOLIDUS
|
||||
0x30, // 0 // DIGIT ZERO
|
||||
0x31, // 1 // DIGIT ONE
|
||||
0x32, // 2 // DIGIT TWO
|
||||
0x33, // 3 // DIGIT THREE
|
||||
0x34, // 4 // DIGIT FOUR
|
||||
0x35, // 5 // DIGIT FIVE
|
||||
0x36, // 6 // DIGIT SIX
|
||||
0x37, // 7 // DIGIT SEVEN
|
||||
0x38, // 8 // DIGIT EIGHT
|
||||
0x39, // 9 // DIGIT NINE
|
||||
0x3a, // : // COLON
|
||||
0x3b, // ; // SEMICOLON
|
||||
0x3c, // < // LESS-THAN SIGN
|
||||
0x3d, // = // EQUALS SIGN
|
||||
0x3e, // > // GREATER-THAN SIGN
|
||||
0x3f, // ? // QUESTION MARK
|
||||
0x40, // @ // COMMERCIAL AT
|
||||
0x41, // A // LATIN CAPITAL LETTER A
|
||||
0x42, // B // LATIN CAPITAL LETTER B
|
||||
0x43, // C // LATIN CAPITAL LETTER C
|
||||
0x44, // D // LATIN CAPITAL LETTER D
|
||||
0x45, // E // LATIN CAPITAL LETTER E
|
||||
0x46, // F // LATIN CAPITAL LETTER F
|
||||
0x47, // G // LATIN CAPITAL LETTER G
|
||||
0x48, // H // LATIN CAPITAL LETTER H
|
||||
0x49, // I // LATIN CAPITAL LETTER I
|
||||
0x4a, // J // LATIN CAPITAL LETTER J
|
||||
0x4b, // K // LATIN CAPITAL LETTER K
|
||||
0x4c, // L // LATIN CAPITAL LETTER L
|
||||
0x4d, // M // LATIN CAPITAL LETTER M
|
||||
0x4e, // N // LATIN CAPITAL LETTER N
|
||||
0x4f, // O // LATIN CAPITAL LETTER O
|
||||
0x50, // P // LATIN CAPITAL LETTER P
|
||||
0x51, // Q // LATIN CAPITAL LETTER Q
|
||||
0x52, // R // LATIN CAPITAL LETTER R
|
||||
0x53, // S // LATIN CAPITAL LETTER S
|
||||
0x54, // T // LATIN CAPITAL LETTER T
|
||||
0x55, // U // LATIN CAPITAL LETTER U
|
||||
0x56, // V // LATIN CAPITAL LETTER V
|
||||
0x57, // W // LATIN CAPITAL LETTER W
|
||||
0x58, // X // LATIN CAPITAL LETTER X
|
||||
0x59, // Y // LATIN CAPITAL LETTER Y
|
||||
0x5a, // Z // LATIN CAPITAL LETTER Z
|
||||
0x5b, // [ // LEFT SQUARE BRACKET
|
||||
0x5c, // \ // REVERSE SOLIDUS
|
||||
0x5d, // ] // RIGHT SQUARE BRACKET
|
||||
0x5e, // ^ // CIRCUMFLEX ACCENT
|
||||
0x5f, // _ // LOW LINE
|
||||
0x60, // ` // GRAVE ACCENT
|
||||
0x61, // a // LATIN SMALL LETTER A
|
||||
0x62, // b // LATIN SMALL LETTER B
|
||||
0x63, // c // LATIN SMALL LETTER C
|
||||
0x64, // d // LATIN SMALL LETTER D
|
||||
0x65, // e // LATIN SMALL LETTER E
|
||||
0x66, // f // LATIN SMALL LETTER F
|
||||
0x67, // g // LATIN SMALL LETTER G
|
||||
0x68, // h // LATIN SMALL LETTER H
|
||||
0x69, // i // LATIN SMALL LETTER I
|
||||
0x6a, // j // LATIN SMALL LETTER J
|
||||
0x6b, // k // LATIN SMALL LETTER K
|
||||
0x6c, // l // LATIN SMALL LETTER L
|
||||
0x6d, // m // LATIN SMALL LETTER M
|
||||
0x6e, // n // LATIN SMALL LETTER N
|
||||
0x6f, // o // LATIN SMALL LETTER O
|
||||
0x70, // p // LATIN SMALL LETTER P
|
||||
0x71, // q // LATIN SMALL LETTER Q
|
||||
0x72, // r // LATIN SMALL LETTER R
|
||||
0x73, // s // LATIN SMALL LETTER S
|
||||
0x74, // t // LATIN SMALL LETTER T
|
||||
0x75, // u // LATIN SMALL LETTER U
|
||||
0x76, // v // LATIN SMALL LETTER V
|
||||
0x77, // w // LATIN SMALL LETTER W
|
||||
0x78, // x // LATIN SMALL LETTER X
|
||||
0x79, // y // LATIN SMALL LETTER Y
|
||||
0x7a, // z // LATIN SMALL LETTER Z
|
||||
0x7b, // { // LEFT CURLY BRACKET
|
||||
0x7c, // | // VERTICAL LINE
|
||||
0x7d, // } // RIGHT CURLY BRACKET
|
||||
0x7e, // ~ // TILDE
|
||||
|
||||
0xb0, // ° // DEGREE SIGN
|
||||
0xb1, // ± // PLUS OR MINUS
|
||||
0xb7, // · // MIDDLE DOT
|
||||
|
||||
0xc6, // Æ // LATIN CAPITAL LETTER AE
|
||||
0xd0, // Ð // LATIN CAPITAL LETTER ETH
|
||||
0xd7, // × // MULTIPLICATION SIGN
|
||||
0xd8, // Ø // LATIN CAPITAL LETTER O WITH STROKE
|
||||
0xde, // Þ // LATIN CAPITAL LETTER THORN
|
||||
0xdf, // ß // LATIN SMALL LETTER SHARP S
|
||||
0xe6, // æ // LATIN SMALL LETTER AE
|
||||
0xf0, // ð // LATIN SMALL LETTER ETH
|
||||
0xf7, // ÷ // DIVISION SIGN
|
||||
0xf8, // ø // LATIN SMALL LETTER O WITH STROKE
|
||||
0xfe, // þ // LATIN SMALL LETTER THORN
|
||||
|
||||
0x300, // ̀ // COMBINING GRAVE ACCENT
|
||||
0x301, // ́ // COMBINING ACUTE ACCENT
|
||||
0x302, // ̂ // COMBINING CIRCUMFLEX ACCENT
|
||||
0x303, // ̃ // COMBINING TILDE
|
||||
0x305, // ̅ // COMBINING OVERLINE
|
||||
0x308, // ̈ // COMBINING DIAERESIS
|
||||
0x30a, // ̊ // COMBINING RING ABOVE
|
||||
0x30b, // ˝// COMBINING DOUBLE ACUTE ACCENT
|
||||
0x327, // ̧ // COMBINING CEDILLA
|
||||
|
||||
0x391, // Α // GREEK CAPITAL LETTER ALPHA
|
||||
0x392, // Β // GREEK CAPITAL LETTER BETA
|
||||
0x393, // Γ // GREEK CAPITAL LETTER GAMMA
|
||||
0x394, // Δ // GREEK CAPITAL LETTER DELTA
|
||||
0x395, // Ε // GREEK CAPITAL LETTER EPSILON
|
||||
0x396, // Ζ // GREEK CAPITAL LETTER ZETA
|
||||
0x397, // Η // GREEK CAPITAL LETTER ETA
|
||||
0x398, // Θ // GREEK CAPITAL LETTER THETA
|
||||
0x399, // Ι // GREEK CAPITAL LETTER IOTA
|
||||
0x39a, // Κ // GREEK CAPITAL LETTER KAPPA
|
||||
0x39b, // Λ // GREEK CAPITAL LETTER LAMBDA
|
||||
0x39c, // Μ // GREEK CAPITAL LETTER MU
|
||||
0x39d, // Ν // GREEK CAPITAL LETTER NU
|
||||
0x39e, // Ξ // GREEK CAPITAL LETTER KSI
|
||||
0x39f, // Ο // GREEK CAPITAL LETTER OMICRON
|
||||
0x3a0, // Π // GREEK CAPITAL LETTER PI
|
||||
0x3a1, // Ρ // GREEK CAPITAL LETTER RHO
|
||||
0x3a3, // Σ // GREEK CAPITAL LETTER SIGMA
|
||||
0x3a4, // Τ // GREEK CAPITAL LETTER TAU
|
||||
0x3a5, // Υ // GREEK CAPITAL LETTER UPSILON
|
||||
0x3a6, // Φ // GREEK CAPITAL LETTER PHI
|
||||
0x3a7, // Χ // GREEK CAPITAL LETTER KHI
|
||||
0x3a8, // Ψ // GREEK CAPITAL LETTER PSI
|
||||
0x3a9, // Ω // GREEK CAPITAL LETTER OMEGA
|
||||
0x3b1, // α // GREEK SMALL LETTER ALPHA
|
||||
0x3b2, // β // GREEK SMALL LETTER BETA
|
||||
0x3b3, // γ // GREEK SMALL LETTER GAMMA
|
||||
0x3b4, // δ // GREEK SMALL LETTER DELTA
|
||||
0x3b5, // ε // GREEK SMALL LETTER EPSILON
|
||||
0x3b6, // ζ // GREEK SMALL LETTER ZETA
|
||||
0x3b7, // η // GREEK SMALL LETTER ETA
|
||||
0x3b8, // θ // GREEK SMALL LETTER THETA
|
||||
0x3b9, // ι // GREEK SMALL LETTER IOTA
|
||||
0x3ba, // κ // GREEK SMALL LETTER KAPPA
|
||||
0x3bb, // λ // GREEK SMALL LETTER LAMBDA
|
||||
0x3bc, // μ // GREEK SMALL LETTER MU
|
||||
0x3bd, // ν // GREEK SMALL LETTER NU
|
||||
0x3be, // ξ // GREEK SMALL LETTER KSI
|
||||
0x3bf, // ο // GREEK SMALL LETTER OMICRON
|
||||
0x3c0, // π // GREEK SMALL LETTER PI
|
||||
0x3c1, // ρ // GREEK SMALL LETTER RHO
|
||||
0x3c3, // σ // GREEK SMALL LETTER SIGMA
|
||||
0x3c4, // τ // GREEK SMALL LETTER TAU
|
||||
0x3c5, // υ // GREEK SMALL LETTER UPSILON
|
||||
0x3c6, // φ // GREEK SMALL LETTER PHI
|
||||
0x3c7, // χ // GREEK SMALL LETTER KHI
|
||||
0x3c8, // ψ // GREEK SMALL LETTER PSI
|
||||
0x3c9, // ω // GREEK SMALL LETTER OMEGA
|
||||
0x1d07, // ᴇ // LATIN LETTER SMALL CAPITAL E
|
||||
0x212f, // ℯ // SCRIPT SMALL E
|
||||
0x2190, // ← // BACKWARD ARROW (leftarrow)
|
||||
0x2191, // ↑ // TOP ARROW (uparrow)
|
||||
0x2192, // → // FORWARD ARROW (rightarrow)
|
||||
0x2193, // ↓ // BOTTOM ARROW (downarrow)
|
||||
0x2194, // ↔ // BACKWARD FORWARD ARROW (leftrightarrow)
|
||||
0x2195, // ↕ // TOP BOTTOM ARROW (updownarrow)
|
||||
0x21d0, // ⇐ // DOUBLE BACKWARD ARROW (Leftarrow)
|
||||
0x21d1, // ⇑ // DOUBLE TOP ARROW (Uparrow)
|
||||
0x21d2, // ⇒ // DOUBLE FORWARD ARROW (Rightarrow)
|
||||
0x21d3, // ⇓ // DOUBLE BOTTOM ARROW (Downarrow)
|
||||
0x2200, // ∀ // FORALL
|
||||
0x2202, // ∂ // PARTIAL
|
||||
0x2203, // ∃ // EXIST
|
||||
0x2211, // ∑ // N-ARY SUMMATION
|
||||
0x221a, // √ // SQUARE ROOT
|
||||
0x221e, // ∞ // INFINITY
|
||||
0x222b, // ∫ // INTEGRAL
|
||||
0x2248, // ≈ // ALMOST EQUAL TO
|
||||
0x2260, // ≠ // NOT EQUAL TO
|
||||
0x2261, // ≡ // IS CONGRUENT TO
|
||||
0x2264, // ≤ // LESS-THAN OR EQUAL TO
|
||||
0x2265, // ≥ // GREATER-THAN OR EQUAL TO
|
||||
0xFFFD, // <20> // REPLACEMENT CHARACTER
|
||||
0x1d422, // 𝐢 // MATHEMATICAL BOLD SMALL I"
|
||||
};
|
||||
|
||||
int NumberOfCodePoints = sizeof(CodePoints)/sizeof(CodePoints[0]);
|
||||
|
||||
#endif
|
||||
@@ -15,7 +15,11 @@
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#ifdef ISBUILDINGFLASHER
|
||||
#include "code_points.h"
|
||||
#else
|
||||
#include "code_points_latex.h"
|
||||
#endif
|
||||
#include "../../ion/src/external/lz4/lz4hc.h"
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ poincare_src += $(addprefix poincare/src/,\
|
||||
right_square_bracket_layout.cpp \
|
||||
sequence_layout.cpp \
|
||||
sum_layout.cpp \
|
||||
vector_layout.cpp \
|
||||
vertical_offset_layout.cpp \
|
||||
)
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ class LayoutCursor final {
|
||||
friend class MatrixLayoutNode;
|
||||
friend class NthRootLayoutNode;
|
||||
friend class SequenceLayoutNode;
|
||||
friend class VectorLayoutNode;
|
||||
friend class VerticalOffsetLayoutNode;
|
||||
public:
|
||||
constexpr static KDCoordinate k_cursorWidth = 1;
|
||||
|
||||
@@ -40,6 +40,7 @@ public:
|
||||
RightParenthesisLayout,
|
||||
RightSquareBracketLayout,
|
||||
SumLayout,
|
||||
VectorLayout,
|
||||
VectorNormLayout,
|
||||
VerticalOffsetLayout
|
||||
};
|
||||
|
||||
53
poincare/include/poincare/vector_layout.h
Normal file
53
poincare/include/poincare/vector_layout.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef POINCARE_VECTOR_LAYOUT_NODE_H
|
||||
#define POINCARE_VECTOR_LAYOUT_NODE_H
|
||||
|
||||
#include <poincare/layout.h>
|
||||
#include <poincare/layout_cursor.h>
|
||||
#include <poincare/serialization_helper.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class VectorLayoutNode final : public LayoutNode {
|
||||
public:
|
||||
// Layout
|
||||
Type type() const override { return Type::VectorLayout; }
|
||||
|
||||
// SerializationHelperInterface
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "vector", true, 0);
|
||||
}
|
||||
|
||||
virtual void moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout, bool forSelection = false);
|
||||
virtual void moveCursorRight(LayoutCursor * cursor, bool * shouldRecomputeLayout, bool forSelection = false);
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(VectorLayoutNode); }
|
||||
int numberOfChildren() const override { return 1; }
|
||||
#if POINCARE_TREE_LOG
|
||||
void logNodeName(std::ostream & stream) const override {
|
||||
stream << "VectorLayout";
|
||||
}
|
||||
#endif
|
||||
|
||||
constexpr static KDCoordinate k_arrowWidth = 5;
|
||||
constexpr static KDCoordinate k_arrowHeight = 9;
|
||||
protected:
|
||||
virtual KDSize computeSize();
|
||||
virtual KDCoordinate computeBaseline();
|
||||
virtual KDPoint positionOfChild(LayoutNode * child);
|
||||
private:
|
||||
virtual void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor, Layout * selectionStart = nullptr, Layout * selectionEnd = nullptr, KDColor selectionColor = KDColorRed);
|
||||
constexpr static KDCoordinate k_sideMargin = 2;
|
||||
constexpr static KDCoordinate k_topMargin = 1;
|
||||
constexpr static KDCoordinate k_arrowLineHeight = 1; // k_arrowHeight - k_arrowLineHeight must be even
|
||||
};
|
||||
|
||||
class VectorLayout final : public Layout {
|
||||
public:
|
||||
static VectorLayout Builder(Layout child) { return TreeHandle::FixedArityBuilder<VectorLayout, VectorLayoutNode>({child}); }
|
||||
VectorLayout() = delete;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <poincare/right_square_bracket_layout.h>
|
||||
#include <poincare/square_bracket_layout.h>
|
||||
#include <poincare/sum_layout.h>
|
||||
#include <poincare/vector_layout.h>
|
||||
#include <poincare/vector_norm_layout.h>
|
||||
#include <poincare/vertical_offset_layout.h>
|
||||
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
#include <poincare/tree_handle.h>
|
||||
#include <poincare_nodes.h>
|
||||
#include <apps/geometry/figures/figures.h>
|
||||
#include <poincare_layouts.h>
|
||||
#include <poincare/ghost.h>
|
||||
|
||||
using namespace Geometry;
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
/* Clone */
|
||||
@@ -378,9 +375,7 @@ template VectorCross TreeHandle::FixedArityBuilder<VectorCross, VectorCrossNode>
|
||||
template VectorDot TreeHandle::FixedArityBuilder<VectorDot, VectorDotNode>(const Tuple &);
|
||||
template VectorNorm TreeHandle::FixedArityBuilder<VectorNorm, VectorNormNode>(const Tuple &);
|
||||
template VectorNormLayout TreeHandle::FixedArityBuilder<VectorNormLayout, VectorNormLayoutNode>(const Tuple &);
|
||||
template VectorLayout TreeHandle::FixedArityBuilder<VectorLayout, VectorLayoutNode>(const Tuple &);
|
||||
template MatrixLayout TreeHandle::NAryBuilder<MatrixLayout, MatrixLayoutNode>(const Tuple &);
|
||||
|
||||
// Geometry templates
|
||||
template PointByCoordinates TreeHandle::FixedArityBuilder<PointByCoordinates, PointByCoordinatesNode>(const Tuple &);
|
||||
|
||||
}
|
||||
|
||||
78
poincare/src/vector_layout.cpp
Normal file
78
poincare/src/vector_layout.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include <poincare/vector_layout.h>
|
||||
|
||||
namespace Poincare
|
||||
{
|
||||
const uint8_t arrowMask[VectorLayoutNode::k_arrowHeight][VectorLayoutNode::k_arrowWidth] = {
|
||||
{0xff, 0xf7, 0xff, 0xff, 0xff},
|
||||
{0xf3, 0x2c, 0xd9, 0xff, 0xff},
|
||||
{0xff, 0x93, 0x46, 0xfb, 0xff},
|
||||
{0xff, 0xfb, 0x46, 0x93, 0xff},
|
||||
{0x13, 0x13, 0x13, 0x13, 0xf0},
|
||||
{0xff, 0xfb, 0x46, 0x93, 0xff},
|
||||
{0xff, 0x93, 0x46, 0xfb, 0xff},
|
||||
{0xf3, 0x2c, 0xd9, 0xff, 0xff},
|
||||
{0xff, 0xf7, 0xff, 0xff, 0xff}
|
||||
};
|
||||
void VectorLayoutNode::moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout, bool forSelection) {
|
||||
if (cursor->layoutNode() == childAtIndex(0)
|
||||
&& cursor->position() == LayoutCursor::Position::Left)
|
||||
{
|
||||
// Case: Left of the operand. Go Left of the brackets.
|
||||
cursor->setLayout(this);
|
||||
return;
|
||||
}
|
||||
assert(cursor->layoutNode() == this);
|
||||
if (cursor->position() == LayoutCursor::Position::Right) {
|
||||
// Case: Right of the brackets. Go Right of the operand.
|
||||
cursor->setLayout(childAtIndex(0));
|
||||
return;
|
||||
}
|
||||
assert(cursor->position() == LayoutCursor::Position::Left);
|
||||
// Case: Left of the brackets. Ask the parent.
|
||||
LayoutNode * parentNode = parent();
|
||||
if (parentNode != nullptr) {
|
||||
parentNode->moveCursorLeft(cursor, shouldRecomputeLayout);
|
||||
}
|
||||
}
|
||||
|
||||
void VectorLayoutNode::moveCursorRight(LayoutCursor * cursor, bool * shouldRecomputeLayout, bool forSelection) {
|
||||
if (cursor->layoutNode() == childAtIndex(0)
|
||||
&& cursor->position() == LayoutCursor::Position::Right)
|
||||
{
|
||||
// Case: Right of the operand. Go Right of the brackets.
|
||||
cursor->setLayout(this);
|
||||
return;
|
||||
}
|
||||
assert(cursor->layoutNode() == this);
|
||||
if (cursor->position() == LayoutCursor::Position::Left) {
|
||||
// Case: Left of the brackets. Go Left of the operand.
|
||||
cursor->setLayout(childAtIndex(0));
|
||||
return;
|
||||
}
|
||||
assert(cursor->position() == LayoutCursor::Position::Right);
|
||||
// Case: Right of the brackets. Ask the parent.
|
||||
LayoutNode * parentNode = parent();
|
||||
if (parentNode != nullptr) {
|
||||
parentNode->moveCursorRight(cursor, shouldRecomputeLayout);
|
||||
}
|
||||
}
|
||||
KDSize VectorLayoutNode::computeSize() {
|
||||
KDSize size = childAtIndex(0)->layoutSize();
|
||||
return KDSize(2 * k_sideMargin + size.width() + k_arrowWidth + k_sideMargin, k_topMargin + (k_arrowHeight+k_arrowLineHeight)/2 + size.height());
|
||||
}
|
||||
|
||||
KDCoordinate VectorLayoutNode::computeBaseline() {
|
||||
return childAtIndex(0)->baseline() + (k_arrowHeight+k_arrowLineHeight)/2 + k_arrowLineHeight + k_topMargin;
|
||||
}
|
||||
|
||||
KDPoint VectorLayoutNode::positionOfChild(LayoutNode * child) {
|
||||
assert(child == childAtIndex(0));
|
||||
return KDPoint(k_sideMargin * 2, k_topMargin + (k_arrowHeight+k_arrowLineHeight)/2 + k_arrowLineHeight);
|
||||
}
|
||||
void VectorLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor, Layout * selectionStart, Layout * selectionEnd, KDColor selectionColor) {
|
||||
KDColor workingBuffer[k_arrowWidth * k_arrowHeight];
|
||||
ctx->fillRect(KDRect(p.x() + k_sideMargin, p.y() + k_topMargin + (k_arrowHeight-k_arrowLineHeight)/2, 2 * k_sideMargin + childAtIndex(0)->layoutSize().width(), k_arrowLineHeight), expressionColor);
|
||||
ctx->blendRectWithMask(KDRect(p.x() + 2 * k_sideMargin + childAtIndex(0)->layoutSize().width(), p.y() + k_topMargin, k_arrowWidth, k_arrowHeight), expressionColor, (const uint8_t *)arrowMask, workingBuffer);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -363,11 +363,6 @@ Q(upper)
|
||||
Q(value)
|
||||
Q(values)
|
||||
Q(zip)
|
||||
Q(doc)
|
||||
Q(property)
|
||||
Q(getter)
|
||||
Q(setter)
|
||||
Q(deleter)
|
||||
|
||||
// Ion QSTR
|
||||
Q(ion)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modkandinsky_color_obj, 1, 3, modkandinsky_color);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(modkandinsky_get_pixel_obj, modkandinsky_get_pixel);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(modkandinsky_set_pixel_obj, modkandinsky_set_pixel);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modkandinsky_draw_string_obj, 3, 6, modkandinsky_draw_string);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modkandinsky_draw_string_obj, 3, 5, modkandinsky_draw_string);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modkandinsky_draw_line_obj, 5, 5, modkandinsky_draw_line);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modkandinsky_draw_circle_obj, 4, 4, modkandinsky_draw_circle);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modkandinsky_fill_rect_obj, 5, 5, modkandinsky_fill_rect);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user