Compare commits

..

36 Commits

Author SHA1 Message Date
Laury
352cf39602 Merge overrightarrow 2021-11-11 20:21:44 +01:00
Mino1289
eed6683c74 Merge pull request #3 from Mino1289/upsilon-ref-latex
[apps/reader] Refactoring the LaTeX parser
2021-11-07 20:54:59 +01:00
Mino1289
9d5904396d [apps/reader] Fix rendering bug 2021-11-07 20:52:21 +01:00
Mino1289
7dec23dd91 Merge pull request #4 from devdl11/upsilon-ref-latex
[apps/reader] Fixing LD Error
2021-11-07 17:40:34 +01:00
dl11
e5fb5f390e LD Simple Fix 2021-11-07 17:05:55 +01:00
Mino1289
e3887ca077 [apps/reader] Refactoring the parser 2021-11-07 15:14:00 +01:00
Mino1289
46a30a6061 [kandinsky/font] Simplify including code_points 2021-11-05 16:49:04 +01:00
Mino1289
32ccd8530c [kandinsky/font build] Using all font only when reader app is defined, else it's the classic font 2021-11-04 23:59:18 +01:00
Mino1289
6ff8b007be Update apps/reader/README.md
Co-authored-by: Lauryy06 <80424145+Lauryy06@users.noreply.github.com>
2021-11-04 22:08:45 +01:00
Mino1289
0834cbd054 [apps/reader] Ajout d'une documentation (md & html) 2021-11-01 18:16:18 +01:00
Mino1289
a138ecaa9e [apps/reader] Ajout d'une documentation (md & html) 2021-11-01 18:14:55 +01:00
Mino1289
f8e6ee64ef [apps/reader] Changement de nom de certaines lettres grecs, comme LaTeX 2021-11-01 17:50:56 +01:00
Mino1289
5fbc7feaa1 [apps/reader] Ajout de \leq et \neq 2021-10-31 23:18:32 +01:00
Mino1289
1a2a61a43c [apps/reader build] Fix n0110 CI Merci @RedGl0w pour l'aide :) 2021-10-30 18:54:36 +02:00
Mino1289
25766967e2 [apps/reader] Add symbols and Arrows 2021-10-30 17:36:55 +02:00
Mino1289
52ac8e2acb [apps/reader] Changement du FLAG pour éviter de compiler certains caractères sans l'app reader 2021-10-30 17:34:53 +02:00
Mino1289
8cc09405e1 [apps/reader kandinsky/fonts] Remove useless font if reader app is not compiled 2021-10-29 15:24:44 +02:00
Mino1289
efdf2a379f [apps/reader] Ajout de toute les lettres grecs Majuscule 2021-10-27 21:46:54 +02:00
Laury
26496fbf00 [reader] Added ovverightarrow in parser and fix a bug in reader 2021-10-27 15:39:53 +02:00
Mino1289
668641ce95 [apps/reader] Toutes les lettres grecs en minuscule 2021-10-26 22:33:08 +02:00
Mino1289
72dfb76cc8 [apps/reader] Add mathematical symbols to TexParser 2021-10-26 20:07:34 +02:00
Mino1289
0dafa539df [apps/reader] TexParser fixed 2021-10-26 17:19:23 +02:00
Mino1289
36c984c73b [apps/reader] Modification du caractère d'erreur 2021-10-25 22:27:23 +02:00
Mino1289
fd5fba07e5 [apps/reader] Meilleur builder pour les symbols, mais ne marche pas 2021-10-24 15:15:59 +02:00
Mino1289
6e6ba6a985 [kandinsky] Extract lots of useful symbols of font file 2021-10-24 00:11:19 +02:00
Mino1289
57078755a3 [apps/reader] Support de \pi & \theta (compile mais n'affiche pas dans reader) 2021-10-23 23:28:02 +02:00
Lauryy06
710930d8e1 Merge branch 'upsilon-dev-latex' into upsilon-dev-latex 2021-10-23 13:35:52 +02:00
Laury
5c9bccdd99 [reader] Continuation of Latex parser 2021-10-23 00:21:28 +02:00
Mino1289
6ffb70e513 [apps/reader] oublie d'un ; 2021-10-23 00:09:46 +02:00
Mino1289
b42d4197c9 [apps/code] fix et réorganisation du fichier (un peu) 2021-10-23 00:07:19 +02:00
Mino1289
17be5934e0 [apps/reader] Ajout du support de \sqrt[n]{x} dans le parser LaTeX 2021-10-22 23:44:10 +02:00
Mino1289
18e7926500 Finish merging (unsolved conflicts) 2021-10-22 22:57:45 +02:00
Mino1289
559d5d26dd Merge branch 'upsilon-dev-latex' of https://github.com/Mino1289/Upsilon into upsilon-dev-latex 2021-10-22 22:55:50 +02:00
Laury
89c08acc7f [reader] Fix bug in Latex handling 2021-10-22 22:37:17 +02:00
Mino1289
04cf7bb0bf [apps/reader] Changing lot of if/else if for a switch statement 2021-10-22 22:09:57 +02:00
Laury
73f2a7ecac [reader] Foundation of latex handling 2021-10-22 21:23:35 +02:00
875 changed files with 8801 additions and 28287 deletions

View File

@@ -1,6 +1,6 @@
---
name: Bug report
about: Upsilon is not working like it should? Let us know!
about: Omega is not working like it should? Let us know!
title: ''
labels: 'Status: Triage, Type: Bug'
assignees: ''
@@ -23,7 +23,5 @@ A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**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 commit: [settings > about > click one time on epsilon version]
**Desktop (please complete the following information):**
- Omega Version: [go to settings > about > Omega Version and type the version here]

View File

@@ -1,6 +1,6 @@
---
name: Feature request
about: Suggest an idea for Upsilon
about: Suggest an idea for Omega
title: ''
labels: 'Status: Triage, Type: Feature'
assignees: ''

View File

@@ -0,0 +1,28 @@
---
name: OMEGA BETA ONLY - Bug report
about: Omega 1.21 is not working like it should? Let us know!
title: "[BETA-1.21] …"
labels: 'Status: Triage, Type: Bug'
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- Omega Version: [go to settings > about > Omega Version and type the version here]
- Discord username: ..........#....

View File

@@ -1,6 +1,6 @@
---
name: Problems during installation
about: Need help to install Upsilon?
about: Need help to install Omega?
title: ''
labels: 'Status: Triage, Type: Installation issue'
assignees: ''
@@ -16,4 +16,4 @@ Copy/paste the logs here (If you have some)
```
**Environment**
- Upsilon Version: {go to settings > about > Upsilon Version and type the version here}
- Omega Version: {go to settings > about > Omega Version and type the version here}

View File

@@ -17,6 +17,7 @@ on:
description: 'Run 3DS tests'
required: true
default: 'no'
jobs:
nintendo_3ds:
if: github.event.inputs.trigger3DS == 'yes'
@@ -49,18 +50,6 @@ jobs:
with:
submodules: 'recursive'
- 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
with:
name: epsilon-android.apk
@@ -102,18 +91,6 @@ jobs:
- run: mv output/release/device/n0100/flasher.light.bin final-output/flasher.light.bin
- run: find final-output/ -type f -exec bash -c "shasum -a 256 -b {} > {}.sha256" \;
- run: tar cvfz binpack-n0100.tgz final-output/*
- 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
with:
name: epsilon-binpack-n0100.tgz
@@ -132,49 +109,14 @@ jobs:
- run: make -j2 epsilon.onboarding.beta.dfu
- run: make -j2 flasher.light.dfu
- run: make -j2 flasher.verbose.dfu
# We don't need bench as it is used only in factory
# - run: make -j2 bench.ram.dfu
# - run: make -j2 bench.flash.dfu
- run: make -j2 bench.ram.dfu
- run: make -j2 bench.flash.dfu
- run: make -j2 binpack
- run: cp output/release/device/n0110/binpack-n0110-`git rev-parse HEAD | head -c 7`.tgz output/release/device/n0110/binpack-n0110.tgz
- 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
with:
name: epsilon-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:
runs-on: windows-latest
defaults:
@@ -189,18 +131,6 @@ jobs:
- run: make -j2 PLATFORM=simulator
- run: make -j2 PLATFORM=simulator test.exe
- 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
with:
name: epsilon-windows.exe
@@ -210,25 +140,13 @@ jobs:
steps:
- uses: numworks/setup-emscripten@v1
with:
sdk: 1.40.1
sdk: latest-upstream
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- run: make -j2 PLATFORM=simulator TARGET=web
- run: make -j2 PLATFORM=simulator TARGET=web test.js
- 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
with:
name: epsilon-web.zip
@@ -243,18 +161,6 @@ jobs:
- run: make -j2 PLATFORM=simulator
- run: make -j2 PLATFORM=simulator test.bin
- 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
with:
name: epsilon-linux.bin

2
.gitmodules vendored
View File

@@ -1,6 +1,6 @@
[submodule "apps/rpn"]
path = apps/rpn
url = https://github.com/Lauryy06/Upsilon-RPN.git
url = https://github.com/Omega-Numworks/Omega-RPN.git
[submodule "apps/atomic"]
path = apps/atomic
url = https://github.com/Lauryy06/atomic

View File

@@ -27,18 +27,10 @@ ifeq (${MODEL}, n0100)
endif
endif
ifeq ($(filter reader,$(apps_list)),)
HAS_READER := 1
endif
ifeq (${MODEL}, n0110)
apps_list = ${EPSILON_APPS}
else
ifeq (${MODEL},bootloader)
apps_list = ${EPSILON_APPS}
else
apps_list = $(foreach i, ${EPSILON_APPS}, $(if $(filter external, $(i)),,$(i)))
endif
apps_list = $(foreach i, ${EPSILON_APPS}, $(if $(filter external, $(i)),,$(i)))
endif
ifdef FORCE_EXTERNAL
@@ -109,7 +101,7 @@ print-%:
@echo $*\'s origin is $(origin $*)
# Since we're building out-of-tree, we need to make sure the output directories
# are created, otherwise the recipes will fail (e.g. gcc will fail to create
# are created, otherwise the receipes will fail (e.g. gcc will fail to create
# "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
# rid of them upon completion (and fail, since those folders won't be empty).
@@ -141,7 +133,6 @@ include poincare/Makefile
include python/Makefile
include escher/Makefile
# Executable Makefiles
include bootloader/Makefile
include apps/Makefile
include build/struct_layout/Makefile
include build/scenario/Makefile
@@ -214,13 +205,3 @@ clean_run: cleanandcompile
.PHONY: run
run: compile
${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://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/>
<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>
<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>
</p>
> Don't understand french ? speak english ? here's the [english README](./README.md) !
@@ -25,276 +25,72 @@ Upsilon est un fork d'Omega, un fork d'Epsilon, l'OS de Numworks tournant sur le
## 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
*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*
*A l'heure actuelle, seule l'installation manuelle est possible.*
### 1. Installation du SDK
<br>
Tout d'abord, suivez **la première étape** [ici](https://www.numworks.com/resources/engineering/software/build/), puis :
<details>
<summary><b>Modèle n0100</b></summary>
<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:
(note : vous pouvez changer `EPSILON_I18N=fr` en `en`, `nl`, `pt`, `it`, `de`, `es` ou `hu`).
```bash
git clone --recursive https://github.com/Lauryy06/Upsilon.git
cd Upsilon
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
git checkout omega-master
make MODEL=n0100 clean
make MODEL=n0100 EPSILON_I18N=en OMEGA_USERNAME="{Votre nom, maximum 15 caractères}" -j4
```
Maintenant, lancez soit:
```bash
make MODEL=n0100 EPSILON_I18N=fr OMEGA_USERNAME="{Votre nom ici, 15 caractères max}" -j4
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.
<br>
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/).
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>
<summary><b>Model n0110</b></summary>
<summary><b>Modèle n0110</b></summary>
```bash
git clone --recursive https://github.com/Lauryy06/Upsilon.git
cd Upsilon
git checkout omega-master
make clean
make OMEGA_USERNAME="{Votre nom, maximum 15 caractères}" -j4
```
Maintenant, lancez soit:
```bash
make OMEGA_USERNAME="{Votre nom ici, 15 caractères max}" -j4
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.
<br>
soit:
```bash
make 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/).
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>
<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/)).
<summary><b>Simulateur web</b></summary>
```bash
git clone --recursive https://github.com/Lauryy06/Upsilon.git
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
```
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>
<summary><b>Simulateur web</b></summary>
D'abord, installez emsdk :
```bash
@@ -308,41 +104,40 @@ source emsdk_env.sh
Puis, compilez Upsilon :
```bash
git clone --recursive https://github.com/Lauryy06/Upsilon.git
cd Upsilon
git checkout omega-master
make clean
make PLATFORM=simulator TARGET=web OMEGA_USERNAME="{Votre nom, maximum 15 caractères}" -j4
make PLATFORM=simulator TARGET=web OMEGA_USERNAME="{Votre nom ici, 15 caractères max}" -j4
```
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>
<summary><b>Simulateur pour 3DS</b></summary>
Il vous faut devkitPro et devkitARM installés et dans votre path (les instructions sont [ici](https://devkitpro.org/wiki/Getting_Started))
<summary><b>Simulateur 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))
```bash
git clone --recursive https://github.com/Lauryy06/Upsilon.git
cd Upsilon
git checkout --recursive upsilon-dev
git checkout --recursive omega-dev
make PLATFORM=simulator TARGET=3ds -j
```
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
3dslink output/release/simulator/3ds/epsilon.3dsx -a <3DS' IP ADDRESS>
3dslink output/release/simulator/3ds/epsilon.3dsx -a <ADRESSE IP 3DS>
```
</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
<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>

144
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://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/>
<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>
<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>
</p>
> 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
- Enhancements for the Kandinsky python module
- Support for wallpapers
- External apps
- Exernal apps
- A custom theme
- Operator overload for python
- Improvements for the Periodic table application
@@ -29,15 +29,9 @@ Upsilon is a fork of Omega, an user-made OS that runs on the Numworks calculator
## 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
*You can refer to this [website](https://www.numworks.com/resources/engineering/software/build/) for the first step if you get errors.*
*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.*
@@ -46,13 +40,12 @@ Do not disconnect your calculator until the installation is complete.
<br>
<details>
<summary><b>1.1 Linux</b></summary>
<br>
<details>
<details>
<summary>Debian or Ubuntu</summary>
<br>
@@ -70,27 +63,26 @@ And there you can go to step 2!
</details>
<details>
<summary>Fedora</summary>
<br>
To install basics dev tools:
First install basics dev tools.
```bash
dnf install make automake gcc gcc-c++ kernel-devel
```
And then install required packages.
Then install required packages.
```bash
install git ImageMagick libX11-devel libXext-devel freetype-devel libpng-devel libjpeg-devel pkg-config
dnf install git ImageMagick libX11-devel libXext-devel freetype-devel libpng-devel libjpeg-devel pkg-config
```
Then, install GCC cross compiler for ARM.
```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>
@@ -102,17 +94,14 @@ Then, install GCC cross compiler for ARM.
</details>
<details>
<summary><b>1.2 Mac</b></summary>
<br>
It's recommended to use [Homebrew](https://brew.sh/). Once it's installed, just run:
```bash
brew install numworks/tap/epsilon-sdk
```
and it will install all dependencies.
<br>
@@ -121,108 +110,32 @@ And there you can go to step 2!
<br>
</details>
<details>
<summary><b>1.3 Windows</b></summary>
<br>
<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.
[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.
```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
```
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:
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:
```bash
echo "export PATH=$PATH:$HOME/gcc-arm/bin" >> .bashrc
```
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>
Just restart and you can go to step 2!
</details>
<br>
### 2. Set up repo
@@ -240,8 +153,7 @@ git checkout upsilon-dev
<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`).
@@ -255,7 +167,7 @@ Now, run either:
```bash
make MODEL=n0100 epsilon_flash
```
to directly flash the calculator after pressing simultaneously `reset` and `6` buttons and plugging in.
to directly flash the calculator after pressing simultaneously `reset` and `6` buttons and pluging in.
<br>
@@ -264,13 +176,12 @@ or:
```bash
make MODEL=n0100 OMEGA_USERNAME="" binpack -j4
```
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.
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.
</details>
<details>
<summary><b>Model n0110</b></summary>
<summary><b>Model n0110</b></summary>
```bash
@@ -283,7 +194,7 @@ Now, run either:
```bash
make epsilon_flash
```
to directly flash the calculator after pressing simultaneously `reset` and `6` buttons and plugging in.
to directly flash the calculator after pressing simultaneously `reset` and `6` buttons and pluging in.
<br>
@@ -292,14 +203,13 @@ or:
```bash
make OMEGA_USERNAME="" binpack -j4
```
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.
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.
</details>
<details>
<summary><b>Web simulator</b></summary>
<summary><b>Web simulator</b></summary>
First, install emsdk :
```bash
@@ -319,18 +229,18 @@ make PLATFORM=simulator TARGET=web OMEGA_USERNAME="{Your name, max 15 characters
The simulator is now in `output/release/simulator/web/simulator.zip`
</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))
```bash
git clone --recursive https://github.com/Lauryy06/Upsilon.git
cd Upsilon
git checkout --recursive upsilon-dev
git checkout --recursive omega-dev
make PLATFORM=simulator TARGET=3ds -j
```
You can then put epsilon.3dsx on a SD card to run it from the HBC or use 3dslink to launch it over the network:
@@ -360,7 +270,7 @@ If you need help, you can join our Discord server here : https://discord.gg/NFvz
## Contributing
To contribute, please refer to [Omega's Wiki](https://github.com/Omega-Numworks/Omega/wiki/Contributing), the same rules apply here.
## Related repositories
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)))
ifeq ($(miss_modules), 1)
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 "\nSome submodules apps seem to be missing. To download them, assumming you git clone'd the repo, do\n")
PLS_IGNORE := $(shell >&2 printf " git submodule init\n")
PLS_IGNORE := $(shell >&2 printf " git submodule update\n\n")
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
language_preferences = apps/language_preferences.csv
# The header is referred to as <apps/i18n.h> so make sure it's findable this way
# The header is refered to as <apps/i18n.h> so make sure it's findable this way
SFLAGS += -I$(BUILD_DIR)
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
* (which makes bigger files to download and slower execution), or
* whitelisting all the symbols (that's a big amount of symbols to find and
* quite paint to maintain).
* quite painy to maintain).
* We just remove the circuit breaker for now.
* TODO: Put the Poincare circuit breaker back on epsilon's web emulator */
@@ -147,7 +147,7 @@ bool AppsContainer::dispatchEvent(Ion::Events::Event event) {
* pictogram. */
updateBatteryState();
if (switchTo(usbConnectedAppSnapshot())) {
Ion::USB::DFU(true);
Ion::USB::DFU();
// Update LED when exiting DFU mode
Ion::LED::updateColorWithPlugAndCharge();
bool switched = switchTo(activeSnapshot);
@@ -243,18 +243,15 @@ bool AppsContainer::processEvent(Ion::Events::Event event) {
}
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) {
switchTo(appSnapshotAtIndex(0));
return true;
}
// If shift + Home are pressed, we switch to the first app.
if (event == Ion::Events::ShiftHome) {
switchTo(appSnapshotAtIndex(1));
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++) {
if (event == switch_events[i]) {
m_window.redraw(true);
@@ -263,20 +260,13 @@ 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) {
suspend(true);
return true;
}
if (event == Ion::Events::BrightnessPlus || event == Ion::Events::BrightnessMinus) {
int delta = Ion::Backlight::MaxBrightness/GlobalPreferences::NumberOfBrightnessStates;
int NumberOfStepsPerShortcut = GlobalPreferences::sharedGlobalPreferences()->brightnessShortcut();
int direction = (event == Ion::Events::BrightnessPlus) ? NumberOfStepsPerShortcut*delta : -delta*NumberOfStepsPerShortcut;
int direction = (event == Ion::Events::BrightnessPlus) ? Ion::Backlight::NumberOfStepsPerShortcut*delta : -delta*Ion::Backlight::NumberOfStepsPerShortcut;
GlobalPreferences::sharedGlobalPreferences()->setBrightnessLevel(GlobalPreferences::sharedGlobalPreferences()->brightnessLevel()+direction);
}
return false;
@@ -329,7 +319,7 @@ void AppsContainer::run() {
* destroyed from the pool. To avoid using them before packing the app
* (in App::willBecomeInactive for instance), we tidy them early on. */
s_activeApp->snapshot()->tidy();
/* When an app encountered an exception due to a full pool, the next time
/* When an app encoutered an exception due to a full pool, the next time
* the user enters the app, the same exception could happen again which
* 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
@@ -363,8 +353,6 @@ bool AppsContainer::updateBatteryState() {
}
void AppsContainer::refreshPreferences() {
m_suspendTimer.reset(GlobalPreferences::sharedGlobalPreferences()->idleBeforeSuspendSeconds()*1000/Timer::TickDuration);
m_backlightDimmingTimer.reset(GlobalPreferences::sharedGlobalPreferences()->idleBeforeDimmingSeconds()*1000/Timer::TickDuration);
m_window.refreshPreferences();
}

View File

@@ -1,26 +1,11 @@
#include "backlight_dimming_timer.h"
#include "global_preferences.h"
#include <ion/backlight.h>
#include <ion/events.h>
#include <apps/apps_container.h>
BacklightDimmingTimer::BacklightDimmingTimer() :
Timer(GlobalPreferences::sharedGlobalPreferences()->idleBeforeDimmingSeconds()*1000/Timer::TickDuration)
Timer(k_idleBeforeDimmingDuration/Timer::TickDuration)
{
}
bool BacklightDimmingTimer::fire(){
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;
}
bool BacklightDimmingTimer::fire() {
Ion::Backlight::setBrightness(k_dimBacklightBrightness);
return false;
}

View File

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

View File

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

View File

@@ -20,21 +20,15 @@ using namespace Poincare;
using namespace Shared;
namespace Calculation {
void SecondDegreeListController::setExpression(Poincare::Expression e) {
ExpressionsListController::setExpression(e);
assert(!m_expression.isUninitialized());
Expression polynomialCoefficients[Expression::k_maxNumberOfPolynomialCoefficients];
Context * context = App::app()->localContext();
Preferences * preferences = Preferences::sharedPreferences();
Poincare::ExpressionNode::ReductionContext reductionContext = Poincare::ExpressionNode::ReductionContext(context,
preferences->complexFormat(), preferences->angleUnit(),
GlobalPreferences::sharedGlobalPreferences()->unitFormat(),
ExpressionNode::ReductionTarget::SystemForApproximation,
ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition,
Poincare::ExpressionNode::UnitConversion::Default);
PoincareHelpers::Reduce(&m_expression, context, ExpressionNode::ReductionTarget::SystemForAnalysis);
@@ -53,105 +47,59 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
Expression b = polynomialCoefficients[1];
Expression c = polynomialCoefficients[0];
bool aIsNotOne = !(a.type() == ExpressionNode::Type::Rational && static_cast<const Rational &>(a).isOne());
Expression delta = Subtraction::Builder(Power::Builder(b.clone(), Rational::Builder(2)), Multiplication::Builder(Rational::Builder(4), a.clone(), c.clone()));
PoincareHelpers::Simplify(&delta, context, ExpressionNode::ReductionTarget::SystemForApproximation);
// Alpha is -b/2a, but because after we use -α, we immediately store -α=-(-b/2a)=b/2a.
Expression minusAlpha = Division::Builder(b.clone(), Multiplication::Builder(Rational::Builder(2), a.clone()));
PoincareHelpers::Reduce(&minusAlpha, context, ExpressionNode::ReductionTarget::SystemForApproximation);
Expression alpha = Opposite::Builder(Division::Builder(b.clone(), Multiplication::Builder(Rational::Builder(2), a.clone())));
PoincareHelpers::Simplify(&alpha, context, ExpressionNode::ReductionTarget::User);
// Same thing for β
Expression minusBeta = Division::Builder(delta.clone(), Multiplication::Builder(Rational::Builder(4), a.clone()));
PoincareHelpers::Reduce(&minusBeta, context, ExpressionNode::ReductionTarget::SystemForApproximation);
Expression beta = Opposite::Builder(Division::Builder(delta.clone(), Multiplication::Builder(Rational::Builder(4), a.clone())));
PoincareHelpers::Simplify(&beta, context, ExpressionNode::ReductionTarget::User);
enum MultiplicationTypeForA {
Nothing,
Minus,
Parenthesis,
Normal
};
MultiplicationTypeForA multiplicationTypeForA;
if (a.type() == ExpressionNode::Type::Rational && static_cast<const Rational &>(a).isOne()) {
multiplicationTypeForA = MultiplicationTypeForA::Nothing;
} else if(a.type() == ExpressionNode::Type::Rational && static_cast<const Rational &>(a).isMinusOne()){
multiplicationTypeForA = MultiplicationTypeForA::Minus;
} else if (a.type() == ExpressionNode::Type::Addition) {
multiplicationTypeForA = MultiplicationTypeForA::Parenthesis;
} else {
multiplicationTypeForA = MultiplicationTypeForA::Normal;
}
PoincareHelpers::Simplify(&a, context, ExpressionNode::ReductionTarget::User);
/*
* Because when can't apply reduce or simplify to keep the
* canonized form we must beautify the expression manually
/*
* Because when can't apply reduce or simplify to keep the canonised
* we must beautify the expression manually
*/
Expression xMinusAlphaPowerTwo;
Expression alpha = getOppositeIfExists(minusAlpha, &reductionContext);
if (alpha.isUninitialized()) {
PoincareHelpers::Simplify(&minusAlpha, context, ExpressionNode::ReductionTarget::User);
xMinusAlphaPowerTwo = Power::Builder(Parenthesis::Builder(Addition::Builder(Symbol::Builder("x", strlen("x")), minusAlpha)), Rational::Builder(2));
} else {
PoincareHelpers::Simplify(&alpha, context, ExpressionNode::ReductionTarget::User);
xMinusAlphaPowerTwo = Power::Builder(Parenthesis::Builder(Subtraction::Builder(Symbol::Builder("x", strlen("x")), alpha)), Rational::Builder(2));
}
Expression xMinusAlphaPowerTwoWithFactor;
switch (multiplicationTypeForA)
{
case MultiplicationTypeForA::Nothing:
xMinusAlphaPowerTwoWithFactor = xMinusAlphaPowerTwo;
break;
case MultiplicationTypeForA::Minus:
xMinusAlphaPowerTwoWithFactor = Opposite::Builder(xMinusAlphaPowerTwo);
break;
case MultiplicationTypeForA::Parenthesis:
xMinusAlphaPowerTwoWithFactor = Multiplication::Builder(Parenthesis::Builder(a.clone()), xMinusAlphaPowerTwo);
break;
case MultiplicationTypeForA::Normal:
xMinusAlphaPowerTwoWithFactor = Multiplication::Builder(a.clone(), xMinusAlphaPowerTwo);
break;
default:
assert(false);
break;
}
Expression canonized;
PoincareHelpers::Simplify(&minusBeta, context, ExpressionNode::ReductionTarget::User);
Expression beta = getOppositeIfExists(minusBeta, &reductionContext);
if (beta.isUninitialized()) {
if (minusBeta.type() == ExpressionNode::Type::Addition || minusBeta.type() == ExpressionNode::Type::Subtraction) {
canonized = Subtraction::Builder(xMinusAlphaPowerTwoWithFactor, Parenthesis::Builder(minusBeta));
} else {
canonized = Subtraction::Builder(xMinusAlphaPowerTwoWithFactor, minusBeta);
}
} else {
PoincareHelpers::Simplify(&beta, context, ExpressionNode::ReductionTarget::User);
canonized = Addition::Builder(xMinusAlphaPowerTwoWithFactor, beta);
Expression canonised;
if (alpha.type() == ExpressionNode::Type::Opposite) {
canonised = Addition::Builder(Symbol::Builder("x", strlen("x")), alpha.childAtIndex(0).clone());
}
else {
canonised = Subtraction::Builder(Symbol::Builder("x", strlen("x")), alpha.clone());
}
canonised = Power::Builder(Parenthesis::Builder(canonised.clone()), Rational::Builder(2));
if (aIsNotOne) {
canonised = Multiplication::Builder(a.clone(), canonised.clone());
}
if (beta.type() == ExpressionNode::Type::Opposite) {
canonised = Subtraction::Builder(canonised.clone(), beta.childAtIndex(0).clone());
}
else {
canonised = Addition::Builder(canonised.clone(), beta.clone());
}
Expression x0;
Expression x1;
if (delta.nullStatus(context) == ExpressionNode::NullStatus::Null) {
// x0 = x1 = -b/(2a)
x0 = Division::Builder(Opposite::Builder(b.clone()), Multiplication::Builder(Rational::Builder(2), a.clone()));
x0 = Division::Builder(Opposite::Builder(b), Multiplication::Builder(Rational::Builder(2), a));
m_numberOfSolutions = 1;
PoincareHelpers::Simplify(&x0, context, ExpressionNode::ReductionTarget::SystemForApproximation);
} else {
PoincareHelpers::Simplify(&x0, context, ExpressionNode::ReductionTarget::User);
}
else {
// x0 = (-b-sqrt(delta))/(2a)
x0 = Division::Builder(Subtraction::Builder(Opposite::Builder(b.clone()), SquareRoot::Builder(delta.clone())), Multiplication::Builder(Rational::Builder(2), a.clone()));
// x1 = (-b+sqrt(delta))/(2a)
x1 = Division::Builder(Addition::Builder(Opposite::Builder(b.clone()), SquareRoot::Builder(delta.clone())), Multiplication::Builder(Rational::Builder(2), a.clone()));
x1 = Division::Builder(Addition::Builder(Opposite::Builder(b), SquareRoot::Builder(delta.clone())), Multiplication::Builder(Rational::Builder(2), a));
m_numberOfSolutions = 2;
PoincareHelpers::Simplify(&x0, context, ExpressionNode::ReductionTarget::SystemForApproximation);
PoincareHelpers::Simplify(&x1, context, ExpressionNode::ReductionTarget::SystemForApproximation);
PoincareHelpers::Simplify(&x0, context, ExpressionNode::ReductionTarget::User);
PoincareHelpers::Simplify(&x1, context, ExpressionNode::ReductionTarget::User);
if (x0.type() == ExpressionNode::Type::Unreal) {
assert(x1.type() == ExpressionNode::Type::Unreal);
m_numberOfSolutions = 0;
@@ -161,99 +109,40 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
Expression factorized;
if (m_numberOfSolutions == 2) {
Expression firstFactor;
Expression secondFactor;
Expression x0Opposite = getOppositeIfExists(x0, &reductionContext);
if (x0Opposite.isUninitialized()) {
PoincareHelpers::Simplify(&x0, context, ExpressionNode::ReductionTarget::User);
if (x0.type() == ExpressionNode::Type::Addition || x0.type() == ExpressionNode::Type::Subtraction) {
firstFactor = Subtraction::Builder(Symbol::Builder("x", strlen("x")), Parenthesis::Builder(x0.clone()));
} else {
firstFactor = Subtraction::Builder(Symbol::Builder("x", strlen("x")), x0.clone());
}
} else {
if (x0Opposite.type() == ExpressionNode::Type::Addition || x0Opposite.type() == ExpressionNode::Type::Subtraction) {
x0Opposite = Parenthesis::Builder(x0Opposite.clone());
}
firstFactor = Addition::Builder(Symbol::Builder("x", strlen("x")), x0Opposite.clone());
if (x0.type() == ExpressionNode::Type::Opposite) {
factorized = Parenthesis::Builder(Addition::Builder(Symbol::Builder("x", strlen("x")), x0.childAtIndex(0).clone()));
}
else {
factorized = Parenthesis::Builder(Subtraction::Builder(Symbol::Builder("x", strlen("x")), x0.clone()));
}
if (x1.type() == ExpressionNode::Type::Opposite) {
factorized = Multiplication::Builder(factorized.clone(), Parenthesis::Builder(Addition::Builder(Symbol::Builder("x", strlen("x")), x1.childAtIndex(0).clone())));
}
else {
factorized = Multiplication::Builder(factorized.clone(), Parenthesis::Builder(Subtraction::Builder(Symbol::Builder("x", strlen("x")), x1.clone())));
}
Expression x1Opposite = getOppositeIfExists(x1, &reductionContext);
if (x1Opposite.isUninitialized()) {
PoincareHelpers::Simplify(&x1, context, ExpressionNode::ReductionTarget::User);
if (x1.type() == ExpressionNode::Type::Addition || x1.type() == ExpressionNode::Type::Subtraction) {
secondFactor = Subtraction::Builder(Symbol::Builder("x", strlen("x")), Parenthesis::Builder(x1.clone()));
} else {
secondFactor = Subtraction::Builder(Symbol::Builder("x", strlen("x")), x1.clone());
}
} else {
PoincareHelpers::Simplify(&x1Opposite, context, ExpressionNode::ReductionTarget::User);
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));
switch (multiplicationTypeForA)
{
case MultiplicationTypeForA::Nothing:
factorized = solutionProduct;
break;
case MultiplicationTypeForA::Minus:
factorized = Opposite::Builder(solutionProduct);
break;
case MultiplicationTypeForA::Parenthesis:
factorized = Multiplication::Builder(Parenthesis::Builder(a.clone()), solutionProduct);
break;
case MultiplicationTypeForA::Normal:
factorized = Multiplication::Builder(a.clone(), solutionProduct);
break;
default:
assert(false);
break;
}
} else if (m_numberOfSolutions == 1) {
Expression x0Opposite = getOppositeIfExists(x0, &reductionContext);
Expression factor;
if (x0Opposite.isUninitialized()) {
PoincareHelpers::Simplify(&x0, context, ExpressionNode::ReductionTarget::User);
if (x0.type() == ExpressionNode::Type::Addition || x0.type() == ExpressionNode::Type::Subtraction) {
factor = Subtraction::Builder(Symbol::Builder("x", strlen("x")), Parenthesis::Builder(x0.clone()));
} else {
factor = Subtraction::Builder(Symbol::Builder("x", strlen("x")), x0.clone());
}
} else {
PoincareHelpers::Simplify(&x0Opposite, context, ExpressionNode::ReductionTarget::User);
factor = Addition::Builder(Symbol::Builder("x", strlen("x")), x0Opposite.clone());
}
Expression solutionProduct = Power::Builder(Parenthesis::Builder(factor), Rational::Builder(2));
switch (multiplicationTypeForA)
{
case MultiplicationTypeForA::Nothing:
factorized = solutionProduct;
break;
case MultiplicationTypeForA::Minus:
factorized = Opposite::Builder(solutionProduct);
break;
case MultiplicationTypeForA::Parenthesis:
factorized = Multiplication::Builder(Parenthesis::Builder(a.clone()), solutionProduct);
break;
case MultiplicationTypeForA::Normal:
factorized = Multiplication::Builder(a.clone(), solutionProduct);
break;
default:
assert(false);
break;
if (aIsNotOne) {
factorized = Multiplication::Builder(a.clone(), factorized.clone());
}
}
else if (m_numberOfSolutions == 1) {
if (x0.type() == ExpressionNode::Type::Opposite) {
factorized = Power::Builder(Parenthesis::Builder(Addition::Builder(Symbol::Builder("x", strlen("x")), x0.childAtIndex(0).clone())), Rational::Builder(2));
}
else {
factorized = Power::Builder(Parenthesis::Builder(Subtraction::Builder(Symbol::Builder("x", strlen("x")), x0.clone())), Rational::Builder(2));
}
if (aIsNotOne) {
factorized = Multiplication::Builder(a.clone(), factorized.clone());
}
}
PoincareHelpers::Simplify(&delta, context, ExpressionNode::ReductionTarget::User);
m_layouts[0] = PoincareHelpers::CreateLayout(canonized);
m_layouts[0] = PoincareHelpers::CreateLayout(canonised);
if (m_numberOfSolutions > 0) {
m_layouts[1] = PoincareHelpers::CreateLayout(factorized);
m_layouts[2] = PoincareHelpers::CreateLayout(delta);
@@ -261,38 +150,17 @@ void SecondDegreeListController::setExpression(Poincare::Expression e) {
if (m_numberOfSolutions > 1) {
m_layouts[4] = PoincareHelpers::CreateLayout(x1);
}
} else {
}
else {
m_layouts[1] = PoincareHelpers::CreateLayout(delta);
}
}
Expression SecondDegreeListController::getOppositeIfExists(Expression e, Poincare::ExpressionNode::ReductionContext * reductionContext) {
if (e.isNumber() && e.sign(reductionContext->context()) == ExpressionNode::Sign::Negative) {
Number n = static_cast<Number&>(e);
return std::move(n.setSign(ExpressionNode::Sign::Positive));
} else if(e.type() == ExpressionNode::Type::Opposite) {
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);
if (m.childAtIndex(0).type() == ExpressionNode::Type::Rational && static_cast<Rational&>(e).isMinusOne()) {
// The negative numeral factor is -1, we just remove it
m.removeChildAtIndexInPlace(0);
} else {
Expression firstChild = m.childAtIndex(0);
Number n = static_cast<Number&>(firstChild);
m.childAtIndex(0).setChildrenInPlace(n.setSign(ExpressionNode::Sign::Positive));
}
PoincareHelpers::Simplify(&m, reductionContext->context(), ExpressionNode::ReductionTarget::User);
return std::move(m);
}
return Expression();
}
I18n::Message SecondDegreeListController::messageAtIndex(int index) {
if (m_numberOfSolutions > 0) {
if (index == 0) {
return I18n::Message::CanonicalForm;
}
}
if (index == 1) {
return I18n::Message::FactorizedForm;
}
@@ -302,12 +170,14 @@ I18n::Message SecondDegreeListController::messageAtIndex(int index) {
if (index == 3) {
if (m_numberOfSolutions == 1) {
return I18n::Message::OnlyRoot;
} else {
}
else {
return I18n::Message::FirstRoot;
}
}
return I18n::Message::SecondRoot;
} else {
}
else {
switch (index) {
case 0:
return I18n::Message::CanonicalForm;

View File

@@ -14,7 +14,6 @@ public:
void setExpression(Poincare::Expression e) override;
private:
Poincare::Expression getOppositeIfExists(Poincare::Expression e, Poincare::ExpressionNode::ReductionContext * reductionContext);
I18n::Message messageAtIndex(int index) override;
int m_numberOfSolutions;
};

View File

@@ -1,63 +1,16 @@
#include "trigonometry_list_controller.h"
#include "../app.h"
#include <poincare_nodes.h>
#include "../../shared/poincare_helpers.h"
using namespace Poincare;
namespace Calculation {
static constexpr int s_fullCircle[] = {
360,
2,
400
};
Poincare::Constant toConstant(Expression e) {
return static_cast<Poincare::Constant &>(e);
}
void TrigonometryListController::setExpression(Expression e) {
void TrigonometryListController::setExpression(Poincare::Expression e) {
assert(e.type() == ExpressionNode::Type::Cosine || e.type() == ExpressionNode::Type::Sine);
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);
IllustratedListController::setExpression(e.childAtIndex(0));
// Fill calculation store
Poincare::Context * context = App::app()->localContext();
m_calculationStore.push("sin(θ)", context, CalculationHeight);
m_calculationStore.push("cos(θ)", context, CalculationHeight);
m_calculationStore.push("θ", context, CalculationHeight);

View File

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

View File

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

View File

@@ -68,15 +68,6 @@ void EditExpressionController::memoizeInput() {
*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() {
m_historyController->viewWillAppear();
}

View File

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

View File

@@ -35,7 +35,6 @@ public:
int typeAtLocation(int i, int j) 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 reinsertTrash() { m_calculationStore->reinsertTrash(); }
private:
int storeIndex(int i) { return numberOfRows() - i - 1; }
Shared::ExpiringPointer<Calculation> calculationAtIndex(int i);

View File

@@ -81,7 +81,7 @@ void HistoryViewCell::reloadSubviewHighlight() {
m_ellipsis.setHighlighted(false);
if (isHighlighted()) {
if (m_dataSource->selectedSubviewType() == HistoryViewCellDataSource::SubviewType::Input) {
m_inputView.setExpressionBackgroundColor(Palette::Select);
m_inputView.setExpressionBackgroundColor(Palette::ListCellBackgroundSelected);
} else if (m_dataSource->selectedSubviewType() == HistoryViewCellDataSource::SubviewType::Output) {
m_scrollableOutputView.evenOddCell()->setHighlighted(true);
} else {

View File

@@ -1,8 +1,6 @@
apps += Code::App
app_headers += apps/code/app.h
SFLAGS += -DHAS_CODE
app_code_src = $(addprefix apps/code/,\
app.cpp \
console_controller.cpp \

View File

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

View File

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

View File

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

View File

@@ -53,7 +53,6 @@ PythonErfc = "Complementary error function"
PythonEval = "Return the evaluated expression"
PythonExp = "Exponential function"
PythonExpm1 = "Compute exp(x)-1"
PythonFactorial = "Factorial of x"
PythonFabs = "Absolute value"
PythonFillCircle = "Fill a circle"
PythonFillPolygon = "Fill a polygon"
@@ -91,56 +90,8 @@ PythonIsKeyDown = "Return True if the k key is down"
PythonBattery = "Return battery voltage"
PythonBatteryLevel = "Return battery level"
PythonBatteryIscharging = "Return if battery is charging"
PythonSetBrightness = "Set brightness level"
PythonGetBrightness = "Get brightness level"
PythonIsNaN = "Check if x is a NaN"
PythonKandinskyFunction = "kandinsky module function prefix"
PythonKeyLeft = "LEFT ARROW key"
PythonKeyUp = "UP ARROW key"
PythonKeyDown = "DOWN ARROW key"
PythonKeyRight = "RIGHT ARROW key"
PythonKeyOk = "OK key"
PythonKeyBack = "BACK key"
PythonKeyHome = "HOME key"
PythonKeyOnOff = "ON/OFF key"
PythonKeyShift = "SHIFT key"
PythonKeyAlpha = "ALPHA key"
PythonKeyXnt = "X,N,T key"
PythonKeyVar = "VAR key"
PythonKeyToolbox = "TOOLBOX key"
PythonKeyBackspace = "BACKSPACE key"
PythonKeyExp = "EXPONENTIAL key"
PythonKeyLn = "NATURAL LOGARITHM key"
PythonKeyLog = "DECIMAL LOGARITHM key"
PythonKeyImaginary = "IMAGINARY I key"
PythonKeyComma = "COMMA key"
PythonKeyPower = "POWER key"
PythonKeySine = "SINE key"
PythonKeyCosine = "COSINE key"
PythonKeyTangent = "TANGENT key"
PythonKeyPi = "PI key"
PythonKeySqrt = "SQUARE ROOT key"
PythonKeySquare = "SQUARE key"
PythonKeySeven = "7 key"
PythonKeyEight = "8 key"
PythonKeyNine = "9 key"
PythonKeyLeftParenthesis = "LEFT PARENTHESIS key"
PythonKeyRightParenthesis = "RIGHT PARENTHESIS key"
PythonKeyFour = "4 key"
PythonKeyFive = "5 key"
PythonKeySix = "6 key"
PythonKeyMultiplication = "MULTIPLICATION key"
PythonKeyDivision = "DIVISION key"
PythonKeyOne = "1 key"
PythonKeyTwo = "2 key"
PythonKeyThree = "3 key"
PythonKeyPlus = "PLUS key"
PythonKeyMinus = "MINUS key"
PythonKeyZero = "0 key"
PythonKeyDot = "DOT key"
PythonKeyEe = "10 POWER X key"
PythonKeyAns = "ANS key"
PythonKeyExe = "EXE key"
PythonLdexp = "Return x*(2**i), inverse of frexp"
PythonLength = "Length of an object"
PythonLgamma = "Log-gamma function"
@@ -218,6 +169,7 @@ PythonTurtlePosition = "Return the current (x,y) location"
PythonTurtleReset = "Reset the drawing"
PythonTurtleRight = "Turn right by a degrees"
PythonTurtleSetheading = "Set the orientation to a degrees"
PythonTurtleSetposition = "Positionne la tortue"
PythonTurtleShowturtle = "Show the turtle"
PythonTurtleSpeed = "Drawing speed between 0 and 10"
PythonTurtleWrite = "Display a text"
@@ -237,6 +189,8 @@ PythonSysImplementation = "Information about Python"
PythonSysModules = "Dictionary of loaded modules"
PythonSysVersion = "Python language version (string)"
PythonSysVersioninfo = "Python language version (tuple)"
PythonTimePrefix = "time module function prefix"
PythonTimeSleep = "Wait for n second"
PythonMonotonic = "Return monotonic time"
PythonFileOpen = "Opens a file"
PythonFileSeekable = "Tells if seek can be used on a file"

View File

@@ -53,7 +53,6 @@ PythonErfc = "Complementary error function"
PythonEval = "Return the evaluated expression"
PythonExp = "Exponential function"
PythonExpm1 = "Compute exp(x)-1"
PythonFactorial = "factorial de x"
PythonFabs = "Absolute value"
PythonFillCircle = "Fill a circle"
PythonFillPolygon = "Fill a polygon"
@@ -88,59 +87,11 @@ PythonIonFunction = "ion module function prefix"
PythonIsFinite = "Check if x is finite"
PythonIsInfinite = "Check if x is infinity"
PythonIsKeyDown = "Return True if the k key is down"
PythonBattery = "Rückgabe der Batteriespannung"
PythonBatteryLevel = "Gibt den Batteriestand zurück"
PythonBatteryIscharging = "Gibt zurück, ob die Batterie geladen wird"
PythonSetBrightness = "Establecer nivel de brillo"
PythonGetBrightness = "Obtener nivel de brillo"
PythonBattery = "Return battery voltage"
PythonBatteryLevel = "Return battery level"
PythonBatteryIscharging = "Return if battery is charging"
PythonIsNaN = "Check if x is a NaN"
PythonKandinskyFunction = "kandinsky module function prefix"
PythonKeyLeft = "LEFT ARROW key"
PythonKeyUp = "UP ARROW key"
PythonKeyDown = "DOWN ARROW key"
PythonKeyRight = "RIGHT ARROW key"
PythonKeyOk = "OK key"
PythonKeyBack = "BACK key"
PythonKeyHome = "HOME key"
PythonKeyOnOff = "ON/OFF key"
PythonKeyShift = "SHIFT key"
PythonKeyAlpha = "ALPHA key"
PythonKeyXnt = "X,N,T key"
PythonKeyVar = "VAR key"
PythonKeyToolbox = "TOOLBOX key"
PythonKeyBackspace = "BACKSPACE key"
PythonKeyExp = "EXPONENTIAL key"
PythonKeyLn = "NATURAL LOGARITHM key"
PythonKeyLog = "DECIMAL LOGARITHM key"
PythonKeyImaginary = "IMAGINARY I key"
PythonKeyComma = "COMMA key"
PythonKeyPower = "POWER key"
PythonKeySine = "SINE key"
PythonKeyCosine = "COSINE key"
PythonKeyTangent = "TANGENT key"
PythonKeyPi = "PI key"
PythonKeySqrt = "SQUARE ROOT key"
PythonKeySquare = "SQUARE key"
PythonKeySeven = "7 key"
PythonKeyEight = "8 key"
PythonKeyNine = "9 key"
PythonKeyLeftParenthesis = "LEFT PARENTHESIS key"
PythonKeyRightParenthesis = "RIGHT PARENTHESIS key"
PythonKeyFour = "4 key"
PythonKeyFive = "5 key"
PythonKeySix = "6 key"
PythonKeyMultiplication = "MULTIPLICATION key"
PythonKeyDivision = "DIVISION key"
PythonKeyOne = "1 key"
PythonKeyTwo = "2 key"
PythonKeyThree = "3 key"
PythonKeyPlus = "PLUS key"
PythonKeyMinus = "MINUS key"
PythonKeyZero = "0 key"
PythonKeyDot = "DOT key"
PythonKeyEe = "10 POWER X key"
PythonKeyAns = "ANS key"
PythonKeyExe = "EXE key"
PythonLdexp = "Return x*(2**i), inverse of frexp"
PythonLength = "Length of an object"
PythonLgamma = "Log-gamma function"
@@ -218,6 +169,7 @@ PythonTurtlePosition = "Return the current (x,y) location"
PythonTurtleReset = "Reset the drawing"
PythonTurtleRight = "Turn right by a degrees"
PythonTurtleSetheading = "Set the orientation to a degrees"
PythonTurtleSetposition = "Positionne la tortue"
PythonTurtleShowturtle = "Show the turtle"
PythonTurtleSpeed = "Drawing speed between 0 and 10"
PythonTurtleWrite = "Display a text"
@@ -237,6 +189,8 @@ PythonSysImplementation = "Information about Python"
PythonSysModules = "Dictionary of loaded modules"
PythonSysVersion = "Python language version (string)"
PythonSysVersioninfo = "Python language version (tuple)"
PythonTimePrefix = "time module function prefix"
PythonTimeSleep = "Esperar n segundos"
PythonMonotonic = "Tiempo monótono de retorno"
PythonFileOpen = "Opens a file"
PythonFileSeekable = "Tells if seek can be used on a file"

View File

@@ -53,7 +53,6 @@ PythonErfc = "Fonction d'erreur complémentaire"
PythonEval = "Evalue l'expression en argument "
PythonExp = "Fonction exponentielle"
PythonExpm1 = "Calcul de exp(x)-1"
PythonFactorial = "Factorielle de x"
PythonFabs = "Valeur absolue"
PythonFillCircle = "Remplit un cercle"
PythonFillPolygon = "Remplit un polygone"
@@ -91,56 +90,8 @@ PythonIsKeyDown = "Renvoie True si touche k enfoncée"
PythonBattery = "Renvoie le voltage de la batterie"
PythonBatteryLevel = "Renvoie le niveau de la batterie"
PythonBatteryIscharging = "Chargement en cours"
PythonSetBrightness = "Définir le niveau de luminosité"
PythonGetBrightness = "Obtenir le niveau de luminosité"
PythonIsNaN = "Teste si x est NaN"
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)"
PythonLength = "Longueur d'un objet"
PythonLgamma = "Logarithme de la fonction gamma"
@@ -176,7 +127,7 @@ PythonRandrange = "Nombre dans range(start,stop)"
PythonRangeStartStop = "Liste de start à stop-1"
PythonRangeStop = "Liste de 0 à stop-1"
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"
PythonRound = "Arrondi à n décimales"
PythonScatter = "Nuage des points (x,y)"
@@ -218,6 +169,7 @@ PythonTurtlePosition = "Renvoie la position (x,y)"
PythonTurtleReset = "Réinitialise le dessin"
PythonTurtleRight = "Pivote de a degrés vers la droite"
PythonTurtleSetheading = "Met un cap de a degrés"
PythonTurtleSetposition = "Positionne la tortue"
PythonTurtleShowturtle = "Affiche la tortue"
PythonTurtleSpeed = "Vitesse du tracé entre 0 et 10"
PythonTurtleWrite = "Affiche un texte"
@@ -237,6 +189,8 @@ PythonSysImplementation = "Information sur Python"
PythonSysModules = "Dictionnaire des modules chargés"
PythonSysVersion = "Version du langage Python (string)"
PythonSysVersioninfo = "Version du langage Python (tuple)"
PythonTimePrefix = "Préfixe fonction du module temps"
PythonTimeSleep = "Attendre n secondes"
PythonMonotonic = "Retourne le temps monotone"
PythonFileOpen = "Ouvre un fichier"
PythonFileSeekable = "Indique si seek peut être utilisé"

View File

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

View File

@@ -53,7 +53,6 @@ PythonErfc = "Funzione d'errore complementare"
PythonEval = "Valuta l'espressione nell'argomento "
PythonExp = "Funzione esponenziale"
PythonExpm1 = "Calcola exp(x)-1"
PythonFactorial = "Fattoriale di x"
PythonFabs = "Valore assoluto"
PythonFillCircle = "Riempire un cerchio"
PythonFillPolygon = "Riempire un poligono"
@@ -102,59 +101,11 @@ PythonIonFunction = "Prefisso di funzione modulo ion"
PythonIsFinite = "Testa se x è finito"
PythonIsInfinite = "Testa se x est infinito"
PythonIsKeyDown = "Restituisce True premendo tasto k"
PythonBattery = "Restituisce la tensione della batteria"
PythonBatteryLevel = "Restituisce il livello della batteria"
PythonBatteryIscharging = "Restituisce se la batteria è in carica"
PythonSetBrightness = "Imposta livello di luminosità"
PythonGetBrightness = "Ottieni livello di luminosità"
PythonBattery = "Return battery voltage"
PythonBatteryLevel = "Return battery level"
PythonBatteryIscharging = "Return if battery is charging"
PythonIsNaN = "Testa se x è NaN"
PythonKandinskyFunction = "Prefisso funzione modulo kandinsky"
PythonKeyLeft = "Tasto FRECCIA SINISTRA"
PythonKeyUp = "Tasto FRECCIA ALTO"
PythonKeyDown = "Tasto FRECCIA BASSO"
PythonKeyRight = "Tasto FRECCIA DESTRA"
PythonKeyOk = "Tasto OK"
PythonKeyBack = "Tasto INDIETRO"
PythonKeyHome = "Tasto CASA"
PythonKeyOnOff = "Tasto ON/OFF"
PythonKeyShift = "Tasto SHIFT"
PythonKeyAlpha = "Tasto ALPHA"
PythonKeyXnt = "Tasto X,N,T"
PythonKeyVar = "Tasto VAR"
PythonKeyToolbox = "Tasto TOOLBOX"
PythonKeyBackspace = "Tasto CANCELLA"
PythonKeyExp = "Tasto ESPONENZIALE"
PythonKeyLn = "Tasto LOGARITMO NEPERIANO"
PythonKeyLog = "Tasto LOGARITMO DECIMALE"
PythonKeyImaginary = "Tasto I IMMAGINE"
PythonKeyComma = "Tasto VIRGOLA"
PythonKeyPower = "Tasto POTENZA"
PythonKeySine = "Tasto SENO"
PythonKeyCosine = "Tasto COSENO"
PythonKeyTangent = "Tasto TANGENTE"
PythonKeyPi = "Tasto PI"
PythonKeySqrt = "Tasto RADICE QUADRATA"
PythonKeySquare = "Tasto QUADRATO"
PythonKeySeven = "Tasto 7"
PythonKeyEight = "Tasto 8"
PythonKeyNine = "Tasto 9"
PythonKeyLeftParenthesis = "Tasto PARENTESI SINISTRA"
PythonKeyRightParenthesis = "Tasto PARENTESI DESTRA"
PythonKeyFour = "Tasto 4"
PythonKeyFive = "Tasto 5"
PythonKeySix = "Tasto 6"
PythonKeyMultiplication = "Tasto MOLTIPLICAZIONE"
PythonKeyDivision = "Tasto DIVISIONE"
PythonKeyOne = "Tasto 1"
PythonKeyTwo = "Tasto 2"
PythonKeyThree = "Tasto 3"
PythonKeyPlus = "Tasto PIÙ"
PythonKeyMinus = "Tasto MENO"
PythonKeyZero = "Tasto 0"
PythonKeyDot = "Tasto PUNTO"
PythonKeyEe = "Tasto 10 POTENZA X"
PythonKeyAns = "Tasto ANS"
PythonKeyExe = "Tasto EXE"
PythonLdexp = "Inversa di frexp : x*(2**i)"
PythonLength = "Longhezza di un oggetto"
PythonLgamma = "Logaritmo della funzione gamma"
@@ -190,7 +141,7 @@ PythonRandrange = "Numero dentro il range(start, stop)"
PythonRangeStartStop = "Lista da start a stop-1"
PythonRangeStop = "Lista da 0 a stop-1"
PythonRect = "Converte in coordinate algebriche"
PythonRemove = "Cancella la prima x dalla lista"
PythonRemove = "Cancella la prima x dalla lista"
PythonReverse = "Inverte gli elementi della lista"
PythonRound = "Arrotondato a n cifre decimali"
PythonScatter = "Diagramma dispersione y in f. di x"
@@ -232,11 +183,14 @@ PythonTurtlePosition = "Fornisce posizione corrente (x,y)"
PythonTurtleReset = "Azzera il disegno"
PythonTurtleRight = "Ruota di a gradi a destra"
PythonTurtleSetheading = "Imposta l'orientamento per a gradi"
PythonTurtleSetposition = "Posiziona la tartaruga"
PythonTurtleShowturtle = "Mostra la tartaruga"
PythonTurtleSpeed = "Velocità di disegno (x tra 0 e 10)"
PythonTurtleWrite = "Mostra un testo"
PythonUniform = "Numero decimale tra [a,b]"
PythonImportTime = "Import time module"
PythonTimePrefix = "time module function prefix"
PythonTimeSleep = "Wait for n second"
PythonMonotonic = "Return monotonic time"
PythonFileOpen = "Opens a file"
PythonFileSeekable = "Tells if seek can be used on a file"

View File

@@ -53,7 +53,6 @@ PythonErfc = "Complementaire error functie"
PythonEval = "Geef de geëvalueerde uitdrukking"
PythonExp = "Exponentiële functie"
PythonExpm1 = "Bereken exp(x)-1"
PythonFactorial = "faculteit van x"
PythonFabs = "Absolute waarde"
PythonFillCircle = "Vul een cirkel"
PythonFillPolygon = "Vul een veelhoek"
@@ -103,59 +102,11 @@ PythonIonFunction = "ion module voorvoegsel"
PythonIsFinite = "Controleer of x eindig is"
PythonIsInfinite = "Controleer of x oneindig is"
PythonIsKeyDown = "Geef True als k toets omlaag is"
PythonBattery = "Return batterijspanning"
PythonBatteryLevel = "Batterijniveau teruggeven"
PythonBatteryIscharging = "Keer terug als de batterij wordt opgeladen"
PythonSetBrightness = "Set brightness level"
PythonGetBrightness = "Get brightness level"
PythonBattery = "Return battery voltage"
PythonBatteryLevel = "Return battery level"
PythonBatteryIscharging = "Return if battery is charging"
PythonIsNaN = "Controleer of x geen getal is"
PythonKandinskyFunction = "kandinsky module voorvoegsel"
PythonKeyLeft = "PIJL NAAR LINKS toets"
PythonKeyUp = "PIJL OMHOOG toets"
PythonKeyDown = "PIJL OMLAAG toets"
PythonKeyRight = "PIJL NAAR RECHTS toets"
PythonKeyOk = "OK toets"
PythonKeyBack = "TERUG toets"
PythonKeyHome = "HOME toets"
PythonKeyOnOff = "AAN/UIT toets"
PythonKeyShift = "SHIFT toets"
PythonKeyAlpha = "ALPHA toets"
PythonKeyXnt = "X,N,T toets"
PythonKeyVar = "VAR toets"
PythonKeyToolbox = "TOOLBOX toets"
PythonKeyBackspace = "BACKSPACE toets"
PythonKeyExp = "EXPONENTIEEL toets"
PythonKeyLn = "NATUURLIJKE LOGARITME toets"
PythonKeyLog = "BRIGGSE LOGARITME toets"
PythonKeyImaginary = "IMAGINAIRE I toets"
PythonKeyComma = "KOMMA toets"
PythonKeyPower = "MACHT toets"
PythonKeySine = "SINUS toets"
PythonKeyCosine = "COSINUS toets"
PythonKeyTangent = "TANGENS toets"
PythonKeyPi = "PI toets"
PythonKeySqrt = "VIERKANTSWORTEL toets"
PythonKeySquare = "KWADRAAT toets"
PythonKeySeven = "7 toets"
PythonKeyEight = "8 toets"
PythonKeyNine = "9 toets"
PythonKeyLeftParenthesis = "HAAKJE OPENEN toets"
PythonKeyRightParenthesis = "HAAKJE SLUITEN toets"
PythonKeyFour = "4 toets"
PythonKeyFive = "5 toets"
PythonKeySix = "6 toets"
PythonKeyMultiplication = "VERMENIGVULDIGEN toets"
PythonKeyDivision = "DELEN toets"
PythonKeyOne = "1 toets"
PythonKeyTwo = "2 toets"
PythonKeyThree = "3 toets"
PythonKeyPlus = "PLUS toets"
PythonKeyMinus = "MIN toets"
PythonKeyZero = "0 toets"
PythonKeyDot = "PUNT toets"
PythonKeyEe = "10 TOT DE MACHT X toets"
PythonKeyAns = "ANS toets"
PythonKeyExe = "EXE toets"
PythonLdexp = "Geeft x*(2**i), inversie van frexp"
PythonLength = "Lengte van een object"
PythonLgamma = "Log-gammafunctie"
@@ -198,7 +149,7 @@ PythonScatter = "Teken scatterplot van y versus x"
PythonSeed = "Start willek. getallengenerator"
PythonSetPixel = "Kleur pixel (x,y)"
PythonShow = "Figuur weergeven"
PythonSin = "Sinus"
PythonSin= "Sinus"
PythonSinh = "Sinus hyperbolicus"
PythonSleep = "Stel executie voor t seconden uit"
PythonLocalTime = "Zet tijd om in tuple"
@@ -233,11 +184,14 @@ PythonTurtlePosition = "Zet huidige (x,y) locatie terug"
PythonTurtleReset = "Reset de tekening"
PythonTurtleRight = "Ga rechtsaf met a graden"
PythonTurtleSetheading = "Zet de oriëntatie op a graden"
PythonTurtleSetposition = "Plaats de schildpad"
PythonTurtleShowturtle = "Laat de schildpad zien"
PythonTurtleSpeed = "Tekensnelheid tussen 0 and 10"
PythonTurtleWrite = "Display a text"
PythonUniform = "Decimaal getal in [a,b]"
PythonImportTime = "Import time module"
PythonTimePrefix = "time module function prefix"
PythonTimeSleep = "Wait for n second"
PythonMonotonic = "Return monotonic time"
PythonFileOpen = "Opens a file"
PythonFileSeekable = "Tells if seek can be used on a file"

View File

@@ -53,7 +53,6 @@ PythonErfc = "Função erro complementar"
PythonEval = "Devolve a expressão avaliada"
PythonExp = "Função exponencial"
PythonExpm1 = "Calcular exp(x)-1"
PythonFactorial = "Fatorial de x"
PythonFabs = "Valor absoluto"
PythonFillCircle = "Preencher um círculo"
PythonFillPolygon = "Preencher um polígono"
@@ -88,59 +87,11 @@ PythonIonFunction = "Prefixo da função do módulo ion"
PythonIsFinite = "Verificar se x é finito"
PythonIsInfinite = "Verificar se x é infinito"
PythonIsKeyDown = "Devolve True se tecla k pressionada"
PythonBattery = "Retornar a voltagem da bateria"
PythonBatteryLevel = "Retornar nível de bateria"
PythonBatteryIscharging = "Retorne se a bateria estiver carregando"
PythonSetBrightness = "Definir nível de brilho"
PythonGetBrightness = "Obter nível de brilho"
PythonBattery = "Return battery voltage"
PythonBatteryLevel = "Return battery level"
PythonBatteryIscharging = "Return if battery is charging"
PythonIsNaN = "Verificar se x é um NaN"
PythonKandinskyFunction = "Prefixo da função do módulo kandinsky"
PythonKeyLeft = "tecla SETA ESQUERDA"
PythonKeyUp = "tecla SETA CIMA "
PythonKeyDown = "tecla SETA BAIXO"
PythonKeyRight = "tecla SETA DIREITA"
PythonKeyOk = "tecla OK"
PythonKeyBack = "tecla VOLTAR"
PythonKeyHome = "tecla HOME"
PythonKeyOnOff = "tecla ON/OFF"
PythonKeyShift = "tecla SHIFT"
PythonKeyAlpha = "tecla ALPHA"
PythonKeyXnt = "tecla X,N,T"
PythonKeyVar = "tecla VAR"
PythonKeyToolbox = "tecla CAIXA DE FERRAMENTAS"
PythonKeyBackspace = "tecla APAGAR"
PythonKeyExp = "tecla EXPONENCIAL"
PythonKeyLn = "tecla LOGARITMO NATURAL"
PythonKeyLog = "tecla LOGARITMO DECIMAL"
PythonKeyImaginary = "tecla I IMAGINÁRIO"
PythonKeyComma = "tecla VÍRGULA"
PythonKeyPower = "tecla EXPOENTE"
PythonKeySine = "tecla SENO"
PythonKeyCosine = "tecla COSSENO"
PythonKeyTangent = "tecla TANGENTE"
PythonKeyPi = "tecla PI"
PythonKeySqrt = "tecla RAIZ QUADRADA"
PythonKeySquare = "tecla AO QUADRADO"
PythonKeySeven = "tecla 7"
PythonKeyEight = "tecla 8"
PythonKeyNine = "tecla 9"
PythonKeyLeftParenthesis = "tecla PARÊNTESE ESQUERDO"
PythonKeyRightParenthesis = "tecla PARÊNTESE DIREITO"
PythonKeyFour = "tecla 4"
PythonKeyFive = "tecla 5"
PythonKeySix = "tecla 6"
PythonKeyMultiplication = "tecla MULTIPLICAÇÃO"
PythonKeyDivision = "tecla DIVISÃO"
PythonKeyOne = "tecla 1"
PythonKeyTwo = "tecla 2"
PythonKeyThree = "tecla 3"
PythonKeyPlus = "tecla MAIS"
PythonKeyMinus = "tecla MENOS"
PythonKeyZero = "tecla 0"
PythonKeyDot = "tecla PONTO"
PythonKeyEe = "tecla 10 expoente X"
PythonKeyAns = "tecla ANS"
PythonKeyExe = "tecla EXE"
PythonLdexp = "Devolve x*(2**i), inverso de frexp"
PythonLength = "Comprimento de um objeto"
PythonLgamma = "Logaritmo da função gama"
@@ -218,6 +169,7 @@ PythonTurtlePosition = "Devolve a posição atual (x,y)"
PythonTurtleReset = "Reiniciar o desenho"
PythonTurtleRight = "Virar à esquerda por a graus"
PythonTurtleSetheading = "Definir a orientação por a graus"
PythonTurtleSetposition = "Positionne la tortue"
PythonTurtleShowturtle = "Mostrar o turtle"
PythonTurtleSpeed = "Velocidade do desenho entre 0 e 10"
PythonTurtleWrite = "Mostrar um texto"
@@ -237,6 +189,8 @@ PythonSysImplementation = "Information about Python"
PythonSysModules = "Dictionary of loaded modules"
PythonSysVersion = "Python language version (string)"
PythonSysVersioninfo = "Python language version (tuple)"
PythonTimePrefix = "time module function prefix"
PythonTimeSleep = "Wait for n second"
PythonMonotonic = "Return monotonic time"
PythonFileOpen = "Opens a file"
PythonFileSeekable = "Tells if seek can be used on a file"

View File

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

View File

@@ -4,7 +4,6 @@
#include "app.h"
#include <escher/metric.h>
#include <ion.h>
#include "../global_preferences.h"
using namespace Shared;
@@ -64,20 +63,10 @@ void EditorController::didBecomeFirstResponder() {
void EditorController::viewWillAppear() {
ViewController::viewWillAppear();
m_editorView.loadSyntaxHighlighter();
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()));
}
m_editorView.setCursorLocation(m_editorView.text() + strlen(m_editorView.text()));
}
void EditorController::viewDidDisappear() {
m_script.setCursorOffset(m_editorView.cursorLocation() - m_script.content());
m_editorView.resetSelection();
m_menuController->scriptContentEditionDidFinish();
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -75,7 +75,6 @@ const ToolboxMessageTree MathModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandAtan2, I18n::Message::PythonAtan2),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCeil, I18n::Message::PythonCeil),
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::PythonCommandFloor, I18n::Message::PythonFloor),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFmod, I18n::Message::PythonFmod),
@@ -366,72 +365,18 @@ const ToolboxMessageTree KandinskyModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFillRect, I18n::Message::PythonFillRect),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFillCircle, I18n::Message::PythonFillCircle),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFillPolygon, I18n::Message::PythonFillPolygon),
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)
};
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandGetKeys, I18n::Message::PythonGetKeys),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandGetPalette, I18n::Message::PythonGetPalette)};
const ToolboxMessageTree IonModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportIon, 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::PythonCommandIsKeyDown, I18n::Message::PythonIsKeyDown),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandGetKeys, I18n::Message::PythonGetKeys),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandBattery, I18n::Message::PythonBattery),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandBatteryLevel, I18n::Message::PythonBatteryLevel),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandBatteryIscharging, I18n::Message::PythonBatteryIscharging),
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)
ToolboxMessageTree::Leaf(I18n::Message::IonSelector, I18n::Message::IonSelector)
};
const ToolboxMessageTree TimeModuleChildren[] = {
@@ -458,7 +403,6 @@ const ToolboxMessageTree OsModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonOsCommandListdir, I18n::Message::PythonOsListdir, false)
};
#if MICROPY_PY_SYS
const ToolboxMessageTree SysModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportSys, I18n::Message::PythonImportSys, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportFromSys, I18n::Message::PythonImportSys, false),
@@ -470,7 +414,6 @@ const ToolboxMessageTree SysModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonSysCommandVersion, I18n::Message::PythonSysVersion, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonSysCommandVersioninfo, I18n::Message::PythonSysVersioninfo, false)
};
#endif
const ToolboxMessageTree modulesChildren[] = {
ToolboxMessageTree::Node(I18n::Message::MathModule, MathModuleChildren),
@@ -484,9 +427,7 @@ const ToolboxMessageTree modulesChildren[] = {
ToolboxMessageTree::Node(I18n::Message::KandinskyModule, KandinskyModuleChildren),
ToolboxMessageTree::Node(I18n::Message::IonModule, IonModuleChildren),
ToolboxMessageTree::Node(I18n::Message::OsModule, OsModuleChildren),
#if MICROPY_PY_SYS
ToolboxMessageTree::Node(I18n::Message::SysModule, SysModuleChildren),
#endif
ToolboxMessageTree::Node(I18n::Message::TimeModule, TimeModuleChildren)
};
@@ -751,13 +692,19 @@ KDCoordinate PythonToolbox::rowHeight(int j) {
return Toolbox::rowHeight(j);
}
bool PythonToolbox::selectLeaf(int selectedRow, bool quitToolbox) {
bool PythonToolbox::selectLeaf(int selectedRow) {
ToolboxMessageTree * node = (ToolboxMessageTree *)m_messageTreeModel->childAtIndex(selectedRow);
#if defined(INCLUDE_ULAB)
if(node->text() == I18n::Message::UlabDocumentationLink){
return true;
}
#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());
// strippedEditedText array needs to be in the same scope as editedText
char strippedEditedText[k_maxMessageSize];
@@ -768,25 +715,10 @@ bool PythonToolbox::selectLeaf(int selectedRow, bool quitToolbox) {
editedText = strippedEditedText;
}
sender()->handleEventWithText(editedText, true);
if (quitToolbox) {
m_selectableTableView.deselectTable();
Container::activeApp()->dismissModalViewController();
}
Container::activeApp()->dismissModalViewController();
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 {
return &toolboxModel;
}

View File

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

View File

@@ -65,21 +65,6 @@ bool Script::nameCompliant(const char * name) {
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) {
return const_cast<uint8_t *>(static_cast<const uint8_t *>(d.buffer));
}

View File

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

View File

@@ -21,10 +21,10 @@ void ScriptNodeCell::ScriptNodeView::drawRect(KDContext * ctx, KDRect rect) cons
const int nodeNameLength = m_scriptNode->nameLength();
KDSize nameSize = k_font->stringSize(nodeName, nodeNameLength);
const KDCoordinate nodeNameY = k_topMargin;
ctx->drawString(nodeName, KDPoint(0, nodeNameY), k_font, Palette::PrimaryText, backgroundColor, nodeNameLength);
ctx->drawString(nodeName, KDPoint(0, nodeNameY), k_font, KDColorBlack, backgroundColor, nodeNameLength);
// If it is needed, draw the parentheses
if (m_scriptNode->type() == ScriptNode::Type::WithParentheses) {
ctx->drawString(ScriptNodeCell::k_parentheses, KDPoint(nameSize.width(), nodeNameY), k_font, Palette::PrimaryText, backgroundColor);
ctx->drawString(ScriptNodeCell::k_parentheses, KDPoint(nameSize.width(), nodeNameY), k_font, KDColorBlack, backgroundColor);
}
/* If it exists, draw the source name. If it did not fit, we would have put

View File

@@ -8,9 +8,11 @@ bool ScriptStore::ScriptNameIsFree(const char * baseName) {
return ScriptBaseNamed(baseName).isNull();
}
// Here we add "base" script
ScriptStore::ScriptStore() {
addScriptFromTemplate(ScriptTemplate::Squares());
addScriptFromTemplate(ScriptTemplate::Parabola());
addScriptFromTemplate(ScriptTemplate::Mandelbrot());
addScriptFromTemplate(ScriptTemplate::Polynomial());
}
void ScriptStore::deleteAllScripts() {

View File

@@ -49,7 +49,7 @@ private:
* k_fullFreeSpaceSizeLimit, we consider the script store as full.
* 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
* importation status (1 char), the cursor (2 char), the default content "from math import *\n"
* importation status (1 char), the default content "from math import *\n"
* (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;
};

View File

@@ -5,9 +5,103 @@ namespace Code {
constexpr ScriptTemplate emptyScriptTemplate(".py", "\x01" R"(from math import *
)");
constexpr ScriptTemplate squaresScriptTemplate("squares.py", "\x01" R"(from math import *
from turtle import *
def squares(angle=0.5):
reset()
L=330
speed(10)
penup()
goto(-L/2,-L/2)
pendown()
for i in range(660):
forward(L)
left(90+angle)
L=L-L*sin(angle*pi/180)
hideturtle())");
constexpr ScriptTemplate mandelbrotScriptTemplate("mandelbrot.py", "\x01" R"(# This script draws a Mandelbrot fractal set
# N_iteration: degree of precision
import kandinsky
def mandelbrot(N_iteration):
for x in range(320):
for y in range(222):
# Compute the mandelbrot sequence for the point c = (c_r, c_i) with start value z = (z_r, z_i)
z = complex(0,0)
# Rescale to fit the drawing screen 320x222
c = complex(3.5*x/319-2.5, -2.5*y/221+1.25)
i = 0
while (i < N_iteration) and abs(z) < 2:
i = i + 1
z = z*z+c
# Choose the color of the dot from the Mandelbrot sequence
rgb = int(255*i/N_iteration)
col = kandinsky.color(int(rgb*0.82),int(rgb*0.13),int(rgb*0.18))
# Draw a pixel colored in 'col' at position (x,y)
kandinsky.set_pixel(x,y,col))");
constexpr ScriptTemplate polynomialScriptTemplate("polynomial.py", "\x01" R"(from math import *
# roots(a,b,c) computes the solutions of the equation a*x**2+b*x+c=0
def roots(a,b,c):
delta = b*b-4*a*c
if delta == 0:
return -b/(2*a)
elif delta > 0:
x_1 = (-b-sqrt(delta))/(2*a)
x_2 = (-b+sqrt(delta))/(2*a)
return x_1, x_2
else:
return None)");
constexpr ScriptTemplate parabolaScriptTemplate("parabola.py", "\x01" R"(from matplotlib.pyplot import *
from math import *
g=9.81
def x(t,v_0,alpha):
return v_0*cos(alpha)*t
def y(t,v_0,alpha,h_0):
return -0.5*g*t**2+v_0*sin(alpha)*t+h_0
def vx(v_0,alpha):
return v_0*cos(alpha)
def vy(t,v_0,alpha):
return -g*t+v_0*sin(alpha)
def t_max(v_0,alpha,h_0):
return (v_0*sin(alpha)+sqrt((v_0**2)*(sin(alpha)**2)+2*g*h_0))/g
def simulation(v_0=15,alpha=pi/4,h_0=2):
tMax=t_max(v_0,alpha,h_0)
accuracy=1/10**(floor(log10(tMax))-1)
T_MAX=floor(tMax*accuracy)+1
X=[x(t/accuracy,v_0,alpha) for t in range(T_MAX)]
Y=[y(t/accuracy,v_0,alpha,h_0) for t in range(T_MAX)]
VX=[vx(v_0,alpha) for t in range(T_MAX)]
VY=[vy(t/accuracy,v_0,alpha) for t in range(T_MAX)]
for i in range(T_MAX):
arrow(X[i],Y[i],VX[i]/accuracy,VY[i]/accuracy)
grid()
show())");
const ScriptTemplate * ScriptTemplate::Empty() {
return &emptyScriptTemplate;
}
const ScriptTemplate * ScriptTemplate::Squares() {
return &squaresScriptTemplate;
}
const ScriptTemplate * ScriptTemplate::Mandelbrot() {
return &mandelbrotScriptTemplate;
}
const ScriptTemplate * ScriptTemplate::Polynomial() {
return &polynomialScriptTemplate;
}
const ScriptTemplate * ScriptTemplate::Parabola() {
return &parabolaScriptTemplate;
}
}

View File

@@ -9,8 +9,12 @@ class ScriptTemplate {
public:
constexpr ScriptTemplate(const char * name, const char * value) : m_name(name), m_value(value) {}
static const ScriptTemplate * Empty();
static const ScriptTemplate * Squares();
static const ScriptTemplate * Mandelbrot();
static const ScriptTemplate * Polynomial();
static const ScriptTemplate * Parabola();
const char * name() const { return m_name; }
const char * content() const { return m_value; + Script::StatusSize();}
const char * content() const { return m_value + Script::StatusSize(); }
const char * value() const { return m_value; }
private:
const char * m_name;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,52 +6,45 @@ extern "C" {
#include <py/obj.h>
#include <py/objfun.h>
}
extern "C" const mp_rom_map_elem_t modion_module_globals_table[52];
extern const mp_rom_map_elem_t modion_module_globals_table[48];
namespace Code {
ToolboxIonKeys::ToolboxIonKeys() :
toolboxIonKeys::toolboxIonKeys() :
ViewController(nullptr),
m_view()
{
}
{
}
bool ToolboxIonKeys::handleEvent(Ion::Events::Event e) {
// FIXME: Use event data to get the pressed key and fix the EXE key.
Ion::Keyboard::State state = Ion::Keyboard::scan();
for (uint16_t i = 0; i < sizeof(modion_module_globals_table) / sizeof(_mp_rom_map_elem_t); i++) {
_mp_rom_map_elem_t element = modion_module_globals_table[i];
if (mp_obj_is_small_int(element.value)) {
int key = mp_obj_get_int(element.value);
if (state.keyDown(static_cast<Ion::Keyboard::Key>(key))) {
m_sender->handleEventWithText(qstr_str(MP_OBJ_QSTR_VALUE(element.key)), true);
bool toolboxIonKeys::handleEvent(Ion::Events::Event e) {
Ion::Keyboard::State state = Ion::Keyboard::scan();
for(uint16_t i = 0; i < sizeof(modion_module_globals_table)/sizeof(_mp_rom_map_elem_t); i++){
_mp_rom_map_elem_t element = modion_module_globals_table[i];
if(mp_obj_is_small_int(element.value)){
int key = mp_obj_get_int(element.value);
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() :
View()
{
}
toolboxIonKeys::toolboxIonView::toolboxIonView():
View()
{
}
void ToolboxIonKeys::toolboxIonView::drawRect(KDContext * ctx, KDRect rect) const {
ctx->fillRect(rect, Palette::WallScreen);
ctx->strokeRect(rect, Palette::ListCellBorder);
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);
void toolboxIonKeys::toolboxIonView::drawRect(KDContext * ctx, KDRect rect) const {
ctx->fillRect(rect, Palette::GrayBright);
ctx->strokeRect(rect, Palette::GrayDark);
ctx->drawString(I18n::translate(I18n::Message::PressAKey),KDPoint(rect.left()+80, rect.top()+20));
ctx->drawString(message, textPosition, KDFont::LargeFont, Palette::PrimaryText, Palette::WallScreen);
}
View * ToolboxIonKeys::view() {
return &m_view;
}
}
View * toolboxIonKeys::view(){
return &m_view;
}
}

View File

@@ -2,9 +2,9 @@
namespace Code {
class ToolboxIonKeys : public ViewController {
class toolboxIonKeys : public ViewController {
public :
ToolboxIonKeys();
toolboxIonKeys();
View * view() override;
bool handleEvent(Ion::Events::Event e) override;
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 quitToolbox) {
bool VariableBoxController::selectLeaf(int rowIndex) {
assert(rowIndex >= 0 && rowIndex < numberOfRows());
m_selectableTableView.deselectTable();
@@ -516,7 +516,7 @@ void VariableBoxController::loadBuiltinNodes(const char * textToAutocomplete, in
assert(sizeof(builtinNames) / sizeof(builtinNames[0]) == k_totalBuiltinNodesCount);
for (int i = 0; i < k_totalBuiltinNodesCount; i++) {
if (addNodeIfMatches(textToAutocomplete, textToAutocompleteLength, builtinNames[i].type, NodeOrigin::Builtins, builtinNames[i].name)) {
/* We can leverage on the fact that builtin nodes are stored in
/* We can leverage on the fact that buitin nodes are stored in
* alphabetical order. */
return;
}
@@ -575,7 +575,7 @@ void VariableBoxController::loadImportedVariablesInScript(const char * scriptCon
}
void VariableBoxController::loadCurrentVariablesInScript(const char * scriptContent, const char * textToAutocomplete, int textToAutocompleteLength) {
/* To find variable and function names: we lex the script and keep all
/* To find variable and funtion names: we lex the script and keep all
* MP_TOKEN_NAME that complete the text to autocomplete and are not already in
* 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
* will not have main structures of the wanted type.
* We look for structures at first level (not inside nested scopes) that
* are either function definitions, variables statements or imports. */
* are either dunction definitions, variables statements or imports. */
size_t n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
for (size_t i = 0; i < n; 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;
}
bool VariableBoxController::importationSourceIsScript(const char * sourceName, const char * * scriptFullName, Script * retrievedScript) {
bool VariableBoxController::importationSourceIsScript(const char * sourceName, const char * * scriptFullName, Script * retreivedScript) {
// Try fetching the nodes from a script
Script importedScript = ScriptStore::ScriptBaseNamed(sourceName);
if (importedScript.isNull()) {
return false;
}
*scriptFullName = importedScript.fullName();
if (retrievedScript != nullptr) {
*retrievedScript = importedScript;
if (retreivedScript != nullptr) {
*retreivedScript = importedScript;
}
return true;
}

View File

@@ -80,7 +80,7 @@ private:
// NestedMenuController
HighlightCell * leafCellAtIndex(int index) override { assert(false); return nullptr; }
HighlightCell * nodeCellAtIndex(int index) override { assert(false); return nullptr; }
bool selectLeaf(int rowIndex, bool quitToolbox) override;
bool selectLeaf(int rowIndex) override;
void insertTextInCaller(const char * text, int textLength = -1);
// Loading
@@ -92,7 +92,7 @@ private:
bool addNodesFromImportMaybe(mp_parse_node_struct_t * parseNode, const char * textToAutocomplete, int textToAutocompleteLength, bool importFromModules = true);
const char * importationSourceNameFromNode(mp_parse_node_t & node);
bool importationSourceIsModule(const char * sourceName, const ToolboxMessageTree * * moduleChildren = nullptr, int * numberOfModuleChildren = nullptr);
bool importationSourceIsScript(const char * sourceName, const char * * scriptFullName, Script * retrievedScript = nullptr);
bool importationSourceIsScript(const char * sourceName, const char * * scriptFullName, Script * retreivedScript = nullptr);
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
* 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;
StackViewController m_stackViewController;
Window * m_window;
static constexpr int k_externalHeapSize = 99000;
static constexpr int k_externalHeapSize = 100000;
char m_externalHeap[k_externalHeapSize];
};

View File

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

View File

@@ -9,16 +9,10 @@
#include "../apps_container.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>
extern "C" {
#include <python/port/mphalport.h>
#include <python/port/mphalport.h>
}
uint64_t extapp_millis() {
@@ -36,7 +30,7 @@ uint64_t extapp_scanKeyboard() {
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);
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) {
@@ -48,10 +42,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) {
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);
auto ctx = KDIonContext::sharedContext();
@@ -62,7 +56,7 @@ int16_t extapp_drawTextLarge(const char * text, int16_t x, int16_t y, uint16_t f
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);
auto ctx = KDIonContext::sharedContext();
@@ -77,7 +71,7 @@ bool extapp_waitForVBlank() {
return Ion::Display::waitForVBlank();
}
void extapp_clipboardStore(const char * text) {
void extapp_clipboardStore(const char *text) {
Clipboard::sharedClipboard()->store(text);
}
@@ -85,103 +79,101 @@ const char * extapp_clipboardText() {
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 j = 0;
if (storage == EXTAPP_RAM_FILE_SYSTEM || storage == EXTAPP_BOTH_FILE_SYSTEM) {
if(storage == EXTAPP_RAM_FILE_SYSTEM) {
int n = Ion::Storage::sharedStorage()->numberOfRecordsWithExtension(extension);
if (n > maxrecords) {
n = maxrecords;
}
for (; j < n; j++) {
filenames[j] = Ion::Storage::sharedStorage()->recordWithExtensionAtIndex(extension, j).fullName();
for(int i = 0; i < n; i++) {
filenames[i] = Ion::Storage::sharedStorage()->recordWithExtensionAtIndex(extension, i).fullName();
}
if (j == maxrecords) {
return j;
}
}
// 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) {
return n;
} else if(storage == EXTAPP_FLASH_FILE_SYSTEM) {
// TODO: filter by extension
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;
}
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;
}
return j;
}
bool extapp_fileExists(const char * filename, int storage) {
if (storage == EXTAPP_RAM_FILE_SYSTEM || storage == EXTAPP_BOTH_FILE_SYSTEM) {
if (!Ion::Storage::sharedStorage()->recordNamed(filename).isNull())
return true;
}
if (storage == EXTAPP_FLASH_FILE_SYSTEM || storage == EXTAPP_BOTH_FILE_SYSTEM) {
if(storage == EXTAPP_RAM_FILE_SYSTEM) {
return !Ion::Storage::sharedStorage()->recordNamed(filename).isNull();
} else if(storage == EXTAPP_FLASH_FILE_SYSTEM) {
return External::Archive::indexFromName(filename) >= 0;
} else {
return false;
}
return false;
}
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);
if (record.isNull()) {
if(record.isNull()) {
return false;
} else {
record.destroy();
return true;
}
record.destroy();
return true;
} else {
return false;
}
return false;
}
const char * extapp_fileRead(const char * filename, size_t * len, int storage) {
if (storage == EXTAPP_RAM_FILE_SYSTEM || storage == EXTAPP_BOTH_FILE_SYSTEM) {
const char * extapp_fileRead(const char * filename, size_t *len, int storage) {
if(storage == EXTAPP_RAM_FILE_SYSTEM) {
const Ion::Storage::Record record = Ion::Storage::sharedStorage()->recordNamed(filename);
if (!record.isNull()){
int delta = 0;
if (match(filename, ".py") || match(filename, ".xw"))
delta++;
// skip record type
if (len)
*len = record.value().size - delta;
return (const char *)record.value().buffer + delta;
if (record.isNull()) {
return NULL;
} else {
if(len) {
*len = record.value().size;
}
return (const char *) record.value().buffer;
}
}
if (storage == EXTAPP_FLASH_FILE_SYSTEM || storage == EXTAPP_BOTH_FILE_SYSTEM) {
} else if(storage == EXTAPP_FLASH_FILE_SYSTEM) {
int index = External::Archive::indexFromName(filename);
if (index >= 0) {
External::Archive::File entry;
External::Archive::fileAtIndex(index, entry);
if (len) {
if(len) {
*len = entry.dataLength;
}
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) {
if (storage == EXTAPP_RAM_FILE_SYSTEM) {
if(storage == EXTAPP_RAM_FILE_SYSTEM) {
Ion::Storage::Record::ErrorStatus status = Ion::Storage::sharedStorage()->createRecordWithFullName(filename, content, len);
if (status == Ion::Storage::Record::ErrorStatus::NameTaken) {
Ion::Storage::Record::Data data;
data.buffer = content;
data.size = len;
return Ion::Storage::sharedStorage()->recordNamed(filename).setValue(data) == Ion::Storage::Record::ErrorStatus::None;
}
if (status == Ion::Storage::Record::ErrorStatus::None)
} else if (status == Ion::Storage::Record::ErrorStatus::None) {
return true;
} else {
return false;
}
} else {
return false;
}
return false;
}
static void reloadTitleBar() {
@@ -252,42 +244,19 @@ const int16_t translated_keys[] =
#define TICKS_PER_MINUTE 11862
#endif
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 extapp_getKey(bool allowSuspend, bool *alphaWasActive) {
int key = -1;
size_t t1 = Ion::Timing::millis();
for (;;) {
int timeout = 10000;
if (alphaWasActive) {
if(alphaWasActive) {
*alphaWasActive = Ion::Events::isAlphaActive();
}
Ion::Events::Event event = Ion::Events::getEvent(&timeout);
reloadTitleBar();
if (event == Ion::Events::None) {
size_t t2 = Ion::Timing::millis();
if (t2 - t1 > 3 * TICKS_PER_MINUTE) {
if (t2 - t1 > 2 * TICKS_PER_MINUTE) {
event = Ion::Events::OnOff;
}
} else {
@@ -301,10 +270,10 @@ int extapp_getKey(int allowSuspend, bool * alphaWasActive) {
}
if (event.isKeyboardEvent()) {
key = static_cast<uint8_t>(event);
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) {
if (key == 17 || key == 4 || key == 5 || key == 52) {
extapp_resetKeyboard();
}
if (allowSuspend && key == (int)Ion::Keyboard::Key::OnOff) {
if (allowSuspend && (key == 7 || key == 8)) { // power
Ion::Power::suspend(true);
extapp_pushRectUniform(0, 0, 320, 240, 65535);
Ion::Backlight::setBrightness(GlobalPreferences::sharedGlobalPreferences()->brightnessLevel());
@@ -316,45 +285,6 @@ int extapp_getKey(int allowSuspend, bool * alphaWasActive) {
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) = {
(void (*)(void)) extapp_millis,
(void (*)(void)) extapp_msleep,
@@ -375,10 +305,5 @@ extern "C" void (* const apiPointers[])(void) = {
(void (*)(void)) extapp_lockAlpha,
(void (*)(void)) extapp_resetKeyboard,
(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,
};
};

View File

@@ -18,7 +18,6 @@
#define EXTAPP_RAM_FILE_SYSTEM 0
#define EXTAPP_FLASH_FILE_SYSTEM 1
#define EXTAPP_BOTH_FILE_SYSTEM 2
#define SCANCODE_Left ((uint64_t)1 << 0)
#define SCANCODE_Up ((uint64_t)1 << 1)
@@ -252,10 +251,6 @@ 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 void extapp_lockAlpha();
EXTERNC void extapp_resetKeyboard();
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);
EXTERNC int extapp_getKey(bool allowSuspend, bool *alphaWasActive);
#endif

View File

@@ -41,25 +41,6 @@ void GlobalPreferences::setBrightnessLevel(int brightnessLevel) {
brightnessLevel = brightnessLevel < 0 ? 0 : brightnessLevel;
brightnessLevel = brightnessLevel > Ion::Backlight::MaxBrightness ? Ion::Backlight::MaxBrightness : brightnessLevel;
m_brightnessLevel = brightnessLevel;
Ion::Backlight::setBrightness(m_brightnessLevel);
}
}
void GlobalPreferences::setIdleBeforeSuspendSeconds(int idleBeforeSuspendSeconds) {
if (m_idleBeforeSuspendSeconds != idleBeforeSuspendSeconds) {
idleBeforeSuspendSeconds = idleBeforeSuspendSeconds < 5 ? 5 : idleBeforeSuspendSeconds;
idleBeforeSuspendSeconds = idleBeforeSuspendSeconds > 7200 ? 7200 : idleBeforeSuspendSeconds;
m_idleBeforeSuspendSeconds = idleBeforeSuspendSeconds;
}
}
void GlobalPreferences::setIdleBeforeDimmingSeconds(int idleBeforeDimmingSeconds) {
if (m_idleBeforeDimmingSeconds != idleBeforeDimmingSeconds) {
idleBeforeDimmingSeconds = idleBeforeDimmingSeconds < 3 ? 3 : idleBeforeDimmingSeconds;
idleBeforeDimmingSeconds = idleBeforeDimmingSeconds > 1200 ? 1200 : idleBeforeDimmingSeconds;
m_idleBeforeDimmingSeconds = idleBeforeDimmingSeconds;
}
}
void GlobalPreferences::setBrightnessShortcut(int brightnessShortcut){
m_brightnessShortcut = brightnessShortcut;
}

View File

@@ -30,29 +30,13 @@ public:
void setTempExamMode(ExamMode examMode);
bool showPopUp() const { return m_showPopUp; }
void setShowPopUp(bool showPopUp) { m_showPopUp = showPopUp; }
bool dfuUnlocked() const { return m_dfuUnlocked; }
void setDfuUnlocked(bool unlocked) { m_dfuUnlocked = unlocked; }
bool autocomplete() const { return m_autoComplete; }
void setAutocomplete(bool autocomple) { m_autoComplete = autocomple; }
bool syntaxhighlighting() const { return m_syntaxhighlighting; }
void setSyntaxhighlighting(bool syntaxhighlight) { m_syntaxhighlighting = syntaxhighlight; }
bool cursorSaving() const { return m_cursorSaving; }
void setCursorSaving(bool cursorsave) { m_cursorSaving = cursorsave; }
int brightnessLevel() const { return m_brightnessLevel; }
void setBrightnessLevel(int brightnessLevel);
const KDFont * font() const { return m_font; }
void setFont(const KDFont * font) { m_font = font; }
constexpr static int NumberOfBrightnessStates = 15;
int idleBeforeSuspendSeconds() const { return m_idleBeforeSuspendSeconds; }
void setIdleBeforeSuspendSeconds(int m_idleBeforeSuspendSeconds);
int idleBeforeDimmingSeconds() const { return m_idleBeforeDimmingSeconds; }
void setIdleBeforeDimmingSeconds(int m_idleBeforeDimmingSeconds);
int brightnessShortcut() const { return m_brightnessShortcut; }
void setBrightnessShortcut(int m_BrightnessShortcut);
bool externalAppWritePermission() const { return m_externalAppWritePermission; }
void setExternalAppWritePermission(bool extapp_write) { m_externalAppWritePermission = extapp_write; }
bool externalAppShown() const { return m_externalAppShown; }
void setExternalAppShown(bool externalAppShown) { m_externalAppShown = externalAppShown; }
private:
static_assert(I18n::NumberOfLanguages > 0, "I18n::NumberOfLanguages is not superior to 0"); // There should already have been an error when processing an empty EPSILON_I18N flag
static_assert(I18n::NumberOfCountries > 0, "I18n::NumberOfCountries is not superior to 0"); // There should already have been an error when processing an empty EPSILON_COUNTRIES flag
@@ -62,16 +46,8 @@ private:
m_examMode(ExamMode::Unknown),
m_tempExamMode(ExamMode::Standard),
m_showPopUp(true),
m_dfuUnlocked(false),
m_autoComplete(true),
m_syntaxhighlighting(true),
m_cursorSaving(true),
m_brightnessLevel(Ion::Backlight::MaxBrightness),
m_idleBeforeSuspendSeconds(55),
m_idleBeforeDimmingSeconds(45),
m_brightnessShortcut(4),
m_externalAppWritePermission(false),
m_externalAppShown(true),
m_font(KDFont::LargeFont) {}
I18n::Language m_language;
I18n::Country m_country;
@@ -80,16 +56,8 @@ private:
mutable ExamMode m_examMode;
mutable ExamMode m_tempExamMode;
bool m_showPopUp;
bool m_dfuUnlocked;
bool m_autoComplete;
bool m_syntaxhighlighting;
bool m_cursorSaving;
int m_brightnessLevel;
int m_idleBeforeSuspendSeconds;
int m_idleBeforeDimmingSeconds;
int m_brightnessShortcut;
bool m_externalAppWritePermission;
bool m_externalAppShown;
const KDFont * m_font;
};

View File

@@ -27,8 +27,7 @@ const Image * App::Descriptor::icon() {
App::Snapshot::Snapshot() :
Shared::FunctionApp::Snapshot::Snapshot(),
m_functionStore(),
m_graphRange(),
m_shouldDisplayDerivative(false)
m_graphRange()
{
}
@@ -41,7 +40,6 @@ void App::Snapshot::reset() {
for (int i = 0; i < Shared::ContinuousFunction::k_numberOfPlotTypes; i++) {
m_interval[i].reset();
}
m_shouldDisplayDerivative = false;
}
App::Descriptor * App::Snapshot::descriptor() {
@@ -60,7 +58,7 @@ App::App(Snapshot * snapshot) :
m_listFooter(&m_listHeader, &m_listController, &m_listController, ButtonRowController::Position::Bottom, ButtonRowController::Style::EmbossedGray),
m_listHeader(&m_listStackViewController, &m_listFooter, &m_listController),
m_listStackViewController(&m_tabViewController, &m_listHeader),
m_graphController(&m_graphAlternateEmptyViewController, this, snapshot->graphRange(), snapshot->cursor(), snapshot->indexFunctionSelectedByCursor(), snapshot->rangeVersion(), &m_graphHeader, snapshot->shouldDisplayDerivative()),
m_graphController(&m_graphAlternateEmptyViewController, this, snapshot->graphRange(), snapshot->cursor(), snapshot->indexFunctionSelectedByCursor(), snapshot->rangeVersion(), &m_graphHeader),
m_graphAlternateEmptyViewController(&m_graphHeader, &m_graphController, &m_graphController),
m_graphHeader(&m_graphStackViewController, &m_graphAlternateEmptyViewController, &m_graphController),
m_graphStackViewController(&m_tabViewController, &m_graphHeader),

View File

@@ -31,13 +31,11 @@ public:
Shared::Interval * intervalForType(Shared::ContinuousFunction::PlotType plotType) {
return m_interval + static_cast<size_t>(plotType);
}
bool * shouldDisplayDerivative() { return &m_shouldDisplayDerivative; }
private:
void tidy() override;
ContinuousFunctionStore m_functionStore;
Shared::InteractiveCurveViewRange m_graphRange;
Shared::Interval m_interval[Shared::ContinuousFunction::k_numberOfPlotTypes];
bool m_shouldDisplayDerivative;
};
static App * app() {
return static_cast<App *>(Container::activeApp());

View File

@@ -7,13 +7,13 @@ using namespace Shared;
namespace Graph {
GraphController::GraphController(Responder * parentResponder, ::InputEventHandlerDelegate * inputEventHandlerDelegate, Shared::InteractiveCurveViewRange * curveViewRange, CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * rangeVersion, ButtonRowController * header, bool * shouldDisplayDerivative) :
GraphController::GraphController(Responder * parentResponder, ::InputEventHandlerDelegate * inputEventHandlerDelegate, Shared::InteractiveCurveViewRange * curveViewRange, CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * rangeVersion, ButtonRowController * header) :
FunctionGraphController(parentResponder, inputEventHandlerDelegate, header, curveViewRange, &m_view, cursor, indexFunctionSelectedByCursor, rangeVersion),
m_bannerView(this, inputEventHandlerDelegate, this),
m_view(curveViewRange, m_cursor, &m_bannerView, &m_cursorView),
m_graphRange(curveViewRange),
m_curveParameterController(inputEventHandlerDelegate, curveViewRange, &m_bannerView, m_cursor, &m_view, this),
m_displayDerivativeInBanner(shouldDisplayDerivative)
m_displayDerivativeInBanner(false)
{
m_graphRange->setDelegate(this);
}
@@ -47,7 +47,7 @@ void GraphController::selectFunctionWithCursor(int functionIndex) {
void GraphController::reloadBannerView() {
Ion::Storage::Record record = functionStore()->activeRecordAtIndex(indexFunctionSelectedByCursor());
bool displayDerivative = *m_displayDerivativeInBanner &&
bool displayDerivative = m_displayDerivativeInBanner &&
functionStore()->modelForRecord(record)->plotType() == ContinuousFunction::PlotType::Cartesian;
m_bannerView.setNumberOfSubviews(Shared::XYBannerView::k_numberOfSubviews + displayDerivative);
FunctionGraphController::reloadBannerView();

View File

@@ -15,13 +15,13 @@ namespace Graph {
class GraphController : public Shared::FunctionGraphController, public GraphControllerHelper {
public:
GraphController(Responder * parentResponder, ::InputEventHandlerDelegate * inputEventHandlerDelegate, Shared::InteractiveCurveViewRange * curveViewRange, Shared::CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * rangeVersion, ButtonRowController * header, bool * shouldDisplayDerivative);
GraphController(Responder * parentResponder, ::InputEventHandlerDelegate * inputEventHandlerDelegate, Shared::InteractiveCurveViewRange * curveViewRange, Shared::CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * rangeVersion, ButtonRowController * header);
I18n::Message emptyMessage() override;
void viewWillAppear() override;
bool displayDerivativeInBanner() const { return *m_displayDerivativeInBanner; }
void setDisplayDerivativeInBanner(bool displayDerivative) { *m_displayDerivativeInBanner = displayDerivative; }
bool displayDerivativeInBanner() const { return m_displayDerivativeInBanner; }
void setDisplayDerivativeInBanner(bool displayDerivative) { m_displayDerivativeInBanner = displayDerivative; }
private:
int estimatedBannerNumberOfLines() const override { return 1 + *m_displayDerivativeInBanner; }
int estimatedBannerNumberOfLines() const override { return 1 + m_displayDerivativeInBanner; }
void selectFunctionWithCursor(int functionIndex) override;
BannerView * bannerView() override { return &m_bannerView; }
void reloadBannerView() override;
@@ -41,7 +41,7 @@ private:
GraphView m_view;
Shared::InteractiveCurveViewRange * m_graphRange;
CurveParameterController m_curveParameterController;
bool * m_displayDerivativeInBanner;
bool m_displayDerivativeInBanner;
};
}

View File

@@ -21,8 +21,6 @@ public:
bool textFieldDidAbortEditing(TextField * textField) override;
bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override;
bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override;
protected:
virtual const char * recordExtension() const override { return Ion::Storage::funcExtension; }
private:
constexpr static int k_maxNumberOfDisplayableRows = 5;
Shared::ListParameterController * parameterController() override;

View File

@@ -41,7 +41,7 @@ bool ListParameterController::handleEvent(Ion::Events::Event event) {
}
if (event == Ion::Events::Right) {
int selectedR = selectedRow();
if (selectedR == 0 || selectedR == 1 || selectedR == 3) {
if (selectedR == 0 || selectedR == 1) {
// Go in the submenu
return handleEnterOnRow(selectedR);
}

View File

@@ -343,7 +343,7 @@ EvenOddBufferTextCell * ValuesController::floatCells(int j) {
/* ValuesController::ValuesSelectableTableView */
int writeMatrixBrackets(char * buffer, const int bufferSize, int type) {
int writeMatrixBrakets(char * buffer, const int bufferSize, int type) {
/* Write the double brackets required in matrix notation.
* - type == 1: "[["
* - type == 0: "]["
@@ -365,14 +365,14 @@ bool ValuesController::ValuesSelectableTableView::handleEvent(Ion::Events::Event
constexpr int bufferSize = 2*PrintFloat::k_maxFloatCharSize + 6; // "[[a][b]]" gives 6 characters in addition to the 2 floats
char buffer[bufferSize];
int currentChar = 0;
currentChar += writeMatrixBrackets(buffer + currentChar, bufferSize - currentChar, -1);
currentChar += writeMatrixBrakets(buffer + currentChar, bufferSize - currentChar, -1);
assert(currentChar < bufferSize-1);
size_t semiColonPosition = UTF8Helper::CopyUntilCodePoint(buffer+currentChar, TextField::maxBufferSize() - currentChar, text+1, ';');
currentChar += semiColonPosition;
currentChar += writeMatrixBrackets(buffer + currentChar, bufferSize - currentChar, 0);
currentChar += writeMatrixBrakets(buffer + currentChar, bufferSize - currentChar, 0);
assert(currentChar < bufferSize-1);
currentChar += UTF8Helper::CopyUntilCodePoint(buffer+currentChar, TextField::maxBufferSize() - currentChar, text+1+semiColonPosition+1, ')');
currentChar += writeMatrixBrackets(buffer + currentChar, bufferSize - currentChar, 1);
currentChar += writeMatrixBrakets(buffer + currentChar, bufferSize - currentChar, 1);
assert(currentChar < bufferSize-1);
buffer[currentChar] = 0;
Clipboard::sharedClipboard()->store(buffer);

View File

@@ -12,7 +12,7 @@ i18n_files += $(call i18n_without_universal_for,home/base)
# Apps layout file generation
# The header is referred to as <apps/home/apps_layout.h> so make sure it's
# The header is refered to as <apps/home/apps_layout.h> so make sure it's
# findable this way
SFLAGS += -I$(BUILD_DIR)

View File

@@ -1,2 +1,2 @@
Default,calculation,graph,rpn,code,statistics,probability,solver,atomic,sequence,regression,reader,settings
HidePython,calculation,graph,rpn,code,statistics,probability,solver,atomic,sequence,regression,reader,settings
Default,calculation,rpn,graph,code,statistics,probability,solver,atomic,sequence,regression,reader,settings
HidePython,calculation,rpn,graph,code,statistics,probability,solver,atomic,sequence,regression,reader,settings
1 Default calculation rpn graph code statistics probability solver atomic sequence regression reader settings
2 HidePython calculation rpn graph code statistics probability solver atomic sequence regression reader settings

View File

@@ -1,4 +1,4 @@
Apps = "Anwendungen"
AppsCapital = "UPSILON"
ForbiddenAppInExamMode1 = "Diese Anwendung ist im"
ForbiddenAppInExamMode2 = "Prüfungsmodus nicht erlaubt."
ForbidenAppInExamMode1 = "Diese Anwendung ist im"
ForbidenAppInExamMode2 = "Prüfungsmodus nicht erlaubt."

View File

@@ -1,4 +1,4 @@
Apps = "Applications"
AppsCapital = "UPSILON"
ForbiddenAppInExamMode1 = "This application is"
ForbiddenAppInExamMode2 = "forbidden in exam mode"
ForbidenAppInExamMode1 = "This application is"
ForbidenAppInExamMode2 = "forbidden in exam mode"

View File

@@ -1,4 +1,4 @@
Apps = "Aplicaciones"
AppsCapital = "UPSILON"
ForbiddenAppInExamMode1 = "Esta aplicación está prohibida"
ForbiddenAppInExamMode2 = "en el modo de examen"
ForbidenAppInExamMode1 = "Esta aplicación está prohibida"
ForbidenAppInExamMode2 = "en el modo de examen"

View File

@@ -1,4 +1,4 @@
Apps = "Applications"
AppsCapital = "UPSILON"
ForbiddenAppInExamMode1 = "Cette application n'est"
ForbiddenAppInExamMode2 = "pas autorisée en mode examen."
ForbidenAppInExamMode1 = "Cette application n'est"
ForbidenAppInExamMode2 = "pas autorisée en mode examen."

View File

@@ -1,4 +1,4 @@
Apps = "Alkalmazások"
AppsCapital = "UPSILON"
ForbiddenAppInExamMode1 = "Ez az alkalmazás"
ForbiddenAppInExamMode2 = "tilos vizsga módban"
ForbidenAppInExamMode1 = "Ez az alkalmazás"
ForbidenAppInExamMode2 = "tilos vizsga módban"

View File

@@ -1,4 +1,4 @@
Apps = "Applicazioni"
AppsCapital = "UPSILON"
ForbiddenAppInExamMode1 = "Questa applicazione è"
ForbiddenAppInExamMode2 = "proibita nella modalità d'esame"
ForbidenAppInExamMode1 = "Questa applicazione è"
ForbidenAppInExamMode2 = "proibita nella modalità d'esame"

View File

@@ -1,4 +1,4 @@
Apps = "Applicaties"
AppsCapital = "UPSILON"
ForbiddenAppInExamMode1 = "Deze applicatie is"
ForbiddenAppInExamMode2 = "uitgesloten in examenstand"
ForbidenAppInExamMode1 = "Deze applicatie is"
ForbidenAppInExamMode2 = "uitgesloten in examenstand"

View File

@@ -1,4 +1,4 @@
Apps = "Aplicações"
AppsCapital = "UPSILON"
ForbiddenAppInExamMode1 = "Esta aplicação é"
ForbiddenAppInExamMode2 = "proibida no Modo de Exame"
ForbidenAppInExamMode1 = "Esta aplicação é"
ForbidenAppInExamMode2 = "proibida no Modo de Exame"

View File

@@ -94,7 +94,7 @@ bool Controller::handleEvent(Ion::Events::Event event) {
#ifdef HOME_DISPLAY_EXTERNALS
if (index >= container->numberOfApps()) {
if (GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::Dutch || GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::NoSymNoText || GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::NoSym) {
App::app()->displayWarning(I18n::Message::ForbiddenAppInExamMode1, I18n::Message::ForbiddenAppInExamMode2);
App::app()->displayWarning(I18n::Message::ForbidenAppInExamMode1, I18n::Message::ForbidenAppInExamMode2);
} else {
External::Archive::File executable;
if (External::Archive::executableAtIndex(index - container->numberOfApps(), executable)) {
@@ -120,7 +120,7 @@ bool Controller::handleEvent(Ion::Events::Event event) {
#endif
::App::Snapshot * selectedSnapshot = container->appSnapshotAtIndex(index);
if (ExamModeConfiguration::appIsForbiddenInExamMode(selectedSnapshot->descriptor()->examinationLevel(), GlobalPreferences::sharedGlobalPreferences()->examMode())) {
App::app()->displayWarning(I18n::Message::ForbiddenAppInExamMode1, I18n::Message::ForbiddenAppInExamMode2);
App::app()->displayWarning(I18n::Message::ForbidenAppInExamMode1, I18n::Message::ForbidenAppInExamMode2);
} else {
bool switched = container->switchTo(selectedSnapshot);
assert(switched);

View File

@@ -30,7 +30,7 @@ const ToolboxMessageTree calculChildren[] = {
const ToolboxMessageTree complexChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::AbsCommandWithArg,I18n::Message::ComplexAbsoluteValue),
ToolboxMessageTree::Leaf(I18n::Message::ArgCommandWithArg, I18n::Message::Argument),
ToolboxMessageTree::Leaf(I18n::Message::ArgCommandWithArg, I18n::Message::Agument),
ToolboxMessageTree::Leaf(I18n::Message::ReCommandWithArg, I18n::Message::RealPart),
ToolboxMessageTree::Leaf(I18n::Message::ImCommandWithArg, I18n::Message::ImaginaryPart),
ToolboxMessageTree::Leaf(I18n::Message::ConjCommandWithArg, I18n::Message::Conjugate)
@@ -252,7 +252,7 @@ const ToolboxMessageTree unitEnergyElectronVoltChildren[] = {
};
const ToolboxMessageTree unitEnergyChildren[] = {
ToolboxMessageTree::Node(I18n::Message::UnitEnergyJouleMenu, unitEnergyJouleChildren),
ToolboxMessageTree::Node(I18n::Message::UnitEnergyElectronVoltMenu, unitEnergyElectronVoltChildren)};
ToolboxMessageTree::Node(I18n::Message::UnitEnergyEletronVoltMenu, unitEnergyElectronVoltChildren)};
const ToolboxMessageTree unitPowerWattChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::UnitPowerWattMicroSymbol, I18n::Message::UnitPowerWattMicro),
@@ -877,7 +877,7 @@ MathToolbox::MathToolbox() :
{
}
bool MathToolbox::selectLeaf(int selectedRow, bool quitToolbox) {
bool MathToolbox::selectLeaf(int selectedRow) {
ToolboxMessageTree * messageTree = (ToolboxMessageTree *)m_messageTreeModel->childAtIndex(selectedRow);
m_selectableTableView.deselectTable();

View File

@@ -9,7 +9,7 @@ public:
MathToolbox();
const ToolboxMessageTree * rootModel() const override;
protected:
bool selectLeaf(int selectedRow, bool quitToolbox) override;
bool selectLeaf(int selectedRow) override;
MessageTableCellWithMessage * leafCellAtIndex(int index) override;
MessageTableCellWithChevron* nodeCellAtIndex(int index) override;
int maxNumberOfDisplayedRows() override;

View File

@@ -124,7 +124,7 @@ void MathVariableBoxController::willDisplayCellForIndex(HighlightCell * cell, in
symbolName,
Shared::Sequence::k_maxNameWithArgumentSize
);
Expression symbolExpression = Expression::Parse(symbolName, AppsContainer::sharedAppsContainer()->globalContext());
Expression symbolExpression = Expression::ParseAndSimplify(symbolName, AppsContainer::sharedAppsContainer()->globalContext(), Poincare::Preferences::sharedPreferences()->complexFormat(), Poincare::Preferences::sharedPreferences()->angleUnit(), GlobalPreferences::sharedGlobalPreferences()->unitFormat());
symbolLayout = symbolExpression.createLayout(Poincare::Preferences::sharedPreferences()->displayMode(), Poincare::Preferences::sharedPreferences()->numberOfSignificantDigits());
}
if (symbolLayout.isUninitialized()) {
@@ -193,7 +193,7 @@ bool MathVariableBoxController::returnToPreviousMenu() {
return AlternateEmptyNestedMenuController::returnToPreviousMenu();
}
bool MathVariableBoxController::selectLeaf(int selectedRow, bool quitToolbox) {
bool MathVariableBoxController::selectLeaf(int selectedRow) {
if (isDisplayingEmptyController()) {
/* We do not want to handle OK/EXE events in that case. */
return false;

View File

@@ -42,7 +42,7 @@ private:
void setPage(Page page);
bool selectSubMenu(int selectedRow) override;
bool returnToPreviousMenu() override;
bool selectLeaf(int selectedRow, bool quitToolbox) override;
bool selectLeaf(int selectedRow) override;
I18n::Message nodeLabelAtIndex(int index);
Poincare::Layout expressionLayoutForRecord(Ion::Storage::Record record, int index);
const char * extension() const;

View File

@@ -5,7 +5,7 @@
MathVariableBoxEmptyController::MathVariableBoxEmptyView::MathVariableBoxEmptyView() :
ModalViewEmptyView(),
m_layoutExample(0.5f, 0.5f, Palette::PrimaryText, Palette::WallScreen)
m_layoutExample(0.5f, 0.5f, KDColorBlack, Palette::WallScreen)
{
initMessageViews();
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -183,7 +183,7 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int
constexpr int precision = Preferences::LargeNumberOfSignificantDigits;
constexpr int bufferSize = PrintFloat::charSizeForFloatsWithPrecision(precision);
char buffer[bufferSize];
// FIXME: Leo has not decided yet if we should use the preferred mode instead of always using scientific mode
// FIXME: Leo has not decided yet if we should use the prefered mode instead of always using scientific mode
PoincareHelpers::ConvertFloatToTextWithDisplayMode<double>(m_calculation->parameterAtIndex(i-1), buffer, bufferSize, precision, Preferences::PrintFloatMode::Decimal);
field->setText(buffer);
}

View File

@@ -134,7 +134,7 @@ double Distribution::cumulativeDistributiveInverseForProbabilityUsingIncreasingF
* the given ax bx bounds */
if (!(std::isnan(result.x2()) || std::fabs(result.x2()) <= FLT_EPSILON || std::fabs(result.x1()- ax) < FLT_EPSILON || std::fabs(result.x1() - bx) < FLT_EPSILON)) {
/* TODO We would like to put this as an assertion, but sometimes we do get
* false result: we replace them with inf to make the problem obvious to
* false result: we replace them with inf to make the problem obvisous to
* the student. */
return *probability > 0.5 ? INFINITY : -INFINITY;
}

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