Compare commits

...

982 Commits

Author SHA1 Message Date
Quentin Guidée
46658f7077 [omega] 1.20.3 2020-08-26 14:17:23 +02:00
Charlotte THOMAS
cf5cd35bc9 [Change] Constants based on the CODATA 2018 (#398) 2020-08-17 21:52:39 +02:00
Quentin Guidée
a74a5ac796 [fix] conflicts 2020-08-09 13:28:22 +02:00
Quentin Guidée
4f30089d47 Revert "Merge pull request #393 from RedGl0w/MenuFix"
This reverts commit a9d75c6c7a, reversing
changes made to ebc9384131.
2020-08-06 15:23:08 +02:00
Léa Saviot
edafa0e155 [poincare/multiplication] Assert no child is undef in removeUnit 2020-07-29 10:13:19 +02:00
Léa Saviot
b885098963 [apps/calculation] Fix additionalInformationType
If an expression hasUnits and is then reduced, it might not have units
anymore for instance if it was replaced with undefined).
Scenario: Enter "[5000000000000000]^20 _s" in the calculation app
2020-07-29 10:13:19 +02:00
Léa Saviot
f3628f368f [poincare/expression] Return undef if simplification interrupted
Without this change, we would get weird "reduced" expression, such as
multiplication(undef, _s), but we do not always check
sSimplificationHasBeenInterrupted afterwards.
2020-07-29 10:13:19 +02:00
Hugo Saint-Vignes
5c75cc55d3 [apps/shared] Apply changes on confirm with GoTo functions
Change-Id: I6ebec412b4b6612710476274a8665375d21f9ef8
2020-07-29 10:07:07 +02:00
Hugo Saint-Vignes
61792058d3 [apps/shared] Fix typos for Interval and curve view temporary params
Change-Id: I610726ed5966d353397be923b76dd003297940a7
2020-07-29 10:07:07 +02:00
Joachim LF
d37bf9e344 [Apps/Shared] Fixed interval and curve view exit 2020-07-29 10:07:07 +02:00
Émilie Feral
b4a3dd10e1 [apps/shared] ToolBoxHelpers: don't overflow buffer
If the commandLength is > than the buffer size, we have to escape at
some point to avoid overflowing the buffer.
2020-07-29 09:43:51 +02:00
Quentin
a9d75c6c7a Merge pull request #393 from RedGl0w/MenuFix
[Apps/home] Change menu behaviour with incomplete lines
2020-07-27 16:45:30 +02:00
Joachim LF
c57f8d257b [Apps/home] Change menu behaviour with incomplete lines 2020-07-27 16:41:01 +02:00
Quentin
ebc9384131 Merge pull request #392 from RedGl0w/KeyDown
[ion/src/simulator] Visual keyboard only change state on keydown
2020-07-27 13:25:20 +02:00
Quentin
b478c98fe0 Merge pull request #391 from quentinguidee/omega-rename-username
[username] Change USERNAME to OMEGA_USERNAME
2020-07-24 10:27:12 +02:00
Quentin Guidée
93f4281bdc [themes] Update submodule 2020-07-24 09:05:01 +02:00
Quentin Guidée
7b07a2e3ac [username] Change USERNAME to OMEGA_USERNAME 2020-07-24 08:24:12 +02:00
Quentin
d2a2925746 Merge pull request #390 from quentinguidee/omega-hotfix
[apps/settings] remove LEDS_CHOICE
2020-07-24 00:03:03 +02:00
Quentin Guidée
7fc145d455 [apps/settings] remove LEDS_CHOICE 2020-07-23 23:22:31 +02:00
Quentin Guidée
2f246ad604 [android] Change SDK version to 29 2020-07-23 20:15:24 +02:00
Quentin Guidée
0235de8010 [omega] 1.20.2 2020-07-23 18:23:30 +02:00
Quentin Guidée
636c5c1d24 Merge branch 'omega-hotfix' into omega-master 2020-07-23 18:23:11 +02:00
Quentin
36bcd138d8 Merge pull request #389 from M4xi1m3/omega-hotfix
Omega 1.20.2
2020-07-23 18:07:37 +02:00
Quentin Guidée
22415c1bc3 [ion/src/simulator] Update background.jpg 2020-07-23 18:06:27 +02:00
M4x1m3
12fb82b028 [apps/code] Added os in toolbox 2020-07-23 17:13:40 +02:00
M4x1m3
c5500eee06 [mpy/os] Removes useless file 2020-07-23 11:12:31 +02:00
M4x1m3
587ea39aaf [app/code] Wipe scripts when adding one with opt 2020-07-23 11:12:31 +02:00
M4x1m3
f582ce0e6d [simu] Added shadow to logo 2020-07-23 11:12:31 +02:00
M4x1m3
b11c58f11c [simu] Persistant script store (and other stuff) 2020-07-23 11:12:27 +02:00
Quentin Guidée
32be8854c9 [omega] 1.20.1 2020-07-21 22:37:29 +02:00
Quentin Guidée
4af76cc3ae [omega] 1.20.1 2020-07-21 22:32:19 +02:00
Quentin
93c431be04 Merge pull request #387 from M4xi1m3/omega-hotfix
[mpy] Fix crash on append on new file, new os module
2020-07-21 22:30:32 +02:00
M4x1m3
63acf7b0ee [app/code] Changed color of mandelbrot script 2020-07-21 22:27:04 +02:00
M4x1m3
14a3ea51c4 [mpy/os] listdir 2020-07-21 22:27:04 +02:00
M4x1m3
18ccc0c771 [mpy/os] rename 2020-07-21 22:27:04 +02:00
M4x1m3
f65881420c [mpy/file] Fixed concurency issues 2020-07-21 22:27:04 +02:00
M4x1m3
8eeae5f161 [mpy/os] Added remove 2020-07-21 22:27:04 +02:00
M4x1m3
2dce8a1343 [mpy/os] uname 2020-07-21 22:27:00 +02:00
M4x1m3
b9a6298ffa [mpy] Added os module 2020-07-21 18:00:12 +02:00
M4x1m3
2040a2cd5b [mpy/files] Fixed crash with new files in append mode 2020-07-21 16:57:57 +02:00
Quentin Guidée
73037e3faf [github] Fix README.md 2020-07-21 09:32:14 +02:00
Quentin Guidée
132f899237 [omega] 1.20.0 2020-07-20 17:09:03 +02:00
Quentin Guidée
8f3415f74d [i18n] Fix it and nl homescreen translations 2020-07-20 17:02:52 +02:00
Léa Saviot
3e6e1729a2 [ion/device] Add screen id for gamma calibration 2020-07-20 10:35:59 +02:00
Quentin
635c5cbabd Merge pull request #385 from M4xi1m3/omega-dev-e14
[ion] Fixed issue with backspace
2020-07-19 16:01:08 +02:00
M4x1m3
58a33e8190 [ion] Fixed issue with backspace 2020-07-19 15:39:27 +02:00
Charlotte THOMAS
0086368b2c [i18n] Translated constants in Italian and NL (#384)
* NL: translation of the physics constant
EN: correction of "Elemental charge" into "Elementary Charge"

* Italian translation

* Fixed some italian translation ( thanks Clem' :) )

* [Fix]: NL and IT translation

Co-authored-by: Shadow15510 <antoine.royer31@orange.fr>
2020-07-18 17:19:35 +02:00
Quentin
094e2c86b4 Merge pull request #383 from M4xi1m3/omega-dev-e14
[ci] Added customs RAM and ROM sections to the metric system
2020-07-18 17:16:28 +02:00
M4x1m3
699c653882 [ci/metric] Removed space in numbers (fixed leading 0s issue) 2020-07-18 17:08:26 +02:00
M4x1m3
96d49feaf6 [ci/metric] Marked parenthesis as safe character. 2020-07-18 15:48:41 +02:00
M4x1m3
b87e9879bc [ci] Added customs RAM and ROM sections to the metric system 2020-07-18 15:40:03 +02:00
Quentin Guidée
57a37d7028 [GitHub] CI Metric 2020-07-18 12:22:30 +02:00
Quentin Guidée
26ecff543a [GitHub] CI Metric 2020-07-18 11:50:11 +02:00
Quentin Guidée
c2df1c33d1 [Fix] Examination level 2020-07-18 10:31:14 +02:00
Quentin Guidée
a826bb7cc9 [Update] Update README.md 2020-07-18 09:32:18 +02:00
Charlotte THOMAS
357aa8291d [Fix] Repaired units (#381) 2020-07-18 00:02:20 +02:00
Quentin Guidée
6f8192cce2 Merge branch 'omega-dev-e14' of github.com:Omega-Numworks/Omega into omega-dev-e14 2020-07-17 23:52:16 +02:00
Quentin Guidée
e37e59e4bc [Update] Contributors 2020-07-17 23:50:30 +02:00
Quentin
c31480c7cb Merge pull request #380 from LeGmask/patch-1
[Fix] Fixed non-erasable empty character
2020-07-17 22:54:57 +02:00
Evann DREUMONT
2d2eb8c9aa [Fix] Fixed non-erasable empty character 2020-07-17 20:36:32 +00:00
Quentin Guidée
9188f8c054 [Update] Contributors 2020-07-17 21:26:30 +02:00
Quentin Guidée
28f5e119db [GitHub] Fix link README.md 2020-07-17 21:04:40 +02:00
Quentin
88b9f6735c Merge pull request #379 from M4xi1m3/omega-dev-e14
[escher] Fixed theme engine
2020-07-17 20:46:39 +02:00
M4x1m3
52cd5318a1 [escher] Fixed theme engine 2020-07-17 19:59:06 +02:00
Quentin
b323e63f09 Merge pull request #378 from M4xi1m3/omega-dev-e14
[ion/kb] Reverted #370, found a better way to fix.
2020-07-17 16:34:24 +02:00
Quentin Guidée
2de3da8e67 [Change] Move Expression Format with others Format settings 2020-07-17 11:58:47 +02:00
M4x1m3
efd2896a34 [ion/kb] Reverted #370, found a better way to fix. 2020-07-17 10:09:07 +02:00
Émilie Feral
22549d4d50 [apps/calculation] CalculationStore: change name CalculationHeight -->
HeightComputer
2020-07-16 14:37:38 +02:00
Émilie Feral
83ecefda00 [apps/calculation] Fix tests 2020-07-16 14:37:38 +02:00
Émilie Feral
1fb8c09714 [apps/calculation] Remove old TODOs 2020-07-16 14:37:38 +02:00
Émilie Feral
df74c2c551 [apps/calculation] The heights (common and expanded) of calculation cells are
computed when the calculation is added to the store and don't change afterwards.
Otherwise, if their heights change when scrolling (due to a modification of the
display output type - ExactOnly, ApproximateOnly...), it generates crashes.
2020-07-16 14:37:38 +02:00
Émilie Feral
c2db00cc88 [apps/calculation] When leaving calculation app, do not invalid
calculation height memoization. They're computed from the layouts which
don't depend on the complex format (or any other settings parameters
which could have changed).
2020-07-16 14:37:38 +02:00
Léa Saviot
708477dece [apps/i18n] Fix missing upper case 2020-07-16 11:53:12 +02:00
Léa Saviot
b4dd4b5e7e [apps/code/i18n] Make italian wording fit 2020-07-16 11:53:12 +02:00
Léa Saviot
c20261940f [poincare] Handle removeUnit that create Undefined expressions
UnitConvert::removeUnit replaces the unit ocnvert with an undefined.
2020-07-16 11:46:23 +02:00
Léa Saviot
3a046f5bcb [poincare/multiplication] Fix Multiplication::removeUnit
Scenario:
f(x) = 0->_A
evaluate 0f(0)
2020-07-16 11:46:23 +02:00
Léa Saviot
36bc70aaee [poincare/power] Better Power::shallowReduce
Take care of an undefined index that arrived during the remove unit
2020-07-16 11:46:23 +02:00
Léa Saviot
9e94304db0 [poincre/test] Rename assert_simplify -> assert_reduce
And assert_expression_simplify -> assert_expression_reduce
2020-07-16 11:46:23 +02:00
Émilie Feral
c92b3d49e9 [apps/calculation] HistoryController: reload the subview selection when
deleting row

This fixes the following bug: input 1, OK, 1.2 OK, delete the row whose
input is '1' with the selection on the output view. The output of 1.2
does not toggle and it should.
2020-07-16 09:48:22 +02:00
Quentin Guidée
dacb7351c3 [Fix] Remove unused i18n keys 2020-07-16 00:31:11 +02:00
Quentin Guidée
96b1cd38cf Merge remote-tracking branch 'upstream/master' into omega-dev-e14 2020-07-15 13:39:24 +02:00
Léa Saviot
43744bcae9 [poincare/power] Fix shallowReduce
Scenario: f(x) = 0->0
In graph, go to x = e^(f(0))
2020-07-15 13:07:17 +02:00
Quentin Guidée
e31912054c Merge branch 'omega-dev-e14' of github.com:Omega-Numworks/Omega into omega-dev-e14 2020-07-15 12:09:28 +02:00
Quentin Guidée
b5a9323a81 [Fix] Conflicts 2020-07-15 12:09:12 +02:00
Quentin
e2611648c9 Merge pull request #376 from M4xi1m3/omega-dev-e14
[mpy] Added passing errors to JS
2020-07-15 11:41:16 +02:00
M4x1m3
231223086c [mpy] Added passing errors to JS 2020-07-15 11:38:40 +02:00
Joachim Le Fournis
46ede2eb59 Resolved the wrong gender of font in fr 2020-07-15 10:41:37 +02:00
Charlotte THOMAS
b5f9deb169 Update calculation.cpp
removed white
2020-07-15 10:28:15 +02:00
Charlotte THOMAS
7754693bdf fix: change IsIS => IsSI in test too 2020-07-15 10:28:15 +02:00
Charlotte THOMAS
f1dab081e1 Fix: CI test 2020-07-15 10:28:15 +02:00
Charlotte THOMAS
9d8b62894f Fix: Changed "IS" to "SI" because even in english the short for "International System of Units" is "SI" 2020-07-15 10:28:15 +02:00
Quentin
8ee213a443 Merge pull request #375 from M4xi1m3/omega-dev-e14
Various improvements to the 3DS simu.
2020-07-14 17:09:49 +02:00
M4x1m3
efd5be4c23 [build] Added 3ds in help, fixed the pimp 2020-07-14 17:04:30 +02:00
M4x1m3
5c23d6fb8e [ion/3ds] Changed background to new one 2020-07-14 17:03:02 +02:00
Quentin Guidée
c2390bebe3 Merge branch 'omega-dev-e14' of github.com:Omega-Numworks/Omega into omega-dev-e14 2020-07-14 15:52:50 +02:00
Quentin Guidée
6a77ec3f87 [Update] RPN 2020-07-14 15:52:37 +02:00
Quentin
443b70ec10 Merge pull request #374 from M4xi1m3/omega-dev-e14
[ci] Generate .sha256 for N0100
2020-07-14 15:32:07 +02:00
Maxime FRIESS
a7ca30b793 [ci] Generate .sha256 for N0100 2020-07-14 15:17:19 +02:00
Quentin Guidée
6553afacdd Merge branch 'omega-dev-e14' of github.com:Omega-Numworks/Omega into omega-dev-e14 2020-07-14 14:37:11 +02:00
Quentin Guidée
360bb17a4f [Fix] Conflicts 2020-07-14 14:36:39 +02:00
Quentin
7590e6ce31 Merge pull request #373 from M4xi1m3/omega-dev-e14
[ci] Added hu to N0100
2020-07-14 13:57:31 +02:00
Maxime FRIESS
0a384e7c8a [ci] Added hu to N0100 2020-07-14 13:56:26 +02:00
Quentin
cb58189fc5 Merge pull request #372 from M4xi1m3/omega-dev-e14
N0100 Generate one binary per langage
2020-07-14 13:19:54 +02:00
M4x1m3
84442fca10 [ci] Faster way 2020-07-14 12:10:41 +02:00
M4x1m3
c915894c0d [ci] N0100 generates one fw per language. 2020-07-14 12:00:43 +02:00
Quentin Guidée
ef8b74781b [Update] Atom 2020-07-14 11:50:41 +02:00
Quentin
f8fa492418 Merge pull request #371 from quentinguidee/omega-dev-e14
[Fix] Missing translations
2020-07-14 11:40:28 +02:00
Quentin Guidée
7227d0dccb [Fix] Missing translations 2020-07-14 11:28:01 +02:00
Quentin
3f11728e1a Merge pull request #370 from M4xi1m3/e14-bf2
[escher] Fixed alpha+arrow / alpha-lock + arrow
2020-07-14 11:27:38 +02:00
M4x1m3
c029474a61 [escher] Fixed alpha+arrow / alpha-lock + arrow 2020-07-14 11:00:08 +02:00
Quentin
15b1c96580 Merge pull request #369 from M4xi1m3/e14-bf3
[apps/home] Made external apps selectable again.
2020-07-14 10:36:38 +02:00
M4x1m3
51cb57d1a1 [apps/home] Made external apps selectable again. 2020-07-14 10:04:00 +02:00
Quentin Guidée
5c3dd4f6d2 [Revert] 3DS workflows 2020-07-13 11:49:25 +02:00
Quentin Guidée
3bac01189f [i18n/fr] Format expressions -> Format expression 2020-07-13 11:15:37 +02:00
Quentin Guidée
0d80f148b4 [Fix] Click on symbolic expression caused undef 2020-07-13 11:09:22 +02:00
Quentin Guidée
d13e79509a [Update] RPN with Epsilon 14 2020-07-13 10:48:07 +02:00
Joachim LF
04901e3231 Fixed % in alpha lock 2020-07-13 10:38:22 +02:00
Joachim LF
d7ac7e19bb [Update] Epsilon 14 2020-07-13 10:36:47 +02:00
Léa Saviot
b83c686773 build: Version 14.4.1 2020-07-10 10:49:19 +02:00
Léa Saviot
2af89fb546 [build/android] Prevent code relocations in MicroPython 2020-07-09 20:24:16 -04:00
Léa Saviot
1fde815769 [ion/android] Do not setWindowStyle if SDL not initialized
When a library was broken, we would see an error due to the failed
setWindowStyle call, instead of getting the briken library error.
2020-07-09 20:24:16 -04:00
Joachim LF
4a5681576c Visual keyboard only change state on keydown 2020-07-09 19:17:36 +02:00
Quentin
d2a2c9e208 Merge pull request #366 from M4xi1m3/omega-dev
Adding file support to micropython
2020-07-08 13:20:25 +02:00
Léa Saviot
ef8a4f9e7b build: Version 14.4.0 2020-07-07 09:55:21 +02:00
Léa Saviot
d8f17da04e [apps/calculation] Add TODO comments about factorization 2020-07-07 09:55:20 +02:00
Léa Saviot
cc4ff3d40d [apps/calculation] Apply fix about Height computation
There was a problem with the way of computing Height, see
Calculation::HistoryViewCell. We did not encounter a problemeatic
scenario here, but there is no reason it would have been safe before.
2020-07-07 09:55:20 +02:00
Léa Saviot
982b467268 [apps/calculation] Fix scrolling
If the last cell is too big to fit entirely, we would scroll to the top
of the calculation, instead of the bottom
2020-07-07 09:46:26 +02:00
Léa Saviot
1128134c37 [apps/calculation] Raise exception if row height miscomputed
Scenario:
Put the complex mode to exponential, then go back to Calculation and:
Toolbox, Down, Down, Down, Down, OK, OK, Two, Plus, Imaginary,
Toolbox, Down, Down, Down, Down, OK, Down, OK, Two, Plus,
Imaginary, OK, Toolbox, Down, Down, Down, Down, Down, OK,
Down, OK, Up, OK, Right, Zero, OK, OK, Toolbox, Down,
Down, OK, Toolbox, Back, Up, Zero, Up, OK, Zero, Up, Up, Up
2020-07-07 09:46:26 +02:00
Léa Saviot
924e235ba8 [apps/calculation] Factorize some code 2020-07-06 17:16:22 +02:00
Léa Saviot
35f20c4312 [apps/calculation] Comment possible failed height computation 2020-07-06 16:35:35 +02:00
M4x1m3
c4363103f6 [apps/code] Added exceptions handling in toolbox 2020-07-06 12:45:47 +02:00
M4x1m3
73688343a0 [apps/code] Added File category to python toolbox 2020-07-06 11:56:11 +02:00
M4x1m3
646088e429 [mpy/files] Removed RAM/FLASH logic, added a bit of doc. 2020-07-06 10:05:55 +02:00
M4x1m3
efcf9903a9 [mpy/files] implemented open 2020-07-05 21:20:52 +02:00
M4x1m3
61a9e492bd [mpy/files] truncate, readlines, writelines, name, mode 2020-07-05 21:20:47 +02:00
M4x1m3
55bc23c6d7 [mpy/files] __iter__, __next__ 2020-07-05 21:20:40 +02:00
M4x1m3
fba5295502 [mpy/files] readline 2020-07-05 21:20:37 +02:00
M4x1m3
a47ef29236 [mpy/files] __enter__, __exit__ 2020-07-05 21:20:32 +02:00
M4x1m3
1aebec52bb [mpy/files] fixed read, added write 2020-07-05 21:20:25 +02:00
M4x1m3
8178eadd49 [mpy/files] read 2020-07-05 21:20:20 +02:00
M4x1m3
7d61f867cf [mpy/files] closed attribute 2020-07-05 21:20:14 +02:00
M4x1m3
420edf6092 [mpy/files] close 2020-07-05 21:20:09 +02:00
M4x1m3
a20ac589ec [mpy/files] seek, tell, seekable 2020-07-05 21:19:57 +02:00
M4x1m3
d0f3ec887e [mpy/files] Added ion.file 2020-07-05 21:19:49 +02:00
Léa Saviot
1ef3f34a31 [ion/apple] App needs to be inside Payload folder to build .ipa
Otherwise the .ipa cannot be uploaded to the app store.
2020-07-03 14:21:56 +02:00
Quentin
ce00a8ba94 Merge pull request #364 from M4xi1m3/omega-dev
Made CI output binpacks instead of DFU
2020-07-03 11:25:32 +02:00
Maxime FRIESS
7c837238bd Made CI output binpacks instead of DFU 2020-07-03 11:12:44 +02:00
Quentin Guidée
b8b5a9cb7c [GitHub] Create CODE_OF_CONDUCT.md 2020-07-02 22:26:25 +02:00
Quentin Guidée
7996610451 [Update] Epsilon master 2020-07-02 19:07:29 +02:00
Quentin Guidée
cd2a250d20 [Change] Settings camelCase 2020-07-02 18:10:19 +02:00
Émilie Feral
38f3c9b813 build: Version 14.3.0 2020-07-02 17:09:38 +02:00
Léa Saviot
759fa6a60a [escher] Fix constexpr due to linux warning 2020-07-02 17:09:38 +02:00
Léa Saviot
6b60fc561f [apps/regression] Fix wrong proportional model fit 2020-07-02 17:09:38 +02:00
Romain Goyet
5dfccd4a04 [ion/simulator] Relayout on any windows event
We might be relayouting a bit too often, but better safe than sorry!
Jokes aside, most SDL_WINDOWEVENT should trigger a relayout, and in
general those events aren't triggered on a regular basis anyway.
2020-07-02 14:42:59 +02:00
Romain Goyet
7a9954152a [ion/simulator] Ion::Simulator::Main::relayout() should not draw
That function is supposed to recompute the layout, not perform any
drawing. Namely, presenting the render without a potential previous call
to SDL_RenderClear could lead to some visual glitches.
2020-07-02 14:42:59 +02:00
Romain Goyet
026fe120fe [simulator] Make the calculator's screen pixel-perfect 2020-07-02 14:42:59 +02:00
Émilie Feral
558d0f6343 [.github/workflow] ci-workflow: fix emscripten version to 1.39.16 (later
versions removed EMTERPRETER)
2020-07-02 14:42:59 +02:00
Romain Goyet
585bf65294 [ion/simulator] Relayout on any windows event
We might be relayouting a bit too often, but better safe than sorry!
Jokes aside, most SDL_WINDOWEVENT should trigger a relayout, and in
general those events aren't triggered on a regular basis anyway.
2020-07-02 14:41:49 +02:00
Romain Goyet
85a10ab084 [ion/simulator] Ion::Simulator::Main::relayout() should not draw
That function is supposed to recompute the layout, not perform any
drawing. Namely, presenting the render without a potential previous call
to SDL_RenderClear could lead to some visual glitches.
2020-07-02 14:41:49 +02:00
Romain Goyet
3d24b3c054 [simulator] Make the calculator's screen pixel-perfect 2020-07-02 14:40:36 +02:00
Quentin
bd6c7200cd [GitHub] Update README.md 2020-07-02 13:23:29 +02:00
Quentin
81a1f907d0 Merge pull request #363 from M4xi1m3/omega-dev
Changed simulator background
2020-07-02 11:00:04 +02:00
M4x1m3
154152440b Changed simulator background 2020-07-02 10:57:59 +02:00
Léa Saviot
3cf80b86d6 [apps/i18n] Fix italian translation typo 2020-07-02 10:23:27 +02:00
Quentin
19ed9e96d9 [GitHub] Update README.md 2020-07-01 23:15:24 +02:00
Quentin
35589e2e75 [GitHub] README with better Discord visibility 2020-07-01 22:21:21 +02:00
Quentin
b1f8040741 Merge pull request #362 from M4xi1m3/omega-dev
Enabled circuit breaker with emscripten
2020-07-01 21:38:36 +02:00
Quentin
101e4477f3 [.github/workflows] Fix 3DS CI 2020-07-01 21:37:06 +02:00
M4x1m3
81e9cbc0e0 Enabled circuit breaker with emscripten
This is possible because we use WASM and ASYNCIFY with the latest-upstream
toolchain.
2020-07-01 21:23:50 +02:00
Quentin
6c6da43047 [GitHub] Update README.md 2020-07-01 13:35:05 +02:00
Quentin
e2fef63062 Merge pull request #361 from M4xi1m3/omega-dev
Fixed 3DS build, added 3DS CI
2020-07-01 12:20:54 +02:00
M4x1m3
10a11dddeb Fixed 3DS build, added 3DS CI 2020-07-01 11:45:26 +02:00
Léa Saviot
a4c0903f53 [i18n/pt] Fix typo 2020-06-30 17:24:50 +02:00
Gabriel Ozouf
e78c5c02d3 [apps/calculation] Fixed history scroll
Fixed a bug involving mishandled negative offsets in
CalculationSelectableTableView::scrollToSubviewOfTypeOfCellAtLocation
and cleaned up the function.

Change-Id: I4394ca9dc9748e8b761e7f722e41014d71d3373f
2020-06-30 15:41:56 +02:00
Quentin
80404db33d [Makefile] Fixed i18n dependency issue 2020-06-28 18:52:11 +02:00
Émilie Feral
cb62747e48 build: Version 14.2.0 2020-06-26 17:48:31 +02:00
Émilie Feral
96c7d84633 [apps/calculation] Factorize code to avoid selecting ellipsis on cell
where ellipsis is not displayed
2020-06-26 17:48:31 +02:00
Émilie Feral
1281a4a508 [apps/calculation] HistoryController: avoid duplicate code when handling
backspace event. Keep the same selected subview.
2020-06-26 17:48:31 +02:00
Émilie Feral
94d3ac9828 [apps/calculation] HistoryController: fix order of actions in Backspace
handle event

This fixes the following bug: input 1/2/3/4/5/6/7/8, OK, OK, input 1,
OK, up, backspace. The selection disappeared.
2020-06-26 17:48:31 +02:00
Émilie Feral
aef804d149 [apps/calculation] HistoryController: avoid 2 calls to
setSelectedSubviewType in tableViewDidChangeSelectionAndDidScroll
2020-06-26 17:48:31 +02:00
Émilie Feral
736833da34 [escher] Typo 2020-06-26 17:48:31 +02:00
Émilie Feral
457fa6a925 [apps/calculation] When EditExpressionController becomes the first
responder, scroll to the bottom of the table (and not the last cell).
Indeed, the last cell might be to big to be displayed and scroll to it
might scroll to its top.

This fixes the following bug: input 1/2/3/4/5/6/7/8, OK, up, down. We
did not scroll to the bottom of the table.
2020-06-26 17:48:31 +02:00
Émilie Feral
1da2f23914 [escher] SelectableTableView: fix delegate notification when
deselecting table view

This fixes the following bug: input 1.2/2, OK, up, down, the exact ouput
is still displayed but should have toggled
2020-06-26 17:48:31 +02:00
Émilie Feral
db331e054a [apps/code] variable_box_controller: avoid unused variable warning when DEBUG=0 2020-06-26 10:47:14 +02:00
Émilie Feral
9508a89a1b [apps/calculation] Missing inclusion 2020-06-26 10:47:14 +02:00
Émilie Feral
0b74dd005d [apps/calculation] SelectableTableView: fix scrollToSubviewOfTypeOfCellAtLocation
When scrolling, the table layout is likely to change and the selected
cell might not been the same.
2020-06-26 10:45:55 +02:00
Quentin
ac682a15c4 Merge branch 'omega-dev' of github.com:Omega-Numworks/Omega into omega-dev 2020-06-26 10:37:10 +02:00
Quentin
50a0fce958 [Feature] Add Omega and Mu symbols, closes #301 2020-06-26 10:37:01 +02:00
Gabriel Ozouf
123d5f9076 [apps/calculation] Fixed tall calculation scroll
When displaying a calculation taller than the screen, the output could
be displayed above the screen.
  - type 1/2/3/4/5/6/7/8/9 (the main fraction between the 1 and 2)
  - press UP to select the output
==> The output is still offscreen.

Change-Id: Ic3ed7664ae693d22486f8b2f9f3a8f2324c3d7c9
2020-06-26 09:50:10 +02:00
Gabriel Ozouf
363bf4a620 [apps/calculation] Fixed ellipsis scrolling
When scrolling to a calculation without additional outputs from a
calculation with additional outputs, the ellipsis, though invisible,
would remain selected.

Change-Id: I7408ae004b9374e432ac58361616fa2ecf1550d8
2020-06-25 18:03:29 +02:00
Roberta Rabotti
981c627bc4 [IT]changed Sample standard deviation 2020-06-25 17:15:09 +02:00
Roberta Rabotti
d48f66fdad [IT]chenges graphs 2020-06-25 17:15:03 +02:00
Émilie Feral
bac2949a5e [escher][apps] SelectableTableViewDelegate: add
tableViewDidChangeSelectionAndDidScroll method and implement it for
Calculation::HistoryController

This fixes the following bug: In the calculation application, input 1,
OK, 1/2/3/4/5/6/7/8, OK, up, up, left, down, up. The selection failed.
2020-06-25 13:48:47 +02:00
Léa Saviot
2d1d3ca944 [apps/code] Fix variables loading in the console
The two following scenari display empty variable boxes, when there
should be loaded variables.
1) Open the console, go back to the scripts menu, go back to the
console, open the variable box
2) Open the console, execute mandelbrot, open the variable box
2020-06-25 11:31:01 +02:00
Quentin
ee575ecf1c Merge pull request #359 from M4xi1m3/omega-dev
[apps/home] Changed wrong background color on app_cell
2020-06-24 16:18:06 +02:00
Maxime FRIESS
f2cd8367d6 [apps/home] Changed wrong background color on app_cell 2020-06-24 14:59:53 +02:00
Quentin
aa6ce1f389 [Fix] Webworkflows 2020-06-23 19:20:21 +02:00
M4x1m3
150e4a727c [simu/web] Changed to emsdk upstream-latest. Now using WASM. 2020-06-23 19:17:31 +02:00
Quentin
af0ed7ebc8 [Docker] Rename job 2020-06-23 19:13:20 +02:00
Quentin
0f4df66097 [Docker] Rename job 2020-06-23 19:12:46 +02:00
Quentin
6af893c7a6 [Docker] README.md 2020-06-23 19:06:32 +02:00
Evann DREUMONT
8b973e9c77 [Feature] Add docker and docker CI
fix CI
2020-06-23 19:06:15 +02:00
Quentin
c6fc70aa42 [Docker] README.md 2020-06-23 18:22:00 +02:00
Quentin
37eca1dfb2 Merge pull request #358 from LeGmask/docker
[Docker] Add docker and docker CI
2020-06-23 17:52:42 +02:00
Evann DREUMONT
036401a3c4 [Feature] Add docker and docker CI
fix CI
2020-06-23 17:39:12 +02:00
Quentin
6da053508d Merge branch 'M4xi1m3-omega-dev' into omega-dev 2020-06-23 17:36:13 +02:00
Quentin
1f3ad54c05 [Change] OMEGA_THEME_* to THEME_* 2020-06-23 17:35:39 +02:00
Quentin
ea75f8ac26 Merge branch 'omega-dev' of https://github.com/M4xi1m3/Omega into M4xi1m3-omega-dev 2020-06-23 17:30:06 +02:00
Quentin
5d42fbc938 Merge pull request #353 from quentinguidee/patch-themes
[Fix] Patched colors
2020-06-23 17:23:20 +02:00
M4x1m3
72d9e31847 Added support for git theme repos
Usage:
OMEGA_THEME_REPO must be set to a valid git url, or local for local repository
OMEGA_THEME_NAME must be set to an existing theme in the repository
2020-06-22 19:02:32 +02:00
Quentin
3c1cc62302 [Fix] undefined reference to CalculationTrigoAndComplexForeground 2020-06-20 19:46:47 +02:00
Quentin
27a0935311 [Fix] Patched colors 2020-06-20 19:46:47 +02:00
Quentin
3f959a44db Merge pull request #355 from M4xi1m3/omega-dev
[simu/web] Changed to emsdk upstream-latest. Now using WASM.
2020-06-20 19:34:22 +02:00
Quentin
1b76a48ae2 [Revert] Omega App 2020-06-20 19:31:42 +02:00
M4x1m3
f04c645fee [simu/web] Changed to emsdk upstream-latest. Now using WASM. 2020-06-20 19:05:22 +02:00
Quentin
710e4cf56b [Change] Contributors 2020-06-19 20:49:05 +02:00
Émilie Feral
ef210f9cff build: Version 14.1.0 2020-06-19 12:10:24 +02:00
Léa Saviot
1045f54633 [apps/code] Fix variables loading in the console
Scenario: execute a script, open the variable box, select a leaf, reopen
the variable box -> it shows empty
2020-06-19 12:10:24 +02:00
Quentin
8d10e2884b [Update] Themes Submodules 2020-06-19 11:47:07 +02:00
Quentin
d9d6d1f31e [Update] Themes Submodules 2020-06-19 11:19:09 +02:00
Quentin
523cd87334 [Update] Themes 2020-06-19 11:14:58 +02:00
Quentin
49fd8d1534 [GitHub] Update README.md with 3DS simulator 2020-06-19 09:21:10 +02:00
Quentin
38c503da40 Merge branch 'omega-dev' of github.com:Omega-Numworks/Omega into omega-dev 2020-06-19 09:14:39 +02:00
Quentin
03afd1d681 [Revert] Stay Home(ga) 2020-06-19 09:14:22 +02:00
Quentin
b35d6105c5 [GitHub] Disable blank issues 2020-06-18 23:42:34 +02:00
Evann DREUMONT
2dff5c511e [Feature] Add \ and @ 2020-06-18 22:28:55 +02:00
Quentin
5134d0e352 [Fix] Conflicts 2020-06-18 19:58:34 +02:00
Quentin
2c99f38a93 [Revert] Compact display 2020-06-18 19:38:22 +02:00
Quentin
db10723e76 [Update] Upstream 2020-06-18 19:25:17 +02:00
Émilie Feral
043c564a25 [.github/workflow] ci-workflow: fix emscripten version to 1.39.16 (later
versions removed EMTERPRETER)
2020-06-17 09:51:00 +02:00
Léa Saviot
cf4eaa3d1f [apps/poincare] Use symbolicComputation in recursivelyMatches
This fixes a failed assertion for the scenario:
[3]->x then, in the Equation app, solve x+1->0
2020-06-15 16:20:09 +02:00
Léa Saviot
1f0b3770e3 [apps/code] Fix syntaxic coloration
Scenario: +, -, / operators where no longer properly colored during
script edition.
This was due to the MicroPython update, which changed the lexer tokens
order.
2020-06-15 13:26:32 +02:00
Émilie Feral
1cae01b120 [apps/solver] Equation: handle circularly defined equations 2020-06-15 13:09:03 +02:00
Evann DREUMONT
f0c46adebe [Feature] Add root and log setting (#290)
* [setting + layout] add function setting

* [GitHub] GitHub Actions

* [GitHub/Fix] GitHub Actions

* Update config.mak

* Fix setting name

* Fix setting name

* Fix setting name

* Fix setting name

* Fix setting name

* Fix setting name

* Fix typo error

* Fix trad

Co-authored-by: Quentin Guidée <quentin.guidee@gmail.com>
2020-06-13 00:10:33 +02:00
Quentin
b7a5abe597 [Feature] Add ALPHA to some shortcuts 2020-06-13 00:03:01 +02:00
Antonin Loubiere
5f15b37918 [Feature] Add Toolbox / Table shortcuts (#327) 2020-06-12 23:58:49 +02:00
Quentin
c12d3bbd33 [Fix] Toolbox crash 2020-06-12 23:55:38 +02:00
Quentin
a6162a9623 Merge pull request #332 from M4xi1m3/omega-3ds-dev
[Feature] Port Omega to the 3DS
2020-06-12 23:00:28 +02:00
Quentin
23002f2522 Merge pull request #338 from coco33920/correct_units
[Change] A way to stop the US Unit's imperialism
2020-06-12 22:32:53 +02:00
Quentin
e3fd67fff7 Merge branch 'M4xi1m3-omega-dev' into omega-dev 2020-06-12 22:14:02 +02:00
Quentin
a58a36e7da Merge branch 'omega-dev' of https://github.com/M4xi1m3/Omega into M4xi1m3-omega-dev 2020-06-12 22:13:31 +02:00
Quentin
bdf0930077 [Update] Themes 2020-06-12 22:13:18 +02:00
M4x1m3
5f928bb8f2 [build] Made HOME_DISPLAY_EXTERNALS=1 default (closes #343) 2020-06-12 21:17:27 +02:00
M4x1m3
2d1e48eb79 [apps/external] Fixed external app color bug 2020-06-12 21:16:18 +02:00
Émilie Feral
1ed97500d0 [ion] Increase stack in DEBUG=1 to avoid breaking the test due to stack
overflow
2020-06-12 14:12:35 +02:00
Émilie Feral
d21c9b0880 [poincare] Expression: clean magic numbers 2020-06-12 13:49:32 +02:00
Léa Saviot
ff3b756080 [apps/console] Fix the script console fetch status cleaning
unloadPythonEnvironment is not called when leaving the app, only after
editing a script, so it did not do what we wanted.
2020-06-11 14:12:50 +02:00
Émilie Feral
dfef134603 [poincare] typo 2020-06-11 12:03:21 +02:00
Émilie Feral
a26dc4be79 [apps/calculation/additional_outputs] Expression::removeUnit can be
called on reduced expression only
2020-06-11 12:02:48 +02:00
Émilie Feral
ad86378a5c [poincare] Unit: -_m should be beautified to -1x_m 2020-06-11 12:02:17 +02:00
Émilie Feral
555db32670 [apps/code] Fix test on variable_box_controller 2020-06-11 11:36:45 +02:00
Léa Saviot
6e6236a651 [poincare/integer] Integer::isExtractable
This factorizes and fixes wrong isExtractable checks
2020-06-10 11:57:41 +02:00
Léa Saviot
bee7441444 [apps/code] Fix an assertion break
Scenario: write a script, execute it in the console and open the
variable box, go back to edition and trigger autocompletion.
2020-06-10 10:49:22 +02:00
Arthur Camouseigt
d7fb5c256c [turtle] Fixed remanent images bug
We now erase the turtle before writing text. This way we can redraw it
on top of it, preventing overlapping and remanent images.

Those scripts are causing issues :
goto(-30,50)
write('coucou')
left(270)
goto(30,50)
write('oui')
-----------
up()
goto(-30,50)
write('coucou')
goto(30,50)
write('oui')

Change-Id: I01a6e5f8308937b5051165548c2046883da587d2
2020-06-10 10:35:13 +02:00
Léa Saviot
1ccb55a16e [apps/code] Fix script importation status
Scenario: Execute the script parabola.py, open the variable box, select
any leaf, enter, open the variable box again -> no variables are loaded
anymore
2020-06-09 15:12:13 +02:00
Léa Saviot
213d3d322d [apps/solver] Fix symbol replacement in equation solving
If the symbol replacement led to an undefined reduce equation, we did
not realize we could try without replacing the symbol.
2020-06-08 17:11:59 +02:00
Léa Saviot
9bd411f405 [apps/solver] Add test about failing equation resolution 2020-06-08 17:10:02 +02:00
Quentin
973a64c813 [Fix] Github conflicts fail in qstrdefs.in.h 2020-06-07 22:34:42 +02:00
Quentin
b058898e27 Merge pull request #345 from quentinguidee/omega-dev
[Feature] RGB files compatibility
2020-06-06 14:21:12 +02:00
Quentin
e4a3110149 [Feature] RGB files compatibility 2020-06-05 21:07:24 +02:00
Léa Saviot
84e8ac5bec [apps/calculation/i18n] Fix typo 2020-06-05 15:58:28 +02:00
Léa Saviot
9a1ff2bd33 [apps/code] Status at the beginning of a script is one byte long
This saves space + avoids clashes with the NumWorks Workshop when
exchanging scripts
2020-06-05 11:28:12 +02:00
Léa Saviot
d53a16eb91 [ion/storage] Add TODO 2020-06-05 11:02:39 +02:00
Léa Saviot
7699dc9929 [apps/on_boarding] Fix too long i18n 2020-06-05 10:31:58 +02:00
Émilie Feral
97ffab1fc2 build: Version 14.0.0 2020-06-04 14:58:20 +02:00
Émilie Feral
2630d0dee2 [poincare] Change approximation test to work on the device
implementation of libm (hypotf is not as accurate on the device)
2020-06-04 14:58:20 +02:00
Émilie Feral
9556ae3aa4 [poincare] Unit: comparison can rely on the pointer addresses only when
the object are ordered in a table. Otherwise, the compiler is free to
order them as it wants.

This fixes the test on the device: 10_m^2→_mm×_km simplifies to 10×_km×_mm
2020-06-04 14:58:20 +02:00
Émilie Feral
6abc3b8c99 [poincare] Enable to set POINCARE_TREE_LOG from environment variable 2020-06-04 14:58:20 +02:00
Léa Saviot
49e4abb964 [poincare/multiplication] Fix comment 2020-06-04 14:58:20 +02:00
Léa Saviot
72e342e1b1 [apps/curve_view] Fix drawArrow
Compute everything in pixels + fix glitch when zooming on the tip of
arrow(0,0,2,3)
2020-06-04 14:58:20 +02:00
Émilie Feral
2ebad3062c [apps/code] Test: strcpy isn't available on the device 2020-06-04 14:50:10 +02:00
Émilie Feral
fc238f639a [python] Fix test on matplotlib 2020-06-04 14:50:10 +02:00
Émilie Feral
4b83da21b7 [poincare] Fix Multiplication between 0 and a unreduced matrix: it
should not be equal to 0 but to Matrix(0)
2020-06-04 14:50:10 +02:00
Émilie Feral
420dd04766 [apps/shared][python/port] CurveView::drawArrow uses pixel computation
instead of float computation to avoid precision errors, by default the
arrow size is decided in pixels.
2020-06-04 14:50:10 +02:00
Léa Saviot
a9fbcf99b2 [poincare/test] Add failing test about multiplication simplification
The result should be 0*[[1,0][0,1]]^500, or, maybe later, [[0,0][0,0]]
2020-06-04 14:50:10 +02:00
Léa Saviot
0c040a7db6 [poincare/power] Fix infinite loop in reduction
Fix the broken simplification test 1/identity(2)^500
2020-06-04 14:50:10 +02:00
Léa Saviot
55ae258653 [poincare/test] Add failing matrix/power simplification test 2020-06-04 14:50:10 +02:00
Arthur Camouseigt
4b20c69174 [python/modturtle.cpp] Added support for float parameter in colormode()
The function can now accept the value 1.0 in addition to 1

Change-Id: I9a7021076844784ca997fc618253524089cbe855
(cherry picked from commit c69e1542ecc9a7e474a3f1e92cc97f644bf4b701)
2020-06-04 14:50:10 +02:00
Émilie Feral
1b2750c247 [python] matplotlib: add assertions to ensure authorized access to
args[i]
2020-06-04 14:50:10 +02:00
Arthur Camouseigt
aec25eb8d4 [matplotlib/modpyplot.cpp] Modified the error messages due to too many arguments
Change-Id: I48a8283a0c6311a52df152cbce3b0c824b46454b
(cherry picked from commit 94b90533c751c10dadb8e6144e613ed4839f09c4)
2020-06-04 14:50:10 +02:00
Arthur Camouseigt
e1a356fe88 [matplotlib/modpyplot.cpp] Added support for third parameter color in plot function
It is now possible to specify the color of the plot through a third positional argument in the plot function. However, is a keyword (color or c) is then used, it will override the previous color command.

Change-Id: I5a73ddb322e650db486de568e4a56b4752751cfb
(cherry picked from commit e6cc196cca405e5a4f8058a6af917aa0e7962b8a)
2020-06-04 14:50:10 +02:00
Arthur Camouseigt
4b88521e14 [matplotlib/modpyplot.cpp] Removing c keyword from some functions to match pyplot spec
Change-Id: I53fa8c9edc8bcfdfb9c36797b41a1c36494e2c74
(cherry picked from commit 42b245ed97d6fa3394316888489660f4f76f0a78)
2020-06-04 14:50:10 +02:00
Arthur Camouseigt
06dc97152c [matplotlib/modpyplot.cpp] Added support for keyword argument c, a shortcut for color
Change-Id: I89227a73fca6fd50ae190107fc23c3c7acadc6db
(cherry picked from commit bc642c2d8d105ed609cf8b4d86800879645afd7e)
2020-06-04 14:50:10 +02:00
Émilie Feral
7b150deaeb [apps/calculation] Hide additional outputs for Dutch exam mode 2020-06-04 14:50:10 +02:00
Émilie Feral
90fb9b4ea2 [apps/calculation] Hide calculations involving units in Dutch exam mode 2020-06-04 14:50:10 +02:00
Émilie Feral
fbeb5ed982 [apps/controller] All code regarding Dutch exam mode is in
ExamModeConfiguration
2020-06-04 14:50:10 +02:00
Léa Saviot
8412087cc8 [apps/calculaiton] Fix cursor bug
Scenario:
1 EXE MATRIX MATRIX Down Down 1 Up Up -> it crashed
2020-06-04 14:50:10 +02:00
Émilie Feral
e24de79a9e [apps/calculation] HistoryController: avoid dereferencing nullptr 2020-06-04 14:50:10 +02:00
Émilie Feral
66ba985108 [apps/code] In toolbox: plot(x,y) --> plot(x,y,color) 2020-06-04 14:50:10 +02:00
Émilie Feral
6c54fb4ebc [apps/code] Add 'write' to the toolbox (in Turtle module and catalog) 2020-06-04 14:50:10 +02:00
Émilie Feral
8ceb368047 [poincare] Adding a number before orphan unit is done at beautification
instead of at reducing (revert previous commit)

This fixes the following bug: input log(0*f(_t)) --> crash due to an
infinite loop where we remove/add 1 before the multiplication
2020-06-04 14:50:10 +02:00
Léa Saviot
163a14d9b9 [apps/exam_mode] Dutch exam mode available when language is EN/NL 2020-06-04 14:50:10 +02:00
Léa Saviot
1635f6132b [apps/code] Fix circular importation in the variable box
Scenario (crashed only on the calculator):

script1.py
from script2 import *
a=1

script2.py
from script1 import *
b=2
2020-06-04 14:50:10 +02:00
Léa Saviot
6819041c1d [apps/code] Remove TODOs 2020-06-04 14:50:10 +02:00
Léa Saviot
622cbe2e03 [apps/code] Fix auticompletion of color from Turtle
It added color(|)/color(,,) instead of just color(|)
2020-06-04 14:50:10 +02:00
Léa Saviot
e6b87be75e [apps/i18n] Fix some i18n
Did not fit or missed a space
2020-06-04 14:50:10 +02:00
Léa Saviot
02b7ed3e27 [poincare/test] Add test for commit 02a1246 2020-06-04 14:50:10 +02:00
Émilie Feral
2f4c59b881 [apps/code] VariableBoxController::addNodeIfMatches: factorize the checking
for node unicity and the insertion index computation
2020-06-04 14:50:10 +02:00
Léa Saviot
e5976984a2 [poincare/poincare] Fix typo 2020-06-04 14:50:10 +02:00
Arthur Camouseigt
d6e32594b8 [test/matplotlib.cpp][modpyplot.cpp] Changed matplotlib tests
Modified the tests for pyplot module and added error raisers to module functions

Change-Id: I164feafaf562f16d646841c1f9dfbbe32e6a763b
2020-06-04 14:50:10 +02:00
Arthur Camouseigt
68e3208799 [matplotlib/modpyplot.cpp] Removed function previously used for setting colors
Change-Id: I76bb489d5a5b78162873f68c5e3cca8cebb77aba
2020-06-04 14:50:10 +02:00
Arthur Camouseigt
c39b432dd6 [matplotlib/modpyplot.cpp] Adding keyword arguments support for plot function
plot function can now take into account the following keywords arguments :
- color

Change-Id: I29b82ba25fa68ec4d8e1797112f133440dee22a0
2020-06-04 14:50:10 +02:00
Arthur Camouseigt
b26d448573 [matplotlib/modpyplot.cpp] Adding keyword arguments support for scatter function
scatter function can now take into account the following keywords arguments :
- color

Change-Id: Iaea5a7a46d25e3efe2214368334ce859900d6ae6
2020-06-04 14:50:10 +02:00
Arthur Camouseigt
5daaa2c050 [matplotlib/modpyplot.cpp] Adding keyword arguments support for hist function
hist function can now take into account the following keyword arguments :
- color

Change-Id: I69eca6555d892db958d2bd002f438a40908b2d9d
2020-06-04 14:50:10 +02:00
Arthur Camouseigt
0e3684e137 [matplotlib/modpyplot.cpp] Adding keyword arguments support for bar function
bar function can now take into account the following keywords arguments :
- color

Change-Id: Iefa68cff59986d89c37cfecd7e3750f03c33ca59
2020-06-04 14:50:09 +02:00
Arthur Camouseigt
41da4f2bd5 [matplotlib/modpyplot] Adding keyword argument support for arrow function
Arrow function can now take into account the following keywords arguements :
- head_width
- color

Change-Id: I205dcd5776d53a4efcbf1e6da4edf29d8e399cab
2020-06-04 14:50:09 +02:00
Émilie Feral
555617aff3 [apps/code] Factorize VariableBoxController::addNode 2020-06-04 14:50:09 +02:00
Émilie Feral
705b1812f1 [apps/code] VariableBoxController: fix NodeNameCompare when nameLength >
nodeNameLength (step 2)
2020-06-04 14:50:09 +02:00
Émilie Feral
41bb169edd [apps/variable_box_controller] Auto-import: ignore variable when it is
the autocompleted one
2020-06-04 14:50:09 +02:00
Émilie Feral
d82e6de6e8 [apps/code] VariableBoxController: fix NodeNameCompare when nameLength >
nodeNameLength
2020-06-04 14:50:09 +02:00
Émilie Feral
2b53ea748d [apps/code] Typo 2020-06-04 14:50:09 +02:00
Émilie Feral
d99357fd0d [poincare] Power: don't escape normal shallowReduce for expression
containing matrix of complex form (for instance ConfidenceInterval).

This fixes the following bug: input (2_m*confidence(0.2,12))^(-1) -->
crashes
2020-06-04 14:50:09 +02:00
Émilie Feral
ade90db392 [poincare] UnitConvert: implement removeUnit since UnitConvert can be a
reduced expression
2020-06-04 14:50:09 +02:00
Émilie Feral
b3994127c2 [poincare] Remove false assertion (splitIntoNormalForm can be called by
denominator() at reduction - there is no reason that there is no unit at
this stage...)
2020-06-04 14:50:09 +02:00
Arthur Camouseigt
985c31920d [matplotlib/plot_store.cpp] Removed useless function
checkFloatType function used to check for an obj type before cast. This is already done by mp_obj_get_float

Change-Id: I745bb3066328678ab0b2a2149c8f38a84f26fbd2
2020-06-04 14:50:09 +02:00
Arthur Camouseigt
68ff71f72a [matplotlib/modpyplot.cpp] Modified the way to add mp_float
To prevent crashes caused by failed casts from char to float, removed optimization.

Change-Id: Ia91aafa007538b6c05f7aace5e5962989d313c98
2020-06-04 14:50:09 +02:00
Léa Saviot
34a4a3311a [apps/code] Add test on variable_box_controller 2020-06-04 14:50:09 +02:00
Léa Saviot
5412410723 [apps/code] Remove duplicates in the variable box
Example script:
from turtle import *
hideturtle()

We had "hideturtle" in the local variables, and "hideturtle()" in the
imported. Now we should only have the latter.
2020-06-04 14:50:09 +02:00
Léa Saviot
40d98389d4 [apps/code] Cleaner code in VariableBoxController::loadCurrentVariablesInScript 2020-06-04 14:50:09 +02:00
Léa Saviot
6b558c3328 [apps/code] Replace if with assertion 2020-06-04 14:50:09 +02:00
Léa Saviot
b466a8711b [apps/code] Remove dead code 2020-06-04 14:50:09 +02:00
Léa Saviot
38443c0e83 [apps/code] Fix VariableBoxController::empty
No scenario, but it seems right to reset m_shortenResultCharCount
2020-06-04 14:50:09 +02:00
Émilie Feral
8b64851903 [poincare] Multiplication::shallowBeautify: handle edge case: the
expression contains a unit but we can't extract it (2^_min for instance)
2020-06-04 14:50:09 +02:00
Léa Saviot
c102bf2e4e [apps/code] Fix again variable_box_controller
Scenario: add the script
from matplotlib.pyplot import *\nfrom math import *\n\ng=9.81\n\ndef x(t,v_0,alpha):\n  return v_0*cos(alpha)*t\ndef y(t,v_0,alpha,h_0):\n  return -0.5*g*t**2+v_0*sin(alpha)*t+h_0\n\ndef vx(v_0,alpha):\n  return v_0*cos(alpha)\ndef vy(t,v_0,alpha):\n  return -g*t+v_0*sin(alpha)\n\ndef t_max(v_0,alpha,h_0):\n  return (v_0*sin(alpha)+sqrt((v_0**2)*(sin(alpha)**2)+2*g*h_0))/g\n\ndef simulation(v_0=15,alpha=pi/4,h_0=2):\n  tMax=t_max(v_0,alpha,h_0)\n  accuracy=1/10**(floor(log10(tMax))-1)\n  T_MAX=floor(tMax*accuracy)+1\n  X=[x(t/accuracy,v_0,alpha) for t in range(T_MAX)]\n  Y=[y(t/accuracy,v_0,alpha,h_0) for t in range(T_MAX)]\n  VX=[vx(v_0,alpha) for t in range(T_MAX)]\n  VY=[vy(t/accuracy,v_0,alpha) for t in range(T_MAX)]\n  for i in range(T_MAX):\n    arrow(X[i],Y[i],VX[i]/accuracy,VY[i]/accuracy)\n  grid()\n  show()tan(if :\n    \n  celse:\n  )c
then autocomplete after the last c.
2020-06-04 14:50:09 +02:00
Léa Saviot
5d49f5dca2 [apps/code] Fix VariableBoxController::addNodesFromImportMaybe
Scenario: write a ascrip "from matplotlib.pyplot0 import *" than open
the variable box
2020-06-04 14:50:09 +02:00
Léa Saviot
9d8eb1dbb6 [apps/code] Fix misnamed i18n 2020-06-04 14:50:09 +02:00
Léa Saviot
2bea3f3d47 [apps/code] Fix again VariableBoxController::loadCurrentVariablesInScript 2020-06-04 14:50:09 +02:00
Léa Saviot
00291c8974 [apps/code] Fix var initialisation in variable_box_controller 2020-06-04 14:50:09 +02:00
Arthur
59bf8bbcf4 [matplotlib] Added cyan color to the color palette
Change-Id: I29476d8148ad98285505adc460b90628573518fa
2020-06-04 14:50:09 +02:00
Arthur
472cfc012c [matplotlib] Added colors to the toolbox in python
Change-Id: I3ff3d4fb3552bcb8c375c77651db3b7c44991646
2020-06-04 14:50:09 +02:00
Arthur
fe7c4b1a8a [python/turtle] Added write method
Allows user to print strings with the turtle

Change-Id: I06a3832f6fa36d29506be10c48a1b2fb34cb69fb
2020-06-04 14:50:09 +02:00
Arthur
7cd0b7e0e0 [matplotlib] Removed useless initializers in PlotStore constructor
Change-Id: Idea0ce07cbc800139539f9d3fb27811920645184
2020-06-04 14:50:09 +02:00
Arthur
13d0bcf676 [matplotlib] Modified isEmpty method for showing axis
Added a condition for being considered empty.
Allows axis("on") or axis((0,1,2,3)) to display something with show()
This behavior is the same as the python module

Change-Id: If5f3b07c280ee9ead2bc23d23cbbb4f01da7eae5
2020-06-04 14:50:09 +02:00
Émilie Feral
d8666a52d3 [python] matplotlib: fix tests about arrow function 2020-06-04 14:50:09 +02:00
Émilie Feral
0c9fb57b33 [python] matplotlib: check float type of the head_width arg of arrow function 2020-06-04 14:50:09 +02:00
Émilie Feral
9b7c47a7f0 [python] matplotlib: arrow can have up to 6 args 2020-06-04 14:50:09 +02:00
Émilie Feral
12db7a5093 [apps/shared] Change default shape of arrow in CurveView (to match
matplotlib shape)
2020-06-04 14:50:09 +02:00
Émilie Feral
083f959b7b [python] matplotlib: Enable to change the arrow shape via the head_width
arg
2020-06-04 14:50:09 +02:00
Émilie Feral
c826c53659 [apps/shared] CurveView: change drawArrow API to take arrow shape
arguments in float instead of coordinates
2020-06-04 14:50:09 +02:00
Émilie Feral
0f8f82b94b [python] matplotlib: Add a parameter to to arrow to set the arrow width 2020-06-04 14:50:09 +02:00
Émilie Feral
e92b56b78e [apps/shared] CurveView: change drawArrow arguments (new definition of
arrow shape)
2020-06-04 14:50:09 +02:00
Émilie Feral
e2c06cbb44 [python] matplotlib: add color argument to plot, scatter, hist, bar and
arrow
2020-06-04 14:50:08 +02:00
Émilie Feral
a22990943b [python] matplotlib: missing static keyword 2020-06-04 14:50:08 +02:00
Émilie Feral
273d10dc26 [python] Change names: ColorParse::ParseColor --> Color::Parse 2020-06-04 14:50:08 +02:00
Émilie Feral
5aaa6723d0 [apps/calculation] Fix duplicate removal in unit additional results
This fixes the following bug: input _ns, go to additional results -->
crash
2020-06-04 14:50:08 +02:00
Émilie Feral
5725ba1c14 [escher] LayoutField: reset selection when clearing layout 2020-06-04 14:50:08 +02:00
Émilie Feral
80015ca6aa [apps/shared] RoundCursorView: fix potential black trail when redrawing
cursor (issue #1458 on GitHub)
2020-06-04 14:50:08 +02:00
Émilie Feral
9a3e2c960f [escher] LayoutField: update the grey squares when using insertion
cursor
2020-06-04 14:50:08 +02:00
Émilie Feral
79e7626dc3 [escher] LayoutField: the insertion cursor can't point to an EmptyLayout
as it might be destroyed

This fixes the following crash: input 1, OK, input ans/[], go up to the history --> crash
2020-06-04 14:50:08 +02:00
Émilie Feral
a53379781f [apps/shared] Fix comment 2020-06-04 14:50:08 +02:00
Léa Saviot
691c6739af [apps/variable_box_controller] Fix loadCurrentVariablesInScript
Scenario: write the script:

def squares():
  for i in range(660):
    forward(L)lo)

Put the cursor right of "lo" and press backspace.
2020-06-04 14:50:08 +02:00
Émilie Feral
03367cfdf6 [poincare] Makefile: POINCARE_TREE_LOG is by set by default when DEBUG=1 2020-06-04 14:50:08 +02:00
Émilie Feral
b596488a01 [poincare] Multiplication::shallowBeautify: removeUnit can only be
called on reduced expression

This fixes the following bug: input i+10*sqrt(i)
2020-06-04 14:50:08 +02:00
Émilie Feral
a4c591dea6 [apps/calculation] additional_outputs: fix complex range for infinite
values
2020-06-04 14:50:08 +02:00
Émilie Feral
6a0d65b049 [apps/calculation] additional_outputs: the complex illustration chose
its range to be orthornomal
2020-06-04 14:50:08 +02:00
Émilie Feral
d3bd086125 [apps/graph] Fix order of actions to edit the function name, we should
update the bufferSize before setting the text

This fixes the following bug: add a function, rename it "f123456",
change its type to a polar function, rename it --> crash
2020-06-04 14:50:08 +02:00
Émilie Feral
465fa5c63f [escher] TextField: fix insertTextAtLocation (confusion between size and
length)

This fixes the following bug: in a textfield, input '000', clear, input
'00', backspace --> crash
2020-06-04 14:50:08 +02:00
Émilie Feral
ab69c0069c [python] Fix alignement issues in MicroPython::collectRootsAtAddress 2020-06-04 14:50:08 +02:00
Émilie Feral
f2a1c635ef [apps/code] I18n: Missing translations 2020-06-04 14:50:08 +02:00
Léa Saviot
7d5304686d [apps/scrollable_multiple_expressions_view] Add TODO comment 2020-06-04 14:50:08 +02:00
Léa Saviot
b096d6f5e4 [escher/table_view] COding style 2020-06-04 14:50:08 +02:00
Léa Saviot
44af4b1fde [escher/table_view] Fix numberOfDisplayableRows/Columns
Did not take into account the margin so was too big sometimes
2020-06-04 14:50:08 +02:00
Léa Saviot
515aa543d3 [escher/table_view] Remove dead code 2020-06-04 14:50:08 +02:00
Léa Saviot
12a45ef8e6 [escher/poincare] Coding style 2020-06-04 14:50:08 +02:00
Léa Saviot
9d5e58f32b [escher/scroll_view] Do not compute offset if view invisible 2020-06-04 14:50:08 +02:00
Léa Saviot
3e4478454c [escher] Avoid useless redrawing in ExpressionView::setLayout 2020-06-04 14:50:08 +02:00
Léa Saviot
e8d97f561c [apps/proba] Fix tests 2020-06-04 14:50:08 +02:00
Léa Saviot
9b2f91f5e1 [apps/probability] Geometric distribution default computed value is 1 2020-06-04 14:50:07 +02:00
Léa Saviot
a9c47a9468 [apps/probability] Change geometric distribution definition
THe distribution now represents the number of trials neded before a
success, so is defined for k in {1, 2, 3, ...}
2020-06-04 14:50:07 +02:00
Léa Saviot
d200688f20 [apps/proba] Geometric distibution should return 0, not nan for x < 0 2020-06-04 14:50:07 +02:00
Léa Saviot
503227b49b [apps/proba] Fix float/integer comparison 2020-06-04 14:50:07 +02:00
Léa Saviot
5f26ca40cc [apps/escher] Fix scroll view indicator margin
So it does not overflow the scrolled view. Fixed for the language
controllers (on boarding app and settings), one value was changed from a
magic 14 to Metric::CommonTopMargin = 15, it did not seem to break
anything.
2020-06-04 14:50:07 +02:00
Léa Saviot
b8244ec0c5 [apps] Fix margins of LanguageController
Add margin at the bottom and fix margin values
2020-06-04 14:50:07 +02:00
Léa Saviot
d41b93c711 [apps/code] Put back the squares script template 2020-06-04 14:50:07 +02:00
Léa Saviot
6dfccc6edf Revert "[apps/code] EXE event accepts autocompletion"
This reverts commit 5a96fd0e5de4a9bda30900e0c81a0b15f3fe081a.
2020-06-04 14:50:07 +02:00
Émilie Feral
88a39c335f [poincare] Fix Unit::IsISEnergy 2020-06-04 14:50:07 +02:00
Émilie Feral
7bb4a2ae98 [apps/calculation] Additional outputs: do not display identical unit as
the outpu
2020-06-04 14:50:07 +02:00
Émilie Feral
05a42cd2eb [apps/shared] PoincareHelpers: implement Reduce static inline function 2020-06-04 14:50:07 +02:00
Émilie Feral
1f9cdc5648 [apps] Calculation: do not offer additional results on units if there
will be only one identical to the output
2020-06-04 14:50:07 +02:00
Émilie Feral
7b2d020128 [poincare] Unit: implement IsIS 2020-06-04 14:50:07 +02:00
Émilie Feral
0f4eee2d71 [poincare] Add comment on how Units are built 2020-06-04 14:50:07 +02:00
Émilie Feral
a48f65ba95 [poincare] Unit: ensure one unique instance of each prefix 2020-06-04 14:50:07 +02:00
Émilie Feral
bcbdc9312e [poincare] Fix Unit::isSecond, Unit::isMeter and Unit::isKilogram: the
EmptyPrefix is not unique, we can't only compare pointers
2020-06-04 14:50:07 +02:00
Émilie Feral
b6ee72bc21 [poincare] Clean tests on Unit 2020-06-04 14:50:07 +02:00
Émilie Feral
3b7d7e7898 [poincare] Clean magic numbers in Unit 2020-06-04 14:50:07 +02:00
Émilie Feral
67b1c12bf7 [poincare] Remove useless variables 2020-06-04 14:50:07 +02:00
Léa Saviot
0b88bb0767 [apps/code] Reset m_autocompletionResultIndex when addingAutocompletion 2020-06-04 14:50:07 +02:00
Léa Saviot
a53edf5202 [apps/code] Remove TODOs 2020-06-04 14:50:07 +02:00
Léa Saviot
f763bb50ac [apps/code] Do not display subtitles in var box from console 2020-06-04 14:50:07 +02:00
Léa Saviot
780c593c26 [apps/code] Autocompletion for "abs" proposes parentheses 2020-06-04 14:50:06 +02:00
Léa Saviot
b070eaad45 [apps/code] Remove double call to addAutocompletion 2020-06-04 14:50:06 +02:00
Léa Saviot
c915eb0b27 [apps/code] Do not autocomplete with arguments
Eg : arr|ow(x,y,dx,dy) should give arrow(|,,,)
2020-06-04 14:50:06 +02:00
Léa Saviot
e4aac3f9c6 [apps/code] Remove more TODOs 2020-06-04 14:50:06 +02:00
Léa Saviot
8142e1d344 [apps/code] Remove TODO comment 2020-06-04 14:50:06 +02:00
Léa Saviot
0dac6b5bac [apps/code] Replace int with size_t 2020-06-04 14:50:06 +02:00
Léa Saviot
7ef17960c8 [apps/code/variable_box_controller] More TODOs removal 2020-06-04 14:50:06 +02:00
Léa Saviot
714410287a [apps/code] Remove TODOs 2020-06-04 14:50:06 +02:00
Léa Saviot
68867e45e7 [apps] Factorize isDisplayingEmptyController
Because we can now, it might need to be de-factorized later, if more
classes inherit from alternate_empty_nested_menu_controller
2020-06-04 14:50:06 +02:00
Léa Saviot
c5f2f7cf83 [apps/code] Remove TODO comments 2020-06-04 14:50:06 +02:00
Léa Saviot
43d0ab5ea7 [apps] Rename displayEmptyController -> displayEmptyControllerIfNeeded 2020-06-04 14:50:06 +02:00
Léa Saviot
e28f4ed7e2 [apps/code/variable_box_controller] Use std::min 2020-06-04 14:50:06 +02:00
Léa Saviot
59db24c518 [apps/code/variable_box_controller] Comment out unused variables 2020-06-04 14:50:06 +02:00
Léa Saviot
f306b51fc5 [apps/escher] Move ModalViewEmptyController to escher 2020-06-04 14:50:06 +02:00
Léa Saviot
645a55284f [apps/variable_box_empty_controller] Remove unneeded include 2020-06-04 14:50:06 +02:00
Léa Saviot
790cb374df [apps/code] i18n in alphabetical order 2020-06-04 14:50:06 +02:00
Léa Saviot
8ed902ceb2 [app/code] Comment about ContentFetchedFromConsoleStatus in Script 2020-06-04 14:50:06 +02:00
Léa Saviot
cf6b9d580b [apps/code] rename Script::scriptContent() -> Script::content() 2020-06-04 14:50:06 +02:00
Léa Saviot
6d7b294bca [apps/escher] Rename ToolboxMessageTree::children -> childAtIndex 2020-06-04 14:50:06 +02:00
Léa Saviot
bba5b237d2 [apps/code] Display different varbox titles from editor and console 2020-06-04 14:50:06 +02:00
Léa Saviot
5986716031 [apps/code] Fix first varbox row that never appeared again
After scrolling down
2020-06-04 14:50:06 +02:00
Léa Saviot
2fbf5d2d9f [apps/code] No variables starting with underscore in imported variables
In the variable box
2020-06-04 14:50:06 +02:00
Léa Saviot
ccca872a0f [appx/code] Empty variable box before loading it in the console 2020-06-04 14:50:06 +02:00
Léa Saviot
0c82334a96 [apps/code] Fix preventing module importations in varbox from console 2020-06-04 14:50:06 +02:00
Léa Saviot
5ffcb77c69 [apps/code] Fix missing return 2020-06-04 14:50:06 +02:00
Léa Saviot
ac654f0097 [apps/code] Load varbox before returning it in console 2020-06-04 14:50:06 +02:00
Léa Saviot
d1c8bbdaf7 [apps/code] The console marks imported script for the var box
After lauching the console, if we fetch a script we mark it as fetched.
When the variable box displays variables from imported scripts, it scans
all the variables from the scripts marked as fetched.
2020-06-04 14:50:06 +02:00
Léa Saviot
9e973adbab [apps/code] VarBox from console 2020-06-04 14:50:06 +02:00
Léa Saviot
c81420c4b2 [apps/code] EXE event accepts autocompletion 2020-06-04 14:50:06 +02:00
Léa Saviot
d8cab18eb3 [apps/code] Do not display varbox source name if it does not fit 2020-06-04 14:50:06 +02:00
Léa Saviot
4fb0a7e467 [apps/code] properly display the importation source
- It sould be nameOfScript.py, not just nameOfScript, when the source is
a script
- Fix the source for script name variables. For instance, "from
script1 import *" should display the node "script1" with the source "script1.py"
- If a script has the same name as a module, the module will be imported
and not the script, so do not load its variables (even if the module is
not in the toolbox).
2020-06-04 14:50:06 +02:00
Léa Saviot
f49bf76b19 [apps/code] More complete comment 2020-06-04 14:50:06 +02:00
Léa Saviot
2eed894599 [apps/variable_box_empty_controller] Draw the background
This was not necessary when it was only used for the expressions
variable box, because the background was already of the right color
thanks to the previous displayed menu. We need to draw it for the python
variable box.
2020-06-04 14:50:06 +02:00
Léa Saviot
3fe6af281f [apps/code] Fix variable box that crashed 2020-06-04 14:50:05 +02:00
Léa Saviot
a7773576f8 [apps/code] Fix PythonTextArea::autocompletionType 2020-06-04 14:50:05 +02:00
Léa Saviot
f9bbc94eea [apps/code] Handle autocompletionAlternativeAtIndex with no nodes 2020-06-04 14:50:05 +02:00
Léa Saviot
2a823419ff [apps/code] Cycle through possible autocompletions with up/down 2020-06-04 14:50:05 +02:00
Léa Saviot
afdf34bbb9 [apps/code] Signed/unsigned comparison 2020-06-04 14:50:05 +02:00
Léa Saviot
e7bfb3b5f3 [apps/code] Use variable 2020-06-04 14:50:05 +02:00
Léa Saviot
94e9a10f16 [apps/code] Autocomplete only with parentheses if needed
For instance, type "abs", there is "()" autocompletion
2020-06-04 14:50:05 +02:00
Léa Saviot
5d2910188d [apps/code] Add the parentheses in the autocompletion 2020-06-04 14:50:05 +02:00
Léa Saviot
2ed0c85ebf [apps/code] Autocompletion end is end of token, not next ' ' 2020-06-04 14:50:05 +02:00
Léa Saviot
da2730dd64 [apps/code] Autocomplete at the end of tokens
Not at the end of "words" separated by spaces.
2020-06-04 14:50:05 +02:00
Léa Saviot
9bf361d5a5 [apps/code] Autocomplete only after edition
Reverts 39c3d66cd
2020-06-04 14:50:05 +02:00
Léa Saviot
4502ae4fbd [apps/code] Change autocomplete color 2020-06-04 14:50:05 +02:00
Léa Saviot
7636c001e1 [apps/code] Fix varbox parentheses bug
Scenario: write i, open the varbox and select "in" -> parentheses are
added, but there shouldn't be any
2020-06-04 14:50:05 +02:00
Léa Saviot
e630b0e9e5 [apps/code] Remove __import__ from builtins 2020-06-04 14:50:05 +02:00
Léa Saviot
e73ae9bcdf [apps/code] Fix varbox that should autocomplete the current word 2020-06-04 14:50:05 +02:00
Léa Saviot
dd6c2a4f54 [apps/code] Translate the variable box 2020-06-04 14:50:05 +02:00
Léa Saviot
0f2ac5b110 [escher/text_field] Fix std::min use 2020-06-04 14:50:05 +02:00
Léa Saviot
5393ec7273 [apps/code] Add matplotlib.pyplot in the var box 2020-06-04 14:50:05 +02:00
Léa Saviot
a165c6d85b [escher] Clean InputEventHandler 2020-06-04 14:50:05 +02:00
Léa Saviot
003317647e [apps/code] Display empty message in var box 2020-06-04 14:50:05 +02:00
Léa Saviot
398de8bda3 [apps/code] Empty controller in the var box 2020-06-04 14:50:05 +02:00
Léa Saviot
f98c171d2a [apps/variable_box] Prepare for Code::VariableBox factorization 2020-06-04 14:50:05 +02:00
Léa Saviot
f371126708 [apps/code] Fix assertion 2020-06-04 14:50:05 +02:00
Léa Saviot
33d8d10286 [apps/code] Do not select subtitles in the variable box 2020-06-04 14:50:05 +02:00
Léa Saviot
0d6016116d [apps/code] Cosmetic fixes on the variable box 2020-06-04 14:50:05 +02:00
Léa Saviot
bbeb17c3a9 [apps/code] Rename ScriptNode::Types to With/WithoutParentheses
Because some functions already have the parentheses in their name, so
their type would have been Variable but it is clearer to give it the
type WithoutParentheses. this is the case for nodes created from toolbox
nodes.
2020-06-04 14:50:05 +02:00
Léa Saviot
74b786f875 [apps/code] Add list methods to the variable box 2020-06-04 14:50:05 +02:00
Léa Saviot
3d64b8dc47 [apps] AlternateEmptyNestedMenuController handles empty lists 2020-06-04 14:50:05 +02:00
Léa Saviot
b3d87c0e18 [escher/stack_view_controller] Inline some methods 2020-06-04 14:50:05 +02:00
Léa Saviot
b41d1e393e [apps/code] Autocomplete when cursor at the end of the word
Not just after adding or deleting text
2020-06-04 14:50:05 +02:00
Léa Saviot
03471bb7b4 [apps/code] Insert right text form var box
The text was iffset due to the subtitle rows
2020-06-04 14:50:05 +02:00
Léa Saviot
38854d2435 [apps/code] Fix cell type 2020-06-04 14:50:05 +02:00
Léa Saviot
1d416b3299 [apps/code] Fix varbox row height 2020-06-04 14:50:05 +02:00
Léa Saviot
d5e1e620fd [apps/code] Display source and description in var box 2020-06-04 14:50:05 +02:00
Léa Saviot
96d68d6b44 [apps/code/varbox] Subtitles and basic items are displayed properly 2020-06-04 14:50:05 +02:00
Léa Saviot
34a1a8e35f [apps/code] Fix willDisplayCellForIndex
Problem: some nodes were not displayed, because the subtitles count was
not taken into account when using the index parameter if
willDisplayCellForIndex
2020-06-04 14:50:05 +02:00
Léa Saviot
69abd75460 [apps/code] Clean ScriptNodeCell 2020-06-04 14:50:05 +02:00
Léa Saviot
0863abc4da [apps/code] VariableBox cells with node origins 2020-06-04 14:50:05 +02:00
Léa Saviot
52644bf76d [apps/code] Subtitles in the variable box 2020-06-04 14:50:05 +02:00
Léa Saviot
a98f4b6ca0 [apps/code] Edit the builtins list 2020-06-04 14:50:05 +02:00
Léa Saviot
6aa150d5d7 [apps/code] Cleaning 3 2020-06-04 14:50:05 +02:00
Léa Saviot
86435bf647 [apps/code] Cleaning 2 2020-06-04 14:50:04 +02:00
Léa Saviot
327dd0ac41 [apps/code] Cleaning 1 2020-06-04 14:50:04 +02:00
Léa Saviot
044dc706cb [apps/code] Remove unneeded code 2020-06-04 14:50:04 +02:00
Léa Saviot
332cd0ed3a [apps/code] Handle "from a.b import *" in the var box 2020-06-04 14:50:04 +02:00
Léa Saviot
97aaff9430 [apps/code] Fix imported script variables fetching 2020-06-04 14:50:04 +02:00
Léa Saviot
1e59abf55b [apps/code] Load global and imported variables from imported scripts 2020-06-04 14:50:04 +02:00
Léa Saviot
4f24a7d870 [apps/code] Use nodesForOrigin 2020-06-04 14:50:04 +02:00
Léa Saviot
0428c814e8 [apps/code] Fix array shifting 2020-06-04 14:50:04 +02:00
Léa Saviot
0b0a7227a6 [apps/code– Fix typo in python_toolbox 2020-06-04 14:50:04 +02:00
Léa Saviot
2b83d9b952 [apps/code] Continue cleaning and refactoring in variable box 2020-06-04 14:50:04 +02:00
Léa Saviot
b11bab4045 [apps/code] Refactoring 2020-06-04 14:50:04 +02:00
Léa Saviot
d2bfe01cd4 [apps/code] VariableBoxController::contains method 2020-06-04 14:50:04 +02:00
Léa Saviot
4cb947759d [apps/code] Get imported modules in the variable box 2020-06-04 14:50:04 +02:00
Léa Saviot
a0f1d0f24b [apps/code] Start getting importations in the variable box 2020-06-04 14:50:04 +02:00
Léa Saviot
78a747d9c6 [apps/code] Start loading imported variables in var box 2020-06-04 14:50:04 +02:00
Léa Saviot
6311f408b4 [escher/text_area] Fix overlap in textInsert 2020-06-04 14:50:04 +02:00
Léa Saviot
af3394d35a [apps/code] Better event handling for autocompletion 2020-06-04 14:50:04 +02:00
Léa Saviot
5a37b1df53 [apps/code] Use Default color at beginning of autocompleted token 2020-06-04 14:50:04 +02:00
Léa Saviot
fd1b0e08ee [escher/text_field] Fix insertion size computation 2020-06-04 14:50:04 +02:00
Léa Saviot
ac3a09bdeb [apps/code] Insert only the completing text when autocompleting 2020-06-04 14:50:04 +02:00
Léa Saviot
ad5c998b97 [apps/code] Add module names to the builtins 2020-06-04 14:50:04 +02:00
Léa Saviot
14f914e3d6 [apps/code] Remove unused functions and argument 2020-06-04 14:50:04 +02:00
Léa Saviot
bc4d96bc3f [apps/code] Reload the variable box less often 2020-06-04 14:50:04 +02:00
Léa Saviot
e32a5ccc17 [apps/code] Simpler VarBoxController::autocompletionForText 2020-06-04 14:50:04 +02:00
Léa Saviot
6b93a5b83a [apps/code] Load current script vars according to autocompleted text 2020-06-04 14:50:04 +02:00
Léa Saviot
e934bb39e3 [apps/code] Clean ScriptNode 2020-06-04 14:50:04 +02:00
Léa Saviot
1b828196e9 [apps/code] Use ScriptNode::Type in VariableBoxController 2020-06-04 14:50:04 +02:00
Léa Saviot
f412d95584 [apps/code] Load builtins according to autocompleted text 2020-06-04 14:50:04 +02:00
Léa Saviot
1599b16e03 [apps/code] Fix current script variables fetching 2020-06-04 14:50:04 +02:00
Léa Saviot
4b36a16cea [apps/code] Fix NodeNameCompare 2020-06-04 14:50:04 +02:00
Léa Saviot
86349675c1 [apps/code] Code cleaning 2020-06-04 14:50:04 +02:00
Léa Saviot
25f73770de [apps/code] Remove compilation warning 2020-06-04 14:50:04 +02:00
Léa Saviot
558d539194 [apps/code] Clean VariableBoxController::scriptNodeAtIndex 2020-06-04 14:50:04 +02:00
Léa Saviot
6f2dedf8ee [apps/code] Search aphabetically if var is already in var box 2020-06-04 14:50:04 +02:00
Léa Saviot
75ea4ce74e [apps/code] Clean comments 2020-06-04 14:50:04 +02:00
Léa Saviot
5d4a3f8726 [apps/code] Add variables in alphabetical order in the var box 2020-06-04 14:50:03 +02:00
Léa Saviot
c273f734fe [apps/code] Add some buitin vars in the varbox 2020-06-04 14:50:03 +02:00
Léa Saviot
eec92d51fc [apps/code] Fix VariableBoxController::autocompletionForText 2020-06-04 14:50:03 +02:00
Léa Saviot
0f02a61dc4 [apps/code] Use textLength in VarBoxController::insertTextInCaller 2020-06-04 14:50:03 +02:00
Léa Saviot
eeb42f2544 [apps/code] autocompletionText uses the right text length
Before, there was no notion that the autocompleted text might not be a
null terminated string.
2020-06-04 14:50:03 +02:00
Léa Saviot
12bb77cd9f [apps/code] Do not import the same current variable twice 2020-06-04 14:50:03 +02:00
Léa Saviot
7f486d790f [apps/code] Get current script variables and functions 2020-06-04 14:50:03 +02:00
Léa Saviot
b9693f1f26 [apps/code] Load variable box with script index argument 2020-06-04 14:50:03 +02:00
Léa Saviot
321f87ea78 [apps/code] VariableBoxController::autocompletionForText 2020-06-04 14:50:03 +02:00
Léa Saviot
f883516716 [apps/code] Editor asks VariableBox for autocompletion 2020-06-04 14:50:03 +02:00
Léa Saviot
72aedaadd0 [apps/code] VarBox contains current/buitin/imported vars and functions 2020-06-04 14:50:03 +02:00
Léa Saviot
1e2492c5f4 [apps/code] Autocomplete only at the end of the word
For instance, if the cursor is: "he|llo" and the user adds the letter
'i', there is no autocompletion provided as the cursor is still in the
middle of a word.
2020-06-04 14:50:03 +02:00
Léa Saviot
77e34f0446 [apps/code] Reload the view for autocompletion changes 2020-06-04 14:50:03 +02:00
Léa Saviot
f82079a40a [apps/code] Autocomplete only if char before cursor is not ' ' or '\n' 2020-06-04 14:50:03 +02:00
Léa Saviot
a2cc923a02 [apps/code] Fix assertion 2020-06-04 14:50:03 +02:00
Léa Saviot
5dd4f12ee3 [apps/code] Handle acception/dismissal of autocompletion 2020-06-04 14:50:03 +02:00
Léa Saviot
938e0dd840 [apps/code] Autocompletion steps 2020-06-04 14:50:03 +02:00
Léa Saviot
343d2328b8 [ion/utf8_helper] EndOfWord helper 2020-06-04 14:50:03 +02:00
Léa Saviot
32fbea9d06 [apps/code] Handle autocomplete coloring 2020-06-04 14:50:03 +02:00
Léa Saviot
9b8b0bc98f [apps/code] PythonTextArea should always be the PythonUser when coloring 2020-06-04 14:50:03 +02:00
Émilie Feral
62e2e733b2 [poincare] Add comment on unit tests 2020-06-04 14:50:03 +02:00
Émilie Feral
22fd3388ed [poincare] Add tests on Unit::BuildTimeSplit 2020-06-04 14:50:03 +02:00
Émilie Feral
a248302132 [poincare] Unit: define order on representatives in a way that time
addition are displayed: years + months + ... + seconds
2020-06-04 14:50:03 +02:00
Émilie Feral
5fa50ec79d [poincare] Unit::BuildTimeSplit can split negative time 2020-06-04 14:50:03 +02:00
Émilie Feral
23540e93ce [poincare] Unit::BuildTimeSplit rounds its argument to avoid displaying
very small seconds due to approximations

This fixes: Input "310_min", in additional results, you get
"5_h+10_min+0.000000???_s"
2020-06-04 14:50:03 +02:00
Émilie Feral
fe0a858352 [poincare] Unit: improve BuildTimeSplit to avoid displaing null sub unit
in the final addition and to keep the fractional part of the seconds
2020-06-04 14:50:03 +02:00
Émilie Feral
115ae59b5a [apps/calculation] additional_outputs: reorder unit addition outputs 2020-06-04 14:50:03 +02:00
Émilie Feral
73a598e023 [poincare] Unit: enable to tune both the prefix and the Representant or
just the prefix on a given Unit
2020-06-04 14:50:03 +02:00
Émilie Feral
e063c0a913 [apps/calculation] additional_outputs: add electronVolt row to
additional results on energy units
2020-06-04 14:50:03 +02:00
Émilie Feral
ec95ed0789 [poincare] Add Unit::ElectronVolt builder 2020-06-04 14:50:03 +02:00
Émilie Feral
0d0a37c02a [apps/calculation] additional_outputs: improve unit_list_controller to
compute all expressions before being displayed
2020-06-04 14:50:03 +02:00
Émilie Feral
785d7a0a62 [apps] additional_outputs: misc. clean-up on unit additional results 2020-06-04 14:50:03 +02:00
Émilie Feral
1a9014645c [apps] additional_outputs: fill unit additional results 2020-06-04 14:50:03 +02:00
Émilie Feral
53db27ffeb [poincare] Discard UnitConversion::Classic mode. This will be done in
Calculation app
2020-06-04 14:50:03 +02:00
Émilie Feral
7b28f760b7 [poincare] Float: float can be layouted 2020-06-04 14:50:03 +02:00
Émilie Feral
83a63155b1 [apps] PoincareHelpers: enable to specify the UnitConversion mode in
Simplify
2020-06-04 14:50:03 +02:00
Émilie Feral
397aac27c5 [poincare] Add test on Unit helpers 2020-06-04 14:50:03 +02:00
Émilie Feral
71b13bb84f [poincare] Fix Unit::BuildTimeSplit 2020-06-04 14:50:03 +02:00
Émilie Feral
845a118073 [poincare] Add Unit::BuildTimeSplit and helpers for time units 2020-06-04 14:50:02 +02:00
Émilie Feral
94c5941fb5 [poincare] Unit: improve ChooseBestMultipleForValue 2020-06-04 14:50:02 +02:00
Émilie Feral
8d12cf1e8b [poincare] Multiplication: clean code 2020-06-04 14:50:02 +02:00
Émilie Feral
ec7382c75e [poincare] Unit::chooseBestMultipleForValue handles edge cases (inf, 1,
0) cases itself
2020-06-04 14:50:02 +02:00
Émilie Feral
687766567d [poincare] Multiplication::shallowBeautify: don't bother to choose best
unit for UnitConversion::Classic
2020-06-04 14:50:02 +02:00
Émilie Feral
4d7b9aa2a9 [poincare] Add watthour representation to classic unit conversion 2020-06-04 14:50:02 +02:00
Émilie Feral
cc114900fa [poincare] Add Liter representation to classic unit conversion 2020-06-04 14:50:02 +02:00
Émilie Feral
e2dc79c2d5 [poincare] Partially implement simplification for UnitConversion::Classic 2020-06-04 14:50:02 +02:00
Léa Saviot
ddd3904ea9 [apps/calculation] Translate ES toolbox 2020-06-04 14:50:02 +02:00
Roberta Rabotti
33b2633729 [it]python 2020-06-04 14:50:02 +02:00
Roberta Rabotti
71ab038e97 [it]python 2020-06-04 14:50:02 +02:00
Roberta Rabotti
98da319a2b [it]python 2020-06-04 14:50:02 +02:00
Roberta Rabotti
e203f7ae08 [it]Forma 2020-06-04 14:50:02 +02:00
Léa Saviot
e542296b81 [apps/shared.i18n] Remove unused value 2020-06-04 14:50:02 +02:00
Léa Saviot
6cd9b744e1 [apps/code] Fix some toolbox descriptions 2020-06-04 14:50:02 +02:00
Léa Saviot
33ebd3d1aa [apps/pt] Remove superfluous upper case 2020-06-04 14:50:02 +02:00
Serenela Moreira
21e4af967a [pt] base and catalog translations
new translations that were missing after version 13
2020-06-04 14:50:02 +02:00
Léa Saviot
e803ada15f [apps/Makefiles] Automatize i18n adding for different locales 2020-06-04 14:50:02 +02:00
Roberta Rabotti
8aa323b043 [it]python 2020-06-04 14:50:02 +02:00
Léa Saviot
c7c47acc1b [build/config] Change the languages order 2020-06-04 14:50:02 +02:00
Léa Saviot
64a221a72c [apps/code] Add missing i18n (not translated yet) 2020-06-04 14:50:02 +02:00
Léa Saviot
c9d7229566 [apps/code] Fix ' characters 2020-06-04 14:50:02 +02:00
Léa Saviot
883455c958 [apps] IT and NL iso6391 definitions 2020-06-04 14:50:02 +02:00
Roberta Rabotti
40a1f1a10c [it]changes 2020-06-04 14:50:02 +02:00
Roberta Rabotti
51d20a6164 [it]changes 2020-06-04 14:50:02 +02:00
Roberta Rabotti
1f66eb9203 [it]changes 2020-06-04 14:50:02 +02:00
Roberta Rabotti
549f537ff6 [it] Add i18n files to Makefiles 2020-06-04 14:50:02 +02:00
Roberta Rabotti
3ef28ec155 [it] new translation files 2020-06-04 14:50:02 +02:00
Serenela Moreira
834a8784c9 [pt] chaged settings name 2020-06-04 14:50:02 +02:00
Serenela Moreira
b1e8f65a67 [pt] corrected typo 2020-06-04 14:50:02 +02:00
Serenela Moreira
7aecec705e [pt] shorten too long lines and other details 2020-06-04 14:50:02 +02:00
Serenela Moreira
e880dfe4b4 [pt] corrected base 2020-06-04 14:50:02 +02:00
Serenela Moreira
4802299f3c [pt] corrected regression and sequences 2020-06-04 14:50:02 +02:00
Serenela Moreira
e26739d4ad [pt] corrected toolbox 2020-06-04 14:50:02 +02:00
Serenela Moreira
ff0fb4b4c2 [pt] corrected typos in usb 2020-06-04 14:50:02 +02:00
Serenela Moreira
578c8be857 [pt] corrected shared and base 2020-06-04 14:50:02 +02:00
Serenela Moreira
b9ce07b24d [pt] translated catalog - python 2020-06-04 14:50:02 +02:00
Serenela Moreira
9c2753148b [pt] changed toolbox 2020-06-04 14:50:02 +02:00
Serenela Moreira
ad348cb64e [pt] changed graph mistakes 2020-06-04 14:50:02 +02:00
Serenela Moreira
d0a9dabd64 [pt] changed details in home and probabilities 2020-06-04 14:50:02 +02:00
Serenela Moreira
1f54ddf245 [pt] changed settings again
improved details
2020-06-04 14:50:02 +02:00
Serenela Moreira
a64ad87146 [pt] corrected settings and statistics 2020-06-04 14:50:02 +02:00
Jorick Alberga
b1e737879d [nl] Translation Epsilon 2020-06-04 14:50:02 +02:00
Jorick Alberga
c70b5b07cc [nl] Epsilon translation 2020-06-04 14:50:02 +02:00
Jorick Alberga
08fe49526c [nl] Epsilon translation update 2020-06-04 14:50:02 +02:00
Jorick Alberga
7f561b0a3d [nl] Update translation Epsilon 2020-06-04 14:50:02 +02:00
Jorick Alberga
07f924bed6 [nl] Translation Functions app And other translation
In file: epsilon/apps/graph/base.nl.i18n some text would look better if placed slightly to the left. I'm talking about lines 23 and 24: SelectLowerBound and SelectUpperBound
2020-06-04 14:50:01 +02:00
Jorick Alberga
1426da8c44 [nl] Also python-app 2020-06-04 14:50:01 +02:00
Jorick Alberga
00064ba824 [nl] Translation Python-app 2020-06-04 14:50:01 +02:00
Jorick Alberga
8a37096680 [nl] Start translation 2020-06-04 14:50:01 +02:00
Émilie Feral
ae71c23147 [poincare] Override method Unit::node to return UnitNode 2020-06-04 14:50:01 +02:00
Émilie Feral
3308b13b9c [poincare] UnitConvert:
- do the smart part at beautification to avoid
requiring an escape case just for UnitConvert
- Use UnitConvert::None
2020-06-04 14:50:01 +02:00
Émilie Feral
c3e68d1968 [poincare] Add test on the UnitConversion mode 2020-06-04 14:50:01 +02:00
Émilie Feral
3f34e5e644 [poincare] Enable to choose the "UnitConversion" mode at simplification
between: only SI, none, default...
2020-06-04 14:50:01 +02:00
Émilie Feral
d805c59202 [poincare] Fix extractUnit into removeUnit paradigm 2020-06-04 14:50:01 +02:00
Émilie Feral
4e2da5de05 [poincare] Add crashing tests on units 2020-06-04 14:50:01 +02:00
Émilie Feral
38659587f5 [poincare] Multiplication::shallowBeautify: fix typo (fix tests) 2020-06-04 14:50:01 +02:00
Émilie Feral
56c45d1390 [poincare] Parsing: expression -> expression is always parsed but return
"undef" when the left expression is neither a custom variable or
function nor a unit.
This makes the behaviour consistent on theses expressions:
2 -> a+a
2 -> 2*a
2020-06-04 14:50:01 +02:00
Émilie Feral
e4848a7535 [apps/calculation] HistoryController: favour understandable code 2020-06-04 14:50:01 +02:00
Ruben Dashyan
266482ef99 [apps/calculation] Additional outputs for Unit 2020-06-04 14:50:01 +02:00
Ruben Dashyan
f8050f0673 [poincare/symbol_abstract] Remove redundant code
This case is already handled in shallowReduce of Function and Symbol
2020-06-04 14:50:01 +02:00
Ruben Dashyan
407ce0534c [poincare/expression] Use extractUnits instead of hasUnit when possible 2020-06-04 14:50:01 +02:00
Ruben Dashyan
f227cd719f [poincare/multiplication] Use extractUnits instead of splitIntoNormalForm in shallowBeautify 2020-06-04 14:50:01 +02:00
Ruben Dashyan
914bb38a8e [poincare/test/helper] Do not beautify in assert_simplify helper function
Simplifying a Store expression does not generally reduce the children,
so the children should probably not be beautified ?
2020-06-04 14:50:01 +02:00
Ruben Dashyan
c71cce2957 [poincare/test] Factor assertions 2020-06-04 14:50:01 +02:00
Ruben Dashyan
651b705dbd Revert "[poincare/expression] deepBeautify bubbles up Undefined children"
This reverts commit 300399fe4d.

Not necessary anymore to bubble up Undefined children in deepBeautify
since Unit::shallowBeautify does not introduce any Undefined Expression.
2020-06-04 14:50:01 +02:00
Ruben Dashyan
01b94f8543 [poincare/unit] Units homogeneity is already handled in each Expression subclass
specifically if needed or generically in defaultHandleUnitsInChildren
2020-06-04 14:50:01 +02:00
Ruben Dashyan
7ef28a93bc [poincare/multiplication] Do not expand Multiplication in presence of units 2020-06-04 14:50:01 +02:00
Ruben Dashyan
bf9653d510 [poincare/expression] Turn getUnit into extractUnits
Addition::shallowReduce factors the unit across its terms.
Previously expressions of the form 1_m+π_m were reduced to undef.
2020-06-04 14:50:01 +02:00
Ruben Dashyan
94e1fdfc7a [poincare/test/simplification] Uncomment passing tests 2020-06-04 14:50:01 +02:00
Ruben Dashyan
f2bfc7ec9b [poincare/expression] Remove redundancies in getUnit 2020-06-04 14:50:01 +02:00
Ruben Dashyan
9a762f1bf6 [poincare] A (Power of) Unit must not be orphan 2020-06-04 14:50:01 +02:00
Ruben Dashyan
c12ab3a2e2 [poincare/multiplication] Simplify shallowBeautify 2020-06-04 14:50:01 +02:00
Ruben Dashyan
2895d365a6 [poincare/multiplication] Make sure a Multiplication is not made of (Power of) Units only 2020-06-04 14:50:01 +02:00
Ruben Dashyan
4d1129b0db [poincare/multiplication] Reorder steps in shallowBeautify 2020-06-04 14:50:01 +02:00
Ruben Dashyan
b8786dd32c Revert "[poincare/multiplication] Fix handling of units with non-integer exponent"
This reverts commit 50f1ee9721.

Since Power::shallowReduce now checks that the exponent of a Unit is an
Integer, instead of Unit::shallowBeautify, there is no need anymore to
handle that in Multiplication::splitIntoNormalForm.
2020-06-04 14:50:01 +02:00
Ruben Dashyan
1351babe37 [poincare] Move Power vs Unit checks to Power::shallowReduce 2020-06-04 14:50:01 +02:00
Ruben Dashyan
fa1235939b [poincare/multiplication] Correct cast 2020-06-04 14:50:01 +02:00
Ruben Dashyan
c181650922 [poincare/multiplication] Simplify privateShallowReduce 2020-06-04 14:50:01 +02:00
Ruben Dashyan
f224ac31e3 [poincare/n_ary_expression] Add TODO about mergeSameTypeChildrenInPlace 2020-06-04 14:50:01 +02:00
Ruben Dashyan
965e3b1d9a [poincare/n_ary_expression] Factor mergeMultiplicationChildrenInPlace
from Multiplication to NAryExpression so as to use it in Addition
2020-06-04 14:50:01 +02:00
Ruben Dashyan
43327e482e [poincare/multiplication] Use mergeChildrenAtIndexInPlace instead of mergeMultiplicationChildrenInPlace 2020-06-04 14:50:01 +02:00
Ruben Dashyan
4558e777c8 [poincare/multiplication] Remove old TODO 2020-06-04 14:50:01 +02:00
Ruben Dashyan
0c4434d088 [poincare/expression] getUnit returns an uninitialized Expression
when there is no Unit instead of Undefined
2020-06-04 14:50:01 +02:00
Ruben Dashyan
f5b964339c [poincare/test/expression_properties] Fix helper assert_reduced_expression_unit
First reduce
Then getUnit
2020-06-04 14:50:01 +02:00
Ruben Dashyan
2fea3c9b3a [poincare/addition] Addition has no Unit 2020-06-04 14:50:01 +02:00
Ruben Dashyan
121e16a6a5 [poincare/absolute_value] AbsoluteValue has no Unit
shallowReduce returns Undefined if its unique child has a Unit
2020-06-04 14:50:01 +02:00
Ruben Dashyan
032723eae1 [poincare/layout_node] Remove unused variable 2020-06-04 14:50:01 +02:00
Ruben Dashyan
8365735f98 [apps/calculation/additional_outputs/expression_list_controller] Computed Layouts must not be uninitialized 2020-06-04 14:50:01 +02:00
Ruben Dashyan
a31524173f [apps/calculation/history_controller] Factor handleEvent 2020-06-04 14:50:01 +02:00
Ruben Dashyan
a3265996fe [apps/calculation/history_controller] Factor handleEvent 2020-06-04 14:50:01 +02:00
Ruben Dashyan
f3bcedd43d [apps/calculation/history_controller] Simplify and harmonize handleEvent 2020-06-04 14:50:01 +02:00
Ruben Dashyan
167827f0e4 [apps/calculation] EditExpressionController accesses subview directly 2020-06-04 14:50:01 +02:00
Ruben Dashyan
63ab8710b9 [apps/calculation] Factor EditExpressionController::insertTextBody 2020-06-04 14:50:01 +02:00
Ruben Dashyan
145381ad4b [apps/calculation/additional_outputs] Remove parentResponder parameter from ListControllers' constructor
which was always set to nullptr
2020-06-04 14:50:01 +02:00
Ruben Dashyan
e018c9ddc8 [poincare/trigonometry_cheat_table] Reorder parameter names correctly 2020-06-04 14:50:01 +02:00
Ruben Dashyan
b8993eafa9 [poincare/expression] Call reduce instead of deepReduce 2020-06-04 14:50:01 +02:00
Ruben Dashyan
8e71e03b6e [poincare] Remove ostream and iostream header inclusions and keep them precisely where needed 2020-06-04 14:50:01 +02:00
Ruben Dashyan
b05202f2ec [poincare] Remove stdio.h inclusions 2020-06-04 14:50:01 +02:00
Ruben Dashyan
e03c628381 [poincare/multiplication] shallowBeautify builds Unit only if necessary 2020-06-04 14:50:01 +02:00
Ruben Dashyan
e43362eee0 [poincare/multiplication] Factor CanSimplifyUnitProduct 2020-06-04 14:50:01 +02:00
Ruben Dashyan
9cbbffcdd6 [poincare/multiplication] shallowBeautify builds Power only if necessary 2020-06-04 14:50:01 +02:00
Ruben Dashyan
94bad10ddb [poincare/multiplication] CanSimplifyUnitProduct gets int8_t entryUnitExponent parameter instead of operationOnExponents 2020-06-04 14:50:00 +02:00
Ruben Dashyan
79a81968c8 [poincare/unit] Avoid cloning expression in Dimension::Vector::FromBaseUnits 2020-06-04 14:50:00 +02:00
Ruben Dashyan
2f708cc36c [poincare/unit] Dimension::Vector::FromBaseUnits accepts only products of powers of base units
and no other factor at all
2020-06-04 14:50:00 +02:00
Ruben Dashyan
394e86a28a [poincare] Unit::Dimension holds a Vector
The Vector does not need to be recomputed from a Representative's
definition, which requires parsing and time-consuming reduction.
2020-06-04 14:50:00 +02:00
Ruben Dashyan
d7dab2ae99 [poincare/multiplication] bestUnitNorm not necessary anymore 2020-06-04 14:50:00 +02:00
Ruben Dashyan
191680d96f [poincare/multiplication] Simplify Unit::Dimension::Vector::Metrics comparison 2020-06-04 14:50:00 +02:00
Ruben Dashyan
67241bb564 [poincare] Make code more object oriented
Turn ExponentsOfBaseUnits function into a static method of the
Unit::Dimension::Vector class
2020-06-04 14:50:00 +02:00
Ruben Dashyan
b6d07cbd90 [poincare] Make code more object oriented
Turn ExponentsOfBaseUnits function into a method of the
Unit::Dimension::Vector class
2020-06-04 14:50:00 +02:00
Ruben Dashyan
e2cdf78605 [poincare] Define and use Unit::Dimension::Vector::Metrics 2020-06-04 14:50:00 +02:00
Ruben Dashyan
2f6770cd69 [poincare/multiplication] Change signature of ExponentsOfBaseUnits 2020-06-04 14:50:00 +02:00
Ruben Dashyan
0eb6df27dc [poincare] Turn Unit::Dimension::Vector type into a struct 2020-06-04 14:50:00 +02:00
Ruben Dashyan
202beb3b13 [poincare/unit] Add comment about namespace and scope usage 2020-06-04 14:50:00 +02:00
Ruben Dashyan
2fa71e4350 [poincare] Define and use Unit::NumberOfBaseUnits instead of magic number 2020-06-04 14:50:00 +02:00
Ruben Dashyan
be2892eae5 [poincare] Define Unit::Dimension::Vector type 2020-06-04 14:50:00 +02:00
Ruben Dashyan
157d74c0da [poincare/unit] Coding style 2020-06-04 14:50:00 +02:00
Ruben Dashyan
f01f91d000 [poincare/unit] Clean serialize
The prefix should be correct at that point and it should not be
necessary to check whether the prefix is allowed.
2020-06-04 14:50:00 +02:00
Ruben Dashyan
bc0b21463e [quiz][ion/test] Move time measurements to quiz
to be able to do measurements in any test
2020-06-04 14:50:00 +02:00
Léa Saviot
068ed96d79 [apps/range_1D] Add comment abour k_minFloat 2020-06-04 14:50:00 +02:00
Léa Saviot
ed753b793b [apps/statistics] Do not initRangeParameters too often 2020-06-04 14:50:00 +02:00
Léa Saviot
51b5edbe69 [apps/statistics] Remove too strict condition
One could not set the bin with / x start to a value that would not show
any data
-> The condition was asymetrical, as nextFirstDrawnBarAbscissa could not
be higher to the biggest data, but could have been too small to display
any data
-> We restricted the user
2020-06-04 14:50:00 +02:00
Léa Saviot
59aea9ca83 [apps/statistics] Factorize HistogramParamCtrlr::setParamAtIdx 2020-06-04 14:50:00 +02:00
Léa Saviot
250f4ec3dd [apps/statistics] Clean code 2020-06-04 14:50:00 +02:00
Léa Saviot
93d687abc2 [apps/calculation] Fix height computation in additional results 2020-06-04 05:47:55 -07:00
Émilie Feral
884d9890cf [.github/workflow] ci-workflow: update setup-emscripten to v2 2020-06-04 09:37:11 +02:00
Quentin
6f2ed02d07 [Fix] CI 2020-06-02 18:56:19 +02:00
Quentin
b2e5d1ef15 [Update] RPN 2020-06-02 18:42:37 +02:00
Quentin
482c7df15d [Update] RPN 2020-06-02 14:08:35 +02:00
Joachim Le Fournis
899e0d4a6b [apps/shared] Fixed a small mistake in parameter_text_field_delegate.cpp
In this commit, there was a small oversight in 7a4ee746b2, which caused https://github.com/numworks/epsilon/issues/1570
2020-05-29 02:27:48 -07:00
Léa Saviot
b034f8e054 [apps/calculation] Fix history navigation
When calculations span on two lines, better selection
2020-05-28 04:44:27 -07:00
Léa Saviot
a56a73b0ba [apps/calculation] Fix calculation height computation
It was done in two places before, which created inconsistencies
2020-05-28 04:44:27 -07:00
Léa Saviot
0379327b06 [apps/calculation] Geographic navigation in the history 2020-05-28 04:44:27 -07:00
Léa Saviot
1d3a949b6f [apps/shared] Add escape case 2020-05-28 04:44:27 -07:00
Léa Saviot
e2f4b30b84 [apps/calculation] Remove unused variable 2020-05-28 04:44:27 -07:00
Léa Saviot
c4908c2bd9 [apps/calculation] Fix bottom calculation margin
Scenario: enter a calculation that uses two lines, the margin on the
bottom is too big
2020-05-28 04:44:27 -07:00
Léa Saviot
5535145b51 [apps/calculation] Calculation on 2 lines if does not fit when expanded
Scenario: 1+1+1+1+1+1+1+10.5 fits on one line when not expanded, but
when the exact result is displayed not -> we thus always display it on
two lines
2020-05-28 04:44:27 -07:00
Léa Saviot
feee0a673c [apps/calculation] HistoryViewCell cleaning 2020-05-28 04:44:27 -07:00
Léa Saviot
6948011ae0 [apps/calculation] Handle navigation in single lined output 2020-05-28 04:44:27 -07:00
Léa Saviot
579485c8c0 [apps/calculation] CanBeSingleLine differs if args are view/layout sizes
If the sizes are for layouts, we need to add the margins added by the
views.
2020-05-28 04:44:27 -07:00
Léa Saviot
4f50a72abf [apps/calculation] Clean Calculation::height 2020-05-28 04:44:27 -07:00
Léa Saviot
11c39b6206 [apps/calculation] Calculation::height has two types of margin arguments
One for the margin between layouts and on top / at the bottom of the
cell, the other for the margin surrounding each layout.
2020-05-28 04:44:27 -07:00
Léa Saviot
78cac6ddae [apps/calculation] Calculation::height has CanBeSingleLine argument 2020-05-28 04:44:27 -07:00
Léa Saviot
1c2801907f [apps/calculation] Factorize and clean code 2020-05-28 04:44:27 -07:00
Léa Saviot
30c243e2e4 [apps/scrollable_multiple_expressions_view] Factorize baseline() 2020-05-28 04:44:27 -07:00
Léa Saviot
525290427a [apps/calculation] Calculation::height takes verticalMargin argument 2020-05-28 04:44:27 -07:00
Léa Saviot
7ccaf3fc50 [apps/calculation] Rename allExpressionsInline to forceSingleLine 2020-05-28 04:44:27 -07:00
Léa Saviot
5a68b44aa1 [apps/calc] Merge SingleLine and allExpressionsInline behaviours 2020-05-28 04:44:27 -07:00
Léa Saviot
c3d8520e73 [apps/calculation] Remove unnecessary bool 2020-05-28 04:44:27 -07:00
0b101
b48d3d6e4a Added a new compact result display mode 2020-05-28 04:44:27 -07:00
Joachim Le Fournis
67fc7502e2 [App/zoom_parameter_controller] Add comment
See : https://github.com/numworks/epsilon/pull/1548#discussion_r425708055
2020-05-22 00:42:05 -07:00
Joachim Le Fournis
f1209bcf76 [App/zoom_parameter_controller] Changed subview order
This fixes #500
2020-05-22 00:42:05 -07:00
Émilie Feral
7f3f67aba0 [python] Clean type confusion 2020-05-18 14:39:46 +02:00
Émilie Feral
4e1f7c1cb8 [python] Fix comment 2020-05-18 14:39:46 +02:00
Émilie Feral
4cd0d20585 [ion] Fix comment 2020-05-18 14:39:46 +02:00
Émilie Feral
0f61b2ccf3 [ion] Add comment on default collectRegisters implementation 2020-05-18 14:39:46 +02:00
Émilie Feral
3f6647f3ae [ion][python] Implement an architecture-dependant collect_registers.
setjmp is not guaranteed to collect all registers without modification
on all platforms.

This fixes the following bug: when the pointer of a newly allocated
object on the Python heap is stored in rpb registers on x86_64 arch, it
was not collected by the garbarge collector.
2020-05-18 14:39:46 +02:00
Émilie Feral
5a32006dcd [python] Revert: collectRoots does not need to look for unaligned
pointers as they should not exist
2020-05-18 14:39:46 +02:00
Émilie Feral
3f5487ca90 [python] Forbid inlining on gc_collect to avoid missing some roots 2020-05-18 14:39:46 +02:00
TheTrueBrot
055f8bf1bd Fixed a small mistake in the german Translation 2020-05-15 02:54:34 -07:00
Léa Saviot
e7988b9fa2 [apps/round_cursor_view] Add comment about flaw in algorithm 2020-05-15 02:52:54 -07:00
Léa Saviot
a0c5a1fe1c [apps] InteractCurveVwCtlr::addMargin adds more than the required margin 2020-05-15 02:52:54 -07:00
Léa Saviot
ee78948cf8 [apps/interactive_curve_view_range] Clean panToMakePointVisible 2020-05-15 02:52:54 -07:00
Léa Saviot
456cd3c73a Revert "[apps] Add FLT_EPSILON in float comparisons in interactive_curve_vw_rge"
This reverts commit 18381fd334.
2020-05-15 02:52:54 -07:00
Léa Saviot
016f87c266 [escher/layout_field] Reset the scroll when clearing the layout
Scenario: Go to the graph app, create f(x) = 1 then create g(x) -> there
is a weird big margin in the edition field
2020-05-15 02:39:11 -07:00
Léa Saviot
73c55f0437 [apps/regression] Add test for proportional_regression 2020-05-13 15:25:33 +02:00
Léa Saviot
21a4139c19 [apps/regression] Clean partialDerivate of the models 2020-05-13 15:25:33 +02:00
Léa Saviot
980a62da6c [apps/regression] Clean proportional_model.cpp 2020-05-13 15:25:33 +02:00
Léa Saviot
588533fadf [apps/regression] Remove r and r2 for Proportional regression 2020-05-13 15:25:33 +02:00
Léa Saviot
2e5e2a3258 [apps/regression] Rename Affine -> Linear and Linear -> Proportional 2020-05-13 15:25:33 +02:00
Joachim LF
740e9e9d12 [Regression] Fixed affine and linear name errors 2020-05-13 15:25:33 +02:00
Joachim LF
5297f28ffa [Regression] Switched affine and linear 2020-05-13 15:25:33 +02:00
Joachim LF
833f6ec778 [Regression] Add affine regression 2020-05-13 15:25:33 +02:00
Émilie Feral
c955f45457 [escher] View: remove useless virtual destructor 2020-05-12 13:19:28 +02:00
Quentin
ebf836e361 Merge pull request #336 from M4xi1m3/omega-dev-exthome
External apps on home menu
2020-05-11 14:13:46 +02:00
Quentin
f16918ba1a Merge pull request #335 from M4xi1m3/fast-lto
[build] Enable jobserver lto.
2020-05-11 14:12:58 +02:00
Romain Goyet
a07ab8015e [apps/calculation] Correct insert in fractions 2020-05-11 10:34:28 +02:00
Romain Goyet
884e53f75d [escher/layout_field] Add a comment 2020-05-11 10:34:28 +02:00
Romain Goyet
213d80002c [escher/layout_field] Insertion event can be customized 2020-05-11 10:34:28 +02:00
Romain Goyet
fc4b0a8d35 [escher] Add an insertionField in LayoutField 2020-05-11 10:34:28 +02:00
Charlotte THOMAS
0f2f51cdf4 A stop to the imparialism of the US Units
A constant rule the total number of units
Passed the lbs and inch as base units to avoid unwanted conversion from SI to imperial ones
2020-05-08 18:20:57 +02:00
Léa Saviot
efe5b4d6f8 [ion/storage] Private constructor and cleaner sharedStorage() 2020-05-07 06:22:42 -07:00
M4x1m3
befe0b8214 [build] Enable jobserver lto. 2020-05-07 09:24:26 +02:00
Léa Saviot
bbb8308a6d [poincare/normal_distribution] More values are computed
We limited the precision too much before.
2020-05-06 01:01:58 -07:00
Quentin
1d7a83526c Merge pull request #334 from M4xi1m3/omega-dev
[apps/external] Fixed extapps not displayed on device since #333
2020-05-05 16:43:10 +02:00
M4x1m3
2ae312c703 [apps/external] Added icon support, fixed stuff. 2020-05-05 16:17:03 +02:00
M4x1m3
becada912a [app/external] External apps on home menu. 2020-05-05 16:17:03 +02:00
M4x1m3
efac211a13 [apps/external] Fixed extapps not displayed on device since #333 2020-05-05 11:42:48 +02:00
Joachim Le Fournis
480459ab19 Changed setRecompute() to forceRecompute()
See https://github.com/numworks/epsilon/pull/1538#discussion_r419255425
2020-05-04 01:16:04 -07:00
Joachim Le Fournis
9e8229e767 [Interval] Removed useless getter
See https://github.com/numworks/epsilon/pull/1538#discussion_r419252679
2020-05-04 01:16:04 -07:00
Joachim LF
43bceac2c9 [Interval] Coding style on compute 2020-05-04 01:16:04 -07:00
Joachim LF
f250311856 [Interval] Patch the need recomputing 2020-05-04 01:16:04 -07:00
sagessylu
a52202fa90 put accents in toolbox French translation 2020-05-04 01:15:46 -07:00
Émilie Feral
9b419acf40 [python] kandinsky port: rename TupleForRGB to TupleForKDColor 2020-04-30 14:12:32 +02:00
Émilie Feral
25b2ff31c2 [apps/code] Simplify colormode entry in toolbox 2020-04-30 14:12:32 +02:00
Émilie Feral
4bca330f0d [python] Coding style 2020-04-30 14:12:32 +02:00
Émilie Feral
0811221943 [python] Clean port ColorParser 2020-04-30 14:12:32 +02:00
Émilie Feral
7c24f2fc28 [python] Coding style 2020-04-30 14:12:32 +02:00
Émilie Feral
ba15415847 [python] modturtle: avoid unexpected cast 2020-04-30 14:12:32 +02:00
Émilie Feral
4f99aa709a [apps/code] Add colormode to Toolbox: in Catalog and Turtle module 2020-04-30 14:12:32 +02:00
Émilie Feral
686a1493e5 [python] Coding style 2020-04-30 14:12:32 +02:00
Émilie Feral
e7df25d558 [python] Kandinsky module: color accepts "#FF0000", "red" kinds of
arguments
2020-04-30 14:12:32 +02:00
Émilie Feral
af0cdbcc1b Coding style 2020-04-30 14:12:32 +02:00
Émilie Feral
1b0b9e48f5 [python] ColorParser: add a TODO 2020-04-30 14:12:32 +02:00
Émilie Feral
8f5fa50f22 [python] Color: avoid magic number 255, clean code of ColorParser and
Turtle::colormode
2020-04-30 14:12:32 +02:00
Émilie Feral
c920df1f76 [python] Change enum class name: ColorModes --> ColorMode 2020-04-30 14:12:32 +02:00
Émilie Feral
995cc04533 [python] Use of mp_obj_is_str instead of MP_OBJ_IS_STR for more
consistency
2020-04-30 14:12:32 +02:00
Émilie Feral
a564efcaa5 [python] Fix bug in ParseColor 2020-04-30 14:12:32 +02:00
Émilie Feral
3d1b3f9a0b [python] Factorize implementation of pencode (Turtle module) 2020-04-30 14:12:32 +02:00
Émilie Feral
f5e8d4d9bb [python] Avoid modifying micropython external source, use parsenum.h methods directly 2020-04-30 14:12:32 +02:00
Joachim LF
e76abcf67e [Python] universal colors 2020-04-30 14:12:32 +02:00
Léa Saviot
061fe05b40 [poincare/normal_distribution] Fix StandardNormalCumulDistFuncAtAbs 2020-04-28 02:52:17 -07:00
TheTrueBrot
2768c143c8 Fix a mistake in German translation 2020-04-28 02:17:54 -07:00
Émilie Feral
2d0d4a3a8d [apps] Fix misc errors in German translation 2020-04-27 15:29:05 +02:00
M4x1m3
4434b528f6 [ion/3ds] LED driver 2020-04-26 12:50:48 +02:00
Maxime FRIESS
bb9f52b355 [Feature] Made external app testable on simu again. (#333)
Build with make PLATFORM=simulator FORCE_EXTERNAL=1 EXTERNAL_BUILTIN=1
2020-04-24 16:00:06 +02:00
M4x1m3
b169c3dc2d [ion/3ds] Cleaning, added support for battery and USB. Now can quit exam mode. 2020-04-21 22:08:13 +02:00
M4x1m3
1919933f8d [ion/3ds] Cleaning, non-debug keyboard, can exit now. 2020-04-21 22:08:10 +02:00
M4x1m3
18ad90e2d3 [ion/3ds] Added smdh data to the 3dsx 2020-04-21 22:08:04 +02:00
M4x1m3
e20cbaa4af [ion/3ds] Produces .3dsx file. 2020-04-21 22:08:00 +02:00
M4x1m3
460987e9a7 [poincare] Made the simu build again on linux. 2020-04-21 22:07:50 +02:00
maximilianwalter
0b488bc548 Update toolbox.de.i18n 2020-04-21 06:45:17 -07:00
maximilianwalter
b87674ab73 Update toolbox.de.i18n 2020-04-21 06:45:17 -07:00
maximilianwalter
de7aaeb188 Update base.de.i18n 2020-04-21 06:45:17 -07:00
maximilianwalter
37b876a941 added equivalents 2020-04-21 06:45:17 -07:00
maximilianwalter
7b40f55973 added equivalents 2020-04-21 06:45:17 -07:00
M4x1m3
e8740edb04 [ion/3ds] Modified the build system to work with epsilon master 2020-04-19 15:29:21 +02:00
M4x1m3
f7609e0001 [poincare] Made the simu build again on linux. 2020-04-19 15:23:29 +02:00
M4x1m3
b49af643ef [ion/3ds] Added keyboard support. 2020-04-19 15:23:26 +02:00
M4x1m3
0deb74b47b [ion/3ds] Added button support. 2020-04-19 15:23:16 +02:00
M4x1m3
3f976d3873 [ion/3ds] Got something on screen! 2020-04-19 15:23:10 +02:00
M4x1m3
2f01603c4d [ion/3ds] Got it to build. 2020-04-19 15:23:04 +02:00
Quentin
13874cd2e0 Merge branch 'omega-hotfix' into omega-dev 2020-04-16 14:24:47 +02:00
Quentin
3013dda9d6 [Fix] Conflicts 2020-04-16 14:12:38 +02:00
Quentin
0d88a5ac70 Merge branch 'RedGl0w-RevertPercent' into omega-hotfix 2020-04-16 14:05:58 +02:00
Quentin
a7a212c652 Merge branch 'RevertPercent' of https://github.com/RedGl0w/epsilon into RedGl0w-RevertPercent 2020-04-16 14:05:11 +02:00
Quentin
f37040dc8a [Fix] Conflicts 2020-04-16 14:04:56 +02:00
Émilie Feral
61399d07eb [python] Turtle: use std::fabs std::copysign when possible 2020-04-16 09:44:37 +02:00
Émilie Feral
675a0d3f4c Add missing definition of static member variables 2020-04-15 10:34:00 -04:00
Léa Saviot
c2bd19d9a1 [apps/solver] Fix polar tests 2020-04-15 09:16:32 -04:00
Léa Saviot
9988447b9a [poincare] Expression::isIdenticalToWithoutParentheses 2020-04-15 09:16:32 -04:00
Romain Goyet
56f3204a17 [apps/solver] Fix the polar tests 2020-04-15 09:16:32 -04:00
Romain Goyet
240e60cb68 [liba] Include strlcat in the bridge too 2020-04-15 09:16:32 -04:00
Romain Goyet
870d704e7f [apps/solver] Rewrite the tests to they can be read by a human being 2020-04-15 09:16:32 -04:00
Romain Goyet
2e6dec5f1d [libaxx] initializer_list use size_t 2020-04-15 09:16:32 -04:00
Romain Goyet
5faa251c1f [apps/solver] Quiz assertion are supposed to run in release mode too 2020-04-15 09:16:32 -04:00
Émilie Feral
42d643aa7e [apps/settings] improve German locale 2020-04-15 09:15:37 -04:00
Joachim LF
c15bb3d893 Negative diameter circle turtle support 2020-04-15 06:15:28 -07:00
Émilie Feral
dcfabf754d [ion] Init random seed with time in simulator main 2020-04-15 09:11:52 -04:00
Émilie Feral
870dd868e9 [ion] Tidy files:
- move from shared to simulator/shared
- delete files used only be deprecated blackbox
2020-04-15 09:11:52 -04:00
Romain Goyet
4d981fbfb6 [poincare] Define a member variable even if it's kind of useless
https://stackoverflow.com/questions/8016780/undefined-reference-to-static-constexpr-char
2020-04-14 09:31:02 -04:00
Romain Goyet
84768472bd Explicit std::min/max template usage
This is unfortunately required in several cases:
 - Sometimes when we use either float and double (this should be changed)
 - Because KDCoordinate is not an int, so any arithmemtic promotes it to
an int
 - Because we mix pointer differences and ints
2020-04-14 09:31:02 -04:00
Romain Goyet
c71dcca691 [apps/code] Consistently use size_t 2020-04-14 09:31:02 -04:00
Romain Goyet
644c44e069 Misc cleanups 2020-04-14 09:31:02 -04:00
Romain Goyet
950862f8d0 Use std::min and std::max 2020-04-14 09:31:02 -04:00
Romain Goyet
77ee5126e1 [libaxx] Add algorithm
Only contains a super simple min and max implementation
2020-04-14 09:31:02 -04:00
Aleks ANDRÉ
1839a91982 Terminologie lycée FR
Références :
* [Seconde](https://cache.media.education.gouv.fr/file/SP1-MEN-22-1-2019/95/7/spe631_annexe_1062957.pdf)
* [Première](https://cache.media.education.gouv.fr/file/SP1-MEN-22-1-2019/16/8/spe632_annexe_1063168.pdf)
* [Terminale (spécialité)](https://cache.media.education.gouv.fr/file/SPE8_MENJ_25_7_2019/90/7/spe246_annexe_1158907.pdf )
* [Terminale (complémentaire)](https://cache.media.education.gouv.fr/file/SPE8_MENJ_25_7_2019/13/4/spe265_annexe_1159134.pdf)
* [Terminale (experte)](https://cache.media.education.gouv.fr/file/SPE8_MENJ_25_7_2019/82/5/spe264_annexe_1158825.pdf)
2020-04-14 03:36:05 -07:00
Romain Goyet
196a94e199 [ci] Report .text, .rodata, .bss and .data sections
Note that .text and .rodata are cumulative (internal+external)
2020-04-14 01:44:35 -07:00
Romain Goyet
56f4b275a5 [python] Turn a warning into a error when appropriate 2020-04-14 01:17:25 -07:00
Romain Goyet
cbb0110c2f [liba] Define UINT8_MAX
This will be needed in python to check that some QSTRs aren't too big.
And it doesn't cost anything to add it straight away.
2020-04-14 01:17:25 -07:00
Romain Goyet
8a43b17df9 [python] Reorder QSTRs to match an implicit assertion in uPy
In py/scope.c, an assertion is made that some qstrs should be "low".
Let's make sure it is indeed the case.

Note: https://github.com/micropython/micropython/pull/5903
2020-04-14 01:17:25 -07:00
Joachim LF
53743ab531 Revert percent 2020-04-11 19:06:40 +02:00
Romain Goyet
807dd73e7b [poincare] Use a Tuple instead of an ArrayBuilder for expression
The Tuple is simply an initializer_list along with a convenience method
to cast between a list of TreeHandle and a list of Expression
2020-04-10 13:35:14 -04:00
Romain Goyet
1bd6105a0a [libaxx] Add initializer_list 2020-04-10 13:35:14 -04:00
Émilie Feral
e1b9703a2e [.github] workflows: don't launch the windows executable from msys2 2020-04-10 13:34:00 -04:00
Émilie Feral
ec5587904f [poincare] Unit: double comparison should be done with care. On windows
platform pow(10.0, -6.0) leads to small loss of precision and eventually
to beautify(_Mg) --> _t
2020-04-10 13:34:00 -04:00
Émilie Feral
8c844a772b [poincare] Fix tests to be passed on windows platform (approximation
issues)
2020-04-10 13:34:00 -04:00
Émilie Feral
499d0a8292 [.github/workflows] Crash of the tests on windows should trigger a CI
failure
2020-04-10 13:34:00 -04:00
Léa Saviot
e6ce3ca249 [apps] GET_OPT uses generated i18n language codes to find language 2020-04-10 04:46:22 -07:00
Léa Saviot
2ed354710f [build/simulator] NDEBUG flag in release mode
This way, asserts are not performed on simulator platforms
2020-04-10 00:49:15 -07:00
Joachim Le Fournis
4a9bfca1f6 [ion] Alpha-locked percent becomes backspace 2020-04-09 12:09:03 -04:00
Émilie Feral
8dbe719a68 [Build] Add address sanitizer option if ASAN=1 2020-04-09 15:14:30 +02:00
Joachim LF
a4af2942e6 [Fix] Conflicts 2020-04-09 14:52:49 +02:00
Émilie Feral
f2efd46814 [build] defaults.mak: don't override previously-added SFLAGS 2020-04-09 14:30:57 +02:00
Léa Saviot
449b1a4fc4 [liba/openbds] Use OpenBSD and not FreeBSD s_erff.c and s_logbf.c files 2020-04-09 13:58:56 +02:00
Léa Saviot
49cd841f99 [poincare/test] Increase some test precisions 2020-04-09 13:58:56 +02:00
Léa Saviot
44fb06890e [poincare/test] Reduce asin(-1) approximation test precision
Now the computation is really done in floats
2020-04-09 13:58:56 +02:00
Neven Sajko
dd6a729f65 Better usage of some floating point constants 2020-04-09 13:58:56 +02:00
Neven Sajko
201ecaef5b Performance fixes relating to floating point: erf and erfc
erf and erfc are missing float versions, so I import them from
openlibm. erf is used from Poincare::NormalDistribution::
StandardNormalCumulativeDistributiveFunctionAtAbscissa<float>, and erfc
is used (?) just from MicroPython.

To clarify, if there is no float version of a function like erf, but
there is a double version, C++ promotes the possible float parameter to
double and soft-float hilarity ensues.
2020-04-09 13:58:56 +02:00
Neven Sajko
c0c73accef [probability] Prevent soft-float in StudentDistribution::lnCoefficient 2020-04-09 13:58:56 +02:00
Neven Sajko
bdc5be94b6 Performance fixes relating to floating point
Removes unneccesary usage of soft-float double usage. The reason for the
useless double math being done were broken standard C++ functions:
atanh<float>, sqrt<float>, asinh<float>, operator/<float>. This was in
turn caused by missing float versions of C++ functions hypot, atan2,
logb, scalbn.

A logbf implementation was missing from the libm, so I added one from
openlibm.
2020-04-09 13:58:56 +02:00
Neven Sajko
c92b770112 Performance fixes relating to floating point constants
This replaces unnecessary double-precision soft-float operations with
single-precision floating-point operations, mainly by casting.

In a couple places I also replace a function call with a constant.
2020-04-09 13:58:56 +02:00
Émilie Feral
068325d151 Coding style: remove unecessary 'virtual' keyword when 'override' is
present 2/2
2020-04-09 11:36:51 +02:00
Émilie Feral
82c4936e04 Coding style: remove unecessary 'virtual' keyword when 'override' is
present 1/2
2020-04-09 11:36:51 +02:00
Romain Goyet
64a1094edf [escher/layout_field] Use IsMoveEvent 2020-04-09 09:47:43 +02:00
Romain Goyet
ec4def61c3 [escher/layout_field] Avoid calling the same method over and over again 2020-04-09 09:47:43 +02:00
Quentin
e383c3429f [Fix] Conflicts 2020-04-08 15:05:17 +02:00
Quentin
e77e26e2de Merge branch 'RedGl0w-patch-1' into omega-hotfix 2020-04-08 13:47:41 +02:00
Quentin
765ac98044 Merge branch 'patch-1' of https://github.com/RedGl0w/epsilon into RedGl0w-patch-1 2020-04-08 13:44:04 +02:00
Joachim Le Fournis
ded69970ab Update extapp_api.cpp 2020-04-08 13:35:26 +02:00
Quentin
53d9a9ec25 [GitHub] Remove metrics workflow 2020-04-08 13:33:42 +02:00
Joachim Le Fournis
68f6bbc378 Update Makefile 2020-04-08 13:23:59 +02:00
Quentin
26d68c8039 [Update] Upstream 2020-04-08 12:48:09 +02:00
Quentin
883d1312a3 [Fix] Fix compilation crash 2020-04-08 12:37:02 +02:00
Jean-Baptiste Boric
2f61b823d0 [poincare] Remove statically-allocated buffers 2020-04-08 10:09:47 +02:00
Jean-Baptiste Boric
2768ac2b48 [escher] Remove statically-allocated buffers 2020-04-08 10:09:47 +02:00
Jean-Baptiste Boric
64d0b3107f [apps] Remove statically-allocated buffers 2020-04-08 10:09:47 +02:00
FloMiau
b59085bd7f Update German language file
replace "Testmodus" with "Prüfungsmodus"
Real: "Reel" -> "Reell"
Gradians: "Gone" -> "Gon"
2020-04-08 10:09:24 +02:00
Romain Goyet
743eb104bf [ion] Replace Ion::Events::Event::id() by an explicit cast operator 2020-04-08 09:56:33 +02:00
Romain Goyet
35d446353f [escher] Avoid long switches on Left/Up/Right/Down 2020-04-08 09:56:33 +02:00
Romain Goyet
ed7e6bec9d [build/device] Generate a RAM map 2020-04-07 17:15:05 +02:00
David
9272d4e75f Increase Brightness Levels to 12 2020-04-07 15:10:22 +02:00
Quentin
a3e91fd3ff [Fix] Fix conflicts ._. 2020-04-07 15:01:44 +02:00
Quentin
aea963dac0 [Fix] Fix conflicts ._. 2020-04-07 14:53:19 +02:00
Aleks ANDRÉ
3ae1dcd9bf retours à la ligne aidant à la lecture 2020-04-07 14:42:38 +02:00
Émilie Feral
c363231673 [build] --silent option in rule_for_arch_executable prevent from running
'make V=1' and getting the expected output
2020-04-07 14:22:33 +02:00
Aleks ANDRÉ
ee56f02f2b Margin, messages 2020-04-07 13:57:47 +02:00
Aleks ANDRÉ
b30eb20ac2 Margins, message 2020-04-07 13:57:27 +02:00
Aleks ANDRÉ
53e15787cd Margins, message 2020-04-07 13:57:06 +02:00
Aleks ANDRÉ
1fd216c97e Margins, message 2020-04-07 13:56:46 +02:00
Aleks ANDRÉ
73f34f8f3d Relecture
– zéro → racine. Il s’agit de la terminologie du programme de [1re spécialité](https://cache.media.education.gouv.fr/file/SP1-MEN-22-1-2019/16/8/spe632_annexe_1063168.pdf)
– homogénéisation avec autres applications
2020-04-07 13:55:24 +02:00
Aleks ANDRÉ
e399472577 Anglicismes 2020-04-07 13:46:11 +02:00
Quentin
4411f3aeee [Fix] Re-enable all apps 2020-04-07 13:25:11 +02:00
Quentin
d6d235f273 [Feature] Contributors Controller in the Omega App (WIP) 2020-04-07 13:08:31 +02:00
wow
42fa0e7fbc More friendly french translations 2020-04-07 11:46:30 +02:00
Émilie Feral
7df8c2935a [python] upgrade to micropython 1.12 2020-04-07 11:28:32 +02:00
Émilie Feral
010fb1894f [python] Remove mpversion useless header 2020-04-07 11:28:32 +02:00
Émilie Feral
26aab94ac0 [apps/shared] Avoid signed/unsigned int comparison warning 2020-04-07 09:51:39 +02:00
Émilie Feral
e1d7b6bb04 [apps] Avoid unsigned/signed comparison: storeChecksumAtIndex takes an
int as parameter
2020-04-07 09:51:39 +02:00
Émilie Feral
154625a945 [python] Fix warning: comparisons between signed and unsigned integers 2020-04-07 09:51:39 +02:00
Romain Goyet
e314f2eb65 [ci] Use steps to pass the binary_size result 2020-04-06 19:18:47 -04:00
Joachim LF
7e02a90b2a Don't scan not loaded script in toolbox 2020-04-06 18:31:32 +02:00
Joachim LF
77af9ab92b I18NWarn 2020-04-06 18:29:48 +02:00
Neven Sajko
bc7d598517 [ion] do not increment volatile variable in isr_systick
In 2019 a proposal was approved which is deprecating this and other
harmful usage of volatile in C++ in 2020. See web links at the end.

Note that this did not at all change the GCC-generated machine code.

Deprecating volatile (adopted in 2019 for C++20):
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1152r0.html
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1152r4.html

Related, but less relevant:

volatile_load<T> and volatile_store<T>:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1382r1.pdf

Deprecating volatile: library:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1831r0.html
2020-04-06 17:18:03 +02:00
Neven Sajko
1c9b402645 [ion] Remove volatile qualifier from millis return type
Qualification of an integer return type as volatile is ignored by the
compiler. To clarify, an integer value (not a variable), which is what
the return type is, can not be assigned to anyway, so qualification as
volatile does not make sense.
2020-04-06 17:18:03 +02:00
Romain Goyet
e34811ff18 [ci] Report metrics on each PR 2020-04-06 15:29:03 +02:00
Romain Goyet
02738ba06a [build] Add a tool to compare the size of two ELF files 2020-04-06 15:29:03 +02:00
Léa Saviot
efff509e2a [apps/global_preferences] DefaultLanguage is the first of the locales
Not EN, because we might build without the EN locale
2020-04-06 13:35:18 +02:00
Léa Saviot
19b5653851 [apps/i18n] Remove Language::Default
We never translate a i18n message to something else than the currrent
language selected
2020-04-06 13:35:18 +02:00
Émilie Feral
c58456a058 [python] matplotlib: add comment WIP 2020-04-06 12:30:52 +02:00
Émilie Feral
b7392dbd95 [python] matplotlib: clean implementation (by using
mp_obj_float_binary_op)
2020-04-06 12:30:52 +02:00
Émilie Feral
190802aa23 [python] Remove unused duplicate file 2020-04-06 12:30:52 +02:00
Aleks ANDRÉ
5348640925 Traduction 2020-04-06 10:37:34 +02:00
Romain Goyet
bfb39618e1 [poincare] Add some missing std::move 2020-04-06 10:13:14 +02:00
Romain Goyet
84f6b179de [build] rule_for now takes both "local" and "global" parameters
Previous the build would fail on macOS if you had an epsilon.elf file in
at the root of the project. Indeed, the %.elf -> %.bin rule would get
triggered, but this rule should only operate on generated (intermediate)
elf file.
2020-04-06 10:12:54 +02:00
Romain Goyet
7d5cad32b1 [build/all] Q isn't defined (and isn't needed either) 2020-04-06 10:02:06 +02:00
Romain Goyet
edde8e8eba [build/all] Re-sourcing emsdk isn't needed 2020-04-06 10:02:06 +02:00
Romain Goyet
f450e36e65 [build/all] Use the short iOS and Android targets 2020-04-06 10:02:06 +02:00
Romain Goyet
88912be9a8 [build] The all target can live in a standalone Makefile 2020-04-06 10:02:06 +02:00
Romain Goyet
a840e7fb05 [liba] Define SEEK_CUR
For some reason it was defined in Python and raised re-def errors
2020-04-06 09:51:04 +02:00
Romain Goyet
6de90d97a4 [build] Remove duplication of HANDY_TARGETS_EXTENSIONS 2020-04-03 22:26:55 -04:00
Romain Goyet
13b5cd0151 [ci] Build for the iOS Simulator too
This means building an x86_64 binary that will run on a Mac simulating
an iPhone or an iPad
2020-04-03 22:26:55 -04:00
Romain Goyet
1886918900 [ci] Simplify bucket names 2020-04-03 22:26:55 -04:00
Romain Goyet
1b2bbd163b [ion/device] Rename a file 2020-04-03 22:26:55 -04:00
Romain Goyet
f7911bae72 [build] Remove DEFAULT
It was redundant with HANDY_TARGETS and HANDY_TARGETS_EXTENSIONS
2020-04-03 22:26:55 -04:00
Romain Goyet
99b916e179 [build] Share multi-app code 2020-04-03 22:26:55 -04:00
Romain Goyet
f9b0843578 [build/simulator/apple] Share code 2020-04-03 22:26:55 -04:00
Romain Goyet
fff20eb530 [ion/simulator/apple] Rename Make helper 2020-04-03 22:26:55 -04:00
Romain Goyet
d4149b1a3d [build] Move %_run targets in the build dir 2020-04-03 22:26:55 -04:00
Romain Goyet
ed7038262c [ci] Misc cleanups 2020-04-03 22:26:55 -04:00
Romain Goyet
3f2b14ac3e [build] Misc cleanups 2020-04-03 22:26:55 -04:00
Romain Goyet
ba57dbde61 [build] macOS and iOS can now build any binary 2020-04-03 22:26:55 -04:00
Romain Goyet
ada205b1a7 [build] Use variants
- Move helpers functions into build/helpers.mak
- Move official warning into official targets only
2020-04-03 22:26:55 -04:00
Quentin
1c00373348 [Feature] Selectable tableViewCell in the Omega App 2020-04-03 17:07:26 +02:00
Émilie Feral
8d621e4dce [apps/shared] ScrollableMultipleExpressionsView: reload scroll content
view layout when changing the displayed expression layouts

Fix bug: input (transpose([1 1 1 1 1 1])[1 1 1 1 1 1])^30, click on 'OK'
and then 'up'. The cell is mis-displayed.
2020-04-03 10:42:42 +02:00
Émilie Feral
300de8fb15 [apps/calculation] HistoryViewCell: when changing SubviewType, set the
right subcell as first responder!

This fixes the following bug: when selecting a cell whose content is too
long to be displayed, the scrolling is broken
2020-04-03 10:42:42 +02:00
Émilie Feral
90222c3f45 [apps/calculation] SelectableTableView: scrollToCell once the margin
have been updated

This fixes the following bug: input the vertical matrix [1,2,3], the
scroll failed
2020-04-03 10:42:42 +02:00
Émilie Feral
e6516ae0e7 [apps/calculation] Fix typo 2020-04-03 10:39:05 +02:00
Émilie Feral
40986ebb99 [python] Change math module test to be true on all platforms 2020-04-01 16:39:59 +02:00
Émilie Feral
8a5af352bf [python] Fix warning: signed/unsigned int comparison 2020-04-01 16:39:59 +02:00
Émilie Feral
cdff61f64b [python] Add tests for each module 2020-04-01 16:39:59 +02:00
Émilie Feral
ec5803f06f [python] Test: fix printText 2020-04-01 16:39:59 +02:00
Émilie Feral
d0a77bda2b [python] Improve test API 2020-04-01 16:39:59 +02:00
Émilie Feral
ffb8f8f953 [python] Test: add all template scripts 2020-04-01 16:39:59 +02:00
Émilie Feral
11dc259566 [python] test: add a function to run single command test 2020-04-01 16:39:59 +02:00
Émilie Feral
d7804ad5d1 [python] Tidy matplotlib tests 2020-04-01 16:39:59 +02:00
Émilie Feral
2738d30684 [python] test: check wether script execution lead to a Python error 2020-04-01 16:39:59 +02:00
Émilie Feral
2f171eb2fd [python] Add matplotlib test WIP 2020-04-01 16:39:59 +02:00
Léa Saviot
11ac25e935 [apps/code] Fix toolbox comment 2020-04-01 13:42:44 +02:00
Léa Saviot
92c62ce3dc [apps/code] Remove superfluous spaces in toolbox 2020-04-01 13:42:44 +02:00
Quentin
00e58de708 [Feature] Stay Home 2020-04-01 12:46:04 +02:00
Quentin
3fac1fdf78 [Feature] Stay Home 2020-04-01 12:45:41 +02:00
Quentin
b854ec903a Merge branch 'omega-hotfix' into omega-dev 2020-04-01 12:14:37 +02:00
Léa Saviot
76e0deb9bf [tests/solver] Test solve equation with max number of variables 2020-04-01 11:47:19 +02:00
Émilie Feral
633776b92f [apps/shared] Fix CurveView::drawArrow on arrow without orientation 2020-04-01 11:46:25 +02:00
Quentin
e35b9c5fb1 Merge branch 'omega-dev' of github.com:Omega-Numworks/Omega into omega-dev 2020-04-01 00:17:56 +02:00
Quentin
9ecdaeeb88 Merge branch 'omega-hotfix' into omega-dev 2020-04-01 00:17:37 +02:00
David
a7c62aa176 [Feature] Made Compact Display the Default (#317)
* Made Compact Display the Default

* Made Input Field Slightly Smaller

* Removed Comma

* Fixed bug with x->a(x)

* Update escher/include/escher/expression_field.h

* Update escher/include/escher/expression_field.h
2020-03-28 17:09:00 +01:00
Quentin
0ab6c53999 Merge branch 'omega-hotfix' into omega-dev 2020-03-27 21:30:53 +01:00
Quentin
0beec8f506 Merge branch 'omega-hotfix' into omega-dev 2020-03-27 21:17:09 +01:00
David
cd8965fdd4 [Feature] Shift + Home is now a shortcut to go to calculation (#320) 2020-03-27 21:02:35 +01:00
Quentin Guidée
dde2d67634 Fix conflicts 2020-03-23 10:37:17 +01:00
Quentin Guidée
9b8f5b4132 Merge branch 'omega-hotfix' into omega-dev 2020-03-21 11:43:09 +01:00
Quentin Guidée
742e7a165d [Feature] Hide undef with symbolic calculation 2020-03-21 11:10:14 +01:00
Quentin Guidée
10c9a4458d Merge branch 'omega-hotfix' into omega-dev 2020-03-20 22:05:21 +01:00
Quentin Guidée
6716a43141 Merge branch '0b101-freedomUnits' into omega-dev 2020-03-17 21:22:52 +01:00
Quentin Guidée
a25bb04122 Fix conflicts 2020-03-17 21:22:31 +01:00
Quentin Guidée
b1d558617a Merge branch 'omega-hotfix' into omega-dev 2020-03-17 21:03:52 +01:00
Quentin Guidée
676107e5b7 Merge branch 'omega-hotfix' into omega-dev 2020-03-12 13:26:31 +01:00
Quentin Guidée
9ed8958006 [GitHub] Removed converter and cli installer from the README 2020-03-11 19:46:12 +01:00
Quentin Guidée
4bfe189ed5 [GitHub] Updated submodules 2020-03-11 19:15:24 +01:00
Quentin Guidée
bd5bb45344 Merge branch 'omega-hotfix' into omega-dev 2020-03-11 19:12:47 +01:00
Quentin Guidée
f340bb718d [Fix] Max OSX -> macOS 2020-03-11 18:16:53 +01:00
Maxime FRIESS
afc34dfea8 [Feature] Added message when compilation starts
* Added message when compilation starts.

* Added version, getting fancy.

* Fixed echo -e incompatibility.

* Added OS printing, moved pimp to proper pimp file.

* Fixed recursive pimp.
2020-03-10 21:45:23 +01:00
Quentin Guidée
14c900be4d [Change] CustomSoftwareVersion -> OmegaVersion 2020-03-10 18:21:59 +01:00
Quentin Guidée
e1a372414f Merge branch 'omega-hotfix' into omega-dev 2020-03-10 18:03:51 +01:00
Quentin Guidée
13f1acb592 Merge branch 'omega-hotfix' into omega-dev 2020-03-09 21:44:40 +01:00
Quentin Guidée
d94021677e Merge branch 'omega-hotfix' into omega-dev 2020-03-06 16:13:02 +01:00
Quentin Guidée
1d048ade53 [Reformat] Clean all spaces 2020-03-01 00:19:51 +01:00
Charlotte THOMAS
67a1000ddc [Feature] New Constants & Units
* Added some constant
Move mass on a new submenu of Physics
Added universal translation for a future easter-egg

* Added lenght constant menu
Added radiuses and distances submenu to lenght
Added Faraday Constant

* Constant
Added 16 usual pKa couple values

* Added some constant
( stefan-boltzmann, water triple point, wien, atmospheric pressure, vacuum impedance, bohr magneton, nuclear magneton, muon mass, atomic mass unit, bohr radius )
Missing hungarian translation

* Planck update
added some plancks units ( fondamentals units and energy/power units )

* Changed the Physics constants submenu
Here's the new pattern

1. Fundamental Constants => for the 5 fundamental constants
2. Electromagnetism => 3 constants remain in this submenu
3. Nuclear and Atomic Constnats => bohr magneton & nuclear magneton, bohr radius and particle mass submenu
4. Thermodynamics => this section is mostly unchanged
5. Gravitation => same as before
6. Speed => 2 submenus one for sound speeds and one for escape velocities
7. Mass => the mass of earth/sun/moon
8. Length => 2 submenus, one for radius of earth/sun/moon and one for distances earth-moon and earth-sun
9. Planck Units => The natural system of units

* Units
Added steradian, lumen and lux to the avaliables units
Warning steradian is a new fundamental units ( definition is nullptr )

* Remove debugging and includes

* Added 15 constants

* Update apps/toolbox.fr.i18n

Co-Authored-By: Quentin <quentin.guidee@gmail.com>

* Update apps/toolbox.fr.i18n

Co-Authored-By: Quentin <quentin.guidee@gmail.com>

* Corrected french and english

* Added hu translation
Correct de translation
added combining double acute accent

* q

* Revert "q"

This reverts commit 959786ae504ddf106249a3f799929471eecb8708.

Co-authored-by: Quentin <quentin.guidee@gmail.com>
2020-02-29 23:50:49 +01:00
Quentin Guidée
83686568ad Merge branch 'omega-hotfix' into omega-dev 2020-02-29 18:56:01 +01:00
Quentin Guidée
849c6e2559 [Feature] Omega App 2020-02-29 18:42:22 +01:00
Quentin Guidée
8a7f815c8e [Feature] Omega App : List 2020-02-29 15:27:17 +01:00
Quentin Guidée
0a10e38caf [Fix] Omega App 2020-02-29 14:01:03 +01:00
Quentin Guidée
79c425100d [Feature] Omega App 2020-02-29 14:00:36 +01:00
Quentin Guidée
d8464ba6a9 Fix conflicts 2020-02-29 12:45:54 +01:00
Quentin Guidée
3affdcfd3d Merge branch 'omega-hotfix' into omega-dev 2020-02-29 10:57:50 +01:00
Quentin Guidée
3e04537abe Merge branch 'omega-hotfix' into omega-dev 2020-02-28 19:52:46 +01:00
Quentin Guidée
9bf0d39030 [GitHub/Fix] GitHub Actions 2020-02-28 19:36:19 +01:00
Quentin Guidée
e21245afbf [GitHub] GitHub Actions 2020-02-28 19:21:06 +01:00
Quentin Guidée
c99ced1699 Merge branch 'omega-hotfix' into omega-dev 2020-02-26 22:20:07 +01:00
Quentin Guidée
bfa727520b Merge branch 'omega-hotfix' into omega-dev 2020-02-26 17:46:03 +01:00
Quentin Guidée
724980280a Merge branch 'coco33920-add_name' into omega-dev 2020-02-25 20:59:08 +01:00
Quentin Guidée
485a8da0fd Merge branch 'add_name' of https://github.com/coco33920/Omega-1 into coco33920-add_name 2020-02-25 20:59:00 +01:00
Quentin Guidée
ae36929760 Merge branch 'omega-dev' of github.com:Omega-Numworks/Omega into omega-dev 2020-02-25 20:46:40 +01:00
Quentin Guidée
cea1df1015 Merge branch 'omega-hotfix' into omega-dev 2020-02-25 20:46:26 +01:00
Colin Thomas
81c5e4797c Add name into contributors page 2020-02-25 20:11:05 +01:00
Charlotte THOMAS
3f76902340 [Fix] Replaced Const by Constante in French i18n files 2020-02-25 19:37:28 +01:00
Charlotte THOMAS
854b660859 [Feature] New physical constants
* Units
Added units to physics constant

* Units
Corrected the value of speed of light ( from 2.998e8 to 2.99792458e8 m/s )

* fix compilation error

* Units
Rename Units Of Measurements => Speed
Suppress light year ( native unit )
Added some speed of sound values

* Update shared.de.i18n

* Update toolbox.es.i18n

* Update toolbox.fr.i18n

* Update toolbox.pt.i18n

* Update toolbox.en.i18n

* Update shared.universal.i18n

Co-authored-by: Quentin <quentin.guidee@gmail.com>
2020-02-25 17:57:25 +01:00
Quentin Guidée
912e7fbc29 Merge branch 'omega-hotfix' into omega-dev 2020-02-25 15:22:02 +01:00
Quentin Guidée
c603469a64 Merge branch 'omega-hotfix' into omega-dev 2020-02-25 15:18:20 +01:00
Charlotte THOMAS
1f39c37b56 [Feature] Adding units to physics const
* Units
Added units to physics constant

* Units
Corrected the value of speed of light ( from 2.998e8 to 2.99792458e8 m/s )

* fix compilation error
2020-02-25 15:08:24 +01:00
Quentin Guidée
074afa2fef Fix conflicts 2020-02-23 13:45:07 +01:00
Quentin Guidée
836b23b06c Merge branch 'omega-dev' of github.com:Omega-Numworks/Omega into omega-dev 2020-02-21 18:14:07 +01:00
Quentin Guidée
a32e802cf4 New Omega App 2020-02-21 18:13:57 +01:00
Quentin
7a4a67a144 Merge pull request #271 from RedGl0w/patch-15
Android simulator renamed
2020-02-21 17:06:07 +01:00
redgl0w
ae884856fe Update strings.xml 2020-02-21 16:56:24 +01:00
Quentin Guidée
4d8a6488c4 Simulator and web simulator renamed 2020-02-21 16:56:16 +01:00
Quentin Guidée
e9a440abca Merge branch 'omega-hotfix' into omega-dev 2020-02-20 23:44:06 +01:00
Quentin Guidée
1310c459b0 Merge branch 'omega-hotfix' into omega-dev 2020-02-20 23:30:40 +01:00
Quentin Guidée
071c19c6a0 Merge branch '0b101-moveResultDisplay' into omega-dev 2020-02-20 22:51:59 +01:00
Quentin Guidée
295d86ce71 Merge branch 'moveResultDisplay' of git://github.com/0b101/Omega-1 into 0b101-moveResultDisplay 2020-02-20 22:49:28 +01:00
0b101
377ab54a58 Moved the result display settings to the math sub-menu 2020-02-20 15:45:54 -06:00
Quentin Guidée
2c22c3ea68 Merge branch 'omega-hotfix' into omega-dev 2020-02-20 21:54:16 +01:00
Quentin Guidée
54b39a14d6 Merge branch 'omega-hotfix' into omega-dev 2020-02-20 00:43:11 +01:00
Quentin Guidée
1f8ae2dc88 Omega 1.20.0 2020-02-18 21:30:05 +01:00
David
96723d8d99 Update apps/toolbox.hu.i18n
Co-Authored-By: Gegenter <36822415+Gegenter@users.noreply.github.com>
2020-02-17 14:41:32 -06:00
David
c456db337f Update apps/toolbox.hu.i18n
Co-Authored-By: Gegenter <36822415+Gegenter@users.noreply.github.com>
2020-02-17 14:41:24 -06:00
David
513c3a8676 Update apps/toolbox.hu.i18n
Co-Authored-By: Gegenter <36822415+Gegenter@users.noreply.github.com>
2020-02-17 14:40:02 -06:00
David
b3e714f8ab Update apps/toolbox.hu.i18n
Co-Authored-By: Gegenter <36822415+Gegenter@users.noreply.github.com>
2020-02-17 14:39:11 -06:00
David
c18b9244ed Update apps/toolbox.hu.i18n
Co-Authored-By: Gegenter <36822415+Gegenter@users.noreply.github.com>
2020-02-17 14:39:04 -06:00
David
41999663aa Update apps/toolbox.hu.i18n
Co-Authored-By: Gegenter <36822415+Gegenter@users.noreply.github.com>
2020-02-17 14:38:58 -06:00
David
ef781d49d0 Update apps/toolbox.hu.i18n
Co-Authored-By: Gegenter <36822415+Gegenter@users.noreply.github.com>
2020-02-17 14:38:52 -06:00
David
207daa31bc Update apps/toolbox.hu.i18n
Co-Authored-By: Gegenter <36822415+Gegenter@users.noreply.github.com>
2020-02-17 14:38:45 -06:00
0b101
97b756bc54 Fixed error 2020-02-17 08:56:25 -06:00
0b101
978c3e28e9 Added more units 2020-02-17 08:54:43 -06:00
920 changed files with 39491 additions and 8047 deletions

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1 @@
blank_issues_enabled: false

12
.github/workflows/ci-docker.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
name: Docker Image CI
on: [pull_request, push]
jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Build the Docker image
run: docker build . --file docker/Dockerfile --tag omega:$(date +%s)

View File

@@ -2,7 +2,25 @@ name: Continuous integration
on: [pull_request, push]
jobs:
build-simulator-android:
# nintendo_3ds:
# runs-on: ubuntu-latest
# steps:
# - run: wget https://github.com/devkitPro/pacman/releases/download/v1.0.2/devkitpro-pacman.amd64.deb -O /tmp/devkitpro-pacman.deb
# - run: yes | sudo dpkg -i /tmp/devkitpro-pacman.deb
# - run: yes | sudo dkp-pacman -Syu --needed devkitARM 3dstools libctru
# - run: echo ::set-env name=DEVKITPRO::/opt/devkitpro
# - run: echo ::set-env name=DEVKITARM::/opt/devkitpro/devkitARM
# - run: echo ::set-env name=PATH::$DEVKITPRO/tools/bin:$DEVKITARM/bin:$PATH
# - uses: actions/checkout@v1
# with:
# submodules: true
# - run: make -j2 PLATFORM=simulator TARGET=3ds
# - uses: actions/upload-artifact@master
# with:
# name: epsilon-3ds.3dsx
# path: output/release/simulator/3ds/epsilon.3dsx
android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
@@ -11,9 +29,9 @@ jobs:
- run: make -j2 PLATFORM=simulator TARGET=android
- uses: actions/upload-artifact@master
with:
name: epsilon-simulator-android.apk
path: output/release/simulator/android/app/outputs/apk/release/android-release-unsigned.apk
build-device-n0100:
name: epsilon-android.apk
path: output/release/simulator/android/epsilon.apk
n0100:
runs-on: ubuntu-latest
steps:
- run: sudo apt-get install build-essential imagemagick libfreetype6-dev libjpeg-dev libpng-dev pkg-config
@@ -21,18 +39,40 @@ jobs:
- uses: actions/checkout@v1
with:
submodules: true
- run: make -j2 MODEL=n0100 epsilon.dfu
- run: make -j2 MODEL=n0100 epsilon.onboarding.dfu
- run: make -j2 MODEL=n0100 epsilon.onboarding.update.dfu
- run: make -j2 MODEL=n0100 epsilon.onboarding.beta.dfu
- run: make -j2 MODEL=n0100 flasher.light.dfu
- run: make -j2 MODEL=n0100 flasher.verbose.dfu
- run: mkdir final-output
- run: make -j2 MODEL=n0100 EPSILON_I18N=en output/release/device/n0100/epsilon.onboarding.two_binaries
- run: mv output/release/device/n0100/epsilon.onboarding.internal.bin final-output/epsilon.onboarding.internal.en.bin
- run: rm output/release/device/n0100/apps/i18n.o output/release/device/n0100/apps/i18n.cpp
- run: make -j2 MODEL=n0100 EPSILON_I18N=fr output/release/device/n0100/epsilon.onboarding.two_binaries
- run: mv output/release/device/n0100/epsilon.onboarding.internal.bin final-output/epsilon.onboarding.internal.fr.bin
- run: rm output/release/device/n0100/apps/i18n.o output/release/device/n0100/apps/i18n.cpp
- run: make -j2 MODEL=n0100 EPSILON_I18N=nl output/release/device/n0100/epsilon.onboarding.two_binaries
- run: mv output/release/device/n0100/epsilon.onboarding.internal.bin final-output/epsilon.onboarding.internal.nl.bin
- run: rm output/release/device/n0100/apps/i18n.o output/release/device/n0100/apps/i18n.cpp
- run: make -j2 MODEL=n0100 EPSILON_I18N=pt output/release/device/n0100/epsilon.onboarding.two_binaries
- run: mv output/release/device/n0100/epsilon.onboarding.internal.bin final-output/epsilon.onboarding.internal.pt.bin
- run: rm output/release/device/n0100/apps/i18n.o output/release/device/n0100/apps/i18n.cpp
- run: make -j2 MODEL=n0100 EPSILON_I18N=it output/release/device/n0100/epsilon.onboarding.two_binaries
- run: mv output/release/device/n0100/epsilon.onboarding.internal.bin final-output/epsilon.onboarding.internal.it.bin
- run: rm output/release/device/n0100/apps/i18n.o output/release/device/n0100/apps/i18n.cpp
- run: make -j2 MODEL=n0100 EPSILON_I18N=de output/release/device/n0100/epsilon.onboarding.two_binaries
- run: mv output/release/device/n0100/epsilon.onboarding.internal.bin final-output/epsilon.onboarding.internal.de.bin
- run: rm output/release/device/n0100/apps/i18n.o output/release/device/n0100/apps/i18n.cpp
- run: make -j2 MODEL=n0100 EPSILON_I18N=es output/release/device/n0100/epsilon.onboarding.two_binaries
- run: mv output/release/device/n0100/epsilon.onboarding.internal.bin final-output/epsilon.onboarding.internal.es.bin
- run: rm output/release/device/n0100/apps/i18n.o output/release/device/n0100/apps/i18n.cpp
- run: make -j2 MODEL=n0100 EPSILON_I18N=hu output/release/device/n0100/epsilon.onboarding.two_binaries
- run: mv output/release/device/n0100/epsilon.onboarding.internal.bin final-output/epsilon.onboarding.internal.hu.bin
- run: rm output/release/device/n0100/apps/i18n.o output/release/device/n0100/apps/i18n.cpp
- run: make -j2 MODEL=n0100 output/release/device/n0100/flasher.light.bin
- run: mv output/release/device/n0100/flasher.light.bin final-output/flasher.light.bin
- run: find final-output/ -type f -exec bash -c "shasum -a 256 -b {} > {}.sha256" \;
- run: tar cvfz binpack-n0100.tgz final-output/*
- uses: actions/upload-artifact@master
with:
name: epsilon-device-n0100.dfu
path: output/release/device/n0100/epsilon.dfu
- run: make -j2 MODEL=n0100 test.elf
build-device-n0110:
name: epsilon-binpack-n0100.tgz
path: binpack-n0100.tgz
n0110:
runs-on: ubuntu-latest
steps:
- run: sudo apt-get install build-essential imagemagick libfreetype6-dev libjpeg-dev libpng-dev pkg-config
@@ -48,27 +88,27 @@ jobs:
- run: make -j2 flasher.verbose.dfu
- run: make -j2 bench.ram.dfu
- run: make -j2 bench.flash.dfu
- run: make -j2 binpack
- run: cp output/release/device/n0110/binpack-n0110-`git rev-parse HEAD | head -c 7`.tgz output/release/device/n0110/binpack-n0110.tgz
- uses: actions/upload-artifact@master
with:
name: epsilon-device-n0110.dfu
path: output/release/device/n0110/epsilon.dfu
- run: make -j2 test.elf
build-simulator-web:
name: epsilon-binpack-n0110.tgz
path: output/release/device/n0110/binpack-n0110.tgz
web:
runs-on: ubuntu-latest
steps:
- uses: numworks/setup-emscripten@v1
- uses: numworks/setup-emscripten@v2
with:
sdk: latest-fastcomp
sdk: latest-upstream
- uses: actions/checkout@v1
with:
submodules: true
- run: make -j2 PLATFORM=simulator TARGET=web
- uses: actions/upload-artifact@master
with:
name: epsilon-simulator-web.zip
name: epsilon-web.zip
path: output/release/simulator/web/epsilon.zip
- run: make -j2 PLATFORM=simulator TARGET=web test.headless.js
build-simulator-linux:
linux:
runs-on: ubuntu-latest
steps:
- run: sudo apt-get install build-essential imagemagick libfreetype6-dev libjpeg-dev libpng-dev pkg-config
@@ -78,6 +118,6 @@ jobs:
- run: make -j2 PLATFORM=simulator
- uses: actions/upload-artifact@master
with:
name: epsilon-simulator-linux.bin
name: epsilon-linux.bin
path: output/release/simulator/linux/epsilon.bin
- run: make -j2 PLATFORM=simulator test.headless.bin

38
.github/workflows/metric-workflow.yml vendored Normal file
View File

@@ -0,0 +1,38 @@
name: Metrics
on: [pull_request]
jobs:
binary-size:
runs-on: ubuntu-latest
steps:
- name: Install dependencies
run: sudo apt-get install build-essential imagemagick libfreetype6-dev libjpeg-dev libpng-dev pkg-config
- name: Install ARM toolchain
uses: numworks/setup-arm-toolchain@v1
- name: Checkout PR base
uses: actions/checkout@v2
with:
submodules: recursive
ref: ${{ github.event.pull_request.base.sha }}
path: base
- name: Build base
run: make -j2 -C base epsilon.elf
- name: Checkout PR head
uses: actions/checkout@v2
with:
submodules: recursive
ref: ${{ github.event.pull_request.head.sha }}
path: head
- name: Build head
run: make -j2 -C head epsilon.elf
- name: Retrieve binary size analysis
id: binary_size
run: echo "::set-output name=table::$(python3 head/build/metrics/binary_size.py base/output/release/device/n0110/epsilon.elf head/output/release/device/n0110/epsilon.elf --labels Base Head --sections .text .rodata .bss .data --custom 'Total (RAM)' .data .bss --custom 'Total (ROM)' .text .rodata .data --escape)"
- name: Prepare comment auth
run: echo "::set-env name=GITHUB_TOKEN::$(echo YjgxYTk1YTQ4YzYxNjU4ZTA3YWQzNDYwNTk3ZTI2MTlkODU5MThlOQo= | base64 --decode)"
- name: Add comment
uses: actions/github@v1.0.0
env:
GITHUB_TOKEN: ${{ env.GITHUB_TOKEN }}
with:
args: comment ${{ steps.binary_size.outputs.table }}

1
.gitignore vendored
View File

@@ -2,6 +2,7 @@
/build/artifacts/
build/device/**/*.pyc
epsilon.elf
epsilon.map
.vscode
.DS_Store
.gradle

76
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,76 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at getomega.pro@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

View File

@@ -1,4 +1,16 @@
# Disable default Make rules
.SUFFIXES:
# Define the default recipe
default:
include build/config.mak
include build/pimp.mak
include build/defaults.mak
include build/platform.$(PLATFORM).mak
include build/toolchain.$(TOOLCHAIN).mak
include build/variants.mak
include build/helpers.mk
ifeq (${MODEL}, n0110)
apps_list = ${EPSILON_APPS}
@@ -10,46 +22,24 @@ ifdef FORCE_EXTERNAL
apps_list = ${EPSILON_APPS}
endif
# Disable default Make rules
.SUFFIXES:
object_for = $(addprefix $(BUILD_DIR)/,$(addsuffix .o,$(basename $(1))))
# Define the default recipe
default:
# Define a standard rule helper
# If passed a last parameter value of with_local_version, we also define an
# extra rule that can build source files within the $(BUILD_DIR). This is useful
# for rules that can be applied for intermediate objects (for example, when
# going .png -> .cpp -> .o).
define rule_label
@ echo "$(shell printf "%-8s" $(strip $(1)))$(@:$(BUILD_DIR)/%=%)"
endef
define rule_for
ifeq ($(strip $(5)),with_local_version)
$(addprefix $$(BUILD_DIR)/,$(strip $(2))): $(addprefix $$(BUILD_DIR)/,$(strip $(3))) | $(if $(findstring official,${MAKECMDGOALS}),official_authorization)
@ echo "$(shell printf "%-8s" $(strip $(1)))$$(@:$$(BUILD_DIR)/%=%)"
$(Q) $(4)
ifdef HOME_DISPLAY_EXTERNALS
ifneq ($(filter external,$(apps_list)),)
SFLAGS += -DHOME_DISPLAY_EXTERNALS
else
$(warning HOME_DISPLAY_EXTERNALS is set but external isn't included, ignoring flag.)
endif
endif
$(addprefix $$(BUILD_DIR)/,$(strip $(2))): $(strip $(3)) | $$$$(@D)/. $(if $(findstring official,${MAKECMDGOALS}),official_authorization)
@ echo "$(shell printf "%-8s" $(strip $(1)))$$(@:$$(BUILD_DIR)/%=%)"
$(Q) $(4)
endef
.PHONY: info
info:
@echo "EPSILON_VERSION = $(EPSILON_VERSION)"
@echo "EPSILON_APPS = $(EPSILON_APPS)"
@echo "EPSILON_I18N = $(EPSILON_I18N)"
@echo "OMEGA_THEME = $(OMEGA_THEME)"
@echo "THEME_NAME = $(THEME_NAME)"
@echo "THEME_REPO = $(THEME_REPO)"
@echo "BUILD_DIR = $(BUILD_DIR)"
@echo "PLATFORM" = $(PLATFORM)
@echo "DEBUG" = $(DEBUG)
@echo "LEDS_CHOICE" = $(LEDS_CHOICE)
@echo "EPSILON_GETOPT" = $(EPSILON_GETOPT)
@echo "ESCHER_LOG_EVENTS_BINARY" = $(ESCHER_LOG_EVENTS_BINARY)
@echo "QUIZ_USE_CONSOLE" = $(QUIZ_USE_CONSOLE)
@@ -78,6 +68,7 @@ help:
@echo " make PLATFORM=simulator TARGET=macos"
@echo " make PLATFORM=simulator TARGET=web"
@echo " make PLATFORM=simulator TARGET=windows"
@echo " make PLATFORM=simulator TARGET=3ds"
.PHONY: doc
doc:
@@ -107,7 +98,9 @@ $(BUILD_DIR)%/.:
# Each sub-Makefile can either add sources to $(%_src) variables or define a
# new executable target. The $(%_src) variables list the sources that can be
# built and linked to executables being generated.
ifndef USE_LIBA
$(error platform.mak should define USE_LIBA)
endif
ifeq ($(USE_LIBA),0)
include liba/Makefile.bridge
else
@@ -126,10 +119,10 @@ include build/struct_layout/Makefile
include build/scenario/Makefile
include quiz/Makefile # Quiz needs to be included at the end
all_src = $(apps_all_src) $(escher_src) $(ion_all_src) $(kandinsky_src) $(liba_src) $(libaxx_src) $(poincare_src) $(python_src) $(runner_src) $(ion_target_device_flasher_light_src) $(ion_target_device_flasher_verbose_src) $(ion_target_device_bench_src) $(tests_src)
all_src = $(apps_src) $(escher_src) $(ion_src) $(kandinsky_src) $(liba_src) $(libaxx_src) $(poincare_src) $(python_src) $(runner_src) $(ion_device_flasher_src) $(ion_device_bench_src) $(tests_src)
# Make palette.h a dep for every source-file.
# This ensures that the theming engine works correctly.
$(call object_for,$(all_app_src)): $(BUILD_DIR)/escher/palette.h
$(call object_for,$(all_src)): $(BUILD_DIR)/escher/palette.h $(BUILD_DIR)/apps/i18n.h
all_objs = $(call object_for,$(all_src))
.SECONDARY: $(all_objs)
@@ -144,8 +137,7 @@ all_objs = $(call object_for,$(all_src))
include build/targets.mak
# Fill in the default recipe
DEFAULT ?= $(BUILD_DIR)/epsilon.$(EXE)
default: $(DEFAULT)
default: $(firstword $(HANDY_TARGETS)).$(firstword $(HANDY_TARGETS_EXTENSIONS))
# Load standard build rules
include build/rules.mk
@@ -185,7 +177,7 @@ cleanandcompile:
.PHONY: start
start:
@echo "INFO Starting output/$(BUILD_TYPE)/simulator/$(HOST)/epsilon.$(EXE)"
@$(Q) output/$(BUILD_TYPE)/simulator/$(HOST)/epsilon.$(EXE)
@$(Q) output/$(BUILD_TYPE)/simulator/$(HOST)/epsilon.$(EXE) -v
.PHONY: clean_run
clean_run: cleanandcompile

View File

@@ -1,10 +1,10 @@
<p align="center"><img src="https://github.com/Omega-Numworks/Omega-Design/blob/master/Omega-Banner.png" /></p>
<p align="center"><img src="https://user-images.githubusercontent.com/12123721/87953533-75a22380-caab-11ea-8cde-c40291c4a9ae.png" /></p>
<p align="center">
<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="cc by-nc-sa 4.0" src="https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-525252.svg?labelColor=292929&logo=creative%20commons&style=for-the-badge" /></a>
<a href="https://github.com/Omega-Numworks/Omega/issues"><img alt="Issues" src="https://img.shields.io/github/issues/Omega-Numworks/Omega.svg?labelColor=292929&logo=git&style=for-the-badge" /></a>
<br/>
<a href="https://discord.gg/hjH3gtd"><img alt="Discord" src="https://img.shields.io/discord/663420259851567114?color=blue&labelColor=292929&label=chat%20-%20discord&logo=discord&style=for-the-badge" /></a>
<a href="https://discord.gg/X2TWhh9"><img alt="Discord" src="https://img.shields.io/discord/663420259851567114?color=blue&labelColor=292929&label=chat%20-%20discord&logo=discord&style=for-the-badge" /></a>
</p>
## About
@@ -19,10 +19,18 @@ Omega is a fork of Numworks' Epsilon, the OS that runs on their calculator, whic
- ~~32 KB Python heap instead of 16 KB~~ Now available on Epsilon `>=13.2.0`!
- And more...
The main new features are listed [here](https://github.com/Omega-Numworks/Omega/wiki/Main-features), and the complete changelog can be found [here](https://github.com/quentinguidee/Omega/wiki/Complete-changelog).
The main new features are listed [here](https://github.com/Omega-Numworks/Omega/wiki/Main-features), and the complete changelog can be found [here](https://github.com/Omega-Numworks/Omega/wiki/Changelog).
## Installation
### Automatic
You can install Omega automatically on our website [here](https://getomega.web.app/) in the "install" page.
<a href="https://getomega.web.app"><p align="center"><img alt="Omega Banner Discord" src="https://user-images.githubusercontent.com/12123721/86352956-e9000480-bc66-11ea-82b7-79fd7e56fa27.png" /></p></a>
### Manual
First of all, follow **step 1** [here](https://www.numworks.com/resources/engineering/software/build/). Then:
<details>
@@ -33,7 +41,7 @@ git clone --recursive https://github.com/Omega-Numworks/Omega.git
cd Omega
git checkout omega-master
make MODEL=n0100 clean
make MODEL=n0100 USERNAME="{Your name, max 15 characters}" -j4
make MODEL=n0100 OMEGA_USERNAME="{Your name, max 15 characters}" -j4
make MODEL=n0100 epsilon_flash
```
@@ -50,7 +58,7 @@ git clone --recursive https://github.com/Omega-Numworks/Omega.git
cd Omega
git checkout omega-master
make clean
make USERNAME="{Your name, max 15 characters}" -j4
make OMEGA_USERNAME="{Your name, max 15 characters}" -j4
make epsilon_flash
```
@@ -69,10 +77,10 @@ git clone --recursive https://github.com/Omega-Numworks/Omega.git
cd Omega
git checkout omega-master
make clean
make MODEL=n0100 USERNAME="" -j8
make MODEL=n0100 USERNAME="" binpack -j8
make USERNAME="" -j8
make USERNAME="" binpack -j8
make MODEL=n0100 OMEGA_USERNAME="" -j8
make MODEL=n0100 OMEGA_USERNAME="" binpack -j8
make OMEGA_USERNAME="" -j8
make OMEGA_USERNAME="" binpack -j8
```
Important: Don't forget the `--recursive` tag, because Omega relies on submodules.
@@ -100,7 +108,7 @@ git clone --recursive https://github.com/Omega-Numworks/Omega.git
cd Omega
git checkout omega-master
make clean
make PLATFORM=simulator TARGET=web USERNAME="{Your name, max 15 characters}" -j4
make PLATFORM=simulator TARGET=web OMEGA_USERNAME="{Your name, max 15 characters}" -j4
```
The simulator is now in `output/release/simulator/web/simulator.zip`
@@ -110,6 +118,28 @@ Also, you can change the number of processes that run in parallel during the bui
</details>
<details>
<summary><b>3DS Simulator</b></summary>
You need devkitPro and devkitARM installed and in your path (instructions [here](https://devkitpro.org/wiki/Getting_Started))
```
git clone --recursive https://github.com/Omega-Numworks/Omega.git
cd Omega
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:
```
3dslink output/release/simulator/3ds/epsilon.3dsx -a <3DS' IP ADDRESS>
```
</details>
If you need help, you can join our Discord server here : https://discord.gg/X2TWhh9
<a href="https://discord.gg/X2TWhh9"><p align="center"><img alt="Omega Banner Discord" src="https://user-images.githubusercontent.com/12123721/86287349-54ef5800-bbe8-11ea-80c1-34eb1f93eebd.png" /></p></a>
---
## Contributing
To contribute, please refer to the [Wiki](https://github.com/Omega-Numworks/Omega/wiki/Contributing)
@@ -126,9 +156,7 @@ To contribute, please refer to the [Wiki](https://github.com/Omega-Numworks/Omeg
* [Omega Website](https://github.com/Omega-Numworks/Omega-Website)
* [Omega RPN `APP`](https://github.com/Omega-Numworks/Omega-RPN)
* [Omega Atom `APP`](https://github.com/Omega-Numworks/Omega-Atom)
* [Omega Converter `APP`](https://github.com/Omega-Numworks/Omega-Converter)
* [Omega Design](https://github.com/Omega-Numworks/Omega-Design)
* [Omega CLI Installer `BETA`](https://github.com/Omega-Numworks/Omega-CLI-Installer)
* [Omega App Template `BETA`](https://github.com/Omega-Numworks/Omega-App-Template)
## About Epsilon
@@ -137,15 +165,11 @@ Omega is a fork of Epsilon, a high-performance graphing calculator operating sys
You can try Epsilon straight from your browser in the [online simulator](https://www.numworks.com/simulator/).
## Contributors ✨
Thanks goes to these wonderful people!
<p align="center"><img src="https://github.com/Omega-Numworks/Omega-Design/blob/master/Omega-Contributors.png" /></p>
## License
NumWorks is a registered trademark. Omega is not affiliated with NumWorks.
NumWorks is a registered trademark of NumWorks SAS, 24 Rue Godot de Mauroy, 75009 Paris, France.
Nintendo and Nintendo 3DS are registered trademarks of Nintendo of America Inc, 4600 150th Ave NE, Redmond, WA 98052, USA.
NumWorks SAS and Nintendo of America Inc aren't associated in any shape or form with this project.
* NumWorks Epsilon is released under a [CC BY-NC-SA License](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode).
* Omega is released under a [CC BY-NC-SA License](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode).

View File

@@ -1,3 +1,4 @@
include apps/helpers.mk
include apps/shared/Makefile
include apps/home/Makefile
include apps/on_boarding/Makefile
@@ -10,8 +11,15 @@ apps =
# (path to the apps header).
$(foreach i,${apps_list},${eval include apps/$(i)/Makefile})
app_src += $(addprefix apps/,\
apps_src += $(addprefix apps/,\
alternate_empty_nested_menu_controller.cpp \
apps_container.cpp \
apps_container_launch_default.cpp:-onboarding \
apps_container_launch_on_boarding.cpp:+onboarding \
apps_container_prompt_beta.cpp:+beta \
apps_container_prompt_none.cpp:-beta \
apps_container_prompt_none.cpp:-update \
apps_container_prompt_update.cpp:+update \
apps_container_storage.cpp \
apps_window.cpp \
backlight_dimming_timer.cpp \
@@ -19,27 +27,21 @@ app_src += $(addprefix apps/,\
battery_view.cpp \
empty_battery_window.cpp \
exam_pop_up_controller.cpp \
exam_mode_configuration_official.cpp:+official \
exam_mode_configuration_non_official.cpp:-official \
global_preferences.cpp \
i18n.py \
lock_view.cpp \
main.cpp \
math_toolbox.cpp \
math_variable_box_controller.cpp \
math_variable_box_empty_controller.cpp \
shift_alpha_lock_view.cpp \
suspend_timer.cpp \
title_bar_view.cpp \
variable_box_controller.cpp \
variable_box_empty_controller.cpp \
)
tests_src += apps/exam_mode_configuration_non_official.cpp
apps_official += apps/exam_mode_configuration_non_official.cpp
apps_non_official += apps/exam_mode_configuration_non_official.cpp
apps_launch_on_boarding_src += apps/apps_container_launch_on_boarding.cpp
apps_launch_default_src += apps/apps_container_launch_default.cpp
apps_prompt_none_src += apps/apps_container_prompt_none.cpp
apps_prompt_beta_src += apps/apps_container_prompt_beta.cpp
apps_prompt_update_src += apps/apps_container_prompt_update.cpp
snapshots_declaration = $(foreach i,$(apps),$(i)::Snapshot m_snapshot$(subst :,,$(i))Snapshot;)
apps_declaration = $(foreach i,$(apps),$(i) m_$(subst :,,$(i));)
@@ -49,7 +51,7 @@ snapshots_count = $(words $(apps))
snapshot_includes = $(foreach i,$(app_headers),-include $(i) )
epsilon_app_names = '$(foreach i,${apps_list},"$(i)", )'
$(call object_for,apps/apps_container_storage.cpp apps/apps_container.cpp apps/main.cpp): CXXFLAGS += $(snapshot_includes) -DAPPS_CONTAINER_APPS_DECLARATION="$(apps_declaration)" -DAPPS_CONTAINER_SNAPSHOT_DECLARATIONS="$(snapshots_declaration)" -DAPPS_CONTAINER_SNAPSHOT_CONSTRUCTORS="$(snapshots_construction)" -DAPPS_CONTAINER_SNAPSHOT_LIST="$(snapshots_list)" -DAPPS_CONTAINER_SNAPSHOT_COUNT=$(snapshots_count) -DEPSILON_APPS_NAMES=$(epsilon_app_names) -DUSERNAME="$(USERNAME)"
$(call object_for,apps/apps_container_storage.cpp apps/apps_container.cpp apps/main.cpp): CXXFLAGS += $(snapshot_includes) -DAPPS_CONTAINER_APPS_DECLARATION="$(apps_declaration)" -DAPPS_CONTAINER_SNAPSHOT_DECLARATIONS="$(snapshots_declaration)" -DAPPS_CONTAINER_SNAPSHOT_CONSTRUCTORS="$(snapshots_construction)" -DAPPS_CONTAINER_SNAPSHOT_LIST="$(snapshots_list)" -DAPPS_CONTAINER_SNAPSHOT_COUNT=$(snapshots_count) -DEPSILON_APPS_NAMES=$(epsilon_app_names) -DOMEGA_USERNAME="$(OMEGA_USERNAME)"
# I18n file generation
@@ -57,33 +59,20 @@ $(call object_for,apps/apps_container_storage.cpp apps/apps_container.cpp apps/m
SFLAGS += -I$(BUILD_DIR)
i18n_files += $(addprefix apps/language_,$(addsuffix .universal.i18n, $(EPSILON_I18N)))
i18n_files += $(addprefix apps/,\
shared.de.i18n\
shared.en.i18n\
shared.es.i18n\
shared.fr.i18n\
shared.pt.i18n\
shared.hu.i18n\
shared.universal.i18n\
toolbox.de.i18n\
toolbox.en.i18n\
toolbox.es.i18n\
toolbox.fr.i18n\
toolbox.pt.i18n\
toolbox.hu.i18n\
variables.de.i18n\
variables.en.i18n\
variables.es.i18n\
variables.fr.i18n\
variables.pt.i18n\
variables.hu.i18n\
)
ifeq ($(EPSILON_GETOPT),1)
i18n_files += $(addprefix apps/language_,$(addsuffix _iso6391.universal.i18n, $(EPSILON_I18N)))
endif
i18n_files += $(call i18n_with_universal_for,shared)
i18n_files += $(call i18n_without_universal_for,toolbox)
i18n_files += $(call i18n_without_universal_for,variables)
$(eval $(call rule_for, \
I18N, \
apps/i18n.cpp, \
$(i18n_files), \
$$(PYTHON) apps/i18n.py --header $$(subst .cpp,.h,$$@) --implementation $$@ --locales $$(EPSILON_I18N) --files $$^ \
$$(PYTHON) apps/i18n.py --codepoints $(code_points) --header $$(subst .cpp,.h,$$@) --implementation $$@ --locales $$(EPSILON_I18N) --files $$^ --generateISO6391locales $$(EPSILON_GETOPT), \
global \
))
@@ -94,36 +83,30 @@ $(BUILD_DIR)/apps/i18n.h: $(BUILD_DIR)/apps/i18n.cpp
$(eval $(call depends_on_image,apps/title_bar_view.cpp,apps/exam_icon.png))
all_app_src = $(app_src)(apps_launch_on_boarding_src) $(apps_launch_default_src) $(apps_prompt_none_src) $(apps_prompt_update_src) $(apps_prompt_beta_src) $(apps_official) $(apps_non_official) $(tests_src)
$(call object_for,$(apps_src) $(tests_src)): $(BUILD_DIR)/apps/i18n.h
$(call object_for,$(apps_src) $(tests_src)): $(BUILD_DIR)/python/port/genhdr/qstrdefs.generated.h
$(call object_for,$(all_app_src)): $(BUILD_DIR)/apps/i18n.h
$(call object_for,$(all_app_src)): $(BUILD_DIR)/python/port/genhdr/qstrdefs.generated.h
apps_tests_src = $(app_calculation_test_src) $(app_probability_test_src) $(app_regression_test_src) $(app_sequence_test_src) $(app_shared_test_src) $(app_statistics_test_src) $(app_settings_test_src) $(app_solver_test_src)
apps_tests_src = $(app_calculation_test_src) $(app_code_test_src) $(app_probability_test_src) $(app_regression_test_src) $(app_sequence_test_src) $(app_shared_test_src) $(app_statistics_test_src) $(app_settings_test_src) $(app_solver_test_src)
apps_tests_src += $(addprefix apps/,\
alternate_empty_nested_menu_controller.cpp \
global_preferences.cpp \
)
ifeq ($(THEME_REPO),local)
$(foreach img,$(image_list), $(eval $(call rule_for, \
ICON, \
$(img), \
$(addprefix themes/themes/, $(addsuffix .json, $(OMEGA_THEME))), \
$$(PYTHON) themes/themes_manager.py -i $(OMEGA_THEME) $$@ $(BUILD_DIR)/ \
$(addprefix themes/themes/local/, $(addsuffix .json, $(THEME_NAME))), \
$$(PYTHON) themes/themes_manager.py -i $(THEME_REPO) $(THEME_NAME) $$@ $(BUILD_DIR)/, \
global \
)))
# Configure variants
apps_all_src = $(app_src)
apps_all_src += $(apps_official) $(apps_non_official)
apps_all_src += $(apps_launch_default_src) $(apps_launch_on_boarding_src)
apps_all_src += $(apps_prompt_none_src) $(apps_prompt_update_src) $(apps_prompt_beta_src)
apps_default_src = $(app_src) $(apps_non_official) $(apps_launch_default_src) $(apps_prompt_none_src)
apps_official_default_src = $(app_src) $(apps_official) $(apps_launch_default_src) $(apps_prompt_none_src)
apps_onboarding_src = $(app_src) $(apps_non_official) $(apps_launch_on_boarding_src) $(apps_prompt_none_src)
apps_official_onboarding_src = $(app_src) $(apps_official) $(apps_launch_on_boarding_src) $(apps_prompt_none_src)
apps_onboarding_update_src = $(app_src) $(apps_non_official) $(apps_launch_on_boarding_src) $(apps_prompt_update_src)
apps_official_onboarding_update_src = $(app_src) $(apps_official) $(apps_launch_on_boarding_src) $(apps_prompt_update_src)
apps_onboarding_beta_src = $(app_src) $(apps_non_official) $(apps_launch_on_boarding_src) $(apps_prompt_beta_src)
apps_official_onboarding_beta_src = $(app_src) $(apps_official) $(apps_launch_on_boarding_src) $(apps_prompt_beta_src)
else
$(foreach img,$(image_list), $(eval $(call rule_for, \
ICON, \
$(img), \
$(addsuffix /escher/palette.h, $(BUILD_DIR)), \
$$(PYTHON) themes/themes_manager.py -i $(THEME_REPO) $(THEME_NAME) $$@ $(BUILD_DIR)/, \
global \
)))
endif

View File

@@ -0,0 +1,18 @@
#include "alternate_empty_nested_menu_controller.h"
void AlternateEmptyNestedMenuController::viewDidDisappear() {
if (isDisplayingEmptyController()) {
pop();
}
NestedMenuController::viewDidDisappear();
}
bool AlternateEmptyNestedMenuController::displayEmptyControllerIfNeeded() {
assert(!isDisplayingEmptyController());
// If the content is empty, we push an empty controller.
if (numberOfRows() == 0) {
push(emptyViewController());
return true;
}
return false;
}

View File

@@ -0,0 +1,19 @@
#ifndef APPS_ALTERNATE_EMPTY_NESTED_MENU_CONTROLLER_H
#define APPS_ALTERNATE_EMPTY_NESTED_MENU_CONTROLLER_H
#include <escher/nested_menu_controller.h>
class AlternateEmptyNestedMenuController : public NestedMenuController {
public:
AlternateEmptyNestedMenuController(I18n::Message title) :
NestedMenuController(nullptr, title)
{}
// View Controller
void viewDidDisappear() override;
protected:
virtual ViewController * emptyViewController() = 0;
bool isDisplayingEmptyController() { return StackViewController::depth() == 2; }
bool displayEmptyControllerIfNeeded();
};
#endif

View File

@@ -37,7 +37,7 @@ AppsContainer::AppsContainer() :
m_usbConnectedSnapshot()
{
m_emptyBatteryWindow.setFrame(KDRect(0, 0, Ion::Display::Width, Ion::Display::Height), false);
#if __EMSCRIPTEN__
// #if __EMSCRIPTEN__
/* AppsContainer::poincareCircuitBreaker uses Ion::Keyboard::scan(), which
* calls emscripten_sleep. If we set the poincare circuit breaker, we would
* need to whitelist all the methods that might be in the call stack when
@@ -47,9 +47,13 @@ AppsContainer::AppsContainer() :
* quite painy to maintain).
* We just remove the circuit breaker for now.
* TODO: Put the Poincare circuit breaker back on epsilon's web emulator */
#else
/*
* This can be run in Omega, since it uses WebASM.
*/
// #else
Poincare::Expression::SetCircuitBreaker(AppsContainer::poincareCircuitBreaker);
#endif
// #endif
Ion::Storage::sharedStorage()->setDelegate(this);
}
@@ -88,7 +92,7 @@ MathToolbox * AppsContainer::mathToolbox() {
return &m_mathToolbox;
}
VariableBoxController * AppsContainer::variableBoxController() {
MathVariableBoxController * AppsContainer::variableBoxController() {
return &m_variableBoxController;
}
@@ -218,6 +222,10 @@ bool AppsContainer::processEvent(Ion::Events::Event event) {
switchTo(appSnapshotAtIndex(0));
return true;
}
if (event == Ion::Events::ShiftHome) {
switchTo(appSnapshotAtIndex(1));
return true;
}
if (event == Ion::Events::OnOff) {
suspend(true);
return true;
@@ -366,30 +374,7 @@ void AppsContainer::redrawWindow(bool force) {
void AppsContainer::activateExamMode(GlobalPreferences::ExamMode examMode) {
assert(examMode != GlobalPreferences::ExamMode::Off && examMode != GlobalPreferences::ExamMode::Unknown);
reset();
Preferences * preferences = Preferences::sharedPreferences();
switch ((int)preferences->colorOfLED()) {
case 0:
Ion::LED::setColor(KDColorRed);
break;
case 1:
Ion::LED::setColor(KDColorWhite);
break;
case 2:
Ion::LED::setColor(KDColorGreen);
break;
case 3:
Ion::LED::setColor(KDColorBlue);
break;
case 4:
Ion::LED::setColor(KDColorYellow);
break;
case 5:
Ion::LED::setColor(KDColorPurple);
break;
case 6:
Ion::LED::setColor(KDColorOrange);
break;
}
Ion::LED::setColor(KDColorRed);
/* The Dutch exam mode LED is supposed to be orange but we can only make
* blink "pure" colors: with RGB leds on or off (as the PWM is used for
* blinking). The closest "pure" color is Yellow. Moreover, Orange LED is

View File

@@ -8,7 +8,7 @@
#include "apps_window.h"
#include "empty_battery_window.h"
#include "math_toolbox.h"
#include "variable_box_controller.h"
#include "math_variable_box_controller.h"
#include "exam_pop_up_controller.h"
#include "exam_pop_up_controller_delegate.h"
#include "battery_timer.h"
@@ -34,9 +34,9 @@ public:
void reset();
Poincare::Context * globalContext();
MathToolbox * mathToolbox();
VariableBoxController * variableBoxController();
MathVariableBoxController * variableBoxController();
void suspend(bool checkIfOnOffKeyReleased = false);
virtual bool dispatchEvent(Ion::Events::Event event) override;
bool dispatchEvent(Ion::Events::Event event) override;
bool switchTo(App::Snapshot * snapshot) override;
void run() override;
bool updateBatteryState();
@@ -70,7 +70,7 @@ private:
EmptyBatteryWindow m_emptyBatteryWindow;
Shared::GlobalContext m_globalContext;
MathToolbox m_mathToolbox;
VariableBoxController m_variableBoxController;
MathVariableBoxController m_variableBoxController;
ExamPopUpController m_examPopUpController;
OnBoarding::PopUpController m_promptController;
BatteryTimer m_batteryTimer;

View File

@@ -21,6 +21,7 @@ app_calculation_src = $(addprefix apps/calculation/,\
additional_outputs/trigonometry_graph_cell.cpp \
additional_outputs/trigonometry_list_controller.cpp \
additional_outputs/trigonometry_model.cpp \
additional_outputs/unit_list_controller.cpp \
app.cpp \
edit_expression_controller.cpp \
expression_field.cpp \
@@ -30,16 +31,9 @@ app_calculation_src = $(addprefix apps/calculation/,\
)
app_calculation_src += $(app_calculation_test_src)
app_src += $(app_calculation_src)
apps_src += $(app_calculation_src)
i18n_files += $(addprefix apps/calculation/,\
base.de.i18n\
base.en.i18n\
base.es.i18n\
base.fr.i18n\
base.pt.i18n\
base.hu.i18n\
)
i18n_files += $(call i18n_without_universal_for,calculation/base)
tests_src += $(addprefix apps/calculation/test/,\
calculation_store.cpp\

View File

@@ -1,4 +1,5 @@
#include "complex_graph_cell.h"
#include <escher/palette.h>
using namespace Shared;
using namespace Poincare;
@@ -12,7 +13,7 @@ ComplexGraphView::ComplexGraphView(ComplexModel * complexModel) :
}
void ComplexGraphView::drawRect(KDContext * ctx, KDRect rect) const {
ctx->fillRect(rect, KDColorWhite);
ctx->fillRect(rect, Palette::BackgroundApps);
// Draw grid, axes and graduations
drawGrid(ctx, rect);
@@ -25,7 +26,7 @@ void ComplexGraphView::drawRect(KDContext * ctx, KDRect rect) const {
assert(!std::isnan(real) && !std::isnan(imag) && !std::isinf(real) && !std::isinf(imag));
// Draw the segment from the origin to the dot (real, imag)
drawSegment(ctx, rect, 0.0f, 0.0f, m_complex->real(), m_complex->imag(), Palette::GreyDark, false);
drawSegment(ctx, rect, 0.0f, 0.0f, m_complex->real(), m_complex->imag(), Palette::SecondaryText, false);
/* Draw the partial ellipse indicating the angle θ
* - the ellipse parameters are a = |real|/5 and b = |imag|/5,
@@ -39,7 +40,7 @@ void ComplexGraphView::drawRect(KDContext * ctx, KDRect rect) const {
* and the line of equation (real*t,imag*t).
* (a*cos(t), b*sin(t)) = (real*t,imag*t) --> tan(t) = sign(a)*sign(b) (± π)
* --> t = π/4 [π/2] according to sign(a) and sign(b). */
float th = real < 0.0f ? 3.0f*M_PI/4.0f : M_PI/4.0f;
float th = real < 0.0f ? (float)(3.0*M_PI_4) : (float)M_PI_4;
th = imag < 0.0f ? -th : th;
// Compute ellipsis parameters a and b
float factor = 5.0f;
@@ -48,7 +49,7 @@ void ComplexGraphView::drawRect(KDContext * ctx, KDRect rect) const {
// Avoid flat ellipsis for edge cases (for real = 0, the case imag = 0 is excluded)
if (real == 0.0f) {
a = 1.0f/factor;
th = imag < 0.0f ? -M_PI/2.0f : M_PI/2.0f;
th = imag < 0.0f ? (float)-M_PI_2 : (float)M_PI_2;
}
std::complex<float> parameters(a,b);
drawCurve(ctx, rect, 0.0f, 1.0f, 0.01f,
@@ -58,27 +59,27 @@ void ComplexGraphView::drawRect(KDContext * ctx, KDRect rect) const {
float a = parameters.real();
float b = parameters.imag();
return Poincare::Coordinate2D<float>(a*std::cos(t*th), b*std::sin(t*th));
}, &parameters, &th, false, Palette::GreyDark, false);
}, &parameters, &th, false, Palette::SecondaryText, false);
// Draw dashed segment to indicate real and imaginary
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, real, 0.0f, imag, Palette::Red, 1, 3);
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Horizontal, imag, 0.0f, real, Palette::Red, 1, 3);
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, real, 0.0f, imag, Palette::CalculationTrigoAndComplexForeground, 1, 3);
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Horizontal, imag, 0.0f, real, Palette::CalculationTrigoAndComplexForeground, 1, 3);
// Draw complex position on the plan
drawDot(ctx, rect, real, imag, Palette::Red, Size::Large);
drawDot(ctx, rect, real, imag, Palette::CalculationTrigoAndComplexForeground, Size::Large);
// Draw labels
// 're(z)' label
drawLabel(ctx, rect, real, 0.0f, "re(z)", Palette::Red, CurveView::RelativePosition::None, imag >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After);
drawLabel(ctx, rect, real, 0.0f, "re(z)", Palette::CalculationTrigoAndComplexForeground, CurveView::RelativePosition::None, imag >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After);
// 'im(z)' label
drawLabel(ctx, rect, 0.0f, imag, "im(θ)", Palette::Red, real >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After, CurveView::RelativePosition::None);
drawLabel(ctx, rect, 0.0f, imag, "im(z)", Palette::CalculationTrigoAndComplexForeground, real >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After, CurveView::RelativePosition::None);
// '|z|' label, the relative horizontal position of this label depends on the quadrant
CurveView::RelativePosition verticalPosition = real*imag < 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After;
if (real == 0.0f) {
// Edge case: pure imaginary
verticalPosition = CurveView::RelativePosition::None;
}
drawLabel(ctx, rect, real/2.0f, imag/2.0f, "|z|", Palette::Red, CurveView::RelativePosition::None, verticalPosition);
drawLabel(ctx, rect, real/2.0f, imag/2.0f, "|z|", Palette::CalculationTrigoAndComplexForeground, CurveView::RelativePosition::None, verticalPosition);
// 'arg(z)' label, the absolute and relative horizontal/vertical positions of this label depends on the quadrant
CurveView::RelativePosition horizontalPosition = real >= 0.0f ? CurveView::RelativePosition::After : CurveView::RelativePosition::None;
verticalPosition = imag >= 0.0f ? CurveView::RelativePosition::After : CurveView::RelativePosition::Before;
@@ -87,7 +88,7 @@ void ComplexGraphView::drawRect(KDContext * ctx, KDRect rect) const {
* and for the left half plan, we position the label at the half angle. The
* relative position is chosen accordingly. */
float anglePositionRatio = real >= 0.0f ? 0.0f : 0.5f;
drawLabel(ctx, rect, a*std::cos(anglePositionRatio*th), b*std::sin(anglePositionRatio*th), "arg(z)", Palette::Red, horizontalPosition, verticalPosition);
drawLabel(ctx, rect, a*std::cos(anglePositionRatio*th), b*std::sin(anglePositionRatio*th), "arg(z)", Palette::CalculationTrigoAndComplexForeground, horizontalPosition, verticalPosition);
}
}

View File

@@ -26,10 +26,10 @@ void ComplexListController::setExpression(Poincare::Expression e) {
}
Poincare::Context * context = App::app()->localContext();
// Fill Calculation Store
m_calculationStore.push("im(z)", context);
m_calculationStore.push("re(z)", context);
m_calculationStore.push("arg(z)", context);
m_calculationStore.push("abs(z)", context);
m_calculationStore.push("im(z)", context, CalculationHeight);
m_calculationStore.push("re(z)", context, CalculationHeight);
m_calculationStore.push("arg(z)", context, CalculationHeight);
m_calculationStore.push("abs(z)", context, CalculationHeight);
// Set Complex illustration
// Compute a and b as in Expression::hasDefinedComplexApproximation to ensure the same defined result

View File

@@ -10,7 +10,7 @@ namespace Calculation {
class ComplexListController : public IllustratedListController {
public:
ComplexListController(EditExpressionController * editExpressionController) :
IllustratedListController(nullptr, editExpressionController),
IllustratedListController(editExpressionController),
m_complexGraphCell(&m_model) {}
// ViewController

View File

@@ -17,10 +17,10 @@ float ComplexModel::rangeBound(float direction, bool horizontal) const {
maxFactor = k_maxHorizontalMarginFactor;
value = real();
}
if (std::isnan(value) || std::isinf(value) || value == 0.0f) {
return direction*maxFactor;
}
float factor = direction*value >= 0.0f ? maxFactor : minFactor;
if (std::isnan(value) || std::isinf(value) || value == 0.0f) {
return direction*factor;
}
return factor*value;
}

View File

@@ -2,6 +2,7 @@
#define CALCULATION_ADDITIONAL_OUTPUTS_COMPLEX_MODEL_H
#include "../../shared/curve_view_range.h"
#include "illustrated_list_controller.h"
#include <complex>
namespace Calculation {
@@ -17,11 +18,53 @@ public:
void setComplex(std::complex<float> c) { *this = ComplexModel(c); }
static constexpr float k_minVerticalMarginFactor = -0.5f;
static constexpr float k_maxVerticalMarginFactor = 1.2f;
/* The range is computed from these criteria:
* - The real part is centered horizontally
* - Both left and right margins are equal to the real length
* - The imaginary part is the same length as the real part
* - The remaining vertical margin are splitted as one third at the top, 2
* thirds at the bottom
*
* | | 1/3 * vertical_margin
* +----------+
* | / | |
* | / | | Imaginary
* | / | |
* | / | |
* ----------+----------+----------
* |
* | 2/3 * vertical_margin
* -----------
* Real
*
*/
// Horizontal range
static constexpr float k_minHorizontalMarginFactor = -1.0f;
static constexpr float k_maxHorizontalMarginFactor = 2.0f;
// Vertical range
static constexpr KDCoordinate k_width = Ion::Display::Width - Metric::PopUpRightMargin - Metric::PopUpLeftMargin;
static constexpr KDCoordinate k_height = IllustratedListController::k_illustrationHeight;
static constexpr KDCoordinate k_unit = k_width/3;
/*
* VerticalMaring = k_height - k_unit
*
* Values | Coordinates
* --------+----------------------------------
* imag | k_unit
* Ymax | k_unit + (1/3)*VerticalMargin
* Ymin | -(2/3)*VerticalMargin
*
* Thus:
* Ymin = -(2/3)*k_verticalMargin*imag/k_unit
* = -(2/3)*(k_height/k_unit - 1)*imag
* = 2/3*(1 - k_height/k_unit)*imag
* Ymax = (k_unit + (1/3)*VerticalMargin)*imag/k_unit
* = (1 + (1/3)*(k_height/k_unit - 1))*imag
* = 1/3*(2 + k_height/k_unit)*imag
*
* */
static constexpr float k_minVerticalMarginFactor = 2.0f/3.0f*(1.0f - (float)k_height/(float)k_unit);
static constexpr float k_maxVerticalMarginFactor = 1.0f/3.0f*(2.0f + (float)k_height/(float)k_unit);
private:
float rangeBound(float direction, bool horizontal) const;

View File

@@ -4,13 +4,14 @@
#include <escher.h>
#include <apps/i18n.h>
#include <poincare/layout.h>
#include <escher/palette.h>
namespace Calculation {
class ExpressionWithEqualSignView : public ExpressionView {
public:
ExpressionWithEqualSignView() :
m_equalSign(KDFont::LargeFont, I18n::Message::Equal, 0.5f, 0.5f, KDColorBlack)
m_equalSign(KDFont::LargeFont, I18n::Message::Equal, 0.5f, 0.5f, Palette::PrimaryText)
{}
KDSize minimalSizeForOptimalDisplay() const override;
void drawRect(KDContext * ctx, KDRect rect) const override;

View File

@@ -7,8 +7,8 @@ namespace Calculation {
/* Expressions list controller */
ExpressionsListController::ExpressionsListController(Responder * parentResponder, EditExpressionController * editExpressionController) :
ListController(parentResponder, editExpressionController),
ExpressionsListController::ExpressionsListController(EditExpressionController * editExpressionController) :
ListController(editExpressionController),
m_cells{}
{
for (int i = 0; i < k_maxNumberOfCells; i++) {
@@ -38,9 +38,7 @@ HighlightCell * ExpressionsListController::reusableCell(int index, int type) {
KDCoordinate ExpressionsListController::rowHeight(int j) {
Layout l = layoutAtIndex(j);
if (l.isUninitialized()) {
return 0;
}
assert(!l.isUninitialized());
return l.layoutSize().height() + 2 * Metric::CommonSmallMargin + Metric::CellSeparatorThickness;
}

View File

@@ -10,7 +10,7 @@ namespace Calculation {
class ExpressionsListController : public ListController {
public:
ExpressionsListController(Responder * parentResponder, EditExpressionController * editExpressionController);
ExpressionsListController(EditExpressionController * editExpressionController);
// Responder
void viewDidDisappear() override;
@@ -28,7 +28,7 @@ public:
protected:
constexpr static int k_maxNumberOfCells = 4;
virtual int textAtIndex(char * buffer, size_t bufferSize, int index) override;
int textAtIndex(char * buffer, size_t bufferSize, int index) override;
Poincare::Expression m_expression;
// Memoization of layouts
mutable Poincare::Layout m_layouts[k_maxNumberOfCells];

View File

@@ -1,4 +1,5 @@
#include "illustrated_list_controller.h"
#include <poincare/exception_checkpoint.h>
#include <poincare/symbol.h>
#include "../app.h"
@@ -8,8 +9,8 @@ namespace Calculation {
/* Illustrated list controller */
IllustratedListController::IllustratedListController(Responder * parentResponder, EditExpressionController * editExpressionController) :
ListController(parentResponder, editExpressionController, this),
IllustratedListController::IllustratedListController(EditExpressionController * editExpressionController) :
ListController(editExpressionController, this),
m_additionalCalculationCells{}
{
for (int i = 0; i < k_maxNumberOfAdditionalCalculations; i++) {
@@ -78,7 +79,8 @@ KDCoordinate IllustratedListController::rowHeight(int j) {
return 0;
}
Shared::ExpiringPointer<Calculation> calculation = m_calculationStore.calculationAtIndex(calculationIndex);
return calculation->height(App::app()->localContext(), true, true) + 2 * Metric::CommonSmallMargin + Metric::CellSeparatorThickness;
constexpr bool expanded = true;
return calculation->height(expanded) + Metric::CellSeparatorThickness;
}
int IllustratedListController::typeAtLocation(int i, int j) {
@@ -87,7 +89,6 @@ int IllustratedListController::typeAtLocation(int i, int j) {
void IllustratedListController::willDisplayCellForIndex(HighlightCell * cell, int index) {
if (index == 0) {
// TODO ?
return;
}
Poincare::Context * context = App::app()->localContext();
@@ -95,7 +96,6 @@ void IllustratedListController::willDisplayCellForIndex(HighlightCell * cell, in
Calculation * c = m_calculationStore.calculationAtIndex(index-1).pointer();
myCell->setCalculation(c);
myCell->setDisplayCenter(c->displayOutput(context) != Calculation::DisplayOutput::ApproximateOnly);
//myCell->setHighlighted(myCell->isHighlighted()); //TODO??
}
void IllustratedListController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) {

View File

@@ -11,7 +11,7 @@ namespace Calculation {
class IllustratedListController : public ListController, public SelectableTableViewDelegate {
public:
IllustratedListController(Responder * parentResponder, EditExpressionController * editExpressionController);
IllustratedListController(EditExpressionController * editExpressionController);
// Responder
void viewDidDisappear() override;
@@ -31,8 +31,9 @@ public:
// IllustratedListController
void setExpression(Poincare::Expression e) override;
constexpr static KDCoordinate k_illustrationHeight = 100;
constexpr static KDCoordinate k_illustrationHeight = 120;
protected:
static KDCoordinate CalculationHeight(Calculation * c, bool expanded) { return ScrollableThreeExpressionsCell::Height(c); }
Poincare::Expression m_savedExpression;
CalculationStore m_calculationStore;
private:

View File

@@ -10,7 +10,7 @@ void IllustrationCell::layoutSubviews(bool force) {
}
void IllustrationCell::drawRect(KDContext * ctx, KDRect rect) const {
drawBorderOfRect(ctx, bounds(), Palette::GreyBright);
drawBorderOfRect(ctx, bounds(), Palette::ListCellBorder);
}
}

View File

@@ -28,9 +28,6 @@ Integer::Base baseAtIndex(int index) {
}
void IntegerListController::computeLayoutAtIndex(int index) {
if (!m_layouts[index].isUninitialized()) {
return;
}
assert(m_expression.type() == ExpressionNode::Type::BasedInteger);
// For index = k_indexOfFactorExpression, the layout is assumed to be alreday memoized because it is needed to compute the numberOfRows
assert(index < k_indexOfFactorExpression);
@@ -65,6 +62,6 @@ bool IntegerListController::factorExpressionIsComputable() const {
}
m_layouts[k_indexOfFactorExpression] = EmptyLayout::Builder();
return false;
}
}
}

View File

@@ -8,7 +8,7 @@ namespace Calculation {
class IntegerListController : public ExpressionsListController {
public:
IntegerListController(EditExpressionController * editExpressionController) :
ExpressionsListController(nullptr, editExpressionController) {}
ExpressionsListController(editExpressionController) {}
//ListViewDataSource
int numberOfRows() const override;

View File

@@ -21,8 +21,8 @@ void ListController::InnerListController::didBecomeFirstResponder() {
/* List Controller */
ListController::ListController(Responder * parentResponder, EditExpressionController * editExpressionController, SelectableTableViewDelegate * delegate) :
StackViewController(parentResponder, &m_listController, Palette::ToolboxHeaderText, Palette::ToolboxHeaderBackground, Palette::ToolboxHeaderBorder),
ListController::ListController(EditExpressionController * editExpressionController, SelectableTableViewDelegate * delegate) :
StackViewController(nullptr, &m_listController, Palette::ToolboxHeaderText, Palette::ToolboxHeaderBackground, Palette::ToolboxHeaderBorder),
m_listController(this, delegate),
m_editExpressionController(editExpressionController)
{
@@ -38,7 +38,6 @@ bool ListController::handleEvent(Ion::Events::Event event) {
* insertTextBody. */
Container::activeApp()->dismissModalViewController();
m_editExpressionController->insertTextBody(buffer);
Container::activeApp()->setFirstResponder(m_editExpressionController);
return true;
}
return false;

View File

@@ -10,7 +10,7 @@ class EditExpressionController;
class ListController : public StackViewController, public ListViewDataSource, public SelectableTableViewDataSource {
public:
ListController(Responder * parentResponder, EditExpressionController * editExpressionController, SelectableTableViewDelegate * delegate = nullptr);
ListController(EditExpressionController * editExpressionController, SelectableTableViewDelegate * delegate = nullptr);
// Responder
bool handleEvent(Ion::Events::Event event) override;

View File

@@ -8,7 +8,7 @@ namespace Calculation {
class RationalListController : public ExpressionsListController {
public:
RationalListController(EditExpressionController * editExpressionController) :
ExpressionsListController(nullptr, editExpressionController) {}
ExpressionsListController(editExpressionController) {}
//ListViewDataSource
int numberOfRows() const override;

View File

@@ -8,7 +8,8 @@ void ScrollableThreeExpressionsView::resetMemoization() {
setLayouts(Poincare::Layout(), Poincare::Layout(), Poincare::Layout());
}
void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation) {
// TODO: factorize with HistoryViewCell!
void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation, bool canChangeDisplayOutput) {
Poincare::Context * context = App::app()->localContext();
// Clean the layouts to make room in the pool
@@ -23,10 +24,10 @@ void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation) {
bool couldNotCreateExactLayout = false;
exactOutputLayout = calculation->createExactOutputLayout(&couldNotCreateExactLayout);
if (couldNotCreateExactLayout) {
if (calculation->displayOutput(context) == ::Calculation::Calculation::DisplayOutput::ExactOnly) {
Poincare::ExceptionCheckpoint::Raise();
} else {
if (canChangeDisplayOutput && calculation->displayOutput(context) != ::Calculation::Calculation::DisplayOutput::ExactOnly) {
calculation->forceDisplayOutput(::Calculation::Calculation::DisplayOutput::ApproximateOnly);
} else {
Poincare::ExceptionCheckpoint::Raise();
}
}
}
@@ -40,9 +41,7 @@ void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation) {
bool couldNotCreateApproximateLayout = false;
approximateOutputLayout = calculation->createApproximateOutputLayout(context, &couldNotCreateApproximateLayout);
if (couldNotCreateApproximateLayout) {
if (calculation->displayOutput(context) == ::Calculation::Calculation::DisplayOutput::ApproximateOnly) {
Poincare::ExceptionCheckpoint::Raise();
} else {
if (canChangeDisplayOutput && calculation->displayOutput(context) != ::Calculation::Calculation::DisplayOutput::ApproximateOnly) {
/* Set the display output to ApproximateOnly, make room in the pool by
* erasing the exact layout, and retry to create the approximate layout */
calculation->forceDisplayOutput(::Calculation::Calculation::DisplayOutput::ApproximateOnly);
@@ -52,6 +51,8 @@ void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation) {
if (couldNotCreateApproximateLayout) {
Poincare::ExceptionCheckpoint::Raise();
}
} else {
Poincare::ExceptionCheckpoint::Raise();
}
}
@@ -65,6 +66,18 @@ void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation) {
layoutSubviews();
}
KDCoordinate ScrollableThreeExpressionsCell::Height(Calculation * calculation) {
ScrollableThreeExpressionsCell cell;
cell.setCalculation(calculation, true);
KDRect leftFrame = KDRectZero;
KDRect centerFrame = KDRectZero;
KDRect approximateSignFrame = KDRectZero;
KDRect rightFrame = KDRectZero;
cell.subviewFrames(&leftFrame, &centerFrame, &approximateSignFrame, &rightFrame);
KDRect unionedFrame = leftFrame.unionedWith(centerFrame).unionedWith(rightFrame);
return unionedFrame.height() + 2 * ScrollableThreeExpressionsView::k_margin;
}
void ScrollableThreeExpressionsCell::didBecomeFirstResponder() {
reinitSelection();
Container::activeApp()->setFirstResponder(&m_view);
@@ -75,8 +88,8 @@ void ScrollableThreeExpressionsCell::reinitSelection() {
m_view.reloadScroll();
}
void ScrollableThreeExpressionsCell::setCalculation(Calculation * calculation) {
m_view.setCalculation(calculation);
void ScrollableThreeExpressionsCell::setCalculation(Calculation * calculation, bool canChangeDisplayOutput) {
m_view.setCalculation(calculation, canChangeDisplayOutput);
layoutSubviews();
}

View File

@@ -5,22 +5,30 @@
#include "../../shared/scrollable_multiple_expressions_view.h"
#include "../calculation.h"
#include "expression_with_equal_sign_view.h"
#include <escher/palette.h>
namespace Calculation {
/* TODO There is factorizable code between this and Calculation::HistoryViewCell
* (at least setCalculation). */
class ScrollableThreeExpressionsView : public Shared::AbstractScrollableMultipleExpressionsView {
public:
static constexpr KDCoordinate k_margin = Metric::CommonSmallMargin;
ScrollableThreeExpressionsView(Responder * parentResponder) : Shared::AbstractScrollableMultipleExpressionsView(parentResponder, &m_contentCell), m_contentCell() {
setMargins(Metric::CommonSmallMargin, Metric::CommonSmallMargin, Metric::CommonSmallMargin, Metric::CommonSmallMargin); // Left Right margins are already added by TableCell
setBackgroundColor(KDColorWhite);
setMargins(k_margin, k_margin, k_margin, k_margin); // Left Right margins are already added by TableCell
setBackgroundColor(Palette::BackgroundApps);
}
void resetMemoization();
void setCalculation(Calculation * calculation);
void setCalculation(Calculation * calculation, bool canChangeDisplayOutput);
void subviewFrames(KDRect * leftFrame, KDRect * centerFrame, KDRect * approximateSignFrame, KDRect * rightFrame) {
return m_contentCell.subviewFrames(leftFrame, centerFrame, approximateSignFrame, rightFrame);
}
private:
class ContentCell : public Shared::AbstractScrollableMultipleExpressionsView::ContentCell {
public:
ContentCell() : m_leftExpressionView() {}
KDColor backgroundColor() const override { return KDColorWhite; }
KDColor backgroundColor() const override { return Palette::BackgroundApps; }
void setEven(bool even) override { return; }
ExpressionView * leftExpressionView() const override { return const_cast<ExpressionWithEqualSignView *>(&m_leftExpressionView); }
private:
@@ -28,12 +36,13 @@ private:
};
ContentCell * contentCell() override { return &m_contentCell; };
const ContentCell * constContentCell() const override { return &m_contentCell; };
const ContentCell * constContentCell() const override { return &m_contentCell; };
ContentCell m_contentCell;
};
class ScrollableThreeExpressionsCell : public TableCell, public Responder {
public:
static KDCoordinate Height(Calculation * calculation);
ScrollableThreeExpressionsCell() :
Responder(nullptr),
m_view(this) {}
@@ -52,12 +61,15 @@ public:
void setHighlighted(bool highlight) override { m_view.evenOddCell()->setHighlighted(highlight); }
void resetMemoization() { m_view.resetMemoization(); }
void setCalculation(Calculation * calculation);
void setCalculation(Calculation * calculation, bool canChangeDisplayOutput = false);
void setDisplayCenter(bool display);
ScrollableThreeExpressionsView::SubviewPosition selectedSubviewPosition() { return m_view.selectedSubviewPosition(); }
void setSelectedSubviewPosition(ScrollableThreeExpressionsView::SubviewPosition subviewPosition) { m_view.setSelectedSubviewPosition(subviewPosition); }
void reinitSelection();
void subviewFrames(KDRect * leftFrame, KDRect * centerFrame, KDRect * approximateSignFrame, KDRect * rightFrame) {
return m_view.subviewFrames(leftFrame, centerFrame, approximateSignFrame, rightFrame);
}
private:
// Remove label margin added by TableCell because they're already handled by ScrollableThreeExpressionsView
KDCoordinate labelMargin() const override { return 0; }

View File

@@ -1,4 +1,5 @@
#include "trigonometry_graph_cell.h"
#include <escher/palette.h>
using namespace Shared;
using namespace Poincare;
@@ -14,24 +15,24 @@ TrigonometryGraphView::TrigonometryGraphView(TrigonometryModel * model) :
void TrigonometryGraphView::drawRect(KDContext * ctx, KDRect rect) const {
float s = std::sin(m_model->angle());
float c = std::cos(m_model->angle());
ctx->fillRect(rect, KDColorWhite);
ctx->fillRect(rect, Palette::BackgroundApps);
drawGrid(ctx, rect);
drawAxes(ctx, rect);
// Draw the circle
drawCurve(ctx, rect, 0.0f, 2.0f*M_PI, M_PI/180.0f, [](float t, void * model, void * context) {
return Poincare::Coordinate2D<float>(std::cos(t), std::sin(t));
}, nullptr, nullptr, true, Palette::GreyDark, false);
}, nullptr, nullptr, true, Palette::SecondaryText, false);
// Draw dashed segment to indicate sine and cosine
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, c, 0.0f, s, Palette::Red, 1, 3);
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Horizontal, s, 0.0f, c, Palette::Red, 1, 3);
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, c, 0.0f, s, Palette::CalculationTrigoAndComplexForeground, 1, 3);
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Horizontal, s, 0.0f, c, Palette::CalculationTrigoAndComplexForeground, 1, 3);
// Draw angle position on the circle
drawDot(ctx, rect, c, s, Palette::Red, Size::Large);
drawDot(ctx, rect, c, s, Palette::CalculationTrigoAndComplexForeground, Size::Large);
// Draw graduations
drawLabelsAndGraduations(ctx, rect, Axis::Vertical, false, true);
drawLabelsAndGraduations(ctx, rect, Axis::Horizontal, false, true);
// Draw labels
drawLabel(ctx, rect, 0.0f, s, "sin(θ)", Palette::Red, c >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After, CurveView::RelativePosition::None);
drawLabel(ctx, rect, c, 0.0f, "cos(θ)", Palette::Red, CurveView::RelativePosition::None, s >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After);
drawLabel(ctx, rect, 0.0f, s, "sin(θ)", Palette::CalculationTrigoAndComplexForeground, c >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After, CurveView::RelativePosition::None);
drawLabel(ctx, rect, c, 0.0f, "cos(θ)", Palette::CalculationTrigoAndComplexForeground, CurveView::RelativePosition::None, s >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After);
}
}

View File

@@ -11,9 +11,9 @@ void TrigonometryListController::setExpression(Poincare::Expression e) {
// Fill calculation store
Poincare::Context * context = App::app()->localContext();
m_calculationStore.push("sin(θ)", context);
m_calculationStore.push("cos(θ)", context);
m_calculationStore.push("θ", context);
m_calculationStore.push("sin(θ)", context, CalculationHeight);
m_calculationStore.push("cos(θ)", context, CalculationHeight);
m_calculationStore.push("θ", context, CalculationHeight);
// Set trigonometry illustration
float angle = Shared::PoincareHelpers::ApproximateToScalar<float>(m_calculationStore.calculationAtIndex(0)->approximateOutput(context, Calculation::NumberOfSignificantDigits::Maximal), context);

View File

@@ -10,7 +10,7 @@ namespace Calculation {
class TrigonometryListController : public IllustratedListController {
public:
TrigonometryListController(EditExpressionController * editExpressionController) :
IllustratedListController(nullptr, editExpressionController),
IllustratedListController(editExpressionController),
m_graphCell(&m_model) {}
void setExpression(Poincare::Expression e) override;
private:

View File

@@ -18,7 +18,7 @@ public:
float yMax() const override { return yCenter() + yHalfRange(); }
void setAngle(float f) { m_angle = f; }
float angle() const { return m_angle*M_PI/Poincare::Trigonometry::PiInAngleUnit(Poincare::Preferences::sharedPreferences()->angleUnit()); }
float angle() const { return m_angle*(float)M_PI/(float)Poincare::Trigonometry::PiInAngleUnit(Poincare::Preferences::sharedPreferences()->angleUnit()); }
private:
constexpr static float k_xHalfRange = 2.1f;
// We center the yRange around the semi-circle where the angle is

View File

@@ -0,0 +1,155 @@
#include "unit_list_controller.h"
#include "../app.h"
#include "../../shared/poincare_helpers.h"
#include <poincare/unit_convert.h>
#include <poincare/multiplication.h>
#include <poincare/power.h>
#include <poincare/undefined.h>
#include <poincare/unit.h>
using namespace Poincare;
using namespace Shared;
namespace Calculation {
void UnitListController::setExpression(Poincare::Expression e) {
ExpressionsListController::setExpression(e);
assert(!m_expression.isUninitialized());
// Reinitialize m_memoizedExpressions
for (size_t i = 0; i < k_maxNumberOfCells; i++) {
m_memoizedExpressions[i] = Expression();
}
size_t numberOfMemoizedExpressions = 0;
// 1. First rows: miscellaneous classic units for some dimensions
Expression copy = m_expression.clone();
Expression units;
// Reduce to be able to recognize units
PoincareHelpers::Reduce(&copy, App::app()->localContext(), ExpressionNode::ReductionTarget::User);
copy = copy.removeUnit(&units);
bool requireSimplification = false;
bool canChangeUnitPrefix = false;
if (Unit::IsSISpeed(units)) {
// 1.a. Turn speed into km/h
m_memoizedExpressions[numberOfMemoizedExpressions++] = UnitConvert::Builder(
m_expression.clone(),
Multiplication::Builder(
Unit::Kilometer(),
Power::Builder(
Unit::Hour(),
Rational::Builder(-1)
)
)
);
requireSimplification = true; // Simplify the conversion
} else if (Unit::IsSIVolume(units)) {
// 1.b. Turn volume into L
m_memoizedExpressions[numberOfMemoizedExpressions++] = UnitConvert::Builder(
m_expression.clone(),
Unit::Liter()
);
requireSimplification = true; // Simplify the conversion
canChangeUnitPrefix = true; // Pick best prefix (mL)
} else if (Unit::IsSIEnergy(units)) {
// 1.c. Turn energy into Wh
m_memoizedExpressions[numberOfMemoizedExpressions++] = UnitConvert::Builder(
m_expression.clone(),
Multiplication::Builder(
Unit::Watt(),
Unit::Hour()
)
);
m_memoizedExpressions[numberOfMemoizedExpressions++] = UnitConvert::Builder(
m_expression.clone(),
Unit::ElectronVolt()
);
requireSimplification = true; // Simplify the conversion
canChangeUnitPrefix = true; // Pick best prefix (kWh)
} else if (Unit::IsSITime(units)) {
// Turn time into ? year + ? month + ? day + ? h + ? min + ? s
double value = Shared::PoincareHelpers::ApproximateToScalar<double>(copy, App::app()->localContext());
m_memoizedExpressions[numberOfMemoizedExpressions++] = Unit::BuildTimeSplit(value, App::app()->localContext(), Preferences::sharedPreferences()->complexFormat(), Preferences::sharedPreferences()->angleUnit());
}
// 1.d. Simplify and tune prefix of all computed expressions
size_t currentExpressionIndex = 0;
while (currentExpressionIndex < numberOfMemoizedExpressions) {
assert(!m_memoizedExpressions[currentExpressionIndex].isUninitialized());
if (requireSimplification) {
Shared::PoincareHelpers::Simplify(&m_memoizedExpressions[currentExpressionIndex], App::app()->localContext(), ExpressionNode::ReductionTarget::User);
}
if (canChangeUnitPrefix) {
Expression newUnits;
// Reduce to be able to removeUnit
PoincareHelpers::Reduce(&m_memoizedExpressions[currentExpressionIndex], App::app()->localContext(), ExpressionNode::ReductionTarget::User);
m_memoizedExpressions[currentExpressionIndex] = m_memoizedExpressions[currentExpressionIndex].removeUnit(&newUnits);
double value = Shared::PoincareHelpers::ApproximateToScalar<double>(m_memoizedExpressions[currentExpressionIndex], App::app()->localContext());
ExpressionNode::ReductionContext reductionContext(
App::app()->localContext(),
Preferences::sharedPreferences()->complexFormat(),
Preferences::sharedPreferences()->angleUnit(),
ExpressionNode::ReductionTarget::User,
ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined);
Unit::ChooseBestPrefixForValue(&newUnits, &value, reductionContext);
m_memoizedExpressions[currentExpressionIndex] = Multiplication::Builder(Number::FloatNumber(value), newUnits);
}
currentExpressionIndex++;
}
// 2. IS units only
assert(numberOfMemoizedExpressions < k_maxNumberOfCells - 1);
m_memoizedExpressions[numberOfMemoizedExpressions] = m_expression.clone();
Shared::PoincareHelpers::Simplify(&m_memoizedExpressions[numberOfMemoizedExpressions], App::app()->localContext(), ExpressionNode::ReductionTarget::User, Poincare::ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, Poincare::ExpressionNode::UnitConversion::InternationalSystem);
numberOfMemoizedExpressions++;
// 3. Get rid of duplicates
Expression reduceExpression = m_expression.clone();
// Make m_expression compareable to m_memoizedExpressions (turn BasedInteger into Rational for instance)
Shared::PoincareHelpers::Simplify(&reduceExpression, App::app()->localContext(), ExpressionNode::ReductionTarget::User, Poincare::ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, Poincare::ExpressionNode::UnitConversion::None);
currentExpressionIndex = 1;
while (currentExpressionIndex < numberOfMemoizedExpressions) {
bool duplicateFound = false;
for (size_t i = 0; i < currentExpressionIndex + 1; i++) {
// Compare the currentExpression to all previous memoized expressions and to m_expression
Expression comparedExpression = i == currentExpressionIndex ? reduceExpression : m_memoizedExpressions[i];
assert(!comparedExpression.isUninitialized());
if (comparedExpression.isIdenticalTo(m_memoizedExpressions[currentExpressionIndex])) {
numberOfMemoizedExpressions--;
// Shift next expressions
for (size_t j = currentExpressionIndex; j < numberOfMemoizedExpressions; j++) {
m_memoizedExpressions[j] = m_memoizedExpressions[j+1];
}
// Remove last expression
m_memoizedExpressions[numberOfMemoizedExpressions] = Expression();
// The current expression has been discarded, no need to increment the current index
duplicateFound = true;
break;
}
}
if (!duplicateFound) {
// The current expression is not a duplicate, check next expression
currentExpressionIndex++;
}
}
}
int UnitListController::numberOfRows() const {
int nbOfRows = 0;
for (size_t i = 0; i < k_maxNumberOfCells; i++) {
if (!m_memoizedExpressions[i].isUninitialized()) {
nbOfRows++;
}
}
return nbOfRows;
}
void UnitListController::computeLayoutAtIndex(int index) {
assert(!m_memoizedExpressions[index].isUninitialized());
m_layouts[index] = Shared::PoincareHelpers::CreateLayout(m_memoizedExpressions[index]);
}
I18n::Message UnitListController::messageAtIndex(int index) {
return (I18n::Message)0;
}
}

View File

@@ -0,0 +1,26 @@
#ifndef CALCULATION_ADDITIONAL_OUTPUTS_UNIT_LIST_CONTROLLER_H
#define CALCULATION_ADDITIONAL_OUTPUTS_UNIT_LIST_CONTROLLER_H
#include "expressions_list_controller.h"
namespace Calculation {
class UnitListController : public ExpressionsListController {
public:
UnitListController(EditExpressionController * editExpressionController) :
ExpressionsListController(editExpressionController) {}
void setExpression(Poincare::Expression e) override;
//ListViewDataSource
int numberOfRows() const override;
private:
void computeLayoutAtIndex(int index) override;
I18n::Message messageAtIndex(int index) override;
// Memoization of expressions
mutable Poincare::Expression m_memoizedExpressions[k_maxNumberOfCells];
};
}
#endif

View File

@@ -17,8 +17,8 @@ I18n::Message App::Descriptor::upperName() {
return I18n::Message::CalculAppCapital;
}
int App::Descriptor::examinationLevel() {
return App::Descriptor::StrictExaminationLevel;
App::Descriptor::ExaminationLevel App::Descriptor::examinationLevel() {
return App::Descriptor::ExaminationLevel::Strict;
}
const Image * App::Descriptor::icon() {

View File

@@ -15,7 +15,7 @@ public:
public:
I18n::Message name() override;
I18n::Message upperName() override;
int examinationLevel() override;
App::Descriptor::ExaminationLevel examinationLevel() override;
const Image * icon() override;
};
class Snapshot : public ::App::Snapshot {

View File

@@ -4,6 +4,6 @@ AdditionalResults = "Weitere Ergebnisse"
DecimalBase = "Dezimal"
HexadecimalBase = "Hexadezimal"
BinaryBase = "Binär"
PrimeFactors = "Primfaktor"
MixedFraction = "Gemischte Fraktion"
EuclideanDivision = "Euklidische Division"
PrimeFactors = "Primfaktoren"
MixedFraction = "Gemischte Zahl"
EuclideanDivision = "Division mit Rest"

View File

@@ -1,9 +1,9 @@
CalculApp = "Cálculo"
CalculAppCapital = "CÁLCULO"
AdditionalResults = "????"
DecimalBase = "????"
HexadecimalBase = "????"
BinaryBase = "????"
PrimeFactors = "????"
MixedFraction = "????"
EuclideanDivision = "????"
AdditionalResults = "Resultados adicionales"
DecimalBase = "Decimal"
HexadecimalBase = "Hexadecimal"
BinaryBase = "Binario"
PrimeFactors = "Factores primos"
MixedFraction = "Fracción mixta"
EuclideanDivision = "División euclidiana"

View File

@@ -0,0 +1,9 @@
CalculApp = "Calcolo"
CalculAppCapital = "CALCOLO"
AdditionalResults = "Risultati complementari"
DecimalBase = "Decimale"
HexadecimalBase = "Esadecimale"
BinaryBase = "Binario"
PrimeFactors = "Fattori primi"
MixedFraction = "Frazione mista"
EuclideanDivision = "Divisione euclidea"

View File

@@ -0,0 +1,9 @@
CalculApp = "Calculatie"
CalculAppCapital = "CALCULATIE"
AdditionalResults = "Bijkomende resultaten"
DecimalBase = "Decimaal"
HexadecimalBase = "Hexadecimaal"
BinaryBase = "Binaire"
PrimeFactors = "Priemfactoren"
MixedFraction = "Gemengde breuk"
EuclideanDivision = "Geheeltallige deling"

View File

@@ -1,9 +1,9 @@
CalculApp = "Cálculo"
CalculAppCapital = "CÁLCULO"
AdditionalResults = "????"
DecimalBase = "????"
HexadecimalBase = "????"
BinaryBase = "????"
PrimeFactors = "????"
MixedFraction = "????"
EuclideanDivision = "????"
AdditionalResults = "Resultados adicionais"
DecimalBase = "Decimal"
HexadecimalBase = "Hexadecimal"
BinaryBase = "Binário"
PrimeFactors = "Fatores primos"
MixedFraction = "Fração mista"
EuclideanDivision = "Divisão euclidiana"

View File

@@ -1,20 +1,22 @@
#include "calculation.h"
#include "../shared/poincare_helpers.h"
#include "../shared/scrollable_multiple_expressions_view.h"
#include "../global_preferences.h"
#include "../exam_mode_configuration.h"
#include "app.h"
#include <poincare/exception_checkpoint.h>
#include <poincare/undefined.h>
#include <poincare/unit.h>
#include <poincare/unreal.h>
#include <string.h>
#include <cmath>
#include <algorithm>
using namespace Poincare;
using namespace Shared;
namespace Calculation {
static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; }
bool Calculation::operator==(const Calculation& c) {
return strcmp(inputText(), c.inputText()) == 0
&& strcmp(approximateOutputText(NumberOfSignificantDigits::Maximal), c.approximateOutputText(NumberOfSignificantDigits::Maximal)) == 0
@@ -36,13 +38,6 @@ Calculation * Calculation::next() const {
return reinterpret_cast<Calculation *>(const_cast<char *>(result));
}
void Calculation::tidy() {
/* Reset height memoization (the complex format could have changed when
* re-entering Calculation app which would impact the heights). */
m_height = -1;
m_expandedHeight = -1;
}
const char * Calculation::approximateOutputText(NumberOfSignificantDigits numberOfSignificantDigits) const {
const char * exactOutput = exactOutputText();
const char * approximateOutputTextWithMaxNumberOfDigits = exactOutput + strlen(exactOutput) + 1;
@@ -125,123 +120,15 @@ Layout Calculation::createApproximateOutputLayout(Context * context, bool * coul
}
}
KDCoordinate Calculation::height(Context * context, bool expanded, bool allExpressionsInline) {
KDCoordinate result = expanded ? m_expandedHeight : m_height;
if (result >= 0) {
// Height already computed
return result;
}
KDCoordinate Calculation::height(bool expanded) {
KDCoordinate h = expanded ? m_expandedHeight : m_height;
assert(h >= 0);
return h;
}
// Get input height
Layout inputLayout = createInputLayout();
KDCoordinate inputHeight = inputLayout.layoutSize().height();
KDCoordinate inputWidth = inputLayout.layoutSize().width();
float singleMargin = 2 * Metric::CommonSmallMargin;
float doubleMargin = 4 * Metric::CommonSmallMargin;
bool singleLine = false;
KDCoordinate inputBaseline = inputLayout.baseline();
// Get exact output height if needed
Poincare::Layout exactLayout;
bool couldNotCreateExactLayout = false;
if (DisplaysExact(displayOutput(context))) {
// Create the exact output layout
exactLayout = createExactOutputLayout(&couldNotCreateExactLayout);
if (couldNotCreateExactLayout) {
if (displayOutput(context) != DisplayOutput::ExactOnly) {
forceDisplayOutput(DisplayOutput::ApproximateOnly);
} else {
/* We should only display the exact result, but we cannot create it
* -> raise an exception. */
ExceptionCheckpoint::Raise();
}
}
}
if (displayOutput(context) == DisplayOutput::ExactOnly) {
KDCoordinate exactOutputHeight = exactLayout.layoutSize().height();
KDCoordinate exactOutputWidth = exactLayout.layoutSize().width();
singleLine = exactOutputWidth + inputWidth < maxWidth - 40;
if (singleLine && Poincare::Preferences::sharedPreferences()->resultDisplay() == Poincare::Preferences::ResultDisplay::Compact && !allExpressionsInline) {
KDCoordinate exactOutputBaseline = exactLayout.baseline();
result = maxCoordinate(inputBaseline, exactOutputBaseline) + maxCoordinate(inputHeight - inputBaseline, exactOutputHeight-exactOutputBaseline) + singleMargin;
} else {
if (allExpressionsInline) {
KDCoordinate exactOutputBaseline = exactLayout.baseline();
result = maxCoordinate(inputBaseline, exactOutputBaseline) + maxCoordinate(inputHeight - inputBaseline, exactOutputHeight-exactOutputBaseline);
} else {
result = inputHeight + exactOutputHeight + doubleMargin;
}
}
} else {
bool couldNotCreateApproximateLayout = false;
Layout approximateLayout = createApproximateOutputLayout(context, &couldNotCreateApproximateLayout);
if (couldNotCreateApproximateLayout) {
if (displayOutput(context) == DisplayOutput::ApproximateOnly) {
Poincare::ExceptionCheckpoint::Raise();
} else {
/* Set the display output to ApproximateOnly, make room in the pool by
* erasing the exact layout, and retry to create the approximate layout */
forceDisplayOutput(DisplayOutput::ApproximateOnly);
exactLayout = Poincare::Layout();
couldNotCreateApproximateLayout = false;
approximateLayout = createApproximateOutputLayout(context, &couldNotCreateApproximateLayout);
if (couldNotCreateApproximateLayout) {
Poincare::ExceptionCheckpoint::Raise();
}
}
}
KDCoordinate approximateOutputHeight = approximateLayout.layoutSize().height();
KDCoordinate approximateOutputWidth = approximateLayout.layoutSize().width();
singleLine = approximateOutputWidth + inputWidth < maxWidth - 40;
if (displayOutput(context) == DisplayOutput::ApproximateOnly || (!expanded && displayOutput(context) == DisplayOutput::ExactAndApproximateToggle)) {
if (singleLine && Poincare::Preferences::sharedPreferences()->resultDisplay() == Poincare::Preferences::ResultDisplay::Compact && !allExpressionsInline) {
KDCoordinate approximateOutputBaseline = approximateLayout.baseline();
result = maxCoordinate(inputBaseline, approximateOutputBaseline) + maxCoordinate(inputHeight - inputBaseline, approximateOutputHeight-approximateOutputBaseline) + singleMargin;
} else {
if (allExpressionsInline) {
KDCoordinate approximateOutputBaseline = approximateLayout.baseline();
result = maxCoordinate(inputBaseline, approximateOutputBaseline) + maxCoordinate(inputHeight - inputBaseline, approximateOutputHeight-approximateOutputBaseline);
} else {
result = inputHeight + approximateOutputHeight + doubleMargin;
}
}
} else {
assert(displayOutput(context) == DisplayOutput::ExactAndApproximate || (displayOutput(context) == DisplayOutput::ExactAndApproximateToggle && expanded));
KDCoordinate exactOutputHeight = exactLayout.layoutSize().height();
KDCoordinate exactOutputBaseline = exactLayout.baseline();
KDCoordinate exactOutputWidth = exactLayout.layoutSize().width();
KDCoordinate approximateOutputWidth = approximateLayout.layoutSize().width();
singleLine = exactOutputWidth + approximateOutputWidth + inputWidth < maxWidth - 70;
KDCoordinate approximateOutputBaseline = approximateLayout.baseline();
if (singleLine && Poincare::Preferences::sharedPreferences()->resultDisplay() == Poincare::Preferences::ResultDisplay::Compact) {
result = maxCoordinate(inputBaseline, maxCoordinate(exactOutputBaseline, approximateOutputBaseline)) + maxCoordinate(inputHeight - inputBaseline, maxCoordinate(exactOutputHeight - exactOutputBaseline, approximateOutputHeight-approximateOutputBaseline)) + singleMargin;
} else {
if (allExpressionsInline) {
result = maxCoordinate(inputBaseline, maxCoordinate(exactOutputBaseline, approximateOutputBaseline)) + maxCoordinate(inputHeight - inputBaseline, maxCoordinate(exactOutputHeight - exactOutputBaseline, approximateOutputHeight-approximateOutputBaseline));
} else {
KDCoordinate outputHeight = maxCoordinate(exactOutputBaseline, approximateOutputBaseline) + maxCoordinate(exactOutputHeight-exactOutputBaseline, approximateOutputHeight-approximateOutputBaseline);
result = inputHeight + outputHeight + doubleMargin;
}
}
}
}
/* For all display outputs except ExactAndApproximateToggle, the selected
* height and the usual height are identical. We update both heights in
* theses cases. */
if (displayOutput(context) != DisplayOutput::ExactAndApproximateToggle) {
m_height = result;
m_expandedHeight = result;
} else {
if (expanded) {
m_expandedHeight = result;
} else {
m_height = result;
}
}
return result;
void Calculation::setHeights(KDCoordinate height, KDCoordinate expandedHeight) {
m_height = height;
m_expandedHeight = expandedHeight;
}
Calculation::DisplayOutput Calculation::displayOutput(Context * context) {
@@ -285,7 +172,7 @@ Calculation::DisplayOutput Calculation::displayOutput(Context * context) {
ExpressionNode::Type::PredictionInterval
};
return e.isOfType(approximateOnlyTypes, sizeof(approximateOnlyTypes)/sizeof(ExpressionNode::Type));
}, context, true)
}, context)
)
{
m_displayOutput = DisplayOutput::ApproximateOnly;
@@ -300,17 +187,17 @@ Calculation::DisplayOutput Calculation::displayOutput(Context * context) {
}
void Calculation::forceDisplayOutput(DisplayOutput d) {
// Heights haven't been computed yet
assert(m_height == -1 && m_expandedHeight == -1);
m_displayOutput = d;
// Reset heights memoization as it might have changed when we modify the display output
m_height = -1;
m_expandedHeight = -1;
}
bool Calculation::shouldOnlyDisplayExactOutput() {
/* If the input is a "store in a function", do not display the approximate
* result. This prevents x->f(x) from displaying x = undef. */
Expression i = input();
return i.type() == ExpressionNode::Type::Store
&& i.childAtIndex(1).type() == ExpressionNode::Type::Function;
return (i.type() == ExpressionNode::Type::Store && i.childAtIndex(1).type() == ExpressionNode::Type::Function)
|| strcmp(approximateOutputText(NumberOfSignificantDigits::Maximal), Undefined::Name()) == 0;
}
Calculation::EqualSign Calculation::exactAndApproximateDisplayedOutputsAreEqual(Poincare::Context * context) {
@@ -329,6 +216,7 @@ Calculation::EqualSign Calculation::exactAndApproximateDisplayedOutputsAreEqual(
Poincare::ExceptionCheckpoint ecp;
if (ExceptionRun(ecp)) {
Preferences * preferences = Preferences::sharedPreferences();
// TODO: complex format should not be needed here (as it is not used to create layouts)
Preferences::ComplexFormat complexFormat = Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), m_inputText);
m_equalSign = Expression::ParsedExpressionsAreEqual(exactOutputText(), approximateOutputText(NumberOfSignificantDigits::UserDefined), context, complexFormat, preferences->angleUnit()) ? EqualSign::Equal : EqualSign::Approximation;
return m_equalSign;
@@ -340,6 +228,9 @@ Calculation::EqualSign Calculation::exactAndApproximateDisplayedOutputsAreEqual(
}
Calculation::AdditionalInformationType Calculation::additionalInformationType(Context * context) {
if (ExamModeConfiguration::exactExpressionsAreForbidden(GlobalPreferences::sharedGlobalPreferences()->examMode())) {
return AdditionalInformationType::None;
}
Preferences * preferences = Preferences::sharedPreferences();
Preferences::ComplexFormat complexFormat = Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), m_inputText);
Expression i = input();
@@ -361,8 +252,35 @@ Calculation::AdditionalInformationType Calculation::additionalInformationType(Co
if (input().isDefinedCosineOrSine(context, complexFormat, preferences->angleUnit()) || o.isDefinedCosineOrSine(context, complexFormat, preferences->angleUnit())) {
return AdditionalInformationType::Trigonometry;
}
// TODO: return AdditionalInformationType::Unit
if (o.hasUnit()) {
Expression unit;
PoincareHelpers::Reduce(&o,
App::app()->localContext(),
ExpressionNode::ReductionTarget::User,
ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined,
ExpressionNode::UnitConversion::None);
o = o.removeUnit(&unit);
// There might be no unit in the end, if the reduction was interrupted.
if (!unit.isUninitialized()) {
if (Unit::IsSI(unit)) {
if (Unit::IsSISpeed(unit) || Unit::IsSIVolume(unit) || Unit::IsSIEnergy(unit)) {
/* All these units will provide misc. classic representatives in
* addition to the SI unit in additional information. */
return AdditionalInformationType::Unit;
}
if (Unit::IsSITime(unit)) {
/* If the number of seconds is above 60s, we can write it in the form
* of an addition: 23_min + 12_s for instance. */
double value = Shared::PoincareHelpers::ApproximateToScalar<double>(o, App::app()->localContext());
if (value > Unit::SecondsPerMinute) {
return AdditionalInformationType::Unit;
}
}
return AdditionalInformationType::None;
}
return AdditionalInformationType::Unit;
}
}
if (o.isBasedIntegerCappedBy(k_maximalIntegerWithAdditionalInformation)) {
return AdditionalInformationType::Integer;
}

View File

@@ -61,8 +61,6 @@ public:
bool operator==(const Calculation& c);
Calculation * next() const;
void tidy();
// Texts
enum class NumberOfSignificantDigits {
Maximal,
@@ -83,8 +81,8 @@ public:
Poincare::Layout createExactOutputLayout(bool * couldNotCreateExactLayout);
Poincare::Layout createApproximateOutputLayout(Poincare::Context * context, bool * couldNotCreateApproximateLayout);
// Memoization of height
KDCoordinate height(Poincare::Context * context, bool expanded = false, bool allExpressionsInline = false);
// Heights
KDCoordinate height(bool expanded);
// Displayed output
DisplayOutput displayOutput(Poincare::Context * context);
@@ -99,6 +97,9 @@ private:
static constexpr int k_numberOfExpressions = 4;
static constexpr KDCoordinate k_heightComputationFailureHeight = 50;
static constexpr const char * k_maximalIntegerWithAdditionalInformation = "10000000000000000";
void setHeights(KDCoordinate height, KDCoordinate expandedHeight);
/* Buffers holding text expressions have to be longer than the text written
* by user (of maximum length TextField::maxBufferSize()) because when we
* print an expression we add omitted signs (multiplications, parenthesis...) */

View File

@@ -4,6 +4,7 @@
#include <poincare/rational.h>
#include <poincare/symbol.h>
#include <poincare/undefined.h>
#include "../exam_mode_configuration.h"
#include <assert.h>
using namespace Poincare;
@@ -50,7 +51,7 @@ ExpiringPointer<Calculation> CalculationStore::calculationAtIndex(int i) {
return calculationAtIndex(i);
}
ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context * context) {
ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context * context, HeightComputer heightComputer) {
/* Compute ans now, before the buffer is slided and before the calculation
* might be deleted */
Expression ans = ansExpression(context);
@@ -84,7 +85,7 @@ ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context *
/* If the input does not fit in the store (event if the current
* calculation is the only calculation), just replace the calculation with
* undef. */
return emptyStoreAndPushUndef(context);
return emptyStoreAndPushUndef(context, heightComputer);
}
nextSerializationLocation += strlen(nextSerializationLocation) + 1;
}
@@ -98,8 +99,11 @@ ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context *
// Outputs hold exact output, approximate output and its duplicate
constexpr static int numberOfOutputs = Calculation::k_numberOfExpressions - 1;
Expression outputs[numberOfOutputs] = {Expression(), Expression(), Expression()};
// SYMBOLIC COMPUTATION <= E12: PoincareHelpers::ParseAndSimplifyAndApproximate(inputSerialization, &(outputs[0]), &(outputs[1]), context, GlobalPreferences::sharedGlobalPreferences()->isInExamModeSymbolic()); // Symbolic computation
PoincareHelpers::ParseAndSimplifyAndApproximate(inputSerialization, &(outputs[0]), &(outputs[1]), context, GlobalPreferences::sharedGlobalPreferences()->isInExamModeSymbolic() ? Poincare::ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition : Poincare::ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined);
if (ExamModeConfiguration::exactExpressionsAreForbidden(GlobalPreferences::sharedGlobalPreferences()->examMode()) && outputs[1].hasUnit()) {
// Hide results with units on units if required by the exam mode configuration
outputs[1] = Undefined::Builder();
}
outputs[2] = outputs[1];
int numberOfSignificantDigits = Poincare::PrintFloat::k_numberOfStoredSignificantDigits;
for (int i = 0; i < numberOfOutputs; i++) {
@@ -112,7 +116,7 @@ ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context *
* undef if it fits, else replace the whole calcualtion with undef. */
Expression undef = Undefined::Builder();
if (!pushSerializeExpression(undef, nextSerializationLocation, &newCalculationsLocation)) {
return emptyStoreAndPushUndef(context);
return emptyStoreAndPushUndef(context, heightComputer);
}
}
nextSerializationLocation += strlen(nextSerializationLocation) + 1;
@@ -129,7 +133,15 @@ ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context *
// Clean the memoization
resetMemoizedModelsAfterCalculationIndex(-1);
return ExpiringPointer<Calculation>(reinterpret_cast<Calculation *>(m_buffer));
ExpiringPointer<Calculation> calculation = ExpiringPointer<Calculation>(reinterpret_cast<Calculation *>(m_buffer));
/* Heights are computed now to make sure that the display output is decided
* accordingly to the remaining size in the Poincare pool. Once it is, it
* can't change anymore: the calculation heights are fixed which ensures that
* scrolling computation is right. */
calculation->setHeights(
heightComputer(calculation.pointer(), false),
heightComputer(calculation.pointer(), true));
return calculation;
}
void CalculationStore::deleteCalculationAtIndex(int i) {
@@ -160,9 +172,6 @@ void CalculationStore::tidy() {
return;
}
resetMemoizedModelsAfterCalculationIndex(-1);
for (Calculation * c : *this) {
c->tidy();
}
}
Expression CalculationStore::ansExpression(Context * context) {
@@ -251,12 +260,12 @@ const char * CalculationStore::lastCalculationPosition(const char * calculations
return reinterpret_cast<const char *>(c);
}
Shared::ExpiringPointer<Calculation> CalculationStore::emptyStoreAndPushUndef(Context * context) {
Shared::ExpiringPointer<Calculation> CalculationStore::emptyStoreAndPushUndef(Context * context, HeightComputer heightComputer) {
/* We end up here as a result of a failed calculation push. The store
* attributes are not necessarily clean, so we need to reset them. */
m_slidedBuffer = false;
deleteAll();
return push(Undefined::Name(), context);
return push(Undefined::Name(), context, heightComputer);
}
void CalculationStore::resetMemoizedModelsAfterCalculationIndex(int index) {

View File

@@ -28,7 +28,8 @@ class CalculationStore {
public:
CalculationStore();
Shared::ExpiringPointer<Calculation> calculationAtIndex(int i);
Shared::ExpiringPointer<Calculation> push(const char * text, Poincare::Context * context);
typedef KDCoordinate (*HeightComputer)(Calculation * c, bool expanded);
Shared::ExpiringPointer<Calculation> push(const char * text, Poincare::Context * context, HeightComputer heightComputer);
void deleteCalculationAtIndex(int i);
void deleteAll();
int numberOfCalculations() const { return m_numberOfCalculations; }
@@ -60,7 +61,7 @@ private:
char * slideCalculationsToEndOfBuffer(); // returns the new position of the calculations
size_t deleteLastCalculation(const char * calculationsStart = nullptr);
const char * lastCalculationPosition(const char * calculationsStart) const;
Shared::ExpiringPointer<Calculation> emptyStoreAndPushUndef(Poincare::Context * context);
Shared::ExpiringPointer<Calculation> emptyStoreAndPushUndef(Poincare::Context * context, HeightComputer heightComputer);
char m_buffer[k_bufferSize];
const char * m_bufferEnd;

View File

@@ -9,7 +9,7 @@ using namespace Poincare;
namespace Calculation {
EditExpressionController::ContentView::ContentView(Responder * parentResponder, TableView * subview, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate) :
EditExpressionController::ContentView::ContentView(Responder * parentResponder, CalculationSelectableTableView * subview, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate) :
View(),
m_mainView(subview),
m_expressionField(parentResponder, inputEventHandlerDelegate, textFieldDelegate, layoutFieldDelegate)
@@ -42,18 +42,18 @@ EditExpressionController::EditExpressionController(Responder * parentResponder,
ViewController(parentResponder),
m_historyController(historyController),
m_calculationStore(calculationStore),
m_contentView(this, (TableView *)m_historyController->view(), inputEventHandlerDelegate, this, this)
m_contentView(this, static_cast<CalculationSelectableTableView *>(m_historyController->view()), inputEventHandlerDelegate, this, this)
{
m_cacheBuffer[0] = 0;
}
void EditExpressionController::insertTextBody(const char * text) {
Container::activeApp()->setFirstResponder(this);
m_contentView.expressionField()->handleEventWithText(text, false, true);
}
void EditExpressionController::didBecomeFirstResponder() {
int lastRow = m_calculationStore->numberOfCalculations() > 0 ? m_calculationStore->numberOfCalculations()-1 : 0;
m_historyController->scrollToCell(0, lastRow);
m_contentView.mainView()->scrollToBottom();
m_contentView.expressionField()->setEditing(true, false);
Container::activeApp()->setFirstResponder(m_contentView.expressionField());
}
@@ -122,7 +122,7 @@ bool EditExpressionController::inputViewDidReceiveEvent(Ion::Events::Event event
if (!myApp->isAcceptableText(m_cacheBuffer)) {
return true;
}
m_calculationStore->push(m_cacheBuffer, myApp->localContext());
m_calculationStore->push(m_cacheBuffer, myApp->localContext(), HistoryViewCell::Height);
m_historyController->reload();
return true;
}
@@ -145,7 +145,7 @@ bool EditExpressionController::inputViewDidFinishEditing(const char * text, Layo
} else {
layoutR.serializeParsedExpression(m_cacheBuffer, k_cacheBufferSize, context);
}
m_calculationStore->push(m_cacheBuffer, context);
m_calculationStore->push(m_cacheBuffer, context, HistoryViewCell::Height);
m_historyController->reload();
m_contentView.expressionField()->setEditing(true, true);
telemetryReportEvent("Input", m_cacheBuffer);

View File

@@ -8,6 +8,7 @@
#include "../shared/layout_field_delegate.h"
#include "history_controller.h"
#include "calculation_store.h"
#include "selectable_table_view.h"
namespace Calculation {
@@ -34,15 +35,15 @@ public:
private:
class ContentView : public View {
public:
ContentView(Responder * parentResponder, TableView * subview, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate);
ContentView(Responder * parentResponder, CalculationSelectableTableView * subview, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate);
void reload();
TableView * mainView() { return m_mainView; }
CalculationSelectableTableView * mainView() { return m_mainView; }
ExpressionField * expressionField() { return &m_expressionField; }
private:
int numberOfSubviews() const override { return 2; }
View * subviewAtIndex(int index) override;
void layoutSubviews(bool force = false) override;
TableView * m_mainView;
CalculationSelectableTableView * m_mainView;
ExpressionField m_expressionField;
};
void reloadView();

View File

@@ -7,7 +7,10 @@ namespace Calculation {
class ExpressionField : public ::ExpressionField {
public:
using ::ExpressionField::ExpressionField;
ExpressionField(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandler, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate) :
::ExpressionField(parentResponder, inputEventHandler, textFieldDelegate, layoutFieldDelegate) {
setLayoutInsertionCursorEvent(Ion::Events::Up);
}
protected:
bool handleEvent(Ion::Events::Event event) override;
};

View File

@@ -1,5 +1,6 @@
#include "history_controller.h"
#include "app.h"
#include <poincare/exception_checkpoint.h>
#include <assert.h>
using namespace Shared;
@@ -15,7 +16,8 @@ HistoryController::HistoryController(EditExpressionController * editExpressionCo
m_complexController(editExpressionController),
m_integerController(editExpressionController),
m_rationalController(editExpressionController),
m_trigonometryController(editExpressionController)
m_trigonometryController(editExpressionController),
m_unitController(editExpressionController)
{
for (int i = 0; i < k_maxNumberOfDisplayedRows; i++) {
m_calculationHistory[i].setParentResponder(&m_selectableTableView);
@@ -37,9 +39,9 @@ void HistoryController::reload() {
* the table view twice.
*/
if (numberOfRows() > 0) {
m_selectableTableView.scrollToCell(0, numberOfRows()-1);
m_selectableTableView.scrollToBottom();
// Force to reload last added cell (hide the burger and exact output if necessary)
tableViewDidChangeSelection(&m_selectableTableView, 0, numberOfRows()-1);
tableViewDidChangeSelectionAndDidScroll(&m_selectableTableView, 0, numberOfRows()-1);
}
}
@@ -78,11 +80,9 @@ bool HistoryController::handleEvent(Ion::Events::Event event) {
EditExpressionController * editController = (EditExpressionController *)parentResponder();
if (subviewType == SubviewType::Input) {
m_selectableTableView.deselectTable();
Container::activeApp()->setFirstResponder(editController);
editController->insertTextBody(calculationAtIndex(focusRow)->inputText());
} else if (subviewType == SubviewType::Output) {
m_selectableTableView.deselectTable();
Container::activeApp()->setFirstResponder(editController);
Shared::ExpiringPointer<Calculation> calculation = calculationAtIndex(focusRow);
ScrollableTwoExpressionsView::SubviewPosition outputSubviewPosition = selectedCell->outputView()->selectedSubviewPosition();
if (outputSubviewPosition == ScrollableTwoExpressionsView::SubviewPosition::Right
@@ -108,6 +108,8 @@ bool HistoryController::handleEvent(Ion::Events::Event event) {
vc = &m_integerController;
} else if (additionalInfoType == Calculation::AdditionalInformationType::Rational) {
vc = &m_rationalController;
} else if (additionalInfoType == Calculation::AdditionalInformationType::Unit) {
vc = &m_unitController;
}
if (vc) {
vc->setExpression(e);
@@ -120,24 +122,16 @@ bool HistoryController::handleEvent(Ion::Events::Event event) {
int focusRow = selectedRow();
SubviewType subviewType = selectedSubviewType();
m_selectableTableView.deselectTable();
EditExpressionController * editController = (EditExpressionController *)parentResponder();
m_calculationStore->deleteCalculationAtIndex(storeIndex(focusRow));
reload();
if (numberOfRows()== 0) {
Container::activeApp()->setFirstResponder(editController);
Container::activeApp()->setFirstResponder(parentResponder());
return true;
}
if (focusRow > 0) {
m_selectableTableView.selectCellAtLocation(0, focusRow-1);
} else {
m_selectableTableView.selectCellAtLocation(0, 0);
}
if (subviewType == SubviewType::Input) {
tableViewDidChangeSelection(&m_selectableTableView, 0, selectedRow());
} else {
tableViewDidChangeSelection(&m_selectableTableView, 0, -1);
}
m_selectableTableView.scrollToCell(0, selectedRow());
m_selectableTableView.selectCellAtLocation(0, focusRow > 0 ? focusRow - 1 : 0);
/* The parameters 'sameCell' and 'previousSelectedY' are chosen to enforce
* toggling of the output when necessary. */
setSelectedSubviewType(subviewType, false, 0, (subviewType == SubviewType::Input) ? selectedRow() : -1);
return true;
}
if (event == Ion::Events::Clear) {
@@ -148,9 +142,8 @@ bool HistoryController::handleEvent(Ion::Events::Event event) {
return true;
}
if (event == Ion::Events::Back) {
EditExpressionController * editController = (EditExpressionController *)parentResponder();
m_selectableTableView.deselectTable();
Container::activeApp()->setFirstResponder(editController);
Container::activeApp()->setFirstResponder(parentResponder());
return true;
}
return false;
@@ -160,19 +153,23 @@ Shared::ExpiringPointer<Calculation> HistoryController::calculationAtIndex(int i
return m_calculationStore->calculationAtIndex(storeIndex(i));
}
void HistoryController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) {
void HistoryController::tableViewDidChangeSelectionAndDidScroll(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) {
if (withinTemporarySelection || previousSelectedCellY == selectedRow()) {
return;
}
if (previousSelectedCellY == -1) {
setSelectedSubviewType(SubviewType::Output, false, previousSelectedCellX, previousSelectedCellY);
} else if (selectedRow() < previousSelectedCellY) {
setSelectedSubviewType(SubviewType::Output, false, previousSelectedCellX, previousSelectedCellY);
} else if (selectedRow() > previousSelectedCellY) {
setSelectedSubviewType(SubviewType::Input, false, previousSelectedCellX, previousSelectedCellY);
} else if (selectedRow() == -1) {
setSelectedSubviewType(SubviewType::Input, false, previousSelectedCellX, previousSelectedCellY);
} else {
HistoryViewCell * selectedCell = (HistoryViewCell *)(t->selectedCell());
SubviewType nextSelectedSubviewType = selectedSubviewType();
if (selectedCell && !selectedCell->displaysSingleLine()) {
nextSelectedSubviewType = previousSelectedCellY < selectedRow() ? SubviewType::Input : SubviewType::Output;
}
setSelectedSubviewType(nextSelectedSubviewType, false, previousSelectedCellX, previousSelectedCellY);
}
// The selectedCell may change during setSelectedSubviewType
HistoryViewCell * selectedCell = (HistoryViewCell *)(t->selectedCell());
if (selectedCell == nullptr) {
return;
@@ -208,22 +205,29 @@ KDCoordinate HistoryController::rowHeight(int j) {
return 0;
}
Shared::ExpiringPointer<Calculation> calculation = calculationAtIndex(j);
return calculation->height(App::app()->localContext(), j == selectedRow() && selectedSubviewType() == SubviewType::Output);
bool expanded = j == selectedRow() && selectedSubviewType() == SubviewType::Output;
return calculation->height(expanded);
}
int HistoryController::typeAtLocation(int i, int j) {
return 0;
}
void HistoryController::scrollToCell(int i, int j) {
m_selectableTableView.scrollToCell(i, j);
}
bool HistoryController::calculationAtIndexToggles(int index) {
Context * context = App::app()->localContext();
return index >= 0 && index < m_calculationStore->numberOfCalculations() && calculationAtIndex(index)->displayOutput(context) == Calculation::DisplayOutput::ExactAndApproximateToggle;
}
void HistoryController::setSelectedSubviewType(SubviewType subviewType, bool sameCell, int previousSelectedX, int previousSelectedY) {
// Avoid selecting non-displayed ellipsis
HistoryViewCell * selectedCell = static_cast<HistoryViewCell *>(m_selectableTableView.selectedCell());
if (subviewType == SubviewType::Ellipsis && selectedCell && selectedCell->additionalInformationType() == Calculation::AdditionalInformationType::None) {
subviewType = SubviewType::Output;
}
HistoryViewCellDataSource::setSelectedSubviewType(subviewType, sameCell, previousSelectedX, previousSelectedY);
}
void HistoryController::historyViewCellDidChangeSelection(HistoryViewCell ** cell, HistoryViewCell ** previousCell, int previousSelectedCellX, int previousSelectedCellY, SubviewType type, SubviewType previousType) {
/* If the selection change triggers the toggling of the outputs, we update
* the whole table as the height of the selected cell row might have changed. */

View File

@@ -9,6 +9,7 @@
#include "additional_outputs/integer_list_controller.h"
#include "additional_outputs/rational_list_controller.h"
#include "additional_outputs/trigonometry_list_controller.h"
#include "additional_outputs/unit_list_controller.h"
namespace Calculation {
@@ -30,8 +31,8 @@ public:
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
KDCoordinate rowHeight(int j) override;
int typeAtLocation(int i, int j) override;
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection = false) override;
void scrollToCell(int i, int j);
void setSelectedSubviewType(SubviewType subviewType, bool sameCell, int previousSelectedX = -1, int previousSelectedY = -1) override;
void tableViewDidChangeSelectionAndDidScroll(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection = false) override;
private:
int storeIndex(int i) { return numberOfRows() - i - 1; }
Shared::ExpiringPointer<Calculation> calculationAtIndex(int i);
@@ -46,6 +47,7 @@ private:
IntegerListController m_integerController;
RationalListController m_rationalController;
TrigonometryListController m_trigonometryController;
UnitListController m_unitController;
};
}

View File

@@ -5,17 +5,12 @@
#include <poincare/exception_checkpoint.h>
#include <assert.h>
#include <string.h>
#include <algorithm>
namespace Calculation {
static inline KDCoordinate minCoordinate(KDCoordinate x, KDCoordinate y) { return x < y ? x : y; }
static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; }
/* HistoryViewCellDataSource */
HistoryViewCellDataSource::HistoryViewCellDataSource() :
m_selectedSubviewType(SubviewType::Output) {}
void HistoryViewCellDataSource::setSelectedSubviewType(SubviewType subviewType, bool sameCell, int previousSelectedCellX, int previousSelectedCellY) {
HistoryViewCell * selectedCell = nullptr;
HistoryViewCell * previouslySelectedCell = nullptr;
@@ -30,6 +25,7 @@ void HistoryViewCellDataSource::setSelectedSubviewType(SubviewType subviewType,
if (selectedCell) {
selectedCell->reloadSubviewHighlight();
selectedCell->cellDidSelectSubview(subviewType, previousSubviewType);
Container::activeApp()->setFirstResponder(selectedCell);
}
if (previouslySelectedCell) {
previouslySelectedCell->cellDidSelectSubview(SubviewType::Input);
@@ -38,19 +34,26 @@ void HistoryViewCellDataSource::setSelectedSubviewType(SubviewType subviewType,
/* HistoryViewCell */
HistoryViewCell::HistoryViewCell(Responder * parentResponder) :
Responder(parentResponder),
m_calculationDisplayOutput(Calculation::DisplayOutput::Unknown),
m_calculationAdditionInformation(Calculation::AdditionalInformationType::None),
m_calculationExpanded(false),
m_inputView(this, Metric::CommonLargeMargin, Metric::CommonSmallMargin),
m_scrollableOutputView(this)
{
m_calculationCRC32 = 0;
KDCoordinate HistoryViewCell::Height(Calculation * calculation, bool expanded) {
HistoryViewCell cell(nullptr);
cell.setCalculation(calculation, expanded, true);
KDRect ellipsisFrame = KDRectZero;
KDRect inputFrame = KDRectZero;
KDRect outputFrame = KDRectZero;
cell.computeSubviewFrames(Ion::Display::Width, KDCOORDINATE_MAX, &ellipsisFrame, &inputFrame, &outputFrame);
return k_margin + inputFrame.unionedWith(outputFrame).height() + k_margin;
}
Shared::ScrollableTwoExpressionsView * HistoryViewCell::outputView() {
return &m_scrollableOutputView;
HistoryViewCell::HistoryViewCell(Responder * parentResponder) :
Responder(parentResponder),
m_calculationCRC32(0),
m_calculationDisplayOutput(Calculation::DisplayOutput::Unknown),
m_calculationAdditionInformation(Calculation::AdditionalInformationType::None),
m_inputView(this, k_inputViewHorizontalMargin, k_inputOutputViewsVerticalMargin),
m_scrollableOutputView(this),
m_calculationExpanded(false),
m_calculationSingleLine(false)
{
}
void HistoryViewCell::setEven(bool even) {
@@ -138,15 +141,6 @@ void HistoryViewCell::cellDidSelectSubview(HistoryViewCellDataSource::SubviewTyp
reloadScroll();
}
KDColor HistoryViewCell::backgroundColor() const {
KDColor background = m_even ? Palette::CalculationBackgroundEven : Palette::CalculationBackgroundOdd;
return background;
}
int HistoryViewCell::numberOfSubviews() const {
return 2 + displayedEllipsis();
}
View * HistoryViewCell::subviewAtIndex(int index) {
/* The order of the subviews should not matter here as they don't overlap.
* However, the order determines the order of redrawing as well. For several
@@ -170,29 +164,69 @@ View * HistoryViewCell::subviewAtIndex(int index) {
return views[index];
}
bool HistoryViewCell::ViewsCanBeSingleLine(KDCoordinate inputViewWidth, KDCoordinate outputViewWidth) {
// k_margin is the separation between the input and output.
return (inputViewWidth + k_margin + outputViewWidth) < Ion::Display::Width - Metric::EllipsisCellWidth;
}
void HistoryViewCell::layoutSubviews(bool force) {
KDCoordinate maxFrameWidth = bounds().width();
if (displayedEllipsis()) {
m_ellipsis.setFrame(KDRect(maxFrameWidth - Metric::EllipsisCellWidth, 0, Metric::EllipsisCellWidth, bounds().height()), force);
maxFrameWidth -= Metric::EllipsisCellWidth;
} else {
m_ellipsis.setFrame(KDRectZero, force); // Required to mark previous rect as dirty
KDRect frameBounds = bounds();
if (bounds().width() <= 0 || bounds().height() <= 0) {
// TODO Make this behaviour in a non-virtual layoutSublviews, and all layout subviews should become privateLayoutSubviews
return;
}
KDRect ellipsisFrame = KDRectZero;
KDRect inputFrame = KDRectZero;
KDRect outputFrame = KDRectZero;
computeSubviewFrames(frameBounds.width(), frameBounds.height(), &ellipsisFrame, &inputFrame, &outputFrame);
m_ellipsis.setFrame(ellipsisFrame, force); // Required even if ellipsisFrame is KDRectZero, to mark previous rect as dirty
m_inputView.setFrame(inputFrame,force);
m_scrollableOutputView.setFrame(outputFrame, force);
}
void HistoryViewCell::computeSubviewFrames(KDCoordinate frameWidth, KDCoordinate frameHeight, KDRect * ellipsisFrame, KDRect * inputFrame, KDRect * outputFrame) {
assert(ellipsisFrame != nullptr && inputFrame != nullptr && outputFrame != nullptr);
if (displayedEllipsis()) {
*ellipsisFrame = KDRect(frameWidth - Metric::EllipsisCellWidth, 0, Metric::EllipsisCellWidth, frameHeight);
frameWidth -= Metric::EllipsisCellWidth;
} else {
*ellipsisFrame = KDRectZero;
}
KDSize inputSize = m_inputView.minimalSizeForOptimalDisplay();
m_inputView.setFrame(KDRect(
0, 0,
minCoordinate(maxFrameWidth, inputSize.width()),
inputSize.height()),
force);
KDSize outputSize = m_scrollableOutputView.minimalSizeForOptimalDisplay();
int singleLine = outputSize.width() + inputSize.width() < bounds().width() - 6;
int outputHeight = (singleLine && Poincare::Preferences::sharedPreferences()->resultDisplay() == Poincare::Preferences::ResultDisplay::Compact) ? (maxCoordinate(0, inputSize.height() - outputSize.height()) / 2) + maxCoordinate(0, (inputSize.height() - outputSize.height()) / 2) : inputSize.height();
m_scrollableOutputView.setFrame(KDRect(
maxCoordinate(0, maxFrameWidth - outputSize.width()),
outputHeight,
minCoordinate(maxFrameWidth, outputSize.width()),
outputSize.height()),
force);
/* To compute if the calculation is on a single line, use the expanded width
* if there is both an exact and an approximate layout. */
m_calculationSingleLine = ViewsCanBeSingleLine(inputSize.width(), m_scrollableOutputView.minimalSizeForOptimalDisplayFullSize().width());
KDCoordinate inputY = k_margin;
KDCoordinate outputY = k_margin;
if (m_calculationSingleLine && !m_inputView.layout().isUninitialized()) {
KDCoordinate inputBaseline = m_inputView.layout().baseline();
KDCoordinate outputBaseline = m_scrollableOutputView.baseline();
KDCoordinate baselineDifference = outputBaseline - inputBaseline;
if (baselineDifference > 0) {
inputY += baselineDifference;
} else {
outputY += -baselineDifference;
}
} else {
outputY += inputSize.height();
}
*inputFrame = KDRect(
0,
inputY,
std::min(frameWidth, inputSize.width()),
inputSize.height());
*outputFrame = KDRect(
std::max(0, frameWidth - outputSize.width()),
outputY,
std::min(frameWidth, outputSize.width()),
outputSize.height());
}
void HistoryViewCell::resetMemoization() {
@@ -203,7 +237,7 @@ void HistoryViewCell::resetMemoization() {
m_calculationCRC32 = 0;
}
void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded) {
void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded, bool canChangeDisplayOutput) {
uint32_t newCalculationCRC = Ion::crc32Byte((const uint8_t *)calculation, ((char *)calculation->next()) - ((char *) calculation));
if (newCalculationCRC == m_calculationCRC32 && m_calculationExpanded == expanded) {
return;
@@ -229,7 +263,7 @@ void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded) {
bool couldNotCreateExactLayout = false;
exactOutputLayout = calculation->createExactOutputLayout(&couldNotCreateExactLayout);
if (couldNotCreateExactLayout) {
if (calculation->displayOutput(context) != ::Calculation::Calculation::DisplayOutput::ExactOnly) {
if (canChangeDisplayOutput && calculation->displayOutput(context) != ::Calculation::Calculation::DisplayOutput::ExactOnly) {
calculation->forceDisplayOutput(::Calculation::Calculation::DisplayOutput::ApproximateOnly);
} else {
/* We should only display the exact result, but we cannot create it
@@ -247,9 +281,7 @@ void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded) {
bool couldNotCreateApproximateLayout = false;
approximateOutputLayout = calculation->createApproximateOutputLayout(context, &couldNotCreateApproximateLayout);
if (couldNotCreateApproximateLayout) {
if (calculation->displayOutput(context) == ::Calculation::Calculation::DisplayOutput::ApproximateOnly) {
Poincare::ExceptionCheckpoint::Raise();
} else {
if (canChangeDisplayOutput && calculation->displayOutput(context) != ::Calculation::Calculation::DisplayOutput::ApproximateOnly) {
/* Set the display output to ApproximateOnly, make room in the pool by
* erasing the exact layout, and retry to create the approximate layout */
calculation->forceDisplayOutput(::Calculation::Calculation::DisplayOutput::ApproximateOnly);
@@ -259,6 +291,8 @@ void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded) {
if (couldNotCreateApproximateLayout) {
Poincare::ExceptionCheckpoint::Raise();
}
} else {
Poincare::ExceptionCheckpoint::Raise();
}
}
}
@@ -286,31 +320,41 @@ void HistoryViewCell::didBecomeFirstResponder() {
}
bool HistoryViewCell::handleEvent(Ion::Events::Event event) {
assert(m_dataSource);
assert(m_dataSource != nullptr);
HistoryViewCellDataSource::SubviewType type = m_dataSource->selectedSubviewType();
if ((event == Ion::Events::Down && type == HistoryViewCellDataSource::SubviewType::Input) ||
(event == Ion::Events::Up && type == HistoryViewCellDataSource::SubviewType::Output) ||
(event == Ion::Events::Right && type != HistoryViewCellDataSource::SubviewType::Ellipsis && displayedEllipsis()) ||
(event == Ion::Events::Left && type == HistoryViewCellDataSource::SubviewType::Ellipsis)) {
HistoryViewCellDataSource::SubviewType otherSubviewType;
if (event == Ion::Events::Down) {
otherSubviewType = HistoryViewCellDataSource::SubviewType::Output;
} else if (event == Ion::Events::Up) {
otherSubviewType = HistoryViewCellDataSource::SubviewType::Input;
} else if (event == Ion::Events::Right) {
otherSubviewType = HistoryViewCellDataSource::SubviewType::Ellipsis;
} else {
assert(event == Ion::Events::Left);
otherSubviewType = HistoryViewCellDataSource::SubviewType::Output;
assert(type != HistoryViewCellDataSource::SubviewType::None);
HistoryViewCellDataSource::SubviewType otherSubviewType = HistoryViewCellDataSource::SubviewType::None;
if (m_calculationSingleLine) {
static_assert(
static_cast<int>(HistoryViewCellDataSource::SubviewType::None) == 0
&& static_cast<int>(HistoryViewCellDataSource::SubviewType::Input) == 1
&& static_cast<int>(HistoryViewCellDataSource::SubviewType::Output) == 2
&& static_cast<int>(HistoryViewCellDataSource::SubviewType::Ellipsis) == 3,
"The array types is not well-formed anymore");
HistoryViewCellDataSource::SubviewType types[] = {
HistoryViewCellDataSource::SubviewType::None,
HistoryViewCellDataSource::SubviewType::Input,
HistoryViewCellDataSource::SubviewType::Output,
displayedEllipsis() ? HistoryViewCellDataSource::SubviewType::Ellipsis : HistoryViewCellDataSource::SubviewType::None,
HistoryViewCellDataSource::SubviewType::None,
};
if (event == Ion::Events::Right || event == Ion::Events::Left) {
otherSubviewType = types[static_cast<int>(type) + (event == Ion::Events::Right ? 1 : -1)];
}
m_dataSource->setSelectedSubviewType(otherSubviewType, true);
return true;
} else if ((event == Ion::Events::Down && type == HistoryViewCellDataSource::SubviewType::Input)
|| (event == Ion::Events::Left && type == HistoryViewCellDataSource::SubviewType::Ellipsis))
{
otherSubviewType = HistoryViewCellDataSource::SubviewType::Output;
} else if (event == Ion::Events::Up && type == HistoryViewCellDataSource::SubviewType::Output) {
otherSubviewType = HistoryViewCellDataSource::SubviewType::Input;
} else if (event == Ion::Events::Right && type != HistoryViewCellDataSource::SubviewType::Ellipsis && displayedEllipsis()) {
otherSubviewType = HistoryViewCellDataSource::SubviewType::Ellipsis;
}
return false;
}
bool HistoryViewCell::displayedEllipsis() const {
return m_highlighted && m_calculationAdditionInformation != Calculation::AdditionalInformationType::None;
if (otherSubviewType == HistoryViewCellDataSource::SubviewType::None) {
return false;
}
m_dataSource->setSelectedSubviewType(otherSubviewType, true);
return true;
}
}

View File

@@ -12,14 +12,14 @@ class HistoryViewCell;
class HistoryViewCellDataSource {
public:
enum class SubviewType {
None,
Input,
Output,
Ellipsis
None = 0,
Input = 1,
Output = 2,
Ellipsis = 3
};
HistoryViewCellDataSource();
void setSelectedSubviewType(SubviewType subviewType, bool sameCell, int previousSelectedX = -1, int previousSelectedY = -1);
SubviewType selectedSubviewType() { return m_selectedSubviewType; }
HistoryViewCellDataSource() : m_selectedSubviewType(SubviewType::Output) {}
virtual void setSelectedSubviewType(SubviewType subviewType, bool sameCell, int previousSelectedX = -1, int previousSelectedY = -1);
SubviewType selectedSubviewType() const { return m_selectedSubviewType; }
private:
/* This method should belong to a delegate instead of a data source but as
* both the data source and the delegate will be the same controller, we
@@ -31,39 +31,52 @@ private:
class HistoryViewCell : public ::EvenOddCell, public Responder {
public:
constexpr static KDCoordinate k_margin = Metric::CommonSmallMargin;
constexpr static KDCoordinate k_inputOutputViewsVerticalMargin = k_margin;
constexpr static KDCoordinate k_inputViewHorizontalMargin = Shared::AbstractScrollableMultipleExpressionsView::k_horizontalMargin;
static KDCoordinate Height(Calculation * calculation, bool expanded);
HistoryViewCell(Responder * parentResponder = nullptr);
static bool ViewsCanBeSingleLine(KDCoordinate inputViewWidth, KDCoordinate outputViewWidth);
void cellDidSelectSubview(HistoryViewCellDataSource::SubviewType type, HistoryViewCellDataSource::SubviewType previousType = HistoryViewCellDataSource::SubviewType::None);
void setEven(bool even) override;
void setHighlighted(bool highlight) override;
void reloadSubviewHighlight();
void setDataSource(HistoryViewCellDataSource * dataSource) { m_dataSource = dataSource; }
bool displaysSingleLine() const {
return m_calculationSingleLine;
}
Responder * responder() override {
return this;
}
Poincare::Layout layout() const override;
KDColor backgroundColor() const override;
KDColor backgroundColor() const override { return m_even ? Palette::CalculationBackgroundEven : Palette::CalculationBackgroundOdd; }
void resetMemoization();
void setCalculation(Calculation * calculation, bool expanded);
int numberOfSubviews() const override;
void setCalculation(Calculation * calculation, bool expanded, bool canChangeDisplayOutput = false);
int numberOfSubviews() const override { return 2 + displayedEllipsis(); }
View * subviewAtIndex(int index) override;
void layoutSubviews(bool force = false) override;
void didBecomeFirstResponder() override;
bool handleEvent(Ion::Events::Event event) override;
Shared::ScrollableTwoExpressionsView * outputView();
Shared::ScrollableTwoExpressionsView * outputView() { return &m_scrollableOutputView; }
ScrollableExpressionView * inputView() { return &m_inputView; }
Calculation::AdditionalInformationType additionalInformationType() const { return m_calculationAdditionInformation; }
private:
constexpr static KDCoordinate k_resultWidth = 80;
void computeSubviewFrames(KDCoordinate frameWidth, KDCoordinate frameHeight, KDRect * ellipsisFrame, KDRect * inputFrame, KDRect * outputFrame);
void reloadScroll();
void reloadOutputSelection(HistoryViewCellDataSource::SubviewType previousType);
bool displayedEllipsis() const;
bool displayedEllipsis() const {
return m_highlighted && m_calculationAdditionInformation != Calculation::AdditionalInformationType::None;
}
uint32_t m_calculationCRC32;
Calculation::DisplayOutput m_calculationDisplayOutput;
Calculation::AdditionalInformationType m_calculationAdditionInformation;
bool m_calculationExpanded;
ScrollableExpressionView m_inputView;
Shared::ScrollableTwoExpressionsView m_scrollableOutputView;
EvenOddCellWithEllipsis m_ellipsis;
HistoryViewCellDataSource * m_dataSource;
bool m_calculationExpanded;
bool m_calculationSingleLine;
};
}

View File

@@ -1,4 +1,5 @@
#include "selectable_table_view.h"
#include <algorithm>
namespace Calculation {
@@ -11,18 +12,23 @@ CalculationSelectableTableView::CalculationSelectableTableView(Responder * paren
setDecoratorType(ScrollView::Decorator::Type::None);
}
void CalculationSelectableTableView::scrollToBottom() {
KDCoordinate contentOffsetX = contentOffset().x();
KDCoordinate contentOffsetY = dataSource()->cumulatedHeightFromIndex(dataSource()->numberOfRows()) - maxContentHeightDisplayableWithoutScrolling();
setContentOffset(KDPoint(contentOffsetX, contentOffsetY));
}
void CalculationSelectableTableView::scrollToCell(int i, int j) {
::SelectableTableView::scrollToCell(i, j);
if (m_contentView.bounds().height() < bounds().height()) {
setTopMargin(bounds().height() - m_contentView.bounds().height());
} else {
setTopMargin(0);
}
::SelectableTableView::scrollToCell(i, j);
ScrollView::layoutSubviews();
if (m_contentView.bounds().height() - contentOffset().y() < bounds().height()) {
KDCoordinate contentOffsetX = contentOffset().x();
KDCoordinate contentOffsetY = dataSource()->cumulatedHeightFromIndex(dataSource()->numberOfRows()) - maxContentHeightDisplayableWithoutScrolling();
setContentOffset(KDPoint(contentOffsetX, contentOffsetY));
// Avoid empty space at the end of the table
scrollToBottom();
}
}
@@ -31,23 +37,63 @@ void CalculationSelectableTableView::scrollToSubviewOfTypeOfCellAtLocation(Histo
return;
}
/* As we scroll, the selected calculation does not use the same history view
* cell, thus, we want to deselect the previous used history view cell. */
* cell, thus, we want to deselect the previous used history view cell. (*) */
unhighlightSelectedCell();
/* Main part of the scroll */
HistoryViewCell * cell = static_cast<HistoryViewCell *>(selectedCell());
assert(cell);
KDCoordinate contentOffsetX = contentOffset().x();
KDCoordinate contentOffsetY = dataSource()->cumulatedHeightFromIndex(j+1) - maxContentHeightDisplayableWithoutScrolling();
if (subviewType == HistoryViewCellDataSource::SubviewType::Input) {
if (j == 0) {
contentOffsetY = 0;
} else {
contentOffsetY = dataSource()->cumulatedHeightFromIndex(j);
}
KDCoordinate contentOffsetY = dataSource()->cumulatedHeightFromIndex(j);
if (cell->displaysSingleLine() && dataSource()->rowHeight(j) > maxContentHeightDisplayableWithoutScrolling()) {
/* If we cannot display the full calculation, we display the selected
* layout as close as possible to the top of the screen without drawing
* empty space between the history and the input field.
*
* Below are some values we can assign to contentOffsetY, and the kinds of
* display they entail :
* (the selected cell is at index j)
*
* 1 - cumulatedHeightFromIndex(j)
* Aligns the top of the cell with the top of the zone in which the
* history can be drawn.
*
* 2 - (cumulatedHeightFromIndex(j+1)
* - maxContentHeightDisplayableWithoutScrolling())
* Aligns the bottom of the cell with the top of the input field.
*
* 3 - cumulatedHeightFromIndex(j) + baseline1 - baseline2
* Aligns the top of the selected layout with the top of the screen (only
* used when the selected layout is the smallest).
*
* The following drawing shows where the calculation would be aligned with
* each value of contentOffsetY, for the calculation (1/3)/(4/2) = 1/6.
*
* (1) (2) (3)
* +--------------+ +--------------+ +--------------+
* | 1 | | --- - | | 3 1 |
* | - | | 4 6 | | --- - |
* | 3 1 | | - | | 4 6 |
* | --- - | | 2 | | - |
* +--------------+ +--------------+ +--------------+
* | (1/3)/(4/2) | | (1/3)/(4/2) | | (1/3)/(4/2) |
* +--------------+ +--------------+ +--------------+
*
* */
contentOffsetY += std::min(
dataSource()->rowHeight(j) - maxContentHeightDisplayableWithoutScrolling(),
std::max(0, (cell->inputView()->layout().baseline() - cell->outputView()->baseline()) * (subviewType == HistoryViewCellDataSource::SubviewType::Input ? -1 : 1)));
} else if (subviewType != HistoryViewCellDataSource::SubviewType::Input) {
contentOffsetY += dataSource()->rowHeight(j) - maxContentHeightDisplayableWithoutScrolling();
}
setContentOffset(KDPoint(contentOffsetX, contentOffsetY));
/* For the same reason, we have to rehighlight the new history view cell and
* reselect the first responder. */
HistoryViewCell * cell = (HistoryViewCell *)(selectedCell());
/* For the same reason as (*), we have to rehighlight the new history view
* cell and reselect the first responder.
* We have to recall "selectedCell" because when the table might have been
* relayouted in "setContentOffset".*/
cell = static_cast<HistoryViewCell *>(selectedCell());
assert(cell);
cell->setHighlighted(true);
Container::activeApp()->setFirstResponder(cell);

View File

@@ -9,6 +9,7 @@ class CalculationSelectableTableView : public ::SelectableTableView {
public:
CalculationSelectableTableView(Responder * parentResponder, TableViewDataSource * dataSource,
SelectableTableViewDataSource * selectionDataSource, SelectableTableViewDelegate * delegate = nullptr);
void scrollToBottom();
void scrollToCell(int i, int j) override;
void scrollToSubviewOfTypeOfCellAtLocation(HistoryViewCellDataSource::SubviewType subviewType, int i, int j);
};

View File

@@ -14,6 +14,7 @@ void assert_store_is(CalculationStore * store, const char * * result) {
}
}
KDCoordinate dummyHeight(::Calculation::Calculation * c, bool expanded) { return 0; }
QUIZ_CASE(calculation_store) {
Shared::GlobalContext globalContext;
@@ -22,7 +23,7 @@ QUIZ_CASE(calculation_store) {
const char * result[] = {"9", "8", "7", "6", "5", "4", "3", "2", "1", "0"};
for (int i = 0; i < 10; i++) {
char text[2] = {(char)(i+'0'), 0};
store.push(text, &globalContext);
store.push(text, &globalContext, dummyHeight);
quiz_assert(store.numberOfCalculations() == i+1);
}
assert_store_is(&store, result);
@@ -41,13 +42,13 @@ QUIZ_CASE(calculation_ans) {
Shared::GlobalContext globalContext;
CalculationStore store;
store.push("1+3/4", &globalContext);
store.push("ans+2/3", &globalContext);
store.push("1+3/4", &globalContext, dummyHeight);
store.push("ans+2/3", &globalContext, dummyHeight);
Shared::ExpiringPointer<::Calculation::Calculation> lastCalculation = store.calculationAtIndex(0);
quiz_assert(lastCalculation->displayOutput(&globalContext) == ::Calculation::Calculation::DisplayOutput::ExactAndApproximate);
quiz_assert(strcmp(lastCalculation->exactOutputText(),"29/12") == 0);
store.push("ans+0.22", &globalContext);
store.push("ans+0.22", &globalContext, dummyHeight);
lastCalculation = store.calculationAtIndex(0);
quiz_assert(lastCalculation->displayOutput(&globalContext) == ::Calculation::Calculation::DisplayOutput::ExactAndApproximateToggle);
quiz_assert(strcmp(lastCalculation->approximateOutputText(::Calculation::Calculation::NumberOfSignificantDigits::Maximal),"2.6366666666667") == 0);
@@ -56,7 +57,7 @@ QUIZ_CASE(calculation_ans) {
}
void assertCalculationIs(const char * input, ::Calculation::Calculation::DisplayOutput display, ::Calculation::Calculation::EqualSign sign, const char * exactOutput, const char * displayedApproximateOutput, const char * storedApproximateOutput, Context * context, CalculationStore * store) {
store->push(input, context);
store->push(input, context, dummyHeight);
Shared::ExpiringPointer<::Calculation::Calculation> lastCalculation = store->calculationAtIndex(0);
quiz_assert(lastCalculation->displayOutput(context) == display);
if (sign != ::Calculation::Calculation::EqualSign::Unknown) {

View File

@@ -11,42 +11,31 @@ app_code_src = $(addprefix apps/code/,\
editor_view.cpp \
helpers.cpp \
menu_controller.cpp \
python_toolbox.cpp \
python_text_area.cpp \
sandbox_controller.cpp \
script.cpp \
script_name_cell.cpp \
script_node_cell.cpp \
script_parameter_controller.cpp \
)
app_code_test_src = $(addprefix apps/code/,\
python_toolbox.cpp \
script.cpp \
script_node_cell.cpp \
script_store.cpp \
script_template.cpp \
variable_box_empty_controller.cpp \
variable_box_controller.cpp \
)
app_src += $(app_code_src)
i18n_files += $(addprefix apps/code/,\
base.de.i18n\
base.en.i18n\
base.es.i18n\
base.fr.i18n\
base.pt.i18n\
base.hu.i18n\
base.universal.i18n\
catalog.de.i18n\
catalog.en.i18n\
catalog.es.i18n\
catalog.fr.i18n\
catalog.pt.i18n\
catalog.hu.i18n\
catalog.universal.i18n\
toolbox.de.i18n\
toolbox.en.i18n\
toolbox.es.i18n\
toolbox.fr.i18n\
toolbox.pt.i18n\
toolbox.hu.i18n\
toolbox.universal.i18n\
tests_src += $(addprefix apps/code/test/,\
variable_box_controller.cpp\
)
app_code_src += $(app_code_test_src)
apps_src += $(app_code_src)
i18n_files += $(call i18n_with_universal_for,code/base)
i18n_files += $(call i18n_with_universal_for,code/catalog)
i18n_files += $(call i18n_with_universal_for,code/toolbox)
$(eval $(call depends_on_image,apps/code/app.cpp,apps/code/code_icon.png))

View File

@@ -14,8 +14,8 @@ I18n::Message App::Descriptor::upperName() {
return I18n::Message::CodeAppCapital;
}
int App::Descriptor::examinationLevel() {
return App::Descriptor::BasicExaminationLevel;
App::Descriptor::ExaminationLevel App::Descriptor::examinationLevel() {
return App::Descriptor::ExaminationLevel::Basic;
}
const Image * App::Descriptor::icon() {
@@ -25,6 +25,7 @@ const Image * App::Descriptor::icon() {
App::Snapshot::Snapshot() :
#if EPSILON_GETOPT
m_lockOnConsole(false),
m_hasBeenWiped(false),
#endif
m_scriptStore()
{
@@ -49,10 +50,12 @@ bool App::Snapshot::lockOnConsole() const {
}
void App::Snapshot::setOpt(const char * name, const char * value) {
if (strcmp(name, "wipe") == 0) {
m_scriptStore.deleteAllScripts();
}
if (strcmp(name, "script") == 0) {
if (!m_hasBeenWiped) {
m_hasBeenWiped = true;
m_scriptStore.deleteAllScripts();
}
char * separator = const_cast<char *>(UTF8Helper::CodePointSearch(value, ':'));
if (*separator == 0) {
return;
@@ -67,7 +70,7 @@ void App::Snapshot::setOpt(const char * name, const char * value) {
const char * scriptContent = separator;
Code::ScriptTemplate script(scriptName, scriptContent);
m_scriptStore.addScriptFromTemplate(&script);
m_scriptStore.scriptNamed(scriptName).toggleImportationStatus(); // set Importation Status to 1
ScriptStore::ScriptNamed(scriptName).toggleAutoimportationStatus(); // set Importation Status to 1
return;
}
if (strcmp(name, "lock-on-console") == 0) {

View File

@@ -18,7 +18,7 @@ public:
public:
I18n::Message name() override;
I18n::Message upperName() override;
int examinationLevel() override;
App::Descriptor::ExaminationLevel examinationLevel() override;
const Image * icon() override;
};
class Snapshot : public ::App::Snapshot {
@@ -34,6 +34,7 @@ public:
private:
#if EPSILON_GETOPT
bool m_lockOnConsole;
bool m_hasBeenWiped;
#endif
ScriptStore m_scriptStore;
};
@@ -51,6 +52,7 @@ public:
}
StackViewController * stackViewController() { return &m_codeStackViewController; }
ConsoleController * consoleController() { return &m_consoleController; }
MenuController * menuController() { return &m_menuController; }
/* Responder */
bool handleEvent(Ion::Events::Event event) override;

View File

@@ -1,9 +1,15 @@
Console = "Interaktive Konsole"
AddScript = "Skript hinzufügen"
ScriptOptions = "Skriptoptionen"
ExecuteScript = "Skript ausführen"
AllowedCharactersaz09 = "Erlaubte Zeichen: a-z, 0-9, _"
Autocomplete = "Autovervollständigung"
AutoImportScript = "Automatischer Import in Konsole"
BuiltinsAndKeywords = "Native Funktionen und Schlüsselwörter"
Console = "Interaktive Konsole"
DeleteScript = "Skript löschen"
DuplicateScript = "Skript duplizieren"
ExecuteScript = "Skript ausführen"
FunctionsAndVariables = "Funktionen und Variablen"
AllowedCharactersaz09 = "Erlaubte Zeichen: a-z, 0-9, _"
ImportedModulesAndScripts = "Importierte Module und Skripte"
NoWordAvailableHere = "Kein Wort ist hier verfübar."
ScriptInProgress = "Aktuelle Skript"
ScriptOptions = "Skriptoptionen"
ScriptSize = "Script size"

View File

@@ -1,9 +1,15 @@
Console = "Python shell"
AddScript = "Add a script"
ScriptOptions = "Script options"
ExecuteScript = "Execute script"
AllowedCharactersaz09 = "Allowed characters: a-z, 0-9, _"
Autocomplete = "Autocomplete"
AutoImportScript = "Auto import in shell"
BuiltinsAndKeywords = "Builtins and keywords"
Console = "Python shell"
DeleteScript = "Delete script"
DuplicateScript = "Duplicate script"
ExecuteScript = "Execute script"
FunctionsAndVariables = "Functions and variables"
AllowedCharactersaz09 = "Allowed characters: a-z, 0-9, _"
ImportedModulesAndScripts = "Imported modules and scripts"
NoWordAvailableHere = "No word available here."
ScriptInProgress = "Script in progress"
ScriptOptions = "Script options"
ScriptSize = "Script size"

View File

@@ -1,9 +1,15 @@
Console = "Interprete de comandos"
AddScript = "Agregar un archivo"
ScriptOptions = "Opciones del archivo"
ExecuteScript = "Ejecutar el archivo"
AllowedCharactersaz09 = "Caracteres permitidos : a-z, 0-9, _"
Autocomplete = "Autocompleción"
AutoImportScript = "Importación auto en intérprete"
BuiltinsAndKeywords = "Funciones nativas y palabras clave"
Console = "Interprete de comandos"
DeleteScript = "Eliminar el archivo"
DuplicateScript = "Duplicar el guión"
ExecuteScript = "Ejecutar el archivo"
FunctionsAndVariables = "Funciones y variables"
AllowedCharactersaz09 = "Caracteres permitidos : a-z, 0-9, _"
ImportedModulesAndScripts = "Módulos y archivos importados"
NoWordAvailableHere = "No hay ninguna palabra disponible aquí."
ScriptInProgress = "Archivo en curso"
ScriptOptions = "Opciones del archivo"
ScriptSize = "Script size"

View File

@@ -1,9 +1,15 @@
Console = "Console d'exécution"
AddScript = "Ajouter un script"
ScriptOptions = "Options de script"
ExecuteScript = "Exécuter le script"
AllowedCharactersaz09 = "Caractères autorisés : a-z, 0-9, _"
Autocomplete = "Auto-complétion"
AutoImportScript = "Importation auto dans la console"
BuiltinsAndKeywords = "Fonctions natives et mots-clés"
Console = "Console d'exécution"
DeleteScript = "Supprimer le script"
DuplicateScript = "Dupliquer le script"
ExecuteScript = "Exécuter le script"
FunctionsAndVariables = "Fonctions et variables"
AllowedCharactersaz09 = "Caractères autorisés : a-z, 0-9, _"
ImportedModulesAndScripts = "Modules et scripts importés"
NoWordAvailableHere = "Aucun mot disponible à cet endroit."
ScriptInProgress = "Script en cours"
ScriptOptions = "Options de script"
ScriptSize = "Script size"

View File

@@ -1,9 +1,15 @@
Console = "Konzol"
AddScript = "Script hozzadáadása"
ScriptOptions = "Script beállítások"
ExecuteScript = "Script indítása"
AllowedCharactersaz09 = "Engedélyezett karakterek: a-z, 0-9, _"
Autocomplete = "Autocomplete"
AutoImportScript = "Script automata importálása"
BuiltinsAndKeywords = "Builtins and keywords"
Console = "Konzol"
DeleteScript = "Script törlése"
DuplicateScript = "Script másolása"
ExecuteScript = "Script indítása"
FunctionsAndVariables = "Függvények és változók"
AllowedCharactersaz09 = "Engedélyezett karakterek: a-z, 0-9, _"
ImportedModulesAndScripts = "Imported modules and scripts"
NoWordAvailableHere = "No word available here."
ScriptInProgress = "Script in progress"
ScriptOptions = "Script beállítások"
ScriptSize = "Script size"

15
apps/code/base.it.i18n Normal file
View File

@@ -0,0 +1,15 @@
AddScript = "Aggiungere script"
AllowedCharactersaz09 = "Caratteri consentiti : a-z, 0-9, _"
Autocomplete = "Autocompletamento"
AutoImportScript = "Auto importazione nella console"
BuiltinsAndKeywords = "Funzioni native e parole chiave"
Console = "Console d'esecuzione"
DeleteScript = "Eliminare lo script"
DuplicateScript = "Duplicate script"
ExecuteScript = "Eseguire lo script"
FunctionsAndVariables = "Funzioni e variabili"
ImportedModulesAndScripts = "Moduli e scripts importati"
NoWordAvailableHere = "Nessuna parola disponibile qui."
ScriptInProgress = "Script in corso"
ScriptOptions = "Opzioni dello script"
ScriptSize = "Script Size"

15
apps/code/base.nl.i18n Normal file
View File

@@ -0,0 +1,15 @@
AddScript = "Script toevoegen"
AllowedCharactersaz09 = "Toegestane tekens: a-z, 0-9, _"
Autocomplete = "Autocomplete"
AutoImportScript = "Automatisch importeren in shell"
BuiltinsAndKeywords = "Builtins and keywords"
Console = "Python shell"
DeleteScript = "Script verwijderen"
DuplicateScript = "Duplicate script"
ExecuteScript = "Script uitvoeren"
FunctionsAndVariables = "Functies en variabelen"
ImportedModulesAndScripts = "Imported modules and scripts"
NoWordAvailableHere = "No word available here."
ScriptInProgress = "Script in progress"
ScriptOptions = "Script opties"
ScriptSize = "Script Size"

View File

@@ -1,9 +1,15 @@
Console = "Interpretador interativo"
AddScript = "Adicionar um script"
ScriptOptions = "Opções de script"
ExecuteScript = "Executar o script"
AllowedCharactersaz09 = "Caracteres permitidos : a-z, 0-9, _"
Autocomplete = "Preenchimento automático"
AutoImportScript = "Importação auto no interpretador"
BuiltinsAndKeywords = "Funções nativas e palavras-chave"
Console = "Interpretador interativo"
DeleteScript = "Eliminar o script"
DuplicateScript = "Duplicar o script"
ExecuteScript = "Executar o script"
FunctionsAndVariables = "Funções e variáveis"
AllowedCharactersaz09 = "Caracteres permitidos : a-z, 0-9, _"
ImportedModulesAndScripts = "Módulos e scripts importados"
NoWordAvailableHere = "Nenhuma palavra disponível aqui."
ScriptInProgress = "Script em curso"
ScriptOptions = "Opções de script"
ScriptSize = "Script Size"

View File

@@ -26,7 +26,18 @@ PythonCeil = "Aufrundung"
PythonChoice = "Zufallszahl aus der Liste"
PythonClear = "Leere die Liste"
PythonCmathFunction = "cmath-Modul-Funktionspräfix"
PythonColor = "Definiert eine RGB-Farbe"
PythonColor = "Definiere eine RGB-Farbe"
PythonColorBlack = "Black color"
PythonColorBlue = "Blue color"
PythonColorBrown = "Brown color"
PythonColorGreen = "Green color"
PythonColorGrey = "Grey color"
PythonColorOrange = "Orange color"
PythonColorPink = "Pink color"
PythonColorPurple = "Purple color"
PythonColorRed = "Red color"
PythonColorWhite = "White color"
PythonColorYellow = "Yellow color"
PythonComplex = "a+ib zurückgeben"
PythonCopySign = "x mit dem Vorzeichen von y"
PythonCos = "Kosinus"
@@ -45,10 +56,10 @@ PythonFillRect = "Malt ein Rechteck bei Pixel (x,y)"
PythonFloat = "Wandelt x zu float um"
PythonFloor = "Floor"
PythonFmod = "a modulo b"
PythonFrExp = "Rest und Exponent von x"
PythonGamma = "Gammafunktion"
PythonGetPixel = "Farbe von Pixel (x,y)"
PythonGetrandbits = "Ganzzahl mit k zufälligen Bits"
PythonFrExp = "Mantissa and exponent of x: (m,e)"
PythonGamma = "Gamma function"
PythonGetPixel = "Return pixel (x,y) color"
PythonGetrandbits = "Integer with k random bits"
PythonGrid = "Toggle the visibility of the grid"
PythonHex = "Ganzzahl zu Hexadecimal"
PythonHist = "Draw the histogram of x"
@@ -58,6 +69,11 @@ PythonImportKandinsky = "kandinsky Modul importieren"
PythonImportRandom = "random Modul importieren"
PythonImportMath = "math Modul importieren"
PythonImportMatplotlibPyplot = "Import matplotlib.pyplot module"
PythonImportOs = "os Modul importieren"
PythonOsUname = "Informieren Sie sich über das System"
PythonOsRemove = "Datei namens Dateiname entfernen"
PythonOsRename = "Datei mit altem Namen in neuen Namen umbenennen"
PythonOsListdir = "Dateien im Speicher auflisten"
PythonImportTime = "time Modul importieren"
PythonImportTurtle = "turtle Modul importieren"
PythonIndex = "Index, bei dem x zuerst vorkommt"
@@ -139,10 +155,10 @@ PythonRadians = "Convert x from degrees to radians"
PythonRandint = "Random integer in [a,b]"
PythonRandom = "Floating point number in [0,1["
PythonRandomFunction = "random module function prefix"
PythonRandrange = "Random number in range(start, stop)"
PythonRandrange = "Random number in range(start,stop)"
PythonRangeStartStop = "List from start to stop-1"
PythonRangeStop = "List from 0 to stop-1"
PythonRect = "z in cartesian coordinates"
PythonRect = "Convert to cartesian coordinates"
PythonRemove = "Remove the first occurrence of x"
PythonReverse = "Reverse the elements of the list"
PythonRound = "Round to n digits"
@@ -162,39 +178,45 @@ PythonText = "Display a text at (x,y) coordinates"
PythonTimeFunction = "time module function prefix"
PythonTrunc = "x truncated to an integer"
PythonTurtleBackward = "Move backward by x pixels"
PythonTurtleBlack = "Schwarze Farbe"
PythonTurtleBlue = "Blaue Farbe"
PythonTurtleBrown = "Braune Farbe"
PythonTurtleCircle = "Circle of radius r pixels"
PythonTurtleColor = "Stiftfarbe setzen"
PythonTurtleColorMode = "Set the color mode to 1.0 or 255"
PythonTurtleForward = "Move forward by x pixels"
PythonTurtleFunction = "turtle module function prefix"
PythonTurtleGoto = "Move to (x,y) coordinates"
PythonTurtleGreen = "Grüne Farbe"
PythonTurtleGrey = "Graue Farbe"
PythonTurtleHeading = "Return the current heading"
PythonTurtleHideturtle = "Hide the turtle"
PythonTurtleIsdown = "Return True if the pen is down"
PythonTurtleLeft = "Turn left by a degrees"
PythonTurtleOrange = "Orange color"
PythonTurtlePendown = "Pull the pen down"
PythonTurtlePensize = "Set the line thickness to x pixels"
PythonTurtlePenup = "Pull the pen up"
PythonTurtlePink = "Pinke Farbe"
PythonTurtlePosition = "Return the current (x,y) location"
PythonTurtlePurple = "Purple color"
PythonTurtleRed = "Rote Farbe"
PythonTurtleReset = "Reset the drawing"
PythonTurtleRight = "Turn right by a degrees"
PythonTurtleSetheading = "Set the orientation to a degrees"
PythonTurtleSetposition = "Position des turtles"
PythonTurtleShowturtle = "Die turtle anzeigen"
PythonTurtleSpeed = "Zeichengeschwindigkeit zwischen 0 und 10"
PythonTurtleWhite = "Weiße Farbe"
PythonTurtleYellow = "Gelbe Farbe"
PythonUniform = "Fließkommazahl in [a,b]"
PythonTimeFromImport = "Import time module"
PythonTimeImport = "Import time module"
PythonTurtleSetposition = "Positionne la tortue"
PythonTurtleShowturtle = "Show the turtle"
PythonTurtleSpeed = "Drawing speed between 0 and 10"
PythonTurtleWrite = "Display a text"
PythonUniform = "Floating point number in [a,b]"
PythonImportTime = "Import time module"
PythonTimePrefix = "time module function prefix"
PythonTimeSleep = "Warten Sie n Sekunden lang"
PythonTimeMonotonic = "Monotone Zeit zurückgeben"
PythonTimeSleep = "Wait for n second"
PythonMonotonic = "Return monotonic time"
PythonFileOpen = "Öffnet eine Datei"
PythonFileSeekable = "Ist eine Datei durchsuchbar?"
PythonFileSeek = "Dateicursor verschieben"
PythonFileTell = "Cursorposition der Datei abrufen"
PythonFileClose = "Schließt eine Datei"
PythonFileClosed = "Wenn Datei geschlossen wurde"
PythonFileRead = "Bis zu size Bytes lesen"
PythonFileWrite = "Schreibe b in die Datei"
PythonFileReadline = "Lies eine Zeile"
PythonFileReadlines = "Liest eine Liste von Zeilen"
PythonFileTruncate = "Größe der Datei ändern"
PythonFileWritelines = "Schreibt eine Liste von Zeilen"
PythonFileName = "Dateiname"
PythonFileMode = "Dateiöffnungsmodus"
PythonFileReadable = "Ist die Datei lesbar?"
PythonFileWritable = "Ist die Datei beschreibbar?"

View File

@@ -1,7 +1,7 @@
PythonPound = "Comment"
PythonPercent = "Modulo"
Python1J = "Imaginary i"
PythonLF = "Line feed"
PythonLF = "line feed"
PythonTab = "Tabulation"
PythonAmpersand = "Bitwise and"
PythonSymbolExp = "Bitwise exclusive or"
@@ -27,6 +27,17 @@ PythonChoice = "Random number in the list"
PythonClear = "Empty the list"
PythonCmathFunction = "cmath module function prefix"
PythonColor = "Define a rgb color"
PythonColorBlack = "Black color"
PythonColorBlue = "Blue color"
PythonColorBrown = "Brown color"
PythonColorGreen = "Green color"
PythonColorGrey = "Grey color"
PythonColorOrange = "Orange color"
PythonColorPink = "Pink color"
PythonColorPurple = "Purple color"
PythonColorRed = "Red color"
PythonColorWhite = "White color"
PythonColorYellow = "Yellow color"
PythonComplex = "Return a+ib"
PythonCopySign = "Return x with the sign of y"
PythonCos = "Cosine"
@@ -45,7 +56,7 @@ PythonFillRect = "Fill a rectangle at pixel (x,y)"
PythonFloat = "Convert x to a float"
PythonFloor = "Floor"
PythonFmod = "a modulo b"
PythonFrExp = "Mantissa and exponent of x"
PythonFrExp = "Mantissa and exponent of x: (m,e)"
PythonGamma = "Gamma function"
PythonGetPixel = "Return pixel (x,y) color"
PythonGetrandbits = "Integer with k random bits"
@@ -139,10 +150,10 @@ PythonRadians = "Convert x from degrees to radians"
PythonRandint = "Random integer in [a,b]"
PythonRandom = "Floating point number in [0,1["
PythonRandomFunction = "random module function prefix"
PythonRandrange = "Random number in range(start, stop)"
PythonRandrange = "Random number in range(start,stop)"
PythonRangeStartStop = "List from start to stop-1"
PythonRangeStop = "List from 0 to stop-1"
PythonRect = "z in cartesian coordinates"
PythonRect = "Convert to cartesian coordinates"
PythonRemove = "Remove the first occurrence of x"
PythonReverse = "Reverse the elements of the list"
PythonRound = "Round to n digits"
@@ -162,39 +173,50 @@ PythonText = "Display a text at (x,y) coordinates"
PythonTimeFunction = "time module function prefix"
PythonTrunc = "x truncated to an integer"
PythonTurtleBackward = "Move backward by x pixels"
PythonTurtleBlack = "Black color"
PythonTurtleBlue = "Blue color"
PythonTurtleBrown = "Brown color"
PythonTurtleCircle = "Circle of radius r pixels"
PythonTurtleColor = "Set the pen color"
PythonTurtleColorMode = "Set the color mode to 1.0 or 255"
PythonTurtleForward = "Move forward by x pixels"
PythonTurtleFunction = "turtle module function prefix"
PythonTurtleGoto = "Move to (x,y) coordinates"
PythonTurtleGreen = "Green color"
PythonTurtleGrey = "Grey color"
PythonTurtleHeading = "Return the current heading"
PythonTurtleHideturtle = "Hide the turtle"
PythonTurtleIsdown = "Return True if the pen is down"
PythonTurtleLeft = "Turn left by a degrees"
PythonTurtleOrange = "Orange color"
PythonTurtlePendown = "Pull the pen down"
PythonTurtlePensize = "Set the line thickness to x pixels"
PythonTurtlePenup = "Pull the pen up"
PythonTurtlePink = "Pink color"
PythonTurtlePosition = "Return the current (x,y) location"
PythonTurtlePurple = "Purple color"
PythonTurtleRed = "Red color"
PythonTurtleReset = "Reset the drawing"
PythonTurtleRight = "Turn right by a degrees"
PythonTurtleSetheading = "Set the orientation to a degrees"
PythonTurtleSetposition = "Positionne la tortue"
PythonTurtleShowturtle = "Show the turtle"
PythonTurtleSpeed = "Drawing speed between 0 and 10"
PythonTurtleWhite = "White color"
PythonTurtleYellow = "Yellow color"
PythonTurtleWrite = "Display a text"
PythonUniform = "Floating point number in [a,b]"
PythonTimeFromImport = "Import time module"
PythonTimeImport = "Import time module"
PythonImportTime = "Import time module"
PythonImportOs = "Import os module"
PythonOsUname = "Get infos about the system"
PythonOsRemove = "Remove file named filename"
PythonOsRename = "Rename file oldname to newname"
PythonOsListdir = "List files in memory"
PythonTimePrefix = "time module function prefix"
PythonTimeSleep = "Wait for n second"
PythonTimeMonotonic = "Return monotonic time"
PythonMonotonic = "Return monotonic time"
PythonFileOpen = "Opens a file"
PythonFileSeekable = "Tells if seek can be used on a file"
PythonFileSeek = "Move file's cursor"
PythonFileTell = "Get file's cursor location"
PythonFileClose = "Closes a file"
PythonFileClosed = "True if file was closed"
PythonFileRead = "Read up to size bytes"
PythonFileWrite = "Write b into file"
PythonFileReadline = "Reads a line or up to size bytes"
PythonFileReadlines = "Reads a list of lines"
PythonFileTruncate = "Resize the file to size"
PythonFileWritelines = "Writes a list of lines"
PythonFileName = "Contains file's name"
PythonFileMode = "Contains file's open mode"
PythonFileReadable = "Tells if read can be used on a file"
PythonFileWritable = "Tells if write can be used on a file"

View File

@@ -27,6 +27,17 @@ PythonChoice = "Random number in the list"
PythonClear = "Empty the list"
PythonCmathFunction = "cmath module function prefix"
PythonColor = "Define a rgb color"
PythonColorBlack = "Black color"
PythonColorBlue = "Blue color"
PythonColorBrown = "Brown color"
PythonColorGreen = "Green color"
PythonColorGrey = "Grey color"
PythonColorOrange = "Orange color"
PythonColorPink = "Pink color"
PythonColorPurple = "Purple color"
PythonColorRed = "Red color"
PythonColorWhite = "White color"
PythonColorYellow = "Yellow color"
PythonComplex = "Return a+ib"
PythonCopySign = "Return x with the sign of y"
PythonCos = "Cosine"
@@ -45,7 +56,7 @@ PythonFillRect = "Fill a rectangle at pixel (x,y)"
PythonFloat = "Convert x to a float"
PythonFloor = "Floor"
PythonFmod = "a modulo b"
PythonFrExp = "Mantissa and exponent of x"
PythonFrExp = "Mantissa and exponent of x: (m,e)"
PythonGamma = "Gamma function"
PythonGetPixel = "Return pixel (x,y) color"
PythonGetrandbits = "Integer with k random bits"
@@ -139,10 +150,10 @@ PythonRadians = "Convert x from degrees to radians"
PythonRandint = "Random integer in [a,b]"
PythonRandom = "Floating point number in [0,1["
PythonRandomFunction = "random module function prefix"
PythonRandrange = "Random number in range(start, stop)"
PythonRandrange = "Random number in range(start,stop)"
PythonRangeStartStop = "List from start to stop-1"
PythonRangeStop = "List from 0 to stop-1"
PythonRect = "z in cartesian coordinates"
PythonRect = "Convert to cartesian coordinates"
PythonRemove = "Remove the first occurrence of x"
PythonReverse = "Reverse the elements of the list"
PythonRound = "Round to n digits"
@@ -162,39 +173,50 @@ PythonText = "Display a text at (x,y) coordinates"
PythonTimeFunction = "time module function prefix"
PythonTrunc = "x truncated to an integer"
PythonTurtleBackward = "Move backward by x pixels"
PythonTurtleBlack = "Black color"
PythonTurtleBlue = "Blue color"
PythonTurtleBrown = "Brown color"
PythonTurtleCircle = "Circle of radius r pixels"
PythonTurtleColor = "Set the pen color"
PythonTurtleColorMode = "Set the color mode to 1.0 or 255"
PythonTurtleForward = "Move forward by x pixels"
PythonTurtleFunction = "turtle module function prefix"
PythonTurtleGoto = "Move to (x,y) coordinates"
PythonTurtleGreen = "Green color"
PythonTurtleGrey = "Grey color"
PythonTurtleHeading = "Return the current heading"
PythonTurtleHideturtle = "Hide the turtle"
PythonTurtleIsdown = "Return True if the pen is down"
PythonTurtleLeft = "Turn left by a degrees"
PythonTurtleOrange = "Orange color"
PythonTurtlePendown = "Pull the pen down"
PythonTurtlePensize = "Set the line thickness to x pixels"
PythonTurtlePenup = "Pull the pen up"
PythonTurtlePink = "Pink color"
PythonTurtlePosition = "Return the current (x,y) location"
PythonTurtlePurple = "Purple color"
PythonTurtleRed = "Red color"
PythonTurtleReset = "Reset the drawing"
PythonTurtleRight = "Turn right by a degrees"
PythonTurtleSetheading = "Set the orientation to a degrees"
PythonTurtleSetposition = "Positionne la tortue"
PythonTurtleShowturtle = "Show the turtle"
PythonTurtleSpeed = "Drawing speed between 0 and 10"
PythonTurtleWhite = "White color"
PythonTurtleYellow = "Yellow color"
PythonTurtleWrite = "Display a text"
PythonUniform = "Floating point number in [a,b]"
PythonTimeFromImport = "Import time module"
PythonTimeImport = "Import time module"
PythonImportTime = "Import time module"
PythonImportOs = "Import os module"
PythonOsUname = " Información del sistema "
PythonOsRemove = "Eliminar un archivo"
PythonOsRename = "Renombrar archivo"
PythonOsListdir = "Archivos de la lista"
PythonTimePrefix = "time module function prefix"
PythonTimeSleep = "Esperar n segundos"
PythonTimeMonotonic = "Tiempo monótono de retorno"
PythonMonotonic = "Tiempo monótono de retorno"
PythonFileOpen = "Opens a file"
PythonFileSeekable = "Tells if seek can be used on a file"
PythonFileSeek = "Move file's internal cursor"
PythonFileTell = "Get file's internal cursor location"
PythonFileClose = "Closes a file"
PythonFileClosed = "True if file was closed"
PythonFileRead = "Read up to size bytes"
PythonFileWrite = "Write b into file"
PythonFileReadline = "Reads a line or up to size bytes"
PythonFileReadlines = "Reads a list of lines"
PythonFileTruncate = "Resize the file to size"
PythonFileWritelines = "Writes a list of lines"
PythonFileName = "Contains file's name"
PythonFileMode = "Contains file's open mode"
PythonFileReadable = "Tells if read can be used on a file"
PythonFileWritable = "Tells if write can be used on a file"

View File

@@ -27,6 +27,17 @@ PythonChoice = "Nombre aléatoire dans la liste"
PythonClear = "Vide la liste"
PythonCmathFunction = "Préfixe fonction du module cmath"
PythonColor = "Définit une couleur rvb"
PythonColorBlack = "Couleur noire"
PythonColorBlue = "Couleur bleue"
PythonColorBrown = "Couleur marron"
PythonColorGreen = "Couleur verte"
PythonColorGrey = "Couleur grise"
PythonColorOrange = "Couleur orange"
PythonColorPink = "Couleur rose"
PythonColorPurple = "Couleur violette"
PythonColorRed = "Couleur rouge"
PythonColorWhite = "Couleur blanche"
PythonColorYellow = "Couleur jaune"
PythonComplex = "Renvoie a+ib"
PythonCopySign = "Renvoie x avec le signe de y"
PythonCos = "Cosinus"
@@ -139,7 +150,7 @@ PythonRadians = "Conversion de degrés en radians"
PythonRandint = "Entier aléatoire dans [a,b]"
PythonRandom = "Nombre décimal dans [0,1["
PythonRandomFunction = "Préfixe fonction du module random"
PythonRandrange = "Nombre dans range(start, stop)"
PythonRandrange = "Nombre dans range(start,stop)"
PythonRangeStartStop = "Liste de start à stop-1"
PythonRangeStop = "Liste de 0 à stop-1"
PythonRect = "Conversion en algébrique"
@@ -162,39 +173,50 @@ PythonText = "Affiche un texte en (x,y)"
PythonTimeFunction = "Préfixe fonction module time"
PythonTrunc = "Troncature entière"
PythonTurtleBackward = "Recule de x pixels"
PythonTurtleBlack = "Couleur noire"
PythonTurtleBlue = "Couleur bleue"
PythonTurtleBrown = "Couleur marron"
PythonTurtleCircle = "Cercle de rayon r pixels"
PythonTurtleColor = "Modifie la couleur du tracé"
PythonTurtleColorMode = "Met le mode de couleur à 1.0 ou 255"
PythonTurtleForward = "Avance de x pixels"
PythonTurtleFunction = "Préfixe fonction du module turtle"
PythonTurtleGoto = "Va au point de coordonnées (x,y)"
PythonTurtleGreen = "Couleur verte"
PythonTurtleGrey = "Couleur grise"
PythonTurtleHeading = "Renvoie l'orientation actuelle"
PythonTurtleHideturtle = "Masque la tortue"
PythonTurtleIsdown = "True si le crayon est abaissé"
PythonTurtleLeft = "Pivote de a degrés vers la gauche"
PythonTurtleOrange = "Couleur orange"
PythonTurtlePendown = "Abaisse le crayon"
PythonTurtlePensize = "Taille du tracé en pixels"
PythonTurtlePenup = "Relève le crayon"
PythonTurtlePink = "Couleur rose"
PythonTurtlePosition = "Renvoie la position (x,y)"
PythonTurtlePurple = "Couleur violette"
PythonTurtleRed = "Couleur rouge"
PythonTurtleReset = "Réinitialise le dessin"
PythonTurtleRight = "Pivote de a degrés vers la droite"
PythonTurtleSetheading = "Met un cap de a degrés"
PythonTurtleSetposition = "Positionne la tortue"
PythonTurtleShowturtle = "Affiche la tortue"
PythonTurtleSpeed = "Vitesse du tracé entre 0 et 10"
PythonTurtleWhite = "Couleur blanche"
PythonTurtleYellow = "Couleur jaune"
PythonTurtleWrite = "Affiche un texte"
PythonUniform = "Nombre décimal dans [a,b]"
PythonTimeFromImport = "Importation du module temps"
PythonTimeImport = "Importation du module temps"
PythonImportTime = "Importation du module temps"
PythonImportOs = "Importation du module os"
PythonOsUname = "Donne des infos sur le système"
PythonOsRemove = "Supprime le fichier nommé filename"
PythonOsRename = "Renomme oldname en newname"
PythonOsListdir = "Liste les fichiers"
PythonTimePrefix = "Préfixe fonction du module temps"
PythonTimeSleep = "Attendre n secondes"
PythonTimeMonotonic = "Retourne le temps monotonic"
PythonMonotonic = "Retourne le temps monotonic"
PythonFileOpen = "Ouvre un fichier"
PythonFileSeekable = "Indique si seek peut être utilisé"
PythonFileSeek = "Déplace le curseur interne"
PythonFileTell = "Donne la posititon du curseur"
PythonFileClose = "Ferme un fichier"
PythonFileClosed = "True si le fichier a été fermé"
PythonFileRead = "Lis jusqu'à size bytes"
PythonFileWrite = "Écris b dans le fichier"
PythonFileReadline = "Lis une ligne ou jusqu'à size bytes"
PythonFileReadlines = "Lis une liste de lignes"
PythonFileTruncate = "Redimensionne le fichier"
PythonFileWritelines = "Écris une liste de lignes"
PythonFileName = "Nom du fichier"
PythonFileMode = "Mode d'ouverture du fichier"
PythonFileReadable = "Indique si read peut être utilisé"
PythonFileWritable = "Indique si write peut être utilisé"

View File

@@ -27,6 +27,17 @@ PythonChoice = "Véletlenszerü szám a listában"
PythonClear = "A lista ürítése"
PythonCmathFunction = "cmath modul funkció elötag"
PythonColor = "Rgb szín meghatározása"
PythonColorBlack = "Fekete szín"
PythonColorBlue = "Kék szín"
PythonColorBrown = "Barna szín"
PythonColorGreen = "Zöld szín"
PythonColorGrey = "Szürke szín"
PythonColorOrange = "Narancssárga szín"
PythonColorPink = "Rózsaszín szín"
PythonColorPurple = "Lila szín"
PythonColorRed = "Piros szín"
PythonColorWhite = "White color"
PythonColorYellow = "Sárga szín"
PythonComplex = "A + ib visszaadása"
PythonCopySign = "Visszatérés x-val y jelével"
PythonCos = "Koszinusz"
@@ -59,6 +70,11 @@ PythonImportRandom = "Véletlenszerü modul importálása"
PythonImportMath = "Import matematikai modul"
PythonImportMatplotlibPyplot = "Import matplotlib.pyplot module"
PythonImportTime = "Idömodul importálása"
PythonImportOs = "Os modul importálása"
PythonOsUname = "Információ a rendszerről"
PythonOsRemove = "Fájl eltávolítása"
PythonOsRename = "Fájl átnevezése"
PythonOsListdir = "Fájlok listázása"
PythonImportTurtle = "Import teknös modul"
PythonIndex = "Az elsö x esemény indexe"
PythonInput = "Érték kérése"
@@ -162,39 +178,45 @@ PythonText = "Display a text at (x,y) coordinates"
PythonTimeFunction = "idömodul funkció elötag"
PythonTrunc = "x egészre csonkítva"
PythonTurtleBackward = "Visszalépés x pixelrel"
PythonTurtleBlack = "Fekete szín"
PythonTurtleBlue = "Kék szín"
PythonTurtleBrown = "Barna szín"
PythonTurtleCircle = "r pixel sugarú kör"
PythonTurtleColor = "Állítsa be az toll színét"
PythonTurtleColorMode = "Set the color mode to 1.0 or 255"
PythonTurtleForward = "Ugrás x pixelrel"
PythonTurtleFunction = "teknös modul funkció elötag"
PythonTurtleGoto = "Mozgatás (x, y) koordinátákra"
PythonTurtleGreen = "Zöld szín"
PythonTurtleGrey = "Szürke szín"
PythonTurtleHeading = "Visszaadja az aktuális címsort"
PythonTurtleHideturtle = "A teknös elrejtése"
PythonTurtleIsdown = "Visszatérés igazhoz, ha az toll lefelé"
PythonTurtleLeft = "Forduljon fokkal balra"
PythonTurtleOrange = "Narancssárga szín"
PythonTurtlePendown = "Húzza le a tollat"
PythonTurtlePensize = "Állítsa a vonalvastagságot x pixelre"
PythonTurtlePenup = "Húzza fel a tollat"
PythonTurtlePink = "Rózsaszín szín"
PythonTurtlePosition = "Az aktuális (x, y) hely visszaadása"
PythonTurtlePurple = "Lila szín"
PythonTurtleRed = "Piros szín"
PythonTurtleReset = "A rajz visszaállítása"
PythonTurtleRight = "Forduljon fokkal jobbra"
PythonTurtleSetheading = "Állítsa be a tájolást fokokra"
PythonTurtleSetposition = "A helymeghatározás"
PythonTurtleShowturtle = "Mutasd a teknösöt"
PythonTurtleSpeed = "Rajzolási sebesség 0 és 10 között"
PythonTurtleWhite = "Fehér szín"
PythonTurtleYellow = "Sárga szín"
PythonTurtleWrite = "Display a text"
PythonUniform = "Lebegöpontos szám [a, b] -ben"
PythonTimeFromImport = "Idömodul importálása"
PythonTimeImport = "Idömodul importálása"
PythonImportTime = "Idömodul importálása"
PythonTimePrefix = "idömodul funkció elötag"
PythonTimeSleep = "Várj n másodpercet"
PythonTimeMonotonic = "Vissza a monoton idö"
PythonMonotonic = "Vissza a monoton idö"
PythonFileOpen = "Fájl megnyitása"
PythonFileSeekable = "A fájl kereshető?"
PythonFileSeek = "A fájl kurzorának áthelyezése"
PythonFileTell = "A fájl kurzorának helye"
PythonFileClose = "Bezár egy fájlt"
PythonFileClosed = "Igaz, ha a fájl bezárt"
PythonFileRead = "Olvasson méretbájtig"
PythonFileWrite = "B beírása fájlba"
PythonFileReadline = "Olvas egy sort"
PythonFileReadlines = "Olvassa a sorok listáját"
PythonFileTruncate = "A fájl átméretezése méretre"
PythonFileWritelines = "Sorok listáját írja"
PythonFileName = "a fájl neve"
PythonFileMode = "a fájl nyitott módja"
PythonFileReadable = "A fájl olvasható?"
PythonFileWritable = "A fájl írható?"

222
apps/code/catalog.it.i18n Normal file
View File

@@ -0,0 +1,222 @@
PythonPound = "Commento"
PythonPercent = "Modulo"
Python1J = "Unità immaginaria"
PythonLF = "Nuova riga"
PythonTab = "Tabulazione"
PythonAmpersand = "Congiunzione"
PythonSymbolExp = "Disgiunzione esclusiva"
PythonVerticalBar = "Disgiunzione"
PythonImag = "Parte immaginaria di z"
PythonReal = "Parte reale di z"
PythonSingleQuote = "Apostrofo"
PythonAbs = "Valore assoluto/Modulo"
PythonAcos = "Coseno d'arco"
PythonAcosh = "Coseno iperbolico inverso"
PythonAppend = "Inserisce x alla fine della lista"
PythonArrow = "Freccia da (x,y) a (x+dx,y+dy)"
PythonAsin = "Arco sinusoidale"
PythonAsinh = "Arco sinusoidale iperbolico"
PythonAtan = "Arco tangente"
PythonAtan2 = "Calcolo di atan(y/x)"
PythonAtanh = "Arco tangente iperbolico"
PythonAxis = "Imposta assi (xmin,xmax,ymin,ymax)"
PythonBar = "Grafico a barre con x valori"
PythonBin = "Converte un intero in binario"
PythonCeil = "Parte intera superiore"
PythonChoice = "Numero aleatorio nella lista"
PythonClear = "Svuota la lista"
PythonCmathFunction = "Funz. prefissata modulo cmath"
PythonColor = "Definisci un colore rvb"
PythonColorBlack = "Colore nero"
PythonColorBlue = "Colore blu"
PythonColorBrown = "Colore marrone"
PythonColorGreen = "Colore verde"
PythonColorGrey = "Colore grigio"
PythonColorOrange = "Colore arancione"
PythonColorPink = "Colore rosa"
PythonColorPurple = "Colore viola"
PythonColorRed = "Colore rosso"
PythonColorWhite = "Colore bianco"
PythonColorYellow = "Colore giallo"
PythonComplex = "Restituisce a+ib"
PythonCopySign = "Restituisce x con segno di y"
PythonCos = "Coseno"
PythonCosh = "Coseno iperbolico"
PythonCount = "Conta le ricorrenze di x"
PythonDegrees = "Conversione di radianti in gradi"
PythonDivMod = "Quoziente e resto"
PythonDrawString = "Visualizza il testo dal pixel x,y"
PythonErf = "Funzione d'errore"
PythonErfc = "Funzione d'errore complementare"
PythonEval = "Valuta l'espressione nell'argomento "
PythonExp = "Funzione esponenziale"
PythonExpm1 = "Calcola exp(x)-1"
PythonFabs = "Valore assoluto"
PythonFillRect = "Riempie un rettangolo"
PythonFloat = "Conversione in flottanti"
PythonFloor = "Parte intera"
PythonFmod = "a modulo b"
PythonFrExp = "Mantissa ed esponente di x : (m,e)"
PythonGamma = "Funzione gamma"
PythonGetPixel = "Restituisce colore del pixel(x,y)"
PythonGetrandbits = "Numero aleatorio con k bit"
PythonGrid = "Attiva la visibilità della griglia"
PythonHex = "Conversione intero in esadecimale"
PythonHist = "Disegna l'istogramma di x"
PythonImportCmath = "Importa modulo cmath"
PythonImportIon = "Importa modulo ion"
PythonImportKandinsky = "Importa modulo kandinsky"
PythonImportRandom = "Importa modulo random"
PythonImportMath = "Importa modulo math"
PythonImportMatplotlibPyplot = "Importa modulo matplotlib.pyplot"
PythonImportTurtle = "Importa del modulo turtle"
PythonImportTime = "Importa del modulo time"
PythonImportOs = "Importa modulo os"
PythonOsUname = "Ottieni informazioni sul sistema"
PythonOsRemove = "Rimuovere un file"
PythonOsRename = "Rinomina file"
PythonOsListdir = "Elenca file"
PythonIndex = "Indice prima occorrenza di x"
PythonInput = "Inserire un valore"
PythonInsert = "Inserire x in posizione i-esima"
PythonInt = "Conversione in intero"
PythonIonFunction = "Prefisso di funzione modulo ion"
PythonIsFinite = "Testa se x è finito"
PythonIsInfinite = "Testa se x est infinito"
PythonIsKeyDown = "Restituisce True premendo tasto k"
PythonIsNaN = "Testa se x è NaN"
PythonKandinskyFunction = "Prefisso funzione modulo kandinsky"
PythonKeyLeft = "Tasto FRECCIA SINISTRA"
PythonKeyUp = "Tasto FRECCIA ALTO"
PythonKeyDown = "Tasto FRECCIA BASSO"
PythonKeyRight = "Tasto FRECCIA DESTRA"
PythonKeyOk = "Tasto OK"
PythonKeyBack = "Tasto INDIETRO"
PythonKeyHome = "Tasto CASA"
PythonKeyOnOff = "Tasto ON/OFF"
PythonKeyShift = "Tasto SHIFT"
PythonKeyAlpha = "Tasto ALPHA"
PythonKeyXnt = "Tasto X,N,T"
PythonKeyVar = "Tasto VAR"
PythonKeyToolbox = "Tasto TOOLBOX"
PythonKeyBackspace = "Tasto CANCELLA"
PythonKeyExp = "Tasto ESPONENZIALE"
PythonKeyLn = "Tasto LOGARITMO NEPERIANO"
PythonKeyLog = "Tasto LOGARITMO DECIMALE"
PythonKeyImaginary = "Tasto I IMMAGINE"
PythonKeyComma = "Tasto VIRGOLA"
PythonKeyPower = "Tasto POTENZA"
PythonKeySine = "Tasto SENO"
PythonKeyCosine = "Tasto COSENO"
PythonKeyTangent = "Tasto TANGENTE"
PythonKeyPi = "Tasto PI"
PythonKeySqrt = "Tasto RADICE QUADRATA"
PythonKeySquare = "Tasto QUADRATO"
PythonKeySeven = "Tasto 7"
PythonKeyEight = "Tasto 8"
PythonKeyNine = "Tasto 9"
PythonKeyLeftParenthesis = "Tasto PARENTESI SINISTRA"
PythonKeyRightParenthesis = "Tasto PARENTESI DESTRA"
PythonKeyFour = "Tasto 4"
PythonKeyFive = "Tasto 5"
PythonKeySix = "Tasto 6"
PythonKeyMultiplication = "Tasto MOLTIPLICAZIONE"
PythonKeyDivision = "Tasto DIVISIONE"
PythonKeyOne = "Tasto 1"
PythonKeyTwo = "Tasto 2"
PythonKeyThree = "Tasto 3"
PythonKeyPlus = "Tasto PIÙ"
PythonKeyMinus = "Tasto MENO"
PythonKeyZero = "Tasto 0"
PythonKeyDot = "Tasto PUNTO"
PythonKeyEe = "Tasto 10 POTENZA X"
PythonKeyAns = "Tasto ANS"
PythonKeyExe = "Tasto EXE"
PythonLdexp = "Inversa di frexp : x*(2**i)"
PythonLength = "Longhezza di un oggetto"
PythonLgamma = "Logaritmo della funzione gamma"
PythonLog = "Logaritmo di base a"
PythonLog10 = "Logaritmo decimale"
PythonLog2 = "Logaritmo di base 2"
PythonMathFunction = "Prefisso funzione del modulo math"
PythonMatplotlibPyplotFunction = "Prefisso modulo matplotlib.pyplot"
PythonMax = "Massimo"
PythonMin = "Minimo"
PythonModf = "Parti frazionarie e intere"
PythonMonotonic = "Restituisce il valore dell'orologio"
PythonOct = "Conversione in ottale"
PythonPhase = "Argomento di z"
PythonPlot = "Disegna y in f. di x come linee"
PythonPolar = "Conversione in polare"
PythonPop = "Cancella l'ultimo elemento"
PythonPower = "x alla potenza y"
PythonPrint = "Visualizza l'oggetto"
PythonRadians = "Conversione da gradi a radianti"
PythonRandint = "Intero aleatorio in [a,b]"
PythonRandom = "Numero aleatorio in [0,1["
PythonRandomFunction = "Prefisso funzione modulo casuale"
PythonRandrange = "Numero dentro il range(start, stop)"
PythonRangeStartStop = "Lista da start a stop-1"
PythonRangeStop = "Lista da 0 a stop-1"
PythonRect = "Converte in coordinate algebriche"
PythonRemove = "Cancella la prima x dalla lista"
PythonReverse = "Inverte gli elementi della lista"
PythonRound = "Arrotondato a n cifre decimali"
PythonScatter = "Diagramma dispersione y in f. di x"
PythonSeed = "Inizializza il generatore random"
PythonSetPixel = "Colora il pixel (x,y)"
PythonShow = "Mostra la figura"
PythonSin = "Seno"
PythonSinh = "Seno iperbolico"
PythonSleep = "Sospende l'esecuzione t secondi"
PythonSort = "Ordina l'elenco"
PythonSqrt = "Radice quadrata"
PythonSum = "Somma degli elementi della lista"
PythonTan = "Tangente"
PythonTanh = "Tangente iperbolica"
PythonText = "Mostra un testo in (x,y)"
PythonTimeFunction = "Prefisso funzione modulo time"
PythonTrunc = "Troncamento intero"
PythonTurtleBackward = "Indietreggia di x pixels"
PythonTurtleCircle = "Cerchio di raggio r pixel"
PythonTurtleColor = "Modifica il colore del tratto"
PythonTurtleColorMode = "Imposta modalità colore a 1.0 o 255"
PythonTurtleForward = "Avanza di x pixel"
PythonTurtleFunction = "Prefisso funzione modello turtle"
PythonTurtleGoto = "Spostati alle coordinate (x,y)"
PythonTurtleHeading = "Restituisce l'orientamento attuale"
PythonTurtleHideturtle = "Nascondi la tartaruga"
PythonTurtleIsdown = "True se la penna è abbassata"
PythonTurtleLeft = "Ruota di a gradi a sinistra"
PythonTurtlePendown = "Abbassa la penna"
PythonTurtlePensize = "Dimensione del tratto in pixel"
PythonTurtlePenup = "Solleva la penna"
PythonTurtlePosition = "Fornisce posizione corrente (x,y)"
PythonTurtleReset = "Azzera il disegno"
PythonTurtleRight = "Ruota di a gradi a destra"
PythonTurtleSetheading = "Imposta l'orientamento per a gradi"
PythonTurtleSetposition = "Posiziona la tartaruga"
PythonTurtleShowturtle = "Mostra la tartaruga"
PythonTurtleSpeed = "Velocità di disegno (x tra 0 e 10)"
PythonTurtleWrite = "Mostra un testo"
PythonUniform = "Numero decimale tra [a,b]"
PythonImportTime = "Import time module"
PythonTimePrefix = "time module function prefix"
PythonTimeSleep = "Wait for n second"
PythonMonotonic = "Return monotonic time"
PythonFileOpen = "Opens a file"
PythonFileSeekable = "Tells if seek can be used on a file"
PythonFileSeek = "Move file's cursor"
PythonFileTell = "Get file's cursor location"
PythonFileClose = "Closes a file"
PythonFileClosed = "True if file was closed"
PythonFileRead = "Read up to size bytes"
PythonFileWrite = "Write b into file"
PythonFileReadline = "Reads a line or up to size bytes"
PythonFileReadlines = "Reads a list of lines"
PythonFileTruncate = "Resize the file to size"
PythonFileWritelines = "Writes a list of lines"
PythonFileName = "Contains file's name"
PythonFileMode = "Contains file's open mode"
PythonFileReadable = "Tells if read can be used on a file"
PythonFileWritable = "Tells if write can be used on a file"

222
apps/code/catalog.nl.i18n Normal file
View File

@@ -0,0 +1,222 @@
PythonPound = "Opmerkingen"
PythonPercent = "Modulo"
Python1J = "Imaginaire i"
PythonLF = "Nieuwe regel"
PythonTab = "Tabulatie"
PythonAmpersand = "Bitsgewijze en"
PythonSymbolExp = "Bitsgewijze exclusieve of"
PythonVerticalBar = "Bitsgewijze of"
PythonImag = "Imaginair deel van z"
PythonReal = "Reëel deel van z"
PythonSingleQuote = "Enkele aanhalingstekens"
PythonAbs = "Absolute waarde"
PythonAcos = "Arccosinus"
PythonAcosh = "Arccosinus hyperbolicus"
PythonAppend = "Voeg x toe aan het eind van je lijst"
PythonArrow = "Arrow from (x,y) to (x+dx,y+dy)"
PythonAsin = "Arcsinus"
PythonAsinh = "Arcsinus hyperbolicus"
PythonAtan = "Arctangens"
PythonAtan2 = "Geeft atan(y/x)"
PythonAtanh = "Arctangens hyperbolicus"
PythonAxis = "Set the axes to (xmin,xmax,ymin,ymax)"
PythonBar = "Draw a bar plot with x values"
PythonBin = "Zet integer om in een binair getal"
PythonCeil = "Plafond"
PythonChoice = "Geeft willek. getal van de lijst"
PythonClear = "Lijst leegmaken"
PythonCmathFunction = "cmath module voorvoegsel"
PythonColor = "Definieer een rgb kleur"
PythonColorBlack = "Zwarte kleur"
PythonColorBlue = "Blauwe kleur"
PythonColorBrown = "Bruine kleur"
PythonColorGreen = "Groene kleur"
PythonColorGrey = "Grijze kleur"
PythonColorOrange = "Oranje kleur"
PythonColorPink = "Roze kleur"
PythonColorPurple = "Paarse kleur"
PythonColorRed = "Rode kleur"
PythonColorWhite = "Witte kleur"
PythonColorYellow = "Gele kleur"
PythonComplex = "Geeft a+ib"
PythonCopySign = "Geeft x met het teken van y"
PythonCos = "Cosinus"
PythonCosh = "Cosinus hyperbolicus"
PythonCount = "Tel voorkomen van x"
PythonDegrees = "Zet x om van radialen naar graden"
PythonDivMod = "Quotiënt en rest"
PythonDrawString = "Geef een tekst weer van pixel (x,y)"
PythonErf = "Error functie"
PythonErfc = "Complementaire error functie"
PythonEval = "Geef de geëvalueerde uitdrukking"
PythonExp = "Exponentiële functie"
PythonExpm1 = "Bereken exp(x)-1"
PythonFabs = "Absolute waarde"
PythonFillRect = "Vul een rechthoek bij pixel (x,y)"
PythonFloat = "Zet x om in een float"
PythonFloor = "Vloer"
PythonFmod = "a modulo b"
PythonFrExp = "Mantisse en exponent van x: (m,e)"
PythonGamma = "Gammafunctie"
PythonGetPixel = "Geef pixel (x,y) kleur (rgb)"
PythonGetrandbits = "Integer met k willekeurige bits"
PythonGrid = "Toggle the visibility of the grid"
PythonHex = "Zet integer om in hexadecimaal"
PythonHist = "Draw the histogram of x"
PythonImportCmath = "Importeer cmath module"
PythonImportIon = "Importeer ion module"
PythonImportKandinsky = "Importeer kandinsky module"
PythonImportRandom = "Importeer random module"
PythonImportMath = "Importeer math module"
PythonImportMatplotlibPyplot = "Import matplotlib.pyplot module"
PythonImportTime = "Importeer time module"
PythonImportOs = "Importeer os module"
PythonOsUname = " Krijg systeeminfo"
PythonOsRemove = "Een bestand verwijderen"
PythonOsRename = "Hernoem bestand"
PythonOsListdir = "Lijstbestanden"
PythonImportTurtle = "Importeer turtle module"
PythonIndex = "Index van de eerste x aanwezigheden"
PythonInput = "Wijs een waarde toe"
PythonInsert = "Voeg x toe aan index i in de lijst"
PythonInt = "Zet x om in een integer"
PythonIonFunction = "ion module voorvoegsel"
PythonIsFinite = "Controleer of x eindig is"
PythonIsInfinite = "Controleer of x oneindig is"
PythonIsKeyDown = "Geef True als k toets omlaag is"
PythonIsNaN = "Controleer of x geen nummer is"
PythonKandinskyFunction = "kandinsky module voorvoegsel"
PythonKeyLeft = "PIJL NAAR LINKS toets"
PythonKeyUp = "PIJL OMHOOG toets"
PythonKeyDown = "PIJL OMLAAG toets"
PythonKeyRight = "PIJL NAAR RECHTS toets"
PythonKeyOk = "OK toets"
PythonKeyBack = "TERUG toets"
PythonKeyHome = "HOME toets"
PythonKeyOnOff = "AAN/UIT toets"
PythonKeyShift = "SHIFT toets"
PythonKeyAlpha = "ALPHA toets"
PythonKeyXnt = "X,N,T toets"
PythonKeyVar = "VAR toets"
PythonKeyToolbox = "TOOLBOX toets"
PythonKeyBackspace = "BACKSPACE toets"
PythonKeyExp = "EXPONENTIEEL toets"
PythonKeyLn = "NATUURLIJKE LOGARITME toets"
PythonKeyLog = "BRIGGSE LOGARITME toets"
PythonKeyImaginary = "IMAGINAIRE I toets"
PythonKeyComma = "KOMMA toets"
PythonKeyPower = "MACHT toets"
PythonKeySine = "SINUS toets"
PythonKeyCosine = "COSINUS toets"
PythonKeyTangent = "TANGENS toets"
PythonKeyPi = "PI toets"
PythonKeySqrt = "VIERKANTSWORTEL toets"
PythonKeySquare = "KWADRAAT toets"
PythonKeySeven = "7 toets"
PythonKeyEight = "8 toets"
PythonKeyNine = "9 toets"
PythonKeyLeftParenthesis = "HAAKJE OPENEN toets"
PythonKeyRightParenthesis = "HAAKJE SLUITEN toets"
PythonKeyFour = "4 toets"
PythonKeyFive = "5 toets"
PythonKeySix = "6 toets"
PythonKeyMultiplication = "VERMENIGVULDIGEN toets"
PythonKeyDivision = "DELEN toets"
PythonKeyOne = "1 toets"
PythonKeyTwo = "2 toets"
PythonKeyThree = "3 toets"
PythonKeyPlus = "PLUS toets"
PythonKeyMinus = "MIN toets"
PythonKeyZero = "0 toets"
PythonKeyDot = "PUNT toets"
PythonKeyEe = "10 TOT DE MACHT X toets"
PythonKeyAns = "ANS toets"
PythonKeyExe = "EXE toets"
PythonLdexp = "Geeft x*(2**i), inversie van frexp"
PythonLength = "Lengte van een object"
PythonLgamma = "Log-gammafunctie"
PythonLog = "Logaritme met grondgetal a"
PythonLog10 = "Logaritme met grondgetal 10"
PythonLog2 = "Logaritme met grondgetal 2"
PythonMathFunction = "math module voorvoegsel"
PythonMatplotlibPyplotFunction = "matplotlib.pyplot module prefix"
PythonMax = "Maximum"
PythonMin = "Minimum"
PythonModf = "Fractionele en gehele delen van x"
PythonMonotonic = "Waarde van een monotone klok"
PythonOct = "Integer omzetten naar octaal"
PythonPhase = "Fase van z in radialen"
PythonPlot = "Plot y versus x as lines"
PythonPolar = "z in poolcoördinaten"
PythonPop = "Verwijder en breng het laatste item terug"
PythonPower = "x tot de macht y"
PythonPrint = "Print object"
PythonRadians = "Zet x om van graden naar radialen"
PythonRandint = "Geeft willek. integer in [a,b]"
PythonRandom = "Een willekeurig getal in [0,1["
PythonRandomFunction = "random module voorvoegsel"
PythonRandrange = "Willek. getal in range(start, stop)"
PythonRangeStartStop = "Lijst van start tot stop-1"
PythonRangeStop = "Lijst van 0 tot stop-1"
PythonRect = "z in cartesiaanse coördinaten"
PythonRemove = "Verwijder het eerste voorkomen van x"
PythonReverse = "Keer de elementen van de lijst om"
PythonRound = "Rond af op n cijfers"
PythonScatter = "Draw a scatter plot of y versus x"
PythonSeed = "Start willek. getallengenerator"
PythonSetPixel = "Kleur pixel (x,y)"
PythonShow = "Display the figure"
PythonSin= "Sinus"
PythonSinh = "Sinus hyperbolicus"
PythonSleep = "Stel executie voor t seconden uit"
PythonSort = "Sorteer de lijst"
PythonSqrt = "Vierkantswortel"
PythonSum = "Sommeer de items van een lijst"
PythonTan = "Tangens"
PythonTanh = "Tangens hyperbolicus"
PythonText = "Display a text at (x,y) coordinates"
PythonTimeFunction = "time module voorvoegsel"
PythonTrunc = "x afgeknot tot een integer"
PythonTurtleBackward = "Ga achterwaarts met x pixels"
PythonTurtleCircle = "Cirkel van straal r pixels"
PythonTurtleColor = "Stel de kleur van de pen in"
PythonTurtleColorMode = "Stel de kleurmodus in op 1.0 of 255"
PythonTurtleForward = "Ga voorwaarts met x pixels"
PythonTurtleFunction = "turtle module voorvoegsel"
PythonTurtleGoto = "Verplaats naar (x,y) coordinaten"
PythonTurtleHeading = "Ga terug naar de huidige koers"
PythonTurtleHideturtle = "Verberg de schildpad"
PythonTurtleIsdown = "Geeft True als pen naar beneden is"
PythonTurtleLeft = "Ga linksaf met a graden"
PythonTurtlePendown = "Zet de pen naar beneden"
PythonTurtlePensize = "Stel de lijndikte in op x pixels"
PythonTurtlePenup = "Zet de pen omhoog"
PythonTurtlePosition = "Zet huidige (x,y) locatie terug"
PythonTurtleReset = "Reset de tekening"
PythonTurtleRight = "Ga rechtsaf met a graden"
PythonTurtleSetheading = "Zet de oriëntatie op a graden"
PythonTurtleSetposition = "Plaats de schildpad"
PythonTurtleShowturtle = "Laat de schildpad zien"
PythonTurtleSpeed = "Tekensnelheid tussen 0 and 10"
PythonTurtleWrite = "Display a text"
PythonUniform = "Zwevendekommagetal in [a,b]"
PythonImportTime = "Import time module"
PythonTimePrefix = "time module function prefix"
PythonTimeSleep = "Wait for n second"
PythonMonotonic = "Return monotonic time"
PythonFileOpen = "Opens a file"
PythonFileSeekable = "Tells if seek can be used on a file"
PythonFileSeek = "Move file's cursor"
PythonFileTell = "Get file's cursor location"
PythonFileClose = "Closes a file"
PythonFileClosed = "True if file was closed"
PythonFileRead = "Read up to size bytes"
PythonFileWrite = "Write b into file"
PythonFileReadline = "Reads a line or up to size bytes"
PythonFileReadlines = "Reads a list of lines"
PythonFileTruncate = "Resize the file to size"
PythonFileWritelines = "Writes a list of lines"
PythonFileName = "Contains file's name"
PythonFileMode = "Contains file's open mode"
PythonFileReadable = "Tells if read can be used on a file"
PythonFileWritable = "Tells if write can be used on a file"

View File

@@ -1,200 +1,222 @@
PythonPound = "Comment"
PythonPercent = "Modulo"
Python1J = "Imaginary i"
PythonLF = "Line feed"
PythonTab = "Tabulation"
PythonAmpersand = "Bitwise and"
PythonSymbolExp = "Bitwise exclusive or"
PythonVerticalBar = "Bitwise or"
PythonSingleQuote = "Single quote"
PythonImag = "Imaginary part of z"
PythonReal = "Real part of z"
PythonAbs = "Absolute value/Magnitude"
PythonAcos = "Arc cosine"
PythonAcosh = "Arc hyperbolic cosine"
PythonAppend = "Add x to the end of the list"
PythonArrow = "Arrow from (x,y) to (x+dx,y+dy)"
PythonAsin = "Arc sine"
PythonAsinh = "Arc hyperbolic sine"
PythonAtan = "Arc tangent"
PythonAtan2 = "Return atan(y/x)"
PythonAtanh = "Arc hyperbolic tangent"
PythonAxis = "Set axes to (xmin,xmax,ymin,ymax)"
PythonBar = "Draw a bar plot with x values"
PythonBin = "Convert integer to binary"
PythonCeil = "Ceiling"
PythonChoice = "Random number in the list"
PythonClear = "Empty the list"
PythonCmathFunction = "cmath module function prefix"
PythonColor = "Define a rgb color"
PythonComplex = "Return a+ib"
PythonCopySign = "Return x with the sign of y"
PythonCos = "Cosine"
PythonCosh = "Hyperbolic cosine"
PythonCount = "Count the occurrences of x"
PythonDegrees = "Convert x from radians to degrees"
PythonDivMod = "Quotient and remainder"
PythonDrawString = "Display a text from pixel (x,y)"
PythonErf = "Error function"
PythonErfc = "Complementary error function"
PythonEval = "Return the evaluated expression"
PythonExp = "Exponential function"
PythonExpm1 = "Compute exp(x)-1"
PythonFabs = "Absolute value"
PythonFillRect = "Fill a rectangle at pixel (x,y)"
PythonFloat = "Convert x to a float"
PythonFloor = "Floor"
PythonFmod = "a modulo b"
PythonFrExp = "Mantissa and exponent of x"
PythonGamma = "Gamma function"
PythonGetPixel = "Return pixel (x,y) color"
PythonGetrandbits = "Integer with k random bits"
PythonGrid = "Toggle the visibility of the grid"
PythonHex = "Convert integer to hexadecimal"
PythonHist = "Draw the histogram of x"
PythonImportCmath = "Import cmath module"
PythonImportIon = "Import ion module"
PythonImportKandinsky = "Import kandinsky module"
PythonImportRandom = "Import random module"
PythonImportMath = "Import math module"
PythonImportMatplotlibPyplot = "Import matplotlib.pyplot module"
PythonImportTime = "Import time module"
PythonImportTurtle = "Import turtle module"
PythonIndex = "Index of the first x occurrence"
PythonInput = "Prompt a value"
PythonInsert = "Insert x at index i in the list"
PythonInt = "Convert x to an integer"
PythonIonFunction = "ion module function prefix"
PythonIsFinite = "Check if x is finite"
PythonIsInfinite = "Check if x is infinity"
PythonIsKeyDown = "Return True if the k key is down"
PythonIsNaN = "Check if x is a NaN"
PythonKandinskyFunction = "kandinsky module function prefix"
PythonKeyLeft = "LEFT ARROW key"
PythonKeyUp = "UP ARROW key"
PythonKeyDown = "DOWN ARROW key"
PythonKeyRight = "RIGHT ARROW key"
PythonKeyOk = "OK key"
PythonKeyBack = "BACK key"
PythonKeyHome = "HOME key"
PythonKeyOnOff = "ON/OFF key"
PythonKeyShift = "SHIFT key"
PythonKeyAlpha = "ALPHA key"
PythonKeyXnt = "X,N,T key"
PythonKeyVar = "VAR key"
PythonKeyToolbox = "TOOLBOX key"
PythonKeyBackspace = "BACKSPACE key"
PythonKeyExp = "EXPONENTIAL key"
PythonKeyLn = "NATURAL LOGARITHM key"
PythonKeyLog = "DECIMAL LOGARITHM key"
PythonKeyImaginary = "IMAGINARY I key"
PythonKeyComma = "COMMA key"
PythonKeyPower = "POWER key"
PythonKeySine = "SINE key"
PythonKeyCosine = "COSINE key"
PythonKeyTangent = "TANGENT key"
PythonKeyPi = "PI key"
PythonKeySqrt = "SQUARE ROOT key"
PythonKeySquare = "SQUARE key"
PythonKeySeven = "7 key"
PythonKeyEight = "8 key"
PythonKeyNine = "9 key"
PythonKeyLeftParenthesis = "LEFT PARENTHESIS key"
PythonKeyRightParenthesis = "RIGHT PARENTHESIS key"
PythonKeyFour = "4 key"
PythonKeyFive = "5 key"
PythonKeySix = "6 key"
PythonKeyMultiplication = "MULTIPLICATION key"
PythonKeyDivision = "DIVISION key"
PythonKeyOne = "1 key"
PythonKeyTwo = "2 key"
PythonKeyThree = "3 key"
PythonKeyPlus = "PLUS key"
PythonKeyMinus = "MINUS key"
PythonKeyZero = "0 key"
PythonKeyDot = "DOT key"
PythonKeyEe = "10 POWER X key"
PythonKeyAns = "ANS key"
PythonKeyExe = "EXE key"
PythonLdexp = "Return x*(2**i), inverse of frexp"
PythonLength = "Length of an object"
PythonLgamma = "Log-gamma function"
PythonLog = "Logarithm to base a"
PythonLog10 = "Logarithm to base 10"
PythonLog2 = "Logarithm to base 2"
PythonMathFunction = "math module function prefix"
PythonMatplotlibPyplotFunction = "matplotlib.pyplot module prefix"
PythonMax = "Maximum"
PythonMin = "Minimum"
PythonModf = "Fractional and integer parts of x"
PythonMonotonic = "Value of a monotonic clock"
PythonOct = "Convert integer to octal"
PythonPhase = "Phase of z"
PythonPlot = "Plot y versus x as lines"
PythonPolar = "z in polar coordinates"
PythonPop = "Remove and return the last item"
PythonPower = "x raised to the power y"
PythonPrint = "Print object"
PythonRadians = "Convert x from degrees to radians"
PythonRandint = "Random integer in [a,b]"
PythonRandom = "Floating point number in [0,1["
PythonRandomFunction = "random module function prefix"
PythonRandrange = "Random number in range(start, stop)"
PythonRangeStartStop = "List from start to stop-1"
PythonRangeStop = "List from 0 to stop-1"
PythonRect = "z in cartesian coordinates"
PythonRemove = "Remove the first occurrence of x"
PythonReverse = "Reverse the elements of the list"
PythonRound = "Round to n digits"
PythonScatter = "Draw a scatter plot of y versus x"
PythonSeed = "Initialize random number generator"
PythonSetPixel = "Color pixel (x,y)"
PythonShow = "Display the figure"
PythonSin = "Sine"
PythonSinh = "Hyperbolic sine"
PythonSleep = "Suspend the execution for t seconds"
PythonSort = "Sort the list"
PythonSqrt = "Square root"
PythonSum = "Sum the items of a list"
PythonTan = "Tangent"
PythonTanh = "Hyperbolic tangent"
PythonText = "Display a text at (x,y) coordinates"
PythonTimeFunction = "time module function prefix"
PythonTrunc = "x truncated to an integer"
PythonTurtleBackward = "Move backward by x pixels"
PythonTurtleBlack = "Black color"
PythonTurtleBlue = "Blue color"
PythonTurtleBrown = "Brown color"
PythonTurtleCircle = "Circle of radius r pixels"
PythonTurtleColor = "Set the pen color"
PythonTurtleForward = "Move forward by x pixels"
PythonTurtleFunction = "turtle module function prefix"
PythonTurtleGoto = "Move to (x,y) coordinates"
PythonTurtleGreen = "Green color"
PythonTurtleGrey = "Grey color"
PythonTurtleHeading = "Return the current heading"
PythonTurtleHideturtle = "Hide the turtle"
PythonTurtleIsdown = "Return True if the pen is down"
PythonTurtleLeft = "Turn left by a degrees"
PythonTurtleOrange = "Orange color"
PythonTurtlePendown = "Pull the pen down"
PythonTurtlePensize = "Set the line thickness to x pixels"
PythonTurtlePenup = "Pull the pen up"
PythonTurtlePink = "Pink color"
PythonTurtlePosition = "Return the current (x,y) location"
PythonTurtlePurple = "Purple color"
PythonTurtleRed = "Red color"
PythonTurtleReset = "Reset the drawing"
PythonTurtleRight = "Turn right by a degrees"
PythonTurtleSetheading = "Set the orientation to a degrees"
PythonPound = "Comentário"
PythonPercent = "Módulo"
Python1J = "i Complexo"
PythonLF = "Nova linha"
PythonTab = "Tabulação"
PythonAmpersand = "Operador binário and"
PythonSymbolExp = "Operador binário exclusivo or"
PythonVerticalBar = "Operador binário or"
PythonSingleQuote = "Apóstrofo"
PythonImag = "Parte imaginária de z"
PythonReal = "Parte real de z"
PythonAbs = "Valor absoluto/módulo"
PythonAcos = "Arco cosseno"
PythonAcosh = "Arco cosseno hiperbólico"
PythonAppend = "Adicionar x no fim da lista"
PythonArrow = "Seta de (x,y) para (x+dx,y+dy)"
PythonAsin = "Arco seno"
PythonAsinh = "Arco seno hiperbólico"
PythonAtan = "Arco tangente"
PythonAtan2 = "Cálculo de atan(y/x)"
PythonAtanh = "Arco tangente hiperbólica"
PythonAxis = "Definir eixos (xmin,xmax,ymin,ymax)"
PythonBar = "Gráfico de barras com valores de x"
PythonBin = "Converter número inteiro em binário"
PythonCeil = "Teto"
PythonChoice = "Número aleatório na lista"
PythonClear = "Esvaziar a lista"
PythonCmathFunction = "Prefixo da função do módulo cmath"
PythonColor = "Define uma cor rgb"
PythonColorBlack = "Cor preta"
PythonColorBlue = "Cor azul"
PythonColorBrown = "Cor castanha"
PythonColorGreen = "Cor verde"
PythonColorGrey = "Cor cinzenta"
PythonColorOrange = "Cor laranja"
PythonColorPink = "Cor rosa"
PythonColorPurple = "Cor roxa"
PythonColorRed = "Cor vermelha"
PythonColorWhite = "Cor branca"
PythonColorYellow = "Cor amarela"
PythonComplex = "Devolve a+ib"
PythonCopySign = "Devolve x com o sinal de y"
PythonCos = "Cosseno"
PythonCosh = "Cosseno hiperbólico"
PythonCount = "Contar as ocorrências de x"
PythonDegrees = "Converter x de radianos para graus"
PythonDivMod = "Quociente e resto"
PythonDrawString = "Mostrar o texto do pixel (x,y)"
PythonErf = "Função erro"
PythonErfc = "Função erro complementar"
PythonEval = "Devolve a expressão avaliada"
PythonExp = "Função exponencial"
PythonExpm1 = "Calcular exp(x)-1"
PythonFabs = "Valor absoluto"
PythonFillRect = "Preencher um retângulo em (x,y)"
PythonFloat = "Converter x num flutuante"
PythonFloor = "Parte inteira"
PythonFmod = "a módulo b"
PythonFrExp = "Coeficiente e expoente de x: (m, e)"
PythonGamma = "Função gama"
PythonGetPixel = "Devolve a cor do pixel (x,y)"
PythonGetrandbits = "Número inteiro aleatório com k bits"
PythonGrid = "Alterar visibilidade da grelha"
PythonHex = "Converter inteiro em hexadecimal"
PythonHist = "Desenhar o histograma de x"
PythonImportCmath = "Importar módulo cmath"
PythonImportIon = "Importar módulo ion"
PythonImportKandinsky = "Importar módulo kandinsky"
PythonImportRandom = "Importar módulo random"
PythonImportMath = "Importar módulo math"
PythonImportMatplotlibPyplot = "Importar módulo matplotlib.pyplot"
PythonImportTime = "Importar módulo time"
PythonImportTurtle = "Importar módulo turtle"
PythonIndex = "Índice da primeira ocorrência de x"
PythonInput = "Adicionar um valor"
PythonInsert = "Inserir x no índice i na lista"
PythonInt = "Converter x num número inteiro"
PythonIonFunction = "Prefixo da função do módulo ion"
PythonIsFinite = "Verificar se x é finito"
PythonIsInfinite = "Verificar se x é infinito"
PythonIsKeyDown = "Devolve True se tecla k pressionada"
PythonIsNaN = "Verificar se x é um NaN"
PythonKandinskyFunction = "Prefixo da função do módulo kandinsky"
PythonKeyLeft = "tecla SETA ESQUERDA"
PythonKeyUp = "tecla SETA CIMA "
PythonKeyDown = "tecla SETA BAIXO"
PythonKeyRight = "tecla SETA DIREITA"
PythonKeyOk = "tecla OK"
PythonKeyBack = "tecla VOLTAR"
PythonKeyHome = "tecla HOME"
PythonKeyOnOff = "tecla ON/OFF"
PythonKeyShift = "tecla SHIFT"
PythonKeyAlpha = "tecla ALPHA"
PythonKeyXnt = "tecla X,N,T"
PythonKeyVar = "tecla VAR"
PythonKeyToolbox = "tecla CAIXA DE FERRAMENTAS"
PythonKeyBackspace = "tecla APAGAR"
PythonKeyExp = "tecla EXPONENCIAL"
PythonKeyLn = "tecla LOGARITMO NATURAL"
PythonKeyLog = "tecla LOGARITMO DECIMAL"
PythonKeyImaginary = "tecla I IMAGINÁRIO"
PythonKeyComma = "tecla VÍRGULA"
PythonKeyPower = "tecla EXPOENTE"
PythonKeySine = "tecla SENO"
PythonKeyCosine = "tecla COSSENO"
PythonKeyTangent = "tecla TANGENTE"
PythonKeyPi = "tecla PI"
PythonKeySqrt = "tecla RAIZ QUADRADA"
PythonKeySquare = "tecla AO QUADRADO"
PythonKeySeven = "tecla 7"
PythonKeyEight = "tecla 8"
PythonKeyNine = "tecla 9"
PythonKeyLeftParenthesis = "tecla PARÊNTESE ESQUERDO"
PythonKeyRightParenthesis = "tecla PARÊNTESE DIREITO"
PythonKeyFour = "tecla 4"
PythonKeyFive = "tecla 5"
PythonKeySix = "tecla 6"
PythonKeyMultiplication = "tecla MULTIPLICAÇÃO"
PythonKeyDivision = "tecla DIVISÃO"
PythonKeyOne = "tecla 1"
PythonKeyTwo = "tecla 2"
PythonKeyThree = "tecla 3"
PythonKeyPlus = "tecla MAIS"
PythonKeyMinus = "tecla MENOS"
PythonKeyZero = "tecla 0"
PythonKeyDot = "tecla PONTO"
PythonKeyEe = "tecla 10 expoente X"
PythonKeyAns = "tecla ANS"
PythonKeyExe = "tecla EXE"
PythonLdexp = "Devolve x*(2**i), inverso de frexp"
PythonLength = "Comprimento de um objeto"
PythonLgamma = "Logaritmo da função gama"
PythonLog = "Logaritmo de base a"
PythonLog10 = "Logaritmo de base 10"
PythonLog2 = "Logaritmo de base 2"
PythonMathFunction = "Prefixo da função do módulo math"
PythonMatplotlibPyplotFunction = "Prefixo do módulo matplotlib.pyplot"
PythonMax = "Máximo"
PythonMin = "Mínimo"
PythonModf = "Partes inteira e frácionária de x"
PythonMonotonic = "Devolve o valor do relógio"
PythonOct = "Converter número inteiro em octal"
PythonPhase = "Argumento de z"
PythonPlot = "Desenhar y em função de x"
PythonPolar = "z em coordenadas polares"
PythonPop = "Remover o último item"
PythonPower = "x levantado a y"
PythonPrint = "Mostrar o objeto"
PythonRadians = "Converter x de graus para radianos"
PythonRandint = "Número inteiro aleatório em [a,b]"
PythonRandom = "Número decimal em [0,1["
PythonRandomFunction = "Prefixo da função do módulo random"
PythonRandrange = "Número aleatório em [start,stop-1]"
PythonRangeStartStop = "Lista de start a stop-1"
PythonRangeStop = "Lista de 0 a stop-1"
PythonRect = "Converter para coordenadas cartesianas"
PythonRemove = "Remover a primeira ocorrência de x"
PythonReverse = "Inverter os elementos da lista"
PythonRound = "Arredondar para n dígitos"
PythonScatter = "Gráfico de dispersão (x,y)"
PythonSeed = "Iniciar gerador aleatório"
PythonSetPixel = "Cor do pixel (x,y)"
PythonShow = "Mostrar a figura"
PythonSin = "Seno"
PythonSinh = "Seno hiperbólico"
PythonSleep = "Suspender a execução por t segundos"
PythonSort = "Ordenar a lista"
PythonSqrt = "Raiz quadrada"
PythonSum = "Soma dos itens da lista"
PythonTan = "Tangente"
PythonTanh = "Tangente hiperbólica"
PythonText = "Mostrar um texto em (x,y)"
PythonTimeFunction = "Prefixo da função do módulo time"
PythonTrunc = "x truncado a um número inteiro"
PythonTurtleBackward = "Recuar x pixels"
PythonTurtleCircle = "Circunferência de raio r pixels"
PythonTurtleColor = "Definir a cor da caneta"
PythonTurtleColorMode = "Define modo de cor para 1.0 ou 255"
PythonTurtleForward = "Avançar x pixels"
PythonTurtleFunction = "Prefixo da função do módulo turtle"
PythonTurtleGoto = "Ir paras as coordenadas (x,y)"
PythonTurtleHeading = "Voltar para a orientação atual"
PythonTurtleHideturtle = "Esconder o turtle"
PythonTurtleIsdown = "True se a caneta está pressionada"
PythonTurtleLeft = "Vira à esquerda por a graus"
PythonTurtlePendown = "Puxar a caneta para baixo"
PythonTurtlePensize = "Definir a espessura para x pixels"
PythonTurtlePenup = "Puxar a caneta para cima"
PythonTurtlePosition = "Devolve a posição atual (x,y)"
PythonTurtleReset = "Reiniciar o desenho"
PythonTurtleRight = "Virar à esquerda por a graus"
PythonTurtleSetheading = "Definir a orientação por a graus"
PythonTurtleSetposition = "Positionne la tortue"
PythonTurtleShowturtle = "Show the turtle"
PythonTurtleSpeed = "Drawing speed between 0 and 10"
PythonTurtleWhite = "White color"
PythonTurtleYellow = "Yellow color"
PythonUniform = "Floating point number in [a,b]"
PythonTimeFromImport = "Import time module"
PythonTimeImport = "Import time module"
PythonTurtleShowturtle = "Mostrar o turtle"
PythonTurtleSpeed = "Velocidade do desenho entre 0 e 10"
PythonTurtleWrite = "Mostrar um texto"
PythonUniform = "Número decimal em [a,b]"
PythonImportTime = "Import time module"
PythonImportOs = "Import os module"
PythonOsUname = " Obter informações do sistema"
PythonOsRemove = "Remover um ficheiro"
PythonOsRename = "Renomear ficheiro"
PythonOsListdir = "Listar ficheiros"
PythonTimePrefix = "time module function prefix"
PythonTimeSleep = "Aguardar n segundos"
PythonTimeMonotonic = "Retornar tempo monotônico"
PythonTimeSleep = "Wait for n second"
PythonMonotonic = "Return monotonic time"
PythonFileOpen = "Opens a file"
PythonFileSeekable = "Tells if seek can be used on a file"
PythonFileSeek = "Move file's cursor"
PythonFileTell = "Get file's cursor location"
PythonFileClose = "Closes a file"
PythonFileClosed = "True if file was closed"
PythonFileRead = "Read up to size bytes"
PythonFileWrite = "Write b into file"
PythonFileReadline = "Reads a line or up to size bytes"
PythonFileReadlines = "Reads a list of lines"
PythonFileTruncate = "Resize the file to size"
PythonFileWritelines = "Writes a list of lines"
PythonFileName = "Contains file's name"
PythonFileMode = "Contains file's open mode"
PythonFileReadable = "Tells if read can be used on a file"
PythonFileWritable = "Tells if write can be used on a file"

View File

@@ -29,6 +29,17 @@ PythonCommandClearWithoutArg = ".clear()"
PythonCommandCmathFunction = "cmath.function"
PythonCommandCmathFunctionWithoutArg = "cmath.\x11"
PythonCommandColor = "color(r,g,b)"
PythonCommandColorBlack = "'black'"
PythonCommandColorBlue = "'blue'"
PythonCommandColorBrown = "'brown'"
PythonCommandColorGreen = "'green'"
PythonCommandColorGrey = "'grey'"
PythonCommandColorOrange = "'orange'"
PythonCommandColorPink = "'pink'"
PythonCommandColorPurple = "'purple'"
PythonCommandColorRed = "'red'"
PythonCommandColorWhite = "'white'"
PythonCommandColorYellow = "'yellow'"
PythonCommandComplex = "complex(a,b)"
PythonCommandConstantPi = "pi"
PythonCommandCopySign = "copysign(x,y)"
@@ -75,6 +86,8 @@ PythonCommandImportKandinsky = "import kandinsky"
PythonCommandImportMath = "import math"
PythonCommandImportMatplotlibPyplot = "import matplotlib.pyplot"
PythonCommandImportRandom = "import random"
PythonCommandImportOs = "import os"
PythonCommandImportFromOs = "from os import *"
PythonCommandImportTime = "import time"
PythonCommandImportTurtle = "import turtle"
PythonCommandIndex = "list.index(x)"
@@ -154,7 +167,7 @@ PythonCommandModf = "modf(x)"
PythonCommandMonotonic = "monotonic()"
PythonCommandOct = "oct(x)"
PythonCommandPhase = "phase(z)"
PythonCommandPlot = "plot(x,y)"
PythonCommandPlot = "plot(x,y,color)"
PythonCommandPolar = "polar(z)"
PythonCommandPop = "list.pop()"
PythonCommandPopWithoutArg = ".pop()"
@@ -165,17 +178,17 @@ PythonCommandRandint = "randint(a,b)"
PythonCommandRandom = "random()"
PythonCommandRandomFunction = "random.function"
PythonCommandRandomFunctionWithoutArg = "random.\x11"
PythonCommandRandrange = "randrange(start, stop)"
PythonCommandRangeStartStop = "range(start, stop)"
PythonCommandRandrange = "randrange(start,stop)"
PythonCommandRangeStartStop = "range(start,stop)"
PythonCommandRangeStop = "range(stop)"
PythonCommandReal = "z.real"
PythonCommandRealWithoutArg = ".real"
PythonCommandRect = "rect(r, arg)"
PythonCommandRect = "rect(r,arg)"
PythonCommandRemove = "list.remove(x)"
PythonCommandRemoveWithoutArg = ".remove(\x11)"
PythonCommandReverse = "list.reverse()"
PythonCommandReverseWithoutArg = ".reverse()"
PythonCommandRound = "round(x, n)"
PythonCommandRound = "round(x,n)"
PythonCommandScatter = "scatter(x,y)"
PythonCommandSeed = "seed(x)"
PythonCommandSetPixel = "set_pixel(x,y,color)"
@@ -201,33 +214,30 @@ PythonCommandTurtleFunctionWithoutArg = "turtle.\x11"
PythonCommandUniform = "uniform(a,b)"
PythonConstantE = "2.718281828459045"
PythonConstantPi = "3.141592653589793"
PythonOsCommandUname = "uname()"
PythonOsCommandRemove = "remove(filename)"
PythonOsCommandRename = "rename(oldname, newname)"
PythonOsCommandRemoveWithoutArg = "remove(\x11)"
PythonOsCommandRenameWithoutArg = "rename(\x11,)"
PythonOsCommandListdir = "listdir()"
PythonTurtleCommandBackward = "backward(x)"
PythonTurtleCommandBlack = "'black'"
PythonTurtleCommandBlue = "'blue'"
PythonTurtleCommandBrown = "'brown'"
PythonTurtleCommandCircle = "circle(r)"
PythonTurtleCommandColor = "color('c')/color(r,g,b)"
PythonTurtleCommandColorWithoutArg = "color(\x11)"
PythonTurtleCommandColor = "color('c')"
PythonTurtleCommandColorMode = "colormode(x)"
PythonTurtleCommandForward = "forward(x)"
PythonTurtleCommandGoto = "goto(x,y)"
PythonTurtleCommandGreen = "'green'"
PythonTurtleCommandGrey = "'grey'"
PythonTurtleCommandHeading = "heading()"
PythonTurtleCommandHideturtle = "hideturtle()"
PythonTurtleCommandIsdown= "isdown()"
PythonTurtleCommandLeft = "left(a)"
PythonTurtleCommandOrange = "'orange'"
PythonTurtleCommandPendown = "pendown()"
PythonTurtleCommandPensize = "pensize(x)"
PythonTurtleCommandPenup = "penup()"
PythonTurtleCommandPink = "'pink'"
PythonTurtleCommandPosition = "position()"
PythonTurtleCommandPurple = "'purple'"
PythonTurtleCommandRed = "'red'"
PythonTurtleCommandReset = "reset()"
PythonTurtleCommandRight = "right(a)"
PythonTurtleCommandSetheading = "setheading(a)"
PythonTurtleCommandSetposition = "setposition(x, [y])"
PythonTurtleCommandSetposition = "setposition(x,[y])"
PythonTurtleCommandShowturtle = "showturtle()"
PythonTurtleCommandSpeed = "speed(x)"
PythonTurtleCommandWhite = "'white'"
@@ -237,3 +247,36 @@ PythonTimeCommandImportFrom = "from time import *"
PythonTimeCommandSleep = "sleep()"
PythonTimeCommandSleepDemo = "sleep(n)"
PythonTimeCommandMonotonic = "monotonic()"
PythonCommandFileOpen = "open(name, [mode])"
PythonCommandFileOpenWithoutArg = "open(\x11)"
PythonCommandFileSeek = "file.seek(offset, [whence])"
PythonCommandFileSeekWithoutArg = ".seek(\x11)"
PythonCommandFileTell = "file.tell()"
PythonCommandFileTellWithoutArg = ".tell()"
PythonCommandFileSeekable = "file.seekable()"
PythonCommandFileSeekableWithoutArg = ".seekable()"
PythonCommandFileClose = "file.close()"
PythonCommandFileCloseWithoutArg = ".close()"
PythonCommandFileClosed = "file.closed"
PythonCommandFileClosedWithoutArg = ".closed"
PythonCommandFileRead = "file.read([size])"
PythonCommandFileReadWithoutArg = ".read(\x11)"
PythonCommandFileWrite = "file.write(b)"
PythonCommandFileWriteWithoutArg = ".write(\x11)"
PythonCommandFileReadline = "file.readline([size])"
PythonCommandFileReadlineWithoutArg = ".readline(\x11)"
PythonCommandFileReadlines = "file.readlines([hint])"
PythonCommandFileReadlinesWithoutArg = ".readlines(\x11)"
PythonCommandFileTruncate = "file.truncate([size])"
PythonCommandFileTruncateWithoutArg = ".truncate(\x11)"
PythonCommandFileWritelines = "file.writelines(lines)"
PythonCommandFileWritelinesWithoutArg = ".writelines(\x11)"
PythonCommandFileName = "file.name"
PythonCommandFileNameWithoutArg = ".name"
PythonCommandFileMode = "file.mode"
PythonCommandFileModeWithoutArg = ".mode"
PythonCommandFileReadable = "file.readable()"
PythonCommandFileReadableWithoutArg = ".readable()"
PythonCommandFileWritable = "file.writable()"
PythonCommandFileWritableWithoutArg = ".writable()"
PythonTurtleCommandWrite = "write(\"text\")"

View File

@@ -3,6 +3,7 @@
#include "script.h"
#include "variable_box_controller.h"
#include <apps/i18n.h>
#include <algorithm>
#include <assert.h>
#include <escher/metric.h>
#include <poincare/preferences.h>
@@ -16,8 +17,6 @@ extern "C" {
namespace Code {
static inline int minInt(int x, int y) { return x < y ? x : y; }
static const char * sStandardPromptText = ">>> ";
ConsoleController::ConsoleController(Responder * parentResponder, App * pythonDelegate, ScriptStore * scriptStore
@@ -32,7 +31,7 @@ ConsoleController::ConsoleController(Responder * parentResponder, App * pythonDe
m_pythonDelegate(pythonDelegate),
m_importScriptsWhenViewAppears(false),
m_selectableTableView(this, this, this, this),
m_editCell(this, pythonDelegate, this),
m_editCell(this, this, this),
m_scriptStore(scriptStore),
m_sandboxController(this),
m_inputRunLoopActive(false)
@@ -49,17 +48,13 @@ ConsoleController::ConsoleController(Responder * parentResponder, App * pythonDe
}
bool ConsoleController::loadPythonEnvironment() {
if (m_pythonDelegate->isPythonUser(this)) {
return true;
if (!m_pythonDelegate->isPythonUser(this)) {
m_scriptStore->clearConsoleFetchInformation();
emptyOutputAccumulationBuffer();
m_pythonDelegate->initPythonWithUser(this);
MicroPython::registerScriptProvider(m_scriptStore);
m_importScriptsWhenViewAppears = m_autoImportScripts;
}
emptyOutputAccumulationBuffer();
m_pythonDelegate->initPythonWithUser(this);
MicroPython::registerScriptProvider(m_scriptStore);
m_importScriptsWhenViewAppears = m_autoImportScripts;
/* We load functions and variables names in the variable box before running
* any other python code to avoid failling to load functions and variables
* due to memory exhaustion. */
App::app()->variableBoxController()->loadFunctionsAndVariables();
return true;
}
@@ -291,7 +286,7 @@ void ConsoleController::willDisplayCellAtLocation(HighlightCell * cell, int i, i
}
}
void ConsoleController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) {
void ConsoleController::tableViewDidChangeSelectionAndDidScroll(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) {
if (withinTemporarySelection) {
return;
}
@@ -376,6 +371,14 @@ bool ConsoleController::textFieldDidAbortEditing(TextField * textField) {
return true;
}
VariableBoxController * ConsoleController::variableBoxForInputEventHandler(InputEventHandler * textInput) {
VariableBoxController * varBox = App::app()->variableBoxController();
varBox->loadVariablesImportedFromScripts();
varBox->setTitle(I18n::Message::FunctionsAndVariables);
varBox->setDisplaySubtitles(false);
return varBox;
}
void ConsoleController::resetSandbox() {
if (stackViewController()->topViewController() != sandbox()) {
return;
@@ -448,7 +451,7 @@ void ConsoleController::printText(const char * text, size_t length) {
flushOutputAccumulationBufferToStore();
micropython_port_vm_hook_refresh_print();
}
#if __EMSCRIPTEN__
// #if __EMSCRIPTEN__
/* If we called micropython_port_interrupt_if_needed here, we would need to
* put in the WHITELIST all the methods that call
* ConsoleController::printText, which means all the MicroPython methods that
@@ -461,13 +464,17 @@ void ConsoleController::printText(const char * text, size_t length) {
* device.
*
* TODO: Allow print interrpution on emscripten -> maybe by using WASM=1 ? */
#else
/*
* This can be run in Omega, since it uses WebASM.
*/
// #else
/* micropython_port_vm_hook_loop is not enough to detect user interruptions,
* because it calls micropython_port_interrupt_if_needed every 20000
* operations, and a print operation is quite long. We thus explicitely call
* micropython_port_interrupt_if_needed here. */
micropython_port_interrupt_if_needed();
#endif
// #endif
}
void ConsoleController::autoImportScript(Script script, bool force) {
@@ -476,7 +483,7 @@ void ConsoleController::autoImportScript(Script script, bool force) {
* the sandbox. */
hideAnyDisplayedViewController();
if (script.importationStatus() || force) {
if (script.autoImportationStatus() || force) {
// Step 1 - Create the command "from scriptName import *".
assert(strlen(k_importCommand1) + strlen(script.fullName()) - strlen(ScriptStore::k_scriptExtension) - 1 + strlen(k_importCommand2) + 1 <= k_maxImportCommandSize);
@@ -488,7 +495,7 @@ void ConsoleController::autoImportScript(Script script, bool force) {
/* Copy the script name without the extension ".py". The '.' is overwritten
* by the null terminating char. */
int copySizeWithNullTerminatingZero = minInt(k_maxImportCommandSize - currentChar, strlen(scriptName) - strlen(ScriptStore::k_scriptExtension));
int copySizeWithNullTerminatingZero = std::min(k_maxImportCommandSize - currentChar, strlen(scriptName) - strlen(ScriptStore::k_scriptExtension));
assert(copySizeWithNullTerminatingZero >= 0);
assert(copySizeWithNullTerminatingZero <= k_maxImportCommandSize - currentChar);
strlcpy(command+currentChar, scriptName, copySizeWithNullTerminatingZero);

View File

@@ -10,12 +10,14 @@
#include "console_store.h"
#include "sandbox_controller.h"
#include "script_store.h"
#include "variable_box_controller.h"
#include "../shared/input_event_handler_delegate.h"
namespace Code {
class App;
class ConsoleController : public ViewController, public ListViewDataSource, public SelectableTableViewDataSource, public SelectableTableViewDelegate, public TextFieldDelegate, public MicroPython::ExecutionEnvironment {
class ConsoleController : public ViewController, public ListViewDataSource, public SelectableTableViewDataSource, public SelectableTableViewDelegate, public TextFieldDelegate, public Shared::InputEventHandlerDelegate, public MicroPython::ExecutionEnvironment {
public:
ConsoleController(Responder * parentResponder, App * pythonDelegate, ScriptStore * scriptStore
#if EPSILON_GETOPT
@@ -52,7 +54,7 @@ public:
void willDisplayCellAtLocation(HighlightCell * cell, int i, int j) override;
// SelectableTableViewDelegate
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) override;
void tableViewDidChangeSelectionAndDidScroll(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) override;
// TextFieldDelegate
bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override;
@@ -60,6 +62,9 @@ public:
bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override;
bool textFieldDidAbortEditing(TextField * textField) override;
// InputEventHandlerDelegate
VariableBoxController * variableBoxForInputEventHandler(InputEventHandler * textInput) override;
// MicroPython::ExecutionEnvironment
ViewController * sandbox() override { return &m_sandboxController; }
void resetSandbox() override;

View File

@@ -4,11 +4,10 @@
#include <apps/i18n.h>
#include <apps/global_preferences.h>
#include <assert.h>
#include <algorithm>
namespace Code {
static inline int minInt(int x, int y) { return x < y ? x : y; }
ConsoleEditCell::ConsoleEditCell(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * delegate) :
HighlightCell(),
Responder(parentResponder),
@@ -70,7 +69,7 @@ const char * ConsoleEditCell::shiftCurrentTextAndClear() {
char * textFieldBuffer = const_cast<char *>(m_textField.text());
char * newTextPosition = textFieldBuffer + 1;
assert(previousBufferSize > 0);
size_t copyLength = minInt(previousBufferSize - 1, strlen(textFieldBuffer));
size_t copyLength = std::min(previousBufferSize - 1, strlen(textFieldBuffer));
memmove(newTextPosition, textFieldBuffer, copyLength);
newTextPosition[copyLength] = 0;
textFieldBuffer[0] = 0;

View File

@@ -19,7 +19,7 @@ void ConsoleLineCell::ScrollableConsoleLineView::ConsoleLineView::setLine(Consol
void ConsoleLineCell::ScrollableConsoleLineView::ConsoleLineView::drawRect(KDContext * ctx, KDRect rect) const {
ctx->fillRect(bounds(), Palette::CodeBackground);
ctx->drawString(m_line->text(), KDPointZero, GlobalPreferences::sharedGlobalPreferences()->font(), textColor(m_line), isHighlighted()? Palette::Select : KDColorWhite);
ctx->drawString(m_line->text(), KDPointZero, GlobalPreferences::sharedGlobalPreferences()->font(), textColor(m_line), isHighlighted()? Palette::Select : Palette::BackgroundApps);
}
KDSize ConsoleLineCell::ScrollableConsoleLineView::ConsoleLineView::minimalSizeForOptimalDisplay() const {

View File

@@ -1,10 +1,9 @@
#include "console_store.h"
#include <string.h>
#include <algorithm>
namespace Code {
static inline int minInt(int x, int y) { return x < y ? x : y; }
void ConsoleStore::startNewSession() {
if (k_historySize < 1) {
return;
@@ -12,7 +11,7 @@ void ConsoleStore::startNewSession() {
m_history[0] = makePrevious(m_history[0]);
for (int i = 0; i < k_historySize - 1; i++) {
for (size_t i = 0; i < k_historySize - 1; i++) {
if (m_history[i] == 0) {
if (m_history[i+1] == 0) {
return ;
@@ -25,7 +24,7 @@ void ConsoleStore::startNewSession() {
ConsoleLine ConsoleStore::lineAtIndex(int i) const {
assert(i >= 0 && i < numberOfLines());
int currentLineIndex = 0;
for (int j=0; j<k_historySize; j++) {
for (size_t j=0; j<k_historySize; j++) {
if (m_history[j] == 0) {
currentLineIndex++;
j++;
@@ -43,7 +42,7 @@ int ConsoleStore::numberOfLines() const {
return 0;
}
int result = 0;
for (int i = 0; i < k_historySize - 1; i++) {
for (size_t i = 0; i < k_historySize - 1; i++) {
if (m_history[i] == 0) {
result++;
if (m_history[i+1] == 0) {
@@ -96,14 +95,14 @@ const char * ConsoleStore::push(const char marker, const char * text) {
if (ConsoleLine::sizeOfConsoleLine(textLength) > k_historySize - 1) {
textLength = k_historySize - 1 - 1 - 1; // Marker, null termination and null marker.
}
int i = indexOfNullMarker();
size_t i = indexOfNullMarker();
// If needed, make room for the text we want to push.
while (i + ConsoleLine::sizeOfConsoleLine(textLength) > k_historySize - 1) {
deleteFirstLine();
i = indexOfNullMarker();
}
m_history[i] = marker;
strlcpy(&m_history[i+1], text, minInt(k_historySize-(i+1),textLength+1));
strlcpy(&m_history[i+1], text, std::min(k_historySize-(i+1),textLength+1));
m_history[i+1+textLength+1] = 0;
return &m_history[i+1];
}
@@ -113,11 +112,11 @@ ConsoleLine::Type ConsoleStore::lineTypeForMarker(char marker) const {
return static_cast<ConsoleLine::Type>(marker-1);
}
int ConsoleStore::indexOfNullMarker() const {
size_t ConsoleStore::indexOfNullMarker() const {
if (m_history[0] == 0) {
return 0;
}
for (int i=0; i<k_historySize; i++) {
for (size_t i=0; i<k_historySize; i++) {
if (m_history[i] == 0 && m_history[i+1] == 0) {
return (i+1);
}
@@ -129,13 +128,13 @@ int ConsoleStore::indexOfNullMarker() const {
void ConsoleStore::deleteLineAtIndex(int index) {
assert(index >=0 && index < numberOfLines());
int currentLineIndex = 0;
for (int i = 0; i < k_historySize - 1; i++) {
for (size_t i = 0; i < k_historySize - 1; i++) {
if (m_history[i] == 0) {
currentLineIndex++;
continue;
}
if (currentLineIndex == index) {
int nextLineStart = i;
size_t nextLineStart = i;
while (m_history[nextLineStart] != 0 && nextLineStart < k_historySize - 2) {
nextLineStart++;
}
@@ -158,7 +157,7 @@ void ConsoleStore::deleteFirstLine() {
secondLineMarkerIndex++;
}
secondLineMarkerIndex++;
for (int i=0; i<k_historySize - secondLineMarkerIndex; i++) {
for (size_t i=0; i<k_historySize - secondLineMarkerIndex; i++) {
m_history[i] = m_history[secondLineMarkerIndex+i];
}
}
@@ -174,7 +173,7 @@ void ConsoleStore::deleteLastLine() {
}
int currentLineIndex = 1;
int lastLineMarkerIndex = 0;
for (int i=0; i<k_historySize; i++) {
for (size_t i=0; i<k_historySize; i++) {
if (m_history[i] == 0) {
currentLineIndex++;
if (currentLineIndex == lineCount) {

View File

@@ -23,7 +23,7 @@ private:
static constexpr char CurrentSessionResultMarker = 0x02;
static constexpr char PreviousSessionCommandMarker = 0x03;
static constexpr char PreviousSessionResultMarker = 0x04;
static constexpr int k_historySize = 1024;
static constexpr size_t k_historySize = 1024;
static char makePrevious(char marker) {
if (marker == CurrentSessionCommandMarker || marker == CurrentSessionResultMarker) {
return marker + 0x02;
@@ -32,7 +32,7 @@ private:
}
const char * push(const char marker, const char * text);
ConsoleLine::Type lineTypeForMarker(char marker) const;
int indexOfNullMarker() const;
size_t indexOfNullMarker() const;
void deleteLineAtIndex(int index);
void deleteFirstLine();
/* When there is no room left to store a new ConsoleLine, we have to delete

View File

@@ -13,13 +13,15 @@ EditorController::EditorController(MenuController * menuController, App * python
ViewController(nullptr),
m_editorView(this, pythonDelegate),
m_script(Ion::Storage::Record()),
m_scriptIndex(-1),
m_menuController(menuController)
{
m_editorView.setTextAreaDelegates(this, this);
}
void EditorController::setScript(Script script) {
void EditorController::setScript(Script script, int scriptIndex) {
m_script = script;
m_scriptIndex = scriptIndex;
/* We edit the script direclty in the storage buffer. We thus put all the
* storage available space at the end of the current edited script and we set
@@ -35,7 +37,7 @@ void EditorController::setScript(Script script) {
* */
size_t newScriptSize = Ion::Storage::sharedStorage()->putAvailableSpaceAtEndOfRecord(m_script);
m_editorView.setText(const_cast<char *>(m_script.scriptContent()), newScriptSize - Script::k_importationStatusSize);
m_editorView.setText(const_cast<char *>(m_script.content()), newScriptSize - Script::StatusSize());
}
void EditorController::willExitApp() {
@@ -78,14 +80,6 @@ bool EditorController::textAreaDidReceiveEvent(TextArea * textArea, Ion::Events:
return true;
}
if(event.hasText()){
if(event.text() == "%" && Ion::Events::isLockActive() ){
return textArea->removePreviousGlyph();
} else {
return textArea->handleEventWithText(event.text(), true, false);
}
}
if (event == Ion::Events::Backspace && textArea->selectionIsEmpty()) {
/* If the cursor is on the left of the text of a line, backspace one
@@ -131,7 +125,24 @@ bool EditorController::textAreaDidReceiveEvent(TextArea * textArea, Ion::Events:
VariableBoxController * EditorController::variableBoxForInputEventHandler(InputEventHandler * textInput) {
VariableBoxController * varBox = App::app()->variableBoxController();
varBox->loadFunctionsAndVariables();
/* If the editor should be autocompleting an identifier, the variable box has
* already been loaded. We check shouldAutocomplete and not isAutocompleting,
* because the autocompletion result might be empty. */
const char * beginningOfAutocompletion = nullptr;
const char * cursor = nullptr;
PythonTextArea::AutocompletionType autocompType = m_editorView.autocompletionType(&beginningOfAutocompletion, &cursor);
if (autocompType == PythonTextArea::AutocompletionType::NoIdentifier) {
varBox->loadFunctionsAndVariables(m_scriptIndex, nullptr, 0);
} else if (autocompType == PythonTextArea::AutocompletionType::MiddleOfIdentifier) {
varBox->empty();
} else {
assert(autocompType == PythonTextArea::AutocompletionType::EndOfIdentifier);
assert(beginningOfAutocompletion != nullptr && cursor != nullptr);
assert(cursor > beginningOfAutocompletion);
varBox->loadFunctionsAndVariables(m_scriptIndex, beginningOfAutocompletion, cursor - beginningOfAutocompletion);
}
varBox->setTitle(I18n::Message::Autocomplete);
varBox->setDisplaySubtitles(true);
return varBox;
}
@@ -146,7 +157,7 @@ void EditorController::cleanStorageEmptySpace() {
Ion::Storage::Record::Data scriptValue = m_script.value();
Ion::Storage::sharedStorage()->getAvailableSpaceFromEndOfRecord(
m_script,
scriptValue.size - Script::k_importationStatusSize - (strlen(m_script.scriptContent()) + 1)); // TODO optimize number of script fetches
scriptValue.size - Script::StatusSize() - (strlen(m_script.content()) + 1)); // TODO optimize number of script fetches
}

View File

@@ -16,7 +16,8 @@ class App;
class EditorController : public ViewController, public TextAreaDelegate, public Shared::InputEventHandlerDelegate {
public:
EditorController(MenuController * menuController, App * pythonDelegate);
void setScript(Script script);
void setScript(Script script, int scriptIndex);
int scriptIndex() const { return m_scriptIndex; }
void willExitApp();
/* ViewController */
@@ -39,6 +40,7 @@ private:
StackViewController * stackController();
EditorView m_editorView;
Script m_script;
int m_scriptIndex;
MenuController * m_menuController;
};

View File

@@ -17,6 +17,10 @@ EditorView::EditorView(Responder * parentResponder, App * pythonDelegate) :
m_textArea.setScrollViewDelegate(this);
}
bool EditorView::isAutocompleting() const {
return m_textArea.isAutocompleting();
}
void EditorView::resetSelection() {
m_textArea.resetSelection();
}
@@ -53,8 +57,8 @@ void EditorView::layoutSubviews(bool force) {
/* EditorView::GutterView */
void EditorView::GutterView::drawRect(KDContext * ctx, KDRect rect) const {
KDColor textColor = KDColor::RGB24(0x919EA4);
KDColor backgroundColor = KDColor::RGB24(0xE4E6E7);
KDColor textColor = Palette::PrimaryText;
KDColor backgroundColor = Palette::CodeGutterViewBackground;
ctx->fillRect(rect, backgroundColor);

View File

@@ -9,6 +9,8 @@ namespace Code {
class EditorView : public Responder, public View, public ScrollViewDelegate {
public:
EditorView(Responder * parentResponder, App * pythonDelegate);
PythonTextArea::AutocompletionType autocompletionType(const char ** autocompletionBeginning, const char ** autocompletionEnd) const { return m_textArea.autocompletionType(nullptr, autocompletionBeginning, autocompletionEnd); }
bool isAutocompleting() const;
void resetSelection();
void setTextAreaDelegates(InputEventHandlerDelegate * inputEventHandlerDelegate, TextAreaDelegate * delegate) {
m_textArea.setDelegates(inputEventHandlerDelegate, delegate);
@@ -17,6 +19,9 @@ public:
void setText(char * textBuffer, size_t textBufferSize) {
m_textArea.setText(textBuffer, textBufferSize);
}
const char * cursorLocation() {
return m_textArea.cursorLocation();
}
bool setCursorLocation(const char * location) {
return m_textArea.setCursorLocation(location);
}

View File

@@ -385,7 +385,7 @@ void MenuController::configureScript() {
void MenuController::editScriptAtIndex(int scriptIndex) {
assert(scriptIndex >=0 && scriptIndex < m_scriptStore->numberOfScripts());
Script script = m_scriptStore->scriptAtIndex(scriptIndex);
m_editorController.setScript(script);
m_editorController.setScript(script, scriptIndex);
stackViewController()->push(&m_editorController);
}

View File

@@ -25,6 +25,7 @@ public:
void openConsoleWithScript(Script script);
void scriptContentEditionDidFinish();
void willExitApp();
int editedScriptIndex() const { return m_editorController.scriptIndex(); }
/* ViewController */
View * view() override { return &m_selectableTableView; }

View File

@@ -9,6 +9,7 @@ extern "C" {
#include "py/lexer.h"
}
#include <stdlib.h>
#include <algorithm>
namespace Code {
@@ -20,8 +21,7 @@ constexpr KDColor OperatorColor = Palette::CodeOperator;
constexpr KDColor StringColor = Palette::CodeString;
constexpr KDColor BackgroundColor = Palette::CodeBackground;
constexpr KDColor HighlightColor = Palette::CodeBackgroundSelected;
static inline const char * minPointer(const char * x, const char * y) { return x < y ? x : y; }
constexpr KDColor AutocompleteColor = KDColor::RGB24(0xC6C6C6); // TODO Palette change
static inline KDColor TokenColor(mp_token_kind_t tokenKind) {
if (tokenKind == MP_TOKEN_STRING) {
@@ -30,13 +30,96 @@ static inline KDColor TokenColor(mp_token_kind_t tokenKind) {
if (tokenKind == MP_TOKEN_INTEGER || tokenKind == MP_TOKEN_FLOAT_OR_IMAG) {
return NumberColor;
}
static_assert(MP_TOKEN_ELLIPSIS + 1 == MP_TOKEN_KW_FALSE
&& MP_TOKEN_KW_FALSE + 1 == MP_TOKEN_KW_NONE
&& MP_TOKEN_KW_NONE + 1 == MP_TOKEN_KW_TRUE
&& MP_TOKEN_KW_TRUE + 1 == MP_TOKEN_KW___DEBUG__
&& MP_TOKEN_KW___DEBUG__ + 1 == MP_TOKEN_KW_AND
&& MP_TOKEN_KW_AND + 1 == MP_TOKEN_KW_AS
&& MP_TOKEN_KW_AS + 1 == MP_TOKEN_KW_ASSERT
/* Here there are keywords that depend on MICROPY_PY_ASYNC_AWAIT, we do
* not test them */
&& MP_TOKEN_KW_BREAK + 1 == MP_TOKEN_KW_CLASS
&& MP_TOKEN_KW_CLASS + 1 == MP_TOKEN_KW_CONTINUE
&& MP_TOKEN_KW_CONTINUE + 1 == MP_TOKEN_KW_DEF
&& MP_TOKEN_KW_DEF + 1 == MP_TOKEN_KW_DEL
&& MP_TOKEN_KW_DEL + 1 == MP_TOKEN_KW_ELIF
&& MP_TOKEN_KW_ELIF + 1 == MP_TOKEN_KW_ELSE
&& MP_TOKEN_KW_ELSE + 1 == MP_TOKEN_KW_EXCEPT
&& MP_TOKEN_KW_EXCEPT + 1 == MP_TOKEN_KW_FINALLY
&& MP_TOKEN_KW_FINALLY + 1 == MP_TOKEN_KW_FOR
&& MP_TOKEN_KW_FOR + 1 == MP_TOKEN_KW_FROM
&& MP_TOKEN_KW_FROM + 1 == MP_TOKEN_KW_GLOBAL
&& MP_TOKEN_KW_GLOBAL + 1 == MP_TOKEN_KW_IF
&& MP_TOKEN_KW_IF + 1 == MP_TOKEN_KW_IMPORT
&& MP_TOKEN_KW_IMPORT + 1 == MP_TOKEN_KW_IN
&& MP_TOKEN_KW_IN + 1 == MP_TOKEN_KW_IS
&& MP_TOKEN_KW_IS + 1 == MP_TOKEN_KW_LAMBDA
&& MP_TOKEN_KW_LAMBDA + 1 == MP_TOKEN_KW_NONLOCAL
&& MP_TOKEN_KW_NONLOCAL + 1 == MP_TOKEN_KW_NOT
&& MP_TOKEN_KW_NOT + 1 == MP_TOKEN_KW_OR
&& MP_TOKEN_KW_OR + 1 == MP_TOKEN_KW_PASS
&& MP_TOKEN_KW_PASS + 1 == MP_TOKEN_KW_RAISE
&& MP_TOKEN_KW_RAISE + 1 == MP_TOKEN_KW_RETURN
&& MP_TOKEN_KW_RETURN + 1 == MP_TOKEN_KW_TRY
&& MP_TOKEN_KW_TRY + 1 == MP_TOKEN_KW_WHILE
&& MP_TOKEN_KW_WHILE + 1 == MP_TOKEN_KW_WITH
&& MP_TOKEN_KW_WITH + 1 == MP_TOKEN_KW_YIELD
&& MP_TOKEN_KW_YIELD + 1 == MP_TOKEN_OP_TILDE,
"MP_TOKEN order changed, so Code::PythonTextArea::TokenColor might need to change too.");
if (tokenKind >= MP_TOKEN_KW_FALSE && tokenKind <= MP_TOKEN_KW_YIELD) {
return KeywordColor;
}
if (tokenKind >= MP_TOKEN_OP_PLUS && tokenKind <= MP_TOKEN_OP_NOT_EQUAL) {
return OperatorColor;
}
if (tokenKind >= MP_TOKEN_DEL_EQUAL && tokenKind <= MP_TOKEN_DEL_MINUS_MORE) {
static_assert(MP_TOKEN_OP_TILDE + 1 == MP_TOKEN_OP_LESS
&& MP_TOKEN_OP_LESS + 1 == MP_TOKEN_OP_MORE
&& MP_TOKEN_OP_MORE + 1 == MP_TOKEN_OP_DBL_EQUAL
&& MP_TOKEN_OP_DBL_EQUAL + 1 == MP_TOKEN_OP_LESS_EQUAL
&& MP_TOKEN_OP_LESS_EQUAL + 1 == MP_TOKEN_OP_MORE_EQUAL
&& MP_TOKEN_OP_MORE_EQUAL + 1 == MP_TOKEN_OP_NOT_EQUAL
&& MP_TOKEN_OP_NOT_EQUAL + 1 == MP_TOKEN_OP_PIPE
&& MP_TOKEN_OP_PIPE + 1 == MP_TOKEN_OP_CARET
&& MP_TOKEN_OP_CARET + 1 == MP_TOKEN_OP_AMPERSAND
&& MP_TOKEN_OP_AMPERSAND + 1 == MP_TOKEN_OP_DBL_LESS
&& MP_TOKEN_OP_DBL_LESS + 1 == MP_TOKEN_OP_DBL_MORE
&& MP_TOKEN_OP_DBL_MORE + 1 == MP_TOKEN_OP_PLUS
&& MP_TOKEN_OP_PLUS + 1 == MP_TOKEN_OP_MINUS
&& MP_TOKEN_OP_MINUS + 1 == MP_TOKEN_OP_STAR
&& MP_TOKEN_OP_STAR + 1 == MP_TOKEN_OP_AT
&& MP_TOKEN_OP_AT + 1 == MP_TOKEN_OP_DBL_SLASH
&& MP_TOKEN_OP_DBL_SLASH + 1 == MP_TOKEN_OP_SLASH
&& MP_TOKEN_OP_SLASH + 1 == MP_TOKEN_OP_PERCENT
&& MP_TOKEN_OP_PERCENT + 1 == MP_TOKEN_OP_DBL_STAR
&& MP_TOKEN_OP_DBL_STAR + 1 == MP_TOKEN_DEL_PIPE_EQUAL
&& MP_TOKEN_DEL_PIPE_EQUAL + 1 == MP_TOKEN_DEL_CARET_EQUAL
&& MP_TOKEN_DEL_CARET_EQUAL + 1 == MP_TOKEN_DEL_AMPERSAND_EQUAL
&& MP_TOKEN_DEL_AMPERSAND_EQUAL + 1 == MP_TOKEN_DEL_DBL_LESS_EQUAL
&& MP_TOKEN_DEL_DBL_LESS_EQUAL + 1 == MP_TOKEN_DEL_DBL_MORE_EQUAL
&& MP_TOKEN_DEL_DBL_MORE_EQUAL + 1 == MP_TOKEN_DEL_PLUS_EQUAL
&& MP_TOKEN_DEL_PLUS_EQUAL + 1 == MP_TOKEN_DEL_MINUS_EQUAL
&& MP_TOKEN_DEL_MINUS_EQUAL + 1 == MP_TOKEN_DEL_STAR_EQUAL
&& MP_TOKEN_DEL_STAR_EQUAL + 1 == MP_TOKEN_DEL_AT_EQUAL
&& MP_TOKEN_DEL_AT_EQUAL + 1 == MP_TOKEN_DEL_DBL_SLASH_EQUAL
&& MP_TOKEN_DEL_DBL_SLASH_EQUAL + 1 == MP_TOKEN_DEL_SLASH_EQUAL
&& MP_TOKEN_DEL_SLASH_EQUAL + 1 == MP_TOKEN_DEL_PERCENT_EQUAL
&& MP_TOKEN_DEL_PERCENT_EQUAL + 1 == MP_TOKEN_DEL_DBL_STAR_EQUAL
&& MP_TOKEN_DEL_DBL_STAR_EQUAL + 1 == MP_TOKEN_DEL_PAREN_OPEN
&& MP_TOKEN_DEL_PAREN_OPEN + 1 == MP_TOKEN_DEL_PAREN_CLOSE
&& MP_TOKEN_DEL_PAREN_CLOSE + 1 == MP_TOKEN_DEL_BRACKET_OPEN
&& MP_TOKEN_DEL_BRACKET_OPEN + 1 == MP_TOKEN_DEL_BRACKET_CLOSE
&& MP_TOKEN_DEL_BRACKET_CLOSE + 1 == MP_TOKEN_DEL_BRACE_OPEN
&& MP_TOKEN_DEL_BRACE_OPEN + 1 == MP_TOKEN_DEL_BRACE_CLOSE
&& MP_TOKEN_DEL_BRACE_CLOSE + 1 == MP_TOKEN_DEL_COMMA
&& MP_TOKEN_DEL_COMMA + 1 == MP_TOKEN_DEL_COLON
&& MP_TOKEN_DEL_COLON + 1 == MP_TOKEN_DEL_PERIOD
&& MP_TOKEN_DEL_PERIOD + 1 == MP_TOKEN_DEL_SEMICOLON
&& MP_TOKEN_DEL_SEMICOLON + 1 == MP_TOKEN_DEL_EQUAL
&& MP_TOKEN_DEL_EQUAL + 1 == MP_TOKEN_DEL_MINUS_MORE,
"MP_TOKEN order changed, so Code::PythonTextArea::TokenColor might need to change too.");
if ((tokenKind >= MP_TOKEN_OP_TILDE && tokenKind <= MP_TOKEN_DEL_DBL_STAR_EQUAL)
|| tokenKind == MP_TOKEN_DEL_EQUAL
|| tokenKind == MP_TOKEN_DEL_MINUS_MORE)
{
return OperatorColor;
}
return Palette::CodeText;
@@ -53,6 +136,76 @@ static inline size_t TokenLength(mp_lexer_t * lex, const char * tokenPosition) {
return lex->column - lex->tok_column;
}
PythonTextArea::AutocompletionType PythonTextArea::autocompletionType(const char * autocompletionLocation, const char ** autocompletionLocationBeginning, const char ** autocompletionLocationEnd) const {
const char * location = autocompletionLocation != nullptr ? autocompletionLocation : cursorLocation();
const char * beginningOfToken = nullptr;
/* If there is already autocompleting, the cursor must be at the end of an
* identifier. Trying to compute autocompletionType will fail: because of the
* autocompletion text, the cursor seems to be in the middle of an identifier. */
AutocompletionType autocompleteType = isAutocompleting() ? AutocompletionType::EndOfIdentifier : AutocompletionType::NoIdentifier;
if (autocompletionLocationBeginning == nullptr && autocompletionLocationEnd == nullptr) {
return autocompleteType;
}
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
const char * firstNonSpace = UTF8Helper::BeginningOfWord(m_contentView.editedText(), location);
mp_lexer_t * lex = mp_lexer_new_from_str_len(0, firstNonSpace, UTF8Helper::EndOfWord(location) - firstNonSpace, 0);
const char * tokenStart;
const char * tokenEnd;
_mp_token_kind_t currentTokenKind = lex->tok_kind;
while (currentTokenKind != MP_TOKEN_NEWLINE && currentTokenKind != MP_TOKEN_END) {
tokenStart = firstNonSpace + lex->tok_column - 1;
tokenEnd = tokenStart + TokenLength(lex, tokenStart);
if (location < tokenStart) {
// The location for autocompletion is not in an identifier
assert(autocompleteType == AutocompletionType::NoIdentifier);
break;
}
if (location <= tokenEnd) {
if (currentTokenKind == MP_TOKEN_NAME
|| (currentTokenKind >= MP_TOKEN_KW_FALSE
&& currentTokenKind <= MP_TOKEN_KW_YIELD))
{
/* The location for autocompletion is in the middle or at the end of
* an identifier. */
beginningOfToken = tokenStart;
/* If autocompleteType is already EndOfIdentifier, we are
* autocompleting, so we do not need to update autocompleteType. If we
* recomputed autocompleteType now, we might wrongly think that it is
* MiddleOfIdentifier because of the autocompetion text.
* Example : fin|ally -> the lexer is at the end of "fin", but because
* we are autocompleting with "ally", the lexer thinks the cursor is
* in the middle of an identifier. */
if (autocompleteType != AutocompletionType::EndOfIdentifier) {
autocompleteType = location < tokenEnd ? AutocompletionType::MiddleOfIdentifier : AutocompletionType::EndOfIdentifier;
}
}
break;
}
mp_lexer_to_next(lex);
currentTokenKind = lex->tok_kind;
}
mp_lexer_free(lex);
nlr_pop();
}
if (autocompletionLocationBeginning != nullptr) {
*autocompletionLocationBeginning = beginningOfToken;
}
if (autocompletionLocationEnd != nullptr) {
*autocompletionLocationEnd = location;
}
assert(!isAutocompleting() || autocompleteType == AutocompletionType::EndOfIdentifier);
return autocompleteType;
}
const char * PythonTextArea::ContentView::textToAutocomplete() const {
return UTF8Helper::BeginningOfWord(editedText(), cursorLocation());
}
void PythonTextArea::ContentView::loadSyntaxHighlighter() {
m_pythonDelegate->initPythonWithUser(this);
}
@@ -76,23 +229,7 @@ void PythonTextArea::ContentView::clearRect(KDContext * ctx, KDRect rect) const
void PythonTextArea::ContentView::drawLine(KDContext * ctx, int line, const char * text, size_t byteLength, int fromColumn, int toColumn, const char * selectionStart, const char * selectionEnd) const {
LOG_DRAW("Drawing \"%.*s\"\n", byteLength, text);
if (!m_pythonDelegate->isPythonUser(this)) {
const char * lineStart = UTF8Helper::CodePointAtGlyphOffset(text, fromColumn);
const char * lineEnd = UTF8Helper::CodePointAtGlyphOffset(text, toColumn);
drawStringAt(
ctx,
line,
fromColumn,
lineStart,
minPointer(text + byteLength, lineEnd) - lineStart,
StringColor,
BackgroundColor,
selectionStart,
selectionEnd,
HighlightColor
);
return;
}
assert(m_pythonDelegate->isPythonUser(this));
/* We're using the MicroPython lexer to do syntax highlighting on a per-line
* basis. This can work, however the MicroPython lexer won't accept a line
@@ -107,7 +244,7 @@ void PythonTextArea::ContentView::drawLine(KDContext * ctx, int line, const char
line,
fromColumn,
spacesStart,
minPointer(text + byteLength, firstNonSpace) - spacesStart,
std::min(text + byteLength, firstNonSpace) - spacesStart,
StringColor,
BackgroundColor,
selectionStart,
@@ -118,6 +255,8 @@ void PythonTextArea::ContentView::drawLine(KDContext * ctx, int line, const char
return;
}
const char * autocompleteStart = m_autocomplete ? m_cursorLocation : nullptr;
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_lexer_t * lex = mp_lexer_new_from_str_len(0, firstNonSpace, byteLength - (firstNonSpace - text), 0);
@@ -135,7 +274,7 @@ void PythonTextArea::ContentView::drawLine(KDContext * ctx, int line, const char
line,
UTF8Helper::GlyphOffsetAtCodePoint(text, tokenEnd),
tokenEnd,
minPointer(text + byteLength, tokenFrom) - tokenEnd,
std::min(text + byteLength, tokenFrom) - tokenEnd,
StringColor,
BackgroundColor,
selectionStart,
@@ -144,12 +283,16 @@ void PythonTextArea::ContentView::drawLine(KDContext * ctx, int line, const char
}
tokenLength = TokenLength(lex, tokenFrom);
tokenEnd = tokenFrom + tokenLength;
// If the token is being autocompleted, use DefaultColor
KDColor color = (tokenFrom <= autocompleteStart && autocompleteStart < tokenEnd) ? Palette::CodeText : TokenColor(lex->tok_kind);
LOG_DRAW("Draw \"%.*s\" for token %d\n", tokenLength, tokenFrom, lex->tok_kind);
drawStringAt(ctx, line,
UTF8Helper::GlyphOffsetAtCodePoint(text, tokenFrom),
tokenFrom,
tokenLength,
TokenColor(lex->tok_kind),
color,
BackgroundColor,
selectionStart,
selectionEnd,
@@ -161,6 +304,7 @@ void PythonTextArea::ContentView::drawLine(KDContext * ctx, int line, const char
tokenFrom += tokenLength;
// Even if the token is being autocompleted, use CommentColor
if (tokenFrom < text + byteLength) {
LOG_DRAW("Draw comment \"%.*s\" from %d\n", byteLength - (tokenFrom - text), firstNonSpace, tokenFrom);
drawStringAt(ctx, line,
@@ -177,6 +321,22 @@ void PythonTextArea::ContentView::drawLine(KDContext * ctx, int line, const char
mp_lexer_free(lex);
nlr_pop();
}
// Redraw the autocompleted word in the right color
if (m_autocomplete && autocompleteStart >= text && autocompleteStart < text + byteLength) {
assert(m_autocompletionEnd != nullptr && m_autocompletionEnd > autocompleteStart);
drawStringAt(
ctx,
line,
UTF8Helper::GlyphOffsetAtCodePoint(text, autocompleteStart),
autocompleteStart,
std::min(text + byteLength, m_autocompletionEnd) - autocompleteStart,
AutocompleteColor,
BackgroundColor,
nullptr,
nullptr,
HighlightColor);
}
}
KDRect PythonTextArea::ContentView::dirtyRectFromPosition(const char * position, bool includeFollowingLines) const {
@@ -194,4 +354,158 @@ KDRect PythonTextArea::ContentView::dirtyRectFromPosition(const char * position,
);
}
bool PythonTextArea::handleEvent(Ion::Events::Event event) {
if (m_contentView.isAutocompleting()) {
// Handle event with autocompletion
if (event == Ion::Events::Right
|| event == Ion::Events::ShiftRight
|| event == Ion::Events::OK)
{
m_contentView.reloadRectFromPosition(m_contentView.cursorLocation(), false);
acceptAutocompletion(event != Ion::Events::ShiftRight);
if (event != Ion::Events::ShiftRight) {
// Do not process the event more
scrollToCursor();
return true;
}
} else if (event == Ion::Events::Toolbox
|| event == Ion::Events::Var
|| event == Ion::Events::Shift
|| event == Ion::Events::Alpha
|| event == Ion::Events::OnOff)
{
} else if(event == Ion::Events::Up
|| event == Ion::Events::Down)
{
cycleAutocompletion(event == Ion::Events::Down);
return true;
} else {
removeAutocompletion();
m_contentView.reloadRectFromPosition(m_contentView.cursorLocation(), false);
if (event == Ion::Events::Back) {
// Do not process the event more
return true;
}
}
}
bool result = TextArea::handleEvent(event);
if (event == Ion::Events::Backspace && !m_contentView.isAutocompleting() && selectionIsEmpty()) {
/* We want to add autocompletion when we are editing a word (after adding or
* deleting text). So if nothing is selected, we add the autocompletion if
* the event is backspace, as autocompletion has already been added if the
* event added text, in handleEventWithText. */
addAutocompletion();
}
return result;
}
bool PythonTextArea::handleEventWithText(const char * text, bool indentation, bool forceCursorRightOfText) {
if (*text == 0) {
return false;
}
if (m_contentView.isAutocompleting()) {
removeAutocompletion();
}
bool result = TextArea::handleEventWithText(text, indentation, forceCursorRightOfText);
addAutocompletion();
return result;
}
void PythonTextArea::removeAutocompletion() {
assert(m_contentView.isAutocompleting());
removeAutocompletionText();
m_contentView.setAutocompleting(false);
}
void PythonTextArea::removeAutocompletionText() {
assert(m_contentView.isAutocompleting());
assert(m_contentView.autocompletionEnd() != nullptr);
const char * autocompleteStart = m_contentView.cursorLocation();
const char * autocompleteEnd = m_contentView.autocompletionEnd();
assert(autocompleteEnd != nullptr && autocompleteEnd > autocompleteStart);
m_contentView.removeText(autocompleteStart, autocompleteEnd);
}
void PythonTextArea::addAutocompletion() {
assert(!m_contentView.isAutocompleting());
const char * autocompletionTokenBeginning = nullptr;
const char * autocompletionLocation = const_cast<char *>(cursorLocation());
m_autocompletionResultIndex = 0;
if (autocompletionType(autocompletionLocation, &autocompletionTokenBeginning) != AutocompletionType::EndOfIdentifier) {
// The cursor is not at the end of an identifier.
return;
}
// First load variables and functions that complete the textToAutocomplete
const int scriptIndex = m_contentView.pythonDelegate()->menuController()->editedScriptIndex();
m_contentView.pythonDelegate()->variableBoxController()->loadFunctionsAndVariables(scriptIndex, autocompletionTokenBeginning, autocompletionLocation - autocompletionTokenBeginning);
if (addAutocompletionTextAtIndex(0)) {
m_contentView.setAutocompleting(true);
}
}
bool PythonTextArea::addAutocompletionTextAtIndex(int nextIndex, int * currentIndexToUpdate) {
// The variable box should be loaded at this point
const char * autocompletionTokenBeginning = nullptr;
const char * autocompletionLocation = const_cast<char *>(cursorLocation());
AutocompletionType type = autocompletionType(autocompletionLocation, &autocompletionTokenBeginning); // Done to get autocompletionTokenBeginning
assert(type == AutocompletionType::EndOfIdentifier);
(void)type; // Silence warnings
VariableBoxController * varBox = m_contentView.pythonDelegate()->variableBoxController();
int textToInsertLength = 0;
bool addParentheses = false;
const char * textToInsert = varBox->autocompletionAlternativeAtIndex(autocompletionLocation - autocompletionTokenBeginning, &textToInsertLength, &addParentheses, nextIndex, currentIndexToUpdate);
if (textToInsert == nullptr) {
return false;
}
if (textToInsertLength > 0) {
// Try to insert the text (this might fail if the buffer is full)
if (!m_contentView.insertTextAtLocation(textToInsert, const_cast<char *>(autocompletionLocation), textToInsertLength)) {
return false;
}
autocompletionLocation += textToInsertLength;
m_contentView.setAutocompletionEnd(autocompletionLocation);
}
// Try to insert the parentheses if needed
const char * parentheses = ScriptNodeCell::k_parentheses;
constexpr int parenthesesLength = 2;
assert(strlen(parentheses) == parenthesesLength);
/* If couldInsertText is false, we should not try to add the parentheses as
* there was already not enough space to add the autocompletion. */
if (addParentheses && m_contentView.insertTextAtLocation(parentheses, const_cast<char *>(autocompletionLocation), parenthesesLength)) {
m_contentView.setAutocompleting(true);
m_contentView.setAutocompletionEnd(autocompletionLocation + parenthesesLength);
}
return true;
}
void PythonTextArea::cycleAutocompletion(bool downwards) {
assert(m_contentView.isAutocompleting());
removeAutocompletionText();
addAutocompletionTextAtIndex(m_autocompletionResultIndex + (downwards ? 1 : -1), &m_autocompletionResultIndex);
}
void PythonTextArea::acceptAutocompletion(bool moveCursorToEndOfAutocompletion) {
assert(m_contentView.isAutocompleting());
// Save the cursor location
const char * previousCursorLocation = cursorLocation();
removeAutocompletion();
m_contentView.pythonDelegate()->variableBoxController()->setSender(this);
m_contentView.pythonDelegate()->variableBoxController()->insertAutocompletionResultAtIndex(m_autocompletionResultIndex);
// insertAutocompletionResultAtIndex already added the autocompletion
// If we did not want to move the cursor, restore its position.
if (!moveCursorToEndOfAutocompletion) {
setCursorLocation(previousCursorLocation);
}
}
}

View File

@@ -9,21 +9,46 @@ class App;
class PythonTextArea : public TextArea {
public:
enum class AutocompletionType : uint8_t {
EndOfIdentifier,
MiddleOfIdentifier,
NoIdentifier
};
PythonTextArea(Responder * parentResponder, App * pythonDelegate, const KDFont * font) :
TextArea(parentResponder, &m_contentView, font),
m_contentView(pythonDelegate, font)
m_contentView(pythonDelegate, font),
m_autocompletionResultIndex(0)
{
}
void loadSyntaxHighlighter() { m_contentView.loadSyntaxHighlighter(); }
void unloadSyntaxHighlighter() { m_contentView.unloadSyntaxHighlighter(); }
bool handleEvent(Ion::Events::Event event) override;
bool handleEventWithText(const char * text, bool indentation = false, bool forceCursorRightOfText = false) override;
/* autocompletionType returns:
* - EndOfIdentifier if there is currently autocompletion, or if the cursor is
* at the end of an identifier,
* - MiddleOfIdentifier is the cursor is in the middle of an identifier,
* - No identifier otherwise.
* The autocompletionLocation can be provided with autocompletionLocation, or
* retreived with autocompletionLocationBeginning and autocompletionLocationEnd. */
AutocompletionType autocompletionType(const char * autocompletionLocation = nullptr, const char ** autocompletionLocationBeginning = nullptr, const char ** autocompletionLocationEnd = nullptr) const;
bool isAutocompleting() const { return m_contentView.isAutocompleting(); }
protected:
class ContentView : public TextArea::ContentView {
public:
ContentView(App * pythonDelegate, const KDFont * font) :
TextArea::ContentView(font),
m_pythonDelegate(pythonDelegate)
m_pythonDelegate(pythonDelegate),
m_autocomplete(false),
m_autocompletionEnd(nullptr)
{
}
App * pythonDelegate() { return m_pythonDelegate; }
void setAutocompleting(bool autocomplete) { m_autocomplete = autocomplete; }
bool isAutocompleting() const { return m_autocomplete; }
const char * autocompletionEnd() const { assert(m_autocomplete); return m_autocompletionEnd; }
void setAutocompletionEnd(const char * end) { m_autocompletionEnd = end; }
const char * textToAutocomplete() const;
void loadSyntaxHighlighter();
void unloadSyntaxHighlighter();
void clearRect(KDContext * ctx, KDRect rect) const override;
@@ -31,10 +56,19 @@ protected:
KDRect dirtyRectFromPosition(const char * position, bool includeFollowingLines) const override;
private:
App * m_pythonDelegate;
bool m_autocomplete;
const char * m_autocompletionEnd;
};
private:
void removeAutocompletion();
void removeAutocompletionText(); // Just removes the suggested text, not the autocompletion mode
void addAutocompletion();
bool addAutocompletionTextAtIndex(int nextIndex, int * currentIndexToUpdate = nullptr); // Assumes the var box is already loaded
void cycleAutocompletion(bool downwards);
void acceptAutocompletion(bool moveCursorToEndOfAutocompletion);
const ContentView * nonEditableContentView() const override { return &m_contentView; }
ContentView m_contentView;
int m_autocompletionResultIndex;
};
}

View File

@@ -120,7 +120,18 @@ const ToolboxMessageTree MatplotlibPyplotModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandPlot, I18n::Message::PythonPlot),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandScatter, I18n::Message::PythonScatter),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandShow, I18n::Message::PythonShow),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandText, I18n::Message::PythonText)
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandText, I18n::Message::PythonText),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorBlue, I18n::Message::PythonColorBlue, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorRed, I18n::Message::PythonColorRed, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorGreen, I18n::Message::PythonColorGreen, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorYellow, I18n::Message::PythonColorYellow, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorBrown, I18n::Message::PythonColorBrown, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorBlack, I18n::Message::PythonColorBlack, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorWhite, I18n::Message::PythonColorWhite, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorPink, I18n::Message::PythonColorPink, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorOrange, I18n::Message::PythonColorOrange, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorPurple, I18n::Message::PythonColorPurple, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorGrey, I18n::Message::PythonColorGrey, false)
};
const ToolboxMessageTree TurtleModuleChildren[] = {
@@ -141,21 +152,23 @@ const ToolboxMessageTree TurtleModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandPenup, I18n::Message::PythonTurtlePenup, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandPensize, I18n::Message::PythonTurtlePensize),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandIsdown, I18n::Message::PythonTurtleIsdown, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandWrite, I18n::Message::PythonTurtleWrite),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandReset, I18n::Message::PythonTurtleReset, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandShowturtle, I18n::Message::PythonTurtleShowturtle, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandHideturtle, I18n::Message::PythonTurtleHideturtle, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandColor, I18n::Message::PythonTurtleColor, false, I18n::Message::PythonTurtleCommandColorWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandBlue, I18n::Message::PythonTurtleBlue, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandRed, I18n::Message::PythonTurtleRed, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandGreen, I18n::Message::PythonTurtleGreen, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandYellow, I18n::Message::PythonTurtleYellow, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandBrown, I18n::Message::PythonTurtleBrown, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandBlack, I18n::Message::PythonTurtleBlack, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandWhite, I18n::Message::PythonTurtleWhite, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandPink, I18n::Message::PythonTurtlePink, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandOrange, I18n::Message::PythonTurtleOrange, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandPurple, I18n::Message::PythonTurtlePurple, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandGrey, I18n::Message::PythonTurtleGrey, false)
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandColor, I18n::Message::PythonTurtleColor),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandColorMode, I18n::Message::PythonTurtleColorMode),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorBlue, I18n::Message::PythonColorBlue, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorRed, I18n::Message::PythonColorRed, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorGreen, I18n::Message::PythonColorGreen, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorYellow, I18n::Message::PythonColorYellow, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorBrown, I18n::Message::PythonColorBrown, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorBlack, I18n::Message::PythonColorBlack, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorWhite, I18n::Message::PythonColorWhite, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorPink, I18n::Message::PythonColorPink, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorOrange, I18n::Message::PythonColorOrange, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorPurple, I18n::Message::PythonColorPurple, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorGrey, I18n::Message::PythonColorGrey, false)
};
const ToolboxMessageTree RandomModuleChildren[] = {
@@ -243,6 +256,15 @@ const ToolboxMessageTree TimeModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandSleep, I18n::Message::PythonSleep)
};
const ToolboxMessageTree OsModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportOs, I18n::Message::PythonImportOs, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportFromOs, I18n::Message::PythonImportOs, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonOsCommandUname, I18n::Message::PythonOsUname, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonOsCommandRemove, I18n::Message::PythonOsRemove, false, I18n::Message::PythonOsCommandRemoveWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonOsCommandRename, I18n::Message::PythonOsRename, false, I18n::Message::PythonOsCommandRenameWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonOsCommandListdir, I18n::Message::PythonOsListdir, false)
};
const ToolboxMessageTree modulesChildren[] = {
ToolboxMessageTree::Node(I18n::Message::MathModule, MathModuleChildren),
ToolboxMessageTree::Node(I18n::Message::CmathModule, CMathModuleChildren),
@@ -251,6 +273,7 @@ const ToolboxMessageTree modulesChildren[] = {
ToolboxMessageTree::Node(I18n::Message::RandomModule, RandomModuleChildren),
ToolboxMessageTree::Node(I18n::Message::KandinskyModule, KandinskyModuleChildren),
ToolboxMessageTree::Node(I18n::Message::IonModule, IonModuleChildren),
ToolboxMessageTree::Node(I18n::Message::OsModule, OsModuleChildren),
ToolboxMessageTree::Node(I18n::Message::TimeModule, TimeModuleChildren)
};
@@ -277,14 +300,15 @@ const ToolboxMessageTree catalogChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandBackward, I18n::Message::PythonTurtleBackward),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandBar, I18n::Message::PythonBar),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandBin, I18n::Message::PythonBin),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandBlack, I18n::Message::PythonTurtleBlack, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandBlue, I18n::Message::PythonTurtleBlue, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandBrown, I18n::Message::PythonTurtleBrown, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorBlack, I18n::Message::PythonColorBlack, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorBlue, I18n::Message::PythonColorBlue, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorBrown, I18n::Message::PythonColorBrown, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCeil, I18n::Message::PythonCeil),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandChoice, I18n::Message::PythonChoice),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandCircle, I18n::Message::PythonTurtleCircle),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCmathFunction, I18n::Message::PythonCmathFunction, false, I18n::Message::PythonCommandCmathFunctionWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColor, I18n::Message::PythonColor),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandColorMode, I18n::Message::PythonTurtleColorMode),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandComplex, I18n::Message::PythonComplex),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCopySign, I18n::Message::PythonCopySign),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCos, I18n::Message::PythonCos),
@@ -317,8 +341,8 @@ const ToolboxMessageTree catalogChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandGetPixel, I18n::Message::PythonGetPixel),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandGetrandbits, I18n::Message::PythonGetrandbits),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandGoto, I18n::Message::PythonTurtleGoto),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandGreen, I18n::Message::PythonTurtleGreen, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandGrey, I18n::Message::PythonTurtleGrey, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorGreen, I18n::Message::PythonColorGreen, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorGrey, I18n::Message::PythonColorGrey, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandGrid, I18n::Message::PythonGrid),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandHeading, I18n::Message::PythonTurtleHeading, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandHex, I18n::Message::PythonHex),
@@ -364,19 +388,19 @@ const ToolboxMessageTree catalogChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandModf, I18n::Message::PythonModf),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandMonotonic, I18n::Message::PythonMonotonic, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandOct, I18n::Message::PythonOct),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandOrange, I18n::Message::PythonTurtleOrange, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorOrange, I18n::Message::PythonColorOrange, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandPendown, I18n::Message::PythonTurtlePendown, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandPenup, I18n::Message::PythonTurtlePenup, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandPensize, I18n::Message::PythonTurtlePensize),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandPhase, I18n::Message::PythonPhase),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandConstantPi, I18n::Message::PythonConstantPi, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandPink, I18n::Message::PythonTurtlePink, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorPink, I18n::Message::PythonColorPink, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandPolar, I18n::Message::PythonPolar),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandPosition, I18n::Message::PythonTurtlePosition, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandPower, I18n::Message::PythonPower),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandPlot, I18n::Message::PythonPlot),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandPrint, I18n::Message::PythonPrint),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandPurple, I18n::Message::PythonTurtlePurple, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorPurple, I18n::Message::PythonColorPurple, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandRadians, I18n::Message::PythonRadians),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandRandint, I18n::Message::PythonRandint),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandRandom, I18n::Message::PythonRandom, false),
@@ -385,7 +409,7 @@ const ToolboxMessageTree catalogChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandRangeStartStop, I18n::Message::PythonRangeStartStop),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandRangeStop, I18n::Message::PythonRangeStop),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandRect, I18n::Message::PythonRect),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandRed, I18n::Message::PythonTurtleRed, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorRed, I18n::Message::PythonColorRed, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandReset, I18n::Message::PythonTurtleReset, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandRight, I18n::Message::PythonTurtleRight),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandRound, I18n::Message::PythonRound),
@@ -409,8 +433,9 @@ const ToolboxMessageTree catalogChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandTrunc, I18n::Message::PythonTrunc),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandTurtleFunction, I18n::Message::PythonTurtleFunction, false, I18n::Message::PythonCommandTurtleFunctionWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandUniform, I18n::Message::PythonUniform),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandWhite, I18n::Message::PythonTurtleWhite, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandYellow, I18n::Message::PythonTurtleYellow, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorWhite, I18n::Message::PythonColorWhite, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandWrite, I18n::Message::PythonTurtleWrite),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorYellow, I18n::Message::PythonColorYellow, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImag, I18n::Message::PythonImag, false, I18n::Message::PythonCommandImagWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandReal, I18n::Message::PythonReal, false, I18n::Message::PythonCommandRealWithoutArg)
};
@@ -420,11 +445,39 @@ const ToolboxMessageTree functionsChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandReturn, I18n::Message::Default)
};
const ToolboxMessageTree fileChildren[] {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileOpen, I18n::Message::PythonFileOpen, false, I18n::Message::PythonCommandFileOpenWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileClose, I18n::Message::PythonFileClose, false, I18n::Message::PythonCommandFileCloseWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileClosed, I18n::Message::PythonFileClosed, false, I18n::Message::PythonCommandFileClosedWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileMode, I18n::Message::PythonFileMode, false, I18n::Message::PythonCommandFileModeWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileName, I18n::Message::PythonFileName, false, I18n::Message::PythonCommandFileNameWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileRead, I18n::Message::PythonFileRead, false, I18n::Message::PythonCommandFileReadWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileReadable, I18n::Message::PythonFileReadable, false, I18n::Message::PythonCommandFileReadableWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileReadline, I18n::Message::PythonFileReadline, false, I18n::Message::PythonCommandFileReadlineWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileReadlines, I18n::Message::PythonFileReadlines, false, I18n::Message::PythonCommandFileReadlinesWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileSeek, I18n::Message::PythonFileSeek, false, I18n::Message::PythonCommandFileSeekWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileSeekable, I18n::Message::PythonFileSeekable, false, I18n::Message::PythonCommandFileSeekableWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileTell, I18n::Message::PythonFileTell, false, I18n::Message::PythonCommandFileTellWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileTruncate, I18n::Message::PythonFileTruncate, false, I18n::Message::PythonCommandFileTruncateWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileWrite, I18n::Message::PythonFileWrite, false, I18n::Message::PythonCommandFileWriteWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileWritable, I18n::Message::PythonFileWritable, false, I18n::Message::PythonCommandFileWritableWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileWritelines, I18n::Message::PythonFileWritelines, false, I18n::Message::PythonCommandFileWritelinesWithoutArg),
};
const ToolboxMessageTree exceptionsChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::TryExcept1ErrorWithArg, I18n::Message::Default, false, I18n::Message::TryExcept1Error),
ToolboxMessageTree::Leaf(I18n::Message::TryExcept1ErrorElseWithArg, I18n::Message::Default, false, I18n::Message::TryExcept1ErrorElse),
ToolboxMessageTree::Leaf(I18n::Message::TryExcept2ErrorWithArg, I18n::Message::Default, false, I18n::Message::TryExcept2Error),
ToolboxMessageTree::Leaf(I18n::Message::WithInstructionWithArg, I18n::Message::Default, false, I18n::Message::WithInstruction),
};
const ToolboxMessageTree menu[] = {
ToolboxMessageTree::Node(I18n::Message::LoopsAndTests, loopsAndTestsChildren),
ToolboxMessageTree::Node(I18n::Message::Modules, modulesChildren),
ToolboxMessageTree::Node(I18n::Message::Catalog, catalogChildren),
ToolboxMessageTree::Node(I18n::Message::Functions, functionsChildren)
ToolboxMessageTree::Node(I18n::Message::Functions, functionsChildren),
ToolboxMessageTree::Node(I18n::Message::Files, fileChildren),
ToolboxMessageTree::Node(I18n::Message::Exceptions, exceptionsChildren)
};
const ToolboxMessageTree toolboxModel = ToolboxMessageTree::Node(I18n::Message::Toolbox, menu);
@@ -435,6 +488,20 @@ PythonToolbox::PythonToolbox() :
{
}
const ToolboxMessageTree * PythonToolbox::moduleChildren(const char * name, int * numberOfNodes) const {
for (ToolboxMessageTree t : modulesChildren) {
if (strcmp(I18n::translate(t.label()), name) == 0) {
const int childrenCount = t.numberOfChildren();
if (numberOfNodes != nullptr) {
*numberOfNodes = childrenCount;
}
assert(childrenCount > 0);
return static_cast<const ToolboxMessageTree *>(t.childAtIndex(0));
}
}
return nullptr;
}
bool PythonToolbox::handleEvent(Ion::Events::Event event) {
if (Toolbox::handleEvent(event)) {
return true;
@@ -450,7 +517,7 @@ bool PythonToolbox::handleEvent(Ion::Events::Event event) {
}
KDCoordinate PythonToolbox::rowHeight(int j) {
if (typeAtLocation(0, j) == Toolbox::LeafCellType && m_messageTreeModel->label() == I18n::Message::IfStatementMenu) {
if (typeAtLocation(0, j) == Toolbox::LeafCellType && (m_messageTreeModel->label() == I18n::Message::IfStatementMenu || m_messageTreeModel->label() == I18n::Message::Exceptions)) {
/* To get the exact height needed for each cell, we have to compute its
* text size, which means scan the text char by char to look for '\n'
* chars. This is very costly and ruins the speed performance when
@@ -460,7 +527,7 @@ KDCoordinate PythonToolbox::rowHeight(int j) {
* We thus decided to compute the real height only for the ifStatement
* children of the toolbox, which is the only menu that has special height
* rows. */
const ToolboxMessageTree * messageTree = static_cast<const ToolboxMessageTree *>(m_messageTreeModel->children(j));
const ToolboxMessageTree * messageTree = static_cast<const ToolboxMessageTree *>(m_messageTreeModel->childAtIndex(j));
return k_font->stringSize(I18n::translate(messageTree->label())).height() + 2*Metric::TableCellVerticalMargin + (messageTree->text() == I18n::Message::Default ? 0 : Toolbox::rowHeight(j));
}
return Toolbox::rowHeight(j);
@@ -468,7 +535,7 @@ KDCoordinate PythonToolbox::rowHeight(int j) {
bool PythonToolbox::selectLeaf(int selectedRow) {
m_selectableTableView.deselectTable();
ToolboxMessageTree * node = (ToolboxMessageTree *)m_messageTreeModel->children(selectedRow);
ToolboxMessageTree * node = (ToolboxMessageTree *)m_messageTreeModel->childAtIndex(selectedRow);
const char * editedText = I18n::translate(node->insertedText());
// strippedEditedText array needs to be in the same scope as editedText
char strippedEditedText[k_maxMessageSize];
@@ -509,7 +576,7 @@ void PythonToolbox::scrollToLetter(char letter) {
char lowerLetter = tolower(letter);
int index = -1;
for (int i = 0; i < m_messageTreeModel->numberOfChildren(); i++) {
char l = tolower(I18n::translate(m_messageTreeModel->children(i)->label())[0]);
char l = tolower(I18n::translate(m_messageTreeModel->childAtIndex(i)->label())[0]);
if (l == lowerLetter) {
index = i;
break;

View File

@@ -10,7 +10,11 @@ namespace Code {
class PythonToolbox : public Toolbox {
public:
// PythonToolbox
PythonToolbox();
const ToolboxMessageTree * moduleChildren(const char * name, int * numberOfNodes) const;
// Toolbox
bool handleEvent(Ion::Events::Event event) override;
const ToolboxMessageTree * rootModel() const override;
protected:

View File

@@ -65,22 +65,54 @@ bool Script::nameCompliant(const char * name) {
return false;
}
bool Script::importationStatus() const {
assert(!isNull());
Data d = value();
return (((char *)d.buffer)[0] == 1);
uint8_t * StatusFromData(Script::Data d) {
return const_cast<uint8_t *>(static_cast<const uint8_t *>(d.buffer));
}
void Script::toggleImportationStatus() {
bool Script::autoImportationStatus() const {
return getStatutBit(k_autoImportationStatusMask);
}
void Script::toggleAutoimportationStatus() {
assert(!isNull());
Data d = value();
((char *)d.buffer)[0] = (((char *)d.buffer)[0] == 1 ? 0 : 1);
*StatusFromData(d) ^= k_autoImportationStatusMask;
setValue(d);
}
const char * Script::scriptContent() const {
const char * Script::content() const {
Data d = value();
return ((const char *)d.buffer) + StatusSize();
}
bool Script::fetchedFromConsole() const {
return getStatutBit(k_fetchedFromConsoleMask);
}
void Script::setFetchedFromConsole(bool fetched) {
setStatutBit(k_fetchedFromConsoleMask, k_fetchedFromConsoleOffset, fetched);
}
bool Script::fetchedForVariableBox() const {
return getStatutBit(k_fetchedForVariableBoxMask);
}
void Script::setFetchedForVariableBox(bool fetched) {
setStatutBit(k_fetchedForVariableBoxMask, k_fetchedForVariableBoxOffset, fetched);
}
bool Script::getStatutBit(uint8_t mask) const {
assert(!isNull());
Data d = value();
return (const char *)d.buffer + k_importationStatusSize;
return ((*StatusFromData(d)) & mask) != 0;
}
void Script::setStatutBit(uint8_t mask, uint8_t offset, bool statusBit) {
assert(!isNull());
Data d = value();
uint8_t * status = StatusFromData(d);
*status = ((*status) & ~mask) | (static_cast<uint8_t>(statusBit) << offset); //TODO Create and use a bit operations library
setValue(d);
}
}

View File

@@ -5,16 +5,36 @@
namespace Code {
/* Record : | Total Size | Name | Body |
* Script: | AutoImportationStatus | Content |*/
/* Record: | Size | Name | Body |
* Script: | | | Status | Content |
*
*
* |FetchedForVariableBoxBit
* Status is one byte long: xxxxxxxx
* ^ ^
* FetchedFromConsoleBit AutoImportationBit
*
* AutoImportationBit is 1 if the script should be auto imported when the
* console opens.
*
* FetchedFromConsoleBit is 1 if its content has been fetched from the console,
* so we can retrieve the correct variables afterwards in the variable box.
*
* FetchedForVariableBoxBit is used to prevent circular importation problems,
* such as scriptA importing scriptB, which imports scriptA. Once we get the
* variables from a script to put them in the variable box, we switch the bit to
* 1 and won't reload it afterwards. */
class Script : public Ion::Storage::Record {
private:
// Default script names are chosen between script1 and script99
static constexpr int k_maxNumberOfDefaultScriptNames = 99;
static constexpr int k_defaultScriptNameNumberMaxSize = 2; // Numbers from 1 to 99 have 2 digits max
// See the comment at the beginning of the file
static constexpr size_t k_statusSize = 1;
public:
static constexpr size_t k_importationStatusSize = 1;
static constexpr int k_defaultScriptNameMaxSize = 6 + k_defaultScriptNameNumberMaxSize + 1;
/* 6 = strlen("script")
* k_defaultScriptNameNumberMaxSize = maxLength of integers between 1 and 99
@@ -22,11 +42,29 @@ public:
static bool DefaultName(char buffer[], size_t bufferSize);
static bool nameCompliant(const char * name);
static constexpr size_t StatusSize() { return k_statusSize; }
Script(Ion::Storage::Record r) : Record(r) {}
bool importationStatus() const;
void toggleImportationStatus();
const char * scriptContent() const;
Script(Ion::Storage::Record r = Ion::Storage::Record()) : Record(r) {}
bool autoImportationStatus() const;
void toggleAutoimportationStatus();
const char * content() const;
/* Fetched status */
bool fetchedFromConsole() const;
void setFetchedFromConsole(bool fetched);
bool fetchedForVariableBox() const;
void setFetchedForVariableBox(bool fetched);
private:
static constexpr uint8_t k_autoImportationStatusMask = 0b1;
static constexpr uint8_t k_fetchedForVariableBoxOffset = 7;
static constexpr uint8_t k_fetchedFromConsoleOffset = 6;
static constexpr uint8_t k_fetchedForVariableBoxMask = 0b1 << k_fetchedForVariableBoxOffset;
static constexpr uint8_t k_fetchedFromConsoleMask = 0b1 << k_fetchedFromConsoleOffset;
bool getStatutBit(uint8_t offset) const;
void setStatutBit(uint8_t mask, uint8_t offset, bool value);
};
}

View File

@@ -1,33 +1,35 @@
#ifndef CODE_SCRIPT_NODE_H
#define CODE_SCRIPT_NODE_H
#include <stddef.h>
#include <stdint.h>
namespace Code {
class ScriptNode {
public:
enum class Type {
Function = 0,
Variable = 1
enum class Type : bool {
WithoutParentheses,
WithParentheses
};
ScriptNode() :
m_type(Type::Function), m_name(nullptr), m_scriptIndex(0) {}
static ScriptNode FunctionNode(const char * name, uint16_t scriptIndex) {
return ScriptNode(Type::Function, name, scriptIndex);
}
static ScriptNode VariableNode(const char * name, uint16_t scriptIndex) {
return ScriptNode(Type::Variable, name, scriptIndex);
}
ScriptNode(Type type = Type::WithoutParentheses, const char * name = nullptr, int nameLength = -1, const char * nodeSourceName = nullptr, const char * description = nullptr) :
m_type(type),
m_name(name),
m_nodeSourceName(nodeSourceName),
m_description(description),
m_nameLength(nameLength)
{}
Type type() const { return m_type; }
const char * name() const { return m_name; }
uint16_t scriptIndex() const { return m_scriptIndex; }
int nameLength() const { return static_cast<int>(m_nameLength); }
const char * nodeSourceName() const { return m_nodeSourceName; }
const char * description() const { return m_description; }
private:
ScriptNode(Type type, const char * name, uint16_t scriptIndex) :
m_type(type), m_name(name), m_scriptIndex(scriptIndex) {}
Type m_type;
const char * m_name;
uint16_t m_scriptIndex;
const char * m_nodeSourceName;
const char * m_description;
size_t m_nameLength;
};
}

View File

@@ -7,47 +7,51 @@ namespace Code {
constexpr char ScriptNodeCell::k_parentheses[];
constexpr char ScriptNodeCell::k_parenthesesWithEmpty[];
ScriptNodeCell::ScriptNodeView::ScriptNodeView() :
HighlightCell(),
m_scriptNode(nullptr),
m_scriptStore(nullptr)
{
}
void ScriptNodeCell::ScriptNodeView::setScriptNode(ScriptNode * scriptNode) {
m_scriptNode = scriptNode;
}
void ScriptNodeCell::ScriptNodeView::setScriptStore(ScriptStore * scriptStore) {
m_scriptStore = scriptStore;
}
void ScriptNodeCell::ScriptNodeView::drawRect(KDContext * ctx, KDRect rect) const {
ctx->drawString(m_scriptNode->name(), KDPoint(0, Metric::TableCellVerticalMargin), k_font, Palette::CodeText, isHighlighted()? Palette::CodeBackgroundSelected : Palette::CodeBackground);
KDSize nameSize = k_font->stringSize(m_scriptNode->name());
if (m_scriptNode->type() == ScriptNode::Type::Function) {
ctx->drawString(ScriptNodeCell::k_parentheses, KDPoint(nameSize.width(), Metric::TableCellVerticalMargin), k_font, Palette::CodeText, isHighlighted()? Palette::CodeBackgroundSelected : Palette::CodeBackground);
const KDColor backgroundColor = isHighlighted()? Palette::CodeBackgroundSelected : Palette::CodeBackground;
// If it exists, draw the description name.
const char * descriptionName = m_scriptNode->description();
if (descriptionName != nullptr) {
ctx->drawString(descriptionName, KDPoint(0, m_frame.height() - k_bottomMargin - k_font->glyphSize().height()), k_font, Palette::GreyDark, backgroundColor);
}
// Draw the node name
const char * nodeName = m_scriptNode->name();
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, 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, KDColorBlack, backgroundColor);
}
/* If it exists, draw the source name. If it did not fit, we would have put
* nullptr at the node creation. */
const char * sourceName = m_scriptNode->nodeSourceName();
if (sourceName != nullptr) {
KDSize sourceNameSize = k_font->stringSize(sourceName);
ctx->drawString(sourceName, KDPoint(m_frame.width() - sourceNameSize.width(), nodeNameY), k_font, Palette::CodeText, backgroundColor);
}
ctx->drawString(m_scriptStore->scriptAtIndex(m_scriptNode->scriptIndex()).fullName(), KDPoint(0, Metric::TableCellVerticalMargin + nameSize.height() + k_verticalMargin), k_font, Palette::SecondaryText, isHighlighted()? Palette::CodeBackgroundSelected : Palette::CodeBackground);
}
KDSize ScriptNodeCell::ScriptNodeView::minimalSizeForOptimalDisplay() const {
if (m_scriptNode->name() == nullptr) {
return KDSizeZero;
}
KDSize size1 = k_font->stringSize(m_scriptNode->name());
KDSize size2 = k_font->stringSize(m_scriptStore->scriptAtIndex(m_scriptNode->scriptIndex()).fullName());
KDSize size3 = KDSizeZero;
if (m_scriptNode->type() == ScriptNode::Type::Function) {
size3 = k_font->stringSize(ScriptNodeCell::k_parentheses);
}
return KDSize(size1.width() + size3.width() > size2.width() ? size1.width() + size3.width() : size2.width(), Metric::TableCellVerticalMargin + size1.width() + k_verticalMargin + size2.width());
return KDSize(
k_optimalWidth,
m_scriptNode->description() == nullptr ? k_simpleItemHeight : k_complexItemHeight);
}
ScriptNodeCell::ScriptNodeCell() :
TableCell(),
m_scriptNodeView()
{
bool ScriptNodeCell::CanDisplayNameAndSource(int nameLength, const char * source) {
if (source == nullptr) {
return true;
}
assert(nameLength > 0);
const KDFont * font = ScriptNodeView::k_font;
return font->glyphSize().width()*(nameLength + 1) + font->stringSize(source).width() <= ScriptNodeView::k_optimalWidth; // + 1 for the separating space
}
void ScriptNodeCell::setScriptNode(ScriptNode * scriptNode) {
@@ -55,10 +59,6 @@ void ScriptNodeCell::setScriptNode(ScriptNode * scriptNode) {
reloadCell();
}
void ScriptNodeCell::setScriptStore(ScriptStore * scriptStore) {
m_scriptNodeView.setScriptStore(scriptStore);
}
void ScriptNodeCell::setHighlighted(bool highlight) {
TableCell::setHighlighted(highlight);
m_scriptNodeView.setHighlighted(highlight);

Some files were not shown because too many files have changed in this diff Show More