Compare commits

..

226 Commits

Author SHA1 Message Date
Laury
5220dda095 Merge remote-tracking branch 'origin/upsilon-dev' into upsilon-master 2022-05-05 18:02:51 +02:00
Yaya-Cout
7c51b1e55d [apps/code] Fix fr" typing in editor
Fix #217
2022-05-05 17:55:19 +02:00
Laury
7a2ee2bc56 [config] Set upsilon version to 1.0.0 2022-05-04 15:49:24 +02:00
Laury
9f6d52d9d5 [usb] Removing residues from the USB protection 2022-05-04 15:49:11 +02:00
Laury
efb32c9612 [bootloader] Fix "make binpack" in the CI 2022-05-03 18:41:39 +02:00
Laury
caf23dcbab [bootloader] Fix compilation to dfu file 2022-05-03 17:48:16 +02:00
Laury
6a894997fc [flasher] Fixed compilation 2022-05-03 16:34:22 +02:00
Laury
f348d9eb5d [bootloader] Fixed compilation 2022-05-03 16:34:07 +02:00
Laury
0e0dc4a9c2 Revert "[apps] Add Shift + Ans shortcut to go to the last application" 2022-05-02 18:55:46 +02:00
Laury
2be1a6e5a9 [usb] Changed link in descriptor 2022-05-02 17:01:20 +02:00
Laury
adab2c223b [reader] Improved previous position algorithm and fixed symbols 2022-05-01 21:02:07 +02:00
Laury
745099842a [poincare] Fixed two serious bugs in sequences simplification 2022-04-30 19:12:54 +02:00
Yaya-Cout
39f33347f9 Merge remote-tracking branch 'upsilon-yayacout/upsilon-dev-ci-bootloader-fix' into upsilon-master 2022-04-29 22:04:52 +02:00
Yaya-Cout
03ae762b4a [external] Updated for compatibility with KhiCAS 2022-04-29 22:00:12 +02:00
Laury
5b7bdc1ec1 Revert "[external] First attempt to merge Khi external API"
This reverts commit 38796253cb.
2022-04-28 21:33:01 +02:00
Laury
7d61e236df [bootloader] Small fixes 2022-04-28 21:32:42 +02:00
devdl11
7f8e6a6b87 Merged new bootloader
Co-authored-by: Yaya-Cout <yaya.cout@free.fr>
2022-04-27 21:02:04 +02:00
devdl11
9c69379096 fix 2022-04-27 20:37:39 +02:00
Yaya-Cout
aff5803ef3 [CI] Fix bootloader CI 2022-04-27 20:07:08 +02:00
devdl11
fd7bdc7345 Dumb error fix 2022-04-27 19:56:37 +02:00
Yaya-Cout
807945ad0f [CI] Fix bench.flash 2022-04-27 19:45:55 +02:00
devdl11
35f09ed389 Merge branch 'upsilon-new-bootloader' of https://github.com/devdl11/Upsilon into upsilon-new-bootloader 2022-04-27 19:25:03 +02:00
devdl11
c73b13bd41 Some code 2022-04-27 19:24:59 +02:00
devdl11
47558446c4 Update bootloader/interface/menus/dfu.h
Co-authored-by: Yaya-Cout <yaya.cout@free.fr>
2022-04-27 18:56:06 +02:00
devdl11
45b4dd337c Update bootloader/interface/static/messages.h
Co-authored-by: Yaya-Cout <yaya.cout@free.fr>
2022-04-27 15:46:31 +02:00
devdl11
0332f43c5c Reviews 2022-04-27 15:44:42 +02:00
Yaya-Cout
667bac136b Merge remote-tracking branch 'upsilon-yayacout/upsilon-dev-autocompletion-fix' into upsilon-master 2022-04-27 15:26:58 +02:00
Yaya-Cout
b15d49511d [apps/python] Use super implementation in the select sub menu function of the toolbox 2022-04-27 14:06:02 +02:00
devdl11
04ae526a39 Removing useless file 2022-04-26 18:10:34 +02:00
devdl11
0e49d23faa Apply suggestions from code review
Co-authored-by: Yaya-Cout <yaya.cout@free.fr>
2022-04-26 15:26:34 +02:00
Laury
595c69bfcf Merged upsilon-dev 2022-04-26 12:48:52 +02:00
devdl11
18ff283580 Boot fix 2022-04-25 19:52:58 +02:00
devdl11
42368ecd6e second patch 2022-04-25 18:40:55 +02:00
devdl11
27cf6a0615 Fix CLI bootloader 2022-04-25 18:35:16 +02:00
devdl11
5ed8aef907 Bootloader pre-release 2022-04-25 18:22:19 +02:00
Laury
3c53421ffa [poincare] Added simplification of nested radicals 2022-04-23 23:10:58 +02:00
Laury
d10d1cd65d [rpn] Updated submodule to fix dirty line 2022-04-17 21:57:47 +02:00
Laury
cec75bfaed [rpn] Updated submodules 2022-04-17 18:05:58 +02:00
Laury
77352e34b5 [storage] Possibility to store metadata with records (cursor in scripts) 2022-04-15 22:30:53 +02:00
Laury
38796253cb [external] First attempt to merge Khi external API 2022-04-15 22:30:35 +02:00
Yaya.Cout
4b7631e78a [apps/apps_container_storage.cpp] Add an assert 2022-04-15 22:19:32 +02:00
Yaya.Cout
c54a97a03d [apps/apps_container_storage.cpp] Add newline 2022-04-15 22:19:32 +02:00
Yaya.Cout
d42e4269a9 [apps] Add Shift + Ans shortcut to go to the last application 2022-04-15 22:19:32 +02:00
Laury
2bf6de5044 [reader] Fixed bug when a word is too big 2022-04-15 22:19:31 +02:00
Laury
22ba190542 [calculation] Fix bug in calculation store 2022-04-15 22:19:31 +02:00
Nithin
0e24823511 Fix Readme Links (#210) 2022-04-15 18:50:17 +02:00
Yaya.Cout
f174fbc3f5 [apps/code] Fix Key selector in auto completion
Scenario: Go in the Python editor and type "from ion import *",
          then type "K" and see what happens.
This fix UpsilonNumworks#198
2022-04-15 17:05:19 +02:00
Lauryy06
4ca7d9208c [escher] Changed PopUpTopMargin in metrics (#201) 2022-04-10 22:17:52 +02:00
LeMoustachu
2bfc243e5a update atomic submodule (#208) 2022-04-09 19:08:04 +02:00
devdl11
add333b920 [bootloade] Fix freezing 2022-04-09 11:08:02 +02:00
devdl11
eeff886cc1 [bootloader > menus] Improvement 2022-04-09 11:02:34 +02:00
devdl11
ff307b8df8 [bootloader > interfaces] Interface improvement 2022-04-08 23:44:24 +02:00
devdl11
21f08a2d06 [bootloader/interface] Yaya-cout commit 2022-04-08 18:53:26 +02:00
devdl11
c837709801 [flasher] Fix old dfu code 2022-04-08 18:40:08 +02:00
devdl11
a0caf67d7c [review] revert flasher code 2022-04-08 18:33:27 +02:00
devdl11
f4e84bc208 Update ion/src/device/n0110/internal_flash.ld
Co-authored-by: Yaya-Cout <67095734+Yaya-Cout@users.noreply.github.com>
2022-04-08 18:07:28 +02:00
devdl11
225b942989 Update ion/src/device/shared/usb/dfu.ld
Co-authored-by: Yaya-Cout <67095734+Yaya-Cout@users.noreply.github.com>
2022-04-08 18:07:11 +02:00
devdl11
3b955c2eb6 Update ion/src/device/n0110/drivers/board.cpp
Co-authored-by: Yaya-Cout <67095734+Yaya-Cout@users.noreply.github.com>
2022-04-08 18:06:59 +02:00
devdl11
0e46954f80 Update ion/src/device/shared/usb/dfu_interface.h
Co-authored-by: Yaya-Cout <67095734+Yaya-Cout@users.noreply.github.com>
2022-04-08 18:06:22 +02:00
devdl11
bf1d570623 Update ion/src/device/shared/usb/dfu_relocated.cpp
Co-authored-by: Yaya-Cout <67095734+Yaya-Cout@users.noreply.github.com>
2022-04-08 18:06:15 +02:00
devdl11
5f50f3fc9c Update ion/src/device/shared/usb/stack/device.cpp
Co-authored-by: Yaya-Cout <67095734+Yaya-Cout@users.noreply.github.com>
2022-04-08 18:06:07 +02:00
devdl11
4a830a0f30 Update ion/src/device/n0100/flash.ld
Co-authored-by: Yaya-Cout <67095734+Yaya-Cout@users.noreply.github.com>
2022-04-08 18:05:57 +02:00
devdl11
01c3f767e4 Update ion/src/device/bootloader/usb/Makefile
Co-authored-by: Yaya-Cout <67095734+Yaya-Cout@users.noreply.github.com>
2022-04-08 18:03:32 +02:00
devdl11
3c098b684b Update bootloader/usb_data.h
Co-authored-by: Yaya-Cout <67095734+Yaya-Cout@users.noreply.github.com>
2022-04-08 18:03:19 +02:00
devdl11
e886863230 Update bootloader/messages.h
Co-authored-by: Yaya-Cout <67095734+Yaya-Cout@users.noreply.github.com>
2022-04-08 18:03:11 +02:00
devdl11
7ce3aac2f6 Update bootloader/messages.h
Co-authored-by: Yaya-Cout <67095734+Yaya-Cout@users.noreply.github.com>
2022-04-08 18:02:56 +02:00
devdl11
3c26035feb [Review] Class to namespace 2022-04-08 14:01:55 +02:00
devdl11
ff40b8b862 Merge branch 'upsilon-new-bootloader' of https://github.com/devdl11/Upsilon into upsilon-new-bootloader 2022-04-08 13:50:39 +02:00
devdl11
62e98107f7 [Reviews] Code correction and improvement 2022-04-08 13:49:44 +02:00
devdl11
7a6c211001 Update bootloader/itoa.cpp
Co-authored-by: Lauryy06 <80424145+Lauryy06@users.noreply.github.com>
2022-04-08 13:20:56 +02:00
devdl11
80f099c274 Update bootloader/usb_data.cpp
Co-authored-by: Lauryy06 <80424145+Lauryy06@users.noreply.github.com>
2022-04-08 13:17:43 +02:00
devdl11
d3754a931a Update bootloader/itoa.h
Co-authored-by: Lauryy06 <80424145+Lauryy06@users.noreply.github.com>
2022-04-08 13:17:27 +02:00
devdl11
3af3d70055 Update bootloader/itoa.cpp
Co-authored-by: Lauryy06 <80424145+Lauryy06@users.noreply.github.com>
2022-04-08 13:17:11 +02:00
devdl11
8db051474c Update bootloader/itoa.cpp
Co-authored-by: Lauryy06 <80424145+Lauryy06@users.noreply.github.com>
2022-04-08 13:17:04 +02:00
devdl11
3328bc28b9 Update bootloader/itoa.cpp
Co-authored-by: Lauryy06 <80424145+Lauryy06@users.noreply.github.com>
2022-04-08 13:16:52 +02:00
devdl11
c65b1c6d3c [Review] Review Update 2022-04-07 22:18:05 +02:00
devdl11
15801ae9e4 [DFU] Fix simulators 2022-04-07 20:07:03 +02:00
devdl11
3dfc8d749c [bootloader/storage] new bootloader and fix python issue 2022-04-07 19:56:53 +02:00
lolocomotive
9f7aba4593 Run upload to firebase only when on UpsilonNumworks/Upsilon on upsilon-dev (#197) 2022-04-06 21:43:46 +02:00
Yaya.Cout
5365718761 [bootloader] Fix building with no computer and cable icons 2022-04-05 18:23:02 +02:00
Yaya.Cout
c0c1615f14 [apps] Swap graph and rpn apps
Close #195
2022-04-03 09:56:07 +02:00
Laury
a770ee919b [code] End of revert #113 2022-03-31 22:23:21 +02:00
Laury
7e64124ddc Revert #113 because of incompatibility with the workshop 2022-03-31 22:19:54 +02:00
Andrej
e2598031c8 [escher] Changed font in Toolbox expressions to LargeFont for better readability and aesthetics (#190) 2022-03-31 16:10:05 +02:00
Yaya.Cout
2ebc1bc22f [apps] Add Shift + EE to go to the settings
Before, EE go to the settings, because ShiftEE event wasn't correctly bound :
It was bound to a simple press of the key, and not to a Shift press.
This commit keep this behavior, but add the correct binding (Shift + EE).

This fix #194.
2022-03-30 19:25:43 +02:00
Yaya.Cout
202c273c67 [apps/graph] Separate Cyan from Blue (fix #192)
This separate the Cyan colour's name from the blue, before this commit, it was the same text
2022-03-30 08:18:18 +02:00
Mino1289
45229b80cd [python] Support more operators overload (classes) (#188) 2022-03-28 20:59:21 +02:00
Laury
b675a78a87 [ion] Part of the fix for CI 2022-03-28 19:25:29 +02:00
Laury
15f0833f3b [ion] Fix compilation 2022-03-28 18:23:22 +02:00
Laury
e40d63a6ff Merge Upsilon-dev 2022-03-23 22:02:27 +01:00
Laury
323eba63e1 Merge with Omega-dev 2022-03-23 21:51:06 +01:00
Yaya-Cout
3b293c822a [apps/graph] Added a color menu in graph and list (#189)
* Revert "[github/workflows] Update Metrics to remove NumWorksBot"

This reverts commit 110f333122.

* Added a color menu in graph and list

* Fixed color select display issue and build issue

* Changed color_cell to a circle

* Revert "Changed color_cell to a circle"

This reverts commit 28dddb42af.

* Color_cell with mask

* Fixed build issue

* Color selection : Added right handle and color name display in menu

* Fixed constexpr static colorMask

* Changed font in color_parameter_controller

* Fix building without debug

* Re-Fix building without debug

* Update colors

Co-authored-by: Hugo Saint-Vignes <hugo.saint-vignes@numworks.com>
Co-authored-by: Joachim LF <joachimlf@pm.me>
2022-03-23 08:36:23 +01:00
Yaya-Cout
8ac969d772 [Feature] Backlight settings (#137)
* Added backlight settings

* Changed location of the brightness setting

* Fix row size of brightness settings

* [apps/settings/brightness] Update translations

* Fix dimmer

* Update translations

* [apps/settings] Add dimmer duration setting

* [apps/settings] Ensure of the brightness level is greater than the dimmed brightness level

* Make transition smooth

* Removed transition time setting
I personally think that this setting is completely useless except if you absolutely want a transition that is not smooth, which is weird.

* Moved everything related to brightness in one submenu

* Some refactoring

* Update defaults

* Removed unnecessary translation

* [apps/settings] Fix Shift + Minus/Plus in settings

* Apply suggestions from code review

* [apps/shared] Remove a think that I don't know what it is

* Apply review suggestions

Co-authored-by: Joachim LF <joachimlf@pm.me>
Co-authored-by: lolocomotive <lolocomotive181@gmail.com>
2022-03-22 17:59:52 +01:00
Yaya-Cout
865bacf89a [build/utilities] Add translations clean script (#179) 2022-03-20 16:10:54 +01:00
Assim ZEMOUCHI
841ac7d5f4 [ion] Fix win11 build for n0110 (#182) (#183) 2022-03-20 16:09:02 +01:00
Yaya-Cout
c92c4d8383 [apps/reader] Add slanted arrows, \in, \cdot, \cdots and \ldots (#184) 2022-03-20 16:08:39 +01:00
Laury
97a168052b [code] Improved code quality in gutter view resize 2022-03-19 23:39:44 +01:00
devdl11
42343d562c [ code ] Gutter improvement (#71) (#168) 2022-03-19 19:01:50 +01:00
Laury
3740a93a9f [ion] Fixed CI 2022-03-19 17:59:07 +01:00
Laury
6dc31401fe [bootloader] Compatibility with Omega 2.0 2022-03-17 20:05:20 +01:00
Maxime FRIESS
8c3378a723 [ion/bootloader] Fixed wrong trampoline call. 2022-03-16 00:06:24 +01:00
Maxime FRIESS
126bdd68bb Merge pull request #2 from quentinguidee/fix-assert-external-flash
[ion/external_flash] Fix SectorAtAddress assert()
2022-03-15 23:59:42 +01:00
Quentin Guidée
f1c24db90a [ion/external_flash] Fix SectorAtAddress assert() 2022-03-15 22:41:51 +01:00
Maxime FRIESS
fd4a2205f3 Merge pull request #1 from quentinguidee/fix-macos-simulator
[Simulator] Fix macOS compilation
2022-03-15 22:36:08 +01:00
Quentin Guidée
fc252672cc [Simulator] Fix macOS compilation 2022-03-15 22:14:08 +01:00
Laury
1c918f549c [ion] Try a fix to make compilation work 2022-03-13 21:43:14 +01:00
Laury
72a25ec26d [ion] Rework of storage trash 2022-03-13 21:32:35 +01:00
M4x1m3
bdfae184e9 [config.mak] Omega 2.0.0 2022-03-10 19:34:49 +01:00
M4x1m3
23936a0c63 [themes] Fixed building bootloader 2022-03-10 19:34:49 +01:00
M4x1m3
209428ca9d [bootloader] Made bootloader Upsilon-aware 2022-03-10 19:34:49 +01:00
M4x1m3
370eb14a04 [build] Fixed wrong model comparaison 2022-03-10 19:34:48 +01:00
lolocomotive
bf8f8bcb27 Fix web simulator 2022-03-10 19:34:48 +01:00
M4x1m3
fc3941511f [build] Fixed bootloader build system 2022-03-10 19:34:48 +01:00
M4x1m3
9fda743de9 [build/bootloader] Rewrote binpack 2022-03-10 19:34:48 +01:00
M4x1m3
74ef528845 [build] Added "bootloader" target 2022-03-10 19:34:48 +01:00
M4x1m3
7a2721c979 [bootloader] Allow quitting the DFU stack 2022-03-10 19:34:48 +01:00
M4x1m3
227ca616ca [bootloader] Boot other slot if a slot is invalid 2022-03-10 19:34:48 +01:00
M4x1m3
1c04949336 [bootloader] Added custom trampolines 2022-03-10 19:34:48 +01:00
M4x1m3
93099ad808 [bootloader] Expose ExternalFlash instead of Flash 2022-03-10 19:34:47 +01:00
M4x1m3
88b4e904c0 [ion/external_flash] Take absolute address for WriteMemory 2022-03-10 19:34:47 +01:00
M4x1m3
dee783065b [bootloader] Use custom USB descriptor 2022-03-10 19:34:47 +01:00
M4x1m3
5a7b076ebe [bootloader] Added dual boot 2022-03-10 19:34:47 +01:00
M4x1m3
85ef57f7ed [bootloader] Added userland header, rewrote lernel header 2022-03-10 19:34:47 +01:00
M4x1m3
63c2b99260 [ion/simulator] Fixed simulator 2022-03-10 19:34:47 +01:00
M4x1m3
377f4eee0c [ci] Build bootloader 2022-03-10 19:34:47 +01:00
M4x1m3
a63cbcf0c2 [bootloader] Make work with Numworks workshop 2022-03-10 19:34:47 +01:00
M4x1m3
f2c17121d2 [bootloader] Added trampolines 2022-03-10 19:34:46 +01:00
M4x1m3
d16808183b [bootloader] MPU config 2022-03-10 19:34:46 +01:00
M4x1m3
6eabe9acae [ion/n0110] Fixed invalid assert in external flash driver 2022-03-10 19:34:46 +01:00
M4x1m3
e1dcbad18a [bootloader] Run usb stack on Reset+4 2022-03-10 19:34:46 +01:00
M4x1m3
4fe84a4959 [bootloader] Added slot definition 2022-03-10 19:34:46 +01:00
M4x1m3
272797f31f [bootloader] Added bootloader 2022-03-10 19:34:46 +01:00
M4x1m3
c635f4e2b9 [ci] Add building Omega for bootloader 2022-03-10 19:34:46 +01:00
M4x1m3
c8ba2fd268 [build/bootloader] Allow building slot A and B 2022-03-10 19:34:46 +01:00
M4x1m3
3a391261c7 [ion/bootloader/usb] Removed internal flash from descriptior 2022-03-10 19:34:45 +01:00
M4x1m3
2da1610b27 [build/bootloader] Include extrnal 2022-03-10 19:34:45 +01:00
M4x1m3
5e130cc4f2 [ion/bootloader] Made suspend work 2022-03-10 19:34:45 +01:00
M4x1m3
2b5a773993 [ion/bootloader] Made exam mode work 2022-03-10 19:34:39 +01:00
BAALBAKYA
19e5562228 2 corrections of bugs about the battery level in the settings (#148)
* added battery level handler for simulator

* added battery level > 100% when charging

* corrected version

* laury version but with float type

* Update apps/settings/sub_menu/about_controller.cpp

* Update apps/settings/sub_menu/about_controller.cpp

Co-authored-by: = <=>
Co-authored-by: Lauryy06 <80424145+Lauryy06@users.noreply.github.com>
2022-03-03 17:16:24 +01:00
Yaya.Cout
9edf026110 [python] Fix brackets in get_keys() 2022-03-01 18:59:22 +01:00
M4x1m3
ffb4c39e04 [ion] Added bootloader device 2022-02-27 00:32:24 +01:00
M4x1m3
61673cd1b5 [apps] Reduced heap to make room for SVC table 2022-02-25 15:07:47 +01:00
Laury
f95f9ebb2d [poincare] Better simplification of sequences 2022-02-24 18:48:10 +01:00
Laury
23af100ed5 [poincare] Allow replacement of sequences by their definition if rank is an integer 2022-02-24 18:05:30 +01:00
Laury
c7516f1464 [settings] Fixed name of contributors 2022-02-22 20:44:16 +01:00
Laury
23a94b7f50 [calculation] Simplify angles in additional outputs and fix an assert in calculation store 2022-02-21 17:30:27 +01:00
Laury
af5f9ea578 [ion/storage] Added the "ctrl-z" system everywhere 2022-02-19 12:09:02 +01:00
Laury
f3d632c462 [apps/calculation] Add a "ctrl-z" system 2022-02-15 22:24:50 +01:00
Laury
893a2a550d [reader] Fixed a bug in list of books 2022-02-14 20:52:33 +01:00
Laury
2443fa7d57 Merge branch 'upsilon-dev' of https://github.com/UpsilonNumworks/Upsilon into upsilon-dev 2022-02-11 19:52:34 +01:00
Yaya-Cout
4f0f41be56 [python] Add FStrings support (#155) 2022-02-09 22:21:07 +01:00
Yaya-Cout
5eb0598107 [apps/code] Add documentation on math.factorial (#146) 2022-02-06 19:06:48 +01:00
LeMoustachu
43b56f3a89 Update doc titlebar to match upsilon color. (#145) 2022-02-05 19:01:47 +01:00
Laury
034fc65bc2 [settings] Updated contributors ! 2022-02-05 19:00:33 +01:00
LeMoustachu
9ab3e6c715 remove white reader icon background in omega_dark (#144) 2022-02-05 13:49:47 +01:00
Jules
d8f93709b8 Update README.fr.md (#142) 2022-02-04 13:14:32 +01:00
Laury
708070c284 [calculation] Fix (again) a bug in second degree additional output 2022-02-02 23:16:52 +01:00
Laury
9632b59b67 [reader] Separated .urt and .txt files 2022-02-02 23:16:52 +01:00
LeMoustachu
a0afbe9916 Update building docs and french readme (#136) 2022-02-02 22:19:36 +01:00
Yaya-Cout
100917f29f [build] Add auto translate script (#140) 2022-02-02 22:18:45 +01:00
Yaya-Cout
814e2dee06 [python] Enable math.factorial (#141) 2022-02-02 22:18:04 +01:00
lolocomotive
1a546e011b Upload artifacts to google cloud (#138) 2022-02-01 19:43:46 +01:00
Yaya-Cout
1faac23ee8 [apps/settings] Fix assert in about submenu when username enabled (#134) 2022-01-25 20:17:07 +01:00
Yaya-Cout
38614a849f [apps/python] Add set_brightness and get_brightness in Ion module (#132) 2022-01-25 18:58:25 +01:00
Yaya-Cout
24205a7e03 Fix CI and replacement character (#133) 2022-01-24 18:22:07 +01:00
Yaya-Cout
f4ce415e32 [apps/code] Fix multiplication in Python app on simulator (#126) 2022-01-21 16:51:58 +01:00
Yaya-Cout
169fb7404e Fix spelling (#128)
* Fix spelling in .cpp files

* Fix spelling in all files
2022-01-20 17:21:35 +01:00
Laury
e575ffc7ce [apps/code] Shift + OK don't quit toolbox 2022-01-15 21:33:32 +01:00
Laury
f591816122 [apps/functions] Save if user want display derivative even when quitting the app 2022-01-15 12:40:06 +01:00
Laury
cbbe7ef6ac [poincare] Fix bug in equal simplifcation 2022-01-15 11:07:06 +01:00
Yaya-Cout
f862cb023a [apps/code] Add a setting for cursor saving (#125) 2022-01-14 13:42:30 +01:00
Laury
f296778014 [python] Moved get_keys to ion module 2022-01-14 13:36:11 +01:00
Laury
16eaab3b52 [apps/calculation] Make the second_degree_controller works 2022-01-13 18:57:34 +01:00
Laury
77707cd930 [kandinsky] Fix bugs in fill_polygon and removed the limit of 32 points 2022-01-13 17:23:25 +01:00
apoleon33
a3e2c9732f fix link to the discord (#122) 2022-01-12 22:25:26 +01:00
Overengined
98c919db88 added mention of the installer in the readme (#119) 2022-01-10 22:20:30 +01:00
Yaya-Cout
8126e0da7e Fix cursor storage (#120) 2022-01-10 20:53:38 +01:00
Laury
685e73c52d [reader] Make reader works ! 2022-01-09 21:47:53 +01:00
Laury
64a90422c4 [settings] Removed auto usb reactivation 2022-01-09 21:47:53 +01:00
Laury
fea588bd9d [escher/timer] Little code quality improvement 2022-01-09 21:47:53 +01:00
Laury
9595ed1570 [calculation] Fix a bug in second degree controller 2022-01-09 21:47:53 +01:00
Laury
4f63100195 [theme] Added reader icons 2022-01-09 21:47:52 +01:00
Laury
ed06b4e48b [python/ulab] Updated ulab 2022-01-09 21:47:52 +01:00
Laury
d5dbb8df6f [reader] Make fonts better 2022-01-09 21:47:51 +01:00
Mino1289
fdef2b5d6e Merge branch 'upsilon-dev-latex' 2022-01-09 21:47:51 +01:00
Laury
7fc28f8b72 [reader] Added detection of rich text files (.urt) TODO: parse differently this files 2022-01-09 21:47:51 +01:00
lolocomotive
2248e415c4 Separate Upsilon and Omega versions (#112) 2022-01-04 20:37:46 +01:00
lolocomotive
1da537479f Fix CI (#115) 2021-12-28 21:51:52 +01:00
devdl11
0860e48cb6 For those who likes to code ❤ (#113) 2021-12-28 15:13:01 +01:00
Yaya-Cout
70b162e63b Fix web simulator and binpack build (#114) 2021-12-28 15:12:13 +01:00
Joachim Le Fournis
398e974ccd Fix ODR warnings (#107) 2021-12-22 17:40:28 +01:00
Yaya-Cout
d57e19ae70 Add natural dimer (#106) 2021-12-18 14:34:35 +01:00
Mino1289
87a5dc354d [apps/calculation/additional_output] Adding parenthesis. (#97) 2021-12-17 22:17:21 +01:00
Yaya-Cout
cd3f5225bb Various fixes (#102) 2021-12-17 19:12:24 +01:00
Lauryy06
139ef4a052 Merge pull request #104 from lemoustachu/upsilon-dev 2021-12-17 18:58:47 +01:00
Lauryy06
66afb977db Merge pull request #103 from lolocomotive/patch-2 2021-12-17 18:57:22 +01:00
Lauryy06
cb9dc38fa9 Merge pull request #101 from Yaya-Cout/mpy-update 2021-12-17 18:43:53 +01:00
LeMoustachu
67e42aaac3 Readme update for wsl usb support 2021-12-17 17:54:44 +01:00
lolocomotive
f1be48bdb1 Use a fallback theme
This allows themes to be incomplete (with missing values), which leads to following benefits:
- Older themes that have not been updated to have the latest colors will not result in compilation errors
- If you only want to change one single color you don't have to copy the whole json file which makes it much more readable
2021-12-15 23:38:54 +01:00
Yaya.Cout
ed5cff15c6 Fix sys in Python toolbox 2021-12-15 18:35:41 +01:00
Lauryy06
963647d59f Merge pull request #100 from Yaya-Cout/mpy-update
MicroPython update
2021-12-15 14:36:46 +01:00
Yaya.Cout
a14f2015cf Remove sys module 2021-12-15 14:31:07 +01:00
Yaya.Cout
dbbf27e59b Fix sys module 2021-12-15 13:40:13 +01:00
ArtichautCosmique
65b3a2857f [ion/simulator/assets] New background.jpg (#99) 2021-12-15 13:39:51 +01:00
devdl11
dd48235721 USB Protection correction (#90) 2021-12-14 21:51:53 +01:00
Yaya.Cout
46041e8e9a Fix Matplotlib 2021-12-14 19:06:50 +01:00
Yaya.Cout
38faecda29 Update MicroPython from 1.12 to 1.17 2021-12-14 18:18:45 +01:00
ArtichautCosmique
0bd30ed2e6 [ion/simulator/assets] New icons Upsilon flavored (#98) 2021-12-13 19:37:12 +01:00
Laury
5cbce3c116 [calculation] Fix a bug in second degree controller 2021-12-09 19:05:42 +01:00
ArtichautCosmique
665de51bae [toolbar] Fix battery icon width when "half full battery" (#93) 2021-12-08 22:12:52 +01:00
apoleon33
47e3036afd [readme] changed link to the discord server (#88)
in the LISEZ_MOI.md
2021-11-29 20:27:29 +01:00
Yaya-Cout
1df3ef87e6 [apps/settings] Fix voltage in settings (#86)
* [apps/settings] Fix voltage in settings

* [apps/settings] Fix batteryLevel size
2021-11-28 19:07:48 +01:00
Laury
4222137549 [apps/code] Improve code style in syntax highlighting setting 2021-11-27 13:42:47 +01:00
Yaya-Cout
806b11b589 [apps/code] Add a setting for syntax highlighting (#85) 2021-11-27 12:34:09 +01:00
Laury
fb4b2ffdfa [usb | recovery] Make the code works 2021-11-26 23:41:53 +01:00
Laury
d2ec87d9fd Merge branch 'upsilon-dev-usb-protection' into upsilon-dev 2021-11-21 21:53:53 +01:00
Laury
6b12d1aebf [settings] Translations and bug fixed 2021-11-21 21:53:33 +01:00
Laury
9afb42716d [usb | recovery] Improve code quality 2021-11-21 21:48:51 +01:00
Thibaut
2d4c0f18d0 Update of a name in the list of contributors (#83) 2021-11-18 19:24:51 +01:00
lolocomotive
918c9249db Partly fix #66 (#82)
Removed the double V appearing sometimes
2021-11-17 12:19:44 +01:00
Quentin Guidée
cf33f84106 [config.mak] Omega 1.23.0 2021-11-11 22:13:07 +01:00
ArtichautCosmique
df7b97bb87 [toolbar] Pimp my battery (#80) 2021-11-11 18:48:01 +01:00
devdl11
e8a1bc6149 Creation of a protection system against unintentional updates to Epsilon 16 (foundation) + Recovery Improvement (#37) 2021-11-11 18:20:16 +01:00
Lauryy06
b304a2ff7d [github] Update bug_report.md 2021-11-11 17:47:12 +01:00
Mino1289
50ee8021f3 [apps/settings] Fixing newline with Flag checking (#77) 2021-11-09 19:28:45 +01:00
lolocomotive
ed7e0bd915 Show battery percentage in about menu (#69) 2021-11-05 13:46:42 +01:00
855 changed files with 29656 additions and 9441 deletions

View File

@@ -23,5 +23,7 @@ A clear and concise description of what you expected to happen.
**Screenshots** **Screenshots**
If applicable, add screenshots to help explain your problem. If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):** **Device (please complete the following information):**
- The device on which you're running Upsilon (computer, n0110, n0100, etc...)
- Upsilon Version: [go to settings > about > Upsilon Version and type the version here] - Upsilon Version: [go to settings > about > Upsilon Version and type the version here]
- Upsilon commit: [settings > about > click one time on epsilon version]

View File

@@ -17,7 +17,6 @@ on:
description: 'Run 3DS tests' description: 'Run 3DS tests'
required: true required: true
default: 'no' default: 'no'
jobs: jobs:
nintendo_3ds: nintendo_3ds:
if: github.event.inputs.trigger3DS == 'yes' if: github.event.inputs.trigger3DS == 'yes'
@@ -50,6 +49,18 @@ jobs:
with: with:
submodules: 'recursive' submodules: 'recursive'
- run: make -j2 PLATFORM=simulator TARGET=android - run: make -j2 PLATFORM=simulator TARGET=android
- id: 'auth'
if: ${{ github.event_name == 'push' && github.ref_name == 'upsilon-dev' && github.repository == 'UpsilonNumworks/Upsilon' }}
uses: 'google-github-actions/auth@v0'
with:
credentials_json: '${{secrets.GOOGLE_CREDENTIALS}}'
- id: 'upload-file'
if: ${{ github.event_name == 'push' && github.ref_name == 'upsilon-dev' && github.repository == 'UpsilonNumworks/Upsilon' }}
uses: 'google-github-actions/upload-cloud-storage@v0'
with:
path: 'output/release/simulator/android/epsilon.apk'
destination: 'upsilon-binfiles.appspot.com/dev/simulator/'
parent: false
- uses: actions/upload-artifact@master - uses: actions/upload-artifact@master
with: with:
name: epsilon-android.apk name: epsilon-android.apk
@@ -91,6 +102,18 @@ jobs:
- run: mv output/release/device/n0100/flasher.light.bin final-output/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: find final-output/ -type f -exec bash -c "shasum -a 256 -b {} > {}.sha256" \;
- run: tar cvfz binpack-n0100.tgz final-output/* - run: tar cvfz binpack-n0100.tgz final-output/*
- id: 'auth'
if: ${{ github.event_name == 'push' && github.ref_name == 'upsilon-dev' && github.repository == 'UpsilonNumworks/Upsilon'}}
uses: 'google-github-actions/auth@v0'
with:
credentials_json: '${{secrets.GOOGLE_CREDENTIALS}}'
- id: 'upload-directory'
if: ${{ github.event_name == 'push' && github.ref_name == 'upsilon-dev' && github.repository == 'UpsilonNumworks/Upsilon'}}
uses: 'google-github-actions/upload-cloud-storage@v0'
with:
path: 'final-output/'
destination: 'upsilon-binfiles.appspot.com/dev/n100/'
parent: false
- uses: actions/upload-artifact@master - uses: actions/upload-artifact@master
with: with:
name: epsilon-binpack-n0100.tgz name: epsilon-binpack-n0100.tgz
@@ -109,14 +132,49 @@ jobs:
- run: make -j2 epsilon.onboarding.beta.dfu - run: make -j2 epsilon.onboarding.beta.dfu
- run: make -j2 flasher.light.dfu - run: make -j2 flasher.light.dfu
- run: make -j2 flasher.verbose.dfu - run: make -j2 flasher.verbose.dfu
- run: make -j2 bench.ram.dfu # We don't need bench as it is used only in factory
- run: make -j2 bench.flash.dfu # - run: make -j2 bench.ram.dfu
# - run: make -j2 bench.flash.dfu
- run: make -j2 binpack - 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 - run: cp output/release/device/n0110/binpack-n0110-`git rev-parse HEAD | head -c 7`.tgz output/release/device/n0110/binpack-n0110.tgz
- id: 'auth'
if: ${{ github.event_name == 'push' && github.ref_name == 'upsilon-dev' && github.repository == 'UpsilonNumworks/Upsilon' }}
uses: 'google-github-actions/auth@v0'
with:
credentials_json: '${{secrets.GOOGLE_CREDENTIALS}}'
- id: 'upload-directory'
if: ${{ github.event_name == 'push' && github.ref_name == 'upsilon-dev' && github.repository == 'UpsilonNumworks/Upsilon' }}
uses: 'google-github-actions/upload-cloud-storage@v0'
with:
path: 'output/release/device/n0110/binpack/'
destination: 'upsilon-binfiles.appspot.com/dev/n110/'
parent: false
- uses: actions/upload-artifact@master - uses: actions/upload-artifact@master
with: with:
name: epsilon-binpack-n0110.tgz name: epsilon-binpack-n0110.tgz
path: output/release/device/n0110/binpack-n0110.tgz path: output/release/device/n0110/binpack-n0110.tgz
bootloader:
runs-on: ubuntu-latest
steps:
- run: sudo apt-get install build-essential imagemagick libfreetype6-dev libjpeg-dev libpng-dev pkg-config
- uses: numworks/setup-arm-toolchain@2020-q2
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- run: make -j2 bootloader.dfu
- run: make MODEL=bootloader -j2 epsilon.A.dfu epsilon.B.dfu
- run: make MODEL=bootloader -j2 epsilon.onboarding.A.dfu
- run: make MODEL=bootloader -j2 epsilon.onboarding.B.dfu
- run: make MODEL=bootloader -j2 epsilon.onboarding.update.A.dfu
- run: make MODEL=bootloader -j2 epsilon.onboarding.update.B.dfu
- run: make MODEL=bootloader -j2 epsilon.onboarding.beta.A.dfu
- run: make MODEL=bootloader -j2 epsilon.onboarding.beta.B.dfu
- run: make MODEL=bootloader -j2 binpack
- run: cp output/release/device/bootloader/binpack-bootloader-`git rev-parse HEAD | head -c 7`.tgz output/release/device/bootloader/binpack-bootloader.tgz
- uses: actions/upload-artifact@master
with:
name: epsilon-binpack-bootloader.tgz
path: output/release/device/bootloader/binpack-bootloader.tgz
windows: windows:
runs-on: windows-latest runs-on: windows-latest
defaults: defaults:
@@ -131,6 +189,18 @@ jobs:
- run: make -j2 PLATFORM=simulator - run: make -j2 PLATFORM=simulator
- run: make -j2 PLATFORM=simulator test.exe - run: make -j2 PLATFORM=simulator test.exe
- run: cmd /c output\release\simulator\windows\test.exe --headless - run: cmd /c output\release\simulator\windows\test.exe --headless
- id: 'auth'
if: ${{ github.event_name == 'push' && github.ref_name == 'upsilon-dev' && github.repository == 'UpsilonNumworks/Upsilon' }}
uses: 'google-github-actions/auth@v0'
with:
credentials_json: '${{secrets.GOOGLE_CREDENTIALS}}'
- id: 'upload-file'
if: ${{ github.event_name == 'push' && github.ref_name == 'upsilon-dev' && github.repository == 'UpsilonNumworks/Upsilon' }}
uses: 'google-github-actions/upload-cloud-storage@v0'
with:
path: 'output/release/simulator/windows/epsilon.exe'
destination: 'upsilon-binfiles.appspot.com/dev/simulator/'
parent: false
- uses: actions/upload-artifact@master - uses: actions/upload-artifact@master
with: with:
name: epsilon-windows.exe name: epsilon-windows.exe
@@ -140,13 +210,25 @@ jobs:
steps: steps:
- uses: numworks/setup-emscripten@v1 - uses: numworks/setup-emscripten@v1
with: with:
sdk: 1.40.1-fastcomp sdk: 1.40.1
- uses: actions/checkout@v2 - uses: actions/checkout@v2
with: with:
submodules: 'recursive' submodules: 'recursive'
- run: make -j2 PLATFORM=simulator TARGET=web - run: make -j2 PLATFORM=simulator TARGET=web
- run: make -j2 PLATFORM=simulator TARGET=web test.js - run: make -j2 PLATFORM=simulator TARGET=web test.js
- run: node output/release/simulator/web/test.js --headless - run: node output/release/simulator/web/test.js --headless
- id: 'auth'
if: ${{ github.event_name == 'push' && github.ref_name == 'upsilon-dev' && github.repository == 'UpsilonNumworks/Upsilon' }}
uses: 'google-github-actions/auth@v0'
with:
credentials_json: '${{secrets.GOOGLE_CREDENTIALS}}'
- id: 'upload-file'
if: ${{ github.event_name == 'push' && github.ref_name == 'upsilon-dev' && github.repository == 'UpsilonNumworks/Upsilon' }}
uses: 'google-github-actions/upload-cloud-storage@v0'
with:
path: 'output/release/simulator/web/epsilon.js'
destination: 'upsilon-binfiles.appspot.com/dev/simulator/'
parent: false
- uses: actions/upload-artifact@master - uses: actions/upload-artifact@master
with: with:
name: epsilon-web.zip name: epsilon-web.zip
@@ -161,6 +243,18 @@ jobs:
- run: make -j2 PLATFORM=simulator - run: make -j2 PLATFORM=simulator
- run: make -j2 PLATFORM=simulator test.bin - run: make -j2 PLATFORM=simulator test.bin
- run: output/release/simulator/linux/test.bin --headless - run: output/release/simulator/linux/test.bin --headless
- id: 'auth'
if: ${{ github.event_name == 'push' && github.ref_name == 'upsilon-dev' && github.repository == 'UpsilonNumworks/Upsilon' }}
uses: 'google-github-actions/auth@v0'
with:
credentials_json: '${{secrets.GOOGLE_CREDENTIALS}}'
- id: 'upload-file'
if: ${{ github.event_name == 'push' && github.ref_name == 'upsilon-dev' && github.repository == 'UpsilonNumworks/Upsilon' }}
uses: 'google-github-actions/upload-cloud-storage@v0'
with:
path: 'output/release/simulator/linux/epsilon.bin'
destination: 'upsilon-binfiles.appspot.com/dev/simulator/'
parent: false
- uses: actions/upload-artifact@master - uses: actions/upload-artifact@master
with: with:
name: epsilon-linux.bin name: epsilon-linux.bin

View File

@@ -27,10 +27,18 @@ ifeq (${MODEL}, n0100)
endif endif
endif endif
ifeq ($(filter reader,$(apps_list)),)
HAS_READER := 1
endif
ifeq (${MODEL}, n0110) ifeq (${MODEL}, n0110)
apps_list = ${EPSILON_APPS} apps_list = ${EPSILON_APPS}
else else
apps_list = $(foreach i, ${EPSILON_APPS}, $(if $(filter external, $(i)),,$(i))) ifeq (${MODEL},bootloader)
apps_list = ${EPSILON_APPS}
else
apps_list = $(foreach i, ${EPSILON_APPS}, $(if $(filter external, $(i)),,$(i)))
endif
endif endif
ifdef FORCE_EXTERNAL ifdef FORCE_EXTERNAL
@@ -101,7 +109,7 @@ print-%:
@echo $*\'s origin is $(origin $*) @echo $*\'s origin is $(origin $*)
# Since we're building out-of-tree, we need to make sure the output directories # Since we're building out-of-tree, we need to make sure the output directories
# are created, otherwise the receipes will fail (e.g. gcc will fail to create # are created, otherwise the recipes will fail (e.g. gcc will fail to create
# "output/foo/bar.o" because the directory "output/foo" doesn't exist). # "output/foo/bar.o" because the directory "output/foo" doesn't exist).
# We need to mark those directories as precious, otherwise Make will try to get # We need to mark those directories as precious, otherwise Make will try to get
# rid of them upon completion (and fail, since those folders won't be empty). # rid of them upon completion (and fail, since those folders won't be empty).
@@ -133,6 +141,7 @@ include poincare/Makefile
include python/Makefile include python/Makefile
include escher/Makefile include escher/Makefile
# Executable Makefiles # Executable Makefiles
include bootloader/Makefile
include apps/Makefile include apps/Makefile
include build/struct_layout/Makefile include build/struct_layout/Makefile
include build/scenario/Makefile include build/scenario/Makefile
@@ -205,3 +214,13 @@ clean_run: cleanandcompile
.PHONY: run .PHONY: run
run: compile run: compile
${MAKE} start ${MAKE} start
.PHONY: translations
translations:
@echo "TRANSLATIONS"
$(Q) ${PYTHON} build/utilities/translate.py
.PHONY: translations_clean
translations_clean:
@echo "TRANSLATIONS CLEAN"
$(Q) ${PYTHON} build/utilities/translations_clean.py

View File

@@ -4,7 +4,7 @@
<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://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/Lauryy06/Upsilon/issues"><img alt="Issues" src="https://img.shields.io/github/issues/Lauryy06/Upsilon.svg?labelColor=292929&logo=git&style=for-the-badge" /></a> <a href="https://github.com/Lauryy06/Upsilon/issues"><img alt="Issues" src="https://img.shields.io/github/issues/Lauryy06/Upsilon.svg?labelColor=292929&logo=git&style=for-the-badge" /></a>
<br/> <br/>
<a href="https://discord.gg/Q9buEMduXG"><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/sbGvhWETAd"><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> </p>
> Don't understand french ? speak english ? here's the [english README](./README.md) ! > Don't understand french ? speak english ? here's the [english README](./README.md) !
@@ -25,72 +25,276 @@ Upsilon est un fork d'Omega, un fork d'Epsilon, l'OS de Numworks tournant sur le
## Installation ## Installation
### Site web
Rendez-vous sur le [site d'Upsilon](https://getupsilon.web.app/) à la section "Installer".
Si votre calculatrice est reconnue, qu'elle contient une version d'Epsilon inférieure à 16 et que votre navigateur accepte WebUSB, la page vous proposera d'installer Upsilon.
Ne débranchez votre calculatrice qu'une fois l'installation terminée.
### Manuelle ### Manuelle
*A l'heure actuelle, seule l'installation manuelle est possible.* *Vous pouvez vous référer à ce [site internet](https://www.numworks.com/resources/engineering/software/build/)pour la première étape si vous avez des erreurs*
Tout d'abord, suivez **la première étape** [ici](https://www.numworks.com/resources/engineering/software/build/), puis :
### 1. Installation du SDK
<br>
<details> <details>
<summary><b>Modèle n0100</b></summary>
(note : vous pouvez changer `EPSILON_I18N=fr` en `en`, `nl`, `pt`, `it`, `de`, `es` ou `hu`). <summary><b>1.1 Linux</b></summary>
<br>
<details>
<summary>Debian ou Ubuntu</summary>
<br>
Il suffit juste d'installer les dépendances en tapant ces commandes dans un Terminal en mode super-utilisateur.
```bash
apt-get install build-essential git imagemagick libx11-dev libxext-dev libfreetype6-dev libpng-dev libjpeg-dev pkg-config gcc-arm-none-eabi binutils-arm-none-eabi
```
C'est fait! Vous pouvez aller à l'étape 2.
<br>
</details>
<details>
<summary>Fedora</summary>
<br>
Installez tout d'abord des outils de développement.
```bash
dnf install make automake gcc gcc-c++ kernel-devel
```
Puis les pquets requis:
```bash
dnf install git ImageMagick libX11-devel libXext-devel freetype-devel libpng-devel libjpeg-devel pkg-config
```
Et enfin la version pour ARM de GCC:
```bash
dnf install arm-none-eabi-gcc-cs arm-none-eabi-gcc-cs-c++
```
<br>
</details>
</details>
<details>
<summary><b>1.2 Mac</b></summary>
<br>
Il est recommandé d'utiliser [Homebrew](https://brew.sh/). Une fois intsallé, utilisez:
```bash
brew install numworks/tap/epsilon-sdk
```
Et toutes les dependances seront installées.
<br>
Vous pouvez aller à l'étape 2.
<br>
</details>
<details>
<summary><b>1.3 Windows</b></summary>
[Git](http://git-scm.com) doit être installé.
<br>
<details>
<summary>Avec Msys2/Mingw (Supportés par Numwoks bien qu'il y ait beaucoup de bugs)</summary>
L'environnement de compilation [Msys2](https://www.msys2.org/) est recommandé par Numworks pour obtenir la plupart des outils requis facilement. C'est ici que vous allez copier-colletoutes lecommandes de ce tutoriel. Une fois installé, copier-coller ces deux commandes dans le terminal:
```bash
pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-freetype mingw-w64-x86_64-pkg-config mingw-w64-x86_64-libusb git make python
echo "export PATH=/mingw64/bin:$PATH" >> .bashrc
```
Ensuite, vous devrez installer [GCC toolchain for ARM](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads). Quand il vouest demandde choisir u dossier d'installation, choisissez `C:\msys64\home\User\gcc-arm\`. Il vous faudra ensuite ajouter ce dossier à votre $PATH. Tapez juste:
```bash
echo "export PATH=$PATH:$HOME/gcc-arm/bin" >> .bashrc
```
Redémarrez votre terminal et vous pouvez aller à l'étape 2!
</details>
<details>
<summary>Avec WSL 2</summary>
WSL est un système qui virtualise un environnement GNU/Linux dans Windows.
Votre version de windows doit être >= 1903.
#### Installation de WSL
1. Apuyez simulatanément sur les touches "windows" et "x" puis cliquez sur "Powershell administrateur". Entrez ensuite ceci dans la nouvelle fenêtre:
```powershell
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux all /norestart
```
Cette commande active WSL
```powershell
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```
Cette commande permet d'autoriser le démarrage des machines signées par Microsoft.
2. Redémarrez votre ordinateur.
3. Téléchargez ce fichier [this file](https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi) et suivez les instructions d'installation.
4. Ouvrez votre fenêtre powershell comme avant et tapez:
```powershell
wsl --set-default-version 2
```
5. téléchargez [Ubuntu](https://www.microsoft.com/store/apps/9n6svws3rx71) depuis le Microsoft store. Vous pouvez aussi installer [Debian](https://www.microsoft.com/store/productI9MSVKQC78PK6).
WSL est maintenant installé.
### Installation d'usbipd pour connecter la calculatrice à WSL (facultatif)
Pour connecter la calculatrice, il faut installer cet [outil](https://github.com/dorssel/usbipd-win/releases/download/v1.3.0/usbipd-win_1.3.0.msi). Il permet de connecter deperiphériques USpar internet.Suivez les instructions pour installer.
#### Ubuntu
1. Dans un terminal WSL Ubuntu, tapez:
```bash
sudo apt install linux-tools-5.4.0-77-generic hwdata
```
2. Editez /etc/sudoers pour que l'on puisse utiliser la commande usbip. Sur Ubutu, cele est fait de cette manière:
```bash
sudo visudo
```
3. Ajoutez `/usr/lib/linux-tools/5.4.0-77-generic` au début du secure_path. Après édition, la ligne devrait ressembler à:
`Defaults secure_path="/usr/lib/linux-tools/5.4.0-77-generic:/usr/local/sbin:..."`
#### Debian
1.Si vous utiliser Debian, utilisez cette commande:
```bash
sudo apt install usbip hwdata usbutils
```
### Pour connecter la calculatrice à WSL
1. Ouvrez encore un powershell en mode administrateur et tapez:
```powershell
usbipd wsl list
```
Ceci va lister les périphériques USB connectés à l'ordinateur. Reagrdez le BUSID de votre "Numworks Calculator".
2. Maintenant, lancez cette commande en remplçant <BUSID> par celui de votre caculatrice:
```powershell
usbipd wsl attach --busid <BUSID>
```
Le mot de passe de votre machine WSL vous sera demandé.
Vous pouvez aller à l'étape 2.
</details>
</details>
<br>
### 2. Récupérer le code source
Le code source est disponible dans une repository git. Récupérez-le de cette manière:
```bash ```bash
git clone --recursive https://github.com/Lauryy06/Upsilon.git git clone --recursive https://github.com/Lauryy06/Upsilon.git
cd Upsilon cd Upsilon
git checkout omega-master git checkout upsilon-dev
```
<br>
### 3. Choisissez le système à compiler
<details>
<summary><b>Model n0100</b></summary>
(note: vous pouvez changer l'argument `EPSILON_I18N=en` avec `fr`, `nl`, `pt`, `it`, `de`, `es` or `hu`).
```bash
make MODEL=n0100 clean make MODEL=n0100 clean
make MODEL=n0100 EPSILON_I18N=fr OMEGA_USERNAME="{Votre nom ici, 15 caractères max}" -j4 make MODEL=n0100 EPSILON_I18N=en OMEGA_USERNAME="{Votre nom, maximum 15 caractères}" -j4
```
Maintenant, lancez soit:
```bash
make MODEL=n0100 epsilon_flash make MODEL=n0100 epsilon_flash
``` ```
pour directement flasher la calculatrice après avoir appuyé simultanément sur `reset` et `6` et avoir branché la calculatrice à l'ordinateur.
Important : N'oubliez pas l'argument `--recursive`, Upsilon a besoin de sous-modules. <br>
Vous pouvez aussi changer le nombre de processus parallèles pendant la compilation en changeant la valeur suivant `-j`.
soit:
```bash
make MODEL=n0100 OMEGA_USERNAME="" binpack -j4
```
pour compiler les binpacks que vous pouvez distribuer et flasher depuis le [Ti-planet's webDFU](https://ti-planet.github.io/webdfu_numworks/n0100/).
</details> </details>
<details> <details>
<summary><b>Modèle n0110</b></summary>
<summary><b>Model n0110</b></summary>
```bash ```bash
git clone --recursive https://github.com/Lauryy06/Upsilon.git
cd Upsilon
git checkout omega-master
make clean make clean
make OMEGA_USERNAME="{Votre nom ici, 15 caractères max}" -j4 make OMEGA_USERNAME="{Votre nom, maximum 15 caractères}" -j4
```
Maintenant, lancez soit:
```bash
make epsilon_flash make epsilon_flash
``` ```
pour directement flasher la calculatrice après avoir appuyé simultanément sur `reset` et `6` et avoir branché la calculatrice à l'ordinateur.
Important : N'oubliez pas l'argument `--recursive`, Upsilon a besoin de sous-modules. <br>
Vous pouvez aussi changer le nombre de processus parallèles pendant la compilation en changeant la valeur suivant `-j`.
</details> soit:
<details>
<summary><b>Fichiers binaires</b></summary>
Ces fichiers peuvent être utilisés pour distribuer Upsilon (pour que tout le monde puisse le flasher via [Webdfu_Numworks](https://ti-planet.github.io/webdfu_numworks/)).
```bash ```bash
git clone --recursive https://github.com/Lauryy06/Upsilon.git make OMEGA_USERNAME="" binpack -j4
cd Upsilon
git checkout omega-master
make clean
make MODEL=n0100 OMEGA_USERNAME="" -j8
make MODEL=n0100 OMEGA_USERNAME="" binpack -j8
make OMEGA_USERNAME="" -j8
make OMEGA_USERNAME="" binpack -j8
``` ```
pour compiler les binpacks que vous pouvez distribuer et flasher depuis le [Ti-planet's webDFU](https://ti-planet.github.io/webdfu_numworks/n0100/).
Important : N'oubliez pas l'argument `--recursive`, Upsilon a besoin de sous-modules.
Vous pouvez aussi changer le nombre de processus parallèles pendant la compilation en changeant la valeur suivant `-j`.
</details> </details>
<details> <details>
<summary><b>Simulateur web</b></summary>
<summary><b>Simulateur web</b></summary>
D'abord, installez emsdk : D'abord, installez emsdk :
```bash ```bash
@@ -104,24 +308,20 @@ source emsdk_env.sh
Puis, compilez Upsilon : Puis, compilez Upsilon :
```bash ```bash
git clone --recursive https://github.com/Lauryy06/Upsilon.git
cd Upsilon
git checkout omega-master
make clean make clean
make PLATFORM=simulator TARGET=web OMEGA_USERNAME="{Votre nom ici, 15 caractères max}" -j4 make PLATFORM=simulator TARGET=web OMEGA_USERNAME="{Votre nom, maximum 15 caractères}" -j4
``` ```
Le simulateur se trouve dans `output/release/simulator/web/simulator.zip` Le simulateur se trouve dans `output/release/simulator/web/simulator.zip`
Important : N'oubliez pas l'argument `--recursive`, Upsilon a besoin de sous-modules.
Vous pouvez aussi changer le nombre de processus parallèles pendant la compilation en changeant la valeur suivant `-j`.
</details> </details>
<details> <details>
<summary><b>Simulateur 3DS</b></summary>
<summary><b>Simulateur pour 3DS</b></summary>
Vous aurez besoin de devkitPro et de devkitARM disponible dans votre `$PATH` (instructions [ici](https://devkitpro.org/wiki/Getting_Started) (en anglais))
Il vous faut devkitPro et devkitARM installés et dans votre path (les instructions sont [ici](https://devkitpro.org/wiki/Getting_Started))
```bash ```bash
git clone --recursive https://github.com/Lauryy06/Upsilon.git git clone --recursive https://github.com/Lauryy06/Upsilon.git
@@ -129,15 +329,20 @@ cd Upsilon
git checkout --recursive upsilon-dev git checkout --recursive upsilon-dev
make PLATFORM=simulator TARGET=3ds -j make PLATFORM=simulator TARGET=3ds -j
``` ```
Vous pouvez ensuite mettre epsilon.3dsx sur une carte SDpour le lancer depuis le HBC ou utilisez 3dslink pour le lancer via le réseau:
Vous pouvez ensuite copier epsilon.3dsx sur une carte SD pour l'exécuter depuis le HBC ou utiliser 3dslink pour le lancer via le réseau :
```bash ```bash
3dslink output/release/simulator/3ds/epsilon.3dsx -a <ADRESSE IP 3DS> 3dslink output/release/simulator/3ds/epsilon.3dsx -a <3DS' IP ADDRESS>
``` ```
</details> </details>
<br>
Important: n'oubliez pas l'argument `--recursive` Parce qu'Upsilon dépend de submodules.
Aussi, vous pouvez changer le nombre de processus de compilation en parallèles en changeant le nombre après l'argument `-j`.
N'oubliez pas de mettre votre nom à la place `{Votre nom, maximum 15 caractères}`.Si vous n'en voulez pas, enlevez l'argument `OMEGA_USERNAME`.
Si vous avez besoin d'aide, n'hésitez pas à rejoindre notre serveur discord : https://discord.gg/Q9buEMduXG Si vous avez besoin d'aide, n'hésitez pas à rejoindre notre serveur discord : https://discord.gg/Q9buEMduXG
<a href="https://discord.gg/Q9buEMduXG"><p align="center"><img alt="Omega Banner Discord" src="https://user-images.githubusercontent.com/12123721/86287349-54ef5800-bbe8-11ea-80c1-34eb1f93eebd.png" /></p></a> <a href="https://discord.gg/Q9buEMduXG"><p align="center"><img alt="Omega Banner Discord" src="https://user-images.githubusercontent.com/12123721/86287349-54ef5800-bbe8-11ea-80c1-34eb1f93eebd.png" /></p></a>

142
README.md
View File

@@ -4,7 +4,7 @@
<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://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/Lauryy06/Upsilon/issues"><img alt="Issues" src="https://img.shields.io/github/issues/Lauryy06/Upsilon.svg?labelColor=292929&logo=git&style=for-the-badge" /></a> <a href="https://github.com/Lauryy06/Upsilon/issues"><img alt="Issues" src="https://img.shields.io/github/issues/Lauryy06/Upsilon.svg?labelColor=292929&logo=git&style=for-the-badge" /></a>
<br/> <br/>
<a href="https://discord.gg/Q9buEMduXG"><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/hnEqPzAJzn"><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> </p>
> Vous ne comprenez pas l'anglais ? Vous êtes francophone ? Regardez le [*LISEZ-MOI* français](./README.fr.md) ! > Vous ne comprenez pas l'anglais ? Vous êtes francophone ? Regardez le [*LISEZ-MOI* français](./README.fr.md) !
@@ -19,7 +19,7 @@ Upsilon is a fork of Omega, an user-made OS that runs on the Numworks calculator
### Some new features ### Some new features
- Enhancements for the Kandinsky python module - Enhancements for the Kandinsky python module
- Support for wallpapers - Support for wallpapers
- Exernal apps - External apps
- A custom theme - A custom theme
- Operator overload for python - Operator overload for python
- Improvements for the Periodic table application - Improvements for the Periodic table application
@@ -29,9 +29,15 @@ Upsilon is a fork of Omega, an user-made OS that runs on the Numworks calculator
## Installation ## Installation
### Installer
Go to the [Upsilon website](https://getupsilon.web.app/) to the "Install" section.
If your calculator is recognized, contains a version of Epsilon lower than 16 and your browser accepts WebUSB, the page will suggest you to install Upsilon.
Do not disconnect your calculator until the installation is complete.
### Manual ### Manual
*As of today, only the manual installation is available. You can refer to this [website](https://www.numworks.com/resources/engineering/software/build/) for the first step if you get errors.* *You can refer to this [website](https://www.numworks.com/resources/engineering/software/build/) for the first step if you get errors.*
@@ -40,12 +46,13 @@ Upsilon is a fork of Omega, an user-made OS that runs on the Numworks calculator
<br> <br>
<details> <details>
<summary><b>1.1 Linux</b></summary> <summary><b>1.1 Linux</b></summary>
<br> <br>
<details> <details>
<summary>Debian or Ubuntu</summary> <summary>Debian or Ubuntu</summary>
<br> <br>
@@ -63,26 +70,27 @@ And there you can go to step 2!
</details> </details>
<details> <details>
<summary>Fedora</summary> <summary>Fedora</summary>
<br> <br>
First install basics dev tools. To install basics dev tools:
```bash ```bash
dnf install make automake gcc gcc-c++ kernel-devel dnf install make automake gcc gcc-c++ kernel-devel
``` ```
Then install required packages. And then install required packages.
```bash ```bash
dnf install git ImageMagick libX11-devel libXext-devel freetype-devel libpng-devel libjpeg-devel pkg-config install git ImageMagick libX11-devel libXext-devel freetype-devel libpng-devel libjpeg-devel pkg-config
``` ```
Then, install GCC cross compiler for ARM. Then, install GCC cross compiler for ARM.
```bash ```bash
dnf install arm-none-eabi-gcc-cs arm-none-eabi-gcc-cs-c++ dnf install arm-none-eabi-gcc-cs arm-none-eabi-gcc-cs-c++
``` ```
<br> <br>
@@ -94,14 +102,17 @@ dnf install arm-none-eabi-gcc-cs arm-none-eabi-gcc-cs-c++
</details> </details>
<details> <details>
<summary><b>1.2 Mac</b></summary> <summary><b>1.2 Mac</b></summary>
<br> <br>
It's recommended to use [Homebrew](https://brew.sh/). Once it's installed, just run: It's recommended to use [Homebrew](https://brew.sh/). Once it's installed, just run:
```bash ```bash
brew install numworks/tap/epsilon-sdk brew install numworks/tap/epsilon-sdk
``` ```
and it will install all dependencies. and it will install all dependencies.
<br> <br>
@@ -110,32 +121,108 @@ And there you can go to step 2!
<br> <br>
</details> </details>
<details> <details>
<summary><b>1.3 Windows</b></summary> <summary><b>1.3 Windows</b></summary>
<br> <br>
[Msys2](https://www.msys2.org/) environment is recommended to get most of the required tools on Windows easily. It's where you'll paste all the commands of this tutorial. Once it's installed, paste these commands into the Msys2 terminal. <details>
<summary>With Msys2/Mingw (officialized by numworks but with a lot of bugs)</summary>
[Msys2](https://www.msys2.org/) environment is recommended by Numworks to get most of the required tools on Windows easily. It's where you'll paste all the commands of this tutorial. Once it'sinstalled, paste these commands into the Msys2 terminal.
```bash ```bash
pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-freetype mingw-w64-x86_64-pkg-config mingw-w64-x86_64-libusb git make python pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-freetype mingw-w64-x86_64-pkg-config mingw-w64-x86_64-libusb git make python
echo "export PATH=/mingw64/bin:$PATH" >> .bashrc echo "export PATH=/mingw64/bin:$PATH" >> .bashrc
``` ```
Next, you'll need to install the [GCC toolchain for ARM](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads). When prompted for an install location, choose `C:\msys64\home\User\gcc-arm\`. You'll then need to add this folder to your $PATH. Just enter: Next, you'll need to install the [GCC toolchain for ARM](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads). When prompted for aninstall location, choose `C:\msys64\home\User\gcc-arm\`. You'll then need to add this folder to your $PATH. Just enter:
```bash ```bash
echo "export PATH=$PATH:$HOME/gcc-arm/bin" >> .bashrc echo "export PATH=$PATH:$HOME/gcc-arm/bin" >> .bashrc
``` ```
Just restart and you can go to step 2! Just restart terminal and you can go to step 2!
</details>
<details>
<summary>With WSL 2</summary>
You need a windows version >= 1903.
#### WSL Installation
1. Use simultaneously win + X keys and then click on "admin powershell".
```powershell
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux all /norestart
```
This command activate WSL functionalities.
```powershell
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```
This one allows virtual machines developed by Microsoft.
2. Restart your computer.
3. Download [this file](https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi) and follow instructions.
4. Now open powershell admin like before and type:
```powershell
wsl --set-default-version 2
```
5. Download [Ubuntu](https://www.microsoft.com/store/apps/9n6svws3rx71) from Microsoft store.
WSL is now installed.
### Usbipd installation to connect your calculator
If you want to connect to the calculator, you have to connect to install this [tool](https://github.com/dorssel/usbipd-win/releases/download/v1.3.0/usbipd-win_1.3.0.msi). This will allow you toconnect WSL to the calculator through internet. Follow the on screen information to install.
#### Ubuntu
1. In a WSL Ubuntu command prompt, type:
```bash
sudo apt install linux-tools-5.4.0-77-generic hwdata
```
2. Edit /etc/sudoers so that root can find the usbip command. On Ubuntu, run this command.
```bash
sudo visudo
```
3. Add `/usr/lib/linux-tools/5.4.0-77-generic` to the beginning of secure_path. After editing, the line should look similar to this.
`Defaults secure_path="/usr/lib/linux-tools/5.4.0-77-generic:/usr/local/sbin:..."`
#### Debian
1. If you use debian for your WSL distro, use this command instead:
```bash
sudo apt install usbip hwdata usbutils
```
And that's all for installation and set up.
### To connect your calculator
1. Open an Admin powershell and type:
```powershell
usbipd wsl list
```
This will list your usb devices connected. Look at the BUSID column and remember the one for your calculator (it should be called "Numworks Calculator").
2. Now run this command replacing <BUSID> by your calculator's usb port id:
```powershell
usbipd wsl attach --busid <BUSID>
```
It will ask you to type your wsl's password and will connect your calculator to WSL.
You can now go to step 2!
</details>
</details> </details>
<br> <br>
### 2. Set up repo ### 2. Set up repo
@@ -153,7 +240,8 @@ git checkout upsilon-dev
<details> <details>
<summary><b>Model n0100</b></summary>
<summary><b>Model n0100</b></summary>
(note: you can change the `EPSILON_I18N=en` flag to `fr`, `nl`, `pt`, `it`, `de`, `es` or `hu`). (note: you can change the `EPSILON_I18N=en` flag to `fr`, `nl`, `pt`, `it`, `de`, `es` or `hu`).
@@ -167,7 +255,7 @@ Now, run either:
```bash ```bash
make MODEL=n0100 epsilon_flash make MODEL=n0100 epsilon_flash
``` ```
to directly flash the calculator after pressing simultaneously `reset` and `6` buttons and pluging in. to directly flash the calculator after pressing simultaneously `reset` and `6` buttons and plugging in.
<br> <br>
@@ -176,12 +264,13 @@ or:
```bash ```bash
make MODEL=n0100 OMEGA_USERNAME="" binpack -j4 make MODEL=n0100 OMEGA_USERNAME="" binpack -j4
``` ```
to make binpack wich you can flash to the caculator from [Ti-planet's webDFU](https://ti-planet.github.io/webdfu_numworks/n0100/). Binpacks are a great way to share a custom build of Upsilon to friends. to make binpack which you can flash to the calculator from [Ti-planet's webDFU](https://ti-planet.github.io/webdfu_numworks/n0100/). Binpacks are a great way to share a custom build of Upsilonto friends.
</details> </details>
<details> <details>
<summary><b>Model n0110</b></summary>
<summary><b>Model n0110</b></summary>
```bash ```bash
@@ -194,7 +283,7 @@ Now, run either:
```bash ```bash
make epsilon_flash make epsilon_flash
``` ```
to directly flash the calculator after pressing simultaneously `reset` and `6` buttons and pluging in. to directly flash the calculator after pressing simultaneously `reset` and `6` buttons and plugging in.
<br> <br>
@@ -203,13 +292,14 @@ or:
```bash ```bash
make OMEGA_USERNAME="" binpack -j4 make OMEGA_USERNAME="" binpack -j4
``` ```
to make binpack wich you can flash to the caculator from [Ti-planet's webDFU](https://ti-planet.github.io/webdfu_numworks/n0110/). Binpacks are a great way to share a custom build of Upsilon to friends. to make binpack witch you can flash to the calculator from [Ti-planet's webDFU](https://ti-planet.github.io/webdfu_numworks/n0110/). Binpacks are a great way to share a custom build of Upsilon to friends.
</details> </details>
<details> <details>
<summary><b>Web simulator</b></summary>
<summary><b>Web simulator</b></summary>
First, install emsdk : First, install emsdk :
```bash ```bash
@@ -229,12 +319,12 @@ make PLATFORM=simulator TARGET=web OMEGA_USERNAME="{Your name, max 15 characters
The simulator is now in `output/release/simulator/web/simulator.zip` The simulator is now in `output/release/simulator/web/simulator.zip`
</details> </details>
<details> <details>
<summary><b>3DS Simulator</b></summary>
<summary><b>3DS Simulator</b></summary>
You need devkitPro and devkitARM installed and in your path (instructions [here](https://devkitpro.org/wiki/Getting_Started)) You need devkitPro and devkitARM installed and in your path (instructions [here](https://devkitpro.org/wiki/Getting_Started))
```bash ```bash
@@ -270,7 +360,7 @@ If you need help, you can join our Discord server here : https://discord.gg/NFvz
## Contributing ## Contributing
To contribute, please refer to [Omega's Wiki](https://github.com/Omega-Numworks/Omega/wiki/Contributing), the same rules apply here. To contribute, please refer to [Omega's Wiki](https://github.com/Omega-Numworks/Omega/wiki/Contributing), the same rules apply here.
## Related repositories ## Related repositories
Here are the main links toward Omega's different websites and repositories, that have been used for the creation of Upsilon. Here are the main links toward Omega's different websites and repositories, that have been used for the creation of Upsilon.

View File

@@ -23,7 +23,7 @@ ifneq ($(strip $(apps_missing)),)
$(foreach i, $(SUBMODULES_APPS), $(if $(call app_equals, $(filter $(i), $(apps_missing)), $(i)), $(eval miss_modules=1))) $(foreach i, $(SUBMODULES_APPS), $(if $(call app_equals, $(filter $(i), $(apps_missing)), $(i)), $(eval miss_modules=1)))
ifeq ($(miss_modules), 1) ifeq ($(miss_modules), 1)
PLS_IGNORE := $(shell >&2 printf "\nSome submodules apps seem to be missing. To download them, assumming you git clone'd the repo, do\n") PLS_IGNORE := $(shell >&2 printf "\nSome submodules apps seem to be missing. To download them, assuming you git clone'd the repo, do\n")
PLS_IGNORE := $(shell >&2 printf " git submodule init\n") PLS_IGNORE := $(shell >&2 printf " git submodule init\n")
PLS_IGNORE := $(shell >&2 printf " git submodule update\n\n") PLS_IGNORE := $(shell >&2 printf " git submodule update\n\n")
endif endif
@@ -81,7 +81,7 @@ $(call object_for,apps/apps_container_storage.cpp apps/apps_container.cpp apps/m
country_preferences = apps/country_preferences.csv country_preferences = apps/country_preferences.csv
language_preferences = apps/language_preferences.csv language_preferences = apps/language_preferences.csv
# The header is refered to as <apps/i18n.h> so make sure it's findable this way # The header is referred to as <apps/i18n.h> so make sure it's findable this way
SFLAGS += -I$(BUILD_DIR) SFLAGS += -I$(BUILD_DIR)
i18n_files += $(addprefix apps/language_,$(addsuffix .universal.i18n, $(EPSILON_I18N))) i18n_files += $(addprefix apps/language_,$(addsuffix .universal.i18n, $(EPSILON_I18N)))

View File

@@ -47,7 +47,7 @@ AppsContainer::AppsContainer() :
* poincareCircuitBreaker is run. This means either whitelisting all Epsilon * poincareCircuitBreaker is run. This means either whitelisting all Epsilon
* (which makes bigger files to download and slower execution), or * (which makes bigger files to download and slower execution), or
* whitelisting all the symbols (that's a big amount of symbols to find and * whitelisting all the symbols (that's a big amount of symbols to find and
* quite painy to maintain). * quite paint to maintain).
* We just remove the circuit breaker for now. * We just remove the circuit breaker for now.
* TODO: Put the Poincare circuit breaker back on epsilon's web emulator */ * TODO: Put the Poincare circuit breaker back on epsilon's web emulator */
@@ -147,7 +147,7 @@ bool AppsContainer::dispatchEvent(Ion::Events::Event event) {
* pictogram. */ * pictogram. */
updateBatteryState(); updateBatteryState();
if (switchTo(usbConnectedAppSnapshot())) { if (switchTo(usbConnectedAppSnapshot())) {
Ion::USB::DFU(); Ion::USB::DFU(true);
// Update LED when exiting DFU mode // Update LED when exiting DFU mode
Ion::LED::updateColorWithPlugAndCharge(); Ion::LED::updateColorWithPlugAndCharge();
bool switched = switchTo(activeSnapshot); bool switched = switchTo(activeSnapshot);
@@ -243,15 +243,18 @@ bool AppsContainer::processEvent(Ion::Events::Event event) {
} }
return true; return true;
} }
// If key home or key back is pressed, we switch to the home app.
if (event == Ion::Events::Home || event == Ion::Events::Back) { if (event == Ion::Events::Home || event == Ion::Events::Back) {
switchTo(appSnapshotAtIndex(0)); switchTo(appSnapshotAtIndex(0));
return true; return true;
} }
// If shift + Home are pressed, we switch to the first app.
if (event == Ion::Events::ShiftHome) { if (event == Ion::Events::ShiftHome) {
switchTo(appSnapshotAtIndex(1)); switchTo(appSnapshotAtIndex(1));
return true; return true;
} }
// Iterate through the switch events to find the one that matches the event, if one match, switch to the app at the index of the switch event.
for(int i = 0; i < std::min((int) (sizeof(switch_events) / sizeof(Ion::Events::Event)), APPS_CONTAINER_SNAPSHOT_COUNT); i++) { for(int i = 0; i < std::min((int) (sizeof(switch_events) / sizeof(Ion::Events::Event)), APPS_CONTAINER_SNAPSHOT_COUNT); i++) {
if (event == switch_events[i]) { if (event == switch_events[i]) {
m_window.redraw(true); m_window.redraw(true);
@@ -260,13 +263,20 @@ bool AppsContainer::processEvent(Ion::Events::Event event) {
} }
} }
// Add EE shortcut to go to the settings (app number 12)
if (event == Ion::Events::EE) {
switchTo(appSnapshotAtIndex(12));
return true;
}
if (event == Ion::Events::OnOff) { if (event == Ion::Events::OnOff) {
suspend(true); suspend(true);
return true; return true;
} }
if (event == Ion::Events::BrightnessPlus || event == Ion::Events::BrightnessMinus) { if (event == Ion::Events::BrightnessPlus || event == Ion::Events::BrightnessMinus) {
int delta = Ion::Backlight::MaxBrightness/GlobalPreferences::NumberOfBrightnessStates; int delta = Ion::Backlight::MaxBrightness/GlobalPreferences::NumberOfBrightnessStates;
int direction = (event == Ion::Events::BrightnessPlus) ? Ion::Backlight::NumberOfStepsPerShortcut*delta : -delta*Ion::Backlight::NumberOfStepsPerShortcut; int NumberOfStepsPerShortcut = GlobalPreferences::sharedGlobalPreferences()->brightnessShortcut();
int direction = (event == Ion::Events::BrightnessPlus) ? NumberOfStepsPerShortcut*delta : -delta*NumberOfStepsPerShortcut;
GlobalPreferences::sharedGlobalPreferences()->setBrightnessLevel(GlobalPreferences::sharedGlobalPreferences()->brightnessLevel()+direction); GlobalPreferences::sharedGlobalPreferences()->setBrightnessLevel(GlobalPreferences::sharedGlobalPreferences()->brightnessLevel()+direction);
} }
return false; return false;
@@ -319,7 +329,7 @@ void AppsContainer::run() {
* destroyed from the pool. To avoid using them before packing the app * destroyed from the pool. To avoid using them before packing the app
* (in App::willBecomeInactive for instance), we tidy them early on. */ * (in App::willBecomeInactive for instance), we tidy them early on. */
s_activeApp->snapshot()->tidy(); s_activeApp->snapshot()->tidy();
/* When an app encoutered an exception due to a full pool, the next time /* When an app encountered an exception due to a full pool, the next time
* the user enters the app, the same exception could happen again which * the user enters the app, the same exception could happen again which
* would prevent from reopening the app. To avoid being stuck outside the * would prevent from reopening the app. To avoid being stuck outside the
* app causing the issue, we reset its snapshot when leaving it due to * app causing the issue, we reset its snapshot when leaving it due to
@@ -353,6 +363,8 @@ bool AppsContainer::updateBatteryState() {
} }
void AppsContainer::refreshPreferences() { void AppsContainer::refreshPreferences() {
m_suspendTimer.reset(GlobalPreferences::sharedGlobalPreferences()->idleBeforeSuspendSeconds()*1000/Timer::TickDuration);
m_backlightDimmingTimer.reset(GlobalPreferences::sharedGlobalPreferences()->idleBeforeDimmingSeconds()*1000/Timer::TickDuration);
m_window.refreshPreferences(); m_window.refreshPreferences();
} }

View File

@@ -1,11 +1,26 @@
#include "backlight_dimming_timer.h" #include "backlight_dimming_timer.h"
#include "global_preferences.h"
#include <ion/backlight.h>
#include <ion/events.h>
#include <apps/apps_container.h>
BacklightDimmingTimer::BacklightDimmingTimer() : BacklightDimmingTimer::BacklightDimmingTimer() :
Timer(k_idleBeforeDimmingDuration/Timer::TickDuration) Timer(GlobalPreferences::sharedGlobalPreferences()->idleBeforeDimmingSeconds()*1000/Timer::TickDuration)
{ {
} }
bool BacklightDimmingTimer::fire() { bool BacklightDimmingTimer::fire(){
Ion::Backlight::setBrightness(k_dimBacklightBrightness); int i = Ion::Backlight::brightness();
while (i > 0){
int t = 20;
Ion::Events::Event e = Ion::Events::getEvent(&t);
AppsContainer::sharedAppsContainer()->dispatchEvent(e);
if (e.isKeyboardEvent()){
return false;
}
Ion::Backlight::setBrightness(i);
i -= 15;
}
return false; return false;
} }

View File

@@ -7,8 +7,6 @@ class BacklightDimmingTimer : public Timer {
public: public:
BacklightDimmingTimer(); BacklightDimmingTimer();
private: private:
constexpr static int k_idleBeforeDimmingDuration = 30*1000; // In miliseconds
constexpr static int k_dimBacklightBrightness = 0;
bool fire() override; bool fire() override;
}; };

View File

@@ -60,32 +60,36 @@ void BatteryView::drawRect(KDContext * ctx, KDRect rect) const {
*'content' depends on the charge */ *'content' depends on the charge */
// Draw the left part // Draw the left part
ctx->fillRect(KDRect(0, 0, k_elementWidth, k_batteryHeight), Palette::Battery); ctx->fillRect(KDRect(0, 1, k_elementWidth, k_batteryHeight - 2), Palette::Battery);
// Draw top and bottom part
ctx->fillRect(KDRect(1, 0, k_batteryWidth-3, 1), Palette::Battery);
ctx->fillRect(KDRect(1, k_batteryHeight-1, k_batteryWidth-3, 1), Palette::Battery);
// Draw the middle part // Draw the middle part
constexpr KDCoordinate batteryInsideX = k_elementWidth+k_separatorThickness; constexpr KDCoordinate batteryInsideX = k_elementWidth+k_separatorThickness;
constexpr KDCoordinate batteryInsideWidth = k_batteryWidth-3*k_elementWidth-2*k_separatorThickness; constexpr KDCoordinate batteryInsideWidth = k_batteryWidth-3*k_elementWidth-2*k_separatorThickness;
if (m_isCharging) { if (m_isCharging) {
// Charging: Yellow background with flash // Charging: Yellow background with flash
ctx->fillRect(KDRect(batteryInsideX, 0, batteryInsideWidth, k_batteryHeight), Palette::BatteryInCharge); ctx->fillRect(KDRect(batteryInsideX, 2, batteryInsideWidth, k_batteryHeight-4), Palette::BatteryInCharge);
KDRect frame((k_batteryWidth-k_flashWidth)/2, 0, k_flashWidth, k_flashHeight); KDRect frame((k_batteryWidth-k_flashWidth)/2, 0, k_flashWidth, k_flashHeight);
KDColor flashWorkingBuffer[BatteryView::k_flashHeight*BatteryView::k_flashWidth]; KDColor flashWorkingBuffer[BatteryView::k_flashHeight*BatteryView::k_flashWidth];
ctx->blendRectWithMask(frame, Palette::Battery, (const uint8_t *)flashMask, flashWorkingBuffer); ctx->blendRectWithMask(frame, Palette::Battery, (const uint8_t *)flashMask, flashWorkingBuffer);
} else if (m_chargeState == Ion::Battery::Charge::LOW) { } else if (m_chargeState == Ion::Battery::Charge::LOW) {
assert(!m_isPlugged); assert(!m_isPlugged);
// Low: Quite empty battery // Low: Quite empty battery
ctx->fillRect(KDRect(batteryInsideX, 0, 2*k_elementWidth, k_batteryHeight), Palette::BatteryLow); ctx->fillRect(KDRect(batteryInsideX, 2, 2*k_elementWidth, k_batteryHeight-4), Palette::BatteryLow);
ctx->fillRect(KDRect(3*k_elementWidth+k_separatorThickness, 0, k_batteryWidth-5*k_elementWidth-2*k_separatorThickness, k_batteryHeight), KDColor::blend(Palette::Toolbar, Palette::Battery, 128)); ctx->fillRect(KDRect(3*k_elementWidth+k_separatorThickness, 2, k_batteryWidth-5*k_elementWidth-2*k_separatorThickness, k_batteryHeight-4), KDColor::blend(Palette::Toolbar, Palette::Battery, 128));
} else if (m_chargeState == Ion::Battery::Charge::SOMEWHERE_INBETWEEN) { } else if (m_chargeState == Ion::Battery::Charge::SOMEWHERE_INBETWEEN) {
assert(!m_isPlugged); assert(!m_isPlugged);
// Middle: Half full battery // Middle: Half full battery
constexpr KDCoordinate middleChargeWidth = batteryInsideWidth/2; constexpr KDCoordinate middleChargeWidth = batteryInsideWidth/2;
ctx->fillRect(KDRect(batteryInsideX, 0, middleChargeWidth, k_batteryHeight), Palette::Battery); ctx->fillRect(KDRect(batteryInsideX, 2, middleChargeWidth, k_batteryHeight-4), Palette::Battery);
ctx->fillRect(KDRect(batteryInsideX+middleChargeWidth, 0, middleChargeWidth, k_batteryHeight), KDColor::blend(Palette::Toolbar, Palette::Battery, 128)); ctx->fillRect(KDRect(batteryInsideX+middleChargeWidth, 2, middleChargeWidth+1, k_batteryHeight-4), KDColor::blend(Palette::Toolbar, Palette::Battery, 128));
} else { } else {
assert(m_chargeState == Ion::Battery::Charge::FULL); assert(m_chargeState == Ion::Battery::Charge::FULL);
// Full but not plugged: Full battery // Full but not plugged: Full battery
ctx->fillRect(KDRect(batteryInsideX, 0, batteryInsideWidth, k_batteryHeight), Palette::Battery); ctx->fillRect(KDRect(batteryInsideX, 2, batteryInsideWidth, k_batteryHeight-4), Palette::Battery);
if (m_isPlugged) { if (m_isPlugged) {
// Plugged and full: Full battery with tick // Plugged and full: Full battery with tick
KDRect frame((k_batteryWidth-k_tickWidth)/2, (k_batteryHeight-k_tickHeight)/2, k_tickWidth, k_tickHeight); KDRect frame((k_batteryWidth-k_tickWidth)/2, (k_batteryHeight-k_tickHeight)/2, k_tickWidth, k_tickHeight);
@@ -95,7 +99,7 @@ void BatteryView::drawRect(KDContext * ctx, KDRect rect) const {
} }
// Draw the right part // Draw the right part
ctx->fillRect(KDRect(k_batteryWidth-2*k_elementWidth, 0, k_elementWidth, k_batteryHeight), Palette::Battery); ctx->fillRect(KDRect(k_batteryWidth-2*k_elementWidth, 1, k_elementWidth, k_batteryHeight-2), Palette::Battery);
ctx->fillRect(KDRect(k_batteryWidth-k_elementWidth, (k_batteryHeight-k_capHeight)/2, k_elementWidth, k_capHeight), Palette::Battery); ctx->fillRect(KDRect(k_batteryWidth-k_elementWidth, (k_batteryHeight-k_capHeight)/2, k_elementWidth, k_capHeight), Palette::Battery);
} }

View File

@@ -20,10 +20,10 @@ public:
constexpr static int k_tickHeight = 6; constexpr static int k_tickHeight = 6;
constexpr static int k_tickWidth = 8; constexpr static int k_tickWidth = 8;
private: private:
constexpr static KDCoordinate k_batteryHeight = 8; constexpr static KDCoordinate k_batteryHeight = 9;
constexpr static KDCoordinate k_batteryWidth = 15; constexpr static KDCoordinate k_batteryWidth = 16;
constexpr static KDCoordinate k_elementWidth = 1; constexpr static KDCoordinate k_elementWidth = 1;
constexpr static KDCoordinate k_capHeight = 4; constexpr static KDCoordinate k_capHeight = 3;
constexpr static KDCoordinate k_separatorThickness = Metric::CellSeparatorThickness; constexpr static KDCoordinate k_separatorThickness = Metric::CellSeparatorThickness;
Ion::Battery::Charge m_chargeState; Ion::Battery::Charge m_chargeState;
bool m_isCharging; bool m_isCharging;

View File

@@ -20,20 +20,20 @@ using namespace Poincare;
using namespace Shared; using namespace Shared;
namespace Calculation { namespace Calculation {
void SecondDegreeListController::setExpression(Poincare::Expression e) { void SecondDegreeListController::setExpression(Poincare::Expression e) {
ExpressionsListController::setExpression(e); ExpressionsListController::setExpression(e);
assert(!m_expression.isUninitialized()); assert(!m_expression.isUninitialized());
Expression polynomialCoefficients[Expression::k_maxNumberOfPolynomialCoefficients]; Expression polynomialCoefficients[Expression::k_maxNumberOfPolynomialCoefficients];
Context * context = App::app()->localContext(); Context * context = App::app()->localContext();
Preferences * preferences = Preferences::sharedPreferences(); Preferences * preferences = Preferences::sharedPreferences();
Poincare::ExpressionNode::ReductionContext reductionContext = Poincare::ExpressionNode::ReductionContext(context, Poincare::ExpressionNode::ReductionContext reductionContext = Poincare::ExpressionNode::ReductionContext(context,
preferences->complexFormat(), preferences->angleUnit(), preferences->complexFormat(), preferences->angleUnit(),
GlobalPreferences::sharedGlobalPreferences()->unitFormat(), GlobalPreferences::sharedGlobalPreferences()->unitFormat(),
ExpressionNode::ReductionTarget::SystemForApproximation, ExpressionNode::ReductionTarget::SystemForApproximation,
ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition,
Poincare::ExpressionNode::UnitConversion::Default); Poincare::ExpressionNode::UnitConversion::Default);
PoincareHelpers::Reduce(&m_expression, context, ExpressionNode::ReductionTarget::SystemForAnalysis); PoincareHelpers::Reduce(&m_expression, context, ExpressionNode::ReductionTarget::SystemForAnalysis);
@@ -52,7 +52,7 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
Expression a = polynomialCoefficients[2]; Expression a = polynomialCoefficients[2];
Expression b = polynomialCoefficients[1]; Expression b = polynomialCoefficients[1];
Expression c = polynomialCoefficients[0]; Expression c = polynomialCoefficients[0];
Expression delta = Subtraction::Builder(Power::Builder(b.clone(), Rational::Builder(2)), Multiplication::Builder(Rational::Builder(4), a.clone(), c.clone())); Expression delta = Subtraction::Builder(Power::Builder(b.clone(), Rational::Builder(2)), Multiplication::Builder(Rational::Builder(4), a.clone(), c.clone()));
PoincareHelpers::Simplify(&delta, context, ExpressionNode::ReductionTarget::SystemForApproximation); PoincareHelpers::Simplify(&delta, context, ExpressionNode::ReductionTarget::SystemForApproximation);
@@ -72,25 +72,22 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
}; };
MultiplicationTypeForA multiplicationTypeForA; MultiplicationTypeForA multiplicationTypeForA;
if (a.type() == ExpressionNode::Type::Rational && static_cast<const Rational &>(a).isOne()) { if (a.type() == ExpressionNode::Type::Rational && static_cast<const Rational &>(a).isOne()) {
multiplicationTypeForA = MultiplicationTypeForA::Nothing; multiplicationTypeForA = MultiplicationTypeForA::Nothing;
} } else if(a.type() == ExpressionNode::Type::Rational && static_cast<const Rational &>(a).isMinusOne()){
else if(a.type() == ExpressionNode::Type::Rational && static_cast<const Rational &>(a).isMinusOne()){
multiplicationTypeForA = MultiplicationTypeForA::Minus; multiplicationTypeForA = MultiplicationTypeForA::Minus;
} } else if (a.type() == ExpressionNode::Type::Addition) {
else if (a.type() == ExpressionNode::Type::Addition) {
multiplicationTypeForA = MultiplicationTypeForA::Parenthesis; multiplicationTypeForA = MultiplicationTypeForA::Parenthesis;
} } else {
else {
multiplicationTypeForA = MultiplicationTypeForA::Normal; multiplicationTypeForA = MultiplicationTypeForA::Normal;
} }
PoincareHelpers::Simplify(&a, context, ExpressionNode::ReductionTarget::User); PoincareHelpers::Simplify(&a, context, ExpressionNode::ReductionTarget::User);
/* /*
* Because when can't apply reduce or simplify to keep the * Because when can't apply reduce or simplify to keep the
* canonized form we must beautify the expression manually * canonized form we must beautify the expression manually
*/ */
Expression xMinusAlphaPowerTwo; Expression xMinusAlphaPowerTwo;
@@ -99,12 +96,11 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
if (alpha.isUninitialized()) { if (alpha.isUninitialized()) {
PoincareHelpers::Simplify(&minusAlpha, context, ExpressionNode::ReductionTarget::User); PoincareHelpers::Simplify(&minusAlpha, context, ExpressionNode::ReductionTarget::User);
xMinusAlphaPowerTwo = Power::Builder(Parenthesis::Builder(Addition::Builder(Symbol::Builder("x", strlen("x")), minusAlpha)), Rational::Builder(2)); xMinusAlphaPowerTwo = Power::Builder(Parenthesis::Builder(Addition::Builder(Symbol::Builder("x", strlen("x")), minusAlpha)), Rational::Builder(2));
} } else {
else {
PoincareHelpers::Simplify(&alpha, context, ExpressionNode::ReductionTarget::User); PoincareHelpers::Simplify(&alpha, context, ExpressionNode::ReductionTarget::User);
xMinusAlphaPowerTwo = Power::Builder(Parenthesis::Builder(Subtraction::Builder(Symbol::Builder("x", strlen("x")), alpha)), Rational::Builder(2)); xMinusAlphaPowerTwo = Power::Builder(Parenthesis::Builder(Subtraction::Builder(Symbol::Builder("x", strlen("x")), alpha)), Rational::Builder(2));
} }
Expression xMinusAlphaPowerTwoWithFactor; Expression xMinusAlphaPowerTwoWithFactor;
switch (multiplicationTypeForA) switch (multiplicationTypeForA)
@@ -113,7 +109,7 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
xMinusAlphaPowerTwoWithFactor = xMinusAlphaPowerTwo; xMinusAlphaPowerTwoWithFactor = xMinusAlphaPowerTwo;
break; break;
case MultiplicationTypeForA::Minus: case MultiplicationTypeForA::Minus:
xMinusAlphaPowerTwoWithFactor = Multiplication::Builder(a.clone(), xMinusAlphaPowerTwo); xMinusAlphaPowerTwoWithFactor = Opposite::Builder(xMinusAlphaPowerTwo);
break; break;
case MultiplicationTypeForA::Parenthesis: case MultiplicationTypeForA::Parenthesis:
xMinusAlphaPowerTwoWithFactor = Multiplication::Builder(Parenthesis::Builder(a.clone()), xMinusAlphaPowerTwo); xMinusAlphaPowerTwoWithFactor = Multiplication::Builder(Parenthesis::Builder(a.clone()), xMinusAlphaPowerTwo);
@@ -125,18 +121,21 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
assert(false); assert(false);
break; break;
} }
Expression canonized; Expression canonized;
PoincareHelpers::Simplify(&minusBeta, context, ExpressionNode::ReductionTarget::User);
Expression beta = getOppositeIfExists(minusBeta, &reductionContext); Expression beta = getOppositeIfExists(minusBeta, &reductionContext);
if (beta.isUninitialized()) { if (beta.isUninitialized()) {
PoincareHelpers::Simplify(&minusBeta, context, ExpressionNode::ReductionTarget::User); if (minusBeta.type() == ExpressionNode::Type::Addition || minusBeta.type() == ExpressionNode::Type::Subtraction) {
canonized = Subtraction::Builder(xMinusAlphaPowerTwoWithFactor, minusBeta); canonized = Subtraction::Builder(xMinusAlphaPowerTwoWithFactor, Parenthesis::Builder(minusBeta));
} } else {
else { canonized = Subtraction::Builder(xMinusAlphaPowerTwoWithFactor, minusBeta);
}
} else {
PoincareHelpers::Simplify(&beta, context, ExpressionNode::ReductionTarget::User); PoincareHelpers::Simplify(&beta, context, ExpressionNode::ReductionTarget::User);
canonized = Addition::Builder(xMinusAlphaPowerTwoWithFactor, beta); canonized = Addition::Builder(xMinusAlphaPowerTwoWithFactor, beta);
} }
Expression x0; Expression x0;
Expression x1; Expression x1;
@@ -145,8 +144,7 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
x0 = Division::Builder(Opposite::Builder(b.clone()), Multiplication::Builder(Rational::Builder(2), a.clone())); x0 = Division::Builder(Opposite::Builder(b.clone()), Multiplication::Builder(Rational::Builder(2), a.clone()));
m_numberOfSolutions = 1; m_numberOfSolutions = 1;
PoincareHelpers::Simplify(&x0, context, ExpressionNode::ReductionTarget::SystemForApproximation); PoincareHelpers::Simplify(&x0, context, ExpressionNode::ReductionTarget::SystemForApproximation);
} } else {
else {
// x0 = (-b-sqrt(delta))/(2a) // x0 = (-b-sqrt(delta))/(2a)
x0 = Division::Builder(Subtraction::Builder(Opposite::Builder(b.clone()), SquareRoot::Builder(delta.clone())), Multiplication::Builder(Rational::Builder(2), a.clone())); x0 = Division::Builder(Subtraction::Builder(Opposite::Builder(b.clone()), SquareRoot::Builder(delta.clone())), Multiplication::Builder(Rational::Builder(2), a.clone()));
// x1 = (-b+sqrt(delta))/(2a) // x1 = (-b+sqrt(delta))/(2a)
@@ -169,24 +167,32 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
Expression x0Opposite = getOppositeIfExists(x0, &reductionContext); Expression x0Opposite = getOppositeIfExists(x0, &reductionContext);
if (x0Opposite.isUninitialized()) { if (x0Opposite.isUninitialized()) {
PoincareHelpers::Simplify(&x0, context, ExpressionNode::ReductionTarget::User); PoincareHelpers::Simplify(&x0, context, ExpressionNode::ReductionTarget::User);
firstFactor = Subtraction::Builder(Symbol::Builder("x", strlen("x")), x0); if (x0.type() == ExpressionNode::Type::Addition || x0.type() == ExpressionNode::Type::Subtraction) {
} firstFactor = Subtraction::Builder(Symbol::Builder("x", strlen("x")), Parenthesis::Builder(x0.clone()));
else { } else {
PoincareHelpers::Simplify(&x0Opposite, context, ExpressionNode::ReductionTarget::User); firstFactor = Subtraction::Builder(Symbol::Builder("x", strlen("x")), x0.clone());
firstFactor = Addition::Builder(Symbol::Builder("x", strlen("x")), x0Opposite); }
} } else {
if (x0.type() == ExpressionNode::Type::Opposite) { if (x0Opposite.type() == ExpressionNode::Type::Addition || x0Opposite.type() == ExpressionNode::Type::Subtraction) {
factorized = Parenthesis::Builder(Addition::Builder(Symbol::Builder("x", strlen("x")), x0.childAtIndex(0).clone())); x0Opposite = Parenthesis::Builder(x0Opposite.clone());
}
firstFactor = Addition::Builder(Symbol::Builder("x", strlen("x")), x0Opposite.clone());
} }
Expression x1Opposite = getOppositeIfExists(x1, &reductionContext); Expression x1Opposite = getOppositeIfExists(x1, &reductionContext);
if (x1Opposite.isUninitialized()) { if (x1Opposite.isUninitialized()) {
PoincareHelpers::Simplify(&x1, context, ExpressionNode::ReductionTarget::User); PoincareHelpers::Simplify(&x1, context, ExpressionNode::ReductionTarget::User);
secondFactor = Subtraction::Builder(Symbol::Builder("x", strlen("x")), x1); if (x1.type() == ExpressionNode::Type::Addition || x1.type() == ExpressionNode::Type::Subtraction) {
} secondFactor = Subtraction::Builder(Symbol::Builder("x", strlen("x")), Parenthesis::Builder(x1.clone()));
else { } else {
secondFactor = Subtraction::Builder(Symbol::Builder("x", strlen("x")), x1.clone());
}
} else {
PoincareHelpers::Simplify(&x1Opposite, context, ExpressionNode::ReductionTarget::User); PoincareHelpers::Simplify(&x1Opposite, context, ExpressionNode::ReductionTarget::User);
secondFactor = Addition::Builder(Symbol::Builder("x", strlen("x")), x1Opposite); if (x1Opposite.type() == ExpressionNode::Type::Addition || x1Opposite.type() == ExpressionNode::Type::Subtraction) {
x1Opposite = Parenthesis::Builder(x1Opposite.clone());
}
secondFactor = Addition::Builder(Symbol::Builder("x", strlen("x")), x1Opposite.clone());
} }
Expression solutionProduct = Multiplication::Builder(Parenthesis::Builder(firstFactor), Parenthesis::Builder(secondFactor)); Expression solutionProduct = Multiplication::Builder(Parenthesis::Builder(firstFactor), Parenthesis::Builder(secondFactor));
@@ -196,7 +202,7 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
factorized = solutionProduct; factorized = solutionProduct;
break; break;
case MultiplicationTypeForA::Minus: case MultiplicationTypeForA::Minus:
factorized = Multiplication::Builder(a.clone(), solutionProduct); factorized = Opposite::Builder(solutionProduct);
break; break;
case MultiplicationTypeForA::Parenthesis: case MultiplicationTypeForA::Parenthesis:
factorized = Multiplication::Builder(Parenthesis::Builder(a.clone()), solutionProduct); factorized = Multiplication::Builder(Parenthesis::Builder(a.clone()), solutionProduct);
@@ -208,18 +214,22 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
assert(false); assert(false);
break; break;
} }
} } else if (m_numberOfSolutions == 1) {
else if (m_numberOfSolutions == 1) {
Expression x0Opposite = getOppositeIfExists(x0, &reductionContext); Expression x0Opposite = getOppositeIfExists(x0, &reductionContext);
Expression factor; Expression factor;
if (x0Opposite.isUninitialized()) { if (x0Opposite.isUninitialized()) {
PoincareHelpers::Simplify(&x0, context, ExpressionNode::ReductionTarget::User); PoincareHelpers::Simplify(&x0, context, ExpressionNode::ReductionTarget::User);
factor = Subtraction::Builder(Symbol::Builder("x", strlen("x")), x0); if (x0.type() == ExpressionNode::Type::Addition || x0.type() == ExpressionNode::Type::Subtraction) {
} factor = Subtraction::Builder(Symbol::Builder("x", strlen("x")), Parenthesis::Builder(x0.clone()));
else { } else {
factor = Subtraction::Builder(Symbol::Builder("x", strlen("x")), x0.clone());
}
} else {
PoincareHelpers::Simplify(&x0Opposite, context, ExpressionNode::ReductionTarget::User); PoincareHelpers::Simplify(&x0Opposite, context, ExpressionNode::ReductionTarget::User);
factor = Addition::Builder(Symbol::Builder("x", strlen("x")), x0Opposite); factor = Addition::Builder(Symbol::Builder("x", strlen("x")), x0Opposite.clone());
} }
Expression solutionProduct = Power::Builder(Parenthesis::Builder(factor), Rational::Builder(2)); Expression solutionProduct = Power::Builder(Parenthesis::Builder(factor), Rational::Builder(2));
switch (multiplicationTypeForA) switch (multiplicationTypeForA)
{ {
@@ -227,7 +237,7 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
factorized = solutionProduct; factorized = solutionProduct;
break; break;
case MultiplicationTypeForA::Minus: case MultiplicationTypeForA::Minus:
factorized = Multiplication::Builder(a.clone(), solutionProduct); factorized = Opposite::Builder(solutionProduct);
break; break;
case MultiplicationTypeForA::Parenthesis: case MultiplicationTypeForA::Parenthesis:
factorized = Multiplication::Builder(Parenthesis::Builder(a.clone()), solutionProduct); factorized = Multiplication::Builder(Parenthesis::Builder(a.clone()), solutionProduct);
@@ -240,7 +250,7 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
break; break;
} }
} }
PoincareHelpers::Simplify(&delta, context, ExpressionNode::ReductionTarget::User); PoincareHelpers::Simplify(&delta, context, ExpressionNode::ReductionTarget::User);
m_layouts[0] = PoincareHelpers::CreateLayout(canonized); m_layouts[0] = PoincareHelpers::CreateLayout(canonized);
@@ -251,8 +261,7 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
if (m_numberOfSolutions > 1) { if (m_numberOfSolutions > 1) {
m_layouts[4] = PoincareHelpers::CreateLayout(x1); m_layouts[4] = PoincareHelpers::CreateLayout(x1);
} }
} } else {
else {
m_layouts[1] = PoincareHelpers::CreateLayout(delta); m_layouts[1] = PoincareHelpers::CreateLayout(delta);
} }
} }
@@ -261,8 +270,9 @@ Expression SecondDegreeListController::getOppositeIfExists(Expression e, Poincar
if (e.isNumber() && e.sign(reductionContext->context()) == ExpressionNode::Sign::Negative) { if (e.isNumber() && e.sign(reductionContext->context()) == ExpressionNode::Sign::Negative) {
Number n = static_cast<Number&>(e); Number n = static_cast<Number&>(e);
return std::move(n.setSign(ExpressionNode::Sign::Positive)); return std::move(n.setSign(ExpressionNode::Sign::Positive));
} } else if(e.type() == ExpressionNode::Type::Opposite) {
else if (e.type() == ExpressionNode::Type::Multiplication && e.numberOfChildren() > 0 && e.childAtIndex(0).isNumber() && e.childAtIndex(0).sign(reductionContext->context()) == ExpressionNode::Sign::Negative) { return std::move(e.childAtIndex(0).clone());
} else if (e.type() == ExpressionNode::Type::Multiplication && e.numberOfChildren() > 0 && e.childAtIndex(0).isNumber() && e.childAtIndex(0).sign(reductionContext->context()) == ExpressionNode::Sign::Negative) {
Multiplication m = static_cast<Multiplication&>(e); Multiplication m = static_cast<Multiplication&>(e);
if (m.childAtIndex(0).type() == ExpressionNode::Type::Rational && static_cast<Rational&>(e).isMinusOne()) { if (m.childAtIndex(0).type() == ExpressionNode::Type::Rational && static_cast<Rational&>(e).isMinusOne()) {
// The negative numeral factor is -1, we just remove it // The negative numeral factor is -1, we just remove it
@@ -282,7 +292,7 @@ I18n::Message SecondDegreeListController::messageAtIndex(int index) {
if (m_numberOfSolutions > 0) { if (m_numberOfSolutions > 0) {
if (index == 0) { if (index == 0) {
return I18n::Message::CanonicalForm; return I18n::Message::CanonicalForm;
} }
if (index == 1) { if (index == 1) {
return I18n::Message::FactorizedForm; return I18n::Message::FactorizedForm;
} }
@@ -292,14 +302,12 @@ I18n::Message SecondDegreeListController::messageAtIndex(int index) {
if (index == 3) { if (index == 3) {
if (m_numberOfSolutions == 1) { if (m_numberOfSolutions == 1) {
return I18n::Message::OnlyRoot; return I18n::Message::OnlyRoot;
} } else {
else {
return I18n::Message::FirstRoot; return I18n::Message::FirstRoot;
} }
} }
return I18n::Message::SecondRoot; return I18n::Message::SecondRoot;
} } else {
else {
switch (index) { switch (index) {
case 0: case 0:
return I18n::Message::CanonicalForm; return I18n::Message::CanonicalForm;

View File

@@ -1,16 +1,63 @@
#include "trigonometry_list_controller.h" #include "trigonometry_list_controller.h"
#include "../app.h" #include "../app.h"
#include <poincare_nodes.h>
#include "../../shared/poincare_helpers.h"
using namespace Poincare; using namespace Poincare;
namespace Calculation { namespace Calculation {
void TrigonometryListController::setExpression(Poincare::Expression e) { static constexpr int s_fullCircle[] = {
360,
2,
400
};
Poincare::Constant toConstant(Expression e) {
return static_cast<Poincare::Constant &>(e);
}
void TrigonometryListController::setExpression(Expression e) {
assert(e.type() == ExpressionNode::Type::Cosine || e.type() == ExpressionNode::Type::Sine); assert(e.type() == ExpressionNode::Type::Cosine || e.type() == ExpressionNode::Type::Sine);
IllustratedListController::setExpression(e.childAtIndex(0));
Poincare::Context * context = App::app()->localContext();
Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences();
Preferences::AngleUnit angleUnit = preferences->angleUnit();
Expression angleExpression = e.childAtIndex(0);
Shared::PoincareHelpers::Reduce(&angleExpression, context, Poincare::ExpressionNode::ReductionTarget::SystemForAnalysis);
if ((angleUnit == Preferences::AngleUnit::Radian
&& angleExpression.type() == ExpressionNode::Type::Multiplication
&& angleExpression.numberOfChildren() == 2
&& angleExpression.childAtIndex(1).type() == ExpressionNode::Type::Constant
&& toConstant(angleExpression.childAtIndex(1)).isPi()
&& angleExpression.childAtIndex(0).type() == ExpressionNode::Type::Rational)
|| ((angleUnit == Preferences::AngleUnit::Degree || angleUnit == Preferences::AngleUnit::Gradian)
&& angleExpression.type() == ExpressionNode::Type::Rational)) {
Expression extracted = angleUnit == Preferences::AngleUnit::Radian ? angleExpression.childAtIndex(0) : angleExpression;
Rational r = static_cast<Rational &>(extracted);
Integer denominator = Integer::Multiplication(r.integerDenominator(), Integer(s_fullCircle[(int) angleUnit]));
IntegerDivision division = Integer::Division(r.signedIntegerNumerator(), denominator);
Integer remainder = division.remainder;
Expression newAngle;
Integer rDenominator = r.integerDenominator();
Rational newCoefficient = Rational::Builder(remainder, rDenominator);
if (angleUnit == Preferences::AngleUnit::Radian) {
angleExpression = Multiplication::Builder(newCoefficient, angleExpression.childAtIndex(1));
} else {
angleExpression = newCoefficient;
}
}
IllustratedListController::setExpression(angleExpression);
// Fill calculation store // Fill calculation store
Poincare::Context * context = App::app()->localContext();
m_calculationStore.push("sin(θ)", context, CalculationHeight); m_calculationStore.push("sin(θ)", context, CalculationHeight);
m_calculationStore.push("cos(θ)", context, CalculationHeight); m_calculationStore.push("cos(θ)", context, CalculationHeight);
m_calculationStore.push("θ", context, CalculationHeight); m_calculationStore.push("θ", context, CalculationHeight);

View File

@@ -16,16 +16,26 @@ CalculationStore::CalculationStore(char * buffer, int size) :
m_buffer(buffer), m_buffer(buffer),
m_bufferSize(size), m_bufferSize(size),
m_calculationAreaEnd(m_buffer), m_calculationAreaEnd(m_buffer),
m_numberOfCalculations(0) m_numberOfCalculations(0),
m_trashIndex(-1)
{ {
assert(m_buffer != nullptr); assert(m_buffer != nullptr);
assert(m_bufferSize > 0); assert(m_bufferSize > 0);
} }
// Returns an expiring pointer to the calculation of index i // Returns an expiring pointer to the calculation of index i, and ignore the trash
ExpiringPointer<Calculation> CalculationStore::calculationAtIndex(int i) { ExpiringPointer<Calculation> CalculationStore::calculationAtIndex(int i) {
if (m_trashIndex == -1 || i < m_trashIndex) {
return realCalculationAtIndex(i);
} else {
return realCalculationAtIndex(i + 1);
}
}
// Returns an expiring pointer to the real calculation of index i
ExpiringPointer<Calculation> CalculationStore::realCalculationAtIndex(int i) {
assert(i >= 0 && i < m_numberOfCalculations); assert(i >= 0 && i < m_numberOfCalculations);
// m_buffer is the adress of the oldest calculation in calculation store // m_buffer is the address of the oldest calculation in calculation store
Calculation * c = (Calculation *) m_buffer; Calculation * c = (Calculation *) m_buffer;
if (i != m_numberOfCalculations-1) { if (i != m_numberOfCalculations-1) {
// The calculation we want is not the oldest one so we get its pointer // The calculation we want is not the oldest one so we get its pointer
@@ -36,12 +46,13 @@ ExpiringPointer<Calculation> CalculationStore::calculationAtIndex(int i) {
// Pushes an expression in the store // Pushes an expression in the store
ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context * context, HeightComputer heightComputer) { ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context * context, HeightComputer heightComputer) {
emptyTrash();
/* Compute ans now, before the buffer is updated and before the calculation /* Compute ans now, before the buffer is updated and before the calculation
* might be deleted */ * might be deleted */
Expression ans = ansExpression(context); Expression ans = ansExpression(context);
/* Prepare the buffer for the new calculation /* Prepare the buffer for the new calculation
*The minimal size to store the new calculation is the minimal size of a calculation plus the pointer to its end */ * The minimal size to store the new calculation is the minimal size of a calculation plus the pointer to its end */
int minSize = Calculation::MinimalSize() + sizeof(Calculation *); int minSize = Calculation::MinimalSize() + sizeof(Calculation *);
assert(m_bufferSize > minSize); assert(m_bufferSize > minSize);
while (remainingBufferSize() < minSize) { while (remainingBufferSize() < minSize) {
@@ -100,9 +111,9 @@ ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context *
numberOfSignificantDigits = Poincare::Preferences::sharedPreferences()->numberOfSignificantDigits(); numberOfSignificantDigits = Poincare::Preferences::sharedPreferences()->numberOfSignificantDigits();
} }
if (!pushSerializeExpression(outputs[i], beginingOfFreeSpace, &endOfFreeSpace, numberOfSignificantDigits)) { if (!pushSerializeExpression(outputs[i], beginingOfFreeSpace, &endOfFreeSpace, numberOfSignificantDigits)) {
/* If the exat/approximate output does not fit in the store (event if the /* If the exact/approximate output does not fit in the store (event if the
* current calculation is the only calculation), replace the output with * current calculation is the only calculation), replace the output with
* undef if it fits, else replace the whole calcualtion with undef. */ * undef if it fits, else replace the whole calculation with undef. */
Expression undef = Undefined::Builder(); Expression undef = Undefined::Builder();
if (!pushSerializeExpression(undef, beginingOfFreeSpace, &endOfFreeSpace)) { if (!pushSerializeExpression(undef, beginingOfFreeSpace, &endOfFreeSpace)) {
return emptyStoreAndPushUndef(context, heightComputer); return emptyStoreAndPushUndef(context, heightComputer);
@@ -132,15 +143,23 @@ ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context *
// Delete the calculation of index i // Delete the calculation of index i
void CalculationStore::deleteCalculationAtIndex(int i) { void CalculationStore::deleteCalculationAtIndex(int i) {
if (m_trashIndex != -1) {
emptyTrash();
}
m_trashIndex = i;
}
// Delete the calculation of index i, internal algorithm
void CalculationStore::realDeleteCalculationAtIndex(int i) {
assert(i >= 0 && i < m_numberOfCalculations); assert(i >= 0 && i < m_numberOfCalculations);
if (i == 0) { if (i == 0) {
ExpiringPointer<Calculation> lastCalculationPointer = calculationAtIndex(0); ExpiringPointer<Calculation> lastCalculationPointer = realCalculationAtIndex(0);
m_calculationAreaEnd = (char *)(lastCalculationPointer.pointer()); m_calculationAreaEnd = (char *)(lastCalculationPointer.pointer());
m_numberOfCalculations--; m_numberOfCalculations--;
return; return;
} }
char * calcI = (char *)calculationAtIndex(i).pointer(); char * calcI = (char *)realCalculationAtIndex(i).pointer();
char * nextCalc = (char *) calculationAtIndex(i-1).pointer(); char * nextCalc = (char *) realCalculationAtIndex(i-1).pointer();
assert(m_calculationAreaEnd >= nextCalc); assert(m_calculationAreaEnd >= nextCalc);
size_t slidingSize = m_calculationAreaEnd - nextCalc; size_t slidingSize = m_calculationAreaEnd - nextCalc;
// Slide the i-1 most recent calculations right after the i+1'th // Slide the i-1 most recent calculations right after the i+1'th
@@ -154,13 +173,14 @@ void CalculationStore::deleteCalculationAtIndex(int i) {
// Delete the oldest calculation in the store and returns the amount of space freed by the operation // Delete the oldest calculation in the store and returns the amount of space freed by the operation
size_t CalculationStore::deleteOldestCalculation() { size_t CalculationStore::deleteOldestCalculation() {
char * oldBufferEnd = (char *) m_calculationAreaEnd; char * oldBufferEnd = (char *) m_calculationAreaEnd;
deleteCalculationAtIndex(numberOfCalculations()-1); realDeleteCalculationAtIndex(numberOfCalculations()-1);
char * newBufferEnd = (char *) m_calculationAreaEnd; char * newBufferEnd = (char *) m_calculationAreaEnd;
return oldBufferEnd - newBufferEnd; return oldBufferEnd - newBufferEnd;
} }
// Delete all calculations // Delete all calculations
void CalculationStore::deleteAll() { void CalculationStore::deleteAll() {
m_trashIndex = -1;
m_calculationAreaEnd = m_buffer; m_calculationAreaEnd = m_buffer;
m_numberOfCalculations = 0; m_numberOfCalculations = 0;
} }
@@ -177,8 +197,8 @@ Expression CalculationStore::ansExpression(Context * context) {
* parsed), ans is replaced by the approximation output when any Store or * parsed), ans is replaced by the approximation output when any Store or
* Equal expression appears. */ * Equal expression appears. */
Expression e = mostRecentCalculation->exactOutput(); Expression e = mostRecentCalculation->exactOutput();
bool exactOuptutInvolvesStoreEqual = e.type() == ExpressionNode::Type::Store || e.type() == ExpressionNode::Type::Equal; bool exactOutputInvolvesStoreEqual = e.type() == ExpressionNode::Type::Store || e.type() == ExpressionNode::Type::Equal;
if (mostRecentCalculation->input().recursivelyMatches(Expression::IsApproximate, context) || exactOuptutInvolvesStoreEqual) { if (mostRecentCalculation->input().recursivelyMatches(Expression::IsApproximate, context) || exactOutputInvolvesStoreEqual) {
return mostRecentCalculation->approximateOutput(context, Calculation::NumberOfSignificantDigits::Maximal); return mostRecentCalculation->approximateOutput(context, Calculation::NumberOfSignificantDigits::Maximal);
} }
return mostRecentCalculation->exactOutput(); return mostRecentCalculation->exactOutput();
@@ -200,6 +220,12 @@ bool CalculationStore::pushSerializeExpression(Expression e, char * location, ch
return expressionIsPushed; return expressionIsPushed;
} }
void CalculationStore::emptyTrash() {
if (m_trashIndex != -1) {
realDeleteCalculationAtIndex(m_trashIndex);
m_trashIndex = -1;
}
}
Shared::ExpiringPointer<Calculation> CalculationStore::emptyStoreAndPushUndef(Context * context, HeightComputer heightComputer) { Shared::ExpiringPointer<Calculation> CalculationStore::emptyStoreAndPushUndef(Context * context, HeightComputer heightComputer) {
@@ -213,7 +239,7 @@ Shared::ExpiringPointer<Calculation> CalculationStore::emptyStoreAndPushUndef(Co
void CalculationStore::recomputeMemoizedPointersAfterCalculationIndex(int index) { void CalculationStore::recomputeMemoizedPointersAfterCalculationIndex(int index) {
assert(index < m_numberOfCalculations); assert(index < m_numberOfCalculations);
// Clear pointer and recompute new ones // Clear pointer and recompute new ones
Calculation * c = calculationAtIndex(index).pointer(); Calculation * c = realCalculationAtIndex(index).pointer();
Calculation * nextCalc; Calculation * nextCalc;
while (index != 0) { while (index != 0) {
nextCalc = c->next(); nextCalc = c->next();

View File

@@ -41,11 +41,15 @@ public:
void deleteCalculationAtIndex(int i); void deleteCalculationAtIndex(int i);
void deleteAll(); void deleteAll();
int remainingBufferSize() const { assert(m_calculationAreaEnd >= m_buffer); return m_bufferSize - (m_calculationAreaEnd - m_buffer) - m_numberOfCalculations*sizeof(Calculation*); } int remainingBufferSize() const { assert(m_calculationAreaEnd >= m_buffer); return m_bufferSize - (m_calculationAreaEnd - m_buffer) - m_numberOfCalculations*sizeof(Calculation*); }
int numberOfCalculations() const { return m_numberOfCalculations; } int numberOfCalculations() const { return m_numberOfCalculations - (m_trashIndex != -1); }
Poincare::Expression ansExpression(Poincare::Context * context); Poincare::Expression ansExpression(Poincare::Context * context);
int bufferSize() { return m_bufferSize; } int bufferSize() { return m_bufferSize; }
void reinsertTrash() { m_trashIndex = -1; }
private: private:
void emptyTrash();
Shared::ExpiringPointer<Calculation> realCalculationAtIndex(int i);
void realDeleteCalculationAtIndex(int i);
class CalculationIterator { class CalculationIterator {
public: public:
@@ -70,6 +74,7 @@ private:
int m_bufferSize; int m_bufferSize;
const char * m_calculationAreaEnd; const char * m_calculationAreaEnd;
int m_numberOfCalculations; int m_numberOfCalculations;
int m_trashIndex;
size_t deleteOldestCalculation(); size_t deleteOldestCalculation();
char * addressOfPointerToCalculationOfIndex(int i) {return m_buffer + m_bufferSize - (m_numberOfCalculations - i)*sizeof(Calculation *);} char * addressOfPointerToCalculationOfIndex(int i) {return m_buffer + m_bufferSize - (m_numberOfCalculations - i)*sizeof(Calculation *);}

View File

@@ -68,6 +68,15 @@ void EditExpressionController::memoizeInput() {
*m_cacheBufferInformation = m_contentView.expressionField()->moveCursorAndDumpContent(m_cacheBuffer, k_cacheBufferSize); *m_cacheBufferInformation = m_contentView.expressionField()->moveCursorAndDumpContent(m_cacheBuffer, k_cacheBufferSize);
} }
bool EditExpressionController::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::ShiftBack) {
m_historyController->reinsertTrash();
m_historyController->reload();
return true;
}
return false;
}
void EditExpressionController::viewWillAppear() { void EditExpressionController::viewWillAppear() {
m_historyController->viewWillAppear(); m_historyController->viewWillAppear();
} }

View File

@@ -31,6 +31,7 @@ public:
void insertTextBody(const char * text); void insertTextBody(const char * text);
void restoreInput(); void restoreInput();
void memoizeInput(); void memoizeInput();
bool handleEvent(Ion::Events::Event event) override;
/* TextFieldDelegate */ /* TextFieldDelegate */
bool textFieldDidReceiveEvent(::TextField * textField, Ion::Events::Event event) override; bool textFieldDidReceiveEvent(::TextField * textField, Ion::Events::Event event) override;

View File

@@ -35,6 +35,7 @@ public:
int typeAtLocation(int i, int j) override; int typeAtLocation(int i, int j) override;
void setSelectedSubviewType(SubviewType subviewType, bool sameCell, int previousSelectedX = -1, int previousSelectedY = -1) override; 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; void tableViewDidChangeSelectionAndDidScroll(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection = false) override;
void reinsertTrash() { m_calculationStore->reinsertTrash(); }
private: private:
int storeIndex(int i) { return numberOfRows() - i - 1; } int storeIndex(int i) { return numberOfRows() - i - 1; }
Shared::ExpiringPointer<Calculation> calculationAtIndex(int i); Shared::ExpiringPointer<Calculation> calculationAtIndex(int i);

View File

@@ -75,7 +75,7 @@ public:
VariableBoxController * variableBoxController() { return &m_variableBoxController; } VariableBoxController * variableBoxController() { return &m_variableBoxController; }
static constexpr int k_pythonHeapSize = 67000; static constexpr int k_pythonHeapSize = 70000;
private: private:
/* Python delegate: /* Python delegate:

View File

@@ -1,3 +1,2 @@
CodeAppCapital = "PYTHON" CodeAppCapital = "PYTHON"
ConsolePrompt = ">>> " ConsolePrompt = ">>> "
ScriptParameters = "..."

View File

@@ -53,6 +53,7 @@ PythonErfc = "Komplementäre Fehlerfunktion"
PythonEval = "Rückgabe ausgewerteter Ausdruck" PythonEval = "Rückgabe ausgewerteter Ausdruck"
PythonExp = "Exponentialfunktion" PythonExp = "Exponentialfunktion"
PythonExpm1 = "Berechne exp(x)-1" PythonExpm1 = "Berechne exp(x)-1"
PythonFactorial = "Fakultät von x"
PythonFabs = "Absoluter Wert" PythonFabs = "Absoluter Wert"
PythonFillRect = "Gefülltes Rechteck bei Pixel (x,y)" PythonFillRect = "Gefülltes Rechteck bei Pixel (x,y)"
PythonFillCircle = "Füllt einen Kreis" PythonFillCircle = "Füllt einen Kreis"
@@ -102,10 +103,58 @@ PythonIsFinite = "Prüfen, ob x endlich ist"
PythonIsInfinite = "Prüfen, ob x unendlich ist" PythonIsInfinite = "Prüfen, ob x unendlich ist"
PythonIsNaN = "Prüfen, ob x keine Zahl ist" PythonIsNaN = "Prüfen, ob x keine Zahl ist"
PythonIsKeyDown = "Wahr, wenn die Taste k gedrückt ist" PythonIsKeyDown = "Wahr, wenn die Taste k gedrückt ist"
PythonBattery = "Return battery voltage" PythonBattery = "Rückgabe der Batteriespannung"
PythonBatteryLevel = "Return battery level" PythonBatteryLevel = "Gibt den Batteriestand zurück"
PythonBatteryIscharging = "Return if battery is charging" PythonBatteryIscharging = "Gibt zurück, ob die Batterie geladen wird"
PythonSetBrightness = "Helligkeitsstufe festlegen"
PythonGetBrightness = "Helligkeitsstufe abrufen"
PythonKandinskyFunction = "Kandinsky-Modul Funktionspräfix" PythonKandinskyFunction = "Kandinsky-Modul Funktionspräfix"
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 = "Liefert x*(2**i), Inverse von frexp" PythonLdexp = "Liefert x*(2**i), Inverse von frexp"
PythonLength = "Länge eines Objekts" PythonLength = "Länge eines Objekts"
PythonLgamma = "Log-Gamma-Funktion" PythonLgamma = "Log-Gamma-Funktion"
@@ -183,14 +232,11 @@ PythonTurtlePosition = "Aktuelle (x,y) Position zurückgeben"
PythonTurtleReset = "Die Zeichnung zurücksetzen" PythonTurtleReset = "Die Zeichnung zurücksetzen"
PythonTurtleRight = "Um ein Grad nach rechts drehen" PythonTurtleRight = "Um ein Grad nach rechts drehen"
PythonTurtleSetheading = "Ausrichtung auf einen Grad setzen" PythonTurtleSetheading = "Ausrichtung auf einen Grad setzen"
PythonTurtleSetposition = "Den Igel auf Position setzen"
PythonTurtleShowturtle = "Den Igel anzeigen" PythonTurtleShowturtle = "Den Igel anzeigen"
PythonTurtleSpeed = "Zeichengeschwindigkeit von 0 bis 10" PythonTurtleSpeed = "Zeichengeschwindigkeit von 0 bis 10"
PythonTurtleWrite = "Einen Text anzeigen" PythonTurtleWrite = "Einen Text anzeigen"
PythonUniform = "Fließkommazahl in [a,b]" PythonUniform = "Fließkommazahl in [a,b]"
PythonImportTime = "Time-Modul importieren" PythonImportTime = "Time-Modul importieren"
PythonTimePrefix = "Zeitmodul-Funktionspräfix"
PythonTimeSleep = "Warte für n Sekunden"
PythonMonotonic = "Monotone Zeit zurückgeben" PythonMonotonic = "Monotone Zeit zurückgeben"
PythonFileOpen = "Öffnet eine Datei" PythonFileOpen = "Öffnet eine Datei"
PythonFileSeekable = "Kann Datei durchsucht werden?" PythonFileSeekable = "Kann Datei durchsucht werden?"

View File

@@ -53,6 +53,7 @@ PythonErfc = "Complementary error function"
PythonEval = "Return the evaluated expression" PythonEval = "Return the evaluated expression"
PythonExp = "Exponential function" PythonExp = "Exponential function"
PythonExpm1 = "Compute exp(x)-1" PythonExpm1 = "Compute exp(x)-1"
PythonFactorial = "Factorial of x"
PythonFabs = "Absolute value" PythonFabs = "Absolute value"
PythonFillCircle = "Fill a circle" PythonFillCircle = "Fill a circle"
PythonFillPolygon = "Fill a polygon" PythonFillPolygon = "Fill a polygon"
@@ -90,8 +91,56 @@ PythonIsKeyDown = "Return True if the k key is down"
PythonBattery = "Return battery voltage" PythonBattery = "Return battery voltage"
PythonBatteryLevel = "Return battery level" PythonBatteryLevel = "Return battery level"
PythonBatteryIscharging = "Return if battery is charging" PythonBatteryIscharging = "Return if battery is charging"
PythonSetBrightness = "Set brightness level"
PythonGetBrightness = "Get brightness level"
PythonIsNaN = "Check if x is a NaN" PythonIsNaN = "Check if x is a NaN"
PythonKandinskyFunction = "kandinsky module function prefix" 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" PythonLdexp = "Return x*(2**i), inverse of frexp"
PythonLength = "Length of an object" PythonLength = "Length of an object"
PythonLgamma = "Log-gamma function" PythonLgamma = "Log-gamma function"
@@ -169,7 +218,6 @@ PythonTurtlePosition = "Return the current (x,y) location"
PythonTurtleReset = "Reset the drawing" PythonTurtleReset = "Reset the drawing"
PythonTurtleRight = "Turn right by a degrees" PythonTurtleRight = "Turn right by a degrees"
PythonTurtleSetheading = "Set the orientation to a degrees" PythonTurtleSetheading = "Set the orientation to a degrees"
PythonTurtleSetposition = "Positionne la tortue"
PythonTurtleShowturtle = "Show the turtle" PythonTurtleShowturtle = "Show the turtle"
PythonTurtleSpeed = "Drawing speed between 0 and 10" PythonTurtleSpeed = "Drawing speed between 0 and 10"
PythonTurtleWrite = "Display a text" PythonTurtleWrite = "Display a text"
@@ -189,8 +237,6 @@ PythonSysImplementation = "Information about Python"
PythonSysModules = "Dictionary of loaded modules" PythonSysModules = "Dictionary of loaded modules"
PythonSysVersion = "Python language version (string)" PythonSysVersion = "Python language version (string)"
PythonSysVersioninfo = "Python language version (tuple)" PythonSysVersioninfo = "Python language version (tuple)"
PythonTimePrefix = "time module function prefix"
PythonTimeSleep = "Wait for n second"
PythonMonotonic = "Return monotonic time" PythonMonotonic = "Return monotonic time"
PythonFileOpen = "Opens a file" PythonFileOpen = "Opens a file"
PythonFileSeekable = "Tells if seek can be used on a file" PythonFileSeekable = "Tells if seek can be used on a file"

View File

@@ -53,6 +53,7 @@ PythonErfc = "Complementary error function"
PythonEval = "Return the evaluated expression" PythonEval = "Return the evaluated expression"
PythonExp = "Exponential function" PythonExp = "Exponential function"
PythonExpm1 = "Compute exp(x)-1" PythonExpm1 = "Compute exp(x)-1"
PythonFactorial = "factorial de x"
PythonFabs = "Absolute value" PythonFabs = "Absolute value"
PythonFillCircle = "Fill a circle" PythonFillCircle = "Fill a circle"
PythonFillPolygon = "Fill a polygon" PythonFillPolygon = "Fill a polygon"
@@ -87,11 +88,59 @@ PythonIonFunction = "ion module function prefix"
PythonIsFinite = "Check if x is finite" PythonIsFinite = "Check if x is finite"
PythonIsInfinite = "Check if x is infinity" PythonIsInfinite = "Check if x is infinity"
PythonIsKeyDown = "Return True if the k key is down" PythonIsKeyDown = "Return True if the k key is down"
PythonBattery = "Return battery voltage" PythonBattery = "Rückgabe der Batteriespannung"
PythonBatteryLevel = "Return battery level" PythonBatteryLevel = "Gibt den Batteriestand zurück"
PythonBatteryIscharging = "Return if battery is charging" PythonBatteryIscharging = "Gibt zurück, ob die Batterie geladen wird"
PythonSetBrightness = "Establecer nivel de brillo"
PythonGetBrightness = "Obtener nivel de brillo"
PythonIsNaN = "Check if x is a NaN" PythonIsNaN = "Check if x is a NaN"
PythonKandinskyFunction = "kandinsky module function prefix" 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" PythonLdexp = "Return x*(2**i), inverse of frexp"
PythonLength = "Length of an object" PythonLength = "Length of an object"
PythonLgamma = "Log-gamma function" PythonLgamma = "Log-gamma function"
@@ -169,7 +218,6 @@ PythonTurtlePosition = "Return the current (x,y) location"
PythonTurtleReset = "Reset the drawing" PythonTurtleReset = "Reset the drawing"
PythonTurtleRight = "Turn right by a degrees" PythonTurtleRight = "Turn right by a degrees"
PythonTurtleSetheading = "Set the orientation to a degrees" PythonTurtleSetheading = "Set the orientation to a degrees"
PythonTurtleSetposition = "Positionne la tortue"
PythonTurtleShowturtle = "Show the turtle" PythonTurtleShowturtle = "Show the turtle"
PythonTurtleSpeed = "Drawing speed between 0 and 10" PythonTurtleSpeed = "Drawing speed between 0 and 10"
PythonTurtleWrite = "Display a text" PythonTurtleWrite = "Display a text"
@@ -189,8 +237,6 @@ PythonSysImplementation = "Information about Python"
PythonSysModules = "Dictionary of loaded modules" PythonSysModules = "Dictionary of loaded modules"
PythonSysVersion = "Python language version (string)" PythonSysVersion = "Python language version (string)"
PythonSysVersioninfo = "Python language version (tuple)" PythonSysVersioninfo = "Python language version (tuple)"
PythonTimePrefix = "time module function prefix"
PythonTimeSleep = "Esperar n segundos"
PythonMonotonic = "Tiempo monótono de retorno" PythonMonotonic = "Tiempo monótono de retorno"
PythonFileOpen = "Opens a file" PythonFileOpen = "Opens a file"
PythonFileSeekable = "Tells if seek can be used on a file" PythonFileSeekable = "Tells if seek can be used on a file"

View File

@@ -53,6 +53,7 @@ PythonErfc = "Fonction d'erreur complémentaire"
PythonEval = "Evalue l'expression en argument " PythonEval = "Evalue l'expression en argument "
PythonExp = "Fonction exponentielle" PythonExp = "Fonction exponentielle"
PythonExpm1 = "Calcul de exp(x)-1" PythonExpm1 = "Calcul de exp(x)-1"
PythonFactorial = "Factorielle de x"
PythonFabs = "Valeur absolue" PythonFabs = "Valeur absolue"
PythonFillCircle = "Remplit un cercle" PythonFillCircle = "Remplit un cercle"
PythonFillPolygon = "Remplit un polygone" PythonFillPolygon = "Remplit un polygone"
@@ -90,8 +91,56 @@ PythonIsKeyDown = "Renvoie True si touche k enfoncée"
PythonBattery = "Renvoie le voltage de la batterie" PythonBattery = "Renvoie le voltage de la batterie"
PythonBatteryLevel = "Renvoie le niveau de la batterie" PythonBatteryLevel = "Renvoie le niveau de la batterie"
PythonBatteryIscharging = "Chargement en cours" PythonBatteryIscharging = "Chargement en cours"
PythonSetBrightness = "Définir le niveau de luminosité"
PythonGetBrightness = "Obtenir le niveau de luminosité"
PythonIsNaN = "Teste si x est NaN" PythonIsNaN = "Teste si x est NaN"
PythonKandinskyFunction = "Préfixe fonction module kandinsky" PythonKandinskyFunction = "Préfixe fonction module kandinsky"
PythonKeyLeft = "Touche FLECHE GAUCHE"
PythonKeyUp = "Touche FLECHE HAUT"
PythonKeyDown = "Touche FLECHE BAS"
PythonKeyRight = "Touche FLECHE DROITE"
PythonKeyOk = "Touche OK"
PythonKeyBack = "Touche RETOUR"
PythonKeyHome = "Touche HOME"
PythonKeyOnOff = "Touche ON/OFF"
PythonKeyShift = "Touche SHIFT"
PythonKeyAlpha = "Touche ALPHA"
PythonKeyXnt = "Touche X,N,T"
PythonKeyVar = "Touche VAR"
PythonKeyToolbox = "Touche BOITE A OUTILS"
PythonKeyBackspace = "Touche EFFACER"
PythonKeyExp = "Touche EXPONENTIELLE"
PythonKeyLn = "Touche LOGARITHME NEPERIEN"
PythonKeyLog = "Touche LOGARITHME DECIMAL"
PythonKeyImaginary = "Touche I IMAGINAIRE"
PythonKeyComma = "Touche VIRGULE"
PythonKeyPower = "Touche PUISSANCE"
PythonKeySine = "Touche SINUS"
PythonKeyCosine = "Touche COSINUS"
PythonKeyTangent = "Touche TANGENTE"
PythonKeyPi = "Touche PI"
PythonKeySqrt = "Touche RACINE CARREE"
PythonKeySquare = "Touche CARRE"
PythonKeySeven = "Touche 7"
PythonKeyEight = "Touche 8"
PythonKeyNine = "Touche 9"
PythonKeyLeftParenthesis = "Touche PARENTHESE GAUCHE"
PythonKeyRightParenthesis = "Touche PARENTHESE DROITE"
PythonKeyFour = "Touche 4"
PythonKeyFive = "Touche 5"
PythonKeySix = "Touche 6"
PythonKeyMultiplication = "Touche MULTIPLICATION"
PythonKeyDivision = "Touche DIVISION"
PythonKeyOne = "Touche 1"
PythonKeyTwo = "Touche 2"
PythonKeyThree = "Touche 3"
PythonKeyPlus = "Touche PLUS"
PythonKeyMinus = "Touche MOINS"
PythonKeyZero = "Touche 0"
PythonKeyDot = "Touche POINT"
PythonKeyEe = "Touche 10 PUISSANCE X"
PythonKeyAns = "Touche ANS"
PythonKeyExe = "Touche EXE"
PythonLdexp = "Inverse de frexp : x*(2**i)" PythonLdexp = "Inverse de frexp : x*(2**i)"
PythonLength = "Longueur d'un objet" PythonLength = "Longueur d'un objet"
PythonLgamma = "Logarithme de la fonction gamma" PythonLgamma = "Logarithme de la fonction gamma"
@@ -127,7 +176,7 @@ PythonRandrange = "Nombre dans range(start,stop)"
PythonRangeStartStop = "Liste de start à stop-1" PythonRangeStartStop = "Liste de start à stop-1"
PythonRangeStop = "Liste de 0 à stop-1" PythonRangeStop = "Liste de 0 à stop-1"
PythonRect = "Conversion en algébrique" PythonRect = "Conversion en algébrique"
PythonRemove = "Supprime le premier x de la liste" PythonRemove = "Supprime le premier x de la liste"
PythonReverse = "Inverse les éléments de la liste" PythonReverse = "Inverse les éléments de la liste"
PythonRound = "Arrondi à n décimales" PythonRound = "Arrondi à n décimales"
PythonScatter = "Nuage des points (x,y)" PythonScatter = "Nuage des points (x,y)"
@@ -169,7 +218,6 @@ PythonTurtlePosition = "Renvoie la position (x,y)"
PythonTurtleReset = "Réinitialise le dessin" PythonTurtleReset = "Réinitialise le dessin"
PythonTurtleRight = "Pivote de a degrés vers la droite" PythonTurtleRight = "Pivote de a degrés vers la droite"
PythonTurtleSetheading = "Met un cap de a degrés" PythonTurtleSetheading = "Met un cap de a degrés"
PythonTurtleSetposition = "Positionne la tortue"
PythonTurtleShowturtle = "Affiche la tortue" PythonTurtleShowturtle = "Affiche la tortue"
PythonTurtleSpeed = "Vitesse du tracé entre 0 et 10" PythonTurtleSpeed = "Vitesse du tracé entre 0 et 10"
PythonTurtleWrite = "Affiche un texte" PythonTurtleWrite = "Affiche un texte"
@@ -189,8 +237,6 @@ PythonSysImplementation = "Information sur Python"
PythonSysModules = "Dictionnaire des modules chargés" PythonSysModules = "Dictionnaire des modules chargés"
PythonSysVersion = "Version du langage Python (string)" PythonSysVersion = "Version du langage Python (string)"
PythonSysVersioninfo = "Version du langage Python (tuple)" PythonSysVersioninfo = "Version du langage Python (tuple)"
PythonTimePrefix = "Préfixe fonction du module temps"
PythonTimeSleep = "Attendre n secondes"
PythonMonotonic = "Retourne le temps monotone" PythonMonotonic = "Retourne le temps monotone"
PythonFileOpen = "Ouvre un fichier" PythonFileOpen = "Ouvre un fichier"
PythonFileSeekable = "Indique si seek peut être utilisé" PythonFileSeekable = "Indique si seek peut être utilisé"

View File

@@ -1,210 +1,256 @@
PythonPound = "Megjegyzés" PythonPound = "Megjegyzés"
PythonPercent = "Modulo" PythonPercent = "Modulo"
Python1J = "Képzeletbeli i" Python1J = "Képzeletbeli i"
PythonLF = "Enter" PythonLF = "Enter"
PythonTab = "Táblázat" PythonTab = "Táblázat"
PythonAmpersand = "Logikus és" PythonAmpersand = "Logikus és"
PythonSymbolExp = "logikus exkluzív vagy pedig" PythonSymbolExp = "logikus exkluzív vagy pedig"
PythonVerticalBar = "logikus vagy pedig" PythonVerticalBar = "logikus vagy pedig"
PythonImag = "z képzeletbeli része" PythonImag = "z képzeletbeli része"
PythonReal = "z valódi része" PythonReal = "z valódi része"
PythonSingleQuote = "apostróf" PythonSingleQuote = "apostróf"
PythonAbs = "Abszolút érték/nagyság" PythonAbs = "Abszolút érték/nagyság"
PythonAcos = "Ív (arc) koszinusz" PythonAcos = "Ív (arc) koszinusz"
PythonAcosh = "Hiperbolikus arc koszinusz" PythonAcosh = "Hiperbolikus arc koszinusz"
PythonAppend = "Lista végére hozzáadni x-et" PythonAppend = "Lista végére hozzáadni x-et"
PythonArrow = "(x,y) nyíla (x+dx,y+dy) nyílához" PythonArrow = "(x,y) nyíla (x+dx,y+dy) nyílához"
PythonAsin = "Ív (arc) szinusz" PythonAsin = "Ív (arc) szinusz"
PythonAsinh = "Hiperbolikus ív (arc) szinusz" PythonAsinh = "Hiperbolikus ív (arc) szinusz"
PythonAtan = "Ív (arc) érintö (tan)" PythonAtan = "Ív (arc) érintö (tan)"
PythonAtan2 = "atan(y/x) sámolása" PythonAtan2 = "atan(y/x) sámolása"
PythonAtanh = "Hiperbolikus ív (arc) érintö (atan)" PythonAtanh = "Hiperbolikus ív (arc) érintö (atan)"
PythonAxis = "Tengelyeket (xmin,xmax,ymin,ymax)-ra állitani" PythonAxis = "Tengelyeket (xmin,xmax,ymin,ymax)-ra állitani"
PythonBar = "Az x lista oszlopdiagramja" PythonBar = "Az x lista oszlopdiagramja"
PythonBin = "Egész szám konvertálása binárisra" PythonBin = "Egész szám konvertálása binárisra"
PythonCeil = "Mennyezet" PythonCeil = "Mennyezet"
PythonChoice = "Véletlenszerü szám a listában" PythonChoice = "Véletlenszerü szám a listában"
PythonClear = "A lista ürítése" PythonClear = "A lista ürítése"
PythonCmathFunction = "cmath modul funkció elötag" PythonCmathFunction = "cmath modul funkció elötag"
PythonColor = "Rgb (pzk) szín allítása" PythonColor = "Rgb (pzk) szín allítása"
PythonColorBlack = "Fekete szín" PythonColorBlack = "Fekete szín"
PythonColorBlue = "Kék szín" PythonColorBlue = "Kék szín"
PythonColorBrown = "Barna szín" PythonColorBrown = "Barna szín"
PythonColorGreen = "Zöld szín" PythonColorGreen = "Zöld szín"
PythonColorGray = "Szürke szín" PythonColorGray = "Szürke szín"
PythonColorOrange = "Narancssárga szín" PythonColorOrange = "Narancssárga szín"
PythonColorPink = "Rózsaszín szín" PythonColorPink = "Rózsaszín szín"
PythonColorPurple = "Lila szín" PythonColorPurple = "Lila szín"
PythonColorRed = "Piros szín" PythonColorRed = "Piros szín"
PythonColorWhite = "Fehér szín" PythonColorWhite = "Fehér szín"
PythonColorYellow = "Sárga szín" PythonColorYellow = "Sárga szín"
PythonComplex = "A + ib visszaadása" PythonComplex = "A + ib visszaadása"
PythonCopySign = "X visszaadása y jelével" PythonCopySign = "X visszaadása y jelével"
PythonCos = "Koszinusz" PythonCos = "Koszinusz"
PythonCosh = "Hiperbolikus koszinusz" PythonCosh = "Hiperbolikus koszinusz"
PythonCount = "Számolja az x elöfordulását" PythonCount = "Számolja az x elöfordulását"
PythonDegrees = "x konvertálása radiánokrol fokokra" PythonDegrees = "x konvertálása radiánokrol fokokra"
PythonDivMod = "Hányados és maradék" PythonDivMod = "Hányados és maradék"
PythonDrawCircle = "Rajzolj egy kört" PythonDrawCircle = "Rajzolj egy kört"
PythonDrawLine = "Húzzon egy vonalat " PythonDrawLine = "Húzzon egy vonalat "
PythonDrawString = "Szöveg megjelenítése (x, y)-en" PythonDrawString = "Szöveg megjelenítése (x, y)-en"
PythonErf = "Hiba funkció" PythonErf = "Hiba funkció"
PythonErfc = "Kiegészítö hiba funkció" PythonErfc = "Kiegészítö hiba funkció"
PythonEval = "Visszaadja az értékelt kifejezést" PythonEval = "Visszaadja az értékelt kifejezést"
PythonExp = "Exponenciális függvény" PythonExp = "Exponenciális függvény"
PythonExpm1 = "exp(x)-1 sámitása" PythonExpm1 = "exp(x)-1 sámitása"
PythonFabs = "Abszolút érték" PythonFactorial = "x faktorál"
PythonFillRect = "Téglalap töltése" PythonFabs = "Abszolút érték"
PythonFillCircle = "Kitölti a kört" PythonFillRect = "Téglalap töltése"
PythonFillPolygon = "Kitölti a poligont" PythonFillCircle = "Kitölti a kört"
PythonFloat = "Konvertálása tizedes számra" PythonFillPolygon = "Kitölti a poligont"
PythonFloor = "Egész része" PythonFloat = "Konvertálása tizedes számra"
PythonFmod = "a modulo b" PythonFloor = "Egész része"
PythonFrExp = "X mantissája és kiállítója" PythonFmod = "a modulo b"
PythonGamma = "Gamma funkció" PythonFrExp = "X mantissája és kiállítója"
PythonGetKeys = "Billentyűk lenyomva" PythonGamma = "Gamma funkció"
PythonGetPalette = "Téma paletta beszerzése" PythonGetKeys = "Billentyűk lenyomva"
PythonGetPixel = "Visszatéríti (x,y) színét" PythonGetPalette = "Téma paletta beszerzése"
PythonGetrandbits = "Váletlenszám visszatérítése k biten" PythonGetPixel = "Visszatéríti (x,y) színét"
PythonGrid = "Rács megjelenítése/elrejtése" PythonGetrandbits = "Váletlenszám visszatérítése k biten"
PythonHex = "Decimális szám konvertálása hexadecimális számra" PythonGrid = "Rács megjelenítése/elrejtése"
PythonHist = "x hisztográmiája" PythonHex = "Decimális szám konvertálása hexadecimális számra"
PythonImportCmath = "cmath modul importálása" PythonHist = "x hisztográmiája"
PythonImportIon = "Ion modul importálása" PythonImportCmath = "cmath modul importálása"
PythonImportKandinsky = "Kandinsky modul importálása" PythonImportIon = "Ion modul importálása"
PythonImportRandom = "Véletlenszerü modul importálása" PythonImportKandinsky = "Kandinsky modul importálása"
PythonImportMath = "math modul importálása" PythonImportRandom = "Véletlenszerü modul importálása"
PythonImportMatplotlibPyplot = "matplotlib.pyplot modul importálása" PythonImportMath = "math modul importálása"
PythonImportNumpy = "ulab.numpy modul importálása" PythonImportMatplotlibPyplot = "matplotlib.pyplot modul importálása"
PythonImportScipy = "ulab.scipy modul importálása" PythonImportNumpy = "ulab.numpy modul importálása"
PythonImportTurtle = "turtle modul importálása" PythonImportScipy = "ulab.scipy modul importálása"
PythonImportTime = "time modul importálása" PythonImportTurtle = "turtle modul importálása"
PythonIndex = "Az elsö x esemény indexe" PythonImportTime = "time modul importálása"
PythonInput = "Irjon egy értéket (számot)" PythonIndex = "Az elsö x esemény indexe"
PythonInsert = "x-et i. pozícióra helyezze a listában" PythonInput = "Irjon egy értéket (számot)"
PythonInt = "egész számra konvertálás" PythonInsert = "x-et i. pozícióra helyezze a listában"
PythonIonFunction = "ion modul funkció elötag" PythonInt = "egész számra konvertálás"
PythonIsFinite = "x véges-e" PythonIonFunction = "ion modul funkció elötag"
PythonIsInfinite = "x végtelen-e" PythonIsFinite = "x véges-e"
PythonIsKeyDown = "True-t válaszol ha a k gomb le van nyomva" PythonIsInfinite = "x végtelen-e"
PythonBattery = "Return battery voltage" PythonIsKeyDown = "True-t válaszol ha a k gomb le van nyomva"
PythonBatteryLevel = "Return battery level" PythonBattery = "Az akkumulátor feszültségének visszaadása"
PythonBatteryIscharging = "Return if battery is charging" PythonBatteryLevel = "Az akkumulátor töltöttségi szintjének visszaadása"
PythonIsNaN = "Ellenörizze hogy x nem NaN" PythonBatteryIscharging = "Visszaadja, ha az akkumulátor töltődik"
PythonKandinskyFunction = "kandinsky modul funkció elötag" PythonSetBrightness = "Fényerőszint beállítása"
PythonLdexp = "frexp ellentéte : x*(2**i)" PythonGetBrightness = "Get brightness level"
PythonLength = "Egy targy hossza" PythonIsNaN = "Ellenörizze hogy x nem NaN"
PythonLgamma = "Gamma funkció logaritmusa" PythonKandinskyFunction = "kandinsky modul funkció elötag"
PythonLog = "a alapú logaritmus" PythonLdexp = "frexp ellentéte : x*(2**i)"
PythonLog10 = "Decimális logaritmus" PythonLength = "Egy targy hossza"
PythonLog2 = "Bináris logaritmus" PythonLgamma = "Gamma funkció logaritmusa"
PythonMathFunction = "math modul funkció elötag" PythonLog = "a alapú logaritmus"
PythonMatplotlibPyplotFunction = "matplotlib.pyplot elötag" PythonLog10 = "Decimális logaritmus"
PythonMax = "Maximum" PythonLog2 = "Bináris logaritmus"
PythonMin = "Minimum" PythonMathFunction = "math modul funkció elötag"
PythonModf = "x-nek tört és egész részei" PythonMatplotlibPyplotFunction = "matplotlib.pyplot elötag"
PythonMonotonic = "Az óra értékét adja vissza" PythonMax = "Maximum"
PythonNumpyFunction = "numpy elötag" PythonMin = "Minimum"
PythonNumpyFftFunction = "numpy.fft elötag" PythonModf = "x-nek tört és egész részei"
PythonNumpyLinalgFunction = "numpy.linalg elötag" PythonMonotonic = "Az óra értékét adja vissza"
PythonScipyFunction = "scipy elötag" PythonNumpyFunction = "numpy elötag"
PythonScipyLinalgFunction = "scipy.linalg elötag" PythonNumpyFftFunction = "numpy.fft elötag"
PythonScipyOptimizeFunction = "scipy.optimize elötag" PythonNumpyLinalgFunction = "numpy.linalg elötag"
PythonScipySignalFunction = "scipy.signal elötag" PythonScipyFunction = "scipy elötag"
PythonScipySpecialFunction = "scipy.special elötag" PythonScipyLinalgFunction = "scipy.linalg elötag"
PythonOct = "Decimális szám konvertálása octális számra" PythonScipyOptimizeFunction = "scipy.optimize elötag"
PythonPhase = "z fázisa" PythonScipySignalFunction = "scipy.signal elötag"
PythonPlot = "y-t jelöli x függvényében" PythonScipySpecialFunction = "scipy.special elötag"
PythonPolar = "Verctorizálni" PythonOct = "Decimális szám konvertálása octális számra"
PythonPop = "Az utolsó elemet el törölni" PythonPhase = "z fázisa"
PythonPower = "x y. kitevö" PythonPlot = "y-t jelöli x függvényében"
PythonPrint = "Ki irni a elemeket" PythonPolar = "Verctorizálni"
PythonRadians = "Fokról radiánra konvertálni" PythonPop = "Az utolsó elemet el törölni"
PythonRandint = "Véletlen egész szám [a;b] -ban" PythonPower = "x y. kitevö"
PythonRandom = "Decimális szám [0;1] -ban" PythonPrint = "Ki irni a elemeket"
PythonRandomFunction = "random modul funkció elötag" PythonRadians = "Fokról radiánra konvertálni"
PythonRandrange = "Véletlen szám range(start,stop)-ban" PythonRandint = "Véletlen egész szám [a;b] -ban"
PythonRangeStartStop = "start-tol stop-ig listája" PythonRandom = "Decimális szám [0;1] -ban"
PythonRangeStop = "0 tol stop-ig lista" PythonRandomFunction = "random modul funkció elötag"
PythonRect = "Algebrai számra konvertálni" PythonRandrange = "Véletlen szám range(start,stop)-ban"
PythonRemove = "Elsö x elöfordulását törolni" PythonRangeStartStop = "start-tol stop-ig listája"
PythonReverse = "A lista elemeit megfordítani (másik irány)" PythonRangeStop = "0 tol stop-ig lista"
PythonRound = "N számjegyre kerekítni" PythonRect = "Algebrai számra konvertálni"
PythonScatter = "(x,y) halmaza" PythonRemove = "Elsö x elöfordulását törolni"
PythonSeed = "Inicializálni a véletlenszám-választót" PythonReverse = "A lista elemeit megfordítani (másik irány)"
PythonSetPixel = "Az (x,y) pixel-t ki szinezni" PythonRound = "N számjegyre kerekítni"
PythonShow = "Mutassa az ábrát" PythonScatter = "(x,y) halmaza"
PythonSin = "Szinusz" PythonSeed = "Inicializálni a véletlenszám-választót"
PythonSinh = "Hiperbolikus szinusz" PythonSetPixel = "Az (x,y) pixel-t ki szinezni"
PythonSleep = "t másodpercre meg állitani a programmot" PythonShow = "Mutassa az ábrát"
PythonLocalTime = "Idő konvertálása csomóvá" PythonSin = "Szinusz"
PythonMktime = "A tuple konvertálása az időben" PythonSinh = "Hiperbolikus szinusz"
PythonTime = "Az aktuális időbélyeg letöltése" PythonSleep = "t másodpercre meg állitani a programmot"
PythonSetLocaltime = "Idő beállítása egy csomóból" PythonLocalTime = "Idő konvertálása csomó"
PythonRTCmode = "Aktuális RTC mód" PythonMktime = "A tuple konvertálása az időben"
PythonSetRTCmode = "RTC mód beállítása" PythonTime = "Az aktuális időbélyeg letöltése"
PythonSort = "A listát rendezni" PythonSetLocaltime = "Idő beállítása egy csomóból"
PythonSqrt = "Négyzetgyök" PythonRTCmode = "Aktuális RTC mód"
PythonSum = "Összeadni a lista elemeit" PythonSetRTCmode = "RTC mód beállítása"
PythonTan = "Érintö (tan)" PythonSort = "A listát rendezni"
PythonTanh = "Hiperbolikus érintö (tan)" PythonSqrt = "Négyzetgyök"
PythonText = "(x,y) nél egy szöveget irni" PythonSum = "Összeadni a lista elemeit"
PythonTimeFunction = "time funkció elötag" PythonTan = "Érintö (tan)"
PythonTrunc = "Egész csonka (?)" PythonTanh = "Hiperbolikus érintö (tan)"
PythonTurtleBackward = "x pixelt hátra" PythonText = "(x,y) nél egy szöveget irni"
PythonTurtleCircle = "r pixel sugarú kört rajzolni" PythonTimeFunction = "time funkció elötag"
PythonTurtleColor = "Toll szinét beállitani" PythonTrunc = "Egész csonka (?)"
PythonTurtleColorMode = "Szin módot 1.0-ra vagy 255-ra állitani" PythonTurtleBackward = "x pixelt hátra"
PythonTurtleForward = "x pixelt elölre" PythonTurtleCircle = "r pixel sugarú kört rajzolni"
PythonTurtleFunction = "turtle modul funkció elötag" PythonTurtleColor = "Toll szinét beállitani"
PythonTurtleGoto = "Menjen a (x,y) koordinátákra" PythonTurtleColorMode = "Szin módot 1.0-ra vagy 255-ra állitani"
PythonTurtleHeading = "Visszaadja az aktuális irányt" PythonTurtleForward = "x pixelt elölre"
PythonTurtleHideturtle = "A teknös elrejtése" PythonTurtleFunction = "turtle modul funkció elötag"
PythonTurtleIsdown = "True-t válaszol ha a toll irás pozícióban van" PythonTurtleGoto = "Menjen a (x,y) koordinátákra"
PythonTurtleLeft = "a fokkot forduljon balra" PythonTurtleHeading = "Visszaadja az aktuális irányt"
PythonTurtlePendown = "Húzza le a tollat" PythonTurtleHideturtle = "A teknös elrejtése"
PythonTurtlePensize = "Állítsa a vonalvastagságot x pixelre" PythonTurtleIsdown = "True-t válaszol ha a toll irás pozícióban van"
PythonTurtlePenup = "Húzza fel a tollat" PythonTurtleLeft = "a fokkot forduljon balra"
PythonTurtlePosition = "Az aktuális (x,y) pozíciót visszaadása" PythonTurtlePendown = "Húzza le a tollat"
PythonTurtleReset = "Visszaállitani a rajzot (torléssel)" PythonTurtlePensize = "Állítsa a vonalvastagságot x pixelre"
PythonTurtleRight = "a fokkot forduljon jobbra" PythonTurtlePenup = "Húzza fel a tollat"
PythonTurtleSetheading = "a fokokra állítja be az irányt" PythonTurtlePosition = "Az aktuális (x,y) pozíciót visszaadása"
PythonTurtleSetposition = "A teknös pozicioját allitja" PythonTurtleReset = "Visszaállitani a rajzot (torléssel)"
PythonTurtleShowturtle = "A teknöst meg mutatni" PythonTurtleRight = "a fokkot forduljon jobbra"
PythonTurtleSpeed = "Rajzolási sebesség 0 és 10 között" PythonTurtleSetheading = "a fokokra állítja be az irányt"
PythonTurtleWrite = "Szöveg irás" PythonTurtleShowturtle = "A teknöst meg mutatni"
PythonUniform = "Lebegöpontos szám [a,b] -ban" PythonTurtleSpeed = "Rajzolási sebesség 0 és 10 között"
PythonImportTime = "time modul importálása" PythonTurtleWrite = "Szöveg irás"
PythonTimePrefix = "time funkció elötag" PythonUniform = "Lebegöpontos szám [a,b] -ban"
PythonTimeSleep = "n másodpercet várni" PythonImportTime = "time modul importálása"
PythonMonotonic = "Meg fordítani a monoton idö" PythonMonotonic = "Meg fordítani a monoton idö"
PythonFileOpen = "Fájl megnyitása" PythonFileOpen = "Fájl megnyitása"
PythonFileSeekable = "Seek-et lehete használni" PythonFileSeekable = "Seek-et lehete használni"
PythonFileSeek = "A kurzort áthelyezni" PythonFileSeek = "A kurzort áthelyezni"
PythonFileTell = "Visszaadja a kurzor helye" PythonFileTell = "Visszaadja a kurzor helye"
PythonFileClose = "Bezárni egy fájlt" PythonFileClose = "Bezárni egy fájlt"
PythonFileClosed = "True ha a fájl bezárva" PythonFileClosed = "True ha a fájl bezárva"
PythonFileRead = "Olvas 16 bájtig" PythonFileRead = "Olvas 16 bájtig"
PythonFileWrite = "b-t irjon a fájlba" PythonFileWrite = "b-t irjon a fájlba"
PythonFileReadline = "Olvas egy sort vagy 16 bájtig" PythonFileReadline = "Olvas egy sort vagy 16 bájtig"
PythonFileReadlines = "Olvas több sort" PythonFileReadlines = "Olvas több sort"
PythonFileTruncate = "A fájl átméretezése" PythonFileTruncate = "A fájl átméretezése"
PythonFileWritelines = "Irjon több sort" PythonFileWritelines = "Irjon több sort"
PythonFileName = "A fájl neve" PythonFileName = "A fájl neve"
PythonFileMode = "A fájl nyitott módja" PythonFileMode = "A fájl nyitott módja"
PythonFileReadable = "read-et lehete használni" PythonFileReadable = "read-et lehete használni"
PythonFileWritable = "write-ot lehete használni" PythonFileWritable = "write-ot lehete használni"
PythonImportOs = "os modul importálása" PythonImportOs = "os modul importálása"
PythonOsUname = "Rendszer informaciók" PythonOsUname = "Rendszer informaciók"
PythonOsGetlogin = "Get username" PythonOsGetlogin = "Get username"
PythonOsRemove = "Fájl törlése" PythonOsRemove = "Fájl törlése"
PythonOsRename = "Fájl átnevezése" PythonOsRename = "Fájl átnevezése"
PythonOsListdir = "Fájlok listája" PythonOsListdir = "Fájlok listája"
PythonImportSys = "sys modul importálása" PythonImportSys = "sys modul importálása"
PythonSysExit = "Terminate current program" PythonSysExit = "Terminate current program"
PythonSysPrintexception = "Print exception" PythonSysPrintexception = "Print exception"
PythonSysByteorder = "The byte order of the system" PythonSysByteorder = "The byte order of the system"
PythonSysImplementation = "Information about Python" PythonSysImplementation = "Information about Python"
PythonSysModules = "Dictionary of loaded modules" PythonSysModules = "Dictionary of loaded modules"
PythonSysVersion = "Python language version (string)" PythonSysVersion = "Python language version (string)"
PythonSysVersioninfo = "Python language version (tuple)" PythonSysVersioninfo = "Python language version (tuple)"
PythonKeyLeft = "BALRA NYÍL billentyű"
PythonKeyUp = "FEL NYÍL billentyű"
PythonKeyDown = "LE NYÍL billentyű"
PythonKeyRight = "JOBBRA NYÍL billentyű"
PythonKeyOk = "OK gomb"
PythonKeyBack = "VISSZA gomb"
PythonKeyHome = "Lakáskulcs"
PythonKeyOnOff = "BE/KI gomb"
PythonKeyShift = "SHIFT billentyű"
PythonKeyAlpha = "ALPHA kulcs"
PythonKeyXnt = "X,N,T gomb"
PythonKeyVar = "VAR gomb"
PythonKeyToolbox = "TOOLBOX gomb"
PythonKeyBackspace = "BACKSPACE billentyű"
PythonKeyExp = "EXPONENTIÁLIS kulcs"
PythonKeyLn = "TERMÉSZETES LOGARITMUS kulcs"
PythonKeyLog = "DECIMÁLIS LOGARITMUS billentyű"
PythonKeyImaginary = "KÉPZELETES I kulcs"
PythonKeyComma = "VESZSŰ gomb"
PythonKeyPower = "POWER gomb"
PythonKeySine = "SINE gomb"
PythonKeyCosine = "KOSINUS kulcs"
PythonKeyTangent = "ÉRINTŐ gomb"
PythonKeyPi = "PI kulcs"
PythonKeySqrt = "NÉGYGYÖK kulcs"
PythonKeySquare = "SZÖGZET billentyű"
PythonKeySeven = "7 kulcs"
PythonKeyEight = "8 kulcs"
PythonKeyNine = "9 kulcs"
PythonKeyLeftParenthesis = "BAL ZÁRÓZELŐ gomb"
PythonKeyRightParenthesis = "JOBB ZÁRÓZELŐ billentyű"
PythonKeyFour = "4 kulcs"
PythonKeyFive = "5 kulcs"
PythonKeySix = "6 kulcs"
PythonKeyMultiplication = "SZORZAT gomb"
PythonKeyDivision = "OSZTÁS kulcs"
PythonKeyOne = "1 kulcs"
PythonKeyTwo = "2 kulcs"
PythonKeyThree = "3 kulcs"
PythonKeyPlus = "PLUSZ kulcs"
PythonKeyMinus = "MÍNUS gomb"
PythonKeyZero = "0 kulcs"
PythonKeyDot = "DOT gomb"
PythonKeyEe = "10 POWER X gomb"
PythonKeyAns = "ANS kulcs"
PythonKeyExe = "EXE kulcs"

View File

@@ -53,6 +53,7 @@ PythonErfc = "Funzione d'errore complementare"
PythonEval = "Valuta l'espressione nell'argomento " PythonEval = "Valuta l'espressione nell'argomento "
PythonExp = "Funzione esponenziale" PythonExp = "Funzione esponenziale"
PythonExpm1 = "Calcola exp(x)-1" PythonExpm1 = "Calcola exp(x)-1"
PythonFactorial = "Fattoriale di x"
PythonFabs = "Valore assoluto" PythonFabs = "Valore assoluto"
PythonFillCircle = "Riempire un cerchio" PythonFillCircle = "Riempire un cerchio"
PythonFillPolygon = "Riempire un poligono" PythonFillPolygon = "Riempire un poligono"
@@ -101,11 +102,59 @@ PythonIonFunction = "Prefisso di funzione modulo ion"
PythonIsFinite = "Testa se x è finito" PythonIsFinite = "Testa se x è finito"
PythonIsInfinite = "Testa se x est infinito" PythonIsInfinite = "Testa se x est infinito"
PythonIsKeyDown = "Restituisce True premendo tasto k" PythonIsKeyDown = "Restituisce True premendo tasto k"
PythonBattery = "Return battery voltage" PythonBattery = "Restituisce la tensione della batteria"
PythonBatteryLevel = "Return battery level" PythonBatteryLevel = "Restituisce il livello della batteria"
PythonBatteryIscharging = "Return if battery is charging" PythonBatteryIscharging = "Restituisce se la batteria è in carica"
PythonSetBrightness = "Imposta livello di luminosità"
PythonGetBrightness = "Ottieni livello di luminosità"
PythonIsNaN = "Testa se x è NaN" PythonIsNaN = "Testa se x è NaN"
PythonKandinskyFunction = "Prefisso funzione modulo kandinsky" 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)" PythonLdexp = "Inversa di frexp : x*(2**i)"
PythonLength = "Longhezza di un oggetto" PythonLength = "Longhezza di un oggetto"
PythonLgamma = "Logaritmo della funzione gamma" PythonLgamma = "Logaritmo della funzione gamma"
@@ -141,7 +190,7 @@ PythonRandrange = "Numero dentro il range(start, stop)"
PythonRangeStartStop = "Lista da start a stop-1" PythonRangeStartStop = "Lista da start a stop-1"
PythonRangeStop = "Lista da 0 a stop-1" PythonRangeStop = "Lista da 0 a stop-1"
PythonRect = "Converte in coordinate algebriche" PythonRect = "Converte in coordinate algebriche"
PythonRemove = "Cancella la prima x dalla lista" PythonRemove = "Cancella la prima x dalla lista"
PythonReverse = "Inverte gli elementi della lista" PythonReverse = "Inverte gli elementi della lista"
PythonRound = "Arrotondato a n cifre decimali" PythonRound = "Arrotondato a n cifre decimali"
PythonScatter = "Diagramma dispersione y in f. di x" PythonScatter = "Diagramma dispersione y in f. di x"
@@ -183,14 +232,11 @@ PythonTurtlePosition = "Fornisce posizione corrente (x,y)"
PythonTurtleReset = "Azzera il disegno" PythonTurtleReset = "Azzera il disegno"
PythonTurtleRight = "Ruota di a gradi a destra" PythonTurtleRight = "Ruota di a gradi a destra"
PythonTurtleSetheading = "Imposta l'orientamento per a gradi" PythonTurtleSetheading = "Imposta l'orientamento per a gradi"
PythonTurtleSetposition = "Posiziona la tartaruga"
PythonTurtleShowturtle = "Mostra la tartaruga" PythonTurtleShowturtle = "Mostra la tartaruga"
PythonTurtleSpeed = "Velocità di disegno (x tra 0 e 10)" PythonTurtleSpeed = "Velocità di disegno (x tra 0 e 10)"
PythonTurtleWrite = "Mostra un testo" PythonTurtleWrite = "Mostra un testo"
PythonUniform = "Numero decimale tra [a,b]" PythonUniform = "Numero decimale tra [a,b]"
PythonImportTime = "Import time module" PythonImportTime = "Import time module"
PythonTimePrefix = "time module function prefix"
PythonTimeSleep = "Wait for n second"
PythonMonotonic = "Return monotonic time" PythonMonotonic = "Return monotonic time"
PythonFileOpen = "Opens a file" PythonFileOpen = "Opens a file"
PythonFileSeekable = "Tells if seek can be used on a file" PythonFileSeekable = "Tells if seek can be used on a file"

View File

@@ -53,6 +53,7 @@ PythonErfc = "Complementaire error functie"
PythonEval = "Geef de geëvalueerde uitdrukking" PythonEval = "Geef de geëvalueerde uitdrukking"
PythonExp = "Exponentiële functie" PythonExp = "Exponentiële functie"
PythonExpm1 = "Bereken exp(x)-1" PythonExpm1 = "Bereken exp(x)-1"
PythonFactorial = "faculteit van x"
PythonFabs = "Absolute waarde" PythonFabs = "Absolute waarde"
PythonFillCircle = "Vul een cirkel" PythonFillCircle = "Vul een cirkel"
PythonFillPolygon = "Vul een veelhoek" PythonFillPolygon = "Vul een veelhoek"
@@ -102,11 +103,59 @@ PythonIonFunction = "ion module voorvoegsel"
PythonIsFinite = "Controleer of x eindig is" PythonIsFinite = "Controleer of x eindig is"
PythonIsInfinite = "Controleer of x oneindig is" PythonIsInfinite = "Controleer of x oneindig is"
PythonIsKeyDown = "Geef True als k toets omlaag is" PythonIsKeyDown = "Geef True als k toets omlaag is"
PythonBattery = "Return battery voltage" PythonBattery = "Return batterijspanning"
PythonBatteryLevel = "Return battery level" PythonBatteryLevel = "Batterijniveau teruggeven"
PythonBatteryIscharging = "Return if battery is charging" PythonBatteryIscharging = "Keer terug als de batterij wordt opgeladen"
PythonSetBrightness = "Set brightness level"
PythonGetBrightness = "Get brightness level"
PythonIsNaN = "Controleer of x geen getal is" PythonIsNaN = "Controleer of x geen getal is"
PythonKandinskyFunction = "kandinsky module voorvoegsel" 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" PythonLdexp = "Geeft x*(2**i), inversie van frexp"
PythonLength = "Lengte van een object" PythonLength = "Lengte van een object"
PythonLgamma = "Log-gammafunctie" PythonLgamma = "Log-gammafunctie"
@@ -149,7 +198,7 @@ PythonScatter = "Teken scatterplot van y versus x"
PythonSeed = "Start willek. getallengenerator" PythonSeed = "Start willek. getallengenerator"
PythonSetPixel = "Kleur pixel (x,y)" PythonSetPixel = "Kleur pixel (x,y)"
PythonShow = "Figuur weergeven" PythonShow = "Figuur weergeven"
PythonSin= "Sinus" PythonSin = "Sinus"
PythonSinh = "Sinus hyperbolicus" PythonSinh = "Sinus hyperbolicus"
PythonSleep = "Stel executie voor t seconden uit" PythonSleep = "Stel executie voor t seconden uit"
PythonLocalTime = "Zet tijd om in tuple" PythonLocalTime = "Zet tijd om in tuple"
@@ -184,14 +233,11 @@ PythonTurtlePosition = "Zet huidige (x,y) locatie terug"
PythonTurtleReset = "Reset de tekening" PythonTurtleReset = "Reset de tekening"
PythonTurtleRight = "Ga rechtsaf met a graden" PythonTurtleRight = "Ga rechtsaf met a graden"
PythonTurtleSetheading = "Zet de oriëntatie op a graden" PythonTurtleSetheading = "Zet de oriëntatie op a graden"
PythonTurtleSetposition = "Plaats de schildpad"
PythonTurtleShowturtle = "Laat de schildpad zien" PythonTurtleShowturtle = "Laat de schildpad zien"
PythonTurtleSpeed = "Tekensnelheid tussen 0 and 10" PythonTurtleSpeed = "Tekensnelheid tussen 0 and 10"
PythonTurtleWrite = "Display a text" PythonTurtleWrite = "Display a text"
PythonUniform = "Decimaal getal in [a,b]" PythonUniform = "Decimaal getal in [a,b]"
PythonImportTime = "Import time module" PythonImportTime = "Import time module"
PythonTimePrefix = "time module function prefix"
PythonTimeSleep = "Wait for n second"
PythonMonotonic = "Return monotonic time" PythonMonotonic = "Return monotonic time"
PythonFileOpen = "Opens a file" PythonFileOpen = "Opens a file"
PythonFileSeekable = "Tells if seek can be used on a file" PythonFileSeekable = "Tells if seek can be used on a file"

View File

@@ -53,6 +53,7 @@ PythonErfc = "Função erro complementar"
PythonEval = "Devolve a expressão avaliada" PythonEval = "Devolve a expressão avaliada"
PythonExp = "Função exponencial" PythonExp = "Função exponencial"
PythonExpm1 = "Calcular exp(x)-1" PythonExpm1 = "Calcular exp(x)-1"
PythonFactorial = "Fatorial de x"
PythonFabs = "Valor absoluto" PythonFabs = "Valor absoluto"
PythonFillCircle = "Preencher um círculo" PythonFillCircle = "Preencher um círculo"
PythonFillPolygon = "Preencher um polígono" PythonFillPolygon = "Preencher um polígono"
@@ -87,11 +88,59 @@ PythonIonFunction = "Prefixo da função do módulo ion"
PythonIsFinite = "Verificar se x é finito" PythonIsFinite = "Verificar se x é finito"
PythonIsInfinite = "Verificar se x é infinito" PythonIsInfinite = "Verificar se x é infinito"
PythonIsKeyDown = "Devolve True se tecla k pressionada" PythonIsKeyDown = "Devolve True se tecla k pressionada"
PythonBattery = "Return battery voltage" PythonBattery = "Retornar a voltagem da bateria"
PythonBatteryLevel = "Return battery level" PythonBatteryLevel = "Retornar nível de bateria"
PythonBatteryIscharging = "Return if battery is charging" PythonBatteryIscharging = "Retorne se a bateria estiver carregando"
PythonSetBrightness = "Definir nível de brilho"
PythonGetBrightness = "Obter nível de brilho"
PythonIsNaN = "Verificar se x é um NaN" PythonIsNaN = "Verificar se x é um NaN"
PythonKandinskyFunction = "Prefixo da função do módulo kandinsky" 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" PythonLdexp = "Devolve x*(2**i), inverso de frexp"
PythonLength = "Comprimento de um objeto" PythonLength = "Comprimento de um objeto"
PythonLgamma = "Logaritmo da função gama" PythonLgamma = "Logaritmo da função gama"
@@ -169,7 +218,6 @@ PythonTurtlePosition = "Devolve a posição atual (x,y)"
PythonTurtleReset = "Reiniciar o desenho" PythonTurtleReset = "Reiniciar o desenho"
PythonTurtleRight = "Virar à esquerda por a graus" PythonTurtleRight = "Virar à esquerda por a graus"
PythonTurtleSetheading = "Definir a orientação por a graus" PythonTurtleSetheading = "Definir a orientação por a graus"
PythonTurtleSetposition = "Positionne la tortue"
PythonTurtleShowturtle = "Mostrar o turtle" PythonTurtleShowturtle = "Mostrar o turtle"
PythonTurtleSpeed = "Velocidade do desenho entre 0 e 10" PythonTurtleSpeed = "Velocidade do desenho entre 0 e 10"
PythonTurtleWrite = "Mostrar um texto" PythonTurtleWrite = "Mostrar um texto"
@@ -189,8 +237,6 @@ PythonSysImplementation = "Information about Python"
PythonSysModules = "Dictionary of loaded modules" PythonSysModules = "Dictionary of loaded modules"
PythonSysVersion = "Python language version (string)" PythonSysVersion = "Python language version (string)"
PythonSysVersioninfo = "Python language version (tuple)" PythonSysVersioninfo = "Python language version (tuple)"
PythonTimePrefix = "time module function prefix"
PythonTimeSleep = "Wait for n second"
PythonMonotonic = "Return monotonic time" PythonMonotonic = "Return monotonic time"
PythonFileOpen = "Opens a file" PythonFileOpen = "Opens a file"
PythonFileSeekable = "Tells if seek can be used on a file" PythonFileSeekable = "Tells if seek can be used on a file"

View File

@@ -60,6 +60,7 @@ PythonCommandEval = "eval(\"expression\")"
PythonCommandExp = "exp(x)" PythonCommandExp = "exp(x)"
PythonCommandExpComplex = "exp(z)" PythonCommandExpComplex = "exp(z)"
PythonCommandExpm1 = "expm1(x)" PythonCommandExpm1 = "expm1(x)"
PythonCommandFactorial = "factorial(x)"
PythonCommandFabs = "fabs(x)" PythonCommandFabs = "fabs(x)"
PythonCommandFillCircle = "fill_circle(x,y,r,color)" PythonCommandFillCircle = "fill_circle(x,y,r,color)"
PythonCommandFillPolygon = "fill_polygon([(x1,y1),...],color)" PythonCommandFillPolygon = "fill_polygon([(x1,y1),...],color)"
@@ -163,6 +164,8 @@ PythonCommandIsKeyDown = "keydown(k)"
PythonCommandBattery = "battery()" PythonCommandBattery = "battery()"
PythonCommandBatteryLevel = "battery_level()" PythonCommandBatteryLevel = "battery_level()"
PythonCommandBatteryIscharging = "battery_ischarging()" PythonCommandBatteryIscharging = "battery_ischarging()"
PythonCommandSetBrightness = "set_brightness()"
PythonCommandGetBrightness = "get_brightness()"
PythonCommandLdexp = "ldexp(x,i)" PythonCommandLdexp = "ldexp(x,i)"
PythonCommandLength = "len(object)" PythonCommandLength = "len(object)"
PythonCommandLgamma = "lgamma(x)" PythonCommandLgamma = "lgamma(x)"
@@ -400,16 +403,8 @@ PythonTurtleCommandPosition = "position()"
PythonTurtleCommandReset = "reset()" PythonTurtleCommandReset = "reset()"
PythonTurtleCommandRight = "right(a)" PythonTurtleCommandRight = "right(a)"
PythonTurtleCommandSetheading = "setheading(a)" PythonTurtleCommandSetheading = "setheading(a)"
PythonTurtleCommandSetposition = "setposition(x,[y])"
PythonTurtleCommandShowturtle = "showturtle()" PythonTurtleCommandShowturtle = "showturtle()"
PythonTurtleCommandSpeed = "speed(x)" PythonTurtleCommandSpeed = "speed(x)"
PythonTurtleCommandWhite = "'white'"
PythonTurtleCommandYellow = "'yellow'"
PythonTimeModule = "time"
PythonTimeCommandImportFrom = "from time import *"
PythonTimeCommandSleep = "sleep()"
PythonTimeCommandSleepDemo = "sleep(n)"
PythonTimeCommandMonotonic = "monotonic()"
PythonCommandFileOpen = "open(name, [mode])" PythonCommandFileOpen = "open(name, [mode])"
PythonCommandFileOpenWithoutArg = "open(\x11)" PythonCommandFileOpenWithoutArg = "open(\x11)"
PythonCommandFileSeek = "file.seek(offset, [whence])" PythonCommandFileSeek = "file.seek(offset, [whence])"

View File

@@ -4,6 +4,7 @@
#include "app.h" #include "app.h"
#include <escher/metric.h> #include <escher/metric.h>
#include <ion.h> #include <ion.h>
#include "../global_preferences.h"
using namespace Shared; using namespace Shared;
@@ -63,10 +64,20 @@ void EditorController::didBecomeFirstResponder() {
void EditorController::viewWillAppear() { void EditorController::viewWillAppear() {
ViewController::viewWillAppear(); ViewController::viewWillAppear();
m_editorView.loadSyntaxHighlighter(); m_editorView.loadSyntaxHighlighter();
m_editorView.setCursorLocation(m_editorView.text() + strlen(m_editorView.text())); if(GlobalPreferences::sharedGlobalPreferences()->cursorSaving()) {
int offset = m_script.cursorOffset();
if (offset != -1) {
m_editorView.setCursorLocation(m_editorView.text() + offset);
} else {
m_editorView.setCursorLocation(m_editorView.text() + strlen(m_editorView.text()));
}
} else {
m_editorView.setCursorLocation(m_editorView.text() + strlen(m_editorView.text()));
}
} }
void EditorController::viewDidDisappear() { void EditorController::viewDidDisappear() {
m_script.setCursorOffset(m_editorView.cursorLocation() - m_script.content());
m_editorView.resetSelection(); m_editorView.resetSelection();
m_menuController->scriptContentEditionDidFinish(); m_menuController->scriptContentEditionDidFinish();
} }

View File

@@ -26,7 +26,9 @@ void EditorView::resetSelection() {
} }
void EditorView::scrollViewDidChangeOffset(ScrollViewDataSource * scrollViewDataSource) { void EditorView::scrollViewDidChangeOffset(ScrollViewDataSource * scrollViewDataSource) {
m_gutterView.setOffset(scrollViewDataSource->offset().y()); if (m_gutterView.setOffsetAndNeedResize(scrollViewDataSource->offset().y())) {
internalLayoutSubviews(true);
}
} }
View * EditorView::subviewAtIndex(int index) { View * EditorView::subviewAtIndex(int index) {
@@ -42,8 +44,12 @@ void EditorView::didBecomeFirstResponder() {
} }
void EditorView::layoutSubviews(bool force) { void EditorView::layoutSubviews(bool force) {
m_gutterView.setOffset(0); m_gutterView.setOffsetAndNeedResize(0); // Whatever the return is, we layout the editor view
KDCoordinate gutterWidth = m_gutterView.minimalSizeForOptimalDisplay().width(); internalLayoutSubviews(force);
}
void EditorView::internalLayoutSubviews(bool force) {
KDCoordinate gutterWidth = m_gutterView.computeWidth();
m_gutterView.setFrame(KDRect(0, 0, gutterWidth, bounds().height()), force); m_gutterView.setFrame(KDRect(0, 0, gutterWidth, bounds().height()), force);
m_textArea.setFrame(KDRect( m_textArea.setFrame(KDRect(
@@ -67,23 +73,23 @@ void EditorView::GutterView::drawRect(KDContext * ctx, KDRect rect) const {
KDCoordinate firstLine = m_offset / glyphSize.height(); KDCoordinate firstLine = m_offset / glyphSize.height();
KDCoordinate firstLinePixelOffset = m_offset - firstLine * glyphSize.height(); KDCoordinate firstLinePixelOffset = m_offset - firstLine * glyphSize.height();
char lineNumber[k_lineNumberCharLength]; char lineNumberBuffer[m_numberOfDigits + 1];
int numberOfLines = bounds().height() / glyphSize.height() + 1; int numberOfLines = bounds().height() / glyphSize.height() + 1;
for (int i=0; i<numberOfLines; i++) { for (int i=0; i<numberOfLines; i++) {
// Only the first two digits are displayed int lineNumberValue = (i + firstLine + 1);
int lineNumberValue = (i + firstLine + 1) % 100;
Poincare::Integer line(lineNumberValue); Poincare::Integer line(lineNumberValue);
if (firstLine < 10 || lineNumberValue >= 10) {
line.serialize(lineNumber, k_lineNumberCharLength); int lineDigits = computeNumberOfDigitsFor(lineNumberValue);
} else {
// Add a leading "0" for (int j=0; j < m_numberOfDigits - lineDigits; j++) {
lineNumber[0] = '0'; lineNumberBuffer[j] = ' ';
line.serialize(lineNumber + 1, k_lineNumberCharLength - 1);
} }
KDCoordinate leftPadding = (2 - strlen(lineNumber)) * glyphSize.width();
line.serialize(lineNumberBuffer + (m_numberOfDigits - lineDigits), m_numberOfDigits + 1);
ctx->drawString( ctx->drawString(
lineNumber, lineNumberBuffer,
KDPoint(k_margin + leftPadding, i*glyphSize.height() - firstLinePixelOffset), KDPoint(k_margin, i*glyphSize.height() - firstLinePixelOffset),
m_font, m_font,
textColor, textColor,
backgroundColor backgroundColor
@@ -91,18 +97,36 @@ void EditorView::GutterView::drawRect(KDContext * ctx, KDRect rect) const {
} }
} }
void EditorView::GutterView::setOffset(KDCoordinate offset) { bool EditorView::GutterView::setOffsetAndNeedResize(KDCoordinate offset) {
if (m_offset == offset) { if (m_offset == offset) {
return; return false;
} }
m_offset = offset; m_offset = offset;
int numberOfDigits = computeMaxNumberOfDigits();
if (numberOfDigits != m_numberOfDigits) {
m_numberOfDigits = numberOfDigits;
return true;
}
markRectAsDirty(bounds()); markRectAsDirty(bounds());
return false;
} }
int EditorView::GutterView::computeWidth() {
return 2 * k_margin + (m_numberOfDigits) * m_font->glyphSize().width();
}
KDSize EditorView::GutterView::minimalSizeForOptimalDisplay() const { int EditorView::GutterView::computeMaxNumberOfDigits() {
int numberOfChars = 2; // TODO: Could be computed return computeNumberOfDigitsFor((bounds().height() / m_font->glyphSize().height() + 1) + (m_offset / m_font->glyphSize().height()));
return KDSize(2 * k_margin + numberOfChars * m_font->glyphSize().width(), 0); }
int EditorView::GutterView::computeNumberOfDigitsFor(int value) {
int digits = 1;
while (value >= pow(10, digits)) {
digits++;
}
return digits;
} }
} }

View File

@@ -29,6 +29,7 @@ public:
void unloadSyntaxHighlighter() { m_textArea.unloadSyntaxHighlighter(); }; void unloadSyntaxHighlighter() { m_textArea.unloadSyntaxHighlighter(); };
void scrollViewDidChangeOffset(ScrollViewDataSource * scrollViewDataSource) override; void scrollViewDidChangeOffset(ScrollViewDataSource * scrollViewDataSource) override;
void didBecomeFirstResponder() override; void didBecomeFirstResponder() override;
void internalLayoutSubviews(bool force);
private: private:
int numberOfSubviews() const override { return 2; } int numberOfSubviews() const override { return 2; }
View * subviewAtIndex(int index) override; View * subviewAtIndex(int index) override;
@@ -36,15 +37,21 @@ private:
class GutterView : public View { class GutterView : public View {
public: public:
GutterView(const KDFont * font) : View(), m_font(font), m_offset(0) {} GutterView(const KDFont * font) : View(), m_font(font), m_offset(0), m_numberOfDigits(2) {}
void drawRect(KDContext * ctx, KDRect rect) const override; void drawRect(KDContext * ctx, KDRect rect) const override;
void setOffset(KDCoordinate offset); bool setOffsetAndNeedResize(KDCoordinate offset); // Return true if the gutter view need to be resized
KDSize minimalSizeForOptimalDisplay() const override;
int computeWidth();
int computeMaxNumberOfDigits();
static int computeNumberOfDigitsFor(int value);
private: private:
static constexpr KDCoordinate k_margin = 2; static constexpr KDCoordinate k_margin = 2;
static constexpr int k_lineNumberCharLength = 3;
const KDFont * m_font; const KDFont * m_font;
KDCoordinate m_offset; KDCoordinate m_offset;
int m_numberOfDigits;
}; };
PythonTextArea m_textArea; PythonTextArea m_textArea;

View File

@@ -90,6 +90,11 @@ bool MenuController::handleEvent(Ion::Events::Event event) {
footer()->setSelectedButton(0); footer()->setSelectedButton(0);
return true; return true;
} }
if (event == Ion::Events::ShiftBack) {
Ion::Storage::sharedStorage()->reinsertTrash("py");
m_selectableTableView.reloadData();
return true;
}
if (event == Ion::Events::Up) { if (event == Ion::Events::Up) {
if (footer()->selectedButton() == 0) { if (footer()->selectedButton() == 0) {
footer()->setSelectedButton(-1); footer()->setSelectedButton(-1);

View File

@@ -25,6 +25,9 @@ constexpr KDColor HighlightColor = Palette::CodeBackgroundSelected;
constexpr KDColor AutocompleteColor = KDColor::RGB24(0xC6C6C6); // TODO Palette change constexpr KDColor AutocompleteColor = KDColor::RGB24(0xC6C6C6); // TODO Palette change
static inline KDColor TokenColor(mp_token_kind_t tokenKind) { static inline KDColor TokenColor(mp_token_kind_t tokenKind) {
if (!GlobalPreferences::sharedGlobalPreferences()->syntaxhighlighting()) {
return Palette::CodeText;
}
if (tokenKind == MP_TOKEN_STRING) { if (tokenKind == MP_TOKEN_STRING) {
return StringColor; return StringColor;
} }
@@ -66,7 +69,8 @@ static inline KDColor TokenColor(mp_token_kind_t tokenKind) {
&& MP_TOKEN_KW_TRY + 1 == MP_TOKEN_KW_WHILE && MP_TOKEN_KW_TRY + 1 == MP_TOKEN_KW_WHILE
&& MP_TOKEN_KW_WHILE + 1 == MP_TOKEN_KW_WITH && MP_TOKEN_KW_WHILE + 1 == MP_TOKEN_KW_WITH
&& MP_TOKEN_KW_WITH + 1 == MP_TOKEN_KW_YIELD && MP_TOKEN_KW_WITH + 1 == MP_TOKEN_KW_YIELD
&& MP_TOKEN_KW_YIELD + 1 == MP_TOKEN_OP_TILDE, && MP_TOKEN_KW_YIELD + 1 == MP_TOKEN_OP_ASSIGN
&& MP_TOKEN_OP_ASSIGN + 1 == MP_TOKEN_OP_TILDE,
"MP_TOKEN order changed, so Code::PythonTextArea::TokenColor might need to change too."); "MP_TOKEN order changed, so Code::PythonTextArea::TokenColor might need to change too.");
if (tokenKind >= MP_TOKEN_KW_FALSE && tokenKind <= MP_TOKEN_KW_YIELD) { if (tokenKind >= MP_TOKEN_KW_FALSE && tokenKind <= MP_TOKEN_KW_YIELD) {
return KeywordColor; return KeywordColor;
@@ -119,7 +123,8 @@ static inline KDColor TokenColor(mp_token_kind_t tokenKind) {
if ((tokenKind >= MP_TOKEN_OP_TILDE && tokenKind <= MP_TOKEN_DEL_DBL_STAR_EQUAL) if ((tokenKind >= MP_TOKEN_OP_TILDE && tokenKind <= MP_TOKEN_DEL_DBL_STAR_EQUAL)
|| tokenKind == MP_TOKEN_DEL_EQUAL || tokenKind == MP_TOKEN_DEL_EQUAL
|| tokenKind == MP_TOKEN_DEL_MINUS_MORE) || tokenKind == MP_TOKEN_DEL_MINUS_MORE
|| tokenKind == MP_TOKEN_OP_ASSIGN)
{ {
return OperatorColor; return OperatorColor;
} }
@@ -157,7 +162,7 @@ PythonTextArea::AutocompletionType PythonTextArea::autocompletionType(const char
const char * tokenEnd; const char * tokenEnd;
_mp_token_kind_t currentTokenKind = lex->tok_kind; _mp_token_kind_t currentTokenKind = lex->tok_kind;
while (currentTokenKind != MP_TOKEN_NEWLINE && currentTokenKind != MP_TOKEN_END) { while (currentTokenKind != MP_TOKEN_NEWLINE && currentTokenKind != MP_TOKEN_END && currentTokenKind != MP_TOKEN_FSTRING_RAW) {
tokenStart = firstNonSpace + lex->tok_column - 1; tokenStart = firstNonSpace + lex->tok_column - 1;
tokenEnd = tokenStart + TokenLength(lex, tokenStart); tokenEnd = tokenStart + TokenLength(lex, tokenStart);
@@ -266,7 +271,7 @@ void PythonTextArea::ContentView::drawLine(KDContext * ctx, int line, const char
const char * tokenFrom = firstNonSpace; const char * tokenFrom = firstNonSpace;
size_t tokenLength = 0; size_t tokenLength = 0;
const char * tokenEnd = firstNonSpace; const char * tokenEnd = firstNonSpace;
while (lex->tok_kind != MP_TOKEN_NEWLINE && lex->tok_kind != MP_TOKEN_END) { while (lex->tok_kind != MP_TOKEN_NEWLINE && lex->tok_kind != MP_TOKEN_END && lex->tok_kind != MP_TOKEN_FSTRING_RAW) {
tokenFrom = firstNonSpace + lex->tok_column - 1; tokenFrom = firstNonSpace + lex->tok_column - 1;
if (tokenFrom != tokenEnd) { if (tokenFrom != tokenEnd) {
// We passed over white spaces, we need to color them // We passed over white spaces, we need to color them
@@ -305,6 +310,10 @@ void PythonTextArea::ContentView::drawLine(KDContext * ctx, int line, const char
tokenFrom += tokenLength; tokenFrom += tokenLength;
KDColor color = CommentColor;
if (!GlobalPreferences::sharedGlobalPreferences()->syntaxhighlighting()) {
color = Palette::CodeText;
}
// Even if the token is being autocompleted, use CommentColor // Even if the token is being autocompleted, use CommentColor
if (tokenFrom < text + byteLength) { if (tokenFrom < text + byteLength) {
LOG_DRAW("Draw comment \"%.*s\" from %d\n", byteLength - (tokenFrom - text), firstNonSpace, tokenFrom); LOG_DRAW("Draw comment \"%.*s\" from %d\n", byteLength - (tokenFrom - text), firstNonSpace, tokenFrom);
@@ -312,7 +321,7 @@ void PythonTextArea::ContentView::drawLine(KDContext * ctx, int line, const char
UTF8Helper::GlyphOffsetAtCodePoint(text, tokenFrom), UTF8Helper::GlyphOffsetAtCodePoint(text, tokenFrom),
tokenFrom, tokenFrom,
text + byteLength - tokenFrom, text + byteLength - tokenFrom,
CommentColor, color,
BackgroundColor, BackgroundColor,
selectionStart, selectionStart,
selectionEnd, selectionEnd,

View File

@@ -30,7 +30,7 @@ public:
* - MiddleOfIdentifier is the cursor is in the middle of an identifier, * - MiddleOfIdentifier is the cursor is in the middle of an identifier,
* - No identifier otherwise. * - No identifier otherwise.
* The autocompletionLocation can be provided with autocompletionLocation, or * The autocompletionLocation can be provided with autocompletionLocation, or
* retreived with autocompletionLocationBeginning and autocompletionLocationEnd. */ * retrieved with autocompletionLocationBeginning and autocompletionLocationEnd. */
AutocompletionType autocompletionType(const char * autocompletionLocation = nullptr, const char ** autocompletionLocationBeginning = nullptr, const char ** autocompletionLocationEnd = nullptr) const; AutocompletionType autocompletionType(const char * autocompletionLocation = nullptr, const char ** autocompletionLocationBeginning = nullptr, const char ** autocompletionLocationEnd = nullptr) const;
bool isAutocompleting() const { return m_contentView.isAutocompleting(); } bool isAutocompleting() const { return m_contentView.isAutocompleting(); }
protected: protected:

View File

@@ -75,6 +75,7 @@ const ToolboxMessageTree MathModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandAtan2, I18n::Message::PythonAtan2), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandAtan2, I18n::Message::PythonAtan2),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCeil, I18n::Message::PythonCeil), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCeil, I18n::Message::PythonCeil),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCopySign, I18n::Message::PythonCopySign), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCopySign, I18n::Message::PythonCopySign),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFactorial, I18n::Message::PythonFactorial),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFabs, I18n::Message::PythonFabs), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFabs, I18n::Message::PythonFabs),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFloor, I18n::Message::PythonFloor), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFloor, I18n::Message::PythonFloor),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFmod, I18n::Message::PythonFmod), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFmod, I18n::Message::PythonFmod),
@@ -365,18 +366,72 @@ const ToolboxMessageTree KandinskyModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFillRect, I18n::Message::PythonFillRect), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFillRect, I18n::Message::PythonFillRect),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFillCircle, I18n::Message::PythonFillCircle), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFillCircle, I18n::Message::PythonFillCircle),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFillPolygon, I18n::Message::PythonFillPolygon), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFillPolygon, I18n::Message::PythonFillPolygon),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandGetKeys, I18n::Message::PythonGetKeys), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandGetPalette, I18n::Message::PythonGetPalette)
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandGetPalette, I18n::Message::PythonGetPalette)}; };
const ToolboxMessageTree IonKeyModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyLeft, I18n::Message::PythonKeyLeft, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyUp, I18n::Message::PythonKeyUp, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyDown, I18n::Message::PythonKeyDown, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyRight, I18n::Message::PythonKeyRight, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyOk, I18n::Message::PythonKeyOk, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyBack, I18n::Message::PythonKeyBack, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyHome, I18n::Message::PythonKeyHome, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyOnOff, I18n::Message::PythonKeyOnOff, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyShift, I18n::Message::PythonKeyShift, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyAlpha, I18n::Message::PythonKeyAlpha, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyXnt, I18n::Message::PythonKeyXnt, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyVar, I18n::Message::PythonKeyVar, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyToolbox, I18n::Message::PythonKeyToolbox, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyBackspace, I18n::Message::PythonKeyBackspace, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyExp, I18n::Message::PythonKeyExp, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyLn, I18n::Message::PythonKeyLn, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyLog, I18n::Message::PythonKeyLog, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyImaginary, I18n::Message::PythonKeyImaginary, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyComma, I18n::Message::PythonKeyComma, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyPower, I18n::Message::PythonKeyPower, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeySine, I18n::Message::PythonKeySine, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyCosine, I18n::Message::PythonKeyCosine, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyTangent, I18n::Message::PythonKeyTangent, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyPi, I18n::Message::PythonKeyPi, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeySqrt, I18n::Message::PythonKeySqrt, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeySquare, I18n::Message::PythonKeySquare, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeySeven, I18n::Message::PythonKeySeven, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyEight, I18n::Message::PythonKeyEight, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyNine, I18n::Message::PythonKeyNine, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyLeftParenthesis, I18n::Message::PythonKeyLeftParenthesis, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyRightParenthesis, I18n::Message::PythonKeyRightParenthesis, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyFour, I18n::Message::PythonKeyFour, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyFive, I18n::Message::PythonKeyFive, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeySix, I18n::Message::PythonKeySix, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyMultiplication, I18n::Message::PythonKeyMultiplication, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyDivision, I18n::Message::PythonKeyDivision, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyOne, I18n::Message::PythonKeyOne, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyTwo, I18n::Message::PythonKeyTwo, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyThree, I18n::Message::PythonKeyThree, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyPlus, I18n::Message::PythonKeyPlus, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyMinus, I18n::Message::PythonKeyMinus, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyZero, I18n::Message::PythonKeyZero, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyDot, I18n::Message::PythonKeyDot, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyEe, I18n::Message::PythonKeyEe, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyAns, I18n::Message::PythonKeyAns, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyExe, I18n::Message::PythonKeyExe, false)
};
const ToolboxMessageTree IonModuleChildren[] = { const ToolboxMessageTree IonModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportIon, I18n::Message::PythonImportIon, false), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportIon, I18n::Message::PythonImportIon, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportFromIon, I18n::Message::PythonImportIon, false), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportFromIon, I18n::Message::PythonImportIon, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandIonFunction, I18n::Message::PythonIonFunction, false, I18n::Message::PythonCommandIonFunctionWithoutArg), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandIonFunction, I18n::Message::PythonIonFunction, false, I18n::Message::PythonCommandIonFunctionWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandIsKeyDown, I18n::Message::PythonIsKeyDown), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandIsKeyDown, I18n::Message::PythonIsKeyDown),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandGetKeys, I18n::Message::PythonGetKeys),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandBattery, I18n::Message::PythonBattery), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandBattery, I18n::Message::PythonBattery),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandBatteryLevel, I18n::Message::PythonBatteryLevel), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandBatteryLevel, I18n::Message::PythonBatteryLevel),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandBatteryIscharging, I18n::Message::PythonBatteryIscharging), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandBatteryIscharging, I18n::Message::PythonBatteryIscharging),
ToolboxMessageTree::Leaf(I18n::Message::IonSelector, I18n::Message::IonSelector) ToolboxMessageTree::Leaf(I18n::Message::PythonCommandSetBrightness, I18n::Message::PythonSetBrightness),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandGetBrightness, I18n::Message::PythonGetBrightness),
// This is a special case, because it is handled separately, so the sub-tree is unused.
ToolboxMessageTree::Node(I18n::Message::IonSelector, IonKeyModuleChildren),
ToolboxMessageTree::Node(I18n::Message::IonKeyList, IonKeyModuleChildren)
}; };
const ToolboxMessageTree TimeModuleChildren[] = { const ToolboxMessageTree TimeModuleChildren[] = {
@@ -403,6 +458,7 @@ const ToolboxMessageTree OsModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonOsCommandListdir, I18n::Message::PythonOsListdir, false) ToolboxMessageTree::Leaf(I18n::Message::PythonOsCommandListdir, I18n::Message::PythonOsListdir, false)
}; };
#if MICROPY_PY_SYS
const ToolboxMessageTree SysModuleChildren[] = { const ToolboxMessageTree SysModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportSys, I18n::Message::PythonImportSys, false), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportSys, I18n::Message::PythonImportSys, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportFromSys, I18n::Message::PythonImportSys, false), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportFromSys, I18n::Message::PythonImportSys, false),
@@ -414,6 +470,7 @@ const ToolboxMessageTree SysModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonSysCommandVersion, I18n::Message::PythonSysVersion, false), ToolboxMessageTree::Leaf(I18n::Message::PythonSysCommandVersion, I18n::Message::PythonSysVersion, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonSysCommandVersioninfo, I18n::Message::PythonSysVersioninfo, false) ToolboxMessageTree::Leaf(I18n::Message::PythonSysCommandVersioninfo, I18n::Message::PythonSysVersioninfo, false)
}; };
#endif
const ToolboxMessageTree modulesChildren[] = { const ToolboxMessageTree modulesChildren[] = {
ToolboxMessageTree::Node(I18n::Message::MathModule, MathModuleChildren), ToolboxMessageTree::Node(I18n::Message::MathModule, MathModuleChildren),
@@ -427,7 +484,9 @@ const ToolboxMessageTree modulesChildren[] = {
ToolboxMessageTree::Node(I18n::Message::KandinskyModule, KandinskyModuleChildren), ToolboxMessageTree::Node(I18n::Message::KandinskyModule, KandinskyModuleChildren),
ToolboxMessageTree::Node(I18n::Message::IonModule, IonModuleChildren), ToolboxMessageTree::Node(I18n::Message::IonModule, IonModuleChildren),
ToolboxMessageTree::Node(I18n::Message::OsModule, OsModuleChildren), ToolboxMessageTree::Node(I18n::Message::OsModule, OsModuleChildren),
#if MICROPY_PY_SYS
ToolboxMessageTree::Node(I18n::Message::SysModule, SysModuleChildren), ToolboxMessageTree::Node(I18n::Message::SysModule, SysModuleChildren),
#endif
ToolboxMessageTree::Node(I18n::Message::TimeModule, TimeModuleChildren) ToolboxMessageTree::Node(I18n::Message::TimeModule, TimeModuleChildren)
}; };
@@ -692,19 +751,13 @@ KDCoordinate PythonToolbox::rowHeight(int j) {
return Toolbox::rowHeight(j); return Toolbox::rowHeight(j);
} }
bool PythonToolbox::selectLeaf(int selectedRow) { bool PythonToolbox::selectLeaf(int selectedRow, bool quitToolbox) {
ToolboxMessageTree * node = (ToolboxMessageTree *)m_messageTreeModel->childAtIndex(selectedRow); ToolboxMessageTree * node = (ToolboxMessageTree *)m_messageTreeModel->childAtIndex(selectedRow);
#if defined(INCLUDE_ULAB) #if defined(INCLUDE_ULAB)
if(node->text() == I18n::Message::UlabDocumentationLink){ if(node->text() == I18n::Message::UlabDocumentationLink){
return true; return true;
} }
#endif #endif
m_selectableTableView.deselectTable();
if(node->insertedText() == I18n::Message::IonSelector){
m_ionKeys.setSender(sender());
Container::activeApp()->displayModalViewController(static_cast<ViewController*>(&m_ionKeys), 0.f, 0.f, Metric::PopUpTopMargin, Metric::PopUpLeftMargin, 0, Metric::PopUpRightMargin);
return true;
}
const char * editedText = I18n::translate(node->insertedText()); const char * editedText = I18n::translate(node->insertedText());
// strippedEditedText array needs to be in the same scope as editedText // strippedEditedText array needs to be in the same scope as editedText
char strippedEditedText[k_maxMessageSize]; char strippedEditedText[k_maxMessageSize];
@@ -715,10 +768,25 @@ bool PythonToolbox::selectLeaf(int selectedRow) {
editedText = strippedEditedText; editedText = strippedEditedText;
} }
sender()->handleEventWithText(editedText, true); sender()->handleEventWithText(editedText, true);
Container::activeApp()->dismissModalViewController(); if (quitToolbox) {
m_selectableTableView.deselectTable();
Container::activeApp()->dismissModalViewController();
}
return true; return true;
} }
// This is the same function as in the Toolbox class, but we need to override it because we need to handle the Key selector differently.
bool PythonToolbox::selectSubMenu(int selectedRow) {
// If the selected row is a is the Key selector, we display the IonKeySelectorViewController
if (m_messageTreeModel->childAtIndex(selectedRow)->label() == I18n::Message::IonSelector) {
m_ionKeys.setSender(sender());
Container::activeApp()->displayModalViewController(static_cast<ViewController*>(&m_ionKeys), 0.f, 0.f, Metric::PopUpTopMargin, Metric::PopUpLeftMargin, 0, Metric::PopUpRightMargin);
return true;
}
return Toolbox::selectSubMenu(selectedRow);
}
const ToolboxMessageTree * PythonToolbox::rootModel() const { const ToolboxMessageTree * PythonToolbox::rootModel() const {
return &toolboxModel; return &toolboxModel;
} }

View File

@@ -20,10 +20,12 @@ public:
const ToolboxMessageTree * rootModel() const override; const ToolboxMessageTree * rootModel() const override;
protected: protected:
KDCoordinate rowHeight(int j) override; KDCoordinate rowHeight(int j) override;
bool selectLeaf(int selectedRow) override; bool selectLeaf(int selectedRow, bool quitToolbox) override;
bool selectSubMenu(int selectedRow) override;
MessageTableCellWithMessage * leafCellAtIndex(int index) override; MessageTableCellWithMessage * leafCellAtIndex(int index) override;
MessageTableCellWithChevron* nodeCellAtIndex(int index) override; MessageTableCellWithChevron* nodeCellAtIndex(int index) override;
int maxNumberOfDisplayedRows() override; int maxNumberOfDisplayedRows() override;
bool canStayInMenu() override { return true; }
constexpr static int k_maxNumberOfDisplayedRows = 13; // = 240/(13+2*3) constexpr static int k_maxNumberOfDisplayedRows = 13; // = 240/(13+2*3)
// 13 = minimal string height size // 13 = minimal string height size
// 3 = vertical margins // 3 = vertical margins
@@ -33,7 +35,7 @@ private:
void scrollToAndSelectChild(int i); void scrollToAndSelectChild(int i);
MessageTableCellWithMessage m_leafCells[k_maxNumberOfDisplayedRows]; MessageTableCellWithMessage m_leafCells[k_maxNumberOfDisplayedRows];
MessageTableCellWithChevron m_nodeCells[k_maxNumberOfDisplayedRows]; MessageTableCellWithChevron m_nodeCells[k_maxNumberOfDisplayedRows];
toolboxIonKeys m_ionKeys; ToolboxIonKeys m_ionKeys;
}; };
} }

View File

@@ -65,6 +65,21 @@ bool Script::nameCompliant(const char * name) {
return false; return false;
} }
uint16_t Script::cursorOffset() {
assert(!isNull());
Ion::Storage::MetadataRowHeader * metadataForRecord = Ion::Storage::sharedStorage()->metadataForRecord(*this);
if (metadataForRecord != nullptr) {
assert(metadataForRecord->metadataSize == 2);
return *((uint16_t*) metadataForRecord->data());
}
return -1;
}
void Script::setCursorOffset(uint16_t position) {
assert(!isNull());
Ion::Storage::sharedStorage()->setMetadataForRecord(*this, sizeof(uint16_t), &position);
}
uint8_t * StatusFromData(Script::Data d) { uint8_t * StatusFromData(Script::Data d) {
return const_cast<uint8_t *>(static_cast<const uint8_t *>(d.buffer)); return const_cast<uint8_t *>(static_cast<const uint8_t *>(d.buffer));
} }

View File

@@ -50,6 +50,8 @@ public:
void toggleAutoimportationStatus(); void toggleAutoimportationStatus();
const char * content() const; const char * content() const;
size_t contentSize() { return value().size - k_statusSize; } size_t contentSize() { return value().size - k_statusSize; }
void setCursorOffset(uint16_t position); // -1 if no metadata
uint16_t cursorOffset();
/* Fetched status */ /* Fetched status */
bool fetchedFromConsole() const; bool fetchedFromConsole() const;

View File

@@ -49,7 +49,7 @@ private:
* k_fullFreeSpaceSizeLimit, we consider the script store as full. * k_fullFreeSpaceSizeLimit, we consider the script store as full.
* To be able to add a new empty record, the available space should at least * To be able to add a new empty record, the available space should at least
* be able to store a Script with default name and its extension, the * be able to store a Script with default name and its extension, the
* importation status (1 char), the default content "from math import *\n" * importation status (1 char), the cursor (2 char), the default content "from math import *\n"
* (20 char) and 10 char of free space. */ * (20 char) and 10 char of free space. */
static constexpr int k_fullFreeSpaceSizeLimit = sizeof(Ion::Storage::record_size_t)+Script::k_defaultScriptNameMaxSize+k_scriptExtensionLength+1+20+10; static constexpr int k_fullFreeSpaceSizeLimit = sizeof(Ion::Storage::record_size_t)+Script::k_defaultScriptNameMaxSize+k_scriptExtensionLength+1+20+10;
}; };

View File

@@ -10,7 +10,7 @@ public:
constexpr ScriptTemplate(const char * name, const char * value) : m_name(name), m_value(value) {} constexpr ScriptTemplate(const char * name, const char * value) : m_name(name), m_value(value) {}
static const ScriptTemplate * Empty(); static const ScriptTemplate * Empty();
const char * name() const { return m_name; } const char * name() const { return m_name; }
const char * content() const { return m_value + Script::StatusSize(); } const char * content() const { return m_value; + Script::StatusSize();}
const char * value() const { return m_value; } const char * value() const { return m_value; }
private: private:
const char * m_name; const char * m_name;

View File

@@ -1,26 +1,26 @@
#include "../toolbox_ion_keys.h" #include "../toolbox_ion_keys.h"
namespace Code { namespace Code {
toolboxIonKeys::toolboxIonKeys() : ToolboxIonKeys::ToolboxIonKeys() :
ViewController(nullptr), ViewController(nullptr),
m_view() m_view()
{ {
} }
bool toolboxIonKeys::handleEvent(Ion::Events::Event e) { bool ToolboxIonKeys::handleEvent(Ion::Events::Event e) {
return false; return false;
} }
toolboxIonKeys::toolboxIonView::toolboxIonView(): ToolboxIonKeys::toolboxIonView::toolboxIonView():
View() View()
{ {
} }
void toolboxIonKeys::toolboxIonView::drawRect(KDContext * ctx, KDRect rect) const { void ToolboxIonKeys::toolboxIonView::drawRect(KDContext * ctx, KDRect rect) const {
return; return;
} }
View * toolboxIonKeys::view(){ View * ToolboxIonKeys::view(){
return &m_view; return &m_view;
} }

View File

@@ -40,7 +40,7 @@ void assert_variables_are(const char * script, const char * nameToComplete, cons
&addParentheses, &addParentheses,
i, i,
&index); &index);
quiz_assert(i == index); // If false, the autompletion has cycled: there are not as many results as expected quiz_assert(i == index); // If false, the autocompletion has cycled: there are not as many results as expected
quiz_assert(strncmp(*(expectedVariables + i), autocompletionI - nameToCompleteLength, textToInsertLength + nameToCompleteLength) == 0); quiz_assert(strncmp(*(expectedVariables + i), autocompletionI - nameToCompleteLength, textToInsertLength + nameToCompleteLength) == 0);
index++; index++;
} }
@@ -63,7 +63,7 @@ QUIZ_CASE(variable_box_controller) {
}; };
// FIXME This test does not load imported variables for now // FIXME This test does not load imported variables for now
assert_variables_are( assert_variables_are(
"\x01 from math import *\nfroo=3", "\x01\x01\x01 from math import *\nfroo=3",
"fr", "fr",
expectedVariables, expectedVariables,
sizeof(expectedVariables) / sizeof(const char *)); sizeof(expectedVariables) / sizeof(const char *));

View File

@@ -5,3 +5,6 @@ LoopsAndTests = "Schleifen und Tests"
Files = "Dateien" Files = "Dateien"
Exceptions = "Ausnahmen" Exceptions = "Ausnahmen"
UlabDocumentation = "Dokumentation" UlabDocumentation = "Dokumentation"
IonSelector = "Schlüsselauswahl"
PressAKey = "drücke eine Taste"
IonKeyList = "Liste der Schlüssel"

View File

@@ -5,3 +5,6 @@ LoopsAndTests = "Loops and tests"
Files = "Files" Files = "Files"
Exceptions = "Exceptions" Exceptions = "Exceptions"
UlabDocumentation = "Documentation" UlabDocumentation = "Documentation"
IonSelector = "Key selector"
PressAKey = "Press a key"
IonKeyList = "List of keys"

View File

@@ -5,3 +5,6 @@ LoopsAndTests = "Loops and tests"
Files = "Files" Files = "Files"
Exceptions = "Exceptions" Exceptions = "Exceptions"
UlabDocumentation = "Documentación" UlabDocumentation = "Documentación"
IonSelector = "Selector de llave"
PressAKey = "presione una tecla"
IonKeyList = "Lista de llaves"

View File

@@ -5,3 +5,6 @@ LoopsAndTests = "Boucles et tests"
Files = "Fichiers" Files = "Fichiers"
Exceptions = "Exceptions" Exceptions = "Exceptions"
UlabDocumentation = "Documentation" UlabDocumentation = "Documentation"
IonSelector = "Sélecteur de touche"
PressAKey = "Appuyez sur une touche"
IonKeyList = "Liste des touches"

View File

@@ -5,3 +5,6 @@ LoopsAndTests = "Hurkok és tesztek"
Files = "Fájlok" Files = "Fájlok"
Exceptions = "Kivételek" Exceptions = "Kivételek"
UlabDocumentation = "Dokumentáció" UlabDocumentation = "Dokumentáció"
IonSelector = "Kulcsválasztó"
PressAKey = "Nyomj meg egy gombot"
IonKeyList = "A kulcsok listája"

View File

@@ -5,3 +5,6 @@ LoopsAndTests = "Cicli e test"
Files = "Files" Files = "Files"
Exceptions = "Exceptions" Exceptions = "Exceptions"
UlabDocumentation = "Documentazione" UlabDocumentation = "Documentazione"
IonSelector = "Selettore a chiave"
PressAKey = "Premi un tasto"
IonKeyList = "Elenco delle chiavi"

View File

@@ -5,3 +5,6 @@ LoopsAndTests = "Herhalingen en testen"
Files = "Files" Files = "Files"
Exceptions = "Exceptions" Exceptions = "Exceptions"
UlabDocumentation = "Documentatie" UlabDocumentation = "Documentatie"
IonSelector = "Toetsenkiezer"
PressAKey = "druk op een knop"
IonKeyList = "Lijst met sleutels"

View File

@@ -5,3 +5,6 @@ LoopsAndTests = "Laços e testes"
Files = "Files" Files = "Files"
Exceptions = "Exceptions" Exceptions = "Exceptions"
UlabDocumentation = "Documentação" UlabDocumentation = "Documentação"
IonSelector = "Seletor de chave"
PressAKey = "Pressione uma tecla"
IonKeyList = "Lista de chaves"

View File

@@ -68,6 +68,4 @@ PythonCommandDef = "def \x11():\n "
PythonCommandDefWithArg = "def function(x):" PythonCommandDefWithArg = "def function(x):"
PythonCommandReturn = "return " PythonCommandReturn = "return "
RandomModule = "random" RandomModule = "random"
IonSelector = "Key selector"
PressAKey = "Press a key"
UlabDocumentationLink = "micropython-ulab.readthedocs.io" UlabDocumentationLink = "micropython-ulab.readthedocs.io"

View File

@@ -6,45 +6,52 @@ extern "C" {
#include <py/obj.h> #include <py/obj.h>
#include <py/objfun.h> #include <py/objfun.h>
} }
extern const mp_rom_map_elem_t modion_module_globals_table[48]; extern "C" const mp_rom_map_elem_t modion_module_globals_table[52];
namespace Code { namespace Code {
toolboxIonKeys::toolboxIonKeys() : ToolboxIonKeys::ToolboxIonKeys() :
ViewController(nullptr), ViewController(nullptr),
m_view() m_view()
{ {
} }
bool toolboxIonKeys::handleEvent(Ion::Events::Event e) { bool ToolboxIonKeys::handleEvent(Ion::Events::Event e) {
Ion::Keyboard::State state = Ion::Keyboard::scan(); // FIXME: Use event data to get the pressed key and fix the EXE key.
for(uint16_t i = 0; i < sizeof(modion_module_globals_table)/sizeof(_mp_rom_map_elem_t); i++){ Ion::Keyboard::State state = Ion::Keyboard::scan();
_mp_rom_map_elem_t element = modion_module_globals_table[i]; for (uint16_t i = 0; i < sizeof(modion_module_globals_table) / sizeof(_mp_rom_map_elem_t); i++) {
if(mp_obj_is_small_int(element.value)){ _mp_rom_map_elem_t element = modion_module_globals_table[i];
int key = mp_obj_get_int(element.value); if (mp_obj_is_small_int(element.value)) {
if(state.keyDown(static_cast<Ion::Keyboard::Key>(key))){ int key = mp_obj_get_int(element.value);
m_sender->handleEventWithText(qstr_str(MP_OBJ_QSTR_VALUE(element.key)), true); if (state.keyDown(static_cast<Ion::Keyboard::Key>(key))) {
} m_sender->handleEventWithText(qstr_str(MP_OBJ_QSTR_VALUE(element.key)), true);
} }
} }
Container::activeApp()->dismissModalViewController();
AppsContainer::sharedAppsContainer()->redrawWindow();
return true;
} }
Container::activeApp()->dismissModalViewController();
AppsContainer::sharedAppsContainer()->redrawWindow();
return true;
}
toolboxIonKeys::toolboxIonView::toolboxIonView(): ToolboxIonKeys::toolboxIonView::toolboxIonView() :
View() View()
{ {
} }
void toolboxIonKeys::toolboxIonView::drawRect(KDContext * ctx, KDRect rect) const { void ToolboxIonKeys::toolboxIonView::drawRect(KDContext * ctx, KDRect rect) const {
ctx->fillRect(rect, Palette::WallScreen); ctx->fillRect(rect, Palette::WallScreen);
ctx->strokeRect(rect, Palette::ListCellBorder); ctx->strokeRect(rect, Palette::ListCellBorder);
ctx->drawString(I18n::translate(I18n::Message::PressAKey),KDPoint(rect.left()+80, rect.top()+20),KDFont::LargeFont,Palette::PrimaryText,Palette::WallScreen); KDSize fontSize = KDFont::LargeFont->glyphSize();
const char * message = I18n::translate(I18n::Message::PressAKey);
} // Get the starting position of the text to center it.
KDPoint textPosition = KDPoint(rect.size().width() / 2 - strlen(message) * fontSize.width() / 2,
rect.size().height() / 2 - fontSize.height() / 2);
View * toolboxIonKeys::view(){ ctx->drawString(message, textPosition, KDFont::LargeFont, Palette::PrimaryText, Palette::WallScreen);
return &m_view;
} }
View * ToolboxIonKeys::view() {
return &m_view;
}
} }

View File

@@ -2,9 +2,9 @@
namespace Code { namespace Code {
class toolboxIonKeys : public ViewController { class ToolboxIonKeys : public ViewController {
public : public :
toolboxIonKeys(); ToolboxIonKeys();
View * view() override; View * view() override;
bool handleEvent(Ion::Events::Event e) override; bool handleEvent(Ion::Events::Event e) override;
void setSender(InputEventHandler * sender) { m_sender = sender; } void setSender(InputEventHandler * sender) { m_sender = sender; }

View File

@@ -365,7 +365,7 @@ int VariableBoxController::typeAndOriginAtLocation(int i, NodeOrigin * resultOri
} }
bool VariableBoxController::selectLeaf(int rowIndex) { bool VariableBoxController::selectLeaf(int rowIndex, bool quitToolbox) {
assert(rowIndex >= 0 && rowIndex < numberOfRows()); assert(rowIndex >= 0 && rowIndex < numberOfRows());
m_selectableTableView.deselectTable(); m_selectableTableView.deselectTable();
@@ -516,7 +516,7 @@ void VariableBoxController::loadBuiltinNodes(const char * textToAutocomplete, in
assert(sizeof(builtinNames) / sizeof(builtinNames[0]) == k_totalBuiltinNodesCount); assert(sizeof(builtinNames) / sizeof(builtinNames[0]) == k_totalBuiltinNodesCount);
for (int i = 0; i < k_totalBuiltinNodesCount; i++) { for (int i = 0; i < k_totalBuiltinNodesCount; i++) {
if (addNodeIfMatches(textToAutocomplete, textToAutocompleteLength, builtinNames[i].type, NodeOrigin::Builtins, builtinNames[i].name)) { if (addNodeIfMatches(textToAutocomplete, textToAutocompleteLength, builtinNames[i].type, NodeOrigin::Builtins, builtinNames[i].name)) {
/* We can leverage on the fact that buitin nodes are stored in /* We can leverage on the fact that builtin nodes are stored in
* alphabetical order. */ * alphabetical order. */
return; return;
} }
@@ -575,7 +575,7 @@ void VariableBoxController::loadImportedVariablesInScript(const char * scriptCon
} }
void VariableBoxController::loadCurrentVariablesInScript(const char * scriptContent, const char * textToAutocomplete, int textToAutocompleteLength) { void VariableBoxController::loadCurrentVariablesInScript(const char * scriptContent, const char * textToAutocomplete, int textToAutocompleteLength) {
/* To find variable and funtion names: we lex the script and keep all /* To find variable and function names: we lex the script and keep all
* MP_TOKEN_NAME that complete the text to autocomplete and are not already in * MP_TOKEN_NAME that complete the text to autocomplete and are not already in
* the builtins or imported scripts. */ * the builtins or imported scripts. */
@@ -653,7 +653,7 @@ void VariableBoxController::loadGlobalAndImportedVariablesInScriptAsImported(Scr
/* At this point, if the script node is not of type "file_input_2", it /* At this point, if the script node is not of type "file_input_2", it
* will not have main structures of the wanted type. * will not have main structures of the wanted type.
* We look for structures at first level (not inside nested scopes) that * We look for structures at first level (not inside nested scopes) that
* are either dunction definitions, variables statements or imports. */ * are either function definitions, variables statements or imports. */
size_t n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); size_t n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
mp_parse_node_t child = pns->nodes[i]; mp_parse_node_t child = pns->nodes[i];
@@ -826,15 +826,15 @@ bool VariableBoxController::importationSourceIsModule(const char * sourceName, c
return mp_module_get(qstr_from_str(sourceName)) != MP_OBJ_NULL; return mp_module_get(qstr_from_str(sourceName)) != MP_OBJ_NULL;
} }
bool VariableBoxController::importationSourceIsScript(const char * sourceName, const char * * scriptFullName, Script * retreivedScript) { bool VariableBoxController::importationSourceIsScript(const char * sourceName, const char * * scriptFullName, Script * retrievedScript) {
// Try fetching the nodes from a script // Try fetching the nodes from a script
Script importedScript = ScriptStore::ScriptBaseNamed(sourceName); Script importedScript = ScriptStore::ScriptBaseNamed(sourceName);
if (importedScript.isNull()) { if (importedScript.isNull()) {
return false; return false;
} }
*scriptFullName = importedScript.fullName(); *scriptFullName = importedScript.fullName();
if (retreivedScript != nullptr) { if (retrievedScript != nullptr) {
*retreivedScript = importedScript; *retrievedScript = importedScript;
} }
return true; return true;
} }

View File

@@ -80,7 +80,7 @@ private:
// NestedMenuController // NestedMenuController
HighlightCell * leafCellAtIndex(int index) override { assert(false); return nullptr; } HighlightCell * leafCellAtIndex(int index) override { assert(false); return nullptr; }
HighlightCell * nodeCellAtIndex(int index) override { assert(false); return nullptr; } HighlightCell * nodeCellAtIndex(int index) override { assert(false); return nullptr; }
bool selectLeaf(int rowIndex) override; bool selectLeaf(int rowIndex, bool quitToolbox) override;
void insertTextInCaller(const char * text, int textLength = -1); void insertTextInCaller(const char * text, int textLength = -1);
// Loading // Loading
@@ -92,7 +92,7 @@ private:
bool addNodesFromImportMaybe(mp_parse_node_struct_t * parseNode, const char * textToAutocomplete, int textToAutocompleteLength, bool importFromModules = true); bool addNodesFromImportMaybe(mp_parse_node_struct_t * parseNode, const char * textToAutocomplete, int textToAutocompleteLength, bool importFromModules = true);
const char * importationSourceNameFromNode(mp_parse_node_t & node); const char * importationSourceNameFromNode(mp_parse_node_t & node);
bool importationSourceIsModule(const char * sourceName, const ToolboxMessageTree * * moduleChildren = nullptr, int * numberOfModuleChildren = nullptr); bool importationSourceIsModule(const char * sourceName, const ToolboxMessageTree * * moduleChildren = nullptr, int * numberOfModuleChildren = nullptr);
bool importationSourceIsScript(const char * sourceName, const char * * scriptFullName, Script * retreivedScript = nullptr); bool importationSourceIsScript(const char * sourceName, const char * * scriptFullName, Script * retrievedScript = nullptr);
bool addImportStructFromScript(mp_parse_node_struct_t * pns, uint structKind, const char * scriptName, const char * textToAutocomplete, int textToAutocompleteLength); bool addImportStructFromScript(mp_parse_node_struct_t * pns, uint structKind, const char * scriptName, const char * textToAutocomplete, int textToAutocompleteLength);
/* Add a node if it completes the text to autocomplete and if it is not /* Add a node if it completes the text to autocomplete and if it is not
* already contained in the variable box. The returned boolean means we * already contained in the variable box. The returned boolean means we

2
apps/external/app.h vendored
View File

@@ -29,7 +29,7 @@ private:
MainController m_mainController; MainController m_mainController;
StackViewController m_stackViewController; StackViewController m_stackViewController;
Window * m_window; Window * m_window;
static constexpr int k_externalHeapSize = 100000; static constexpr int k_externalHeapSize = 99000;
char m_externalHeap[k_externalHeapSize]; char m_externalHeap[k_externalHeapSize];
}; };

View File

@@ -40,9 +40,10 @@ bool isExamModeAndFileNotExecutable(const TarHeader* tar) {
} }
bool fileAtIndex(size_t index, File &entry) { bool fileAtIndex(size_t index, File &entry) {
if (index == -1) if (index == -1) {
return false; return false;
}
const TarHeader* tar = reinterpret_cast<const TarHeader*>(0x90200000); const TarHeader* tar = reinterpret_cast<const TarHeader*>(0x90200000);
unsigned size = 0; unsigned size = 0;
@@ -74,6 +75,8 @@ bool fileAtIndex(size_t index, File &entry) {
entry.data = reinterpret_cast<const uint8_t*>(tar) + sizeof(TarHeader); entry.data = reinterpret_cast<const uint8_t*>(tar) + sizeof(TarHeader);
entry.dataLength = size; entry.dataLength = size;
entry.isExecutable = (tar->mode[4] & 0x01) == 1; entry.isExecutable = (tar->mode[4] & 0x01) == 1;
// TODO: Handle the trash
entry.readable = true;
return true; return true;
} else { } else {
@@ -111,18 +114,31 @@ uint32_t executeFile(const char *name, void * heap, const uint32_t heapSize) {
return -1; return -1;
} }
int indexFromName(const char *name) {
File entry;
for (int i = 0; fileAtIndex(i, entry); i++) { #else
if (strcmp(name, entry.name) == 0) {
return i; bool fileAtIndex(size_t index, File &entry) {
} if (index != 0) {
return false;
} }
return -1; entry.name = "Built-in";
entry.data = NULL;
entry.dataLength = 0;
entry.isExecutable = true;
entry.readable = true;
return true;
} }
extern "C" void extapp_main(void);
uint32_t executeFile(const char *name, void * heap, const uint32_t heapSize) {
extapp_main();
return 0;
}
#endif
size_t numberOfFiles() { size_t numberOfFiles() {
File dummy; File dummy;
size_t count; size_t count;
@@ -132,6 +148,18 @@ size_t numberOfFiles() {
return count; return count;
} }
int indexFromName(const char *name) {
File entry;
for (int i = 0; fileAtIndex(i, entry); i++) {
if (entry.readable && strcmp(name, entry.name) == 0) {
return i;
}
}
return -1;
}
bool executableAtIndex(size_t index, File &entry) { bool executableAtIndex(size_t index, File &entry) {
File dummy; File dummy;
size_t count; size_t count;
@@ -144,16 +172,19 @@ bool executableAtIndex(size_t index, File &entry) {
entry.data = dummy.data; entry.data = dummy.data;
entry.dataLength = dummy.dataLength; entry.dataLength = dummy.dataLength;
entry.isExecutable = dummy.isExecutable; entry.isExecutable = dummy.isExecutable;
entry.readable = dummy.readable;
return true; return true;
} }
final_count++; final_count++;
} }
} }
return false; return false;
} }
size_t numberOfExecutables() { size_t numberOfExecutables() {
if (!GlobalPreferences::sharedGlobalPreferences()->externalAppShown()) {
return false;
}
File dummy; File dummy;
size_t count; size_t count;
size_t final_count = 0; size_t final_count = 0;
@@ -165,48 +196,5 @@ size_t numberOfExecutables() {
return final_count; return final_count;
} }
#else
bool fileAtIndex(size_t index, File &entry) {
if (index != 0)
return false;
entry.name = "Built-in";
entry.data = NULL;
entry.dataLength = 0;
entry.isExecutable = true;
return true;
}
bool executableAtIndex(size_t index, File &entry) {
return fileAtIndex(index, entry);
}
size_t numberOfExecutables() {
return 1;
}
extern "C" void extapp_main(void);
uint32_t executeFile(const char *name, void * heap, const uint32_t heapSize) {
extapp_main();
return 0;
}
int indexFromName(const char *name) {
if (strcmp(name, "Built-in") == 0)
return 0;
else
return -1;
}
size_t numberOfFiles() {
return 1;
}
#endif
} }
} }

View File

@@ -14,6 +14,7 @@ struct File {
const uint8_t *data; const uint8_t *data;
size_t dataLength; size_t dataLength;
bool isExecutable; bool isExecutable;
bool readable;
}; };
bool fileAtIndex(size_t index, File &entry); bool fileAtIndex(size_t index, File &entry);

View File

@@ -9,10 +9,16 @@
#include "../apps_container.h" #include "../apps_container.h"
#include "../global_preferences.h" #include "../global_preferences.h"
#ifdef DEVICE
#include <ion/src/device/shared/drivers/reset.h>
#include <ion/src/device/shared/drivers/board.h>
#include <ion/src/device/shared/drivers/flash.h>
#endif
#include <python/port/port.h> #include <python/port/port.h>
extern "C" { extern "C" {
#include <python/port/mphalport.h> #include <python/port/mphalport.h>
} }
uint64_t extapp_millis() { uint64_t extapp_millis() {
@@ -30,7 +36,7 @@ uint64_t extapp_scanKeyboard() {
void extapp_pushRect(int16_t x, int16_t y, uint16_t w, uint16_t h, const uint16_t * pixels) { void extapp_pushRect(int16_t x, int16_t y, uint16_t w, uint16_t h, const uint16_t * pixels) {
KDRect rect(x, y, w, h); KDRect rect(x, y, w, h);
Ion::Display::pushRect(rect, reinterpret_cast<const KDColor*>(pixels)); Ion::Display::pushRect(rect, reinterpret_cast<const KDColor *>(pixels));
} }
void extapp_pushRectUniform(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t color) { void extapp_pushRectUniform(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t color) {
@@ -42,10 +48,10 @@ void extapp_pushRectUniform(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16
void extapp_pullRect(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t * pixels) { void extapp_pullRect(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t * pixels) {
KDRect rect(x, y, w, h); KDRect rect(x, y, w, h);
Ion::Display::pullRect(rect, (KDColor *) pixels); Ion::Display::pullRect(rect, (KDColor *)pixels);
} }
int16_t extapp_drawTextLarge(const char *text, int16_t x, int16_t y, uint16_t fg, uint16_t bg, bool fake) { int16_t extapp_drawTextLarge(const char * text, int16_t x, int16_t y, uint16_t fg, uint16_t bg, bool fake) {
KDPoint point(x, y); KDPoint point(x, y);
auto ctx = KDIonContext::sharedContext(); auto ctx = KDIonContext::sharedContext();
@@ -56,7 +62,7 @@ int16_t extapp_drawTextLarge(const char *text, int16_t x, int16_t y, uint16_t fg
return point.x(); return point.x();
} }
int16_t extapp_drawTextSmall(const char *text, int16_t x, int16_t y, uint16_t fg, uint16_t bg, bool fake) { int16_t extapp_drawTextSmall(const char * text, int16_t x, int16_t y, uint16_t fg, uint16_t bg, bool fake) {
KDPoint point(x, y); KDPoint point(x, y);
auto ctx = KDIonContext::sharedContext(); auto ctx = KDIonContext::sharedContext();
@@ -71,7 +77,7 @@ bool extapp_waitForVBlank() {
return Ion::Display::waitForVBlank(); return Ion::Display::waitForVBlank();
} }
void extapp_clipboardStore(const char *text) { void extapp_clipboardStore(const char * text) {
Clipboard::sharedClipboard()->store(text); Clipboard::sharedClipboard()->store(text);
} }
@@ -79,101 +85,103 @@ const char * extapp_clipboardText() {
return Clipboard::sharedClipboard()->storedText(); return Clipboard::sharedClipboard()->storedText();
} }
bool match(const char * filename, const char * extension) {
return strcmp(filename + strlen(filename) - strlen(extension), extension) == 0;
}
int extapp_fileListWithExtension(const char ** filenames, int maxrecords, const char * extension, int storage) { int extapp_fileListWithExtension(const char ** filenames, int maxrecords, const char * extension, int storage) {
if(storage == EXTAPP_RAM_FILE_SYSTEM) { int j = 0;
if (storage == EXTAPP_RAM_FILE_SYSTEM || storage == EXTAPP_BOTH_FILE_SYSTEM) {
int n = Ion::Storage::sharedStorage()->numberOfRecordsWithExtension(extension); int n = Ion::Storage::sharedStorage()->numberOfRecordsWithExtension(extension);
if (n > maxrecords) { if (n > maxrecords) {
n = maxrecords; n = maxrecords;
} }
for(int i = 0; i < n; i++) { for (; j < n; j++) {
filenames[i] = Ion::Storage::sharedStorage()->recordWithExtensionAtIndex(extension, i).fullName(); filenames[j] = Ion::Storage::sharedStorage()->recordWithExtensionAtIndex(extension, j).fullName();
} }
return n; if (j == maxrecords) {
} else if(storage == EXTAPP_FLASH_FILE_SYSTEM) { return j;
// TODO: filter by extension
int n = External::Archive::numberOfFiles();
if (n > maxrecords) {
n = maxrecords;
} }
for(int i = 0; i < n; i++) {
External::Archive::File entry;
External::Archive::fileAtIndex(i, entry);
filenames[i] = entry.name;
}
return n;
} else {
return 0;
} }
// Don't read external files the exam mode is enabled
if (GlobalPreferences::sharedGlobalPreferences()->isInExamMode()) return j;
if (storage == EXTAPP_FLASH_FILE_SYSTEM || storage == EXTAPP_BOTH_FILE_SYSTEM) {
int n = External::Archive::numberOfFiles();
for (int i = 0; i < n && j < maxrecords; i++) {
External::Archive::File entry;
// Filter extension
if (External::Archive::fileAtIndex(i, entry) && match(entry.name, extension)) {
filenames[j] = entry.name;
++j;
}
}
}
return j;
} }
bool extapp_fileExists(const char * filename, int storage) { bool extapp_fileExists(const char * filename, int storage) {
if(storage == EXTAPP_RAM_FILE_SYSTEM) { if (storage == EXTAPP_RAM_FILE_SYSTEM || storage == EXTAPP_BOTH_FILE_SYSTEM) {
return !Ion::Storage::sharedStorage()->recordNamed(filename).isNull(); if (!Ion::Storage::sharedStorage()->recordNamed(filename).isNull())
} else if(storage == EXTAPP_FLASH_FILE_SYSTEM) { return true;
return External::Archive::indexFromName(filename) >= 0;
} else {
return false;
} }
if (storage == EXTAPP_FLASH_FILE_SYSTEM || storage == EXTAPP_BOTH_FILE_SYSTEM) {
return External::Archive::indexFromName(filename) >= 0;
}
return false;
} }
bool extapp_fileErase(const char * filename, int storage) { bool extapp_fileErase(const char * filename, int storage) {
if(storage == EXTAPP_RAM_FILE_SYSTEM) { if (storage == EXTAPP_RAM_FILE_SYSTEM) {
Ion::Storage::Record record = Ion::Storage::sharedStorage()->recordNamed(filename); Ion::Storage::Record record = Ion::Storage::sharedStorage()->recordNamed(filename);
if(record.isNull()) { if (record.isNull()) {
return false; return false;
} else {
record.destroy();
return true;
} }
} else { record.destroy();
return false; return true;
} }
return false;
} }
const char * extapp_fileRead(const char * filename, size_t *len, int storage) { const char * extapp_fileRead(const char * filename, size_t * len, int storage) {
if(storage == EXTAPP_RAM_FILE_SYSTEM) { if (storage == EXTAPP_RAM_FILE_SYSTEM || storage == EXTAPP_BOTH_FILE_SYSTEM) {
const Ion::Storage::Record record = Ion::Storage::sharedStorage()->recordNamed(filename); const Ion::Storage::Record record = Ion::Storage::sharedStorage()->recordNamed(filename);
if (record.isNull()) { if (!record.isNull()){
return NULL; int delta = 0;
} else { if (match(filename, ".py") || match(filename, ".xw"))
if(len) { delta++;
*len = record.value().size; // skip record type
} if (len)
return (const char *) record.value().buffer; *len = record.value().size - delta;
return (const char *)record.value().buffer + delta;
} }
} else if(storage == EXTAPP_FLASH_FILE_SYSTEM) { }
if (storage == EXTAPP_FLASH_FILE_SYSTEM || storage == EXTAPP_BOTH_FILE_SYSTEM) {
int index = External::Archive::indexFromName(filename); int index = External::Archive::indexFromName(filename);
if (index >= 0) { if (index >= 0) {
External::Archive::File entry; External::Archive::File entry;
External::Archive::fileAtIndex(index, entry); External::Archive::fileAtIndex(index, entry);
if(len) { if (len) {
*len = entry.dataLength; *len = entry.dataLength;
} }
return (const char *)entry.data; return (const char *)entry.data;
} else {
return NULL;
} }
} else {
return NULL;
} }
return NULL;
} }
bool extapp_fileWrite(const char * filename, const char * content, size_t len, int storage) { bool extapp_fileWrite(const char * filename, const char * content, size_t len, int storage) {
if(storage == EXTAPP_RAM_FILE_SYSTEM) { if (storage == EXTAPP_RAM_FILE_SYSTEM) {
Ion::Storage::Record::ErrorStatus status = Ion::Storage::sharedStorage()->createRecordWithFullName(filename, content, len); Ion::Storage::Record::ErrorStatus status = Ion::Storage::sharedStorage()->createRecordWithFullName(filename, content, len);
if (status == Ion::Storage::Record::ErrorStatus::NameTaken) { if (status == Ion::Storage::Record::ErrorStatus::NameTaken) {
Ion::Storage::Record::Data data; Ion::Storage::Record::Data data;
data.buffer = content; data.buffer = content;
data.size = len; data.size = len;
return Ion::Storage::sharedStorage()->recordNamed(filename).setValue(data) == Ion::Storage::Record::ErrorStatus::None; return Ion::Storage::sharedStorage()->recordNamed(filename).setValue(data) == Ion::Storage::Record::ErrorStatus::None;
} else if (status == Ion::Storage::Record::ErrorStatus::None) {
return true;
} else {
return false;
} }
} else { if (status == Ion::Storage::Record::ErrorStatus::None)
return false; return true;
} }
return false;
} }
static void reloadTitleBar() { static void reloadTitleBar() {
@@ -244,19 +252,42 @@ const int16_t translated_keys[] =
#define TICKS_PER_MINUTE 11862 #define TICKS_PER_MINUTE 11862
#endif #endif
int extapp_getKey(bool allowSuspend, bool *alphaWasActive) {
int extapp_restoreBackup(int mode) {
// Restoring the backup is allowed even if the write protection is enabled, because it may have been writted by Khi.x
if (GlobalPreferences::sharedGlobalPreferences()->isInExamMode())
return 0;
size_t length = 32 * 1024;
if (mode == -1) { // restore backup saved when exam mode was set
uint8_t * src = (uint8_t *)(0x90800000 - 2 * length);
if (src[0] == 0xba && src[1] == 0xdd && src[2] == 0x0b && src[3] == 0xee) {
memcpy((uint8_t *)Ion::storageAddress(), src, length);
return 1;
}
}
if (mode >= 0 && mode < 16) {
uint8_t * src = (uint8_t *)(0x90180000 + mode * length);
if (src[0] == 0xba && src[1] == 0xdd && src[2] == 0x0b && src[3] == 0xee) {
memcpy((uint8_t *)Ion::storageAddress(), src, length);
return 1;
}
}
return 0;
}
int extapp_getKey(int allowSuspend, bool * alphaWasActive) {
int key = -1; int key = -1;
size_t t1 = Ion::Timing::millis(); size_t t1 = Ion::Timing::millis();
for (;;) { for (;;) {
int timeout = 10000; int timeout = 10000;
if(alphaWasActive) { if (alphaWasActive) {
*alphaWasActive = Ion::Events::isAlphaActive(); *alphaWasActive = Ion::Events::isAlphaActive();
} }
Ion::Events::Event event = Ion::Events::getEvent(&timeout); Ion::Events::Event event = Ion::Events::getEvent(&timeout);
reloadTitleBar(); reloadTitleBar();
if (event == Ion::Events::None) { if (event == Ion::Events::None) {
size_t t2 = Ion::Timing::millis(); size_t t2 = Ion::Timing::millis();
if (t2 - t1 > 2 * TICKS_PER_MINUTE) { if (t2 - t1 > 3 * TICKS_PER_MINUTE) {
event = Ion::Events::OnOff; event = Ion::Events::OnOff;
} }
} else { } else {
@@ -270,10 +301,10 @@ int extapp_getKey(bool allowSuspend, bool *alphaWasActive) {
} }
if (event.isKeyboardEvent()) { if (event.isKeyboardEvent()) {
key = static_cast<uint8_t>(event); key = static_cast<uint8_t>(event);
if (key == 17 || key == 4 || key == 5 || key == 52) { if (key == (int)Ion::Keyboard::Key::Backspace || key == (int)Ion::Keyboard::Key::OK || key == (int)Ion::Keyboard::Key::Back || key == (int)Ion::Keyboard::Key::EXE) {
extapp_resetKeyboard(); extapp_resetKeyboard();
} }
if (allowSuspend && (key == 7 || key == 8)) { // power if (allowSuspend && key == (int)Ion::Keyboard::Key::OnOff) {
Ion::Power::suspend(true); Ion::Power::suspend(true);
extapp_pushRectUniform(0, 0, 320, 240, 65535); extapp_pushRectUniform(0, 0, 320, 240, 65535);
Ion::Backlight::setBrightness(GlobalPreferences::sharedGlobalPreferences()->brightnessLevel()); Ion::Backlight::setBrightness(GlobalPreferences::sharedGlobalPreferences()->brightnessLevel());
@@ -285,6 +316,45 @@ int extapp_getKey(bool allowSuspend, bool *alphaWasActive) {
return translated_keys[key]; return translated_keys[key];
} }
bool extapp_isKeydown(int key) {
Ion::Keyboard::State scan = Ion::Keyboard::scan();
return scan.keyDown(Ion::Keyboard::Key(key));
}
bool extapp_eraseSector(void * ptr) {
#ifdef DEVICE
if (ptr == 0)
Ion::Device::Reset::core();
// Disable flash writting
if (GlobalPreferences::sharedGlobalPreferences()->externalAppWritePermission()) {
int i = Ion::Device::Flash::SectorAtAddress((size_t)ptr);
if (i < 0)
return false;
Ion::Device::Flash::EraseSector(i);
return true;
}
#endif
return false;
}
bool extapp_writeMemory(unsigned char * dest, const unsigned char * data, size_t length) {
#ifdef DEVICE
// Disable flash writting
if (GlobalPreferences::sharedGlobalPreferences()->externalAppWritePermission()) {
int n = Ion::Device::Flash::SectorAtAddress((uint32_t)dest);
if (n < 0)
return false;
Ion::Device::Flash::WriteMemory(dest, (unsigned char *)data, length);
return true;
}
#endif
return false;
}
bool extapp_inExamMode() {
return GlobalPreferences::sharedGlobalPreferences()->isInExamMode();
}
extern "C" void (* const apiPointers[])(void) = { extern "C" void (* const apiPointers[])(void) = {
(void (*)(void)) extapp_millis, (void (*)(void)) extapp_millis,
(void (*)(void)) extapp_msleep, (void (*)(void)) extapp_msleep,
@@ -305,5 +375,10 @@ extern "C" void (* const apiPointers[])(void) = {
(void (*)(void)) extapp_lockAlpha, (void (*)(void)) extapp_lockAlpha,
(void (*)(void)) extapp_resetKeyboard, (void (*)(void)) extapp_resetKeyboard,
(void (*)(void)) extapp_getKey, (void (*)(void)) extapp_getKey,
(void (*)(void)) extapp_isKeydown,
(void (*)(void)) extapp_restoreBackup,
(void (*)(void)) extapp_eraseSector,
(void (*)(void)) extapp_writeMemory,
(void (*)(void)) extapp_inExamMode,
(void (*)(void)) nullptr, (void (*)(void)) nullptr,
}; };

View File

@@ -18,6 +18,7 @@
#define EXTAPP_RAM_FILE_SYSTEM 0 #define EXTAPP_RAM_FILE_SYSTEM 0
#define EXTAPP_FLASH_FILE_SYSTEM 1 #define EXTAPP_FLASH_FILE_SYSTEM 1
#define EXTAPP_BOTH_FILE_SYSTEM 2
#define SCANCODE_Left ((uint64_t)1 << 0) #define SCANCODE_Left ((uint64_t)1 << 0)
#define SCANCODE_Up ((uint64_t)1 << 1) #define SCANCODE_Up ((uint64_t)1 << 1)
@@ -251,6 +252,10 @@ EXTERNC const char * extapp_fileRead(const char * filename, size_t *len, int sto
EXTERNC bool extapp_fileWrite(const char * filename, const char * content, size_t len, int storage); EXTERNC bool extapp_fileWrite(const char * filename, const char * content, size_t len, int storage);
EXTERNC void extapp_lockAlpha(); EXTERNC void extapp_lockAlpha();
EXTERNC void extapp_resetKeyboard(); EXTERNC void extapp_resetKeyboard();
EXTERNC int extapp_getKey(bool allowSuspend, bool *alphaWasActive); EXTERNC int extapp_getKey(int allowSuspend, bool *alphaWasActive);
EXTERNC bool extapp_isKeydown(int key);
EXTERNC int extapp_restoreBackup(int mode); // Keep for compatibility with KhiCAS on Khi
EXTERNC bool extapp_eraseSector(void * ptr);
EXTERNC bool extapp_writeMemory(unsigned char * dest,const unsigned char * data,size_t length);
#endif #endif

View File

@@ -1,23 +0,0 @@
apps += Geometry::App
app_headers += apps/geometry/app.h
app_geometry_src = $(addprefix apps/geometry/,\
app.cpp \
list/figures_controller.cpp \
list/definition_type_controller.cpp \
list/figure_type_controller.cpp \
list/figure_parameters_controller.cpp \
list/objects_controller.cpp \
list/message_table_cell_with_selector.cpp \
figure_store.cpp \
graph/graph_controller.cpp \
graph/banner_view.cpp \
)
apps_src += $(app_geometry_src)
app_images += apps/geometry/geometry_icon.png
i18n_files += $(call i18n_with_universal_for,geometry/base)
$(eval $(call depends_on_image,apps/geometry/app.cpp,apps/geometry/geometry_icon.png))

View File

@@ -1,48 +0,0 @@
#include "app.h"
#include "geometry_icon.h"
#include "apps/apps_container.h"
#include "apps/i18n.h"
namespace Geometry
{
I18n::Message App::Descriptor::name()
{
return I18n::Message::GeometryApp;
}
I18n::Message App::Descriptor::upperName()
{
return I18n::Message::GeometryAppCapital;
}
const Image * App::Descriptor::icon()
{
return ImageStore::GeometryIcon;
}
App * App::Snapshot::unpack(Container * container)
{
return new (container->currentAppBuffer()) App(this);
}
App::Descriptor * App::Snapshot::descriptor()
{
static Descriptor descriptor;
return &descriptor;
}
App::App(Snapshot * snapshot) :
TextFieldDelegateApp(snapshot, &m_tabViewController),
m_figuresController(&m_stackViewController),
m_stackViewController(&m_tabViewController, &m_figuresController),
m_graphController(&m_graphAlternateEmptyViewController, this, &m_graphHeader, nullptr, nullptr, nullptr),
m_graphAlternateEmptyViewController(&m_graphHeader, &m_graphController, &m_graphController),
m_graphHeader(&m_graphStackViewController, &m_graphAlternateEmptyViewController, &m_graphController),
m_graphStackViewController(&m_tabViewController, &m_graphHeader),
m_otherViewController(&m_tabViewController),
m_tabViewController(&m_modalViewController, snapshot, &m_stackViewController, &m_graphAlternateEmptyViewController, &m_otherViewController)
{
}
}

View File

@@ -1,40 +0,0 @@
#ifndef GEOMETRY_H
#define GEOMETRY_H
#include <escher.h>
#include "list/figures_controller.h"
#include "graph/graph_controller.h"
#include "other/other_view_controller.h"
#include "../shared/text_field_delegate_app.h"
namespace Geometry {
class App : public Shared::TextFieldDelegateApp {
public:
class Descriptor : public ::App::Descriptor {
public:
I18n::Message name() override;
I18n::Message upperName() override;
const Image * icon() override;
};
class Snapshot : public ::App::Snapshot, public TabViewDataSource {
public:
App * unpack(Container * container) override;
Descriptor * descriptor() override;
};
private:
App(Snapshot * snapshot);
FiguresController m_figuresController;
StackViewController m_stackViewController;
GraphController m_graphController;
AlternateEmptyViewController m_graphAlternateEmptyViewController;
StackViewController m_graphStackViewController;
ButtonRowController m_graphHeader;
OtherViewController m_otherViewController;
TabViewController m_tabViewController;
};
}
#endif

View File

@@ -1,6 +0,0 @@
GeometryApp = "Geometry"
GeometryAppCapital = "GEOMETRY"
AddFigure = "Ajouter une figure"
FigureType = "Type de figure"
DefinitionType = "Définition de la figure"
ParametersChoice = "Choix des paramètres"

View File

@@ -1,6 +0,0 @@
GeometryApp = "Geometry"
GeometryAppCapital = "GEOMETRY"
AddFigure = "Ajouter une figure"
FigureType = "Type de figure"
DefinitionType = "Définition de la figure"
ParametersChoice = "Choix des paramètres"

View File

@@ -1,6 +0,0 @@
GeometryApp = "Geometry"
GeometryAppCapital = "GEOMETRY"
AddFigure = "Ajouter une figure"
FigureType = "Type de figure"
DefinitionType = "Définition de la figure"
ParametersChoice = "Choix des paramètres"

View File

@@ -1,6 +0,0 @@
GeometryApp = "Geometry"
GeometryAppCapital = "GEOMETRY"
AddFigure = "Ajouter une figure"
FigureType = "Type de figure"
DefinitionType = "Définition de la figure"
ParametersChoice = "Choix des paramètres"

View File

@@ -1,6 +0,0 @@
GeometryApp = "Geometry"
GeometryAppCapital = "GEOMETRY"
AddFigure = "Ajouter une figure"
FigureType = "Type de figure"
DefinitionType = "Définition de la figure"
ParametersChoice = "Choix des paramètres"

View File

@@ -1,6 +0,0 @@
GeometryApp = "Geometry"
GeometryAppCapital = "GEOMETRY"
AddFigure = "Ajouter une figure"
FigureType = "Type de figure"
DefinitionType = "Définition de la figure"
ParametersChoice = "Choix des paramètres"

View File

@@ -1,6 +0,0 @@
GeometryApp = "Geometry"
GeometryAppCapital = "GEOMETRY"
AddFigure = "Ajouter une figure"
FigureType = "Type de figure"
DefinitionType = "Définition de la figure"
ParametersChoice = "Choix des paramètres"

View File

@@ -1,6 +0,0 @@
GeometryApp = "Geometry"
GeometryAppCapital = "GEOMETRY"
AddFigure = "Ajouter une figure"
FigureType = "Type de figure"
DefinitionType = "Définition de la figure"
ParametersChoice = "Choix des paramètres"

View File

@@ -1,24 +0,0 @@
FiguresTab = "Figures"
NoFigures = "Aucune figure à afficher"
OtherTab = "TODO"
Coordinates = "Coordonnées"
Middle = "Milieu"
VectorProject = "Projeté vectoriel"
OrthogonalProject = "Projeté orthogonal"
CartesianEquation = "Equation cartésienne"
LinearEquation = "Equation linéaire"
Points = "Points"
PointAndVector = "Point et vecteur"
Parallele = "Parallèle"
Perpendicular = "Perpendiculaire"
PointAndRadius = "Point et rayon"
Diameter = "Diamètre"
TwoPoints = "Deux points"
Segment = "Segment"
Angle = "Angle"
Area = "Surface"
Point = "Point"
Line = "Droite"
Circle = "Cercle"
Vector = "Vecteur"
Indicator = "Indicateur"

View File

@@ -1 +0,0 @@
#include "figure_store.h"

View File

@@ -1,14 +0,0 @@
#ifndef FIGURE__STORE__H
#define FIGURE__STORE__H
#include "../shared/expression_model_store.h"
namespace Geometry {
class FigureStore: Shared::ExpressionModelStore {
};
}
#endif

View File

@@ -1,27 +0,0 @@
#ifndef POINCARE_FIGURE_H
#define POINCARE_FIGURE_H
#include "figure_type.h"
using namespace Poincare;
namespace Geometry {
class FigureNode : public TreeNode {
public:
virtual size_t size() const override = 0;
virtual int numberOfChildren() const override { return 0; }
virtual FigureType type() const = 0;
virtual FigureDefinitionType definitionType() const = 0;
};
class Figure : public TreeHandle {
public:
Figure(const FigureNode * node) : TreeHandle(node) {}
};
}
#endif

View File

@@ -1,24 +0,0 @@
#ifndef GEOMETRY_FIGURE_TYPE_H
#define GEOMETRY_FIGURE_TYPE_H
namespace Geometry {
enum class FigureType {
None = 0, // Used to trigger assert in debug mode
Expression, // It's not a real figure type but we use it to build figures like points
Point,
Line,
Circle,
Vector,
Indicator
};
enum class FigureDefinitionType {
PointByCoordinates
};
}
#endif

View File

@@ -1,6 +0,0 @@
#ifndef FIGURES_H
#define FIGURES_H
#include "point_by_coordinates.h"
#endif

View File

@@ -1 +0,0 @@
#include "point.h"

View File

@@ -1,18 +0,0 @@
#ifndef GEOMETRY_POINT_H
#define GEOMETRY_POINT_H
#include "figure.h"
namespace Geometry {
class PointNode : public FigureNode {
virtual FigureType type() const override { return FigureType::Point; }
};
class Point : public Figure {
public:
Point(const PointNode * n) : Figure(n) {}
};
}
#endif

View File

@@ -1,31 +0,0 @@
#ifndef POINT_BY_COORDINATES_H
#define POINT_BY_COORDINATES_H
#include <poincare/expression.h>
#include "point.h"
namespace Geometry {
class PointByCoordinatesNode : public PointNode {
public:
virtual size_t size() const override { return sizeof(PointByCoordinatesNode); }
virtual int numberOfChildren() const override { return 2; }
virtual FigureDefinitionType definitionType() const override { return FigureDefinitionType::PointByCoordinates; }
#if POINCARE_TREE_LOG
void logNodeName(std::ostream & stream) const override {
stream << "PointByCoordinates";
}
#endif
};
class PointByCoordinates : public Figure {
public:
PointByCoordinates(const PointByCoordinatesNode * n) : Figure(n) {}
static PointByCoordinates Builder(Expression x, Expression y) { return TreeHandle::FixedArityBuilder<PointByCoordinates, PointByCoordinatesNode>({x, x}); }
static int numberOfParameters() { return 2; }
static FigureType parameterTypeAtIndex(int i) { return FigureType::Expression; }
};
}
#endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,15 +0,0 @@
#include "banner_view.h"
namespace Geometry {
BannerView::BannerView(
Responder * parentResponder,
InputEventHandlerDelegate * inputEventHandlerDelegate,
TextFieldDelegate * textFieldDelegate
) :
Shared::XYBannerView(parentResponder, inputEventHandlerDelegate, textFieldDelegate)
{
}
}

View File

@@ -1,15 +0,0 @@
#ifndef GEOMETRY_BANNER_VIEW_H
#define GEOMETRY_BANNER_VIEW_H
#include "../../shared/xy_banner_view.h"
namespace Geometry {
class BannerView : public Shared::XYBannerView {
public:
BannerView(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate);
};
}
#endif

View File

@@ -1,11 +0,0 @@
#include "graph_controller.h"
namespace Geometry {
GraphController::GraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, ButtonRowController * header, Shared::InteractiveCurveViewRange/*TODO -> Store*/ * store, Shared::CurveViewCursor * cursor, uint32_t * rangeVersion) :
InteractiveCurveViewController(parentResponder, inputEventHandlerDelegate, header, store, nullptr, cursor, rangeVersion)
{
/* WHEREIWAS: Now i must make the app launch again without crash, by replacing the multiples nullptr that I used... */
}
}

View File

@@ -1,33 +0,0 @@
#ifndef GRAPH_VIEW_CONTROLLER_H
#define GRAPH_VIEW_CONTROLLER_H
#include "../shared/interactive_curve_view_controller.h"
namespace Geometry {
class GraphController : public Shared::InteractiveCurveViewController {
public:
GraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, ButtonRowController * header, Shared::InteractiveCurveViewRange * store, Shared::CurveViewCursor * cursor, uint32_t * rangeVersion);
virtual Shared::InteractiveCurveViewRange * interactiveCurveViewRange() override { return nullptr; } //TOIMPLEMENT
virtual Shared::CurveView * curveView() override { return nullptr; } //TOIMPLEMENT
virtual void reloadBannerView() override { } //TOIMPLEMENT
virtual bool handleEnter() override { return false; } //TOIMPLEMENT
virtual void initCursorParameters() override { } //TOIMPLEMENT
virtual bool moveCursorVertically(int direction) override { return false; } //TOIMPLEMENT
virtual uint32_t rangeVersion() override { return 0; } //TOIMPLEMENT
virtual bool cursorMatchesModel() override { return false; } //TOIMPLEMENT
virtual Poincare::Coordinate2D<double> xyValues(int curveIndex, double t, Poincare::Context * context) const override { return Poincare::Coordinate2D<double>(0, 0); } //TOIMPLEMENT
virtual bool closestCurveIndexIsSuitable(int newIndex, int currentIndex) const override { return false; }
virtual int selectedCurveIndex() const override { return 0; }
virtual int numberOfCurves() const override { return 0; }
/* AlternateEmptyViewDefaultDelegate */
virtual bool isEmpty() const override { return false; }
virtual I18n::Message emptyMessage() override { return I18n::Message::NoFigures; }
private:
};
}
#endif

View File

@@ -1,147 +0,0 @@
#include "figure_type_controller.h"
#include "../figures/figures.h"
namespace Geometry {
static constexpr I18n::Message sPointDefinitionsMessages[] = {
I18n::Message::Coordinates,
I18n::Message::Middle,
I18n::Message::VectorProject,
I18n::Message::OrthogonalProject
};
static const uint8_t sPointDefinitionsMessagesCount = sizeof(sPointDefinitionsMessages) / sizeof(I18n::Message);
static constexpr I18n::Message sLineDefinitionMessages[] = {
I18n::Message::CartesianEquation,
I18n::Message::LinearEquation,
I18n::Message::Points,
I18n::Message::PointAndVector,
I18n::Message::Parallele,
I18n::Message::Perpendicular
};
static const uint8_t sLineDefinitionsMessagesCount = sizeof(sLineDefinitionMessages) / sizeof(I18n::Message);
static constexpr I18n::Message sCircleDefinitionsMessages[] = {
I18n::Message::PointAndRadius,
I18n::Message::Diameter,
I18n::Message::CartesianEquation,
};
static const uint8_t sCircleDefinitionsMessagesCount = sizeof(sCircleDefinitionsMessages) / sizeof(I18n::Message);
static constexpr I18n::Message sVectorDefinitionsMessages[] = {
I18n::Message::Coordinates,
I18n::Message::TwoPoints
};
static const uint8_t sVectorDefinitionsMessagesCount = sizeof(sVectorDefinitionsMessages) / sizeof(I18n::Message);
static constexpr I18n::Message sIndicatorDefinitionsMessages[] = {
I18n::Message::Segment,
I18n::Message::Angle,
I18n::Message::Area,
};
static const uint8_t sIndicatorDefinitionsMessagesCount = sizeof(sIndicatorDefinitionsMessages) / sizeof(I18n::Message);
DefinitionTypeController::DefinitionTypeController(Responder * parentResponder, FigureParametersController * parametersController):
ViewController(parentResponder),
m_lastSelectedRow(0),
m_selectableTableView(this),
m_messages(nullptr),
m_figureType(FigureType::None),
m_parametersController(parametersController)
{
for (int i = 0; i < k_numberOfCells; i ++) {
m_cells[i].setMessageFont(KDFont::LargeFont);
}
}
void DefinitionTypeController::viewWillAppear() {
assert(m_figureType != FigureType::None && m_messages != nullptr);
selectRow(m_lastSelectedRow);
m_selectableTableView.reloadData(); // We reload the cell of the table view to update their message
}
void DefinitionTypeController::didBecomeFirstResponder() {
//App::app()->snapshot()->setActivePage(App::Snapshot::Page::Distribution);
Container::activeApp()->setFirstResponder(&m_selectableTableView);
}
bool DefinitionTypeController::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) {
m_lastSelectedRow = selectedRow();
StackViewController * stack = static_cast<StackViewController *>(parentResponder());
m_parametersController->setParametersInfoFunctions(PointByCoordinates::numberOfParameters, PointByCoordinates::parameterTypeAtIndex);
stack->push(m_parametersController);
return true;
}
if (event == Ion::Events::Back) {
StackViewController * stack = static_cast<StackViewController *>(parentResponder());
stack->pop();
return true;
}
return false;
}
HighlightCell * DefinitionTypeController::reusableCell(int index) {
assert(index >= 0);
assert(index < k_numberOfCells);
return &m_cells[index];
}
void DefinitionTypeController::willDisplayCellForIndex(HighlightCell * cell, int index) {
MessageTableCellWithChevron * myCell = (MessageTableCellWithChevron *)cell;
myCell->setMessage(m_messages[index]);
}
int DefinitionTypeController::numberOfRows() const {
switch (m_figureType) {
case FigureType::Point:
return sPointDefinitionsMessagesCount;
break;
case FigureType::Line:
return sLineDefinitionsMessagesCount;
break;
case FigureType::Circle:
return sCircleDefinitionsMessagesCount;
break;
case FigureType::Vector:
return sVectorDefinitionsMessagesCount;
break;
case FigureType::Indicator:
return sIndicatorDefinitionsMessagesCount;
break;
default:
assert(false);
return 0;
}
}
void DefinitionTypeController::setFigureType(FigureType figureType) {
m_figureType = figureType;
switch (m_figureType) {
case FigureType::Point:
m_messages = sPointDefinitionsMessages;
break;
case FigureType::Line:
m_messages = sLineDefinitionMessages;
break;
case FigureType::Circle:
m_messages = sCircleDefinitionsMessages;
break;
case FigureType::Vector:
m_messages = sVectorDefinitionsMessages;
break;
case FigureType::Indicator:
m_messages = sIndicatorDefinitionsMessages;
break;
default:
assert(false);
break;
}
}
}

View File

@@ -1,53 +0,0 @@
#ifndef GEOMETRY_DEFINITION_TYPE_CONTROLLER_H
#define GEOMETRY_DEFINITION_TYPE_CONTROLLER_H
#include <escher.h>
#include "apps/i18n.h"
#include "../figures/figure_type.h"
#include "figure_parameters_controller.h"
namespace Geometry {
/**
* \brief DefinitionTypeController is a controller to choose how the figure is defined
*/
class DefinitionTypeController : public ViewController, public SimpleListViewDataSource, public SelectableTableViewDataSource {
public:
DefinitionTypeController(Responder * parentResponder, FigureParametersController * parametersController);
/* ViewController */
View * view() override { return &m_selectableTableView; }
// We want to avoid using half of the screen just for titles
virtual DisplayParameter displayParameter() override { return DisplayParameter::DoNotShowOwnTitle; }
const char * title() override { return I18n::translate(I18n::Message::DefinitionType); }
/* Responder */
bool handleEvent(Ion::Events::Event event) override;
/* ViewController */
void didBecomeFirstResponder() override;
void viewWillAppear() override;
TELEMETRY_ID("FigureType");
/* SelectableTableViewDataSource */
int numberOfRows() const override;
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
KDCoordinate cellHeight() override { return k_cellHeight; }
HighlightCell * reusableCell(int index) override;
int reusableCellCount() const override { return k_numberOfCells; }
/* Customs methods */
void setFigureType(FigureType type);
private:
constexpr static KDCoordinate k_cellHeight = Metric::ParameterCellHeight;
constexpr static int k_numberOfCells = 6;
int m_lastSelectedRow;
MessageTableCellWithChevron m_cells[k_numberOfCells];
SelectableTableView m_selectableTableView;
const I18n::Message * m_messages;
FigureType m_figureType;
FigureParametersController * m_parametersController;
};
}
#endif

View File

@@ -1,114 +0,0 @@
#include "figure_parameters_controller.h"
#include "../app.h"
namespace Geometry {
FigureParametersController::FigureParametersController(Responder * parentResponder):
ViewController(parentResponder),
m_lastSelectedRow(0),
m_selectableTableView(this),
m_okButton(&m_selectableTableView, I18n::Message::Ok, Invocation([](void * context, void * sender) {
FigureParametersController * parameterController = (FigureParametersController *) context;
parameterController->returnToMenu();
return true;
}, this))
{
for (int i = 0; i < k_choiceCells; i++) {
m_choicesCells[i].setParentResponder(&m_selectableTableView);
}
for (int i = 0; i < k_textCells; i++) {
m_textCells[i].setParentResponder(&m_selectableTableView);
m_textCells[i].textField()->setDelegates(this, this);
}
}
void FigureParametersController::setParametersInfoFunctions(NumberOfParametersFunction numberOfParametersFunction, TypeOfParametersAtIndexFunction typeOfParametersAtIndexFunction) {
m_numberOfParametersFunction = numberOfParametersFunction;
m_typeOfParametersAtIndexFunction = typeOfParametersAtIndexFunction;
}
void FigureParametersController::didBecomeFirstResponder() {
Container::activeApp()->setFirstResponder(&m_selectableTableView);
}
void FigureParametersController::viewWillAppear() {
selectRow(m_lastSelectedRow);
}
void FigureParametersController::returnToMenu() {
StackViewController * stack = static_cast<StackViewController *>(parentResponder());
stack->pop();
stack->pop();
stack->pop();
}
/* ListViewDataSource */
int FigureParametersController::typeAtLocation(int i, int j) {
if (j == m_numberOfParametersFunction()) {
return 0; // It's equivalent to "None", so we can use it for button cell
}
return (int) m_typeOfParametersAtIndexFunction(j);
}
int FigureParametersController::reusableCellCount(int type) {
if (type == 0) {
return 1;
}
return type == (int) FigureType::Expression ? k_textCells: k_choiceCells;
}
HighlightCell * FigureParametersController::reusableCell(int index, int type) {
if (type == 0) {
return &m_okButton;
}
if (type == (int) FigureType::Expression) {
return &m_textCells[index];
}
return &m_choicesCells[index];
}
int FigureParametersController::numberOfRows() const {
return m_numberOfParametersFunction() + 1;
}
KDCoordinate FigureParametersController::rowHeight(int j) {
if (j == numberOfRows()-1) {
return Metric::ParameterCellHeight+k_buttonMargin;
}
return Metric::ParameterCellHeight;
}
KDCoordinate FigureParametersController::cumulatedHeightFromIndex(int j) {
if (j == numberOfRows()) {
return j*Metric::ParameterCellHeight+k_buttonMargin;
}
return Metric::ParameterCellHeight*j;
}
int FigureParametersController::indexFromCumulatedHeight(KDCoordinate offsetY) {
return (offsetY - 1) / Metric::ParameterCellHeight;
}
void FigureParametersController::willDisplayCellForIndex(HighlightCell * cell, int index) {
}
bool FigureParametersController::textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) {
return (event == Ion::Events::Down && selectedRow() < numberOfRows()-1)
|| (event == Ion::Events::Up && selectedRow() > 0)
|| TextFieldDelegate::textFieldShouldFinishEditing(textField, event);
}
bool FigureParametersController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) {
m_selectableTableView.reloadCellAtLocation(0, selectedRow());
m_selectableTableView.reloadData();
textField->setText(text);
if (event == Ion::Events::EXE || event == Ion::Events::OK) {
m_selectableTableView.selectCellAtLocation(selectedColumn(), selectedRow() + 1);
} else {
m_selectableTableView.handleEvent(event);
}
return true;
}
}

View File

@@ -1,64 +0,0 @@
#ifndef GEOMETRY_FIGURE_PARAMETERS_CONTROLLER_H
#define GEOMETRY_FIGURE_PARAMETERS_CONTROLLER_H
#include <escher.h>
#include "apps/i18n.h"
#include "message_table_cell_with_selector.h"
#include "../figures/figure.h"
#include "../../shared/parameter_text_field_delegate.h"
#include "../../shared/input_event_handler_delegate.h"
#include "../../shared/button_with_separator.h"
namespace Geometry {
typedef int (*NumberOfParametersFunction)();
typedef FigureType (*TypeOfParametersAtIndexFunction)(int);
/**
* \brief Controller returning the parameter choosen by the user to define the figure
*/
class FigureParametersController : public ViewController, public ListViewDataSource, public SelectableTableViewDataSource, public Shared::ParameterTextFieldDelegate, public Shared::InputEventHandlerDelegate {
public:
FigureParametersController(Responder * parentResponder);
void setParametersInfoFunctions(NumberOfParametersFunction numberOfParametersFunction, TypeOfParametersAtIndexFunction typeOfParametersAtIndexFunction);
void returnToMenu();
/* ViewController */
const char * title() override { return I18n::translate(I18n::Message::ParametersChoice); }
// We want to avoid using half of the screen just for titles
virtual DisplayParameter displayParameter() override { return DisplayParameter::DoNotShowOwnTitle; }
View * view() override { return &m_selectableTableView; };
/* Responder */
void didBecomeFirstResponder() override;
void viewWillAppear() override;
/* ListViewDataSource */
int typeAtLocation(int i, int j) override;
int reusableCellCount(int type) override; // TO IMPLEMENT
HighlightCell * reusableCell(int index, int type) override;
int numberOfRows() const override;
KDCoordinate rowHeight(int j) override;
KDCoordinate cumulatedHeightFromIndex(int j) override;
int indexFromCumulatedHeight(KDCoordinate offsetY) override;
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
/* InputEventHandlerDelegate */
bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override;
bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override;
private:
SelectableTableView m_selectableTableView;
constexpr static int k_textCells = 2;
constexpr static int k_choiceCells = 3;
constexpr static int k_buttonMargin = 6;
int m_lastSelectedRow;
MessageTableCellWithEditableText m_textCells[k_textCells];
MessageTableCellWithSelector m_choicesCells[k_choiceCells];
ButtonWithSeparator m_okButton;
NumberOfParametersFunction m_numberOfParametersFunction;
TypeOfParametersAtIndexFunction m_typeOfParametersAtIndexFunction;
};
}
#endif

View File

@@ -1,70 +0,0 @@
#include "figure_type_controller.h"
#include "apps/i18n.h"
namespace Geometry {
static FigureType sTypes[] = {
FigureType::Point,
FigureType::Line,
FigureType::Circle,
FigureType::Vector,
FigureType::Indicator
};
static I18n::Message sMessages[] = {
I18n::Message::Point,
I18n::Message::Line,
I18n::Message::Circle,
I18n::Message::Vector,
I18n::Message::Indicator
};
FigureTypeController::FigureTypeController(Responder * parentResponder, DefinitionTypeController * definitionTypeController) :
ViewController(parentResponder),
m_lastSelectedRow(0),
m_selectableTableView(this),
m_definitionTypeController(definitionTypeController),
m_messages(sMessages)
{
for (int i = 0; i < k_numberOfCells; i ++) {
m_cells[i].setMessageFont(KDFont::LargeFont);
}
}
void FigureTypeController::viewWillAppear() {
selectRow(m_lastSelectedRow);
}
void FigureTypeController::didBecomeFirstResponder() {
//App::app()->snapshot()->setActivePage(App::Snapshot::Page::Distribution);
Container::activeApp()->setFirstResponder(&m_selectableTableView);
}
bool FigureTypeController::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) {
m_lastSelectedRow = selectedRow();
StackViewController * stack = static_cast<StackViewController *>(parentResponder());
m_definitionTypeController->setFigureType(sTypes[selectedRow()]);
stack->push(m_definitionTypeController);
return true;
}
if (event == Ion::Events::Back ) {
StackViewController * stack = static_cast<StackViewController *>(parentResponder());
stack->pop();
return true;
}
return false;
}
HighlightCell * FigureTypeController::reusableCell(int index) {
assert(index >= 0);
assert(index < k_numberOfCells);
return &m_cells[index];
}
void FigureTypeController::willDisplayCellForIndex(HighlightCell * cell, int index) {
MessageTableCellWithChevron * myCell = (MessageTableCellWithChevron *)cell;
myCell->setMessage(m_messages[index]);
}
}

View File

@@ -1,49 +0,0 @@
#ifndef GEOMETRY_FIGURE_TYPE_CONTROLLER_H
#define GEOMETRY_FIGURE_TYPE_CONTROLLER_H
#include <escher.h>
#include "definition_type_controller.h"
namespace Geometry {
/**
* \brief FigureTypeController is a controller that is used to select the type of
* figure to be created.
*/
class FigureTypeController : public ViewController, public SimpleListViewDataSource, public SelectableTableViewDataSource {
public:
FigureTypeController(Responder * parentResponder, DefinitionTypeController * definitionController);
/* ViewController */
View * view() override { return &m_selectableTableView; }
// We want to avoid using half of the screen just for titles
virtual DisplayParameter displayParameter() override { return DisplayParameter::DoNotShowOwnTitle; }
const char * title() override { return I18n::translate(I18n::Message::FigureType); }
/* Responder */
bool handleEvent(Ion::Events::Event event) override;
void didBecomeFirstResponder() override;
/* ViewController */
void viewWillAppear() override;
TELEMETRY_ID("FigureType");
/* TableViewDataSource */
int numberOfRows() const override { return k_numberOfRows; }
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
KDCoordinate cellHeight() override { return k_cellHeight; }
HighlightCell * reusableCell(int index) override;
int reusableCellCount() const override { return k_numberOfCells; }
private:
constexpr static KDCoordinate k_cellHeight = Metric::ParameterCellHeight;
constexpr static int k_numberOfCells = 5;
constexpr static int k_numberOfRows = 5;
int m_lastSelectedRow;
MessageTableCellWithChevron m_cells[k_numberOfCells];
SelectableTableView m_selectableTableView;
DefinitionTypeController * m_definitionTypeController;
I18n::Message * m_messages;
};
}
#endif

View File

@@ -1,77 +0,0 @@
#include "figures_controller.h"
#include "definition_type_controller.h"
#include <apps/i18n.h>
namespace Geometry {
FiguresController::FiguresController(Responder * parentResponder):
ViewController(parentResponder),
m_selectableTableView(this, this, this, this),
m_addFigureCell(),
m_emptyCell(),
m_figureTypeController(this, &m_definitionTypeController),
m_definitionTypeController(&m_figureTypeController, &m_parametersController),
m_parametersController(&m_definitionTypeController)
{
m_addFigureCell.setMessage(I18n::Message::AddFigure);
}
bool FiguresController::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::OK || event == Ion::Events::EXE) {
if (isAddFigureRow(selectedRow())) {
StackViewController * stack = static_cast<StackViewController *>(parentResponder());
stack->push(&m_figureTypeController);
return true;
}
}
if (event == Ion::Events::Up && selectedRow() == 0) {
m_selectableTableView.deselectTable();
assert(selectedRow() == -1);
Container::activeApp()->setFirstResponder(parentResponder()->parentResponder());
return true;
}
return false;
}
void FiguresController::didBecomeFirstResponder() {
Container::activeApp()->setFirstResponder(&m_selectableTableView);
}
HighlightCell * FiguresController::reusableCell(int index, int type) {
assert(index >= 0);
if (type == 2) {
return &m_emptyCell;
}
return &m_addFigureCell;
}
void FiguresController::willDisplayCellAtLocation(HighlightCell * cell, int i, int j) {
if (i == 0) {
return;
}
EvenOddCell * myCell = (EvenOddCell *)cell;
myCell->setEven(j%2 == 0);
myCell->setHighlighted(i == selectedColumn() && j == selectedRow());
myCell->reloadCell();
}
bool FiguresController::isAddFigureRow(int j) {
return j == 0;
}
int FiguresController::reusableCellCount(int type) {
if (type > 1) {
return 1;
}
return 0;
}
int FiguresController::typeAtLocation(int i, int j) {
if (isAddFigureRow(j)) {
return i + 2;
}
return i;
}
}

View File

@@ -1,47 +0,0 @@
#ifndef FIGURES_CONTROLLER_H
#define FIGURES_CONTROLLER_H
#include <escher.h>
#include "figure_type_controller.h"
namespace Geometry
{
/**
* \brief FiguresController is a controller to show the list of the figures
*/
class FiguresController : public ViewController, public SelectableTableViewDataSource, public SelectableTableViewDelegate, public TableViewDataSource {
public:
FiguresController(Responder * parentResponder);
/* ViewController */
View * view() override { return &m_selectableTableView; }
const char * title() override { return I18n::translate(I18n::Message::FiguresTab); }
virtual DisplayParameter displayParameter() override { return DisplayParameter::DoNotShowOwnTitle; }
/* Responder */
bool handleEvent(Ion::Events::Event event) override; // TO IMPLEMENT
void didBecomeFirstResponder() override;
/* TableView */
int numberOfRows() const override { return 1; } // TO IMPLEMENT
int numberOfColumns() const override { return 2; } // TO IMPLEMENT
KDCoordinate columnWidth(int i) { return i == 0 ? 50 : 150; } // TO IMPLEMENT
KDCoordinate rowHeight(int j) { return 50; } // TO IMPLEMENT
HighlightCell * reusableCell(int index, int type); // TO IMPLEMENT
void willDisplayCellAtLocation(HighlightCell * cell, int i, int j) override; // TO IMPLEMENT
int reusableCellCount(int type);
int typeAtLocation(int i, int j); // TO IMPLEMENT
private:
/* Customs methods */
bool isAddFigureRow(int j); // TO IMPLEMENT
SelectableTableView m_selectableTableView;
EvenOddMessageTextCell m_addFigureCell;
EvenOddCell m_emptyCell;
FigureTypeController m_figureTypeController;
DefinitionTypeController m_definitionTypeController;
FigureParametersController m_parametersController;
};
}
#endif

View File

@@ -1,24 +0,0 @@
#include "message_table_cell_with_selector.h"
#include <escher/container.h>
namespace Geometry {
MessageTableCellWithSelector::MessageTableCellWithSelector(ToolboxMessageTree * root, const KDFont * font) :
Responder(nullptr),
MessageTableCell((I18n::Message)0, font),
m_objectsRoot(root),
m_selectedMessage(nullptr),
m_toolbox(this)
{
}
bool MessageTableCellWithSelector::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::OK || event == Ion::Events::EXE) {
Container::activeApp()->displayModalViewController(&m_toolbox, 0.f, 0.f, Metric::PopUpTopMargin, Metric::PopUpLeftMargin, 0, Metric::PopUpRightMargin);
return true;
}
return false;
}
}

View File

@@ -1,26 +0,0 @@
#ifndef ESHER_MESSAGE_TABLE_CELL_WITH_OBJECT_SELECTOR_H_
#define ESHER_MESSAGE_TABLE_CELL_WITH_OBJECT_SELECTOR_H_
#include <escher/message_table_cell_with_buffer.h>
#include <escher/toolbox_message_tree.h>
#include "objects_controller.h"
namespace Geometry {
class MessageTableCellWithSelector : public Responder, public MessageTableCell {
public:
MessageTableCellWithSelector(ToolboxMessageTree * root = nullptr, const KDFont * font = KDFont::SmallFont);
ToolboxMessageTree * getSelectedMessage() const { return m_selectedMessage; };
bool handleEvent(Ion::Events::Event event);
Responder * responder() override {
return this;
}
private:
ToolboxMessageTree * m_objectsRoot;
ToolboxMessageTree * m_selectedMessage;
ObjectsController m_toolbox;
};
}
#endif

View File

@@ -1,35 +0,0 @@
#include "objects_controller.h"
namespace Geometry {
ObjectsController::ObjectsController(Responder * responder) :
NestedMenuController(this)
{
}
int ObjectsController::numberOfRows() const {
return 0;
}
int ObjectsController::reusableCellCount(int type) {
return 0;
}
int ObjectsController::typeAtLocation(int i, int j) {
return 0;
}
bool ObjectsController::selectLeaf(int type) {
return false;
}
HighlightCell * ObjectsController::leafCellAtIndex(int index) {
return nullptr;
}
HighlightCell * ObjectsController::nodeCellAtIndex(int index) {
return nullptr;
}
}

View File

@@ -1,21 +0,0 @@
#ifndef GEOMETRY_OBJECTS_CONTROLLER_H
#define GEOMETRY_OBJECTS_CONTROLLER_H
#include <escher/nested_menu_controller.h>
namespace Geometry {
class ObjectsController : public NestedMenuController {
public:
ObjectsController(Responder * parentResponder);
virtual int numberOfRows() const override;
virtual int reusableCellCount(int type) override;
virtual int typeAtLocation(int i, int j) override;
virtual bool selectLeaf(int selectedRow) override;
virtual HighlightCell * leafCellAtIndex(int index) override;
virtual HighlightCell * nodeCellAtIndex(int index) override;
};
}
#endif

View File

@@ -1,16 +0,0 @@
#ifndef OTHER_VIEW_CONTROLLER_H
#define OTHER_VIEW_CONTROLLER_H
namespace Geometry {
class OtherViewController : public ViewController {
public:
OtherViewController(Responder * parentResponder):
ViewController(parentResponder) {}
View * view() override { return nullptr; }
const char * title() override { return I18n::translate(I18n::Message::OtherTab); }
};
}
#endif

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