Compare commits

..

4 Commits

Author SHA1 Message Date
Quentin Guidée
46658f7077 [omega] 1.20.3 2020-08-26 14:17:23 +02:00
Quentin Guidée
0235de8010 [omega] 1.20.2 2020-07-23 18:23:30 +02:00
Quentin Guidée
636c5c1d24 Merge branch 'omega-hotfix' into omega-master 2020-07-23 18:23:11 +02:00
Quentin Guidée
4af76cc3ae [omega] 1.20.1 2020-07-21 22:32:19 +02:00
1184 changed files with 10444 additions and 25754 deletions

View File

@@ -1,54 +1,31 @@
name: Continuous integration
#on: [pull_request, push]
on:
push:
pull_request:
workflow_dispatch:
inputs:
triggerIos:
description: 'Run iOS tests'
required: true
default: 'no'
triggerMacos:
description: 'Run macOS tests'
required: true
default: 'no'
trigger3DS:
description: 'Run 3DS tests'
required: true
default: 'no'
on: [pull_request, push]
jobs:
nintendo_3ds:
if: github.event.inputs.trigger3DS == 'yes'
runs-on: ubuntu-latest
steps:
- run: wget https://github.com/devkitPro/pacman/releases/download/v1.0.2/devkitpro-pacman.amd64.deb -O /tmp/devkitpro-pacman.deb
- run: yes | sudo dpkg -i /tmp/devkitpro-pacman.deb
- run: yes | sudo dkp-pacman -Syu --needed devkitARM 3dstools libctru
- run: echo ::set-env name=DEVKITPRO::/opt/devkitpro
- run: echo ::set-env name=DEVKITARM::/opt/devkitpro/devkitARM
- run: echo ::set-env name=PATH::$DEVKITPRO/tools/bin:$DEVKITARM/bin:$PATH
- uses: actions/checkout@v1
with:
submodules: true
- run: make -j2 PLATFORM=simulator TARGET=3ds
- run: make -j2 PLATFORM=simulator TARGET=3ds epsilon.cia
- uses: actions/upload-artifact@master
with:
name: epsilon-3ds.3dsx
path: output/release/simulator/3ds/epsilon.3dsx
- uses: actions/upload-artifact@master
with:
name: epsilon-3ds.cia
path: output/release/simulator/3ds/epsilon.cia
# nintendo_3ds:
# runs-on: ubuntu-latest
# steps:
# - run: wget https://github.com/devkitPro/pacman/releases/download/v1.0.2/devkitpro-pacman.amd64.deb -O /tmp/devkitpro-pacman.deb
# - run: yes | sudo dpkg -i /tmp/devkitpro-pacman.deb
# - run: yes | sudo dkp-pacman -Syu --needed devkitARM 3dstools libctru
# - run: echo ::set-env name=DEVKITPRO::/opt/devkitpro
# - run: echo ::set-env name=DEVKITARM::/opt/devkitpro/devkitARM
# - run: echo ::set-env name=PATH::$DEVKITPRO/tools/bin:$DEVKITARM/bin:$PATH
# - uses: actions/checkout@v1
# with:
# submodules: true
# - run: make -j2 PLATFORM=simulator TARGET=3ds
# - uses: actions/upload-artifact@master
# with:
# name: epsilon-3ds.3dsx
# path: output/release/simulator/3ds/epsilon.3dsx
android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v1
with:
submodules: 'recursive'
submodules: true
- run: make -j2 PLATFORM=simulator TARGET=android
- uses: actions/upload-artifact@master
with:
@@ -58,10 +35,10 @@ jobs:
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
- uses: numworks/setup-arm-toolchain@v1
- uses: actions/checkout@v1
with:
submodules: 'recursive'
submodules: true
- run: mkdir final-output
- run: make -j2 MODEL=n0100 EPSILON_I18N=en output/release/device/n0100/epsilon.onboarding.two_binaries
- run: mv output/release/device/n0100/epsilon.onboarding.internal.bin final-output/epsilon.onboarding.internal.en.bin
@@ -99,10 +76,10 @@ jobs:
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
- uses: numworks/setup-arm-toolchain@v1
- uses: actions/checkout@v1
with:
submodules: 'recursive'
submodules: true
- run: make -j2 epsilon.dfu
- run: make -j2 epsilon.onboarding.dfu
- run: make -j2 epsilon.onboarding.update.dfu
@@ -117,36 +94,16 @@ jobs:
with:
name: epsilon-binpack-n0110.tgz
path: output/release/device/n0110/binpack-n0110.tgz
windows:
runs-on: windows-latest
defaults:
run:
shell: msys2 {0}
steps:
- uses: msys2/setup-msys2@v2
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- run: pacman -S --noconfirm mingw-w64-x86_64-gcc mingw-w64-x86_64-freetype mingw-w64-x86_64-pkg-config make mingw-w64-x86_64-python3 mingw-w64-x86_64-libjpeg-turbo mingw-w64-x86_64-libpng
- run: make -j2 PLATFORM=simulator
- run: make -j2 PLATFORM=simulator test.exe
- run: cmd /c output\release\simulator\windows\test.exe --headless
- uses: actions/upload-artifact@master
with:
name: epsilon-windows.exe
path: output/release/simulator/windows/epsilon.exe
web:
runs-on: ubuntu-latest
steps:
- uses: numworks/setup-emscripten@v1
- uses: numworks/setup-emscripten@v2
with:
sdk: latest-upstream
- uses: actions/checkout@v2
- uses: actions/checkout@v1
with:
submodules: 'recursive'
submodules: true
- 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
- uses: actions/upload-artifact@master
with:
name: epsilon-web.zip
@@ -155,45 +112,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- run: sudo apt-get install build-essential imagemagick libfreetype6-dev libjpeg-dev libpng-dev pkg-config
- uses: actions/checkout@v2
- uses: actions/checkout@v1
with:
submodules: 'recursive'
submodules: true
- run: make -j2 PLATFORM=simulator
- run: make -j2 PLATFORM=simulator test.bin
- run: output/release/simulator/linux/test.bin --headless
- uses: actions/upload-artifact@master
with:
name: epsilon-linux.bin
path: output/release/simulator/linux/epsilon.bin
macos:
if: github.event.inputs.triggerMacos == 'yes'
runs-on: macOS-latest
steps:
- run: brew install numworks/tap/epsilon-sdk
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- run: make -j2 PLATFORM=simulator
- run: make -j2 PLATFORM=simulator ARCH=x86_64 test.bin
- run: output/release/simulator/macos/x86_64/test.bin --headless
- uses: actions/upload-artifact@master
with:
name: epsilon-macos.zip
path: output/release/simulator/macos/epsilon.app
ios:
if: github.event.inputs.triggerIos == 'yes'
runs-on: macOS-latest
steps:
- run: brew install numworks/tap/epsilon-sdk
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- run: make -j2 PLATFORM=simulator TARGET=ios EPSILON_TELEMETRY=0
- run: make -j2 PLATFORM=simulator TARGET=ios EPSILON_TELEMETRY=0 APPLE_PLATFORM=ios-simulator
- uses: actions/upload-artifact@master
with:
name: epsilon-ios.ipa
path: output/release/simulator/ios/epsilon.ipa
env:
ACCEPT_OFFICIAL_TOS: 1
- run: make -j2 PLATFORM=simulator test.headless.bin

View File

@@ -1,5 +1,5 @@
name: Metrics
on: [pull_request_target]
on: [pull_request]
jobs:
binary-size:
@@ -8,7 +8,7 @@ jobs:
- name: Install dependencies
run: sudo apt-get install build-essential imagemagick libfreetype6-dev libjpeg-dev libpng-dev pkg-config
- name: Install ARM toolchain
uses: numworks/setup-arm-toolchain@2020-q2
uses: numworks/setup-arm-toolchain@v1
- name: Checkout PR base
uses: actions/checkout@v2
with:
@@ -28,14 +28,11 @@ jobs:
- name: Retrieve binary size analysis
id: binary_size
run: echo "::set-output name=table::$(python3 head/build/metrics/binary_size.py base/output/release/device/n0110/epsilon.elf head/output/release/device/n0110/epsilon.elf --labels Base Head --sections .text .rodata .bss .data --custom 'Total (RAM)' .data .bss --custom 'Total (ROM)' .text .rodata .data --escape)"
- name: Prepare comment auth
run: echo "::set-env name=GITHUB_TOKEN::$(echo YjgxYTk1YTQ4YzYxNjU4ZTA3YWQzNDYwNTk3ZTI2MTlkODU5MThlOQo= | base64 --decode)"
- name: Add comment
uses: actions/github-script@v3.0.0
uses: actions/github@v1.0.0
env:
GITHUB_TOKEN: ${{ env.GITHUB_TOKEN }}
with:
github-token: ${{ secrets.OMEGA_ROBOT_TOKEN }}
script: |
await github.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body: `${{ steps.binary_size.outputs.table }}`,
});
args: comment ${{ steps.binary_size.outputs.table }}

26
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,26 @@
image: gcc
stages:
- build
job:build:
stage: build
before_script:
- "echo 'deb http://httpredir.debian.org/debian jessie main contrib \n deb-src http://httpredir.debian.org/debian jessie main contrib \n deb http://httpredir.debian.org/debian jessie-updates main contrib \n deb-src http://httpredir.debian.org/debian jessie-updates main contrib \n deb http://security.debian.org/ jessie/updates main contrib \n deb-src http://security.debian.org/ jessie/updates main contrib ' > /etc/apt/source.list"
- "apt-get update"
- "apt -y install build-essential git imagemagick libx11-dev libxext-dev libfreetype6-dev libpng-dev libjpeg-dev pkg-config fltk1.3-dev gcc-arm-none-eabi nodejs npm"
- "git submodule update --init --recursive"
- "git clone https://github.com/RedGl0w/omega-auto-increment"
- "cd omega-auto-increment"
- "npm i request exeq"
- "PrivateToken=$PrivateToken node index.js"
- "cd .."
script:
- make clean
- make MODEL=n0100 epsilon.bin
artifacts:
paths:
- output/release/device/n0100/epsilon.bin
- omega-auto-increment/version.txt
name: artifact:build:simulator

9
.gitmodules vendored
View File

@@ -1,6 +1,9 @@
[submodule "apps/rpn"]
path = apps/rpn
url = https://github.com/Omega-Numworks/Omega-RPN.git
[submodule "apps/atomic"]
path = apps/atomic
url = https://github.com/Omega-Numworks/Omega-Atomic.git
[submodule "apps/atom"]
path = apps/atom
url = https://github.com/Omega-Numworks/Omega-Atom.git
[submodule "themes"]
path = themes
url = https://github.com/Omega-Numworks/Omega-Themes.git

View File

@@ -1,177 +0,0 @@
<p align="center"><img src="https://github.com/Omega-Numworks/Omega-Design/blob/master/Banners/Omega-Banner-Dev-Branch.png?raw=true" /></p>
<p align="center">
<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="cc by-nc-sa 4.0" src="https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-525252.svg?labelColor=292929&logo=creative%20commons&style=for-the-badge" /></a>
<a href="https://github.com/Omega-Numworks/Omega/issues"><img alt="Issues" src="https://img.shields.io/github/issues/Omega-Numworks/Omega.svg?labelColor=292929&logo=git&style=for-the-badge" /></a>
<br/>
<a href="https://discord.gg/X2TWhh9"><img alt="Discord" src="https://img.shields.io/discord/663420259851567114?color=blue&labelColor=292929&label=chat%20-%20discord&logo=discord&style=for-the-badge" /></a>
</p>
> Don't understand french ? speak english ? here's the [english README](./README.md) !
## À propos
Omega est un fork d'Epsilon, l'OS de Numworks tournant sur les calculatrices du même nom, qui apporte beaucoup de fonctionnalités en plus. Omega est fait pour ceux qui aimeraient ajouter certaines fonctionnalités ayant été rejetées par Numworks à leurs calculatrices (pour des raisons 100% compréhensibles !). [Essayez en ligne](https://getomega.web.app/simulator).
### Quelques fonctionnalités supplémentaires
- Retour du calcul littéral
- Une application RPN
- Application Externes
- Des thèmes
- Python amélioré (module os, méthode open...)
- Un tableau périodique et toutes les masses molaires des éléments dans la toolbox
- *Ainsi que d'autres à découvrir...* [Changelogs complets](https://github.com/Omega-Numworks/Omega/wiki/Changelog) | [Fonctionnalités princpales & captures d'écran](https://github.com/Omega-Numworks/Omega/wiki/Main-features).
## Installation
### Automatique
Vous pouvez installer Omega automatiquement depuis [notre site](https://getomega.web.app/) sur la page "installer".
<a href="https://getomega.web.app"><p align="center"><img alt="Omega Banner Discord" src="https://user-images.githubusercontent.com/12123721/86352956-e9000480-bc66-11ea-82b7-79fd7e56fa27.png" /></p></a>
### Manuelle
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>
(note : vous pouvez changer `EPSILON_I18N=fr` en `en`, `nl`, `pt`, `it`, `de`, `es` ou `hu`).
```bash
git clone --recursive https://github.com/Omega-Numworks/Omega.git
cd Omega
git checkout omega-master
make MODEL=n0100 clean
make MODEL=n0100 EPSILON_I18N=fr OMEGA_USERNAME="{Votre nom ici, 15 caractères max}" -j4
make MODEL=n0100 epsilon_flash
```
Important : N'oubliez pas l'argument `--recursive`, Omega 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>Modèle n0110</b></summary>
```bash
git clone --recursive https://github.com/Omega-Numworks/Omega.git
cd Omega
git checkout omega-master
make clean
make OMEGA_USERNAME="{Votre nom ici, 15 caractères max}" -j4
make epsilon_flash
```
Important : N'oubliez pas l'argument `--recursive`, Omega 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 Omega (pour que tout le monde puisse le flasher via [Webdfu_Numworks](https://ti-planet.github.io/webdfu_numworks/)).
```bash
git clone --recursive https://github.com/Omega-Numworks/Omega.git
cd Omega
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`, Omega 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
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest-fastcomp
./emsdk activate latest-fastcomp
source emsdk_env.sh
```
Puis, compilez Omega :
```bash
git clone --recursive https://github.com/Omega-Numworks/Omega.git
cd Omega
git checkout omega-master
make clean
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`, Omega 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 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/Omega-Numworks/Omega.git
cd Omega
git checkout --recursive omega-dev
make PLATFORM=simulator TARGET=3ds -j
```
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 <ADRESSE IP 3DS>
```
</details>
Si vous avez besoin d'aide, n'hésitez pas à rejoindre notre serveur discord : https://discord.gg/X2TWhh9
<a href="https://discord.gg/X2TWhh9"><p align="center"><img alt="Omega Banner Discord" src="https://user-images.githubusercontent.com/12123721/86287349-54ef5800-bbe8-11ea-80c1-34eb1f93eebd.png" /></p></a>
---
## Contribution
Pour contribuer, merci de lire le [Wiki](https://github.com/Omega-Numworks/Omega/wiki/Contributing)
## Nos autres projets
* [Omega Themes](https://github.com/Omega-Numworks/Omega-Themes)
* [Omega Website](https://github.com/Omega-Numworks/Omega-Website)
* [Omega RPN `APP`](https://github.com/Omega-Numworks/Omega-RPN)
* [Omega Atomic `APP`](https://github.com/Omega-Numworks/Omega-Atomic)
* [Omega Design](https://github.com/Omega-Numworks/Omega-Design)
* [Omega Discord Bot](https://github.com/Omega-Numworks/Omega-Discord-Bot)
* [Omega App Template `BETA`](https://github.com/Omega-Numworks/Omega-App-Template)
* [External Apps](https://github.com/Omega-Numworks/External-Apps)
## À propos d'Epsilon
Omega est un fork d'Epsilon, un système d'exploitation performant pour calculatrices graphiques. Il inclut huit applications pour les mathématiques de lycée et d'études supérieurs
Vous pouvez essayer Epsilon depuis votre navigateur sur le [simulateur en ligne](https://www.numworks.com/simulator/).
## Licence
NumWorks est une marque déposée de NumWorks SAS, 24 Rue Godot de Mauroy, 75009 Paris, France.
Nintendo est Nintendo 3DS sont des marques déposées de Nintendo of America Inc, 4600 150th Ave NE, Redmond, WA 98052, Etats-Unis.
NumWorks SAS et Nintendo of America Inc ne sont en aucun cas associés avec ce projet.
* NumWorks Epsilon est disponible sous [Lisense CC BY-NC-SA](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode).
* Omega est disponible sous [Lisense CC BY-NC-SA](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode).

View File

@@ -1,4 +1,4 @@
<p align="center"><img src="https://github.com/Omega-Numworks/Omega-Design/blob/master/Banners/Omega-Banner-Dev-Branch.png?raw=true" /></p>
<p align="center"><img src="https://user-images.githubusercontent.com/12123721/87953533-75a22380-caab-11ea-8cde-c40291c4a9ae.png" /></p>
<p align="center">
<a href="https://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="cc by-nc-sa 4.0" src="https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-525252.svg?labelColor=292929&logo=creative%20commons&style=for-the-badge" /></a>
@@ -7,20 +7,19 @@
<a href="https://discord.gg/X2TWhh9"><img alt="Discord" src="https://img.shields.io/discord/663420259851567114?color=blue&labelColor=292929&label=chat%20-%20discord&logo=discord&style=for-the-badge" /></a>
</p>
> Vous ne comprenez pas l'anglais ? vous êtes francophone ? Regardez le [*LISEZ-MOI* français](./README.fr.md) !
## About
Omega is a fork of Numworks' Epsilon, the OS that runs on their calculator, which brings many features to it. Omega is for the people who want to add features to the calculator, but cannot because they have been rejected by Numworks (for reasons that are 100% understandable!). [Try it online](https://getomega.web.app/simulator).
Omega is a fork of Numworks' Epsilon, the OS that runs on their calculator, which brings many features to it. Omega is for the people who want to add features to the calculator, but cannot because they have been rejected by Numworks (for reasons that are 100% understandable!).
### Some new features
## Some new features
- Adding symbolic calculation back into the calculator
- An app for RPN
- Exernal apps
- A theme engine
- New python features (os module, open method...)
- A periodic table app + all of the molar masses for the elements in the toolbox
- *And much more to discover...* [Complete changelog](https://github.com/Omega-Numworks/Omega/wiki/Changelog) | [Main new features + screenshots](https://github.com/Omega-Numworks/Omega/wiki/Main-features).
- More steps for brightness (16 instead of 5)
- ~~32 KB Python heap instead of 16 KB~~ Now available on Epsilon `>=13.2.0`!
- And more...
The main new features are listed [here](https://github.com/Omega-Numworks/Omega/wiki/Main-features), and the complete changelog can be found [here](https://github.com/Omega-Numworks/Omega/wiki/Changelog).
## Installation
@@ -37,14 +36,12 @@ First of all, follow **step 1** [here](https://www.numworks.com/resources/engine
<details>
<summary><b>Model n0100</b></summary>
(note: you can change the `EPSILON_I18N=en` flag to `fr`, `nl`, `pt`, `it`, `de`, `es` or `hu`).
```bash
```
git clone --recursive https://github.com/Omega-Numworks/Omega.git
cd Omega
git checkout omega-master
make MODEL=n0100 clean
make MODEL=n0100 EPSILON_I18N=en OMEGA_USERNAME="{Your name, max 15 characters}" -j4
make MODEL=n0100 OMEGA_USERNAME="{Your name, max 15 characters}" -j4
make MODEL=n0100 epsilon_flash
```
@@ -56,7 +53,7 @@ Also, you can change the number of processes that run in parallel during the bui
<details>
<summary><b>Model n0110</b></summary>
```bash
```
git clone --recursive https://github.com/Omega-Numworks/Omega.git
cd Omega
git checkout omega-master
@@ -75,7 +72,7 @@ Also, you can change the number of processes that run in parallel during the bui
These can be used to distribute Omega (so that it can be flashed by anyone with [Webdfu_Numworks](https://ti-planet.github.io/webdfu_numworks/)).
```bash
```
git clone --recursive https://github.com/Omega-Numworks/Omega.git
cd Omega
git checkout omega-master
@@ -96,7 +93,7 @@ Also, you can change the number of processes that run in parallel during the bui
First, install emsdk :
```bash
```
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest-fastcomp
@@ -106,7 +103,7 @@ source emsdk_env.sh
Then, compile Omega :
```bash
```
git clone --recursive https://github.com/Omega-Numworks/Omega.git
cd Omega
git checkout omega-master
@@ -125,16 +122,14 @@ Also, you can change the number of processes that run in parallel during the bui
<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/Omega-Numworks/Omega.git
cd Omega
git checkout --recursive omega-dev
make PLATFORM=simulator TARGET=3ds -j
```
You can then put epsilon.3dsx on a SD card to run it from the HBC or use 3dslink to launch it over the network:
```bash
```
3dslink output/release/simulator/3ds/epsilon.3dsx -a <3DS' IP ADDRESS>
```
@@ -149,16 +144,20 @@ If you need help, you can join our Discord server here : https://discord.gg/X2TW
To contribute, please refer to the [Wiki](https://github.com/Omega-Numworks/Omega/wiki/Contributing)
## Branches
* `omega-master` : stable releases
* `omega-dev` : beta releases
* `omega-hotfix` : developers only, branch to fix issues
## Related repositories
* [Omega Themes](https://github.com/Omega-Numworks/Omega-Themes)
* [Omega Website](https://github.com/Omega-Numworks/Omega-Website)
* [Omega RPN `APP`](https://github.com/Omega-Numworks/Omega-RPN)
* [Omega Atomic `APP`](https://github.com/Omega-Numworks/Omega-Atomic)
* [Omega Atom `APP`](https://github.com/Omega-Numworks/Omega-Atom)
* [Omega Design](https://github.com/Omega-Numworks/Omega-Design)
* [Omega Discord Bot](https://github.com/Omega-Numworks/Omega-Discord-Bot)
* [Omega App Template `BETA`](https://github.com/Omega-Numworks/Omega-App-Template)
* [External Apps](https://github.com/Omega-Numworks/External-Apps)
## About Epsilon

View File

@@ -11,25 +11,6 @@ apps =
# (path to the apps header).
$(foreach i,${apps_list},${eval include apps/$(i)/Makefile})
app_equals = $(and $(findstring $(1),$(2)),$(findstring $(2),$(1)))
# We list all the apps that are missing
apps_missing = $(foreach i, ${apps_list}, $(if $(call app_equals, apps/$(i)/Makefile, $(wildcard apps/$(i)/Makefile)),, $(i) ) )
# If the two doesn't match, we got an error.
ifneq ($(strip $(apps_missing)),)
miss_modules = 0
# Check if the missing apps are one that are supposed to be submodules
$(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, 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
$(error Missing apps: $(strip $(apps_missing)))
endif
apps_src += $(addprefix apps/,\
alternate_empty_nested_menu_controller.cpp \
apps_container.cpp \
@@ -44,7 +25,6 @@ apps_src += $(addprefix apps/,\
backlight_dimming_timer.cpp \
battery_timer.cpp \
battery_view.cpp \
clock_timer.cpp \
empty_battery_window.cpp \
exam_pop_up_controller.cpp \
exam_mode_configuration_official.cpp:+official \
@@ -61,10 +41,7 @@ apps_src += $(addprefix apps/,\
title_bar_view.cpp \
)
tests_src += $(addprefix apps/,\
exam_mode_configuration_non_official.cpp \
)
tests_src += apps/exam_mode_configuration_non_official.cpp
snapshots_declaration = $(foreach i,$(apps),$(i)::Snapshot m_snapshot$(subst :,,$(i))Snapshot;)
apps_declaration = $(foreach i,$(apps),$(i) m_$(subst :,,$(i));)
@@ -78,23 +55,23 @@ $(call object_for,apps/apps_container_storage.cpp apps/apps_container.cpp apps/m
# I18n file generation
country_preferences = apps/country_preferences.csv
language_preferences = apps/language_preferences.csv
# The header is refered to as <apps/i18n.h> so make sure it's findable this way
SFLAGS += -I$(BUILD_DIR)
i18n_files += $(addprefix apps/language_,$(addsuffix .universal.i18n, $(EPSILON_I18N)))
ifeq ($(EPSILON_GETOPT),1)
i18n_files += $(addprefix apps/language_,$(addsuffix _iso6391.universal.i18n, $(EPSILON_I18N)))
endif
i18n_files += $(call i18n_with_universal_for,shared)
i18n_files += $(call i18n_with_universal_for,toolbox)
i18n_files += $(call i18n_without_universal_for,toolbox)
i18n_files += $(call i18n_without_universal_for,variables)
$(eval $(call rule_for, \
I18N, \
apps/i18n.cpp, \
$(i18n_files), \
$$(PYTHON) apps/i18n.py --codepoints $(code_points) --countrypreferences $(country_preferences) --languagepreferences $(language_preferences) --header $$(subst .cpp,.h,$$@) --implementation $$@ --locales $$(EPSILON_I18N) --countries $$(EPSILON_COUNTRIES) --files $$^, \
$$(PYTHON) apps/i18n.py --codepoints $(code_points) --header $$(subst .cpp,.h,$$@) --implementation $$@ --locales $$(EPSILON_I18N) --files $$^ --generateISO6391locales $$(EPSILON_GETOPT), \
global \
))
@@ -107,12 +84,9 @@ $(BUILD_DIR)/apps/i18n.h: $(BUILD_DIR)/apps/i18n.cpp
$(eval $(call depends_on_image,apps/title_bar_view.cpp,apps/exam_icon.png))
$(call object_for,$(apps_src) $(tests_src)): $(BUILD_DIR)/apps/i18n.h
$(call object_for,$(apps_src) $(tests_src)): $(BUILD_DIR)/apps/home/apps_layout.h
$(call object_for,$(apps_src) $(tests_src)): $(BUILD_DIR)/python/port/genhdr/qstrdefs.generated.h
$(call object_for,$(apps_src)): $(BUILD_DIR)/apps/home/apps_layout.h
apps_tests_src = $(app_calculation_test_src) $(app_code_test_src) $(app_graph_test_src) $(app_probability_test_src) $(app_regression_test_src) $(app_sequence_test_src) $(app_shared_test_src) $(app_statistics_test_src) $(app_settings_test_src) $(app_solver_test_src)
apps_tests_src = $(app_calculation_test_src) $(app_code_test_src) $(app_probability_test_src) $(app_regression_test_src) $(app_sequence_test_src) $(app_shared_test_src) $(app_statistics_test_src) $(app_settings_test_src) $(app_solver_test_src)
apps_tests_src += $(addprefix apps/,\
alternate_empty_nested_menu_controller.cpp \

View File

@@ -8,8 +8,6 @@
#include <ion/backlight.h>
#include <poincare/preferences.h>
#include <algorithm>
extern "C" {
#include <assert.h>
}
@@ -33,7 +31,6 @@ AppsContainer::AppsContainer() :
m_batteryTimer(),
m_suspendTimer(),
m_backlightDimmingTimer(),
m_clockTimer(ClockTimer(this)),
m_homeSnapshot(),
m_onBoardingSnapshot(),
m_hardwareTestSnapshot(),
@@ -61,23 +58,8 @@ AppsContainer::AppsContainer() :
}
bool AppsContainer::poincareCircuitBreaker() {
constexpr uint64_t minimalPressDuration = 20;
static uint64_t beginningOfInterruption = 0;
Ion::Keyboard::State state = Ion::Keyboard::scan();
bool interrupt = state.keyDown(Ion::Keyboard::Key::Back) || state.keyDown(Ion::Keyboard::Key::Home) || state.keyDown(Ion::Keyboard::Key::OnOff);
if (!interrupt) {
beginningOfInterruption = 0;
return false;
}
if (beginningOfInterruption == 0) {
beginningOfInterruption = Ion::Timing::millis();
return false;
}
if (Ion::Timing::millis() - beginningOfInterruption > minimalPressDuration) {
beginningOfInterruption = 0;
return true;
}
return false;
return state.keyDown(Ion::Keyboard::Key::Back);
}
App::Snapshot * AppsContainer::hardwareTestAppSnapshot() {
@@ -220,13 +202,6 @@ bool AppsContainer::dispatchEvent(Ion::Events::Event event) {
return didProcessEvent || alphaLockWantsRedraw;
}
static constexpr Ion::Events::Event switch_events[] = {
Ion::Events::ShiftSeven, Ion::Events::ShiftEight, Ion::Events::ShiftNine,
Ion::Events::ShiftFour, Ion::Events::ShiftFive, Ion::Events::ShiftSix,
Ion::Events::ShiftOne, Ion::Events::ShiftTwo, Ion::Events::ShiftThree,
Ion::Events::ShiftZero, Ion::Events::ShiftDot, Ion::Events::ShiftEE
};
bool AppsContainer::processEvent(Ion::Events::Event event) {
// Warning: if the window is dirtied, you need to call window()->redraw()
if (event == Ion::Events::USBPlug) {
@@ -251,15 +226,6 @@ bool AppsContainer::processEvent(Ion::Events::Event event) {
switchTo(appSnapshotAtIndex(1));
return true;
}
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);
switchTo(appSnapshotAtIndex(i+1));
return true;
}
}
if (event == Ion::Events::OnOff) {
suspend(true);
return true;
@@ -338,10 +304,6 @@ void AppsContainer::run() {
switchTo(nullptr);
}
bool AppsContainer::updateClock() {
return m_window.updateClock();
}
bool AppsContainer::updateBatteryState() {
bool batteryLevelUpdated = m_window.updateBatteryLevel();
bool pluggedStateUpdated = m_window.updatePluggedState();
@@ -374,7 +336,7 @@ void AppsContainer::shutdownDueToLowBattery() {
* case. */
return;
}
while (Ion::Battery::level() == Ion::Battery::Charge::EMPTY && !Ion::USB::isPlugged()) {
while (Ion::Battery::level() == Ion::Battery::Charge::EMPTY) {
Ion::Backlight::setBrightness(0);
if (!GlobalPreferences::sharedGlobalPreferences()->isInExamMode()) {
/* Unless the LED is lit up for the exam mode, switch off the LED. IF the
@@ -398,7 +360,7 @@ bool AppsContainer::updateAlphaLock() {
return m_window.updateAlphaLock();
}
OnBoarding::PromptController * AppsContainer::promptController() {
OnBoarding::PopUpController * AppsContainer::promptController() {
if (k_promptNumberOfMessages == 0) {
return nullptr;
}
@@ -447,11 +409,11 @@ Window * AppsContainer::window() {
}
int AppsContainer::numberOfContainerTimers() {
return 4;
return 3;
}
Timer * AppsContainer::containerTimerAtIndex(int i) {
Timer * timers[4] = {&m_batteryTimer, &m_suspendTimer, &m_backlightDimmingTimer, &m_clockTimer};
Timer * timers[3] = {&m_batteryTimer, &m_suspendTimer, &m_backlightDimmingTimer};
return timers[i];
}

View File

@@ -16,8 +16,7 @@
#include "global_preferences.h"
#include "backlight_dimming_timer.h"
#include "shared/global_context.h"
#include "clock_timer.h"
#include "on_boarding/prompt_controller.h"
#include "on_boarding/pop_up_controller.h"
#include <ion/events.h>
@@ -40,14 +39,13 @@ public:
bool dispatchEvent(Ion::Events::Event event) override;
bool switchTo(App::Snapshot * snapshot) override;
void run() override;
bool updateClock();
bool updateBatteryState();
void refreshPreferences();
void reloadTitleBarView();
void displayExamModePopUp(GlobalPreferences::ExamMode mode);
void shutdownDueToLowBattery();
void setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus newStatus);
OnBoarding::PromptController * promptController();
OnBoarding::PopUpController * promptController();
void redrawWindow(bool force = false);
void activateExamMode(GlobalPreferences::ExamMode examMode);
// Exam pop-up controller delegate
@@ -74,11 +72,10 @@ private:
MathToolbox m_mathToolbox;
MathVariableBoxController m_variableBoxController;
ExamPopUpController m_examPopUpController;
OnBoarding::PromptController m_promptController;
OnBoarding::PopUpController m_promptController;
BatteryTimer m_batteryTimer;
SuspendTimer m_suspendTimer;
BacklightDimmingTimer m_backlightDimmingTimer;
ClockTimer m_clockTimer;
Home::App::Snapshot m_homeSnapshot;
OnBoarding::App::Snapshot m_onBoardingSnapshot;
HardwareTest::App::Snapshot m_hardwareTestSnapshot;

View File

@@ -3,7 +3,6 @@
extern "C" {
#include <assert.h>
}
#include <ion/rtc.h>
AppsWindow::AppsWindow() :
Window(),
@@ -20,11 +19,6 @@ bool AppsWindow::updateBatteryLevel() {
return m_titleBarView.setChargeState(Ion::Battery::level());
}
bool AppsWindow::updateClock() {
Ion::RTC::DateTime dateTime = Ion::RTC::dateTime();
return m_titleBarView.setClock(dateTime.tm_hour, dateTime.tm_min, Ion::RTC::mode() != Ion::RTC::Mode::Disabled);
}
bool AppsWindow::updateIsChargingState() {
return m_titleBarView.setIsCharging(Ion::Battery::isCharging());
}

View File

@@ -9,7 +9,6 @@ public:
AppsWindow();
void setTitle(I18n::Message title);
bool updateBatteryLevel();
bool updateClock();
bool updateIsChargingState();
bool updatePluggedState();
void refreshPreferences();

1
apps/atom Submodule

Submodule apps/atom added at 8f710a9d3f

Submodule apps/atomic deleted from 64f2e38ed1

View File

@@ -9,7 +9,7 @@ BatteryTimer::BatteryTimer() :
bool BatteryTimer::fire() {
AppsContainer * container = AppsContainer::sharedAppsContainer();
bool needRedrawing = container->updateBatteryState();
if (Ion::Battery::level() == Ion::Battery::Charge::EMPTY && !Ion::USB::isPlugged()) {
if (Ion::Battery::level() == Ion::Battery::Charge::EMPTY) {
container->shutdownDueToLowBattery();
}
return needRedrawing;

View File

@@ -17,7 +17,6 @@ app_calculation_src = $(addprefix apps/calculation/,\
additional_outputs/integer_list_controller.cpp \
additional_outputs/scrollable_three_expressions_cell.cpp \
additional_outputs/list_controller.cpp \
additional_outputs/matrix_list_controller.cpp \
additional_outputs/rational_list_controller.cpp \
additional_outputs/trigonometry_graph_cell.cpp \
additional_outputs/trigonometry_list_controller.cpp \

View File

@@ -11,7 +11,7 @@ ExpressionsListController::ExpressionsListController(EditExpressionController *
ListController(editExpressionController),
m_cells{}
{
for (int i = 0; i < k_maxNumberOfRows; i++) {
for (int i = 0; i < k_maxNumberOfCells; i++) {
m_cells[i].setParentResponder(m_listController.selectableTableView());
}
}
@@ -21,20 +21,15 @@ void ExpressionsListController::didEnterResponderChain(Responder * previousFirst
}
int ExpressionsListController::reusableCellCount(int type) {
return k_maxNumberOfRows;
return k_maxNumberOfCells;
}
void ExpressionsListController::viewDidDisappear() {
ListController::viewDidDisappear();
// Reset layout and cell memoization to avoid taking extra space in the pool
for (int i = 0; i < k_maxNumberOfRows; i++) {
// Reset cell memoization to avoid taking extra space in the pool
for (int i = 0; i < k_maxNumberOfCells; i++) {
m_cells[i].setLayout(Layout());
/* By reseting m_layouts, numberOfRow will go down to 0, and the highlighted
* cells won't be unselected. Therefore we unselect them here. */
m_cells[i].setHighlighted(false);
m_layouts[i] = Layout();
}
m_expression = Expression();
}
HighlightCell * ExpressionsListController::reusableCell(int index, int type) {
@@ -48,34 +43,24 @@ KDCoordinate ExpressionsListController::rowHeight(int j) {
}
void ExpressionsListController::willDisplayCellForIndex(HighlightCell * cell, int index) {
/* Note : To further optimize memoization space in the pool, layout
* serialization could be memoized instead, and layout would be recomputed
* here, when setting cell's layout. */
ExpressionTableCellWithPointer * myCell = static_cast<ExpressionTableCellWithPointer *>(cell);
myCell->setLayout(layoutAtIndex(index));
myCell->setAccessoryMessage(messageAtIndex(index));
myCell->reloadScroll();
}
int ExpressionsListController::numberOfRows() const {
int nbOfRows = 0;
for (size_t i = 0; i < k_maxNumberOfRows; i++) {
if (!m_layouts[i].isUninitialized()) {
nbOfRows++;
}
}
return nbOfRows;
}
void ExpressionsListController::setExpression(Poincare::Expression e) {
// Reinitialize memoization
for (int i = 0; i < k_maxNumberOfRows; i++) {
for (int i = 0; i < k_maxNumberOfCells; i++) {
m_layouts[i] = Layout();
}
m_expression = e;
}
Poincare::Layout ExpressionsListController::layoutAtIndex(int index) {
if (m_layouts[index].isUninitialized()) {
computeLayoutAtIndex(index);
}
assert(!m_layouts[index].isUninitialized());
return m_layouts[index];
}

View File

@@ -22,22 +22,22 @@ public:
KDCoordinate rowHeight(int j) override;
int typeAtLocation(int i, int j) override { return 0; }
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
int numberOfRows() const override;
// IllustratedListController
void setExpression(Poincare::Expression e) override;
protected:
constexpr static int k_maxNumberOfRows = 5;
constexpr static int k_maxNumberOfCells = 4;
int textAtIndex(char * buffer, size_t bufferSize, int index) override;
Poincare::Expression m_expression;
// Memoization of layouts
mutable Poincare::Layout m_layouts[k_maxNumberOfRows];
mutable Poincare::Layout m_layouts[k_maxNumberOfCells];
private:
Poincare::Layout layoutAtIndex(int index);
virtual void computeLayoutAtIndex(int index) = 0;
virtual I18n::Message messageAtIndex(int index) = 0;
// Cells
ExpressionTableCellWithPointer m_cells[k_maxNumberOfRows];
ExpressionTableCellWithPointer m_cells[k_maxNumberOfCells];
};
}

View File

@@ -11,7 +11,6 @@ namespace Calculation {
IllustratedListController::IllustratedListController(EditExpressionController * editExpressionController) :
ListController(editExpressionController, this),
m_calculationStore(m_calculationStoreBuffer, k_calculationStoreBufferSize),
m_additionalCalculationCells{}
{
for (int i = 0; i < k_maxNumberOfAdditionalCalculations; i++) {

View File

@@ -39,10 +39,7 @@ protected:
private:
int textAtIndex(char * buffer, size_t bufferSize, int index) override;
virtual CodePoint expressionSymbol() const = 0;
// Set the size of the buffer needed to store the additional calculation
constexpr static int k_maxNumberOfAdditionalCalculations = 4;
constexpr static int k_calculationStoreBufferSize = k_maxNumberOfAdditionalCalculations * (sizeof(Calculation) + Calculation::k_numberOfExpressions * Constant::MaxSerializedExpressionSize + sizeof(Calculation *));
char m_calculationStoreBuffer[k_calculationStoreBufferSize];
// Cells
virtual HighlightCell * illustrationCell() = 0;
ScrollableThreeExpressionsCell m_additionalCalculationCells[k_maxNumberOfAdditionalCalculations];

View File

@@ -11,6 +11,10 @@ using namespace Shared;
namespace Calculation {
int IntegerListController::numberOfRows() const {
return 3 + factorExpressionIsComputable();
}
Integer::Base baseAtIndex(int index) {
switch (index) {
case 0:
@@ -23,20 +27,12 @@ Integer::Base baseAtIndex(int index) {
}
}
void IntegerListController::setExpression(Poincare::Expression e) {
ExpressionsListController::setExpression(e);
static_assert(k_maxNumberOfRows >= k_indexOfFactorExpression + 1, "k_maxNumberOfRows must be greater than k_indexOfFactorExpression");
assert(!m_expression.isUninitialized() && m_expression.type() == ExpressionNode::Type::BasedInteger);
Integer integer = static_cast<BasedInteger &>(m_expression).integer();
for (int index = 0; index < k_indexOfFactorExpression; ++index) {
m_layouts[index] = integer.createLayout(baseAtIndex(index));
}
// Computing factorExpression
Expression factor = Factor::Builder(m_expression.clone());
PoincareHelpers::Simplify(&factor, App::app()->localContext(), ExpressionNode::ReductionTarget::User);
if (!factor.isUndefined()) {
m_layouts[k_indexOfFactorExpression] = PoincareHelpers::CreateLayout(factor);
}
void IntegerListController::computeLayoutAtIndex(int index) {
assert(m_expression.type() == ExpressionNode::Type::BasedInteger);
// For index = k_indexOfFactorExpression, the layout is assumed to be alreday memoized because it is needed to compute the numberOfRows
assert(index < k_indexOfFactorExpression);
Integer i = static_cast<BasedInteger &>(m_expression).integer();
m_layouts[index] = i.createLayout(baseAtIndex(index));
}
I18n::Message IntegerListController::messageAtIndex(int index) {
@@ -52,4 +48,20 @@ I18n::Message IntegerListController::messageAtIndex(int index) {
}
}
bool IntegerListController::factorExpressionIsComputable() const {
if (!m_layouts[k_indexOfFactorExpression].isUninitialized()) {
// The factor expression is already memoized
return !m_layouts[k_indexOfFactorExpression].isEmpty();
}
Poincare::Context * context = App::app()->localContext();
Expression factor = Factor::Builder(m_expression.clone());
PoincareHelpers::Simplify(&factor, context, ExpressionNode::ReductionTarget::User);
if (!factor.isUndefined()) {
m_layouts[k_indexOfFactorExpression] = PoincareHelpers::CreateLayout(factor);
return true;
}
m_layouts[k_indexOfFactorExpression] = EmptyLayout::Builder();
return false;
}
}

View File

@@ -10,11 +10,13 @@ public:
IntegerListController(EditExpressionController * editExpressionController) :
ExpressionsListController(editExpressionController) {}
void setExpression(Poincare::Expression e) override;
//ListViewDataSource
int numberOfRows() const override;
private:
static constexpr int k_indexOfFactorExpression = 3;
void computeLayoutAtIndex(int index) override;
I18n::Message messageAtIndex(int index) override;
bool factorExpressionIsComputable() const;
};
}

View File

@@ -1,106 +0,0 @@
#include "matrix_list_controller.h"
#include "../app.h"
#include "../../shared/poincare_helpers.h"
#include <apps/global_preferences.h>
#include <poincare_nodes.h>
#include <poincare/matrix.h>
#include <string.h>
using namespace Poincare;
using namespace Shared;
namespace Calculation {
void MatrixListController::setExpression(Poincare::Expression e) {
ExpressionsListController::setExpression(e);
assert(!m_expression.isUninitialized());
static_assert(k_maxNumberOfRows >= k_maxNumberOfOutputRows, "k_maxNumberOfRows must be greater than k_maxNumberOfOutputRows");
Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences();
Poincare::Preferences::ComplexFormat currentComplexFormat = preferences->complexFormat();
if (currentComplexFormat == Poincare::Preferences::ComplexFormat::Real) {
/* Temporary change complex format to avoid all additional expressions to be
* "unreal" (with [i] for instance). As additional results are computed from
* the output, which is built taking ComplexFormat into account, there are
* no risks of displaying additional results on an unreal output. */
preferences->setComplexFormat(Poincare::Preferences::ComplexFormat::Cartesian);
}
Context * context = App::app()->localContext();
ExpressionNode::ReductionContext reductionContext(
context,
preferences->complexFormat(),
preferences->angleUnit(),
GlobalPreferences::sharedGlobalPreferences()->unitFormat(),
ExpressionNode::ReductionTarget::SystemForApproximation,
ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined);
// The expression must be reduced to call methods such as determinant or trace
assert(m_expression.type() == ExpressionNode::Type::Matrix);
bool mIsSquared = (static_cast<Matrix &>(m_expression).numberOfRows() == static_cast<Matrix &>(m_expression).numberOfColumns());
size_t index = 0;
size_t messageIndex = 0;
// 1. Matrix determinant if square matrix
if (mIsSquared) {
/* Determinant is reduced so that a null determinant can be detected.
* However, some exceptions remain such as cos(x)^2+sin(x)^2-1 which will
* not be reduced to a rational, but will be null in theory. */
Expression determinant = Determinant::Builder(m_expression.clone()).reduce(reductionContext);
m_indexMessageMap[index] = messageIndex++;
m_layouts[index++] = getLayoutFromExpression(determinant, context, preferences);
// 2. Matrix inverse if invertible matrix
// A squared matrix is invertible if and only if determinant is non null
if (!determinant.isUndefined() && determinant.nullStatus(context) != ExpressionNode::NullStatus::Null) {
// TODO: Handle ExpressionNode::NullStatus::Unknown
m_indexMessageMap[index] = messageIndex++;
m_layouts[index++] = getLayoutFromExpression(MatrixInverse::Builder(m_expression.clone()), context, preferences);
}
}
// 3. Matrix row echelon form
messageIndex = 2;
Expression rowEchelonForm = MatrixRowEchelonForm::Builder(m_expression.clone());
m_indexMessageMap[index] = messageIndex++;
m_layouts[index++] = getLayoutFromExpression(rowEchelonForm, context, preferences);
/* 4. Matrix reduced row echelon form
* it can be computed from row echelon form to save computation time.*/
m_indexMessageMap[index] = messageIndex++;
m_layouts[index++] = getLayoutFromExpression(MatrixReducedRowEchelonForm::Builder(rowEchelonForm), context, preferences);
// 5. Matrix trace if square matrix
if (mIsSquared) {
m_indexMessageMap[index] = messageIndex++;
m_layouts[index++] = getLayoutFromExpression(MatrixTrace::Builder(m_expression.clone()), context, preferences);
}
// Reset complex format as before
preferences->setComplexFormat(currentComplexFormat);
}
Poincare::Layout MatrixListController::getLayoutFromExpression(Expression e, Context * context, Poincare::Preferences * preferences) {
assert(!e.isUninitialized());
// Simplify or approximate expression
Expression approximateExpression;
Expression simplifiedExpression;
e.simplifyAndApproximate(&simplifiedExpression, &approximateExpression, context,
preferences->complexFormat(), preferences->angleUnit(), GlobalPreferences::sharedGlobalPreferences()->unitFormat(),
ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined);
// simplify might have been interrupted, in which case we use approximate
if (simplifiedExpression.isUninitialized()) {
assert(!approximateExpression.isUninitialized());
return Shared::PoincareHelpers::CreateLayout(approximateExpression);
}
return Shared::PoincareHelpers::CreateLayout(simplifiedExpression);
}
I18n::Message MatrixListController::messageAtIndex(int index) {
// Message index is mapped in setExpression because it depends on the Matrix.
assert(index < k_maxNumberOfOutputRows && index >=0);
I18n::Message messages[k_maxNumberOfOutputRows] = {
I18n::Message::AdditionalDeterminant,
I18n::Message::AdditionalInverse,
I18n::Message::AdditionalRowEchelonForm,
I18n::Message::AdditionalReducedRowEchelonForm,
I18n::Message::AdditionalTrace};
return messages[m_indexMessageMap[index]];
}
}

View File

@@ -1,27 +0,0 @@
#ifndef CALCULATION_ADDITIONAL_OUTPUTS_MATRIX_LIST_CONTROLLER_H
#define CALCULATION_ADDITIONAL_OUTPUTS_MATRIX_LIST_CONTROLLER_H
#include "expressions_list_controller.h"
namespace Calculation {
class MatrixListController : public ExpressionsListController {
public:
MatrixListController(EditExpressionController * editExpressionController) :
ExpressionsListController(editExpressionController) {}
void setExpression(Poincare::Expression e) override;
private:
I18n::Message messageAtIndex(int index) override;
Poincare::Layout getLayoutFromExpression(Poincare::Expression e, Poincare::Context * context, Poincare::Preferences * preferences);
// Map from cell index to message index
constexpr static int k_maxNumberOfOutputRows = 5;
int m_indexMessageMap[k_maxNumberOfOutputRows];
};
}
#endif

View File

@@ -9,31 +9,34 @@ using namespace Shared;
namespace Calculation {
int RationalListController::numberOfRows() const {
return 2;
}
Integer extractInteger(const Expression e) {
assert(e.type() == ExpressionNode::Type::BasedInteger);
return static_cast<const BasedInteger &>(e).integer();
}
void RationalListController::setExpression(Poincare::Expression e) {
ExpressionsListController::setExpression(e);
assert(!m_expression.isUninitialized());
static_assert(k_maxNumberOfRows >= 2, "k_maxNumberOfRows must be greater than 2");
void RationalListController::computeLayoutAtIndex(int index) {
bool negative = false;
Expression div = m_expression;
if (m_expression.type() == ExpressionNode::Type::Opposite) {
negative = true;
div = m_expression.childAtIndex(0);
}
assert(div.type() == ExpressionNode::Type::Division);
Integer numerator = extractInteger(div.childAtIndex(0));
numerator.setNegative(negative);
Integer denominator = extractInteger(div.childAtIndex(1));
int index = 0;
m_layouts[index++] = PoincareHelpers::CreateLayout(Integer::CreateMixedFraction(numerator, denominator));
m_layouts[index++] = PoincareHelpers::CreateLayout(Integer::CreateEuclideanDivision(numerator, denominator));
Expression e;
if (index == 0) {
e = Integer::CreateMixedFraction(numerator, denominator);
} else {
assert(index == 1);
e = Integer::CreateEuclideanDivision(numerator, denominator);
}
m_layouts[index] = PoincareHelpers::CreateLayout(e);
}
I18n::Message RationalListController::messageAtIndex(int index) {

View File

@@ -10,9 +10,10 @@ public:
RationalListController(EditExpressionController * editExpressionController) :
ExpressionsListController(editExpressionController) {}
void setExpression(Poincare::Expression e) override;
//ListViewDataSource
int numberOfRows() const override;
private:
void computeLayoutAtIndex(int index) override;
I18n::Message messageAtIndex(int index) override;
int textAtIndex(char * buffer, size_t bufferSize, int index) override;
};

View File

@@ -15,62 +15,112 @@ namespace Calculation {
void UnitListController::setExpression(Poincare::Expression e) {
ExpressionsListController::setExpression(e);
assert(!m_expression.isUninitialized());
static_assert(k_maxNumberOfRows >= 3, "k_maxNumberOfRows must be greater than 3");
Poincare::Expression expressions[k_maxNumberOfRows];
// Initialize expressions
for (size_t i = 0; i < k_maxNumberOfRows; i++) {
expressions[i] = Expression();
// Reinitialize m_memoizedExpressions
for (size_t i = 0; i < k_maxNumberOfCells; i++) {
m_memoizedExpressions[i] = Expression();
}
/* 1. First rows: miscellaneous classic units for some dimensions, in both
* metric and imperial units. */
size_t numberOfMemoizedExpressions = 0;
// 1. First rows: miscellaneous classic units for some dimensions
Expression copy = m_expression.clone();
Expression units;
// Reduce to be able to recognize units
PoincareHelpers::ReduceAndRemoveUnit(&copy, App::app()->localContext(), ExpressionNode::ReductionTarget::User, &units);
double value = Shared::PoincareHelpers::ApproximateToScalar<double>(copy, App::app()->localContext());
ExpressionNode::ReductionContext reductionContext(
App::app()->localContext(),
Preferences::sharedPreferences()->complexFormat(),
Preferences::sharedPreferences()->angleUnit(),
GlobalPreferences::sharedGlobalPreferences()->unitFormat(),
ExpressionNode::ReductionTarget::User,
ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined);
int numberOfExpressions = Unit::SetAdditionalExpressions(units, value, expressions, k_maxNumberOfRows, reductionContext);
PoincareHelpers::Reduce(&copy, App::app()->localContext(), ExpressionNode::ReductionTarget::User);
copy = copy.removeUnit(&units);
bool requireSimplification = false;
bool canChangeUnitPrefix = false;
// 2. SI units only
assert(numberOfExpressions < k_maxNumberOfRows - 1);
expressions[numberOfExpressions] = m_expression.clone();
Shared::PoincareHelpers::Simplify(&expressions[numberOfExpressions], App::app()->localContext(), ExpressionNode::ReductionTarget::User, Poincare::ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, Poincare::ExpressionNode::UnitConversion::InternationalSystem);
numberOfExpressions++;
if (Unit::IsSISpeed(units)) {
// 1.a. Turn speed into km/h
m_memoizedExpressions[numberOfMemoizedExpressions++] = UnitConvert::Builder(
m_expression.clone(),
Multiplication::Builder(
Unit::Kilometer(),
Power::Builder(
Unit::Hour(),
Rational::Builder(-1)
)
)
);
requireSimplification = true; // Simplify the conversion
} else if (Unit::IsSIVolume(units)) {
// 1.b. Turn volume into L
m_memoizedExpressions[numberOfMemoizedExpressions++] = UnitConvert::Builder(
m_expression.clone(),
Unit::Liter()
);
requireSimplification = true; // Simplify the conversion
canChangeUnitPrefix = true; // Pick best prefix (mL)
} else if (Unit::IsSIEnergy(units)) {
// 1.c. Turn energy into Wh
m_memoizedExpressions[numberOfMemoizedExpressions++] = UnitConvert::Builder(
m_expression.clone(),
Multiplication::Builder(
Unit::Watt(),
Unit::Hour()
)
);
m_memoizedExpressions[numberOfMemoizedExpressions++] = UnitConvert::Builder(
m_expression.clone(),
Unit::ElectronVolt()
);
requireSimplification = true; // Simplify the conversion
canChangeUnitPrefix = true; // Pick best prefix (kWh)
} else if (Unit::IsSITime(units)) {
// Turn time into ? year + ? month + ? day + ? h + ? min + ? s
double value = Shared::PoincareHelpers::ApproximateToScalar<double>(copy, App::app()->localContext());
m_memoizedExpressions[numberOfMemoizedExpressions++] = Unit::BuildTimeSplit(value, App::app()->localContext(), Preferences::sharedPreferences()->complexFormat(), Preferences::sharedPreferences()->angleUnit());
}
// 1.d. Simplify and tune prefix of all computed expressions
size_t currentExpressionIndex = 0;
while (currentExpressionIndex < numberOfMemoizedExpressions) {
assert(!m_memoizedExpressions[currentExpressionIndex].isUninitialized());
if (requireSimplification) {
Shared::PoincareHelpers::Simplify(&m_memoizedExpressions[currentExpressionIndex], App::app()->localContext(), ExpressionNode::ReductionTarget::User);
}
if (canChangeUnitPrefix) {
Expression newUnits;
// Reduce to be able to removeUnit
PoincareHelpers::Reduce(&m_memoizedExpressions[currentExpressionIndex], App::app()->localContext(), ExpressionNode::ReductionTarget::User);
m_memoizedExpressions[currentExpressionIndex] = m_memoizedExpressions[currentExpressionIndex].removeUnit(&newUnits);
double value = Shared::PoincareHelpers::ApproximateToScalar<double>(m_memoizedExpressions[currentExpressionIndex], App::app()->localContext());
ExpressionNode::ReductionContext reductionContext(
App::app()->localContext(),
Preferences::sharedPreferences()->complexFormat(),
Preferences::sharedPreferences()->angleUnit(),
ExpressionNode::ReductionTarget::User,
ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined);
Unit::ChooseBestPrefixForValue(&newUnits, &value, reductionContext);
m_memoizedExpressions[currentExpressionIndex] = Multiplication::Builder(Number::FloatNumber(value), newUnits);
}
currentExpressionIndex++;
}
/* 3. Get rid of duplicates
* We find duplicates by comparing the serializations, to eliminate
* expressions that only differ by the types of their number nodes. */
// 2. IS units only
assert(numberOfMemoizedExpressions < k_maxNumberOfCells - 1);
m_memoizedExpressions[numberOfMemoizedExpressions] = m_expression.clone();
Shared::PoincareHelpers::Simplify(&m_memoizedExpressions[numberOfMemoizedExpressions], App::app()->localContext(), ExpressionNode::ReductionTarget::User, Poincare::ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, Poincare::ExpressionNode::UnitConversion::InternationalSystem);
numberOfMemoizedExpressions++;
// 3. Get rid of duplicates
Expression reduceExpression = m_expression.clone();
// Make m_expression comparable to expressions (turn BasedInteger into Rational for instance)
// Make m_expression compareable to m_memoizedExpressions (turn BasedInteger into Rational for instance)
Shared::PoincareHelpers::Simplify(&reduceExpression, App::app()->localContext(), ExpressionNode::ReductionTarget::User, Poincare::ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition, Poincare::ExpressionNode::UnitConversion::None);
int currentExpressionIndex = 0;
while (currentExpressionIndex < numberOfExpressions) {
currentExpressionIndex = 1;
while (currentExpressionIndex < numberOfMemoizedExpressions) {
bool duplicateFound = false;
constexpr int buffersSize = Constant::MaxSerializedExpressionSize;
char buffer1[buffersSize];
int size1 = PoincareHelpers::Serialize(expressions[currentExpressionIndex], buffer1, buffersSize);
for (int i = 0; i < currentExpressionIndex + 1; i++) {
// Compare the currentExpression to all previous expressions and to m_expression
Expression comparedExpression = i == currentExpressionIndex ? reduceExpression : expressions[i];
for (size_t i = 0; i < currentExpressionIndex + 1; i++) {
// Compare the currentExpression to all previous memoized expressions and to m_expression
Expression comparedExpression = i == currentExpressionIndex ? reduceExpression : m_memoizedExpressions[i];
assert(!comparedExpression.isUninitialized());
char buffer2[buffersSize];
int size2 = PoincareHelpers::Serialize(comparedExpression, buffer2, buffersSize);
if (size1 == size2 && strcmp(buffer1, buffer2) == 0) {
numberOfExpressions--;
if (comparedExpression.isIdenticalTo(m_memoizedExpressions[currentExpressionIndex])) {
numberOfMemoizedExpressions--;
// Shift next expressions
for (int j = currentExpressionIndex; j < numberOfExpressions; j++) {
expressions[j] = expressions[j+1];
for (size_t j = currentExpressionIndex; j < numberOfMemoizedExpressions; j++) {
m_memoizedExpressions[j] = m_memoizedExpressions[j+1];
}
// Remove last expression
expressions[numberOfExpressions] = Expression();
m_memoizedExpressions[numberOfMemoizedExpressions] = Expression();
// The current expression has been discarded, no need to increment the current index
duplicateFound = true;
break;
@@ -81,12 +131,21 @@ void UnitListController::setExpression(Poincare::Expression e) {
currentExpressionIndex++;
}
}
// Memoize layouts
for (size_t i = 0; i < k_maxNumberOfRows; i++) {
if (!expressions[i].isUninitialized()) {
m_layouts[i] = Shared::PoincareHelpers::CreateLayout(expressions[i]);
}
int UnitListController::numberOfRows() const {
int nbOfRows = 0;
for (size_t i = 0; i < k_maxNumberOfCells; i++) {
if (!m_memoizedExpressions[i].isUninitialized()) {
nbOfRows++;
}
}
return nbOfRows;
}
void UnitListController::computeLayoutAtIndex(int index) {
assert(!m_memoizedExpressions[index].isUninitialized());
m_layouts[index] = Shared::PoincareHelpers::CreateLayout(m_memoizedExpressions[index]);
}
I18n::Message UnitListController::messageAtIndex(int index) {

View File

@@ -12,8 +12,13 @@ public:
void setExpression(Poincare::Expression e) override;
//ListViewDataSource
int numberOfRows() const override;
private:
void computeLayoutAtIndex(int index) override;
I18n::Message messageAtIndex(int index) override;
// Memoization of expressions
mutable Poincare::Expression m_memoizedExpressions[k_maxNumberOfCells];
};
}

View File

@@ -31,8 +31,6 @@ App * App::Snapshot::unpack(Container * container) {
void App::Snapshot::reset() {
m_calculationStore.deleteAll();
m_cacheBuffer[0] = 0;
m_cacheBufferInformation = 0;
}
App::Descriptor * App::Snapshot::descriptor() {
@@ -40,14 +38,14 @@ App::Descriptor * App::Snapshot::descriptor() {
return &descriptor;
}
App::Snapshot::Snapshot() : m_calculationStore(m_calculationBuffer, k_calculationBufferSize)
{
void App::Snapshot::tidy() {
m_calculationStore.tidy();
}
App::App(Snapshot * snapshot) :
ExpressionFieldDelegateApp(snapshot, &m_editExpressionController),
m_historyController(&m_editExpressionController, snapshot->calculationStore()),
m_editExpressionController(&m_modalViewController, this, snapshot->cacheBuffer(), snapshot->cacheBufferInformationAddress(), &m_historyController, snapshot->calculationStore())
m_editExpressionController(&m_modalViewController, this, &m_historyController, snapshot->calculationStore())
{
}
@@ -72,17 +70,7 @@ bool App::isAcceptableExpression(const Poincare::Expression expression) {
return false;
}
}
return !(expression.isUninitialized() || expression.type() == ExpressionNode::Type::Equal);
}
void App::didBecomeActive(Window * window) {
m_editExpressionController.restoreInput();
Shared::ExpressionFieldDelegateApp::didBecomeActive(window);
}
void App::willBecomeInactive() {
m_editExpressionController.memoizeInput();
Shared::ExpressionFieldDelegateApp::willBecomeInactive();
return !expression.isUninitialized();
}
}

View File

@@ -6,7 +6,6 @@
#include "history_controller.h"
#include "../shared/text_field_delegate_app.h"
#include <escher.h>
#include "../shared/shared_app.h"
namespace Calculation {
@@ -19,22 +18,15 @@ public:
App::Descriptor::ExaminationLevel examinationLevel() override;
const Image * icon() override;
};
class Snapshot : public ::SharedApp::Snapshot {
class Snapshot : public ::App::Snapshot {
public:
Snapshot();
App * unpack(Container * container) override;
void reset() override;
Descriptor * descriptor() override;
CalculationStore * calculationStore() { return &m_calculationStore; }
char * cacheBuffer() { return m_cacheBuffer; }
size_t * cacheBufferInformationAddress() { return &m_cacheBufferInformation; }
private:
void tidy() override;
CalculationStore m_calculationStore;
// Set the size of the buffer needed to store the calculations
static constexpr int k_calculationBufferSize = 10 * (sizeof(Calculation) + Calculation::k_numberOfExpressions * Constant::MaxSerializedExpressionSize + sizeof(Calculation *));
char m_calculationBuffer[k_calculationBufferSize];
char m_cacheBuffer[EditExpressionController::k_cacheBufferSize];
size_t m_cacheBufferInformation;
};
static App * app() {
return static_cast<App *>(Container::activeApp());
@@ -44,12 +36,9 @@ public:
bool layoutFieldDidReceiveEvent(::LayoutField * layoutField, Ion::Events::Event event) override;
// TextFieldDelegateApp
bool isAcceptableExpression(const Poincare::Expression expression) override;
private:
App(Snapshot * snapshot);
HistoryController m_historyController;
void didBecomeActive(Window * window) override;
void willBecomeInactive() override;
EditExpressionController m_editExpressionController;
};

View File

@@ -7,8 +7,3 @@ BinaryBase = "Binär"
PrimeFactors = "Primfaktoren"
MixedFraction = "Gemischte Zahl"
EuclideanDivision = "Division mit Rest"
AdditionalDeterminant = "Determinante"
AdditionalInverse = "Inverse"
AdditionalRowEchelonForm = "Stufenform"
AdditionalReducedRowEchelonForm = "Reduzierte Stufenform"
AdditionalTrace = "Spur"

View File

@@ -7,8 +7,3 @@ BinaryBase = "Binary"
PrimeFactors = "Prime factors"
MixedFraction = "Mixed fraction"
EuclideanDivision = "Euclidean division"
AdditionalDeterminant = "Determinant"
AdditionalInverse = "Inverse"
AdditionalRowEchelonForm = "Row echelon form"
AdditionalReducedRowEchelonForm = "Reduced row echelon form"
AdditionalTrace = "Trace"

View File

@@ -7,8 +7,3 @@ BinaryBase = "Binario"
PrimeFactors = "Factores primos"
MixedFraction = "Fracción mixta"
EuclideanDivision = "División euclidiana"
AdditionalDeterminant = "Determinante"
AdditionalInverse = "Inversa"
AdditionalRowEchelonForm = "Matriz escalonada"
AdditionalReducedRowEchelonForm = "Matriz escalonada reducida"
AdditionalTrace = "Traza"

View File

@@ -7,8 +7,3 @@ BinaryBase = "Binaire"
PrimeFactors = "Facteurs premiers"
MixedFraction = "Fraction mixte"
EuclideanDivision = "Division euclidienne"
AdditionalDeterminant = "Déterminant"
AdditionalInverse = "Inverse"
AdditionalRowEchelonForm = "Forme échelonnée"
AdditionalReducedRowEchelonForm = "Forme échelonnée réduite"
AdditionalTrace = "Trace"

View File

@@ -3,12 +3,7 @@ CalculAppCapital = "SZÁMOLÁS"
AdditionalResults = "További eredmények"
DecimalBase = "Decimális"
HexadecimalBase = "Hexadecimális"
BinaryBase = "Bináris"
BinaryBase = "Kétkomponensü"
PrimeFactors = "Alapvetö tényezök"
MixedFraction = "Vegyes frakció"
EuclideanDivision = "Euklideszi osztás"
AdditionalDeterminant = "Meghatározó"
AdditionalInverse = "inverz"
AdditionalRowEchelonForm = "Sor echelon forma"
AdditionalReducedRowEchelonForm = "Csökkentett sorú Echelon forma"
AdditionalTrace = "Nyomkövetés"

View File

@@ -4,11 +4,6 @@ AdditionalResults = "Risultati complementari"
DecimalBase = "Decimale"
HexadecimalBase = "Esadecimale"
BinaryBase = "Binario"
PrimeFactors = "Fattorizzazione"
PrimeFactors = "Fattori primi"
MixedFraction = "Frazione mista"
EuclideanDivision = "Divisione euclidea"
AdditionalDeterminant = "Determinante"
AdditionalInverse = "Inversa"
AdditionalRowEchelonForm = "Matrice a scalini"
AdditionalReducedRowEchelonForm = "Matrice ridotta a scalini"
AdditionalTrace = "Traccia"

View File

@@ -1,14 +1,9 @@
CalculApp = "Rekenen"
CalculAppCapital = "REKENEN"
AdditionalResults = "Aanvullende resultaten"
CalculApp = "Calculatie"
CalculAppCapital = "CALCULATIE"
AdditionalResults = "Bijkomende resultaten"
DecimalBase = "Decimaal"
HexadecimalBase = "Hexadecimaal"
BinaryBase = "Binair"
PrimeFactors = "Ontbinding"
BinaryBase = "Binaire"
PrimeFactors = "Priemfactoren"
MixedFraction = "Gemengde breuk"
EuclideanDivision = "Geheeltallige deling"
AdditionalDeterminant = "Determinant"
AdditionalInverse = "Inverse"
AdditionalRowEchelonForm = "Echelonvorm"
AdditionalReducedRowEchelonForm = "Gereduceerde echelonvorm"
AdditionalTrace = "Spoor"

View File

@@ -4,11 +4,6 @@ AdditionalResults = "Resultados adicionais"
DecimalBase = "Decimal"
HexadecimalBase = "Hexadecimal"
BinaryBase = "Binário"
PrimeFactors = "Fatorização"
PrimeFactors = "Fatores primos"
MixedFraction = "Fração mista"
EuclideanDivision = "Divisão euclidiana"
AdditionalDeterminant = "Determinante"
AdditionalInverse = "Matriz inversa"
AdditionalRowEchelonForm = "Matriz escalonada"
AdditionalReducedRowEchelonForm = "Matriz escalonada reduzida"
AdditionalTrace = "Traço"

View File

@@ -169,8 +169,7 @@ Calculation::DisplayOutput Calculation::displayOutput(Context * context) {
ExpressionNode::Type::Sum,
ExpressionNode::Type::Derivative,
ExpressionNode::Type::ConfidenceInterval,
ExpressionNode::Type::PredictionInterval,
ExpressionNode::Type::Sequence
ExpressionNode::Type::PredictionInterval
};
return e.isOfType(approximateOnlyTypes, sizeof(approximateOnlyTypes)/sizeof(ExpressionNode::Type));
}, context)
@@ -219,7 +218,7 @@ Calculation::EqualSign Calculation::exactAndApproximateDisplayedOutputsAreEqual(
Preferences * preferences = Preferences::sharedPreferences();
// TODO: complex format should not be needed here (as it is not used to create layouts)
Preferences::ComplexFormat complexFormat = Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), m_inputText);
m_equalSign = Expression::ParsedExpressionsAreEqual(exactOutputText(), approximateOutputText(NumberOfSignificantDigits::UserDefined), context, complexFormat, preferences->angleUnit(), GlobalPreferences::sharedGlobalPreferences()->unitFormat()) ? EqualSign::Equal : EqualSign::Approximation;
m_equalSign = Expression::ParsedExpressionsAreEqual(exactOutputText(), approximateOutputText(NumberOfSignificantDigits::UserDefined), context, complexFormat, preferences->angleUnit()) ? EqualSign::Equal : EqualSign::Approximation;
return m_equalSign;
} else {
/* Do not override m_equalSign in case there is enough room in the pool
@@ -255,9 +254,32 @@ Calculation::AdditionalInformationType Calculation::additionalInformationType(Co
}
if (o.hasUnit()) {
Expression unit;
PoincareHelpers::ReduceAndRemoveUnit(&o, App::app()->localContext(), ExpressionNode::ReductionTarget::User, &unit, ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined, ExpressionNode::UnitConversion::None);
double value = PoincareHelpers::ApproximateToScalar<double>(o, App::app()->localContext());
return (Unit::ShouldDisplayAdditionalOutputs(value, unit, GlobalPreferences::sharedGlobalPreferences()->unitFormat())) ? AdditionalInformationType::Unit : AdditionalInformationType::None;
PoincareHelpers::Reduce(&o,
App::app()->localContext(),
ExpressionNode::ReductionTarget::User,
ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined,
ExpressionNode::UnitConversion::None);
o = o.removeUnit(&unit);
// There might be no unit in the end, if the reduction was interrupted.
if (!unit.isUninitialized()) {
if (Unit::IsSI(unit)) {
if (Unit::IsSISpeed(unit) || Unit::IsSIVolume(unit) || Unit::IsSIEnergy(unit)) {
/* All these units will provide misc. classic representatives in
* addition to the SI unit in additional information. */
return AdditionalInformationType::Unit;
}
if (Unit::IsSITime(unit)) {
/* If the number of seconds is above 60s, we can write it in the form
* of an addition: 23_min + 12_s for instance. */
double value = Shared::PoincareHelpers::ApproximateToScalar<double>(o, App::app()->localContext());
if (value > Unit::SecondsPerMinute) {
return AdditionalInformationType::Unit;
}
}
return AdditionalInformationType::None;
}
return AdditionalInformationType::Unit;
}
}
if (o.isBasedIntegerCappedBy(k_maximalIntegerWithAdditionalInformation)) {
return AdditionalInformationType::Integer;
@@ -269,9 +291,6 @@ Calculation::AdditionalInformationType Calculation::additionalInformationType(Co
if (o.hasDefinedComplexApproximation(context, complexFormat, preferences->angleUnit())) {
return AdditionalInformationType::Complex;
}
if (o.type() == ExpressionNode::Type::Matrix) {
return AdditionalInformationType::Matrix;
}
return AdditionalInformationType::None;
}

View File

@@ -21,7 +21,6 @@ class CalculationStore;
class Calculation {
friend CalculationStore;
public:
static constexpr int k_numberOfExpressions = 4;
enum class EqualSign : uint8_t {
Unknown,
Approximation,
@@ -41,7 +40,6 @@ public:
Rational,
Trigonometry,
Unit,
Matrix,
Complex
};
static bool DisplaysExact(DisplayOutput d) { return d != DisplayOutput::ApproximateOnly; }
@@ -50,7 +48,7 @@ public:
* calculations instead of clearing less space, then fail to serialize, clear
* more space, fail to serialize, clear more space, etc., until reaching
* sufficient free space. */
static int MinimalSize() { return sizeof(uint8_t) + 2*sizeof(KDCoordinate) + sizeof(uint8_t) + 3*Constant::MaxSerializedExpressionSize + sizeof(Calculation *); }
static int MinimalSize() { return sizeof(uint8_t) + 2*sizeof(KDCoordinate) + sizeof(uint8_t) + 3*Constant::MaxSerializedExpressionSize; }
Calculation() :
m_displayOutput(DisplayOutput::Unknown),
@@ -95,6 +93,8 @@ public:
// Additional Information
AdditionalInformationType additionalInformationType(Poincare::Context * context);
private:
static constexpr int maxWidth = 314;
static constexpr int k_numberOfExpressions = 4;
static constexpr KDCoordinate k_heightComputationFailureHeight = 50;
static constexpr const char * k_maximalIntegerWithAdditionalInformation = "10000000000000000";

View File

@@ -12,47 +12,58 @@ using namespace Shared;
namespace Calculation {
CalculationStore::CalculationStore(char * buffer, int size) :
m_buffer(buffer),
m_bufferSize(size),
m_calculationAreaEnd(m_buffer),
m_numberOfCalculations(0)
CalculationStore::CalculationStore() :
m_bufferEnd(m_buffer),
m_numberOfCalculations(0),
m_slidedBuffer(false),
m_indexOfFirstMemoizedCalculationPointer(0)
{
assert(m_buffer != nullptr);
assert(m_bufferSize > 0);
resetMemoizedModelsAfterCalculationIndex(-1);
}
// Returns an expiring pointer to the calculation of index i
ExpiringPointer<Calculation> CalculationStore::calculationAtIndex(int i) {
assert(!m_slidedBuffer);
assert(i >= 0 && i < m_numberOfCalculations);
// 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
c = *reinterpret_cast<Calculation**>(addressOfPointerToCalculationOfIndex(i+1));
assert(m_indexOfFirstMemoizedCalculationPointer >= 0);
if (i >= m_indexOfFirstMemoizedCalculationPointer && i < m_indexOfFirstMemoizedCalculationPointer + k_numberOfMemoizedCalculationPointers) {
// The calculation is within the range of memoized calculations
Calculation * c = m_memoizedCalculationPointers[i-m_indexOfFirstMemoizedCalculationPointer];
if (c != nullptr) {
// The pointer was memoized
return ExpiringPointer<Calculation>(c);
}
c = bufferCalculationAtIndex(i);
m_memoizedCalculationPointers[i-m_indexOfFirstMemoizedCalculationPointer] = c;
return c;
}
return ExpiringPointer<Calculation>(c);
// Slide the memoization buffer
if (i >= m_indexOfFirstMemoizedCalculationPointer) {
// Slide the memoization buffer to the left
memmove(m_memoizedCalculationPointers, m_memoizedCalculationPointers+1, (k_numberOfMemoizedCalculationPointers - 1) * sizeof(Calculation *));
m_memoizedCalculationPointers[k_numberOfMemoizedCalculationPointers - 1] = nullptr;
m_indexOfFirstMemoizedCalculationPointer++;
} else {
// Slide the memoization buffer to the right
memmove(m_memoizedCalculationPointers+1, m_memoizedCalculationPointers, (k_numberOfMemoizedCalculationPointers - 1) * sizeof(Calculation *));
m_memoizedCalculationPointers[0] = nullptr;
m_indexOfFirstMemoizedCalculationPointer--;
}
return calculationAtIndex(i);
}
// Pushes an expression in the store
ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context * context, HeightComputer heightComputer) {
/* Compute ans now, before the buffer is updated and before the calculation
/* Compute ans now, before the buffer is slided 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 */
int minSize = Calculation::MinimalSize() + sizeof(Calculation *);
assert(m_bufferSize > minSize);
while (remainingBufferSize() < minSize) {
// If there is no more space to store a calculation, we delete the oldest one
deleteOldestCalculation();
// Prepare the buffer for the new calculation
int minSize = Calculation::MinimalSize();
assert(k_bufferSize > minSize);
while (remainingBufferSize() < minSize || m_numberOfCalculations > k_maxNumberOfCalculations) {
deleteLastCalculation();
}
// Getting the adresses of the limits of the free space
char * beginingOfFreeSpace = (char *)m_calculationAreaEnd;
char * endOfFreeSpace = beginingOfMemoizationArea();
char * previousCalc = beginingOfFreeSpace;
char * newCalculationsLocation = slideCalculationsToEndOfBuffer();
char * nextSerializationLocation = m_buffer;
// Add the beginning of the calculation
{
@@ -60,23 +71,23 @@ ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context *
* available, so this memmove will not overide anything. */
Calculation newCalc = Calculation();
size_t calcSize = sizeof(newCalc);
memcpy(beginingOfFreeSpace, &newCalc, calcSize);
beginingOfFreeSpace += calcSize;
memmove(nextSerializationLocation, &newCalc, calcSize);
nextSerializationLocation += calcSize;
}
/* Add the input expression.
* We do not store directly the text entered by the user because we do not
* want to keep Ans symbol in the calculation store. */
const char * inputSerialization = beginingOfFreeSpace;
const char * inputSerialization = nextSerializationLocation;
{
Expression input = Expression::Parse(text, context).replaceSymbolWithExpression(Symbol::Ans(), ans);
if (!pushSerializeExpression(input, beginingOfFreeSpace, &endOfFreeSpace)) {
if (!pushSerializeExpression(input, nextSerializationLocation, &newCalculationsLocation)) {
/* If the input does not fit in the store (event if the current
* calculation is the only calculation), just replace the calculation with
* undef. */
return emptyStoreAndPushUndef(context, heightComputer);
}
beginingOfFreeSpace += strlen(beginingOfFreeSpace) + 1;
nextSerializationLocation += strlen(nextSerializationLocation) + 1;
}
// Compute and serialize the outputs
@@ -99,27 +110,30 @@ ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context *
if (i == numberOfOutputs - 1) {
numberOfSignificantDigits = Poincare::Preferences::sharedPreferences()->numberOfSignificantDigits();
}
if (!pushSerializeExpression(outputs[i], beginingOfFreeSpace, &endOfFreeSpace, numberOfSignificantDigits)) {
if (!pushSerializeExpression(outputs[i], nextSerializationLocation, &newCalculationsLocation, numberOfSignificantDigits)) {
/* 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 calcualtion with undef. */
Expression undef = Undefined::Builder();
if (!pushSerializeExpression(undef, beginingOfFreeSpace, &endOfFreeSpace)) {
if (!pushSerializeExpression(undef, nextSerializationLocation, &newCalculationsLocation)) {
return emptyStoreAndPushUndef(context, heightComputer);
}
}
beginingOfFreeSpace += strlen(beginingOfFreeSpace) + 1;
nextSerializationLocation += strlen(nextSerializationLocation) + 1;
}
}
// Storing the pointer of the end of the new calculation
memcpy(endOfFreeSpace-sizeof(Calculation*),&beginingOfFreeSpace,sizeof(beginingOfFreeSpace));
// The new calculation is now stored
// Restore the other calculations
size_t slideSize = m_buffer + k_bufferSize - newCalculationsLocation;
memcpy(nextSerializationLocation, newCalculationsLocation, slideSize);
m_slidedBuffer = false;
m_numberOfCalculations++;
m_bufferEnd+= nextSerializationLocation - m_buffer;
// The end of the calculation storage area is updated
m_calculationAreaEnd += beginingOfFreeSpace - previousCalc;
ExpiringPointer<Calculation> calculation = ExpiringPointer<Calculation>(reinterpret_cast<Calculation *>(previousCalc));
// Clean the memoization
resetMemoizedModelsAfterCalculationIndex(-1);
ExpiringPointer<Calculation> calculation = ExpiringPointer<Calculation>(reinterpret_cast<Calculation *>(m_buffer));
/* Heights are computed now to make sure that the display output is decided
* accordingly to the remaining size in the Poincare pool. Once it is, it
* can't change anymore: the calculation heights are fixed which ensures that
@@ -130,42 +144,36 @@ ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context *
return calculation;
}
// Delete the calculation of index i
void CalculationStore::deleteCalculationAtIndex(int i) {
assert(i >= 0 && i < m_numberOfCalculations);
if (i == 0) {
ExpiringPointer<Calculation> lastCalculationPointer = calculationAtIndex(0);
m_calculationAreaEnd = (char *)(lastCalculationPointer.pointer());
m_numberOfCalculations--;
assert(!m_slidedBuffer);
ExpiringPointer<Calculation> calcI = calculationAtIndex(i);
char * nextCalc = reinterpret_cast<char *>(calcI->next());
assert(m_bufferEnd >= nextCalc);
size_t slidingSize = m_bufferEnd - nextCalc;
memmove((char *)(calcI.pointer()), nextCalc, slidingSize);
m_bufferEnd -= (nextCalc - (char *)(calcI.pointer()));
m_numberOfCalculations--;
resetMemoizedModelsAfterCalculationIndex(i);
}
void CalculationStore::deleteAll() {
/* We might call deleteAll because the app closed due to a pool allocation
* failure, so we cannot assert that m_slidedBuffer is false. */
m_slidedBuffer = false;
m_bufferEnd = m_buffer;
m_numberOfCalculations = 0;
resetMemoizedModelsAfterCalculationIndex(-1);
}
void CalculationStore::tidy() {
if (m_slidedBuffer) {
deleteAll();
return;
}
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
memmove(calcI, nextCalc, slidingSize);
m_calculationAreaEnd -= nextCalc - calcI;
// Recompute pointer to calculations after the i'th
recomputeMemoizedPointersAfterCalculationIndex(i);
m_numberOfCalculations--;
resetMemoizedModelsAfterCalculationIndex(-1);
}
// 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;
deleteCalculationAtIndex(numberOfCalculations()-1);
char * newBufferEnd = (char *) m_calculationAreaEnd;
return oldBufferEnd - newBufferEnd;
}
// Delete all calculations
void CalculationStore::deleteAll() {
m_calculationAreaEnd = m_buffer;
m_numberOfCalculations = 0;
}
// Replace "Ans" by its expression
Expression CalculationStore::ansExpression(Context * context) {
if (numberOfCalculations() == 0) {
return Rational::Builder(0);
@@ -184,42 +192,92 @@ Expression CalculationStore::ansExpression(Context * context) {
return mostRecentCalculation->exactOutput();
}
// Push converted expression in the buffer
Calculation * CalculationStore::bufferCalculationAtIndex(int i) {
int currentIndex = 0;
for (Calculation * c : *this) {
if (currentIndex == i) {
return c;
}
currentIndex++;
}
assert(false);
return nullptr;
}
bool CalculationStore::pushSerializeExpression(Expression e, char * location, char * * newCalculationsLocation, int numberOfSignificantDigits) {
assert(*newCalculationsLocation <= m_buffer + m_bufferSize);
assert(m_slidedBuffer);
assert(*newCalculationsLocation <= m_buffer + k_bufferSize);
bool expressionIsPushed = false;
while (true) {
size_t locationSize = *newCalculationsLocation - location;
expressionIsPushed = (PoincareHelpers::Serialize(e, location, locationSize, numberOfSignificantDigits) < (int)locationSize-1);
if (expressionIsPushed || *newCalculationsLocation >= m_buffer + m_bufferSize) {
if (expressionIsPushed || *newCalculationsLocation >= m_buffer + k_bufferSize) {
break;
}
*newCalculationsLocation = *newCalculationsLocation + deleteOldestCalculation();
assert(*newCalculationsLocation <= m_buffer + m_bufferSize);
*newCalculationsLocation = *newCalculationsLocation + deleteLastCalculation();
assert(*newCalculationsLocation <= m_buffer + k_bufferSize);
}
return expressionIsPushed;
}
char * CalculationStore::slideCalculationsToEndOfBuffer() {
int calculationsSize = m_bufferEnd - m_buffer;
char * calculationsNewPosition = m_buffer + k_bufferSize - calculationsSize;
memmove(calculationsNewPosition, m_buffer, calculationsSize);
m_slidedBuffer = true;
return calculationsNewPosition;
}
size_t CalculationStore::deleteLastCalculation(const char * calculationsStart) {
assert(m_numberOfCalculations > 0);
size_t result;
if (!m_slidedBuffer) {
assert(calculationsStart == nullptr);
const char * previousBufferEnd = m_bufferEnd;
m_bufferEnd = lastCalculationPosition(m_buffer);
assert(previousBufferEnd > m_bufferEnd);
result = previousBufferEnd - m_bufferEnd;
} else {
assert(calculationsStart != nullptr);
const char * lastCalc = lastCalculationPosition(calculationsStart);
assert(*lastCalc == 0);
result = m_buffer + k_bufferSize - lastCalc;
memmove(const_cast<char *>(calculationsStart + result), calculationsStart, m_buffer + k_bufferSize - calculationsStart - result);
}
m_numberOfCalculations--;
resetMemoizedModelsAfterCalculationIndex(-1);
return result;
}
const char * CalculationStore::lastCalculationPosition(const char * calculationsStart) const {
assert(calculationsStart >= m_buffer && calculationsStart < m_buffer + k_bufferSize);
Calculation * c = reinterpret_cast<Calculation *>(const_cast<char *>(calculationsStart));
int calculationIndex = 0;
while (calculationIndex < m_numberOfCalculations - 1) {
c = c->next();
calculationIndex++;
}
return reinterpret_cast<const char *>(c);
}
Shared::ExpiringPointer<Calculation> CalculationStore::emptyStoreAndPushUndef(Context * context, HeightComputer heightComputer) {
/* We end up here as a result of a failed calculation push. The store
* attributes are not necessarily clean, so we need to reset them. */
m_slidedBuffer = false;
deleteAll();
return push(Undefined::Name(), context, heightComputer);
}
// Recompute memoized pointers to the calculations after index i
void CalculationStore::recomputeMemoizedPointersAfterCalculationIndex(int index) {
assert(index < m_numberOfCalculations);
// Clear pointer and recompute new ones
Calculation * c = calculationAtIndex(index).pointer();
Calculation * nextCalc;
while (index != 0) {
nextCalc = c->next();
memcpy(addressOfPointerToCalculationOfIndex(index), &nextCalc, sizeof(Calculation *));
c = nextCalc;
index--;
void CalculationStore::resetMemoizedModelsAfterCalculationIndex(int index) {
if (index < m_indexOfFirstMemoizedCalculationPointer) {
memset(&m_memoizedCalculationPointers, 0, k_numberOfMemoizedCalculationPointers * sizeof(Calculation *));
return;
}
if (index >= m_indexOfFirstMemoizedCalculationPointer + k_numberOfMemoizedCalculationPointers) {
return;
}
for (int i = index - m_indexOfFirstMemoizedCalculationPointer; i < k_numberOfMemoizedCalculationPointers; i++) {
m_memoizedCalculationPointers[i] = nullptr;
}
}

View File

@@ -7,45 +7,37 @@
namespace Calculation {
/*
To optimize the storage space, we use one big buffer for all calculations.
The calculations are stored one after another while pointers to the end of each
calculation are stored at the end of the buffer, in the opposite direction.
By doing so, we can memoize every calculation entered while not limiting
the number of calculation stored in the buffer.
If the remaining space is too small for storing a new calculation, we
delete the oldest one.
Memory layout :
<- Available space for new calculations ->
+--------------------------------------------------------------------------------------------------------------------+
| | | | | | | | | |
| Calculation 3 | Calculation 2 | Calculation 1 | Calculation O | |p0|p1|p2|p3|
| Oldest | | | | | | | | |
+--------------------------------------------------------------------------------------------------------------------+
^ ^ ^ ^ ^ ^
m_buffer p3 p2 p1 p0 a
m_calculationAreaEnd = p0
a = addressOfPointerToCalculation(0)
*/
/* To optimize the storage space, we use one big buffer for all calculations.
*
* The previous solution was to keep 10 calculations, each containing 3 buffers
* (for input and outputs). To optimize the storage, we then wanted to put all
* outputs in a cache where they could be deleted to add a new entry, and
* recomputed on cache miss. However, the computation depends too much on the
* state of the memory for this to be possible. For instance:
* 6->a
* a+1
* Perform some big computations that remove a+1 from the cache
* Delete a from the variable box.
* Scroll up to display a+1 : a does not exist anymore so the outputs won't be
* recomputed correctly.
*
* Now we do not cap the number of calculations and just delete the oldests to
* create space for a new calculation. */
class CalculationStore {
public:
CalculationStore();
CalculationStore(char * buffer, int size);
Shared::ExpiringPointer<Calculation> calculationAtIndex(int i);
typedef KDCoordinate (*HeightComputer)(Calculation * c, bool expanded);
Shared::ExpiringPointer<Calculation> push(const char * text, Poincare::Context * context, HeightComputer heightComputer);
void deleteCalculationAtIndex(int i);
void deleteAll();
int remainingBufferSize() const { assert(m_calculationAreaEnd >= m_buffer); return m_bufferSize - (m_calculationAreaEnd - m_buffer) - m_numberOfCalculations*sizeof(Calculation*); }
int numberOfCalculations() const { return m_numberOfCalculations; }
Poincare::Expression ansExpression(Poincare::Context * context);
int bufferSize() { return m_bufferSize; }
void tidy();
private:
static constexpr int k_maxNumberOfCalculations = 25;
static constexpr int k_bufferSize = 10 * Calculation::k_numberOfExpressions * Constant::MaxSerializedExpressionSize;
class CalculationIterator {
public:
@@ -61,22 +53,26 @@ private:
};
CalculationIterator begin() const { return CalculationIterator(m_buffer); }
CalculationIterator end() const { return CalculationIterator(m_calculationAreaEnd); }
CalculationIterator end() const { return CalculationIterator(m_bufferEnd); }
Calculation * bufferCalculationAtIndex(int i);
int remainingBufferSize() const { assert(m_bufferEnd >= m_buffer); return k_bufferSize - (m_bufferEnd - m_buffer); }
bool pushSerializeExpression(Poincare::Expression e, char * location, char * * newCalculationsLocation, int numberOfSignificantDigits = Poincare::PrintFloat::k_numberOfStoredSignificantDigits);
char * slideCalculationsToEndOfBuffer(); // returns the new position of the calculations
size_t deleteLastCalculation(const char * calculationsStart = nullptr);
const char * lastCalculationPosition(const char * calculationsStart) const;
Shared::ExpiringPointer<Calculation> emptyStoreAndPushUndef(Poincare::Context * context, HeightComputer heightComputer);
char * m_buffer;
int m_bufferSize;
const char * m_calculationAreaEnd;
char m_buffer[k_bufferSize];
const char * m_bufferEnd;
int m_numberOfCalculations;
size_t deleteOldestCalculation();
char * addressOfPointerToCalculationOfIndex(int i) {return m_buffer + m_bufferSize - (m_numberOfCalculations - i)*sizeof(Calculation *);}
bool m_slidedBuffer;
// Memoization
char * beginingOfMemoizationArea() {return addressOfPointerToCalculationOfIndex(0);};
void recomputeMemoizedPointersAfterCalculationIndex(int index);
static constexpr int k_numberOfMemoizedCalculationPointers = 10;
void resetMemoizedModelsAfterCalculationIndex(int index);
int m_indexOfFirstMemoizedCalculationPointer;
mutable Calculation * m_memoizedCalculationPointers[k_numberOfMemoizedCalculationPointers];
};
}

View File

@@ -38,14 +38,13 @@ void EditExpressionController::ContentView::reload() {
markRectAsDirty(bounds());
}
EditExpressionController::EditExpressionController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, char * cacheBuffer, size_t * cacheBufferInformation, HistoryController * historyController, CalculationStore * calculationStore) :
EditExpressionController::EditExpressionController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, HistoryController * historyController, CalculationStore * calculationStore) :
ViewController(parentResponder),
m_cacheBuffer(cacheBuffer),
m_cacheBufferInformation(cacheBufferInformation),
m_historyController(historyController),
m_calculationStore(calculationStore),
m_contentView(this, static_cast<CalculationSelectableTableView *>(m_historyController->view()), inputEventHandlerDelegate, this, this)
{
m_cacheBuffer[0] = 0;
}
void EditExpressionController::insertTextBody(const char * text) {
@@ -59,15 +58,6 @@ void EditExpressionController::didBecomeFirstResponder() {
Container::activeApp()->setFirstResponder(m_contentView.expressionField());
}
void EditExpressionController::restoreInput() {
m_contentView.expressionField()->restoreContent(m_cacheBuffer, *m_cacheBufferInformation);
clearCacheBuffer();
}
void EditExpressionController::memoizeInput() {
*m_cacheBufferInformation = m_contentView.expressionField()->moveCursorAndDumpContent(m_cacheBuffer, k_cacheBufferSize);
}
void EditExpressionController::viewWillAppear() {
m_historyController->viewWillAppear();
}
@@ -138,7 +128,7 @@ bool EditExpressionController::inputViewDidReceiveEvent(Ion::Events::Event event
}
if (event == Ion::Events::Up) {
if (m_calculationStore->numberOfCalculations() > 0) {
clearCacheBuffer();
m_cacheBuffer[0] = 0;
m_contentView.expressionField()->setEditing(false, false);
Container::activeApp()->setFirstResponder(m_historyController);
}

View File

@@ -7,6 +7,7 @@
#include "../shared/text_field_delegate.h"
#include "../shared/layout_field_delegate.h"
#include "history_controller.h"
#include "calculation_store.h"
#include "selectable_table_view.h"
namespace Calculation {
@@ -14,23 +15,11 @@ namespace Calculation {
/* TODO: implement a split view */
class EditExpressionController : public ViewController, public Shared::TextFieldDelegate, public Shared::LayoutFieldDelegate {
public:
EditExpressionController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, char * cacheBuffer, size_t * cacheBufferInformation, HistoryController * historyController, CalculationStore * calculationStore);
/* k_layoutBufferMaxSize dictates the size under which the expression being
* edited can be remembered when the user leaves Calculation. */
static constexpr int k_layoutBufferMaxSize = 1024;
/* k_cacheBufferSize is the size of the array to which m_cacheBuffer points.
* It is used both as a way to buffer expression when pushing them the
* CalculationStore, and as a storage for the current input when leaving the
* application. */
static constexpr int k_cacheBufferSize = (k_layoutBufferMaxSize < Constant::MaxSerializedExpressionSize) ? Constant::MaxSerializedExpressionSize : k_layoutBufferMaxSize;
EditExpressionController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, HistoryController * historyController, CalculationStore * calculationStore);
View * view() override { return &m_contentView; }
void didBecomeFirstResponder() override;
void viewWillAppear() override;
void insertTextBody(const char * text);
void restoreInput();
void memoizeInput();
/* TextFieldDelegate */
bool textFieldDidReceiveEvent(::TextField * textField, Ion::Events::Event event) override;
@@ -58,12 +47,11 @@ private:
ExpressionField m_expressionField;
};
void reloadView();
void clearCacheBuffer() { m_cacheBuffer[0] = 0; *m_cacheBufferInformation = 0; }
bool inputViewDidReceiveEvent(Ion::Events::Event event, bool shouldDuplicateLastCalculation);
bool inputViewDidFinishEditing(const char * text, Poincare::Layout layoutR);
bool inputViewDidAbortEditing(const char * text);
char * m_cacheBuffer;
size_t * m_cacheBufferInformation;
static constexpr int k_cacheBufferSize = Constant::MaxSerializedExpressionSize;
char m_cacheBuffer[k_cacheBufferSize];
HistoryController * m_historyController;
CalculationStore * m_calculationStore;
ContentView m_contentView;

View File

@@ -17,8 +17,7 @@ bool ExpressionField::handleEvent(Ion::Events::Event event) {
event == Ion::Events::Power ||
event == Ion::Events::Square ||
event == Ion::Events::Division ||
event == Ion::Events::Sto ||
event == Ion::Events::EE)) {
event == Ion::Events::Sto)) {
handleEventWithText(Poincare::Symbol::k_ans);
}
return(::ExpressionField::handleEvent(event));

View File

@@ -17,8 +17,7 @@ HistoryController::HistoryController(EditExpressionController * editExpressionCo
m_integerController(editExpressionController),
m_rationalController(editExpressionController),
m_trigonometryController(editExpressionController),
m_unitController(editExpressionController),
m_matrixController(editExpressionController)
m_unitController(editExpressionController)
{
for (int i = 0; i < k_maxNumberOfDisplayedRows; i++) {
m_calculationHistory[i].setParentResponder(&m_selectableTableView);
@@ -111,8 +110,6 @@ bool HistoryController::handleEvent(Ion::Events::Event event) {
vc = &m_rationalController;
} else if (additionalInfoType == Calculation::AdditionalInformationType::Unit) {
vc = &m_unitController;
} else if (additionalInfoType == Calculation::AdditionalInformationType::Matrix) {
vc = &m_matrixController;
}
if (vc) {
vc->setExpression(e);

View File

@@ -10,7 +10,6 @@
#include "additional_outputs/rational_list_controller.h"
#include "additional_outputs/trigonometry_list_controller.h"
#include "additional_outputs/unit_list_controller.h"
#include "additional_outputs/matrix_list_controller.h"
namespace Calculation {
@@ -49,7 +48,6 @@ private:
RationalListController m_rationalController;
TrigonometryListController m_trigonometryController;
UnitListController m_unitController;
MatrixListController m_matrixController;
};
}

View File

@@ -299,7 +299,6 @@ void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded, b
m_calculationDisplayOutput = calculation->displayOutput(context);
// We must set which subviews are displayed before setLayouts to mark the right rectangle as dirty
m_scrollableOutputView.setDisplayableCenter(m_calculationDisplayOutput == Calculation::DisplayOutput::ExactAndApproximate || m_calculationDisplayOutput == Calculation::DisplayOutput::ExactAndApproximateToggle);
m_scrollableOutputView.setDisplayCenter(m_calculationDisplayOutput == Calculation::DisplayOutput::ExactAndApproximate || m_calculationExpanded);
m_scrollableOutputView.setLayouts(Poincare::Layout(), exactOutputLayout, approximateOutputLayout);
I18n::Message equalMessage = calculation->exactAndApproximateDisplayedOutputsAreEqual(context) == Calculation::EqualSign::Equal ? I18n::Message::Equal : I18n::Message::AlmostEqual;

View File

@@ -5,17 +5,9 @@
#include <assert.h>
#include "../calculation_store.h"
typedef ::Calculation::Calculation::DisplayOutput DisplayOutput;
typedef ::Calculation::Calculation::EqualSign EqualSign ;
typedef ::Calculation::Calculation::NumberOfSignificantDigits NumberOfSignificantDigits;
using namespace Poincare;
using namespace Calculation;
static constexpr int calculationBufferSize = 10 * (sizeof(::Calculation::Calculation) + ::Calculation::Calculation::k_numberOfExpressions * ::Constant::MaxSerializedExpressionSize + sizeof(::Calculation::Calculation *));
char calculationBuffer[calculationBufferSize];
void assert_store_is(CalculationStore * store, const char * * result) {
for (int i = 0; i < store->numberOfCalculations(); i++) {
quiz_assert(strcmp(store->calculationAtIndex(i)->inputText(), result[i]) == 0);
@@ -26,7 +18,7 @@ KDCoordinate dummyHeight(::Calculation::Calculation * c, bool expanded) { return
QUIZ_CASE(calculation_store) {
Shared::GlobalContext globalContext;
CalculationStore store(calculationBuffer,calculationBufferSize);
CalculationStore store;
// Store is now {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
const char * result[] = {"9", "8", "7", "6", "5", "4", "3", "2", "1", "0"};
for (int i = 0; i < 10; i++) {
@@ -37,117 +29,101 @@ QUIZ_CASE(calculation_store) {
assert_store_is(&store, result);
for (int i = 9; i > 0; i = i-2) {
store.deleteCalculationAtIndex(i);
store.deleteCalculationAtIndex(i);
}
// Store is now {9, 7, 5, 3, 1}
const char * result2[] = {"9", "7", "5", "3", "1"};
assert_store_is(&store, result2);
store.deleteAll();
// Checking if the store handles correctly the delete of the oldest calculation when full
static int minSize = ::Calculation::Calculation::MinimalSize();
char text[2] = {'0', 0};
while (store.remainingBufferSize() > minSize) {
store.push(text, &globalContext, dummyHeight);
}
int numberOfCalculations1 = store.numberOfCalculations();
/* The buffer is now to full to push a new calculation.
* Trying to push a new one should delete the oldest one*/
store.push(text, &globalContext, dummyHeight);
int numberOfCalculations2 = store.numberOfCalculations();
// The numberOfCalculations should be the same
quiz_assert(numberOfCalculations1 == numberOfCalculations2);
store.deleteAll();
quiz_assert(store.remainingBufferSize() == store.bufferSize());
}
QUIZ_CASE(calculation_ans) {
Shared::GlobalContext globalContext;
CalculationStore store(calculationBuffer,calculationBufferSize);
CalculationStore store;
store.push("1+3/4", &globalContext, dummyHeight);
store.push("ans+2/3", &globalContext, dummyHeight);
Shared::ExpiringPointer<::Calculation::Calculation> lastCalculation = store.calculationAtIndex(0);
quiz_assert(lastCalculation->displayOutput(&globalContext) == DisplayOutput::ExactAndApproximate);
quiz_assert(lastCalculation->displayOutput(&globalContext) == ::Calculation::Calculation::DisplayOutput::ExactAndApproximate);
quiz_assert(strcmp(lastCalculation->exactOutputText(),"29/12") == 0);
store.push("ans+0.22", &globalContext, dummyHeight);
lastCalculation = store.calculationAtIndex(0);
quiz_assert(lastCalculation->displayOutput(&globalContext) == DisplayOutput::ExactAndApproximateToggle);
quiz_assert(strcmp(lastCalculation->approximateOutputText(NumberOfSignificantDigits::Maximal),"2.6366666666667") == 0);
quiz_assert(lastCalculation->displayOutput(&globalContext) == ::Calculation::Calculation::DisplayOutput::ExactAndApproximateToggle);
quiz_assert(strcmp(lastCalculation->approximateOutputText(::Calculation::Calculation::NumberOfSignificantDigits::Maximal),"2.6366666666667") == 0);
store.deleteAll();
}
void assertCalculationIs(const char * input, DisplayOutput display, EqualSign sign, const char * exactOutput, const char * displayedApproximateOutput, const char * storedApproximateOutput, Context * context, CalculationStore * store) {
void assertCalculationIs(const char * input, ::Calculation::Calculation::DisplayOutput display, ::Calculation::Calculation::EqualSign sign, const char * exactOutput, const char * displayedApproximateOutput, const char * storedApproximateOutput, Context * context, CalculationStore * store) {
store->push(input, context, dummyHeight);
Shared::ExpiringPointer<::Calculation::Calculation> lastCalculation = store->calculationAtIndex(0);
quiz_assert(lastCalculation->displayOutput(context) == display);
if (sign != EqualSign::Unknown) {
if (sign != ::Calculation::Calculation::EqualSign::Unknown) {
quiz_assert(lastCalculation->exactAndApproximateDisplayedOutputsAreEqual(context) == sign);
}
if (exactOutput) {
quiz_assert_print_if_failure(strcmp(lastCalculation->exactOutputText(), exactOutput) == 0, input);
}
if (displayedApproximateOutput) {
quiz_assert_print_if_failure(strcmp(lastCalculation->approximateOutputText(NumberOfSignificantDigits::UserDefined), displayedApproximateOutput) == 0, input);
quiz_assert_print_if_failure(strcmp(lastCalculation->approximateOutputText(::Calculation::Calculation::NumberOfSignificantDigits::UserDefined), displayedApproximateOutput) == 0, input);
}
if (storedApproximateOutput) {
quiz_assert_print_if_failure(strcmp(lastCalculation->approximateOutputText(NumberOfSignificantDigits::Maximal), storedApproximateOutput) == 0, input);
quiz_assert_print_if_failure(strcmp(lastCalculation->approximateOutputText(::Calculation::Calculation::NumberOfSignificantDigits::Maximal), storedApproximateOutput) == 0, input);
}
store->deleteAll();
}
QUIZ_CASE(calculation_significant_digits) {
Shared::GlobalContext globalContext;
CalculationStore store(calculationBuffer,calculationBufferSize);
CalculationStore store;
assertCalculationIs("123456789", DisplayOutput::ExactAndApproximate, EqualSign::Approximation, "123456789", "1.234568ᴇ8", "123456789", &globalContext, &store);
assertCalculationIs("1234567", DisplayOutput::ApproximateOnly, EqualSign::Equal, "1234567", "1234567", "1234567", &globalContext, &store);
assertCalculationIs("123456789", ::Calculation::Calculation::DisplayOutput::ExactAndApproximate, ::Calculation::Calculation::EqualSign::Approximation, "123456789", "1.234568ᴇ8", "123456789", &globalContext, &store);
assertCalculationIs("1234567", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Equal, "1234567", "1234567", "1234567", &globalContext, &store);
}
QUIZ_CASE(calculation_display_exact_approximate) {
Shared::GlobalContext globalContext;
CalculationStore store(calculationBuffer,calculationBufferSize);
CalculationStore store;
assertCalculationIs("1/2", DisplayOutput::ExactAndApproximate, EqualSign::Equal, nullptr, nullptr, nullptr, &globalContext, &store);
assertCalculationIs("1/3", DisplayOutput::ExactAndApproximate, EqualSign::Approximation, nullptr, nullptr, nullptr, &globalContext, &store);
assertCalculationIs("1/0", DisplayOutput::ExactOnly, EqualSign::Unknown, "undef", "undef", "undef", &globalContext, &store);
assertCalculationIs("2x-x", DisplayOutput::ExactOnly, EqualSign::Unknown, "x", "undef", "undef", &globalContext, &store);
assertCalculationIs("[[1,2,3]]", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, nullptr, nullptr, &globalContext, &store);
assertCalculationIs("[[1,x,3]]", DisplayOutput::ExactAndApproximate, EqualSign::Unknown, nullptr, "[[1,undef,3]]", "[[1,undef,3]]", &globalContext, &store);
assertCalculationIs("28^7", DisplayOutput::ExactAndApproximate, EqualSign::Unknown, nullptr, nullptr, nullptr, &globalContext, &store);
assertCalculationIs("3+√(2)→a", DisplayOutput::ExactAndApproximate, EqualSign::Approximation, "√(2)+3", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("1/2", ::Calculation::Calculation::DisplayOutput::ExactAndApproximate, ::Calculation::Calculation::EqualSign::Equal, nullptr, nullptr, nullptr, &globalContext, &store);
assertCalculationIs("1/3", ::Calculation::Calculation::DisplayOutput::ExactAndApproximate, ::Calculation::Calculation::EqualSign::Approximation, nullptr, nullptr, nullptr, &globalContext, &store);
assertCalculationIs("1/0", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, "undef", "undef", "undef", &globalContext, &store);
assertCalculationIs("2x-x", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, "undef", "undef", "undef", &globalContext, &store);
assertCalculationIs("[[1,2,3]]", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, nullptr, nullptr, &globalContext, &store);
assertCalculationIs("[[1,x,3]]", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "undef", "undef", &globalContext, &store);
assertCalculationIs("28^7", ::Calculation::Calculation::DisplayOutput::ExactAndApproximate, ::Calculation::Calculation::EqualSign::Unknown, nullptr, nullptr, nullptr, &globalContext, &store);
assertCalculationIs("3+√(2)→a", ::Calculation::Calculation::DisplayOutput::ExactAndApproximate, ::Calculation::Calculation::EqualSign::Approximation, "√(2)+3", nullptr, nullptr, &globalContext, &store);
Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy();
assertCalculationIs("3+2→a", DisplayOutput::ApproximateOnly, EqualSign::Equal, "5", "5", "5", &globalContext, &store);
assertCalculationIs("3+2→a", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Equal, "5", "5", "5", &globalContext, &store);
Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy();
assertCalculationIs("3→a", DisplayOutput::ApproximateOnly, EqualSign::Equal, "3", "3", "3", &globalContext, &store);
assertCalculationIs("3→a", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Equal, "3", "3", "3", &globalContext, &store);
Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy();
assertCalculationIs("3+x→f(x)", DisplayOutput::ExactOnly, EqualSign::Unknown, "x+3", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("3+x→f(x)", ::Calculation::Calculation::DisplayOutput::ExactOnly, ::Calculation::Calculation::EqualSign::Unknown, "x+3", nullptr, nullptr, &globalContext, &store);
Ion::Storage::sharedStorage()->recordNamed("f.func").destroy();
assertCalculationIs("1+1+random()", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, nullptr, nullptr, &globalContext, &store);
assertCalculationIs("1+1+round(1.343,2)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, "3.34", "3.34", &globalContext, &store);
assertCalculationIs("randint(2,2)+3", DisplayOutput::ApproximateOnly, EqualSign::Unknown, "5", "5", "5", &globalContext, &store);
assertCalculationIs("confidence(0.5,2)+3", DisplayOutput::ExactOnly, EqualSign::Unknown, nullptr, nullptr, nullptr, &globalContext, &store);
assertCalculationIs("prediction(0.5,2)+3", DisplayOutput::ExactOnly, EqualSign::Unknown, nullptr, nullptr, nullptr, &globalContext, &store);
assertCalculationIs("prediction95(0.5,2)+3", DisplayOutput::ExactOnly, EqualSign::Unknown, nullptr, nullptr, nullptr, &globalContext, &store);
assertCalculationIs("1+1+random()", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, nullptr, nullptr, &globalContext, &store);
assertCalculationIs("1+1+round(1.343,2)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "3.34", "3.34", &globalContext, &store);
assertCalculationIs("randint(2,2)+3", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, "5", "5", "5", &globalContext, &store);
assertCalculationIs("confidence(0.5,2)+3", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, nullptr, nullptr, &globalContext, &store);
assertCalculationIs("prediction(0.5,2)+3", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, nullptr, nullptr, &globalContext, &store);
assertCalculationIs("prediction95(0.5,2)+3", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, nullptr, nullptr, &globalContext, &store);
}
QUIZ_CASE(calculation_symbolic_computation) {
Shared::GlobalContext globalContext;
CalculationStore store(calculationBuffer,calculationBufferSize);
CalculationStore store;
assertCalculationIs("x+x+1+3+√(π)", DisplayOutput::ExactOnly, EqualSign::Unknown, "2×x+√(π)+4", "undef", "undef", &globalContext, &store);
assertCalculationIs("f(x)", DisplayOutput::ExactOnly, EqualSign::Unknown, "f×x", "undef", "undef", &globalContext, &store);
assertCalculationIs("1+x→f(x)", DisplayOutput::ExactOnly, EqualSign::Unknown, "x+1", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("f(x)", DisplayOutput::ExactOnly, EqualSign::Unknown, "x+1", "undef", "undef", &globalContext, &store);
assertCalculationIs("f(2)", DisplayOutput::ApproximateOnly, EqualSign::Equal, "3", "3", "3", &globalContext, &store);
assertCalculationIs("2→x", DisplayOutput::ApproximateOnly, EqualSign::Equal, "2", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("f(x)", DisplayOutput::ApproximateOnly, EqualSign::Equal, "3", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("x+x+1+3+√(π)", DisplayOutput::ExactAndApproximate, EqualSign::Approximation, "√(π)+8", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("x+x+1+3+√(π)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, "undef", "undef", "undef", &globalContext, &store);
assertCalculationIs("f(x)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, "undef", "undef", "undef", &globalContext, &store);
assertCalculationIs("1+x→f(x)", ::Calculation::Calculation::DisplayOutput::ExactOnly, ::Calculation::Calculation::EqualSign::Unknown, "x+1", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("f(x)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, "undef", "undef", "undef", &globalContext, &store);
assertCalculationIs("f(2)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Equal, "3", "3", "3", &globalContext, &store);
assertCalculationIs("2→x", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Equal, "2", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("f(x)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Equal, "3", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("x+x+1+3+√(π)", ::Calculation::Calculation::DisplayOutput::ExactAndApproximate, ::Calculation::Calculation::EqualSign::Approximation, "√(π)+8", nullptr, nullptr, &globalContext, &store);
Ion::Storage::sharedStorage()->recordNamed("f.func").destroy();
Ion::Storage::sharedStorage()->recordNamed("x.exp").destroy();
@@ -155,18 +131,18 @@ QUIZ_CASE(calculation_symbolic_computation) {
QUIZ_CASE(calculation_symbolic_computation_and_parametered_expressions) {
Shared::GlobalContext globalContext;
CalculationStore store(calculationBuffer,calculationBufferSize);
CalculationStore store;
assertCalculationIs("int((^(-x))-x^(0.5), x, 0, 3)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, nullptr, nullptr, &globalContext, &store); // Tests a bug with symbolic computation
assertCalculationIs("int(x,x,0,2)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, "2", "2", &globalContext, &store);
assertCalculationIs("sum(x,x,0,2)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, "3", "3", &globalContext, &store);
assertCalculationIs("product(x,x,1,2)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, "2", "2", &globalContext, &store);
assertCalculationIs("diff(x^2,x,3)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, "6", "6", &globalContext, &store);
assertCalculationIs("2→x", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, nullptr, nullptr, &globalContext, &store);
assertCalculationIs("int(x,x,0,2)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, "2", "2", &globalContext, &store);
assertCalculationIs("sum(x,x,0,2)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, "3", "3", &globalContext, &store);
assertCalculationIs("product(x,x,1,2)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, "2", "2", &globalContext, &store);
assertCalculationIs("diff(x^2,x,3)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, "6", "6", &globalContext, &store);
assertCalculationIs("int((^(-x))-x^(0.5), x, 0, 3)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, nullptr, nullptr, &globalContext, &store); // Tests a bug with symbolic computation
assertCalculationIs("int(x,x,0,2)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "2", "2", &globalContext, &store);
assertCalculationIs("sum(x,x,0,2)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "3", "3", &globalContext, &store);
assertCalculationIs("product(x,x,1,2)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "2", "2", &globalContext, &store);
assertCalculationIs("diff(x^2,x,3)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "6", "6", &globalContext, &store);
assertCalculationIs("2→x", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, nullptr, nullptr, &globalContext, &store);
assertCalculationIs("int(x,x,0,2)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "2", "2", &globalContext, &store);
assertCalculationIs("sum(x,x,0,2)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "3", "3", &globalContext, &store);
assertCalculationIs("product(x,x,1,2)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "2", "2", &globalContext, &store);
assertCalculationIs("diff(x^2,x,3)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "6", "6", &globalContext, &store);
Ion::Storage::sharedStorage()->recordNamed("x.exp").destroy();
}
@@ -174,34 +150,34 @@ QUIZ_CASE(calculation_symbolic_computation_and_parametered_expressions) {
QUIZ_CASE(calculation_complex_format) {
Shared::GlobalContext globalContext;
CalculationStore store(calculationBuffer,calculationBufferSize);
CalculationStore store;
Poincare::Preferences::sharedPreferences()->setComplexFormat(Poincare::Preferences::ComplexFormat::Real);
assertCalculationIs("1+𝐢", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, "1+𝐢", "1+𝐢", &globalContext, &store);
assertCalculationIs("√(-1)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, "unreal", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("ln(-2)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, "unreal", "unreal", &globalContext, &store);
assertCalculationIs("√(-1)×√(-1)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, "unreal", "unreal", &globalContext, &store);
assertCalculationIs("(-8)^(1/3)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, "-2", "-2", &globalContext, &store);
assertCalculationIs("(-8)^(2/3)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, "4", "4", &globalContext, &store);
assertCalculationIs("(-2)^(1/4)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, "unreal", "unreal", &globalContext, &store);
assertCalculationIs("1+𝐢", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "1+𝐢", "1+𝐢", &globalContext, &store);
assertCalculationIs("√(-1)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, "unreal", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("ln(-2)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "unreal", "unreal", &globalContext, &store);
assertCalculationIs("√(-1)×√(-1)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "unreal", "unreal", &globalContext, &store);
assertCalculationIs("(-8)^(1/3)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "-2", "-2", &globalContext, &store);
assertCalculationIs("(-8)^(2/3)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "4", "4", &globalContext, &store);
assertCalculationIs("(-2)^(1/4)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "unreal", "unreal", &globalContext, &store);
Poincare::Preferences::sharedPreferences()->setComplexFormat(Poincare::Preferences::ComplexFormat::Cartesian);
assertCalculationIs("1+𝐢", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, "1+𝐢", "1+𝐢", &globalContext, &store);
assertCalculationIs("√(-1)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, "𝐢", "𝐢", &globalContext, &store);
assertCalculationIs("ln(-2)", DisplayOutput::ExactAndApproximate, EqualSign::Approximation, "ln(-2)", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("√(-1)×√(-1)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, "-1", "-1", &globalContext, &store);
assertCalculationIs("(-8)^(1/3)", DisplayOutput::ExactAndApproximate, EqualSign::Approximation, "1+√(3)×𝐢", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("(-8)^(2/3)", DisplayOutput::ExactAndApproximate, EqualSign::Approximation, "-2+2×√(3)×𝐢", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("(-2)^(1/4)", DisplayOutput::ExactAndApproximate, EqualSign::Approximation, "root(8,4)/2+root(8,4)/2×𝐢", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("1+𝐢", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "1+𝐢", "1+𝐢", &globalContext, &store);
assertCalculationIs("√(-1)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "𝐢", "𝐢", &globalContext, &store);
assertCalculationIs("ln(-2)", ::Calculation::Calculation::DisplayOutput::ExactAndApproximate, ::Calculation::Calculation::EqualSign::Approximation, "ln(-2)", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("√(-1)×√(-1)", ::Calculation::Calculation::DisplayOutput::ApproximateOnly, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "-1", "-1", &globalContext, &store);
assertCalculationIs("(-8)^(1/3)", ::Calculation::Calculation::DisplayOutput::ExactAndApproximate, ::Calculation::Calculation::EqualSign::Approximation, "1+√(3)×𝐢", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("(-8)^(2/3)", ::Calculation::Calculation::DisplayOutput::ExactAndApproximate, ::Calculation::Calculation::EqualSign::Approximation, "-2+2×√(3)×𝐢", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("(-2)^(1/4)", ::Calculation::Calculation::DisplayOutput::ExactAndApproximate, ::Calculation::Calculation::EqualSign::Approximation, "root(8,4)/2+root(8,4)/2×𝐢", nullptr, nullptr, &globalContext, &store);
Poincare::Preferences::sharedPreferences()->setComplexFormat(Poincare::Preferences::ComplexFormat::Polar);
assertCalculationIs("1+𝐢", DisplayOutput::ExactAndApproximate, EqualSign::Approximation, "√(2)×^\u0012π/4×𝐢\u0013", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("√(-1)", DisplayOutput::ExactAndApproximate, EqualSign::Approximation, "^\u0012π/2×𝐢\u0013", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("ln(-2)", DisplayOutput::ExactAndApproximate, EqualSign::Approximation, "ln(-2)", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("√(-1)×√(-1)", DisplayOutput::ExactAndApproximate, EqualSign::Unknown, nullptr, "^\u00123.141593×𝐢\u0013", "^\u00123.1415926535898×𝐢\u0013", &globalContext, &store);
assertCalculationIs("(-8)^(1/3)", DisplayOutput::ExactAndApproximate, EqualSign::Approximation, "2×^\u0012π/3×𝐢\u0013", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("(-8)^(2/3)", DisplayOutput::ExactAndApproximate, EqualSign::Approximation, "4×^\u0012\u00122×π\u0013/3×𝐢\u0013", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("(-2)^(1/4)", DisplayOutput::ExactAndApproximate, EqualSign::Approximation, "root(2,4)×^\u0012π/4×𝐢\u0013", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("1+𝐢", ::Calculation::Calculation::DisplayOutput::ExactAndApproximate, ::Calculation::Calculation::EqualSign::Approximation, "√(2)×^\u0012π/4×𝐢\u0013", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("√(-1)", ::Calculation::Calculation::DisplayOutput::ExactAndApproximate, ::Calculation::Calculation::EqualSign::Approximation, "^\u0012π/2×𝐢\u0013", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("ln(-2)", ::Calculation::Calculation::DisplayOutput::ExactAndApproximate, ::Calculation::Calculation::EqualSign::Approximation, "ln(-2)", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("√(-1)×√(-1)", ::Calculation::Calculation::DisplayOutput::ExactAndApproximate, ::Calculation::Calculation::EqualSign::Unknown, nullptr, "^\u00123.141593×𝐢\u0013", "^\u00123.1415926535898×𝐢\u0013", &globalContext, &store);
assertCalculationIs("(-8)^(1/3)", ::Calculation::Calculation::DisplayOutput::ExactAndApproximate, ::Calculation::Calculation::EqualSign::Approximation, "2×^\u0012π/3×𝐢\u0013", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("(-8)^(2/3)", ::Calculation::Calculation::DisplayOutput::ExactAndApproximate, ::Calculation::Calculation::EqualSign::Approximation, "4×^\u0012\u00122×π\u0013/3×𝐢\u0013", nullptr, nullptr, &globalContext, &store);
assertCalculationIs("(-2)^(1/4)", ::Calculation::Calculation::DisplayOutput::ExactAndApproximate, ::Calculation::Calculation::EqualSign::Approximation, "root(2,4)×^\u0012π/4×𝐢\u0013", nullptr, nullptr, &globalContext, &store);
Poincare::Preferences::sharedPreferences()->setComplexFormat(Poincare::Preferences::ComplexFormat::Cartesian);
}

View File

@@ -1,12 +0,0 @@
#include "clock_timer.h"
#include "apps_container.h"
ClockTimer::ClockTimer(AppsContainer * container) :
Timer(1),
m_container(container)
{
}
bool ClockTimer::fire() {
return m_container->updateClock();
}

View File

@@ -1,16 +0,0 @@
#ifndef APPS_CLOCK_TIMER_H
#define APPS_CLOCK_TIMER_H
#include <escher.h>
class AppsContainer;
class ClockTimer : public Timer {
public:
ClockTimer(AppsContainer * container);
private:
bool fire() override;
AppsContainer * m_container;
};
#endif

View File

@@ -15,7 +15,6 @@ app_code_src = $(addprefix apps/code/,\
sandbox_controller.cpp \
script_name_cell.cpp \
script_parameter_controller.cpp \
toolbox_ion_keys.cpp \
)
app_code_test_src = $(addprefix apps/code/,\
@@ -30,7 +29,6 @@ app_code_test_src = $(addprefix apps/code/,\
tests_src += $(addprefix apps/code/test/,\
variable_box_controller.cpp\
toolbox_ion_keys_dummy.cpp \
)
app_code_src += $(app_code_test_src)

View File

@@ -89,18 +89,16 @@ App::App(Snapshot * snapshot) :
, snapshot->lockOnConsole()
#endif
),
m_listFooter(&m_codeStackViewController, &m_menuController, &m_menuController, ButtonRowController::Position::Bottom, ButtonRowController::Style::EmbossedGray, ButtonRowController::Size::Large),
m_listFooter(&m_codeStackViewController, &m_menuController, &m_menuController, ButtonRowController::Position::Bottom, ButtonRowController::Style::EmbossedGrey, ButtonRowController::Size::Large),
m_menuController(&m_listFooter, this, snapshot->scriptStore(), &m_listFooter),
m_codeStackViewController(&m_modalViewController, &m_listFooter),
m_variableBoxController(snapshot->scriptStore())
{
Clipboard::sharedClipboard()->enterPython();
}
App::~App() {
assert(!m_consoleController.inputRunLoopActive());
deinitPython();
Clipboard::sharedClipboard()->exitPython();
}
bool App::handleEvent(Ion::Events::Event event) {

View File

@@ -9,7 +9,6 @@
#include "script_store.h"
#include "python_toolbox.h"
#include "variable_box_controller.h"
#include "../shared/shared_app.h"
namespace Code {
@@ -22,7 +21,7 @@ public:
App::Descriptor::ExaminationLevel examinationLevel() override;
const Image * icon() override;
};
class Snapshot : public SharedApp::Snapshot {
class Snapshot : public ::App::Snapshot {
public:
Snapshot();
App * unpack(Container * container) override;
@@ -75,7 +74,7 @@ public:
VariableBoxController * variableBoxController() { return &m_variableBoxController; }
static constexpr int k_pythonHeapSize = 100000;
static constexpr int k_pythonHeapSize = 32768;
private:
/* Python delegate:

View File

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

View File

@@ -12,4 +12,4 @@ ImportedModulesAndScripts = "Módulos y archivos importados"
NoWordAvailableHere = "No hay ninguna palabra disponible aquí."
ScriptInProgress = "Archivo en curso"
ScriptOptions = "Opciones del archivo"
ScriptSize = "Tamaño del script"
ScriptSize = "Script size"

View File

@@ -12,4 +12,4 @@ ImportedModulesAndScripts = "Modules et scripts importés"
NoWordAvailableHere = "Aucun mot disponible à cet endroit."
ScriptInProgress = "Script en cours"
ScriptOptions = "Options de script"
ScriptSize = "Taille du script"
ScriptSize = "Script size"

View File

@@ -1,15 +1,15 @@
AddScript = "Script hozzáadása"
AddScript = "Script hozzadáadása"
AllowedCharactersaz09 = "Engedélyezett karakterek: a-z, 0-9, _"
Autocomplete = "Önkiegészítés"
Autocomplete = "Autocomplete"
AutoImportScript = "Script automata importálása"
BuiltinsAndKeywords = "Beépített fonkciók és szókincs"
BuiltinsAndKeywords = "Builtins and keywords"
Console = "Konzol"
DeleteScript = "Script törlése"
DuplicateScript = "Script másolása"
ExecuteScript = "Script indítása"
FunctionsAndVariables = "Fonktiók és változók"
ImportedModulesAndScripts = "Importált scriptek és modulok"
NoWordAvailableHere = "Nincs rendelkezésre álló szó."
ScriptInProgress = "Script müködésben"
FunctionsAndVariables = "Függvények és változók"
ImportedModulesAndScripts = "Imported modules and scripts"
NoWordAvailableHere = "No word available here."
ScriptInProgress = "Script in progress"
ScriptOptions = "Script beállítások"
ScriptSize = "Script mérete"
ScriptSize = "Script size"

View File

@@ -3,176 +3,220 @@ PythonPercent = "Modulo"
Python1J = "Imaginäres i"
PythonLF = "Zeilenvorschub"
PythonTab = "Tabulator"
PythonAmpersand = "Bitweises und"
PythonSymbolExp = "Bitweises exklusives oder"
PythonVerticalBar = "Bitweises oder"
PythonAmpersand = "Bitweise und"
PythonSymbolExp = "Bitweise exklusiv oder"
PythonVerticalBar = "Bitweise oder"
PythonImag = "Imaginärteil von z"
PythonReal = "Realteil von z"
PythonSingleQuote = "Einfaches Anführungszeichen"
PythonAbs = "Absoluter Wert/Absolute Größe"
PythonAcos = "Bogenkosinus"
PythonAcosh = "Bogenhyperbolischer Kosinus"
PythonAppend = "x an das Ende der Liste anfügen"
PythonArrow = "Pfeil von (x,y) nach (x+dx,y+dy)"
PythonAsin = "Sinusbogen"
PythonAsinh = "Kreisbogen hyperbolischer Sinus"
PythonAbs = "Absolute/r Wert/Größe"
PythonAcos = "Arkuskosinus"
PythonAcosh = "Hyperbelkosinus"
PythonAppend = "Hängt x an das Ende der Liste"
PythonArrow = "Arrow from (x,y) to (x+dx,y+dy)"
PythonAsin = "Arkussinus"
PythonAsinh = "Hyperbelsinus"
PythonAtan = "Arkustangens"
PythonAtan2 = "Rückgabe atan(y/x)"
PythonAtan2 = "Gib atan(y/x)"
PythonAtanh = "Hyperbeltangens"
PythonAxis = "Achsen auf (xmin,xmax,ymin,ymax)"
PythonBar = "Balkendiagramm mit x-Werten"
PythonBin = "Ganzzahl in Binärwert umwandeln"
PythonCeil = "Aufrunden"
PythonChoice = "Zufällige Zahl in der Liste"
PythonClear = "Liste leeren"
PythonAxis = "Set axes to (xmin,xmax,ymin,ymax)"
PythonBar = "Draw a bar plot with x values"
PythonBin = "Ganzzahl nach binär konvertieren"
PythonCeil = "Aufrundung"
PythonChoice = "Zufallszahl aus der Liste"
PythonClear = "Leere die Liste"
PythonCmathFunction = "cmath-Modul-Funktionspräfix"
PythonColor = "Eine RGB-Farbe definieren"
PythonColorBlack = "Farbe Schwarz"
PythonColorBlue = "Farbe Blau"
PythonColorBrown = "Farbe Braun"
PythonColorGray = "Farbe Grau"
PythonColorGreen = "Farbe Grün"
PythonColorOrange = "Farbe Orange"
PythonColorPink = "Farbe Rosa"
PythonColorPurple = "Farbe Violett"
PythonColorRed = "Farbe Rot"
PythonColorWhite = "Farbe Weiß"
PythonColorYellow = "Farbe Gelb"
PythonComplex = "Gib a+ib zurück"
PythonCopySign = "Gib x mit Vorzeichen von y zurück"
PythonColor = "Definiere eine RGB-Farbe"
PythonColorBlack = "Black color"
PythonColorBlue = "Blue color"
PythonColorBrown = "Brown color"
PythonColorGreen = "Green color"
PythonColorGrey = "Grey color"
PythonColorOrange = "Orange color"
PythonColorPink = "Pink color"
PythonColorPurple = "Purple color"
PythonColorRed = "Red color"
PythonColorWhite = "White color"
PythonColorYellow = "Yellow color"
PythonComplex = "a+ib zurückgeben"
PythonCopySign = "x mit dem Vorzeichen von y"
PythonCos = "Kosinus"
PythonCosh = "Hyperbolischer Kosinus"
PythonCount = "Zählt die Vorkommen von x"
PythonDegrees = "x von Bogenmaß in Grad umrechnen"
PythonCosh = "Hyperbolic cosine"
PythonCount = "Zählt wie oft x vorkommt"
PythonDegrees = "x von Radian zu Grad umwandeln"
PythonDivMod = "Quotient und Rest"
PythonDrawLine = "Eine Linie zeichnen"
PythonDrawString = "Text bei Pixel (x,y) darstellen"
PythonDrawString = "Schreibt Text bei (x,y)"
PythonErf = "Fehlerfunktion"
PythonErfc = "Komplementäre Fehlerfunktion"
PythonEval = "Rückgabe ausgewerteter Ausdruck"
PythonErfc = "Complementary error function"
PythonEval = "Return the evaluated expression"
PythonExp = "Exponentialfunktion"
PythonExpm1 = "Berechne exp(x)-1"
PythonFabs = "Absoluter Wert"
PythonFillRect = "Gefülltes Rechteck bei Pixel (x,y)"
PythonFloat = "x in einen Fließkommawert umwandeln"
PythonFloor = "Abrunden"
PythonFillRect = "Malt ein Rechteck bei Pixel (x,y)"
PythonFloat = "Wandelt x zu float um"
PythonFloor = "Floor"
PythonFmod = "a modulo b"
PythonFrExp = "Mantisse und Exponent von x: (m,e)"
PythonGamma = "Gamma-Funktion"
PythonGetPixel = "Farbe von Pixel (x,y) zurückgeben"
PythonGetrandbits = "Ganzzahl mit k Zufallsbits"
PythonGrid = "Sichtbarkeit des Gitters umschalten"
PythonHex = "Ganzzahl in Hexadezimal umwandeln"
PythonHist = "Zeichnet das Histogramm von x"
PythonImportCmath = "cmath-Modul importieren"
PythonImportIon = "Ion-Modul importieren"
PythonImportKandinsky = "Kandinsky-Modul importieren"
PythonImportRandom = "Random-Modul importieren"
PythonImportMath = "Math-Modul importieren"
PythonImportMatplotlibPyplot = "Matplotlib.pyplot-Modul importieren"
PythonImportOs = "OS-Modul importieren"
PythonOsUname = "Informationen über das System holen"
PythonOsGetlogin = "Benutzernamen holen"
PythonFrExp = "Mantissa and exponent of x: (m,e)"
PythonGamma = "Gamma function"
PythonGetPixel = "Return pixel (x,y) color"
PythonGetrandbits = "Integer with k random bits"
PythonGrid = "Toggle the visibility of the grid"
PythonHex = "Ganzzahl zu Hexadecimal"
PythonHist = "Draw the histogram of x"
PythonImportCmath = "cmath Modul importieren"
PythonImportIon = "ion Modul importieren"
PythonImportKandinsky = "kandinsky Modul importieren"
PythonImportRandom = "random Modul importieren"
PythonImportMath = "math Modul importieren"
PythonImportMatplotlibPyplot = "Import matplotlib.pyplot module"
PythonImportOs = "os Modul importieren"
PythonOsUname = "Informieren Sie sich über das System"
PythonOsRemove = "Datei namens Dateiname entfernen"
PythonOsRename = "Datei umbenennen von Alt nach Neu"
PythonOsRename = "Datei mit altem Namen in neuen Namen umbenennen"
PythonOsListdir = "Dateien im Speicher auflisten"
PythonImportTime = "Time-Modul importieren"
PythonImportTurtle = "Turtle-Modul importieren"
PythonIndex = "Index des ersten x-Vorkommens"
PythonInput = "Einen Wert abfragen"
PythonInsert = "x an Index i in die Liste einfügen"
PythonInt = "x in eine ganze Zahl umwandeln"
PythonIonFunction = "Ion-Modul-Funktionspräfix"
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"
PythonKandinskyFunction = "Kandinsky-Modul Funktionspräfix"
PythonLdexp = "Liefert x*(2**i), Inverse von frexp"
PythonLength = "Länge eines Objekts"
PythonLgamma = "Log-Gamma-Funktion"
PythonLog = "Logarithmus zur Basis a"
PythonLog10 = "Logarithmus zur Basis 10"
PythonLog2 = "Logarithmus zur Basis 2"
PythonMathFunction = "Funktionspräfix des Math-Moduls"
PythonMatplotlibPyplotFunction = "matplotlib.pyplot Modul-Präfix"
PythonImportTime = "time Modul importieren"
PythonImportTurtle = "turtle Modul importieren"
PythonIndex = "Index, bei dem x zuerst vorkommt"
PythonInput = "Eingabeaufforderung"
PythonInsert = "x bei index i in der Liste einsetzen"
PythonInt = "x zu Ganzzahl"
PythonIonFunction = "ion module function prefix"
PythonIsFinite = "Prüft ob x endlich ist"
PythonIsInfinite = "Prüft ob x unendlich ist"
PythonIsNaN = "Prüft ob x NaN ist"
PythonIsKeyDown = "true wenn k gedrückt ist"
PythonKandinskyFunction = "kandinsky module function prefix"
PythonKeyLeft = "Linke Pfeiltaste"
PythonKeyUp = "Pfeiltaste nach oben"
PythonKeyDown = "Pfeiltaste nach unten"
PythonKeyRight = "Rechte Pfeiltaste"
PythonKeyOk = "OK Taste"
PythonKeyBack = "ZURÜCK Taste"
PythonKeyHome = "HOME Taste"
PythonKeyOnOff = "AN/AUS Taste"
PythonKeyShift = "SHIFT Taste"
PythonKeyAlpha = "ALPHA Taste"
PythonKeyXnt = "X,N,T Taste"
PythonKeyVar = "VAR Taste"
PythonKeyToolbox = "WERKZEUGBOX Taste"
PythonKeyBackspace = "LÖSCHEN Taste"
PythonKeyExp = "EXPONENTIAL Taste"
PythonKeyLn = "NATURAL LOGARITHM Taste"
PythonKeyLog = "DECIMAL LOGARITHM Taste"
PythonKeyImaginary = "IMAGINÄRES I Taste"
PythonKeyComma = "KOMMA Taste"
PythonKeyPower = "HOCH Taste"
PythonKeySine = "SINUS Taste"
PythonKeyCosine = "COSINUS Taste"
PythonKeyTangent = "TANGENZ Taste"
PythonKeyPi = "PI Taste"
PythonKeySqrt = "WURZEL Taste"
PythonKeySquare = "QUADRAT Taste"
PythonKeySeven = "7 Taste"
PythonKeyEight = "8 Taste"
PythonKeyNine = "9 Taste"
PythonKeyLeftParenthesis = "LEFT PARENTHESIS key"
PythonKeyRightParenthesis = "RIGHT PARENTHESIS key"
PythonKeyFour = "4 Taste"
PythonKeyFive = "5 Taste"
PythonKeySix = "6 Taste"
PythonKeyMultiplication = "MULTIPLIKATIONSTASTE"
PythonKeyDivision = "DIVISIONSTASTE"
PythonKeyOne = "1 Taste"
PythonKeyTwo = "2 Taste"
PythonKeyThree = "3 Taste"
PythonKeyPlus = "PLUS Taste"
PythonKeyMinus = "MINUS Taste"
PythonKeyZero = "0 Taste"
PythonKeyDot = "PUNKT Taste"
PythonKeyEe = "10 HOCH X Taste"
PythonKeyAns = "ANS Taste"
PythonKeyExe = "EXE Taste"
PythonLdexp = "Return x*(2**i), inverse of frexp"
PythonLength = "Length of an object"
PythonLgamma = "Log-gamma function"
PythonLog = "Logarithm to base a"
PythonLog10 = "Logarithm to base 10"
PythonLog2 = "Logarithm to base 2"
PythonMathFunction = "math module function prefix"
PythonMatplotlibPyplotFunction = "matplotlib.pyplot module prefix"
PythonMax = "Maximum"
PythonMin = "Minimum"
PythonModf = "Bruch- und Ganzzahl-Anteile von x"
PythonMonotonic = "Wert einer monotonen Uhr"
PythonOct = "Ganzzahl in Oktal umwandeln"
PythonPhase = "Phase von z"
PythonPlot = "Plotten von y gegen x als Linien"
PythonPolar = "z in Polarkoordinaten"
PythonPop = "Letztes Element abnehmen"
PythonPower = "x erhöht mit der Potenz y"
PythonPrint = "Objekt drucken"
PythonRadians = "x von Grad in Bogenmaß umrechnen"
PythonRandint = "Zufällige Ganzzahl in [a,b]"
PythonRandom = "Fließkommazahl in [0,1]"
PythonRandomFunction = "Random-Modul Funktionspräfix"
PythonRandrange = "Zufallszahl im Bereich(start,stop)"
PythonRangeStartStop = "Liste von Start bis Stop-1"
PythonRangeStop = "Liste von 0 bis Stop-1"
PythonRect = "In kartesische Koordinaten"
PythonRemove = "Entferne das erste Vorkommen von x"
PythonReverse = "Kehrt die Elemente der Liste um"
PythonRound = "Runden auf n Stellen"
PythonScatter = "Streudiagramm von y gg. x zeichnen"
PythonSeed = "Zufallszahlengenerator initiieren"
PythonSetPixel = "Pixel (x,y) einfärben"
PythonShow = "Figur anzeigen"
PythonSin = "Sinus"
PythonSinh = "Hyperbolischer Sinus"
PythonSleep = "Ausführung aussetzen für t Sekunden"
PythonSort = "Die Liste sortieren"
PythonSqrt = "Quadratwurzel"
PythonSum = "Summe der Elemente einer Liste"
PythonModf = "Fractional and integer parts of x"
PythonMonotonic = "Value of a monotonic clock"
PythonOct = "Convert integer to octal"
PythonPhase = "Phase of z"
PythonPlot = "Plot y versus x as lines"
PythonPolar = "z in polar coordinates"
PythonPop = "Remove and return the last item"
PythonPower = "x raised to the power y"
PythonPrint = "Print object"
PythonRadians = "Convert x from degrees to radians"
PythonRandint = "Random integer in [a,b]"
PythonRandom = "Floating point number in [0,1["
PythonRandomFunction = "random module function prefix"
PythonRandrange = "Random number in range(start,stop)"
PythonRangeStartStop = "List from start to stop-1"
PythonRangeStop = "List from 0 to stop-1"
PythonRect = "Convert to cartesian coordinates"
PythonRemove = "Remove the first occurrence of x"
PythonReverse = "Reverse the elements of the list"
PythonRound = "Round to n digits"
PythonScatter = "Draw a scatter plot of y versus x"
PythonSeed = "Initialize random number generator"
PythonSetPixel = "Color pixel (x,y)"
PythonShow = "Display the figure"
PythonSin = "Sine"
PythonSinh = "Hyperbolic sine"
PythonSleep = "Suspend the execution for t seconds"
PythonSort = "Sort the list"
PythonSqrt = "Wurzel"
PythonSum = "Sum the items of a list"
PythonTan = "Tangens"
PythonTanh = "Hyperbolischer Tangens"
PythonText = "Text an (x,y) Koordinaten anzeigen"
PythonTimeFunction = "Time-Modul-Funktionspräfix"
PythonTrunc = "x abgeschnitten auf eine ganze Zahl"
PythonTurtleBackward = "Um x Pixel rückwärts bewegen"
PythonTurtleCircle = "Kreis mit Radius r Pixel"
PythonTurtleColor = "Setzt die Stiftfarbe"
PythonTurtleColorMode = "Setzt Farbmodus auf 1.0 oder 255"
PythonTurtleForward = "Um x Pixel vorwärts bewegen"
PythonTurtleFunction = "Turtle-Modul-Funktionspräfix"
PythonTurtleGoto = "Bewegen zu (x,y) Koordinaten"
PythonTurtleHeading = "Liefert den aktuellen Kurs"
PythonTurtleHideturtle = "Versteckt den Igel"
PythonTurtleIsdown = "Wahr, wenn der Stift unten ist"
PythonTurtleLeft = "Nach links um ein Grad drehen"
PythonTurtlePendown = "Den Stift nach unten ziehen"
PythonTurtlePensize = "Linienstärke auf x Pixel setzen"
PythonTurtlePenup = "Den Stift nach oben ziehen"
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"
PythonTanh = "Hyperbolic tangent"
PythonText = "Display a text at (x,y) coordinates"
PythonTimeFunction = "time module function prefix"
PythonTrunc = "x truncated to an integer"
PythonTurtleBackward = "Move backward by x pixels"
PythonTurtleCircle = "Circle of radius r pixels"
PythonTurtleColor = "Stiftfarbe setzen"
PythonTurtleColorMode = "Set the color mode to 1.0 or 255"
PythonTurtleForward = "Move forward by x pixels"
PythonTurtleFunction = "turtle module function prefix"
PythonTurtleGoto = "Move to (x,y) coordinates"
PythonTurtleHeading = "Return the current heading"
PythonTurtleHideturtle = "Hide the turtle"
PythonTurtleIsdown = "Return True if the pen is down"
PythonTurtleLeft = "Turn left by a degrees"
PythonTurtlePendown = "Pull the pen down"
PythonTurtlePensize = "Set the line thickness to x pixels"
PythonTurtlePenup = "Pull the pen up"
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"
PythonUniform = "Floating point number in [a,b]"
PythonImportTime = "Import time module"
PythonTimePrefix = "time module function prefix"
PythonTimeSleep = "Wait for n second"
PythonMonotonic = "Return monotonic time"
PythonFileOpen = "Öffnet eine Datei"
PythonFileSeekable = "Kann Datei durchsucht werden?"
PythonFileSeek = "Bewegt den Cursor einer Datei"
PythonFileTell = "Position des Cursors ermitteln"
PythonFileSeekable = "Ist eine Datei durchsuchbar?"
PythonFileSeek = "Dateicursor verschieben"
PythonFileTell = "Cursorposition der Datei abrufen"
PythonFileClose = "Schließt eine Datei"
PythonFileClosed = "Wahr, wenn Datei geschlossen wurde"
PythonFileRead = "Lesen bis zu einer Größe von Bytes"
PythonFileWrite = "Schreibe b in Datei"
PythonFileReadline = "Liest Zeile oder Anzahl Bytes"
PythonFileClosed = "Wenn Datei geschlossen wurde"
PythonFileRead = "Bis zu size Bytes lesen"
PythonFileWrite = "Schreibe b in die Datei"
PythonFileReadline = "Lies eine Zeile"
PythonFileReadlines = "Liest eine Liste von Zeilen"
PythonFileTruncate = "Verkleinert die Datei auf Größe"
PythonFileTruncate = "Größe der Datei ändern"
PythonFileWritelines = "Schreibt eine Liste von Zeilen"
PythonFileName = "Enthält den Namen der Datei"
PythonFileMode = "Enthält den Öffnungsmodus der Datei"
PythonFileReadable = "Kann Datei gelesen werden?"
PythonFileWritable = "Kann Datei geschrieben werden?"
PythonFileName = "Dateiname"
PythonFileMode = "Dateiöffnungsmodus"
PythonFileReadable = "Ist die Datei lesbar?"
PythonFileWritable = "Ist die Datei beschreibbar?"

View File

@@ -1,7 +1,7 @@
PythonPound = "Comment"
PythonPercent = "Modulo"
Python1J = "Imaginary i"
PythonLF = "Line feed"
PythonLF = "line feed"
PythonTab = "Tabulation"
PythonAmpersand = "Bitwise and"
PythonSymbolExp = "Bitwise exclusive or"
@@ -30,8 +30,8 @@ PythonColor = "Define a rgb color"
PythonColorBlack = "Black color"
PythonColorBlue = "Blue color"
PythonColorBrown = "Brown color"
PythonColorGray = "Gray color"
PythonColorGreen = "Green color"
PythonColorGrey = "Grey color"
PythonColorOrange = "Orange color"
PythonColorPink = "Pink color"
PythonColorPurple = "Purple color"
@@ -45,7 +45,6 @@ PythonCosh = "Hyperbolic cosine"
PythonCount = "Count the occurrences of x"
PythonDegrees = "Convert x from radians to degrees"
PythonDivMod = "Quotient and remainder"
PythonDrawLine = "Draw a line"
PythonDrawString = "Display a text from pixel (x,y)"
PythonErf = "Error function"
PythonErfc = "Complementary error function"
@@ -82,6 +81,52 @@ PythonIsInfinite = "Check if x is infinity"
PythonIsKeyDown = "Return True if the k key is down"
PythonIsNaN = "Check if x is a NaN"
PythonKandinskyFunction = "kandinsky module function prefix"
PythonKeyLeft = "LEFT ARROW key"
PythonKeyUp = "UP ARROW key"
PythonKeyDown = "DOWN ARROW key"
PythonKeyRight = "RIGHT ARROW key"
PythonKeyOk = "OK key"
PythonKeyBack = "BACK key"
PythonKeyHome = "HOME key"
PythonKeyOnOff = "ON/OFF key"
PythonKeyShift = "SHIFT key"
PythonKeyAlpha = "ALPHA key"
PythonKeyXnt = "X,N,T key"
PythonKeyVar = "VAR key"
PythonKeyToolbox = "TOOLBOX key"
PythonKeyBackspace = "BACKSPACE key"
PythonKeyExp = "EXPONENTIAL key"
PythonKeyLn = "NATURAL LOGARITHM key"
PythonKeyLog = "DECIMAL LOGARITHM key"
PythonKeyImaginary = "IMAGINARY I key"
PythonKeyComma = "COMMA key"
PythonKeyPower = "POWER key"
PythonKeySine = "SINE key"
PythonKeyCosine = "COSINE key"
PythonKeyTangent = "TANGENT key"
PythonKeyPi = "PI key"
PythonKeySqrt = "SQUARE ROOT key"
PythonKeySquare = "SQUARE key"
PythonKeySeven = "7 key"
PythonKeyEight = "8 key"
PythonKeyNine = "9 key"
PythonKeyLeftParenthesis = "LEFT PARENTHESIS key"
PythonKeyRightParenthesis = "RIGHT PARENTHESIS key"
PythonKeyFour = "4 key"
PythonKeyFive = "5 key"
PythonKeySix = "6 key"
PythonKeyMultiplication = "MULTIPLICATION key"
PythonKeyDivision = "DIVISION key"
PythonKeyOne = "1 key"
PythonKeyTwo = "2 key"
PythonKeyThree = "3 key"
PythonKeyPlus = "PLUS key"
PythonKeyMinus = "MINUS key"
PythonKeyZero = "0 key"
PythonKeyDot = "DOT key"
PythonKeyEe = "10 POWER X key"
PythonKeyAns = "ANS key"
PythonKeyExe = "EXE key"
PythonLdexp = "Return x*(2**i), inverse of frexp"
PythonLength = "Length of an object"
PythonLgamma = "Log-gamma function"
@@ -103,7 +148,7 @@ PythonPower = "x raised to the power y"
PythonPrint = "Print object"
PythonRadians = "Convert x from degrees to radians"
PythonRandint = "Random integer in [a,b]"
PythonRandom = "Floating point number in [0,1]"
PythonRandom = "Floating point number in [0,1["
PythonRandomFunction = "random module function prefix"
PythonRandrange = "Random number in range(start,stop)"
PythonRangeStartStop = "List from start to stop-1"
@@ -153,7 +198,6 @@ PythonUniform = "Floating point number in [a,b]"
PythonImportTime = "Import time module"
PythonImportOs = "Import os module"
PythonOsUname = "Get infos about the system"
PythonOsGetlogin = "Get username"
PythonOsRemove = "Remove file named filename"
PythonOsRename = "Rename file oldname to newname"
PythonOsListdir = "List files in memory"

View File

@@ -30,8 +30,8 @@ PythonColor = "Define a rgb color"
PythonColorBlack = "Black color"
PythonColorBlue = "Blue color"
PythonColorBrown = "Brown color"
PythonColorGray = "Gray color"
PythonColorGreen = "Green color"
PythonColorGrey = "Grey color"
PythonColorOrange = "Orange color"
PythonColorPink = "Pink color"
PythonColorPurple = "Purple color"
@@ -45,7 +45,6 @@ PythonCosh = "Hyperbolic cosine"
PythonCount = "Count the occurrences of x"
PythonDegrees = "Convert x from radians to degrees"
PythonDivMod = "Quotient and remainder"
PythonDrawLine = "Draw a line"
PythonDrawString = "Display a text from pixel (x,y)"
PythonErf = "Error function"
PythonErfc = "Complementary error function"
@@ -82,6 +81,52 @@ PythonIsInfinite = "Check if x is infinity"
PythonIsKeyDown = "Return True if the k key is down"
PythonIsNaN = "Check if x is a NaN"
PythonKandinskyFunction = "kandinsky module function prefix"
PythonKeyLeft = "LEFT ARROW key"
PythonKeyUp = "UP ARROW key"
PythonKeyDown = "DOWN ARROW key"
PythonKeyRight = "RIGHT ARROW key"
PythonKeyOk = "OK key"
PythonKeyBack = "BACK key"
PythonKeyHome = "HOME key"
PythonKeyOnOff = "ON/OFF key"
PythonKeyShift = "SHIFT key"
PythonKeyAlpha = "ALPHA key"
PythonKeyXnt = "X,N,T key"
PythonKeyVar = "VAR key"
PythonKeyToolbox = "TOOLBOX key"
PythonKeyBackspace = "BACKSPACE key"
PythonKeyExp = "EXPONENTIAL key"
PythonKeyLn = "NATURAL LOGARITHM key"
PythonKeyLog = "DECIMAL LOGARITHM key"
PythonKeyImaginary = "IMAGINARY I key"
PythonKeyComma = "COMMA key"
PythonKeyPower = "POWER key"
PythonKeySine = "SINE key"
PythonKeyCosine = "COSINE key"
PythonKeyTangent = "TANGENT key"
PythonKeyPi = "PI key"
PythonKeySqrt = "SQUARE ROOT key"
PythonKeySquare = "SQUARE key"
PythonKeySeven = "7 key"
PythonKeyEight = "8 key"
PythonKeyNine = "9 key"
PythonKeyLeftParenthesis = "LEFT PARENTHESIS key"
PythonKeyRightParenthesis = "RIGHT PARENTHESIS key"
PythonKeyFour = "4 key"
PythonKeyFive = "5 key"
PythonKeySix = "6 key"
PythonKeyMultiplication = "MULTIPLICATION key"
PythonKeyDivision = "DIVISION key"
PythonKeyOne = "1 key"
PythonKeyTwo = "2 key"
PythonKeyThree = "3 key"
PythonKeyPlus = "PLUS key"
PythonKeyMinus = "MINUS key"
PythonKeyZero = "0 key"
PythonKeyDot = "DOT key"
PythonKeyEe = "10 POWER X key"
PythonKeyAns = "ANS key"
PythonKeyExe = "EXE key"
PythonLdexp = "Return x*(2**i), inverse of frexp"
PythonLength = "Length of an object"
PythonLgamma = "Log-gamma function"
@@ -153,7 +198,6 @@ PythonUniform = "Floating point number in [a,b]"
PythonImportTime = "Import time module"
PythonImportOs = "Import os module"
PythonOsUname = " Información del sistema "
PythonOsGetlogin = "Get username"
PythonOsRemove = "Eliminar un archivo"
PythonOsRename = "Renombrar archivo"
PythonOsListdir = "Archivos de la lista"

View File

@@ -30,8 +30,8 @@ PythonColor = "Définit une couleur rvb"
PythonColorBlack = "Couleur noire"
PythonColorBlue = "Couleur bleue"
PythonColorBrown = "Couleur marron"
PythonColorGray = "Couleur grise"
PythonColorGreen = "Couleur verte"
PythonColorGrey = "Couleur grise"
PythonColorOrange = "Couleur orange"
PythonColorPink = "Couleur rose"
PythonColorPurple = "Couleur violette"
@@ -45,7 +45,6 @@ PythonCosh = "Cosinus hyperbolique"
PythonCount = "Compte les occurrences de x"
PythonDegrees = "Conversion de radians en degrés"
PythonDivMod = "Quotient et reste"
PythonDrawLine = "Trace une ligne"
PythonDrawString = "Affiche un texte au pixel (x,y)"
PythonErf = "Fonction d'erreur"
PythonErfc = "Fonction d'erreur complémentaire"
@@ -82,6 +81,52 @@ PythonIsInfinite = "Teste si x est infini"
PythonIsKeyDown = "Renvoie True si touche k enfoncée"
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"
@@ -153,25 +198,24 @@ PythonUniform = "Nombre décimal dans [a,b]"
PythonImportTime = "Importation du module temps"
PythonImportOs = "Importation du module os"
PythonOsUname = "Donne des infos sur le système"
PythonOsGetlogin = "Donne le nom d'utilisateur"
PythonOsRemove = "Supprime le fichier nommé filename"
PythonOsRename = "Renomme oldname en newname"
PythonOsListdir = "Liste les fichiers"
PythonTimePrefix = "Préfixe fonction du module temps"
PythonTimeSleep = "Attendre n secondes"
PythonMonotonic = "Retourne le temps monotone"
PythonMonotonic = "Retourne le temps monotonic"
PythonFileOpen = "Ouvre un fichier"
PythonFileSeekable = "Indique si seek peut être utilisé"
PythonFileSeek = "Déplace le curseur interne"
PythonFileTell = "Donne la posititon du curseur"
PythonFileClose = "Ferme un fichier"
PythonFileClosed = "True si le fichier a été fermé"
PythonFileRead = "Lit jusqu'à size bytes"
PythonFileWrite = "Écrit b dans le fichier"
PythonFileReadline = "Lit une ligne ou jusqu'à size bytes"
PythonFileReadlines = "Lit une liste de lignes"
PythonFileRead = "Lis jusqu'à size bytes"
PythonFileWrite = "Écris b dans le fichier"
PythonFileReadline = "Lis une ligne ou jusqu'à size bytes"
PythonFileReadlines = "Lis une liste de lignes"
PythonFileTruncate = "Redimensionne le fichier"
PythonFileWritelines = "Écrit une liste de lignes"
PythonFileWritelines = "Écris une liste de lignes"
PythonFileName = "Nom du fichier"
PythonFileMode = "Mode d'ouverture du fichier"
PythonFileReadable = "Indique si read peut être utilisé"

View File

@@ -1,178 +1,222 @@
PythonPound = "Megjegyzés"
PythonPercent = "Modulo"
Python1J = "Képzeletbeli i"
PythonLF = "Enter"
PythonLF = "Line feed"
PythonTab = "Táblázat"
PythonAmpersand = "Logikus és"
PythonSymbolExp = "logikus exkluzív vagy pedig"
PythonVerticalBar = "logikus vagy pedig"
PythonAmpersand = "Bitwise és"
PythonSymbolExp = "Bitwise exkluzív vagy"
PythonVerticalBar = "Bitwise vagy"
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"
PythonSingleQuote = "Egyetlen idézet"
PythonAbs = "Abszolút érték / nagyság"
PythonAcos = "Arc koszinusz"
PythonAcosh = "Íves hiperbolikus koszinusz"
PythonAppend = "x hozzáadása a lista végéhez"
PythonArrow = "Arrow from (x,y) to (x+dx,y+dy)"
PythonAsin = "Arc szinusz"
PythonAsinh = "Íves hiperbolikus szinusz"
PythonAtan = "Arc érintö"
PythonAtan2 = "Visszatérés atan (y / x)"
PythonAtanh = "Arc hiperbolikus érintö"
PythonAxis = "Set axes to (xmin,xmax,ymin,ymax)"
PythonBar = "Draw a bar plot with x values"
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"
PythonColor = "Rgb szín meghatározása"
PythonColorBlack = "Fekete szín"
PythonColorBlue = "Kék szín"
PythonColorBrown = "Barna szín"
PythonColorGreen = "Zöld szín"
PythonColorGray = "Szürke szín"
PythonColorGrey = "Szürke szín"
PythonColorOrange = "Narancssárga szín"
PythonColorPink = "Rózsaszín szín"
PythonColorPurple = "Lila szín"
PythonColorRed = "Piros szín"
PythonColorWhite = "Fehér szín"
PythonColorWhite = "White color"
PythonColorYellow = "Sárga szín"
PythonComplex = "A + ib visszaadása"
PythonCopySign = "X visszaadása y jelével"
PythonCopySign = "Visszatérés x-val 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"
PythonDegrees = "x konvertálása x-röl radiánokra fokokra"
PythonDivMod = "Hányados és maradék"
PythonDrawLine = "Húzzon egy vonalat "
PythonDrawString = "Szöveg megjelenítése (x, y)-en"
PythonDrawString = "Szöveg megjelenítése pixelböl (x, y)"
PythonErf = "Hiba funkció"
PythonErfc = "Kiegészítö hiba funkció"
PythonErfc = "Kiegészítö hibafunkció"
PythonEval = "Visszaadja az értékelt kifejezést"
PythonExp = "Exponenciális függvény"
PythonExpm1 = "exp(x)-1 sámitása"
PythonExpm1 = "Számítsuk ki az exp (x) -1-et"
PythonFabs = "Abszolút érték"
PythonFillRect = "Téglalap töltése"
PythonFloat = "Konvertálása tizedes számra"
PythonFloor = "Egész része"
PythonFillRect = "Töltsön meg egy téglalapot pixelnél (x, y)"
PythonFloat = "x konvertálása float-ra"
PythonFloor = "Emelet"
PythonFmod = "a modulo b"
PythonFrExp = "X mantissája és kiállítója"
PythonFrExp = "Mantissa és az x exponense"
PythonGamma = "Gamma funkció"
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"
PythonGetPixel = "Visszatérési pixel (x, y) szín"
PythonGetrandbits = "Egész szám k véletlen bittel"
PythonGrid = "Toggle the visibility of the grid"
PythonHex = "Egész szám konvertálása hexadecimálisra"
PythonHist = "Draw the histogram of x"
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"
PythonImportTurtle = "turtle modul importálása"
PythonImportTime = "time modul importálása"
PythonImportMath = "Import matematikai modul"
PythonImportMatplotlibPyplot = "Import matplotlib.pyplot module"
PythonImportTime = "Idömodul importálása"
PythonImportOs = "Os modul importálása"
PythonOsUname = "Információ a rendszerről"
PythonOsRemove = "Fájl eltávolítása"
PythonOsRename = "Fájl átnevezése"
PythonOsListdir = "Fájlok listázása"
PythonImportTurtle = "Import teknös modul"
PythonIndex = "Az elsö x esemény indexe"
PythonInput = "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"
PythonInput = "Érték kérése"
PythonInsert = "Helyezzen x-t az i indexbe a listában"
PythonInt = "x konvertálása egész számra"
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"
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"
PythonIsFinite = "Ellenörizze, hogy x véges-e"
PythonIsInfinite = "Ellenörizze, hogy x végtelen-e"
PythonIsKeyDown = "True true, ha a k gomb le van nyomva"
PythonIsNaN = "Ellenörizze, hogy x nem NaN"
PythonKandinskyFunction = "kandinsky modul function prefix"
PythonKeyLeft = "Balra nyíl gomb"
PythonKeyUp = "FEL NYÍL gomb"
PythonKeyDown = "LE nyíl gomb"
PythonKeyRight = "JOBB NYÍL gomb"
PythonKeyOk = "OK gomb"
PythonKeyBack = "VISSZA kulcs"
PythonKeyHome = "HOME kulcs"
PythonKeyOnOff = "BE / KI gomb"
PythonKeyShift = "SHIFT kulcs"
PythonKeyAlpha = "ALPHA kulcs"
PythonKeyXnt = "X, N, T kulcs"
PythonKeyVar = "VAR kulcs"
PythonKeyToolbox = "TOOLBOX kulcs"
PythonKeyBackspace = "BACKSPACE kulcs"
PythonKeyExp = "EXPONENTIAL kulcs"
PythonKeyLn = "NATURAL LOGARITHM kulcs"
PythonKeyLog = "DECIMAL LOGARITHM kulcs"
PythonKeyImaginary = "IMAGINÁRIS I kulcs"
PythonKeyComma = "COMMA kulcs"
PythonKeyPower = "POWER kulcs"
PythonKeySine = "SINE kulcs"
PythonKeyCosine = "KOSZIN kulcs"
PythonKeyTangent = "TANGENT kulcs"
PythonKeyPi = "PI kulcs"
PythonKeySqrt = "SQUARE ROOT kulcs"
PythonKeySquare = "SQUARE kulcs"
PythonKeySeven = "7 kulcs"
PythonKeyEight = "8 kulcs"
PythonKeyNine = "9 kulcs"
PythonKeyLeftParenthesis = "Bal oldali PARENTHESIS kulcs"
PythonKeyRightParenthesis = "JOGOS SZÜLETÉS kulcs"
PythonKeyFour = "4 kulcs"
PythonKeyFive = "5 kulcs"
PythonKeySix = "6 kulcs"
PythonKeyMultiplication = "TÖBB MüKÖDÉS kulcs"
PythonKeyDivision = "DIVISION kulcs"
PythonKeyOne = "1 kulcs"
PythonKeyTwo = "2 kulcs"
PythonKeyThree = "3 kulcs"
PythonKeyPlus = "PLUS kulcs"
PythonKeyMinus = "MINUS kulcs"
PythonKeyZero = "0 kulcs"
PythonKeyDot = "DOT kulcs"
PythonKeyEe = "10 POWER X kulcs"
PythonKeyAns = "ANS kulcs"
PythonKeyExe = "EXE kulcs"
PythonLdexp = "Visszatérés x * (2 ** i), inverz a frexp értékhez"
PythonLength = "Objektum hossza"
PythonLgamma = "Log-gamma funkció"
PythonLog = "Logaritmus az alap"
PythonLog10 = "Logaritmus az alaphoz 10"
PythonLog2 = "Logaritmus az alaphoz 2"
PythonMathFunction = "matematikai modul funkció elötag"
PythonMatplotlibPyplotFunction = "matplotlib.pyplot module prefix"
PythonMax = "Maximum"
PythonMin = "Minimum"
PythonModf = "x-nek tört és egész részei"
PythonMonotonic = "Az óra értékét adja vissza"
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"
PythonModf = "Az x tört és egész részei"
PythonMonotonic = "A monoton óra értéke"
PythonOct = "Egész szám konvertálása oktális értékre"
PythonPhase = "z fázis"
PythonPlot = "Plot y versus x as lines"
PythonPolar = "z poláris koordinátákban"
PythonPop = "Az utolsó elem eltávolítása és visszaküldése"
PythonPower = "x emelve az y teljesítményre"
PythonPrint = "Objektum nyomtatása"
PythonRadians = "x konvertálása x fokról radiánra"
PythonRandint = "Véletlen egész szám [a, b] -ben"
PythonRandom = "Lebegöpontos szám [0,1-ben ["
PythonRandomFunction = "véletlenszerü modul funkció elötag"
PythonRandrange = "Véletlen szám a tartományban (start, stop)"
PythonRangeStartStop = "Lista az elejétöl a stop-1-ig"
PythonRangeStop = "Lista 0-tól stop-1-ig"
PythonRect = "z derékszögü koordinátákban"
PythonRemove = "Távolítsa el az x elsö elöfordulását"
PythonReverse = "A lista elemeinek megfordítása"
PythonRound = "N számjegyre kerekítve"
PythonScatter = "Draw a scatter plot of y versus x"
PythonSeed = "Inicializálja a véletlenszám-generátort"
PythonSetPixel = "Színes pixel (x, y)"
PythonShow = "Display the figure"
PythonSin = "Sine"
PythonSinh = "Hiperbolikus szinusz"
PythonSleep = "t másodpercre meg állitani a programmot"
PythonSort = "A listát rendezni"
PythonSleep = "A végrehajtás felfüggesztése t másodpercre"
PythonSort = "A lista rendezése"
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"
PythonSum = "Összegzi a lista elemeit"
PythonTan = "Érintö"
PythonTanh = "Hiperbolikus érintö"
PythonText = "Display a text at (x,y) coordinates"
PythonTimeFunction = "idömodul funkció elötag"
PythonTrunc = "x egészre csonkítva"
PythonTurtleBackward = "Visszalépés x pixelrel"
PythonTurtleCircle = "r pixel sugarú kör"
PythonTurtleColor = "Állítsa be az toll színét"
PythonTurtleColorMode = "Set the color mode to 1.0 or 255"
PythonTurtleForward = "Ugrás x pixelrel"
PythonTurtleFunction = "teknös modul funkció elötag"
PythonTurtleGoto = "Mozgatás (x, y) koordinátákra"
PythonTurtleHeading = "Visszaadja az aktuális címsort"
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"
PythonTurtleIsdown = "Visszatérés igazhoz, ha az toll lefelé"
PythonTurtleLeft = "Forduljon fokkal 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"
PythonTurtlePosition = "Az aktuális (x, y) hely visszaadása"
PythonTurtleReset = "A rajz visszaállítása"
PythonTurtleRight = "Forduljon fokkal jobbra"
PythonTurtleSetheading = "Állítsa be a tájolást fokokra"
PythonTurtleSetposition = "A helymeghatározás"
PythonTurtleShowturtle = "Mutasd a teknösöt"
PythonTurtleSpeed = "Rajzolási sebesség 0 és 10 között"
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ö"
PythonTurtleWrite = "Display a text"
PythonUniform = "Lebegöpontos szám [a, b] -ben"
PythonImportTime = "Idömodul importálása"
PythonTimePrefix = "idömodul funkció elötag"
PythonTimeSleep = "Várj n másodpercet"
PythonMonotonic = "Vissza 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"
PythonFileSeekable = "A fájl kereshető?"
PythonFileSeek = "A fájl kurzorának áthelyezése"
PythonFileTell = "A fájl kurzorának helye"
PythonFileClose = "Bezár egy fájlt"
PythonFileClosed = "Igaz, ha a fájl bezárt"
PythonFileRead = "Olvasson méretbájtig"
PythonFileWrite = "B beírása fájlba"
PythonFileReadline = "Olvas egy sort"
PythonFileReadlines = "Olvassa a sorok listáját"
PythonFileTruncate = "A fájl átméretezése méretre"
PythonFileWritelines = "Sorok listáját írja"
PythonFileName = "a fájl neve"
PythonFileMode = "a fájl nyitott módja"
PythonFileReadable = "A fájl olvasható?"
PythonFileWritable = "A fájl írható?"

View File

@@ -30,8 +30,8 @@ PythonColor = "Definisci un colore rvb"
PythonColorBlack = "Colore nero"
PythonColorBlue = "Colore blu"
PythonColorBrown = "Colore marrone"
PythonColorGray = "Colore grigio"
PythonColorGreen = "Colore verde"
PythonColorGrey = "Colore grigio"
PythonColorOrange = "Colore arancione"
PythonColorPink = "Colore rosa"
PythonColorPurple = "Colore viola"
@@ -45,7 +45,6 @@ PythonCosh = "Coseno iperbolico"
PythonCount = "Conta le ricorrenze di x"
PythonDegrees = "Conversione di radianti in gradi"
PythonDivMod = "Quoziente e resto"
PythonDrawLine = "Disegna una linea"
PythonDrawString = "Visualizza il testo dal pixel x,y"
PythonErf = "Funzione d'errore"
PythonErfc = "Funzione d'errore complementare"
@@ -74,7 +73,6 @@ PythonImportTurtle = "Importa del modulo turtle"
PythonImportTime = "Importa del modulo time"
PythonImportOs = "Importa modulo os"
PythonOsUname = "Ottieni informazioni sul sistema"
PythonOsGetlogin = "Get username"
PythonOsRemove = "Rimuovere un file"
PythonOsRename = "Rinomina file"
PythonOsListdir = "Elenca file"
@@ -88,6 +86,52 @@ PythonIsInfinite = "Testa se x est infinito"
PythonIsKeyDown = "Restituisce True premendo tasto k"
PythonIsNaN = "Testa se x è NaN"
PythonKandinskyFunction = "Prefisso funzione modulo kandinsky"
PythonKeyLeft = "Tasto FRECCIA SINISTRA"
PythonKeyUp = "Tasto FRECCIA ALTO"
PythonKeyDown = "Tasto FRECCIA BASSO"
PythonKeyRight = "Tasto FRECCIA DESTRA"
PythonKeyOk = "Tasto OK"
PythonKeyBack = "Tasto INDIETRO"
PythonKeyHome = "Tasto CASA"
PythonKeyOnOff = "Tasto ON/OFF"
PythonKeyShift = "Tasto SHIFT"
PythonKeyAlpha = "Tasto ALPHA"
PythonKeyXnt = "Tasto X,N,T"
PythonKeyVar = "Tasto VAR"
PythonKeyToolbox = "Tasto TOOLBOX"
PythonKeyBackspace = "Tasto CANCELLA"
PythonKeyExp = "Tasto ESPONENZIALE"
PythonKeyLn = "Tasto LOGARITMO NEPERIANO"
PythonKeyLog = "Tasto LOGARITMO DECIMALE"
PythonKeyImaginary = "Tasto I IMMAGINE"
PythonKeyComma = "Tasto VIRGOLA"
PythonKeyPower = "Tasto POTENZA"
PythonKeySine = "Tasto SENO"
PythonKeyCosine = "Tasto COSENO"
PythonKeyTangent = "Tasto TANGENTE"
PythonKeyPi = "Tasto PI"
PythonKeySqrt = "Tasto RADICE QUADRATA"
PythonKeySquare = "Tasto QUADRATO"
PythonKeySeven = "Tasto 7"
PythonKeyEight = "Tasto 8"
PythonKeyNine = "Tasto 9"
PythonKeyLeftParenthesis = "Tasto PARENTESI SINISTRA"
PythonKeyRightParenthesis = "Tasto PARENTESI DESTRA"
PythonKeyFour = "Tasto 4"
PythonKeyFive = "Tasto 5"
PythonKeySix = "Tasto 6"
PythonKeyMultiplication = "Tasto MOLTIPLICAZIONE"
PythonKeyDivision = "Tasto DIVISIONE"
PythonKeyOne = "Tasto 1"
PythonKeyTwo = "Tasto 2"
PythonKeyThree = "Tasto 3"
PythonKeyPlus = "Tasto PIÙ"
PythonKeyMinus = "Tasto MENO"
PythonKeyZero = "Tasto 0"
PythonKeyDot = "Tasto PUNTO"
PythonKeyEe = "Tasto 10 POTENZA X"
PythonKeyAns = "Tasto ANS"
PythonKeyExe = "Tasto EXE"
PythonLdexp = "Inversa di frexp : x*(2**i)"
PythonLength = "Longhezza di un oggetto"
PythonLgamma = "Logaritmo della funzione gamma"

View File

@@ -13,14 +13,14 @@ PythonAbs = "Absolute waarde"
PythonAcos = "Arccosinus"
PythonAcosh = "Arccosinus hyperbolicus"
PythonAppend = "Voeg x toe aan het eind van je lijst"
PythonArrow = "Pijl van (x,y) naar (x+dx,y+dy)"
PythonArrow = "Arrow from (x,y) to (x+dx,y+dy)"
PythonAsin = "Arcsinus"
PythonAsinh = "Arcsinus hyperbolicus"
PythonAtan = "Arctangens"
PythonAtan2 = "Geeft atan(y/x)"
PythonAtanh = "Arctangens hyperbolicus"
PythonAxis = "Stel de assen in (xmin,xmax,ymin,ymax)"
PythonBar = "Teken staafdiagram met x-waarden"
PythonAxis = "Set the axes to (xmin,xmax,ymin,ymax)"
PythonBar = "Draw a bar plot with x values"
PythonBin = "Zet integer om in een binair getal"
PythonCeil = "Plafond"
PythonChoice = "Geeft willek. getal van de lijst"
@@ -30,8 +30,8 @@ PythonColor = "Definieer een rgb kleur"
PythonColorBlack = "Zwarte kleur"
PythonColorBlue = "Blauwe kleur"
PythonColorBrown = "Bruine kleur"
PythonColorGray = "Grijze kleur"
PythonColorGreen = "Groene kleur"
PythonColorGrey = "Grijze kleur"
PythonColorOrange = "Oranje kleur"
PythonColorPink = "Roze kleur"
PythonColorPurple = "Paarse kleur"
@@ -45,7 +45,6 @@ PythonCosh = "Cosinus hyperbolicus"
PythonCount = "Tel voorkomen van x"
PythonDegrees = "Zet x om van radialen naar graden"
PythonDivMod = "Quotiënt en rest"
PythonDrawLine = "Teken een lijn"
PythonDrawString = "Geef een tekst weer van pixel (x,y)"
PythonErf = "Error functie"
PythonErfc = "Complementaire error functie"
@@ -61,19 +60,18 @@ PythonFrExp = "Mantisse en exponent van x: (m,e)"
PythonGamma = "Gammafunctie"
PythonGetPixel = "Geef pixel (x,y) kleur (rgb)"
PythonGetrandbits = "Integer met k willekeurige bits"
PythonGrid = "Verander zichtbaarheid raster"
PythonGrid = "Toggle the visibility of the grid"
PythonHex = "Zet integer om in hexadecimaal"
PythonHist = "Teken het histogram van x"
PythonHist = "Draw the histogram of x"
PythonImportCmath = "Importeer cmath module"
PythonImportIon = "Importeer ion module"
PythonImportKandinsky = "Importeer kandinsky module"
PythonImportRandom = "Importeer random module"
PythonImportMath = "Importeer math module"
PythonImportMatplotlibPyplot = "Importeer matplotlib.pyplot module"
PythonImportMatplotlibPyplot = "Import matplotlib.pyplot module"
PythonImportTime = "Importeer time module"
PythonImportOs = "Importeer os module"
PythonOsUname = " Krijg systeeminfo"
PythonOsGetlogin = "Get username"
PythonOsRemove = "Een bestand verwijderen"
PythonOsRename = "Hernoem bestand"
PythonOsListdir = "Lijstbestanden"
@@ -86,8 +84,54 @@ PythonIonFunction = "ion module voorvoegsel"
PythonIsFinite = "Controleer of x eindig is"
PythonIsInfinite = "Controleer of x oneindig is"
PythonIsKeyDown = "Geef True als k toets omlaag is"
PythonIsNaN = "Controleer of x geen getal is"
PythonIsNaN = "Controleer of x geen nummer is"
PythonKandinskyFunction = "kandinsky module voorvoegsel"
PythonKeyLeft = "PIJL NAAR LINKS toets"
PythonKeyUp = "PIJL OMHOOG toets"
PythonKeyDown = "PIJL OMLAAG toets"
PythonKeyRight = "PIJL NAAR RECHTS toets"
PythonKeyOk = "OK toets"
PythonKeyBack = "TERUG toets"
PythonKeyHome = "HOME toets"
PythonKeyOnOff = "AAN/UIT toets"
PythonKeyShift = "SHIFT toets"
PythonKeyAlpha = "ALPHA toets"
PythonKeyXnt = "X,N,T toets"
PythonKeyVar = "VAR toets"
PythonKeyToolbox = "TOOLBOX toets"
PythonKeyBackspace = "BACKSPACE toets"
PythonKeyExp = "EXPONENTIEEL toets"
PythonKeyLn = "NATUURLIJKE LOGARITME toets"
PythonKeyLog = "BRIGGSE LOGARITME toets"
PythonKeyImaginary = "IMAGINAIRE I toets"
PythonKeyComma = "KOMMA toets"
PythonKeyPower = "MACHT toets"
PythonKeySine = "SINUS toets"
PythonKeyCosine = "COSINUS toets"
PythonKeyTangent = "TANGENS toets"
PythonKeyPi = "PI toets"
PythonKeySqrt = "VIERKANTSWORTEL toets"
PythonKeySquare = "KWADRAAT toets"
PythonKeySeven = "7 toets"
PythonKeyEight = "8 toets"
PythonKeyNine = "9 toets"
PythonKeyLeftParenthesis = "HAAKJE OPENEN toets"
PythonKeyRightParenthesis = "HAAKJE SLUITEN toets"
PythonKeyFour = "4 toets"
PythonKeyFive = "5 toets"
PythonKeySix = "6 toets"
PythonKeyMultiplication = "VERMENIGVULDIGEN toets"
PythonKeyDivision = "DELEN toets"
PythonKeyOne = "1 toets"
PythonKeyTwo = "2 toets"
PythonKeyThree = "3 toets"
PythonKeyPlus = "PLUS toets"
PythonKeyMinus = "MIN toets"
PythonKeyZero = "0 toets"
PythonKeyDot = "PUNT toets"
PythonKeyEe = "10 TOT DE MACHT X toets"
PythonKeyAns = "ANS toets"
PythonKeyExe = "EXE toets"
PythonLdexp = "Geeft x*(2**i), inversie van frexp"
PythonLength = "Lengte van een object"
PythonLgamma = "Log-gammafunctie"
@@ -102,14 +146,14 @@ PythonModf = "Fractionele en gehele delen van x"
PythonMonotonic = "Waarde van een monotone klok"
PythonOct = "Integer omzetten naar octaal"
PythonPhase = "Fase van z in radialen"
PythonPlot = "Plot y versus x als lijnen"
PythonPlot = "Plot y versus x as lines"
PythonPolar = "z in poolcoördinaten"
PythonPop = "Verwijder en breng het laatste item terug"
PythonPower = "x tot de macht y"
PythonPrint = "Print object"
PythonRadians = "Zet x om van graden naar radialen"
PythonRandint = "Geeft willek. integer in [a,b]"
PythonRandom = "Een willekeurig getal in [0,1)"
PythonRandom = "Een willekeurig getal in [0,1["
PythonRandomFunction = "random module voorvoegsel"
PythonRandrange = "Willek. getal in range(start, stop)"
PythonRangeStartStop = "Lijst van start tot stop-1"
@@ -118,10 +162,10 @@ PythonRect = "z in cartesiaanse coördinaten"
PythonRemove = "Verwijder het eerste voorkomen van x"
PythonReverse = "Keer de elementen van de lijst om"
PythonRound = "Rond af op n cijfers"
PythonScatter = "Teken scatterplot van y versus x"
PythonScatter = "Draw a scatter plot of y versus x"
PythonSeed = "Start willek. getallengenerator"
PythonSetPixel = "Kleur pixel (x,y)"
PythonShow = "Figuur weergeven"
PythonShow = "Display the figure"
PythonSin= "Sinus"
PythonSinh = "Sinus hyperbolicus"
PythonSleep = "Stel executie voor t seconden uit"
@@ -130,7 +174,7 @@ PythonSqrt = "Vierkantswortel"
PythonSum = "Sommeer de items van een lijst"
PythonTan = "Tangens"
PythonTanh = "Tangens hyperbolicus"
PythonText = "Geef tekst weer op coördinaten (x,y)"
PythonText = "Display a text at (x,y) coordinates"
PythonTimeFunction = "time module voorvoegsel"
PythonTrunc = "x afgeknot tot een integer"
PythonTurtleBackward = "Ga achterwaarts met x pixels"
@@ -155,7 +199,7 @@ 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]"
PythonUniform = "Zwevendekommagetal in [a,b]"
PythonImportTime = "Import time module"
PythonTimePrefix = "time module function prefix"
PythonTimeSleep = "Wait for n second"

View File

@@ -30,8 +30,8 @@ PythonColor = "Define uma cor rgb"
PythonColorBlack = "Cor preta"
PythonColorBlue = "Cor azul"
PythonColorBrown = "Cor castanha"
PythonColorGray = "Cor cinzenta"
PythonColorGreen = "Cor verde"
PythonColorGrey = "Cor cinzenta"
PythonColorOrange = "Cor laranja"
PythonColorPink = "Cor rosa"
PythonColorPurple = "Cor roxa"
@@ -45,7 +45,6 @@ PythonCosh = "Cosseno hiperbólico"
PythonCount = "Contar as ocorrências de x"
PythonDegrees = "Converter x de radianos para graus"
PythonDivMod = "Quociente e resto"
PythonDrawLine = "Desenhe uma linha"
PythonDrawString = "Mostrar o texto do pixel (x,y)"
PythonErf = "Função erro"
PythonErfc = "Função erro complementar"
@@ -82,6 +81,52 @@ PythonIsInfinite = "Verificar se x é infinito"
PythonIsKeyDown = "Devolve True se tecla k pressionada"
PythonIsNaN = "Verificar se x é um NaN"
PythonKandinskyFunction = "Prefixo da função do módulo kandinsky"
PythonKeyLeft = "tecla SETA ESQUERDA"
PythonKeyUp = "tecla SETA CIMA "
PythonKeyDown = "tecla SETA BAIXO"
PythonKeyRight = "tecla SETA DIREITA"
PythonKeyOk = "tecla OK"
PythonKeyBack = "tecla VOLTAR"
PythonKeyHome = "tecla HOME"
PythonKeyOnOff = "tecla ON/OFF"
PythonKeyShift = "tecla SHIFT"
PythonKeyAlpha = "tecla ALPHA"
PythonKeyXnt = "tecla X,N,T"
PythonKeyVar = "tecla VAR"
PythonKeyToolbox = "tecla CAIXA DE FERRAMENTAS"
PythonKeyBackspace = "tecla APAGAR"
PythonKeyExp = "tecla EXPONENCIAL"
PythonKeyLn = "tecla LOGARITMO NATURAL"
PythonKeyLog = "tecla LOGARITMO DECIMAL"
PythonKeyImaginary = "tecla I IMAGINÁRIO"
PythonKeyComma = "tecla VÍRGULA"
PythonKeyPower = "tecla EXPOENTE"
PythonKeySine = "tecla SENO"
PythonKeyCosine = "tecla COSSENO"
PythonKeyTangent = "tecla TANGENTE"
PythonKeyPi = "tecla PI"
PythonKeySqrt = "tecla RAIZ QUADRADA"
PythonKeySquare = "tecla AO QUADRADO"
PythonKeySeven = "tecla 7"
PythonKeyEight = "tecla 8"
PythonKeyNine = "tecla 9"
PythonKeyLeftParenthesis = "tecla PARÊNTESE ESQUERDO"
PythonKeyRightParenthesis = "tecla PARÊNTESE DIREITO"
PythonKeyFour = "tecla 4"
PythonKeyFive = "tecla 5"
PythonKeySix = "tecla 6"
PythonKeyMultiplication = "tecla MULTIPLICAÇÃO"
PythonKeyDivision = "tecla DIVISÃO"
PythonKeyOne = "tecla 1"
PythonKeyTwo = "tecla 2"
PythonKeyThree = "tecla 3"
PythonKeyPlus = "tecla MAIS"
PythonKeyMinus = "tecla MENOS"
PythonKeyZero = "tecla 0"
PythonKeyDot = "tecla PONTO"
PythonKeyEe = "tecla 10 expoente X"
PythonKeyAns = "tecla ANS"
PythonKeyExe = "tecla EXE"
PythonLdexp = "Devolve x*(2**i), inverso de frexp"
PythonLength = "Comprimento de um objeto"
PythonLgamma = "Logaritmo da função gama"
@@ -153,7 +198,6 @@ PythonUniform = "Número decimal em [a,b]"
PythonImportTime = "Import time module"
PythonImportOs = "Import os module"
PythonOsUname = " Obter informações do sistema"
PythonOsGetlogin = "Get username"
PythonOsRemove = "Remover um ficheiro"
PythonOsRename = "Renomear ficheiro"
PythonOsListdir = "Listar ficheiros"

View File

@@ -32,8 +32,8 @@ PythonCommandColor = "color(r,g,b)"
PythonCommandColorBlack = "'black'"
PythonCommandColorBlue = "'blue'"
PythonCommandColorBrown = "'brown'"
PythonCommandColorGray = "'gray'"
PythonCommandColorGreen = "'green'"
PythonCommandColorGrey = "'grey'"
PythonCommandColorOrange = "'orange'"
PythonCommandColorPink = "'pink'"
PythonCommandColorPurple = "'purple'"
@@ -50,7 +50,6 @@ PythonCommandCount = "list.count(x)"
PythonCommandCountWithoutArg = ".count(\x11)"
PythonCommandDegrees = "degrees(x)"
PythonCommandDivMod = "divmod(a,b)"
PythonCommandDrawLine = "draw_line(x1,y1,x2,y2,color)"
PythonCommandDrawString = "draw_string(\"text\",x,y)"
PythonCommandConstantE = "e"
PythonCommandErf = "erf(x)"
@@ -216,7 +215,6 @@ PythonCommandUniform = "uniform(a,b)"
PythonConstantE = "2.718281828459045"
PythonConstantPi = "3.141592653589793"
PythonOsCommandUname = "uname()"
PythonOsCommandGetlogin = "getlogin()"
PythonOsCommandRemove = "remove(filename)"
PythonOsCommandRename = "rename(oldname, newname)"
PythonOsCommandRemoveWithoutArg = "remove(\x11)"

View File

@@ -451,6 +451,30 @@ void ConsoleController::printText(const char * text, size_t length) {
flushOutputAccumulationBufferToStore();
micropython_port_vm_hook_refresh_print();
}
// #if __EMSCRIPTEN__
/* If we called micropython_port_interrupt_if_needed here, we would need to
* put in the WHITELIST all the methods that call
* ConsoleController::printText, which means all the MicroPython methods that
* call print... This is a lot of work + might reduce the performance as
* emterpreted code is slower.
*
* We thus do not allow print interruption on the web simulator. It would be
* better to allow it, but the biggest problem was on the device anyways
* -> It is much quicker to interrupt Python on the web simulator than on the
* device.
*
* TODO: Allow print interrpution on emscripten -> maybe by using WASM=1 ? */
/*
* This can be run in Omega, since it uses WebASM.
*/
// #else
/* micropython_port_vm_hook_loop is not enough to detect user interruptions,
* because it calls micropython_port_interrupt_if_needed every 20000
* operations, and a print operation is quite long. We thus explicitely call
* micropython_port_interrupt_if_needed here. */
micropython_port_interrupt_if_needed();
// #endif
}
void ConsoleController::autoImportScript(Script script, bool force) {

View File

@@ -23,7 +23,7 @@ void EditorController::setScript(Script script, int scriptIndex) {
m_script = script;
m_scriptIndex = scriptIndex;
/* We edit the script directly in the storage buffer. We thus put all the
/* We edit the script direclty in the storage buffer. We thus put all the
* storage available space at the end of the current edited script and we set
* its size.
*
@@ -36,8 +36,8 @@ void EditorController::setScript(Script script, int scriptIndex) {
*
* */
Ion::Storage::sharedStorage()->putAvailableSpaceAtEndOfRecord(m_script);
m_editorView.setText(const_cast<char *>(m_script.content()), m_script.contentSize());
size_t newScriptSize = Ion::Storage::sharedStorage()->putAvailableSpaceAtEndOfRecord(m_script);
m_editorView.setText(const_cast<char *>(m_script.content()), newScriptSize - Script::StatusSize());
}
void EditorController::willExitApp() {

View File

@@ -67,19 +67,11 @@ void EditorView::GutterView::drawRect(KDContext * ctx, KDRect rect) const {
KDCoordinate firstLine = m_offset / glyphSize.height();
KDCoordinate firstLinePixelOffset = m_offset - firstLine * glyphSize.height();
char lineNumber[k_lineNumberCharLength];
char lineNumber[4];
int numberOfLines = bounds().height() / glyphSize.height() + 1;
for (int i=0; i<numberOfLines; i++) {
// Only the first two digits are displayed
int lineNumberValue = (i + firstLine + 1) % 100;
Poincare::Integer line(lineNumberValue);
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);
}
Poincare::Integer line(i + firstLine + 1);
line.serialize(lineNumber, 4);
KDCoordinate leftPadding = (2 - strlen(lineNumber)) * glyphSize.width();
ctx->drawString(
lineNumber,

View File

@@ -42,7 +42,6 @@ private:
KDSize minimalSizeForOptimalDisplay() const override;
private:
static constexpr KDCoordinate k_margin = 2;
static constexpr int k_lineNumberCharLength = 3;
const KDFont * m_font;
KDCoordinate m_offset;
};

View File

@@ -1,20 +1,44 @@
#include "helpers.h"
#include <escher/clipboard.h>
#include <string.h>
#include <ion/unicode/code_point.h>
#include <ion.h>
namespace Code {
namespace Helpers {
class EventTextPair {
public:
constexpr EventTextPair(Ion::Events::Event event, const char * text) : m_event(event), m_text(text) {}
Ion::Events::Event event() const { return m_event; }
const char * text() const { return m_text; }
private:
const Ion::Events::Event m_event;
const char * m_text;
};
static_assert('\x11' == UCodePointEmpty, "Unicode error");
static constexpr EventTextPair sEventTextMap[] = {
EventTextPair(Ion::Events::XNT, "x"),
EventTextPair(Ion::Events::Exp, "exp(\x11)"),
EventTextPair(Ion::Events::Ln, "log(\x11)"),
EventTextPair(Ion::Events::Log, "log10(\x11)"),
EventTextPair(Ion::Events::Imaginary, "1j"),
EventTextPair(Ion::Events::Power, "**"),
EventTextPair(Ion::Events::Pi, "pi"),
EventTextPair(Ion::Events::Sqrt, "sqrt(\x11)"),
EventTextPair(Ion::Events::Square, "**2"),
EventTextPair(Ion::Events::Multiplication, "*"),
EventTextPair(Ion::Events::EE, "e"),
};
const char * PythonTextForEvent(Ion::Events::Event event) {
for (size_t i=0; i<NumberOfPythonTextPairs; i++) {
UTF8Helper::TextPair pair = PythonTextPairs[i];
if (event.text() == pair.firstString()) {
return pair.secondString();
}
if (event == Ion::Events::XNT) {
return "x";
for (size_t i=0; i<sizeof(sEventTextMap)/sizeof(sEventTextMap[0]); i++) {
if (event == sEventTextMap[i].event()) {
return sEventTextMap[i].text();
}
}
return nullptr;
}
}
}

View File

@@ -440,7 +440,9 @@ void PythonTextArea::addAutocompletion() {
const int scriptIndex = m_contentView.pythonDelegate()->menuController()->editedScriptIndex();
m_contentView.pythonDelegate()->variableBoxController()->loadFunctionsAndVariables(scriptIndex, autocompletionTokenBeginning, autocompletionLocation - autocompletionTokenBeginning);
addAutocompletionTextAtIndex(0);
if (addAutocompletionTextAtIndex(0)) {
m_contentView.setAutocompleting(true);
}
}
bool PythonTextArea::addAutocompletionTextAtIndex(int nextIndex, int * currentIndexToUpdate) {
@@ -465,7 +467,6 @@ bool PythonTextArea::addAutocompletionTextAtIndex(int nextIndex, int * currentIn
return false;
}
autocompletionLocation += textToInsertLength;
m_contentView.setAutocompleting(true);
m_contentView.setAutocompletionEnd(autocompletionLocation);
}
@@ -478,9 +479,8 @@ bool PythonTextArea::addAutocompletionTextAtIndex(int nextIndex, int * currentIn
if (addParentheses && m_contentView.insertTextAtLocation(parentheses, const_cast<char *>(autocompletionLocation), parenthesesLength)) {
m_contentView.setAutocompleting(true);
m_contentView.setAutocompletionEnd(autocompletionLocation + parenthesesLength);
return true;
}
return (textToInsertLength > 0);
return true;
}
void PythonTextArea::cycleAutocompletion(bool downwards) {

View File

@@ -5,7 +5,6 @@ extern "C" {
#include <string.h>
#include <ctype.h>
}
#include "app.h"
namespace Code {
@@ -132,7 +131,7 @@ const ToolboxMessageTree MatplotlibPyplotModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorPink, I18n::Message::PythonColorPink, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorOrange, I18n::Message::PythonColorOrange, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorPurple, I18n::Message::PythonColorPurple, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorGray, I18n::Message::PythonColorGray, false)
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorGrey, I18n::Message::PythonColorGrey, false)
};
const ToolboxMessageTree TurtleModuleChildren[] = {
@@ -169,7 +168,7 @@ const ToolboxMessageTree TurtleModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorPink, I18n::Message::PythonColorPink, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorOrange, I18n::Message::PythonColorOrange, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorPurple, I18n::Message::PythonColorPurple, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorGray, I18n::Message::PythonColorGray, false)
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorGrey, I18n::Message::PythonColorGrey, false)
};
const ToolboxMessageTree RandomModuleChildren[] = {
@@ -193,7 +192,6 @@ const ToolboxMessageTree KandinskyModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandSetPixel, I18n::Message::PythonSetPixel),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColor, I18n::Message::PythonColor),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDrawString, I18n::Message::PythonDrawString),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDrawLine, I18n::Message::PythonDrawLine),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFillRect, I18n::Message::PythonFillRect)
};
@@ -202,7 +200,52 @@ const ToolboxMessageTree IonModuleChildren[] = {
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::IonSelector, I18n::Message::IonSelector)
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyLeft, I18n::Message::PythonKeyLeft, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyUp, I18n::Message::PythonKeyUp, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyDown, I18n::Message::PythonKeyDown, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyRight, I18n::Message::PythonKeyRight, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyOk, I18n::Message::PythonKeyOk, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyBack, I18n::Message::PythonKeyBack, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyHome, I18n::Message::PythonKeyHome, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyOnOff, I18n::Message::PythonKeyOnOff, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyShift, I18n::Message::PythonKeyShift, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyAlpha, I18n::Message::PythonKeyAlpha, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyXnt, I18n::Message::PythonKeyXnt, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyVar, I18n::Message::PythonKeyVar, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyToolbox, I18n::Message::PythonKeyToolbox, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyBackspace, I18n::Message::PythonKeyBackspace, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyExp, I18n::Message::PythonKeyExp, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyLn, I18n::Message::PythonKeyLn, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyLog, I18n::Message::PythonKeyLog, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyImaginary, I18n::Message::PythonKeyImaginary, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyComma, I18n::Message::PythonKeyComma, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyPower, I18n::Message::PythonKeyPower, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeySine, I18n::Message::PythonKeySine, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyCosine, I18n::Message::PythonKeyCosine, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyTangent, I18n::Message::PythonKeyTangent, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyPi, I18n::Message::PythonKeyPi, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeySqrt, I18n::Message::PythonKeySqrt, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeySquare, I18n::Message::PythonKeySquare, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeySeven, I18n::Message::PythonKeySeven, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyEight, I18n::Message::PythonKeyEight, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyNine, I18n::Message::PythonKeyNine, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyLeftParenthesis, I18n::Message::PythonKeyLeftParenthesis, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyRightParenthesis, I18n::Message::PythonKeyRightParenthesis, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyFour, I18n::Message::PythonKeyFour, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyFive, I18n::Message::PythonKeyFive, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeySix, I18n::Message::PythonKeySix, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyMultiplication, I18n::Message::PythonKeyMultiplication, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyDivision, I18n::Message::PythonKeyDivision, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyOne, I18n::Message::PythonKeyOne, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyTwo, I18n::Message::PythonKeyTwo, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyThree, I18n::Message::PythonKeyThree, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyPlus, I18n::Message::PythonKeyPlus, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyMinus, I18n::Message::PythonKeyMinus, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyZero, I18n::Message::PythonKeyZero, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyDot, I18n::Message::PythonKeyDot, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyEe, I18n::Message::PythonKeyEe, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyAns, I18n::Message::PythonKeyAns, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyExe, I18n::Message::PythonKeyExe, false)
};
const ToolboxMessageTree TimeModuleChildren[] = {
@@ -217,7 +260,6 @@ const ToolboxMessageTree OsModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportOs, I18n::Message::PythonImportOs, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportFromOs, I18n::Message::PythonImportOs, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonOsCommandUname, I18n::Message::PythonOsUname, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonOsCommandGetlogin, I18n::Message::PythonOsGetlogin, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonOsCommandRemove, I18n::Message::PythonOsRemove, false, I18n::Message::PythonOsCommandRemoveWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonOsCommandRename, I18n::Message::PythonOsRename, false, I18n::Message::PythonOsCommandRenameWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonOsCommandListdir, I18n::Message::PythonOsListdir, false)
@@ -273,7 +315,6 @@ const ToolboxMessageTree catalogChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCosh, I18n::Message::PythonCosh),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDegrees, I18n::Message::PythonDegrees),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDivMod, I18n::Message::PythonDivMod),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDrawLine, I18n::Message::PythonDrawLine),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDrawString, I18n::Message::PythonDrawString),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandConstantE, I18n::Message::PythonConstantE, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandErf, I18n::Message::PythonErf),
@@ -300,8 +341,8 @@ const ToolboxMessageTree catalogChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandGetPixel, I18n::Message::PythonGetPixel),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandGetrandbits, I18n::Message::PythonGetrandbits),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandGoto, I18n::Message::PythonTurtleGoto),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorGray, I18n::Message::PythonColorGray, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorGreen, I18n::Message::PythonColorGreen, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColorGrey, I18n::Message::PythonColorGrey, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandGrid, I18n::Message::PythonGrid),
ToolboxMessageTree::Leaf(I18n::Message::PythonTurtleCommandHeading, I18n::Message::PythonTurtleHeading, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandHex, I18n::Message::PythonHex),
@@ -495,11 +536,6 @@ KDCoordinate PythonToolbox::rowHeight(int j) {
bool PythonToolbox::selectLeaf(int selectedRow) {
m_selectableTableView.deselectTable();
ToolboxMessageTree * node = (ToolboxMessageTree *)m_messageTreeModel->childAtIndex(selectedRow);
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];

View File

@@ -5,7 +5,6 @@
#include <escher.h>
#include <ion/events.h>
#include <kandinsky/font.h>
#include "toolbox_ion_keys.h"
namespace Code {
@@ -33,7 +32,6 @@ private:
void scrollToAndSelectChild(int i);
MessageTableCellWithMessage m_leafCells[k_maxNumberOfDisplayedRows];
MessageTableCellWithChevron m_nodeCells[k_maxNumberOfDisplayedRows];
toolboxIonKeys m_ionKeys;
};
}

View File

@@ -49,7 +49,6 @@ public:
bool autoImportationStatus() const;
void toggleAutoimportationStatus();
const char * content() const;
size_t contentSize() { return value().size - k_statusSize; }
/* Fetched status */
bool fetchedFromConsole() const;

View File

@@ -13,7 +13,7 @@ void ScriptNodeCell::ScriptNodeView::drawRect(KDContext * ctx, KDRect rect) cons
// If it exists, draw the description name.
const char * descriptionName = m_scriptNode->description();
if (descriptionName != nullptr) {
ctx->drawString(descriptionName, KDPoint(0, m_frame.height() - k_bottomMargin - k_font->glyphSize().height()), k_font, Palette::GrayDark, backgroundColor);
ctx->drawString(descriptionName, KDPoint(0, m_frame.height() - k_bottomMargin - k_font->glyphSize().height()), k_font, Palette::GreyDark, backgroundColor);
}
// Draw the node name

View File

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

View File

@@ -1,6 +1,6 @@
Functions = "Funzioni"
Catalog = "Catalogo"
Modules = "Moduli"
LoopsAndTests = "Cicli e test"
LoopsAndTests = "Loops e test"
Files = "Files"
Exceptions = "Exceptions"

View File

@@ -1,6 +1,6 @@
Functions = "Functies"
Catalog = "Catalogus"
Modules = "Modules"
LoopsAndTests = "Herhalingen en testen"
LoopsAndTests = "Loops and tests"
Files = "Files"
Exceptions = "Exceptions"

View File

@@ -57,5 +57,3 @@ PythonCommandDef = "def \x11():\n "
PythonCommandDefWithArg = "def function(x):"
PythonCommandReturn = "return "
RandomModule = "random"
IonSelector = "Key selector"
PressAKey = "Press a key"

View File

@@ -1,50 +0,0 @@
#include "toolbox_ion_keys.h"
#include <apps/apps_container.h>
#include <assert.h>
#include <ion.h>
extern "C" {
#include <py/obj.h>
#include <py/objfun.h>
}
extern const mp_rom_map_elem_t modion_module_globals_table[48];
namespace Code {
toolboxIonKeys::toolboxIonKeys() :
ViewController(nullptr),
m_view()
{
}
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;
}
toolboxIonKeys::toolboxIonView::toolboxIonView():
View()
{
}
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));
}
View * toolboxIonKeys::view(){
return &m_view;
}
}

View File

@@ -1,21 +0,0 @@
#include <escher.h>
namespace Code {
class toolboxIonKeys : public ViewController {
public :
toolboxIonKeys();
View * view() override;
bool handleEvent(Ion::Events::Event e) override;
void setSender(InputEventHandler * sender) { m_sender = sender; }
private :
class toolboxIonView : public View {
public :
toolboxIonView();
void drawRect(KDContext * ctx, KDRect rect) const override;
};
toolboxIonView m_view;
InputEventHandler * m_sender;
};
}

View File

@@ -45,7 +45,7 @@ VariableBoxController::VariableBoxController(ScriptStore * scriptStore) :
{
for (int i = 0; i < k_scriptOriginsCount; i++) {
m_subtitleCells[i].setBackgroundColor(Palette::WallScreen);
m_subtitleCells[i].setTextColor(Palette::SecondaryText);
m_subtitleCells[i].setTextColor(Palette::BlueishGrey);
}
}

View File

@@ -1,11 +0,0 @@
CountryCode,CountryPreferences::AvailableExamModes,CountryPreferences::MethodForQuartiles,Poincare::Preferences::UnitFormat,CountryPreferences::HomeAppsLayout
WW,StandardOnly,MedianOfSublist,Metric,Default
CA,StandardOnly,MedianOfSublist,Metric,Default
DE,StandardOnly,MedianOfSublist,Metric,Default
ES,StandardOnly,MedianOfSublist,Metric,Default
FR,StandardOnly,CumulatedFrequency,Metric,Default
GB,StandardOnly,MedianOfSublist,Metric,Default
IT,StandardOnly,CumulatedFrequency,Metric,Default
NL,All,MedianOfSublist,Metric,Default
PT,StandardOnly,MedianOfSublist,Metric,Default
US,StandardOnly,MedianOfSublist,Imperial,HidePython
1 CountryCode CountryPreferences::AvailableExamModes CountryPreferences::MethodForQuartiles Poincare::Preferences::UnitFormat CountryPreferences::HomeAppsLayout
2 WW StandardOnly MedianOfSublist Metric Default
3 CA StandardOnly MedianOfSublist Metric Default
4 DE StandardOnly MedianOfSublist Metric Default
5 ES StandardOnly MedianOfSublist Metric Default
6 FR StandardOnly CumulatedFrequency Metric Default
7 GB StandardOnly MedianOfSublist Metric Default
8 IT StandardOnly CumulatedFrequency Metric Default
9 NL All MedianOfSublist Metric Default
10 PT StandardOnly MedianOfSublist Metric Default
11 US StandardOnly MedianOfSublist Imperial HidePython

View File

@@ -1,42 +0,0 @@
#ifndef COUNTRY_PREFERENCES_H
#define COUNTRY_PREFERENCES_H
#include <poincare/preferences.h>
class CountryPreferences {
public:
enum class AvailableExamModes : uint8_t {
StandardOnly,
All
};
enum class MethodForQuartiles : uint8_t {
MedianOfSublist,
CumulatedFrequency
};
enum class HomeAppsLayout : uint8_t {
Default,
HidePython,
};
constexpr CountryPreferences(AvailableExamModes availableExamModes, MethodForQuartiles methodForQuartiles, Poincare::Preferences::UnitFormat unitFormat, HomeAppsLayout homeAppsLayout) :
m_availableExamModes(availableExamModes),
m_methodForQuartiles(methodForQuartiles),
m_unitFormat(unitFormat),
m_homeAppsLayout(homeAppsLayout)
{}
constexpr AvailableExamModes availableExamModes() const { return m_availableExamModes; }
constexpr MethodForQuartiles methodForQuartiles() const { return m_methodForQuartiles; }
constexpr Poincare::Preferences::UnitFormat unitFormat() const { return m_unitFormat; }
constexpr HomeAppsLayout homeAppsLayout() const { return m_homeAppsLayout; }
private:
const AvailableExamModes m_availableExamModes;
const MethodForQuartiles m_methodForQuartiles;
const Poincare::Preferences::UnitFormat m_unitFormat;
const HomeAppsLayout m_homeAppsLayout;
};
#endif

View File

@@ -41,4 +41,4 @@ bool ExamModeConfiguration::appIsForbiddenInExamMode(App::Descriptor::Examinatio
bool ExamModeConfiguration::exactExpressionsAreForbidden(GlobalPreferences::ExamMode mode) {
return mode == GlobalPreferences::ExamMode::NoSymNoText ? true : false;
}
}

View File

@@ -1,32 +1,16 @@
#include "exam_pop_up_controller.h"
#include "apps_container.h"
#include "exam_mode_configuration.h"
#include <apps/i18n.h>
#include "global_preferences.h"
#include <assert.h>
#include <poincare/preferences.h>
using namespace Poincare;
ExamPopUpController::ExamPopUpController(ExamPopUpControllerDelegate * delegate) :
PopUpController(
k_numberOfLines,
Invocation(
[](void * context, void * sender) {
ExamPopUpController * controller = (ExamPopUpController *)context;
GlobalPreferences::ExamMode mode = controller->targetExamMode();
assert(mode != GlobalPreferences::ExamMode::Unknown);
GlobalPreferences::sharedGlobalPreferences()->setExamMode(mode);
AppsContainer * container = AppsContainer::sharedAppsContainer();
if (mode == GlobalPreferences::ExamMode::Off) {
Ion::LED::setColor(KDColorBlack);
Ion::LED::updateColorWithPlugAndCharge();
} else {
container->activateExamMode(mode);
}
container->refreshPreferences();
Container::activeApp()->dismissModalViewController();
return true;
}, this)
),
ViewController(nullptr),
m_contentView(this),
m_targetExamMode(GlobalPreferences::ExamMode::Unknown),
m_delegate(delegate)
{
@@ -34,9 +18,11 @@ ExamPopUpController::ExamPopUpController(ExamPopUpControllerDelegate * delegate)
void ExamPopUpController::setTargetExamMode(GlobalPreferences::ExamMode mode) {
m_targetExamMode = mode;
for (int i = 0; i < k_numberOfLines; i++) {
m_contentView.setMessage(i, ExamModeConfiguration::examModeActivationWarningMessage(mode, i));
}
m_contentView.setMessagesForExamMode(mode);
}
View * ExamPopUpController::view() {
return &m_contentView;
}
void ExamPopUpController::viewDidDisappear() {
@@ -44,3 +30,103 @@ void ExamPopUpController::viewDidDisappear() {
m_delegate->examDeactivatingPopUpIsDismissed();
}
}
void ExamPopUpController::didBecomeFirstResponder() {
m_contentView.setSelectedButton(0);
}
bool ExamPopUpController::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::Left && m_contentView.selectedButton() == 1) {
m_contentView.setSelectedButton(0);
return true;
}
if (event == Ion::Events::Right && m_contentView.selectedButton() == 0) {
m_contentView.setSelectedButton(1);
return true;
}
return false;
}
ExamPopUpController::ContentView::ContentView(Responder * parentResponder) :
m_cancelButton(parentResponder, I18n::Message::Cancel, Invocation([](void * context, void * sender) {
Container::activeApp()->dismissModalViewController();
return true;
}, parentResponder), KDFont::SmallFont),
m_okButton(parentResponder, I18n::Message::Ok, Invocation([](void * context, void * sender) {
ExamPopUpController * controller = (ExamPopUpController *)context;
GlobalPreferences::ExamMode mode = controller->targetExamMode();
assert(mode != GlobalPreferences::ExamMode::Unknown);
GlobalPreferences::sharedGlobalPreferences()->setExamMode(mode);
AppsContainer * container = AppsContainer::sharedAppsContainer();
if (mode == GlobalPreferences::ExamMode::Off) {
Ion::LED::setColor(KDColorBlack);
Ion::LED::updateColorWithPlugAndCharge();
} else {
container->activateExamMode(mode);
}
container->refreshPreferences();
Container::activeApp()->dismissModalViewController();
return true;
}, parentResponder), KDFont::SmallFont),
m_warningTextView(KDFont::SmallFont, I18n::Message::Warning, 0.5, 0.5, KDColorWhite, KDColorBlack),
m_messageTextViews{}
{
for (int i = 0; i < k_maxNumberOfLines; i++) {
m_messageTextViews[i].setFont(KDFont::SmallFont);
m_messageTextViews[i].setAlignment(0.5f, 0.5f);
m_messageTextViews[i].setBackgroundColor(KDColorBlack);
m_messageTextViews[i].setTextColor(KDColorWhite);
}
}
void ExamPopUpController::ContentView::drawRect(KDContext * ctx, KDRect rect) const {
ctx->fillRect(bounds(), KDColorBlack);
}
void ExamPopUpController::ContentView::setSelectedButton(int selectedButton) {
m_cancelButton.setHighlighted(selectedButton == 0);
m_okButton.setHighlighted(selectedButton == 1);
Container::activeApp()->setFirstResponder(selectedButton == 0 ? &m_cancelButton : &m_okButton);
}
int ExamPopUpController::ContentView::selectedButton() {
if (m_cancelButton.isHighlighted()) {
return 0;
}
return 1;
}
void ExamPopUpController::ContentView::setMessagesForExamMode(GlobalPreferences::ExamMode mode) {
for (int i = 0; i < k_maxNumberOfLines; i++) {
m_messageTextViews[i].setMessage(ExamModeConfiguration::examModeActivationWarningMessage(mode, i));
}
}
int ExamPopUpController::ContentView::numberOfSubviews() const {
return 6;
}
View * ExamPopUpController::ContentView::subviewAtIndex(int index) {
switch (index) {
case 0:
return &m_warningTextView;
case 4:
return &m_cancelButton;
case 5:
return &m_okButton;
default:
return &m_messageTextViews[index-1];
}
}
void ExamPopUpController::ContentView::layoutSubviews(bool force) {
KDCoordinate height = bounds().height();
KDCoordinate width = bounds().width();
KDCoordinate textHeight = KDFont::SmallFont->glyphSize().height();
m_warningTextView.setFrame(KDRect(0, k_topMargin, width, textHeight), force);
for (int i = 0; i < k_maxNumberOfLines; i++) {
m_messageTextViews[i].setFrame(KDRect(0, k_topMargin+k_paragraphHeight+(i+1)*textHeight, width, textHeight), force);
}
m_cancelButton.setFrame(KDRect(k_buttonMargin, height-k_buttonMargin-k_buttonHeight, (width-3*k_buttonMargin)/2, k_buttonHeight), force);
m_okButton.setFrame(KDRect(2*k_buttonMargin+(width-3*k_buttonMargin)/2, height-k_buttonMargin-k_buttonHeight, (width-3*k_buttonMargin)/2, k_buttonHeight), force);
}

View File

@@ -1,20 +1,53 @@
#ifndef APPS_EXAM_POP_UP_CONTROLLER_H
#define APPS_EXAM_POP_UP_CONTROLLER_H
#include <escher/pop_up_controller.h>
#include <escher.h>
#include "exam_pop_up_controller_delegate.h"
#include "global_preferences.h"
class ExamPopUpController : public PopUpController {
class HighContrastButton : public Button {
public:
using Button::Button;
KDColor highlightedBackgroundColor() const override { return Palette::ButtonBackgroundSelectedHighContrast; }
};
class ExamPopUpController : public ViewController {
public:
ExamPopUpController(ExamPopUpControllerDelegate * delegate);
void setTargetExamMode(GlobalPreferences::ExamMode mode);
GlobalPreferences::ExamMode targetExamMode() const { return m_targetExamMode; }
// View Controller
View * view() override;
void viewDidDisappear() override;
// Responder
void didBecomeFirstResponder() override;
bool handleEvent(Ion::Events::Event event) override;
private:
constexpr static int k_numberOfLines = 3;
class ContentView : public View {
public:
ContentView(Responder * parentResponder);
void drawRect(KDContext * ctx, KDRect rect) const override;
void setSelectedButton(int selectedButton);
int selectedButton();
void setMessagesForExamMode(GlobalPreferences::ExamMode mode);
private:
constexpr static KDCoordinate k_buttonMargin = 10;
constexpr static KDCoordinate k_buttonHeight = 20;
constexpr static KDCoordinate k_topMargin = 12;
constexpr static KDCoordinate k_paragraphHeight = 20;
int numberOfSubviews() const override;
View * subviewAtIndex(int index) override;
void layoutSubviews(bool force = false) override;
HighContrastButton m_cancelButton;
HighContrastButton m_okButton;
MessageTextView m_warningTextView;
constexpr static int k_maxNumberOfLines = 3;
MessageTextView m_messageTextViews[k_maxNumberOfLines];
};
ContentView m_contentView;
GlobalPreferences::ExamMode m_targetExamMode;
ExamPopUpControllerDelegate * m_delegate;
};
#endif

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 = 100000;
static constexpr int k_externalHeapSize = 80000;
char m_externalHeap[k_externalHeapSize];
};

View File

@@ -55,43 +55,29 @@ bool fileAtIndex(size_t index, File &entry) {
* TAR files are comprised of a set of records aligned to 512 bytes boundary
* followed by data.
*/
for(;;) {
// Calculate the size
while (index-- > 0) {
size = 0;
for (int i = 0; i < 11; i++)
size = size * 8 + (tar->size[i] - '0');
// Check if we found our file.
if (index == 0) {
// If yes, check for sanity and for exam mode stuff
if (!isSane(tar) || isExamModeAndFileNotExecutable(tar)) {
return false;
}
// File entry found, copy data out.
entry.name = tar->name;
entry.data = reinterpret_cast<const uint8_t*>(tar) + sizeof(TarHeader);
entry.dataLength = size;
entry.isExecutable = (tar->mode[4] & 0x01) == 1;
// Move to the next TAR header.
unsigned stride = (sizeof(TarHeader) + size + 511);
stride = (stride >> 9) << 9;
tar = reinterpret_cast<const TarHeader*>(reinterpret_cast<const char*>(tar) + stride);
return true;
} else {
// move to the next TAR header.
unsigned stride = (sizeof(TarHeader) + size + 511);
stride = (stride >> 9) << 9;
tar = reinterpret_cast<const TarHeader*>(reinterpret_cast<const char*>(tar) + stride);
// Sanity check.
if (!isSane(tar)) {
return false;
}
// Sanity check.
if (!isSane(tar) || isExamModeAndFileNotExecutable(tar)) {
return false;
}
index--;
}
// Achievement unlock: How did we get there ?
return false;
// File entry found, copy data out.
entry.name = tar->name;
entry.data = reinterpret_cast<const uint8_t*>(tar) + sizeof(TarHeader);
entry.dataLength = size;
entry.isExecutable = (tar->mode[4] & 0x01) == 1;
return true;
}
extern "C" void (* const apiPointers[])(void);

View File

@@ -1,9 +1,9 @@
ExternalApp = "External"
ExternalAppCapital = "EXTERNAL"
ExternalAppApiMismatch = "API stimmt nicht überein"
ExternalAppExecError = "Datei kann nicht ausgeführt werden"
ExternalNotCompatible = "Externe App ist nicht kompatibel"
ExternalAppApiMismatch = "API mismatch"
ExternalAppExecError = "Cannot execute file"
ExternalNotCompatible = "External ist nicht kompatibel"
WithSimulator = "mit dem Simulator"
WithN0100 = "mit N0100"
GetMoreAppsAt = "Weitere Apps abrufen bei"
NoAppsInstalled = "Keine Apps installiert"
WithN0100 = "mit n0100"
GetMoreAppsAt = "Weitere Apps erhalten Sie auf"
NoAppsInstalled = "Keine Apps installiert"

View File

@@ -1,7 +1,7 @@
ExternalApp = "External"
ExternalAppCapital = "EXTERNAL"
ExternalAppApiMismatch = "Discordancia de API"
ExternalAppExecError = "No se puede ejecutar el archivo"
ExternalAppApiMismatch = "API mismatch"
ExternalAppExecError = "Cannot execute file"
ExternalNotCompatible = "Externo no es compatible"
WithSimulator = "con el simulador"
WithN0100 = "con n0100"

View File

@@ -1,7 +1,7 @@
ExternalApp = "External"
ExternalAppCapital = "EXTERNAL"
ExternalAppApiMismatch = "Décalage API"
ExternalAppExecError = "Le fichier ne peut pas être exécuté"
ExternalAppApiMismatch = "API mismatch"
ExternalAppExecError = "Cannot execute file"
ExternalNotCompatible = "External n'est pas compatible"
WithSimulator = "avec le simulateur"
WithN0100 = "avec n0100"

View File

@@ -1,9 +1,9 @@
ExternalApp = "Külsö"
ExternalAppCapital = "KÜLSÖ"
ExternalAppCapital = "KÜLSö"
ExternalAppApiMismatch = "API eltérés"
ExternalAppExecError = "A fájl nem futtatható"
ExternalNotCompatible = "Externál nem kompatibilis"
ExternalNotCompatible = "Ez az alkalmazás nem kompatibilis a "
WithSimulator = "Szimulátorral"
WithN0100 = "n0100-al"
GetMoreAppsAt = "Mégtöbb alkalmazás itt :"
NoAppsInstalled = "Nincs letöltött externál"
WithN0100 = "a n0100-el"
GetMoreAppsAt = "Mégtöbb alkalmazás a"
NoAppsInstalled = "Nincs letöltött alkalmazás"

View File

@@ -16,12 +16,6 @@ public:
static GlobalPreferences * sharedGlobalPreferences();
I18n::Language language() const { return m_language; }
void setLanguage(I18n::Language language) { m_language = language; }
I18n::Country country() const { return m_country; }
void setCountry(I18n::Country country) { m_country = country; }
CountryPreferences::AvailableExamModes availableExamModes() const { return I18n::CountryPreferencesArray[static_cast<uint8_t>(m_country)].availableExamModes(); }
CountryPreferences::MethodForQuartiles methodForQuartiles() const { return I18n::CountryPreferencesArray[static_cast<uint8_t>(m_country)].methodForQuartiles(); }
Poincare::Preferences::UnitFormat unitFormat() const { return I18n::CountryPreferencesArray[static_cast<uint8_t>(m_country)].unitFormat(); }
CountryPreferences::HomeAppsLayout homeAppsLayout() const { return I18n::CountryPreferencesArray[static_cast<uint8_t>(m_country)].homeAppsLayout(); }
bool isInExamMode() const { return (int8_t)examMode() > 0; }
bool isInExamModeSymbolic() const { return !((int8_t)examMode() > 1); }
ExamMode examMode() const;
@@ -36,18 +30,15 @@ public:
void setFont(const KDFont * font) { m_font = font; }
constexpr static int NumberOfBrightnessStates = 15;
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
static_assert(I18n::NumberOfLanguages > 0, "I18n::NumberOfLanguages is not superior to 0"); // There should already have be an error when processing an empty EPSILON_I18N flag
GlobalPreferences() :
m_language((I18n::Language)0),
m_country((I18n::Country)0),
m_examMode(ExamMode::Unknown),
m_tempExamMode(ExamMode::Standard),
m_showPopUp(true),
m_brightnessLevel(Ion::Backlight::MaxBrightness),
m_font(KDFont::LargeFont) {}
I18n::Language m_language;
I18n::Country m_country;
static_assert((int8_t)GlobalPreferences::ExamMode::Off == 0, "GlobalPreferences::isInExamMode() is not right");
static_assert((int8_t)GlobalPreferences::ExamMode::Unknown < 0, "GlobalPreferences::isInExamMode() is not right");
mutable ExamMode m_examMode;

View File

@@ -1,12 +1,9 @@
apps += Graph::App
app_headers += apps/graph/app.h
app_graph_test_src = $(addprefix apps/graph/,\
continuous_function_store.cpp \
)
app_graph_src = $(addprefix apps/graph/,\
app.cpp \
continuous_function_store.cpp \
graph/banner_view.cpp \
graph/calculation_graph_controller.cpp \
graph/calculation_parameter_controller.cpp \
@@ -34,15 +31,8 @@ app_graph_src = $(addprefix apps/graph/,\
values/values_controller.cpp \
)
app_graph_src += $(app_graph_test_src)
apps_src += $(app_graph_src)
i18n_files += $(call i18n_without_universal_for,graph/base)
tests_src += $(addprefix apps/graph/test/,\
caching.cpp \
helper.cpp \
ranges.cpp \
)
$(eval $(call depends_on_image,apps/graph/app.cpp,apps/graph/graph_icon.png))

View File

@@ -55,10 +55,10 @@ void App::Snapshot::tidy() {
App::App(Snapshot * snapshot) :
FunctionApp(snapshot, &m_inputViewController),
m_listController(&m_listFooter, &m_listHeader, &m_listFooter, this),
m_listFooter(&m_listHeader, &m_listController, &m_listController, ButtonRowController::Position::Bottom, ButtonRowController::Style::EmbossedGray),
m_listFooter(&m_listHeader, &m_listController, &m_listController, ButtonRowController::Position::Bottom, ButtonRowController::Style::EmbossedGrey),
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),
m_graphController(&m_graphAlternateEmptyViewController, this, snapshot->graphRange(), snapshot->cursor(), snapshot->indexFunctionSelectedByCursor(), snapshot->modelVersion(), snapshot->previousModelsVersions(), snapshot->rangeVersion(), snapshot->angleUnitVersion(), &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

@@ -29,5 +29,5 @@ NoIntersectionFound = "Kein Schnittpunkt gefunden"
NoPreimageFound = "Kein Urbild gefunden"
DerivativeFunctionColumn = "Spalte der Ableitungsfunktion"
HideDerivativeColumn = "Ableitungsfunktion ausblenden"
AllowedCharactersAZaz09 = "Erlaubt: A..Z, a..z, 0..9, _"
AllowedCharactersAZaz09 = "Erlaubte Zeichen: A..Z, a..z, 0..9, _"
ReservedName = "Reserviertes Wort"

View File

@@ -13,21 +13,21 @@ IntervalX = "x intervallum"
FunctionDomain = "Tervtartomány"
FunctionColor = "Funkció színe"
NoFunction = "Nincs funkció"
NoActivatedFunction = "Nincs használt funkció"
PlotOptions = "Görbe beállítások"
Compute = "Kiszámolás"
NoActivatedFunction = "Nincs bekapcsolt funkció"
PlotOptions = "Tervezési lehetöségek"
Compute = "Számítás"
Zeros = "Nullák"
Tangent = "Tangens"
Intersection = "Metszéspont"
Intersection = "Keresztezés"
Preimage = "Inverz kép"
SelectLowerBound = "Alsó határ kiválasztása"
SelectUpperBound = "Felsö határ kiválasztása"
NoMaximumFound = "Nem talált maximum-ot"
NoMinimumFound = "Nem talált minimum-ot"
NoZeroFound = "Nem talált nullát"
NoMaximumFound = "Nem található maximális érték"
NoMinimumFound = "Nem található minimum"
NoZeroFound = "Nem található nulla"
NoIntersectionFound = "Nem található keresztezödés"
NoPreimageFound = "Nem található inverz kép"
DerivativeFunctionColumn = "A derivált fügvény oszlopa"
HideDerivativeColumn = "A derivált függvény oszlop elrejtése"
AllowedCharactersAZaz09 = "Engedélyezett karakterek: A..Z, a..z, 0..9, _"
DerivativeFunctionColumn = "Származékosggvény oszlop"
HideDerivativeColumn = "A derivatív függvény elrejtése"
AllowedCharactersAZaz09 = "Engedélyezett karakterek: A-Z, a-z, 0-9, _"
ReservedName = "Fenntartott név"

View File

@@ -12,22 +12,22 @@ IntervalTheta = "θ interval"
IntervalX = "x interval"
FunctionDomain = "Plotbereik"
FunctionColor = "Functiekleur"
NoFunction = "Geen functie gedefinieerd"
NoActivatedFunction = "Geen functie ingeschakeld"
PlotOptions = "Plotopties"
NoFunction = "Geen functie"
NoActivatedFunction = "Geen functie is ingeschakelt"
PlotOptions = "Plot opties"
Compute = "Bereken"
Zeros = "Nulpunten"
Tangent = "Raaklijn"
Tangent = "Tangens"
Intersection = "Snijpunt"
Preimage = "Origineel"
Preimage = "Inverse beeld"
SelectLowerBound = "Selecteer ondergrens "
SelectUpperBound = "Selecteer bovengrens "
NoMaximumFound = "Geen maximum gevonden"
NoMinimumFound = "Geen minimum gevonden"
NoZeroFound = "Geen nulpunt gevonden"
NoIntersectionFound = "Geen snijpunt gevonden"
NoPreimageFound = "Geen origineel gevonden"
NoPreimageFound = "Geen inverse beeld gevonden"
DerivativeFunctionColumn = "Afgeleide functie kolom"
HideDerivativeColumn = "Verberg de afgeleide functie"
AllowedCharactersAZaz09 = "Toegestane tekens: A-Z, a-z, 0-9, _"
ReservedName = "Gereserveerde naam"
ReservedName = "Voorbehouden naam"

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