mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
Merge branch 'omega-dev' into DrawStringFont
This commit is contained in:
23
.github/ISSUE_TEMPLATE/bug_report.md
vendored
23
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,25 +1,14 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Epsilon is not working like it should? Let us know!
|
||||
labels: 'bug'
|
||||
about: Omega is not working like it should? Let us know!
|
||||
title: ''
|
||||
labels: Bug, Triage
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
#### Describe the bug
|
||||
A clear and concise description of what the bug is. Please describe a **single** bug per issue. Feel free to create multiple issues though!
|
||||
|
||||
#### Screenshots
|
||||
Please provide at least one screenshot of the issue happening. This is by far the best way to quickly show any issue! To attach a screenshot, just go to our [online simulator](https://www.numworks.com/simulator), navigate to reproduce your issue, and click the "screenshot" button. Then drag'n'drop the file here!
|
||||
|
||||
#### To Reproduce
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to the '...' app
|
||||
2. Type '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
#### Expected behavior
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
#### Environment
|
||||
- Epsilon version (Settings > About > Software version).
|
||||
- The platform(s) on which the problem happens: online simulator, actual device, etc...
|
||||
- Omega Version: {go to settings > about > Omega Version and type the version here}
|
||||
|
||||
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
blank_issues_enabled: false
|
||||
22
.github/ISSUE_TEMPLATE/feature_request.md
vendored
22
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,22 +1,10 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for an improvement of Epsilon
|
||||
labels: 'enhancement'
|
||||
about: Suggest an idea for an improvement of Omega
|
||||
title: ''
|
||||
labels: Feature, Triage
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
#### Problem you'd like to fix
|
||||
Is your feature request related to a problem? Please provide a clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
Please describe a **single** improvement per issue. Feel free to open multiple issues though!
|
||||
|
||||
#### Screenshots
|
||||
If possible, please attach a screenshot. You can go on our [online simulator](https://www.numworks.com/simulator), use the screenshot button, and drag'n'drop the file here.
|
||||
|
||||
#### Describe the solution you'd like
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
#### Describe alternatives you've considered
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
#### Additional context
|
||||
Add any other context or screenshots about the feature request here.
|
||||
#### What I want to see in the next version of Omega
|
||||
|
||||
10
.github/ISSUE_TEMPLATE/other.md
vendored
Normal file
10
.github/ISSUE_TEMPLATE/other.md
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: Other
|
||||
about: A question? A problem? ...
|
||||
title: ''
|
||||
labels: Triage
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
|
||||
19
.github/ISSUE_TEMPLATE/problems-during-installation.md
vendored
Normal file
19
.github/ISSUE_TEMPLATE/problems-during-installation.md
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
name: Problems during installation
|
||||
about: Need help to install Omega?
|
||||
title: ''
|
||||
labels: Installation issue, Triage
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
#### Describe the problem
|
||||
|
||||
|
||||
#### Logs
|
||||
```
|
||||
Copy/paste the logs here (If you have some)
|
||||
```
|
||||
|
||||
#### Environment
|
||||
- Omega Version: {go to settings > about > Omega Version and type the version here}
|
||||
12
.github/workflows/ci-docker.yml
vendored
Normal file
12
.github/workflows/ci-docker.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
name: Docker Image CI
|
||||
on: [pull_request, push]
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Build the Docker image
|
||||
run: docker build . --file docker/Dockerfile --tag omega:$(date +%s)
|
||||
112
.github/workflows/ci-workflow.yml
vendored
112
.github/workflows/ci-workflow.yml
vendored
@@ -1,6 +1,7 @@
|
||||
name: Continuous integration
|
||||
#on: [pull_request, push]
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
@@ -12,15 +13,43 @@ on:
|
||||
description: 'Run macOS tests'
|
||||
required: true
|
||||
default: 'no'
|
||||
trigger3DS:
|
||||
description: 'Run 3DS tests'
|
||||
required: true
|
||||
default: 'no'
|
||||
|
||||
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
|
||||
android:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
- run: make -j2 PLATFORM=simulator TARGET=android
|
||||
- run: make -j2 PLATFORM=simulator TARGET=android epsilon.official.apk
|
||||
- run: make -j2 PLATFORM=simulator TARGET=android test.apk
|
||||
- uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: epsilon-android.apk
|
||||
@@ -31,38 +60,63 @@ jobs:
|
||||
- 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
|
||||
- run: make -j2 MODEL=n0100 epsilon.dfu
|
||||
- run: make -j2 MODEL=n0100 epsilon.onboarding.dfu
|
||||
- run: make -j2 MODEL=n0100 epsilon.official.onboarding.dfu
|
||||
- run: make -j2 MODEL=n0100 epsilon.onboarding.update.dfu
|
||||
- run: make -j2 MODEL=n0100 epsilon.onboarding.beta.dfu
|
||||
- run: make -j2 MODEL=n0100 flasher.light.dfu
|
||||
- run: make -j2 MODEL=n0100 flasher.verbose.dfu
|
||||
- run: make -j2 MODEL=n0100 test.elf
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
- run: mkdir final-output
|
||||
- run: make -j2 MODEL=n0100 EPSILON_I18N=en output/release/device/n0100/epsilon.onboarding.two_binaries
|
||||
- run: mv output/release/device/n0100/epsilon.onboarding.internal.bin final-output/epsilon.onboarding.internal.en.bin
|
||||
- run: rm output/release/device/n0100/apps/i18n.o output/release/device/n0100/apps/i18n.cpp
|
||||
- run: make -j2 MODEL=n0100 EPSILON_I18N=fr output/release/device/n0100/epsilon.onboarding.two_binaries
|
||||
- run: mv output/release/device/n0100/epsilon.onboarding.internal.bin final-output/epsilon.onboarding.internal.fr.bin
|
||||
- run: rm output/release/device/n0100/apps/i18n.o output/release/device/n0100/apps/i18n.cpp
|
||||
- run: make -j2 MODEL=n0100 EPSILON_I18N=nl output/release/device/n0100/epsilon.onboarding.two_binaries
|
||||
- run: mv output/release/device/n0100/epsilon.onboarding.internal.bin final-output/epsilon.onboarding.internal.nl.bin
|
||||
- run: rm output/release/device/n0100/apps/i18n.o output/release/device/n0100/apps/i18n.cpp
|
||||
- run: make -j2 MODEL=n0100 EPSILON_I18N=pt output/release/device/n0100/epsilon.onboarding.two_binaries
|
||||
- run: mv output/release/device/n0100/epsilon.onboarding.internal.bin final-output/epsilon.onboarding.internal.pt.bin
|
||||
- run: rm output/release/device/n0100/apps/i18n.o output/release/device/n0100/apps/i18n.cpp
|
||||
- run: make -j2 MODEL=n0100 EPSILON_I18N=it output/release/device/n0100/epsilon.onboarding.two_binaries
|
||||
- run: mv output/release/device/n0100/epsilon.onboarding.internal.bin final-output/epsilon.onboarding.internal.it.bin
|
||||
- run: rm output/release/device/n0100/apps/i18n.o output/release/device/n0100/apps/i18n.cpp
|
||||
- run: make -j2 MODEL=n0100 EPSILON_I18N=de output/release/device/n0100/epsilon.onboarding.two_binaries
|
||||
- run: mv output/release/device/n0100/epsilon.onboarding.internal.bin final-output/epsilon.onboarding.internal.de.bin
|
||||
- run: rm output/release/device/n0100/apps/i18n.o output/release/device/n0100/apps/i18n.cpp
|
||||
- run: make -j2 MODEL=n0100 EPSILON_I18N=es output/release/device/n0100/epsilon.onboarding.two_binaries
|
||||
- run: mv output/release/device/n0100/epsilon.onboarding.internal.bin final-output/epsilon.onboarding.internal.es.bin
|
||||
- run: rm output/release/device/n0100/apps/i18n.o output/release/device/n0100/apps/i18n.cpp
|
||||
- run: make -j2 MODEL=n0100 EPSILON_I18N=hu output/release/device/n0100/epsilon.onboarding.two_binaries
|
||||
- run: mv output/release/device/n0100/epsilon.onboarding.internal.bin final-output/epsilon.onboarding.internal.hu.bin
|
||||
- run: rm output/release/device/n0100/apps/i18n.o output/release/device/n0100/apps/i18n.cpp
|
||||
- run: make -j2 MODEL=n0100 output/release/device/n0100/flasher.light.bin
|
||||
- run: mv output/release/device/n0100/flasher.light.bin final-output/flasher.light.bin
|
||||
- run: find final-output/ -type f -exec bash -c "shasum -a 256 -b {} > {}.sha256" \;
|
||||
- run: tar cvfz binpack-n0100.tgz final-output/*
|
||||
- uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: epsilon-n0100.dfu
|
||||
path: output/release/device/n0100/epsilon.dfu
|
||||
name: epsilon-binpack-n0100.tgz
|
||||
path: binpack-n0100.tgz
|
||||
n0110:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: sudo apt-get install build-essential imagemagick libfreetype6-dev libjpeg-dev libpng-dev pkg-config
|
||||
- uses: numworks/setup-arm-toolchain@2020-q2
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
- run: make -j2 epsilon.dfu
|
||||
- run: make -j2 epsilon.onboarding.dfu
|
||||
- run: make -j2 epsilon.official.onboarding.dfu
|
||||
- run: make -j2 epsilon.onboarding.update.dfu
|
||||
- run: make -j2 epsilon.onboarding.beta.dfu
|
||||
- run: make -j2 flasher.light.dfu
|
||||
- run: make -j2 flasher.verbose.dfu
|
||||
- run: make -j2 bench.ram.dfu
|
||||
- run: make -j2 bench.flash.dfu
|
||||
- run: make -j2 test.elf
|
||||
- run: make -j2 binpack
|
||||
- run: cp output/release/device/n0110/binpack-n0110-`git rev-parse HEAD | head -c 7`.tgz output/release/device/n0110/binpack-n0110.tgz
|
||||
- uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: epsilon-n0110.dfu
|
||||
path: output/release/device/n0110/epsilon.dfu
|
||||
name: epsilon-binpack-n0110.tgz
|
||||
path: output/release/device/n0110/binpack-n0110.tgz
|
||||
windows:
|
||||
runs-on: windows-latest
|
||||
defaults:
|
||||
@@ -71,11 +125,10 @@ jobs:
|
||||
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 epsilon.official.exe
|
||||
- run: make -j2 PLATFORM=simulator test.headless.exe
|
||||
- run: output/release/simulator/windows/test.headless.exe
|
||||
- uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: epsilon-windows.exe
|
||||
@@ -85,12 +138,11 @@ jobs:
|
||||
steps:
|
||||
- uses: numworks/setup-emscripten@v1
|
||||
with:
|
||||
sdk: 1.39.16-fastcomp
|
||||
sdk: latest-upstream
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
- run: make -j2 PLATFORM=simulator TARGET=web
|
||||
- run: make -j2 PLATFORM=simulator TARGET=web epsilon.official.zip
|
||||
- run: make -j2 PLATFORM=simulator TARGET=web test.headless.js
|
||||
- run: node output/release/simulator/web/test.headless.js
|
||||
- uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: epsilon-web.zip
|
||||
@@ -100,10 +152,9 @@ jobs:
|
||||
steps:
|
||||
- run: sudo apt-get install build-essential imagemagick libfreetype6-dev libjpeg-dev libpng-dev pkg-config
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
- run: make -j2 PLATFORM=simulator
|
||||
- run: make -j2 PLATFORM=simulator epsilon.official.bin
|
||||
- run: make -j2 PLATFORM=simulator test.headless.bin
|
||||
- run: output/release/simulator/linux/test.headless.bin
|
||||
- uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: epsilon-linux.bin
|
||||
@@ -114,10 +165,9 @@ jobs:
|
||||
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 epsilon.official.app
|
||||
- run: make -j2 PLATFORM=simulator ARCH=x86_64 test.headless.bin
|
||||
- run: output/release/simulator/macos/x86_64/test.headless.bin
|
||||
- uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: epsilon-macos.zip
|
||||
@@ -128,9 +178,9 @@ jobs:
|
||||
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 epsilon.official.ipa
|
||||
- run: make -j2 PLATFORM=simulator TARGET=ios EPSILON_TELEMETRY=0 test.ipa
|
||||
- run: make -j2 PLATFORM=simulator TARGET=ios EPSILON_TELEMETRY=0 APPLE_PLATFORM=ios-simulator
|
||||
- uses: actions/upload-artifact@master
|
||||
with:
|
||||
|
||||
@@ -12,6 +12,7 @@ jobs:
|
||||
- name: Checkout PR base
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
ref: ${{ github.event.pull_request.base.sha }}
|
||||
path: base
|
||||
- name: Build base
|
||||
@@ -19,17 +20,18 @@ jobs:
|
||||
- name: Checkout PR head
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
path: head
|
||||
- name: Build head
|
||||
run: make -j2 -C head epsilon.elf
|
||||
- name: Retrieve binary size analysis
|
||||
id: binary_size
|
||||
run: echo "::set-output name=table::$(python3 head/build/metrics/binary_size.py base/output/release/device/n0110/epsilon.elf head/output/release/device/n0110/epsilon.elf --labels Base Head --sections .text .rodata .bss .data --escape)"
|
||||
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: Add comment
|
||||
uses: actions/github-script@v3.0.0
|
||||
with:
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
github-token: ${{ secrets.OMEGA_ROBOT_TOKEN }}
|
||||
script: |
|
||||
await github.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
14
.github/workflows/unit-workflow.yml
vendored
Normal file
14
.github/workflows/unit-workflow.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
name: Unit tests
|
||||
on: [pull_request_target]
|
||||
|
||||
jobs:
|
||||
units:
|
||||
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
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
- run: make -j2 PLATFORM=simulator test.headless.bin
|
||||
- run: output/release/simulator/linux/test.headless.bin
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,3 +1,8 @@
|
||||
/output/
|
||||
/build/artifacts/
|
||||
build/device/**/*.pyc
|
||||
epsilon.elf
|
||||
epsilon.map
|
||||
.vscode
|
||||
.DS_Store
|
||||
.gradle
|
||||
|
||||
26
.gitlab-ci.yml
Normal file
26
.gitlab-ci.yml
Normal 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
|
||||
|
||||
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
[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
|
||||
76
CODE_OF_CONDUCT.md
Normal file
76
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at getomega.pro@gmail.com. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
63
Makefile
63
Makefile
@@ -5,17 +5,39 @@
|
||||
default:
|
||||
|
||||
include build/config.mak
|
||||
include build/pimp.mak
|
||||
include build/defaults.mak
|
||||
include build/platform.$(PLATFORM).mak
|
||||
include build/toolchain.$(TOOLCHAIN).mak
|
||||
include build/variants.mak
|
||||
include build/helpers.mk
|
||||
|
||||
ifeq (${MODEL}, n0110)
|
||||
apps_list = ${EPSILON_APPS}
|
||||
else
|
||||
apps_list = $(foreach i, ${EPSILON_APPS}, $(if $(filter external, $(i)),,$(i)))
|
||||
endif
|
||||
|
||||
ifdef FORCE_EXTERNAL
|
||||
apps_list = ${EPSILON_APPS}
|
||||
endif
|
||||
|
||||
ifdef HOME_DISPLAY_EXTERNALS
|
||||
ifneq ($(filter external,$(apps_list)),)
|
||||
SFLAGS += -DHOME_DISPLAY_EXTERNALS
|
||||
else
|
||||
$(warning HOME_DISPLAY_EXTERNALS is set but external isn't included, ignoring flag.)
|
||||
endif
|
||||
endif
|
||||
|
||||
.PHONY: info
|
||||
info:
|
||||
@echo "EPSILON_VERSION = $(EPSILON_VERSION)"
|
||||
@echo "EPSILON_APPS = $(EPSILON_APPS)"
|
||||
@echo "EPSILON_I18N = $(EPSILON_I18N)"
|
||||
@echo "THEME_NAME = $(THEME_NAME)"
|
||||
@echo "THEME_REPO = $(THEME_REPO)"
|
||||
@echo "BUILD_DIR = $(BUILD_DIR)"
|
||||
@echo "PLATFORM" = $(PLATFORM)
|
||||
@echo "DEBUG" = $(DEBUG)
|
||||
@echo "EPSILON_GETOPT" = $(EPSILON_GETOPT)
|
||||
@@ -46,6 +68,18 @@ help:
|
||||
@echo " make PLATFORM=simulator TARGET=macos"
|
||||
@echo " make PLATFORM=simulator TARGET=web"
|
||||
@echo " make PLATFORM=simulator TARGET=windows"
|
||||
@echo " make PLATFORM=simulator TARGET=3ds"
|
||||
|
||||
.PHONY: doc
|
||||
doc:
|
||||
@echo "DOXYGEN"
|
||||
@mkdir -p output/doc/
|
||||
$(Q) doxygen build/doc/Doxyfile
|
||||
|
||||
.PHONY: print-%
|
||||
print-%:
|
||||
@echo $* = $($*)
|
||||
@echo $*\'s origin is $(origin $*)
|
||||
|
||||
# Since we're building out-of-tree, we need to make sure the output directories
|
||||
# are created, otherwise the receipes will fail (e.g. gcc will fail to create
|
||||
@@ -86,6 +120,10 @@ include build/scenario/Makefile
|
||||
include quiz/Makefile # Quiz needs to be included at the end
|
||||
|
||||
all_src = $(apps_src) $(escher_src) $(ion_src) $(kandinsky_src) $(liba_src) $(libaxx_src) $(poincare_src) $(python_src) $(runner_src) $(ion_device_flasher_src) $(ion_device_bench_src) $(tests_src)
|
||||
# Make palette.h a dep for every source-file.
|
||||
# This ensures that the theming engine works correctly.
|
||||
$(call object_for,$(all_src)): $(BUILD_DIR)/escher/palette.h $(BUILD_DIR)/apps/i18n.h
|
||||
|
||||
all_objs = $(call object_for,$(all_src))
|
||||
.SECONDARY: $(all_objs)
|
||||
|
||||
@@ -109,6 +147,11 @@ clean:
|
||||
@echo "CLEAN"
|
||||
$(Q) rm -rf $(BUILD_DIR)
|
||||
|
||||
.PHONY: cleanall
|
||||
cleanall:
|
||||
@echo "CLEANALL"
|
||||
$(Q) rm -rf output
|
||||
|
||||
.PHONY: cowsay_%
|
||||
cowsay_%:
|
||||
@echo " -------"
|
||||
@@ -123,3 +166,23 @@ cowsay_%:
|
||||
.PHONY: clena
|
||||
clena: cowsay_CLENA clean
|
||||
|
||||
.PHONY: compile
|
||||
compile: output/$(BUILD_TYPE)/simulator/$(HOST)/epsilon.$(EXE)
|
||||
|
||||
.PHONY: cleanandcompile
|
||||
cleanandcompile:
|
||||
${MAKE} cleanall
|
||||
${MAKE} compile
|
||||
|
||||
.PHONY: start
|
||||
start:
|
||||
@echo "INFO Starting output/$(BUILD_TYPE)/simulator/$(HOST)/epsilon.$(EXE)"
|
||||
@$(Q) output/$(BUILD_TYPE)/simulator/$(HOST)/epsilon.$(EXE) -v
|
||||
|
||||
.PHONY: clean_run
|
||||
clean_run: cleanandcompile
|
||||
${MAKE} start
|
||||
|
||||
.PHONY: run
|
||||
run: compile
|
||||
${MAKE} start
|
||||
|
||||
177
README.fr.md
Normal file
177
README.fr.md
Normal file
@@ -0,0 +1,177 @@
|
||||
<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).
|
||||
173
README.md
173
README.md
@@ -1,21 +1,176 @@
|
||||
<img src="docs/epsilon.svg?sanitize=true" alt="NumWorks Epsilon logo" height="70" >
|
||||
<p align="center"><img src="https://github.com/Omega-Numworks/Omega-Design/blob/master/Banners/Omega-Banner-Dev-Branch.png?raw=true" /></p>
|
||||
|
||||
[](https://github.com/numworks/epsilon/actions?workflow=Continuous+integration)
|
||||
<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>
|
||||
|
||||
Epsilon is a high-performance graphing calculator operating system. It includes eight apps that cover the high school mathematics curriculum.
|
||||
> Vous ne comprenez pas l'anglais ? vous êtes francophone ? Regardez le [*LISEZ-MOI* français](./README.fr.md) !
|
||||
|
||||
You can try Epsilon straight from your browser in the [online simulator](https://www.numworks.com/simulator/).
|
||||
## About
|
||||
|
||||
## Diving in
|
||||
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).
|
||||
|
||||
We highly recommend you start by reading the [online documentation](https://www.numworks.com/resources/engineering/software/) for this project. You'll learn how to install the [SDK](https://www.numworks.com/resources/engineering/software/build/) and about the overall architecture of the Epsilon.
|
||||
### 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).
|
||||
|
||||
## Installation
|
||||
|
||||
### Automatic
|
||||
|
||||
You can install Omega automatically on our website [here](https://getomega.web.app/) in the "install" page.
|
||||
|
||||
<a href="https://getomega.web.app"><p align="center"><img alt="Omega Banner Discord" src="https://user-images.githubusercontent.com/12123721/86352956-e9000480-bc66-11ea-82b7-79fd7e56fa27.png" /></p></a>
|
||||
|
||||
### Manual
|
||||
|
||||
First of all, follow **step 1** [here](https://www.numworks.com/resources/engineering/software/build/). Then:
|
||||
|
||||
<details>
|
||||
<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 epsilon_flash
|
||||
```
|
||||
|
||||
Important: Don't forget the `--recursive` tag, because Omega relies on submodules.
|
||||
Also, you can change the number of processes that run in parallel during the build by changing the value of the `-j` flag.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Model 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="{Your name, max 15 characters}" -j4
|
||||
make epsilon_flash
|
||||
```
|
||||
|
||||
Important: Don't forget the `--recursive` tag, because Omega relies on submodules.
|
||||
Also, you can change the number of processes that run in parallel during the build by changing the value of the `-j` flag.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Bin files</b></summary>
|
||||
|
||||
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
|
||||
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: Don't forget the `--recursive` tag, because Omega relies on submodules.
|
||||
Also, you can change the number of processes that run in parallel during the build by changing the value of the `-j` flag.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Web simulator</b></summary>
|
||||
|
||||
First, install 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
|
||||
```
|
||||
|
||||
Then, compile 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="{Your name, max 15 characters}" -j4
|
||||
```
|
||||
|
||||
The simulator is now in `output/release/simulator/web/simulator.zip`
|
||||
|
||||
Important: Don't forget the `--recursive` tag, because Omega relies on submodules.
|
||||
Also, you can change the number of processes that run in parallel during the build by changing the value of the `-j` flag.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>3DS Simulator</b></summary>
|
||||
|
||||
You need devkitPro and devkitARM installed and in your path (instructions [here](https://devkitpro.org/wiki/Getting_Started))
|
||||
|
||||
```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>
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
If you need help, you can join our Discord server here : https://discord.gg/X2TWhh9
|
||||
|
||||
<a href="https://discord.gg/X2TWhh9"><p align="center"><img alt="Omega Banner Discord" src="https://user-images.githubusercontent.com/12123721/86287349-54ef5800-bbe8-11ea-80c1-34eb1f93eebd.png" /></p></a>
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
If you run into an issue, we would be very happy if you would file a bug on the [issue tracker](https://github.com/numworks/epsilon/issues).
|
||||
To contribute, please refer to the [Wiki](https://github.com/Omega-Numworks/Omega/wiki/Contributing)
|
||||
|
||||
We welcome contributions. For smaller changes just open a pull request straight away. For larger changes we recommend you open an issue first for discussion.
|
||||
## 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 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
|
||||
|
||||
Omega is a fork of Epsilon, a high-performance graphing calculator operating system. It includes eight apps that cover the high school mathematics curriculum.
|
||||
|
||||
You can try Epsilon straight from your browser in the [online simulator](https://www.numworks.com/simulator/).
|
||||
|
||||
## License
|
||||
|
||||
NumWorks Epsilon is released under a [CC BY-NC-SA License](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode). NumWorks is a registered trademark.
|
||||
NumWorks is a registered trademark of NumWorks SAS, 24 Rue Godot de Mauroy, 75009 Paris, France.
|
||||
Nintendo and Nintendo 3DS are registered trademarks of Nintendo of America Inc, 4600 150th Ave NE, Redmond, WA 98052, USA.
|
||||
NumWorks SAS and Nintendo of America Inc aren't associated in any shape or form with this project.
|
||||
|
||||
* NumWorks Epsilon is released under a [CC BY-NC-SA License](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode).
|
||||
* Omega is released under a [CC BY-NC-SA License](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode).
|
||||
|
||||
@@ -4,12 +4,31 @@ include apps/home/Makefile
|
||||
include apps/on_boarding/Makefile
|
||||
include apps/hardware_test/Makefile
|
||||
include apps/usb/Makefile
|
||||
apps =
|
||||
|
||||
apps =
|
||||
# All selected apps are included. Each Makefile below is responsible for setting
|
||||
# the $apps variable (name of the app class) and the $app_headers
|
||||
# (path to the apps header).
|
||||
$(foreach i,${EPSILON_APPS},$(eval include apps/$(i)/Makefile))
|
||||
$(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 \
|
||||
@@ -25,6 +44,7 @@ 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 \
|
||||
@@ -42,7 +62,7 @@ apps_src += $(addprefix apps/,\
|
||||
)
|
||||
|
||||
tests_src += $(addprefix apps/,\
|
||||
exam_mode_configuration_official.cpp \
|
||||
exam_mode_configuration_non_official.cpp \
|
||||
)
|
||||
|
||||
|
||||
@@ -52,9 +72,9 @@ snapshots_construction = $(foreach i,$(apps),,m_snapshot$(subst :,,$(i))Snapshot
|
||||
snapshots_list = $(foreach i,$(apps),,&m_snapshot$(subst :,,$(i))Snapshot)
|
||||
snapshots_count = $(words $(apps))
|
||||
snapshot_includes = $(foreach i,$(app_headers),-include $(i) )
|
||||
epsilon_app_names = '$(foreach i,${EPSILON_APPS},"$(i)", )'
|
||||
epsilon_app_names = '$(foreach i,${apps_list},"$(i)", )'
|
||||
|
||||
$(call object_for,apps/apps_container_storage.cpp apps/apps_container.cpp apps/main.cpp): CXXFLAGS += $(snapshot_includes) -DAPPS_CONTAINER_APPS_DECLARATION="$(apps_declaration)" -DAPPS_CONTAINER_SNAPSHOT_DECLARATIONS="$(snapshots_declaration)" -DAPPS_CONTAINER_SNAPSHOT_CONSTRUCTORS="$(snapshots_construction)" -DAPPS_CONTAINER_SNAPSHOT_LIST="$(snapshots_list)" -DAPPS_CONTAINER_SNAPSHOT_COUNT=$(snapshots_count) -DEPSILON_APPS_NAMES=$(epsilon_app_names)
|
||||
$(call object_for,apps/apps_container_storage.cpp apps/apps_container.cpp apps/main.cpp): CXXFLAGS += $(snapshot_includes) -DAPPS_CONTAINER_APPS_DECLARATION="$(apps_declaration)" -DAPPS_CONTAINER_SNAPSHOT_DECLARATIONS="$(snapshots_declaration)" -DAPPS_CONTAINER_SNAPSHOT_CONSTRUCTORS="$(snapshots_construction)" -DAPPS_CONTAINER_SNAPSHOT_LIST="$(snapshots_list)" -DAPPS_CONTAINER_SNAPSHOT_COUNT=$(snapshots_count) -DEPSILON_APPS_NAMES=$(epsilon_app_names) -DOMEGA_USERNAME="$(OMEGA_USERNAME)"
|
||||
|
||||
# I18n file generation
|
||||
|
||||
@@ -81,6 +101,8 @@ $(eval $(call rule_for, \
|
||||
global \
|
||||
))
|
||||
|
||||
|
||||
|
||||
$(BUILD_DIR)/apps/i18n.h: $(BUILD_DIR)/apps/i18n.cpp
|
||||
|
||||
# Handle PNG files
|
||||
@@ -88,6 +110,7 @@ $(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
|
||||
|
||||
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)
|
||||
@@ -96,3 +119,21 @@ apps_tests_src += $(addprefix apps/,\
|
||||
alternate_empty_nested_menu_controller.cpp \
|
||||
global_preferences.cpp \
|
||||
)
|
||||
|
||||
ifeq ($(THEME_REPO),local)
|
||||
$(foreach img,$(image_list), $(eval $(call rule_for, \
|
||||
ICON, \
|
||||
$(img), \
|
||||
$(addprefix themes/themes/local/, $(addsuffix .json, $(THEME_NAME))), \
|
||||
$$(PYTHON) themes/themes_manager.py -i $(THEME_REPO) $(THEME_NAME) $$@ $(BUILD_DIR)/, \
|
||||
global \
|
||||
)))
|
||||
else
|
||||
$(foreach img,$(image_list), $(eval $(call rule_for, \
|
||||
ICON, \
|
||||
$(img), \
|
||||
$(addsuffix /escher/palette.h, $(BUILD_DIR)), \
|
||||
$$(PYTHON) themes/themes_manager.py -i $(THEME_REPO) $(THEME_NAME) $$@ $(BUILD_DIR)/, \
|
||||
global \
|
||||
)))
|
||||
endif
|
||||
|
||||
@@ -5,11 +5,14 @@
|
||||
#include <ion.h>
|
||||
#include <poincare/init.h>
|
||||
#include <poincare/exception_checkpoint.h>
|
||||
#include <ion/backlight.h>
|
||||
#include <poincare/preferences.h>
|
||||
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
}
|
||||
|
||||
using namespace Poincare;
|
||||
using namespace Shared;
|
||||
|
||||
AppsContainer * AppsContainer::sharedAppsContainer() {
|
||||
@@ -28,13 +31,14 @@ AppsContainer::AppsContainer() :
|
||||
m_batteryTimer(),
|
||||
m_suspendTimer(),
|
||||
m_backlightDimmingTimer(),
|
||||
m_clockTimer(ClockTimer(this)),
|
||||
m_homeSnapshot(),
|
||||
m_onBoardingSnapshot(),
|
||||
m_hardwareTestSnapshot(),
|
||||
m_usbConnectedSnapshot()
|
||||
{
|
||||
m_emptyBatteryWindow.setFrame(KDRect(0, 0, Ion::Display::Width, Ion::Display::Height), false);
|
||||
#if __EMSCRIPTEN__
|
||||
// #if __EMSCRIPTEN__
|
||||
/* AppsContainer::poincareCircuitBreaker uses Ion::Keyboard::scan(), which
|
||||
* calls emscripten_sleep. If we set the poincare circuit breaker, we would
|
||||
* need to whitelist all the methods that might be in the call stack when
|
||||
@@ -44,9 +48,13 @@ AppsContainer::AppsContainer() :
|
||||
* quite painy to maintain).
|
||||
* We just remove the circuit breaker for now.
|
||||
* TODO: Put the Poincare circuit breaker back on epsilon's web emulator */
|
||||
#else
|
||||
|
||||
/*
|
||||
* This can be run in Omega, since it uses WebASM.
|
||||
*/
|
||||
// #else
|
||||
Poincare::Expression::SetCircuitBreaker(AppsContainer::poincareCircuitBreaker);
|
||||
#endif
|
||||
// #endif
|
||||
Ion::Storage::sharedStorage()->setDelegate(this);
|
||||
}
|
||||
|
||||
@@ -162,6 +170,36 @@ bool AppsContainer::dispatchEvent(Ion::Events::Event event) {
|
||||
Ion::USB::clearEnumerationInterrupt();
|
||||
}
|
||||
} else {
|
||||
if (KDIonContext::sharedContext()->zoomEnabled) {
|
||||
bool changedZoom = true;
|
||||
|
||||
if (event == Ion::Events::ShiftOne) {
|
||||
KDIonContext::sharedContext()->zoomPosition = 0;
|
||||
} else if (event == Ion::Events::ShiftTwo) {
|
||||
KDIonContext::sharedContext()->zoomPosition = 1;
|
||||
} else if (event == Ion::Events::ShiftThree) {
|
||||
KDIonContext::sharedContext()->zoomPosition = 2;
|
||||
} else if (event == Ion::Events::ShiftFour) {
|
||||
KDIonContext::sharedContext()->zoomPosition = 3;
|
||||
} else if (event == Ion::Events::ShiftFive) {
|
||||
KDIonContext::sharedContext()->zoomPosition = 4;
|
||||
} else if (event == Ion::Events::ShiftSix) {
|
||||
KDIonContext::sharedContext()->zoomPosition = 5;
|
||||
} else if (event == Ion::Events::ShiftSeven) {
|
||||
KDIonContext::sharedContext()->zoomPosition = 6;
|
||||
} else if (event == Ion::Events::ShiftEight) {
|
||||
KDIonContext::sharedContext()->zoomPosition = 7;
|
||||
} else if (event == Ion::Events::ShiftNine) {
|
||||
KDIonContext::sharedContext()->zoomPosition = 8;
|
||||
} else {
|
||||
changedZoom = false;
|
||||
}
|
||||
if (changedZoom) {
|
||||
KDIonContext::sharedContext()->updatePostProcessingEffects();
|
||||
redrawWindow(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
didProcessEvent = Container::dispatchEvent(event);
|
||||
}
|
||||
|
||||
@@ -200,10 +238,19 @@ bool AppsContainer::processEvent(Ion::Events::Event event) {
|
||||
switchTo(appSnapshotAtIndex(0));
|
||||
return true;
|
||||
}
|
||||
if (event == Ion::Events::ShiftHome) {
|
||||
switchTo(appSnapshotAtIndex(1));
|
||||
return true;
|
||||
}
|
||||
if (event == Ion::Events::OnOff) {
|
||||
suspend(true);
|
||||
return true;
|
||||
}
|
||||
if (event == Ion::Events::BrightnessPlus || event == Ion::Events::BrightnessMinus) {
|
||||
int delta = Ion::Backlight::MaxBrightness/GlobalPreferences::NumberOfBrightnessStates;
|
||||
int direction = (event == Ion::Events::BrightnessPlus) ? Ion::Backlight::NumberOfStepsPerShortcut*delta : -delta*Ion::Backlight::NumberOfStepsPerShortcut;
|
||||
GlobalPreferences::sharedGlobalPreferences()->setBrightnessLevel(GlobalPreferences::sharedGlobalPreferences()->brightnessLevel()+direction);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -273,6 +320,10 @@ 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();
|
||||
@@ -336,14 +387,22 @@ OnBoarding::PromptController * AppsContainer::promptController() {
|
||||
return &m_promptController;
|
||||
}
|
||||
|
||||
void AppsContainer::redrawWindow() {
|
||||
m_window.redraw();
|
||||
void AppsContainer::redrawWindow(bool force) {
|
||||
m_window.redraw(force);
|
||||
}
|
||||
|
||||
void AppsContainer::activateExamMode(GlobalPreferences::ExamMode examMode) {
|
||||
assert(examMode != GlobalPreferences::ExamMode::Off && examMode != GlobalPreferences::ExamMode::Unknown);
|
||||
reset();
|
||||
Ion::LED::setColor(ExamModeConfiguration::examModeColor(examMode));
|
||||
Ion::LED::setColor(KDColorRed);
|
||||
/* The Dutch exam mode LED is supposed to be orange but we can only make
|
||||
* blink "pure" colors: with RGB leds on or off (as the PWM is used for
|
||||
* blinking). The closest "pure" color is Yellow. Moreover, Orange LED is
|
||||
* already used when the battery is charging. Using yellow, we can assert
|
||||
* that the yellow LED only means that Dutch exam mode is on and avoid
|
||||
* confusing states when the battery is charging and states when the Dutch
|
||||
* exam mode is on. */
|
||||
// Ion::LED::setColor(examMode == GlobalPreferences::ExamMode::Dutch ? KDColorYellow : KDColorRed);
|
||||
Ion::LED::setBlinking(1000, 0.1f);
|
||||
}
|
||||
|
||||
@@ -370,11 +429,11 @@ Window * AppsContainer::window() {
|
||||
}
|
||||
|
||||
int AppsContainer::numberOfContainerTimers() {
|
||||
return 3;
|
||||
return 4;
|
||||
}
|
||||
|
||||
Timer * AppsContainer::containerTimerAtIndex(int i) {
|
||||
Timer * timers[3] = {&m_batteryTimer, &m_suspendTimer, &m_backlightDimmingTimer};
|
||||
Timer * timers[4] = {&m_batteryTimer, &m_suspendTimer, &m_backlightDimmingTimer, &m_clockTimer};
|
||||
return timers[i];
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +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 <ion/events.h>
|
||||
@@ -39,6 +40,7 @@ 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();
|
||||
@@ -46,7 +48,7 @@ public:
|
||||
void shutdownDueToLowBattery();
|
||||
void setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus newStatus);
|
||||
OnBoarding::PromptController * promptController();
|
||||
void redrawWindow();
|
||||
void redrawWindow(bool force = false);
|
||||
void activateExamMode(GlobalPreferences::ExamMode examMode);
|
||||
// Exam pop-up controller delegate
|
||||
void examDeactivatingPopUpIsDismissed() override;
|
||||
@@ -76,6 +78,7 @@ private:
|
||||
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;
|
||||
|
||||
@@ -18,6 +18,6 @@ KDColor AppsContainer::k_promptColors[] = {
|
||||
KDColorWhite,
|
||||
KDColorBlack,
|
||||
KDColorBlack,
|
||||
Palette::YellowDark};
|
||||
Palette::AccentText};
|
||||
|
||||
int AppsContainer::k_promptNumberOfMessages = 8;
|
||||
|
||||
@@ -14,6 +14,6 @@ KDColor AppsContainer::k_promptColors[] = {
|
||||
KDColorBlack,
|
||||
KDColorWhite,
|
||||
KDColorBlack,
|
||||
Palette::YellowDark};
|
||||
Palette::AccentText};
|
||||
|
||||
int AppsContainer::k_promptNumberOfMessages = 6;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
}
|
||||
#include <ion/rtc.h>
|
||||
|
||||
AppsWindow::AppsWindow() :
|
||||
Window(),
|
||||
@@ -19,6 +20,11 @@ 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());
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ public:
|
||||
AppsWindow();
|
||||
void setTitle(I18n::Message title);
|
||||
bool updateBatteryLevel();
|
||||
bool updateClock();
|
||||
bool updateIsChargingState();
|
||||
bool updatePluggedState();
|
||||
void refreshPreferences();
|
||||
|
||||
1
apps/atomic
Submodule
1
apps/atomic
Submodule
Submodule apps/atomic added at 69f7a06ba5
@@ -60,43 +60,43 @@ void BatteryView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
*'content' depends on the charge */
|
||||
|
||||
// Draw the left part
|
||||
ctx->fillRect(KDRect(0, 0, k_elementWidth, k_batteryHeight), KDColorWhite);
|
||||
ctx->fillRect(KDRect(0, 0, k_elementWidth, k_batteryHeight), Palette::Battery);
|
||||
|
||||
// Draw the middle part
|
||||
constexpr KDCoordinate batteryInsideX = k_elementWidth+k_separatorThickness;
|
||||
constexpr KDCoordinate batteryInsideWidth = k_batteryWidth-3*k_elementWidth-2*k_separatorThickness;
|
||||
if (m_isCharging) {
|
||||
// Charging: Yellow background with flash
|
||||
ctx->fillRect(KDRect(batteryInsideX, 0, batteryInsideWidth, k_batteryHeight), Palette::YellowLight);
|
||||
ctx->fillRect(KDRect(batteryInsideX, 0, batteryInsideWidth, k_batteryHeight), Palette::BatteryInCharge);
|
||||
KDRect frame((k_batteryWidth-k_flashWidth)/2, 0, k_flashWidth, k_flashHeight);
|
||||
KDColor flashWorkingBuffer[BatteryView::k_flashHeight*BatteryView::k_flashWidth];
|
||||
ctx->blendRectWithMask(frame, KDColorWhite, (const uint8_t *)flashMask, flashWorkingBuffer);
|
||||
ctx->blendRectWithMask(frame, Palette::Battery, (const uint8_t *)flashMask, flashWorkingBuffer);
|
||||
} else if (m_chargeState == Ion::Battery::Charge::LOW) {
|
||||
assert(!m_isPlugged);
|
||||
// Low: Quite empty battery
|
||||
ctx->fillRect(KDRect(batteryInsideX, 0, 2*k_elementWidth, k_batteryHeight), Palette::LowBattery);
|
||||
ctx->fillRect(KDRect(3*k_elementWidth+k_separatorThickness, 0, k_batteryWidth-5*k_elementWidth-2*k_separatorThickness, k_batteryHeight), Palette::YellowLight);
|
||||
ctx->fillRect(KDRect(batteryInsideX, 0, 2*k_elementWidth, k_batteryHeight), Palette::BatteryLow);
|
||||
ctx->fillRect(KDRect(3*k_elementWidth+k_separatorThickness, 0, k_batteryWidth-5*k_elementWidth-2*k_separatorThickness, k_batteryHeight), Palette::BatteryInCharge);
|
||||
} else if (m_chargeState == Ion::Battery::Charge::SOMEWHERE_INBETWEEN) {
|
||||
assert(!m_isPlugged);
|
||||
// Middle: Half full battery
|
||||
constexpr KDCoordinate middleChargeWidth = batteryInsideWidth/2;
|
||||
ctx->fillRect(KDRect(batteryInsideX, 0, middleChargeWidth, k_batteryHeight), KDColorWhite);
|
||||
ctx->fillRect(KDRect(batteryInsideX+middleChargeWidth, 0, middleChargeWidth, k_batteryHeight), Palette::YellowLight);
|
||||
ctx->fillRect(KDRect(batteryInsideX, 0, middleChargeWidth, k_batteryHeight), Palette::Battery);
|
||||
ctx->fillRect(KDRect(batteryInsideX+middleChargeWidth, 0, middleChargeWidth, k_batteryHeight), Palette::BatteryInCharge);
|
||||
} else {
|
||||
assert(m_chargeState == Ion::Battery::Charge::FULL);
|
||||
// Full but not plugged: Full battery
|
||||
ctx->fillRect(KDRect(batteryInsideX, 0, batteryInsideWidth, k_batteryHeight), KDColorWhite);
|
||||
ctx->fillRect(KDRect(batteryInsideX, 0, batteryInsideWidth, k_batteryHeight), Palette::Battery);
|
||||
if (m_isPlugged) {
|
||||
// Plugged and full: Full battery with tick
|
||||
KDRect frame((k_batteryWidth-k_tickWidth)/2, (k_batteryHeight-k_tickHeight)/2, k_tickWidth, k_tickHeight);
|
||||
KDColor tickWorkingBuffer[BatteryView::k_tickHeight*BatteryView::k_tickWidth];
|
||||
ctx->blendRectWithMask(frame, Palette::YellowDark, (const uint8_t *)tickMask, tickWorkingBuffer);
|
||||
ctx->blendRectWithMask(frame, Palette::Toolbar, (const uint8_t *)tickMask, tickWorkingBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the right part
|
||||
ctx->fillRect(KDRect(k_batteryWidth-2*k_elementWidth, 0, k_elementWidth, k_batteryHeight), KDColorWhite);
|
||||
ctx->fillRect(KDRect(k_batteryWidth-k_elementWidth, (k_batteryHeight-k_capHeight)/2, k_elementWidth, k_capHeight), KDColorWhite);
|
||||
ctx->fillRect(KDRect(k_batteryWidth-2*k_elementWidth, 0, k_elementWidth, k_batteryHeight), Palette::Battery);
|
||||
ctx->fillRect(KDRect(k_batteryWidth-k_elementWidth, (k_batteryHeight-k_capHeight)/2, k_elementWidth, k_capHeight), Palette::Battery);
|
||||
}
|
||||
|
||||
KDSize BatteryView::minimalSizeForOptimalDisplay() const {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "complex_graph_cell.h"
|
||||
#include <escher/palette.h>
|
||||
|
||||
using namespace Shared;
|
||||
using namespace Poincare;
|
||||
@@ -12,7 +13,7 @@ ComplexGraphView::ComplexGraphView(ComplexModel * complexModel) :
|
||||
}
|
||||
|
||||
void ComplexGraphView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
ctx->fillRect(rect, KDColorWhite);
|
||||
ctx->fillRect(rect, Palette::BackgroundApps);
|
||||
|
||||
// Draw grid, axes and graduations
|
||||
drawGrid(ctx, rect);
|
||||
@@ -25,7 +26,7 @@ void ComplexGraphView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
|
||||
assert(!std::isnan(real) && !std::isnan(imag) && !std::isinf(real) && !std::isinf(imag));
|
||||
// Draw the segment from the origin to the dot (real, imag)
|
||||
drawSegment(ctx, rect, 0.0f, 0.0f, m_complex->real(), m_complex->imag(), Palette::GrayDark, false);
|
||||
drawSegment(ctx, rect, 0.0f, 0.0f, m_complex->real(), m_complex->imag(), Palette::SecondaryText, false);
|
||||
|
||||
/* Draw the partial ellipse indicating the angle θ
|
||||
* - the ellipse parameters are a = |real|/5 and b = |imag|/5,
|
||||
@@ -58,27 +59,27 @@ void ComplexGraphView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
float a = parameters.real();
|
||||
float b = parameters.imag();
|
||||
return Poincare::Coordinate2D<float>(a*std::cos(t*th), b*std::sin(t*th));
|
||||
}, ¶meters, &th, false, Palette::GrayDark, false);
|
||||
}, ¶meters, &th, false, Palette::SecondaryText, false);
|
||||
|
||||
// Draw dashed segment to indicate real and imaginary
|
||||
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, real, 0.0f, imag, Palette::Red, 1, 3);
|
||||
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Horizontal, imag, 0.0f, real, Palette::Red, 1, 3);
|
||||
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, real, 0.0f, imag, Palette::CalculationTrigoAndComplexForeground, 1, 3);
|
||||
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Horizontal, imag, 0.0f, real, Palette::CalculationTrigoAndComplexForeground, 1, 3);
|
||||
|
||||
// Draw complex position on the plan
|
||||
drawDot(ctx, rect, real, imag, Palette::Red, Size::Large);
|
||||
drawDot(ctx, rect, real, imag, Palette::CalculationTrigoAndComplexForeground, Size::Large);
|
||||
|
||||
// Draw labels
|
||||
// 're(z)' label
|
||||
drawLabel(ctx, rect, real, 0.0f, "re(z)", Palette::Red, CurveView::RelativePosition::None, imag >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After);
|
||||
drawLabel(ctx, rect, real, 0.0f, "re(z)", Palette::CalculationTrigoAndComplexForeground, CurveView::RelativePosition::None, imag >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After);
|
||||
// 'im(z)' label
|
||||
drawLabel(ctx, rect, 0.0f, imag, "im(z)", Palette::Red, real >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After, CurveView::RelativePosition::None);
|
||||
drawLabel(ctx, rect, 0.0f, imag, "im(z)", Palette::CalculationTrigoAndComplexForeground, real >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After, CurveView::RelativePosition::None);
|
||||
// '|z|' label, the relative horizontal position of this label depends on the quadrant
|
||||
CurveView::RelativePosition verticalPosition = real*imag < 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After;
|
||||
if (real == 0.0f) {
|
||||
// Edge case: pure imaginary
|
||||
verticalPosition = CurveView::RelativePosition::None;
|
||||
}
|
||||
drawLabel(ctx, rect, real/2.0f, imag/2.0f, "|z|", Palette::Red, CurveView::RelativePosition::None, verticalPosition);
|
||||
drawLabel(ctx, rect, real/2.0f, imag/2.0f, "|z|", Palette::CalculationTrigoAndComplexForeground, CurveView::RelativePosition::None, verticalPosition);
|
||||
// 'arg(z)' label, the absolute and relative horizontal/vertical positions of this label depends on the quadrant
|
||||
CurveView::RelativePosition horizontalPosition = real >= 0.0f ? CurveView::RelativePosition::After : CurveView::RelativePosition::None;
|
||||
verticalPosition = imag >= 0.0f ? CurveView::RelativePosition::After : CurveView::RelativePosition::Before;
|
||||
@@ -87,7 +88,7 @@ void ComplexGraphView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
* and for the left half plan, we position the label at the half angle. The
|
||||
* relative position is chosen accordingly. */
|
||||
float anglePositionRatio = real >= 0.0f ? 0.0f : 0.5f;
|
||||
drawLabel(ctx, rect, a*std::cos(anglePositionRatio*th), b*std::sin(anglePositionRatio*th), "arg(z)", Palette::Red, horizontalPosition, verticalPosition);
|
||||
drawLabel(ctx, rect, a*std::cos(anglePositionRatio*th), b*std::sin(anglePositionRatio*th), "arg(z)", Palette::CalculationTrigoAndComplexForeground, horizontalPosition, verticalPosition);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
#include <escher.h>
|
||||
#include <apps/i18n.h>
|
||||
#include <poincare/layout.h>
|
||||
#include <escher/palette.h>
|
||||
|
||||
namespace Calculation {
|
||||
|
||||
class ExpressionWithEqualSignView : public ExpressionView {
|
||||
public:
|
||||
ExpressionWithEqualSignView() :
|
||||
m_equalSign(KDFont::LargeFont, I18n::Message::Equal, 0.5f, 0.5f, KDColorBlack)
|
||||
m_equalSign(KDFont::LargeFont, I18n::Message::Equal, 0.5f, 0.5f, Palette::PrimaryText)
|
||||
{}
|
||||
KDSize minimalSizeForOptimalDisplay() const override;
|
||||
void drawRect(KDContext * ctx, KDRect rect) const override;
|
||||
|
||||
@@ -10,7 +10,7 @@ void IllustrationCell::layoutSubviews(bool force) {
|
||||
}
|
||||
|
||||
void IllustrationCell::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
drawBorderOfRect(ctx, bounds(), Palette::GrayBright);
|
||||
drawBorderOfRect(ctx, bounds(), Palette::ListCellBorder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ void ListController::InnerListController::didBecomeFirstResponder() {
|
||||
/* List Controller */
|
||||
|
||||
ListController::ListController(EditExpressionController * editExpressionController, SelectableTableViewDelegate * delegate) :
|
||||
StackViewController(nullptr, &m_listController, KDColorWhite, Palette::PurpleBright, Palette::PurpleDark),
|
||||
StackViewController(nullptr, &m_listController, Palette::ToolboxHeaderText, Palette::ToolboxHeaderBackground, Palette::ToolboxHeaderBorder),
|
||||
m_listController(this, delegate),
|
||||
m_editExpressionController(editExpressionController)
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "../../shared/scrollable_multiple_expressions_view.h"
|
||||
#include "../calculation.h"
|
||||
#include "expression_with_equal_sign_view.h"
|
||||
#include <escher/palette.h>
|
||||
|
||||
namespace Calculation {
|
||||
|
||||
@@ -16,7 +17,7 @@ public:
|
||||
static constexpr KDCoordinate k_margin = Metric::CommonSmallMargin;
|
||||
ScrollableThreeExpressionsView(Responder * parentResponder) : Shared::AbstractScrollableMultipleExpressionsView(parentResponder, &m_contentCell), m_contentCell() {
|
||||
setMargins(k_margin, k_margin, k_margin, k_margin); // Left Right margins are already added by TableCell
|
||||
setBackgroundColor(KDColorWhite);
|
||||
setBackgroundColor(Palette::BackgroundApps);
|
||||
}
|
||||
void resetMemoization();
|
||||
void setCalculation(Calculation * calculation, bool canChangeDisplayOutput);
|
||||
@@ -27,7 +28,7 @@ private:
|
||||
class ContentCell : public Shared::AbstractScrollableMultipleExpressionsView::ContentCell {
|
||||
public:
|
||||
ContentCell() : m_leftExpressionView() {}
|
||||
KDColor backgroundColor() const override { return KDColorWhite; }
|
||||
KDColor backgroundColor() const override { return Palette::BackgroundApps; }
|
||||
void setEven(bool even) override { return; }
|
||||
ExpressionView * leftExpressionView() const override { return const_cast<ExpressionWithEqualSignView *>(&m_leftExpressionView); }
|
||||
private:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "trigonometry_graph_cell.h"
|
||||
#include <escher/palette.h>
|
||||
|
||||
using namespace Shared;
|
||||
using namespace Poincare;
|
||||
@@ -14,24 +15,24 @@ TrigonometryGraphView::TrigonometryGraphView(TrigonometryModel * model) :
|
||||
void TrigonometryGraphView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
float s = std::sin(m_model->angle());
|
||||
float c = std::cos(m_model->angle());
|
||||
ctx->fillRect(rect, KDColorWhite);
|
||||
ctx->fillRect(rect, Palette::BackgroundApps);
|
||||
drawGrid(ctx, rect);
|
||||
drawAxes(ctx, rect);
|
||||
// Draw the circle
|
||||
drawCurve(ctx, rect, 0.0f, 2.0f*M_PI, M_PI/180.0f, [](float t, void * model, void * context) {
|
||||
return Poincare::Coordinate2D<float>(std::cos(t), std::sin(t));
|
||||
}, nullptr, nullptr, true, Palette::GrayDark, false);
|
||||
}, nullptr, nullptr, true, Palette::SecondaryText, false);
|
||||
// Draw dashed segment to indicate sine and cosine
|
||||
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, c, 0.0f, s, Palette::Red, 1, 3);
|
||||
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Horizontal, s, 0.0f, c, Palette::Red, 1, 3);
|
||||
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, c, 0.0f, s, Palette::CalculationTrigoAndComplexForeground, 1, 3);
|
||||
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Horizontal, s, 0.0f, c, Palette::CalculationTrigoAndComplexForeground, 1, 3);
|
||||
// Draw angle position on the circle
|
||||
drawDot(ctx, rect, c, s, Palette::Red, Size::Large);
|
||||
drawDot(ctx, rect, c, s, Palette::CalculationTrigoAndComplexForeground, Size::Large);
|
||||
// Draw graduations
|
||||
drawLabelsAndGraduations(ctx, rect, Axis::Vertical, false, true);
|
||||
drawLabelsAndGraduations(ctx, rect, Axis::Horizontal, false, true);
|
||||
// Draw labels
|
||||
drawLabel(ctx, rect, 0.0f, s, "sin(θ)", Palette::Red, c >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After, CurveView::RelativePosition::None);
|
||||
drawLabel(ctx, rect, c, 0.0f, "cos(θ)", Palette::Red, CurveView::RelativePosition::None, s >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After);
|
||||
drawLabel(ctx, rect, 0.0f, s, "sin(θ)", Palette::CalculationTrigoAndComplexForeground, c >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After, CurveView::RelativePosition::None);
|
||||
drawLabel(ctx, rect, c, 0.0f, "cos(θ)", Palette::CalculationTrigoAndComplexForeground, CurveView::RelativePosition::None, s >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,10 @@ I18n::Message App::Descriptor::upperName() {
|
||||
return I18n::Message::CalculAppCapital;
|
||||
}
|
||||
|
||||
App::Descriptor::ExaminationLevel App::Descriptor::examinationLevel() {
|
||||
return App::Descriptor::ExaminationLevel::Strict;
|
||||
}
|
||||
|
||||
const Image * App::Descriptor::icon() {
|
||||
return ImageStore::CalculationIcon;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ public:
|
||||
public:
|
||||
I18n::Message name() override;
|
||||
I18n::Message upperName() override;
|
||||
App::Descriptor::ExaminationLevel examinationLevel() override;
|
||||
const Image * icon() override;
|
||||
};
|
||||
class Snapshot : public ::SharedApp::Snapshot {
|
||||
|
||||
@@ -11,4 +11,4 @@ AdditionalDeterminant = "Determinant"
|
||||
AdditionalInverse = "Inverse"
|
||||
AdditionalRowEchelonForm = "Row echelon form"
|
||||
AdditionalReducedRowEchelonForm = "Reduced row echelon form"
|
||||
AdditionalTrace = "Trace"
|
||||
AdditionalTrace = "Trace"
|
||||
|
||||
14
apps/calculation/base.hu.i18n
Normal file
14
apps/calculation/base.hu.i18n
Normal file
@@ -0,0 +1,14 @@
|
||||
CalculApp = "Számolás"
|
||||
CalculAppCapital = "SZÁMOLÁS"
|
||||
AdditionalResults = "További eredmények"
|
||||
DecimalBase = "Decimális"
|
||||
HexadecimalBase = "Hexadecimális"
|
||||
BinaryBase = "Bináris"
|
||||
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"
|
||||
@@ -197,8 +197,8 @@ bool Calculation::shouldOnlyDisplayExactOutput() {
|
||||
/* If the input is a "store in a function", do not display the approximate
|
||||
* result. This prevents x->f(x) from displaying x = undef. */
|
||||
Expression i = input();
|
||||
return i.type() == ExpressionNode::Type::Store
|
||||
&& i.childAtIndex(1).type() == ExpressionNode::Type::Function;
|
||||
return (i.type() == ExpressionNode::Type::Store && i.childAtIndex(1).type() == ExpressionNode::Type::Function)
|
||||
|| strcmp(approximateOutputText(NumberOfSignificantDigits::Maximal), Undefined::Name()) == 0;
|
||||
}
|
||||
|
||||
Calculation::EqualSign Calculation::exactAndApproximateDisplayedOutputsAreEqual(Poincare::Context * context) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "calculation_store.h"
|
||||
#include "../shared/poincare_helpers.h"
|
||||
#include "../global_preferences.h"
|
||||
#include <poincare/rational.h>
|
||||
#include <poincare/symbol.h>
|
||||
#include <poincare/undefined.h>
|
||||
@@ -87,7 +88,7 @@ ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context *
|
||||
// Outputs hold exact output, approximate output and its duplicate
|
||||
constexpr static int numberOfOutputs = Calculation::k_numberOfExpressions - 1;
|
||||
Expression outputs[numberOfOutputs] = {Expression(), Expression(), Expression()};
|
||||
PoincareHelpers::ParseAndSimplifyAndApproximate(inputSerialization, &(outputs[0]), &(outputs[1]), context, Poincare::ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined);
|
||||
PoincareHelpers::ParseAndSimplifyAndApproximate(inputSerialization, &(outputs[0]), &(outputs[1]), context, GlobalPreferences::sharedGlobalPreferences()->isInExamModeSymbolic() ? Poincare::ExpressionNode::SymbolicComputation::ReplaceAllDefinedSymbolsWithDefinition : Poincare::ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined);
|
||||
if (ExamModeConfiguration::exactExpressionsAreForbidden(GlobalPreferences::sharedGlobalPreferences()->examMode()) && outputs[1].hasUnit()) {
|
||||
// Hide results with units on units if required by the exam mode configuration
|
||||
outputs[1] = Undefined::Builder();
|
||||
|
||||
@@ -81,7 +81,7 @@ void HistoryViewCell::reloadSubviewHighlight() {
|
||||
m_ellipsis.setHighlighted(false);
|
||||
if (isHighlighted()) {
|
||||
if (m_dataSource->selectedSubviewType() == HistoryViewCellDataSource::SubviewType::Input) {
|
||||
m_inputView.setExpressionBackgroundColor(Palette::Select);
|
||||
m_inputView.setExpressionBackgroundColor(Palette::ListCellBackgroundSelected);
|
||||
} else if (m_dataSource->selectedSubviewType() == HistoryViewCellDataSource::SubviewType::Output) {
|
||||
m_scrollableOutputView.evenOddCell()->setHighlighted(true);
|
||||
} else {
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
return this;
|
||||
}
|
||||
Poincare::Layout layout() const override;
|
||||
KDColor backgroundColor() const override { return m_even ? KDColorWhite : Palette::WallScreen; }
|
||||
KDColor backgroundColor() const override { return m_even ? Palette::CalculationBackgroundEven : Palette::CalculationBackgroundOdd; }
|
||||
void resetMemoization();
|
||||
void setCalculation(Calculation * calculation, bool expanded, bool canChangeDisplayOutput = false);
|
||||
int numberOfSubviews() const override { return 2 + displayedEllipsis(); }
|
||||
|
||||
11
apps/calculation/test.py
Normal file
11
apps/calculation/test.py
Normal file
@@ -0,0 +1,11 @@
|
||||
import sys, tty
|
||||
def command_line():
|
||||
tty.setraw(sys.stdin)
|
||||
while True:
|
||||
char = sys.stdin.read(1)
|
||||
if ord(char) == 3: # CTRL-C
|
||||
break;
|
||||
print(ord(char))
|
||||
sys.stdout.write(u"\u001b[1000D") # Move all the way left
|
||||
|
||||
command_line();
|
||||
@@ -114,10 +114,10 @@ QUIZ_CASE(calculation_display_exact_approximate) {
|
||||
|
||||
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::ApproximateOnly, EqualSign::Unknown, "undef", "undef", "undef", &globalContext, &store);
|
||||
assertCalculationIs("2x-x", DisplayOutput::ApproximateOnly, EqualSign::Unknown, "undef", "undef", "undef", &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::ApproximateOnly, EqualSign::Unknown, nullptr, "undef", "undef", &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);
|
||||
Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy();
|
||||
@@ -130,9 +130,9 @@ QUIZ_CASE(calculation_display_exact_approximate) {
|
||||
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::ApproximateOnly, EqualSign::Unknown, nullptr, nullptr, nullptr, &globalContext, &store);
|
||||
assertCalculationIs("prediction(0.5,2)+3", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, nullptr, nullptr, &globalContext, &store);
|
||||
assertCalculationIs("prediction95(0.5,2)+3", DisplayOutput::ApproximateOnly, EqualSign::Unknown, nullptr, nullptr, nullptr, &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);
|
||||
|
||||
}
|
||||
|
||||
@@ -140,10 +140,10 @@ QUIZ_CASE(calculation_symbolic_computation) {
|
||||
Shared::GlobalContext globalContext;
|
||||
CalculationStore store(calculationBuffer,calculationBufferSize);
|
||||
|
||||
assertCalculationIs("x+x+1+3+√(π)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, "undef", "undef", "undef", &globalContext, &store);
|
||||
assertCalculationIs("f(x)", DisplayOutput::ApproximateOnly, EqualSign::Unknown, "undef", "undef", "undef", &globalContext, &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::ApproximateOnly, EqualSign::Unknown, "undef", "undef", "undef", &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);
|
||||
|
||||
12
apps/clock_timer.cpp
Normal file
12
apps/clock_timer.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "clock_timer.h"
|
||||
#include "apps_container.h"
|
||||
|
||||
ClockTimer::ClockTimer(AppsContainer * container) :
|
||||
Timer(1),
|
||||
m_container(container)
|
||||
{
|
||||
}
|
||||
|
||||
bool ClockTimer::fire() {
|
||||
return m_container->updateClock();
|
||||
}
|
||||
16
apps/clock_timer.h
Normal file
16
apps/clock_timer.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#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
|
||||
@@ -14,6 +14,10 @@ I18n::Message App::Descriptor::upperName() {
|
||||
return I18n::Message::CodeAppCapital;
|
||||
}
|
||||
|
||||
App::Descriptor::ExaminationLevel App::Descriptor::examinationLevel() {
|
||||
return App::Descriptor::ExaminationLevel::Basic;
|
||||
}
|
||||
|
||||
const Image * App::Descriptor::icon() {
|
||||
return ImageStore::CodeIcon;
|
||||
}
|
||||
@@ -21,6 +25,7 @@ const Image * App::Descriptor::icon() {
|
||||
App::Snapshot::Snapshot() :
|
||||
#if EPSILON_GETOPT
|
||||
m_lockOnConsole(false),
|
||||
m_hasBeenWiped(false),
|
||||
#endif
|
||||
m_scriptStore()
|
||||
{
|
||||
@@ -46,7 +51,11 @@ bool App::Snapshot::lockOnConsole() const {
|
||||
|
||||
void App::Snapshot::setOpt(const char * name, const char * value) {
|
||||
if (strcmp(name, "script") == 0) {
|
||||
m_scriptStore.deleteAllScripts();
|
||||
if (!m_hasBeenWiped) {
|
||||
m_hasBeenWiped = true;
|
||||
m_scriptStore.deleteAllScripts();
|
||||
}
|
||||
|
||||
char * separator = const_cast<char *>(UTF8Helper::CodePointSearch(value, ':'));
|
||||
if (*separator == 0) {
|
||||
return;
|
||||
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
public:
|
||||
I18n::Message name() override;
|
||||
I18n::Message upperName() override;
|
||||
App::Descriptor::ExaminationLevel examinationLevel() override;
|
||||
const Image * icon() override;
|
||||
};
|
||||
class Snapshot : public SharedApp::Snapshot {
|
||||
@@ -34,6 +35,7 @@ public:
|
||||
private:
|
||||
#if EPSILON_GETOPT
|
||||
bool m_lockOnConsole;
|
||||
bool m_hasBeenWiped;
|
||||
#endif
|
||||
ScriptStore m_scriptStore;
|
||||
};
|
||||
@@ -73,7 +75,7 @@ public:
|
||||
|
||||
VariableBoxController * variableBoxController() { return &m_variableBoxController; }
|
||||
|
||||
static constexpr int k_pythonHeapSize = 32768;
|
||||
static constexpr int k_pythonHeapSize = 100000;
|
||||
|
||||
private:
|
||||
/* Python delegate:
|
||||
|
||||
@@ -5,9 +5,11 @@ 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 = "Kein Wort ist hier verfübar."
|
||||
ScriptInProgress = "Aktuelle Skript"
|
||||
ScriptOptions = "Skriptoptionen"
|
||||
ScriptSize = "Script size"
|
||||
|
||||
@@ -5,9 +5,11 @@ AutoImportScript = "Auto import in shell"
|
||||
BuiltinsAndKeywords = "Builtins and keywords"
|
||||
Console = "Python shell"
|
||||
DeleteScript = "Delete script"
|
||||
DuplicateScript = "Duplicate script"
|
||||
ExecuteScript = "Execute script"
|
||||
FunctionsAndVariables = "Functions and variables"
|
||||
ImportedModulesAndScripts = "Imported modules and scripts"
|
||||
NoWordAvailableHere = "No word available here."
|
||||
ScriptInProgress = "Script in progress"
|
||||
ScriptOptions = "Script options"
|
||||
ScriptSize = "Script size"
|
||||
|
||||
@@ -5,9 +5,11 @@ AutoImportScript = "Importación auto en intérprete"
|
||||
BuiltinsAndKeywords = "Funciones nativas y palabras clave"
|
||||
Console = "Interprete de comandos"
|
||||
DeleteScript = "Eliminar el archivo"
|
||||
DuplicateScript = "Duplicar el guión"
|
||||
ExecuteScript = "Ejecutar el archivo"
|
||||
FunctionsAndVariables = "Funciones y variables"
|
||||
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"
|
||||
|
||||
@@ -5,9 +5,11 @@ AutoImportScript = "Importation auto dans la console"
|
||||
BuiltinsAndKeywords = "Fonctions natives et mots-clés"
|
||||
Console = "Console d'exécution"
|
||||
DeleteScript = "Supprimer le script"
|
||||
DuplicateScript = "Dupliquer le script"
|
||||
ExecuteScript = "Exécuter le script"
|
||||
FunctionsAndVariables = "Fonctions et variables"
|
||||
ImportedModulesAndScripts = "Modules et scripts importés"
|
||||
NoWordAvailableHere = "Aucun mot disponible à cet endroit."
|
||||
ScriptInProgress = "Script en cours"
|
||||
ScriptOptions = "Options de script"
|
||||
ScriptSize = "Taille du script"
|
||||
|
||||
15
apps/code/base.hu.i18n
Normal file
15
apps/code/base.hu.i18n
Normal file
@@ -0,0 +1,15 @@
|
||||
AddScript = "Script hozzáadása"
|
||||
AllowedCharactersaz09 = "Engedélyezett karakterek: a-z, 0-9, _"
|
||||
Autocomplete = "Önkiegészítés"
|
||||
AutoImportScript = "Script automata importálása"
|
||||
BuiltinsAndKeywords = "Beépített fonkciók és szókincs"
|
||||
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"
|
||||
ScriptOptions = "Script beállítások"
|
||||
ScriptSize = "Script mérete"
|
||||
@@ -5,9 +5,11 @@ AutoImportScript = "Auto importazione nella console"
|
||||
BuiltinsAndKeywords = "Funzioni native e parole chiave"
|
||||
Console = "Console d'esecuzione"
|
||||
DeleteScript = "Eliminare lo script"
|
||||
DuplicateScript = "Duplicate script"
|
||||
ExecuteScript = "Eseguire lo script"
|
||||
FunctionsAndVariables = "Funzioni e variabili"
|
||||
ImportedModulesAndScripts = "Moduli e scripts importati"
|
||||
NoWordAvailableHere = "Nessuna parola disponibile qui."
|
||||
ScriptInProgress = "Script in corso"
|
||||
ScriptOptions = "Opzioni dello script"
|
||||
ScriptSize = "Script Size"
|
||||
|
||||
@@ -5,9 +5,11 @@ AutoImportScript = "Automatisch importeren in shell"
|
||||
BuiltinsAndKeywords = "Builtins and keywords"
|
||||
Console = "Python shell"
|
||||
DeleteScript = "Script verwijderen"
|
||||
DuplicateScript = "Duplicate script"
|
||||
ExecuteScript = "Script uitvoeren"
|
||||
FunctionsAndVariables = "Functies en variabelen"
|
||||
ImportedModulesAndScripts = "Imported modules and scripts"
|
||||
NoWordAvailableHere = "No word available here."
|
||||
ScriptInProgress = "Script in progress"
|
||||
ScriptOptions = "Script opties"
|
||||
ScriptSize = "Script Size"
|
||||
|
||||
@@ -5,9 +5,11 @@ AutoImportScript = "Importação auto no interpretador"
|
||||
BuiltinsAndKeywords = "Funções nativas e palavras-chave"
|
||||
Console = "Interpretador interativo"
|
||||
DeleteScript = "Eliminar o script"
|
||||
DuplicateScript = "Duplicar o script"
|
||||
ExecuteScript = "Executar o script"
|
||||
FunctionsAndVariables = "Funções e variáveis"
|
||||
ImportedModulesAndScripts = "Módulos e scripts importados"
|
||||
NoWordAvailableHere = "Nenhuma palavra disponível aqui."
|
||||
ScriptInProgress = "Script em curso"
|
||||
ScriptOptions = "Opções de script"
|
||||
ScriptSize = "Script Size"
|
||||
|
||||
@@ -12,7 +12,7 @@ PythonSingleQuote = "Einfaches Anführungszeichen"
|
||||
PythonAbs = "Absolute/r Wert/Größe"
|
||||
PythonAcos = "Arkuskosinus"
|
||||
PythonAcosh = "Hyperbelkosinus"
|
||||
PythonAppend = "Add x to the end of the list"
|
||||
PythonAppend = "Hängt x an das Ende der Liste"
|
||||
PythonArrow = "Arrow from (x,y) to (x+dx,y+dy)"
|
||||
PythonAsin = "Arkussinus"
|
||||
PythonAsinh = "Hyperbelsinus"
|
||||
@@ -24,7 +24,7 @@ PythonBar = "Draw a bar plot with x values"
|
||||
PythonBin = "Ganzzahl nach binär konvertieren"
|
||||
PythonCeil = "Aufrundung"
|
||||
PythonChoice = "Zufallszahl aus der Liste"
|
||||
PythonClear = "Empty the list"
|
||||
PythonClear = "Leere die Liste"
|
||||
PythonCmathFunction = "cmath-Modul-Funktionspräfix"
|
||||
PythonColor = "Definiere eine RGB-Farbe"
|
||||
PythonColorBlack = "Black color"
|
||||
@@ -39,21 +39,21 @@ PythonColorRed = "Red color"
|
||||
PythonColorWhite = "White color"
|
||||
PythonColorYellow = "Yellow color"
|
||||
PythonComplex = "a+ib zurückgeben"
|
||||
PythonCopySign = "Return x with the sign of y"
|
||||
PythonCopySign = "x mit dem Vorzeichen von y"
|
||||
PythonCos = "Kosinus"
|
||||
PythonCosh = "Hyperbolic cosine"
|
||||
PythonCount = "Count the occurrences of x"
|
||||
PythonDegrees = "Convert x from radians to degrees"
|
||||
PythonDivMod = "Quotient and remainder"
|
||||
PythonDrawString = "Display a text from pixel (x,y)"
|
||||
PythonErf = "Error function"
|
||||
PythonCount = "Zählt wie oft x vorkommt"
|
||||
PythonDegrees = "x von Radian zu Grad umwandeln"
|
||||
PythonDivMod = "Quotient und Rest"
|
||||
PythonDrawString = "Schreibt Text bei (x,y)"
|
||||
PythonErf = "Fehlerfunktion"
|
||||
PythonErfc = "Complementary error function"
|
||||
PythonEval = "Return the evaluated expression"
|
||||
PythonExp = "Exponential function"
|
||||
PythonExpm1 = "Compute exp(x)-1"
|
||||
PythonFabs = "Absolute value"
|
||||
PythonFillRect = "Fill a rectangle at pixel (x,y)"
|
||||
PythonFloat = "Convert x to a float"
|
||||
PythonExp = "Exponentialfunktion"
|
||||
PythonExpm1 = "Berechne exp(x)-1"
|
||||
PythonFabs = "Absoluter Wert"
|
||||
PythonFillRect = "Malt ein Rechteck bei Pixel (x,y)"
|
||||
PythonFloat = "Wandelt x zu float um"
|
||||
PythonFloor = "Floor"
|
||||
PythonFmod = "a modulo b"
|
||||
PythonFrExp = "Mantissa and exponent of x: (m,e)"
|
||||
@@ -61,72 +61,77 @@ PythonGamma = "Gamma function"
|
||||
PythonGetPixel = "Return pixel (x,y) color"
|
||||
PythonGetrandbits = "Integer with k random bits"
|
||||
PythonGrid = "Toggle the visibility of the grid"
|
||||
PythonHex = "Convert integer to hexadecimal"
|
||||
PythonHex = "Ganzzahl zu Hexadecimal"
|
||||
PythonHist = "Draw the histogram of x"
|
||||
PythonImportCmath = "Import cmath module"
|
||||
PythonImportIon = "Import ion module"
|
||||
PythonImportKandinsky = "Import kandinsky module"
|
||||
PythonImportRandom = "Import random module"
|
||||
PythonImportMath = "Import math module"
|
||||
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"
|
||||
PythonImportTime = "Import time module"
|
||||
PythonImportTurtle = "Import turtle module"
|
||||
PythonIndex = "Index of the first x occurrence"
|
||||
PythonInput = "Prompt a value"
|
||||
PythonInsert = "Insert x at index i in the list"
|
||||
PythonInt = "Convert x to an integer"
|
||||
PythonImportOs = "os Modul importieren"
|
||||
PythonOsUname = "Informieren Sie sich über das System"
|
||||
PythonOsRemove = "Datei namens Dateiname entfernen"
|
||||
PythonOsRename = "Datei mit altem Namen in neuen Namen umbenennen"
|
||||
PythonOsListdir = "Dateien im Speicher auflisten"
|
||||
PythonImportTime = "time Modul importieren"
|
||||
PythonImportTurtle = "turtle Modul importieren"
|
||||
PythonIndex = "Index, bei dem x zuerst vorkommt"
|
||||
PythonInput = "Eingabeaufforderung"
|
||||
PythonInsert = "x bei index i in der Liste einsetzen"
|
||||
PythonInt = "x zu Ganzzahl"
|
||||
PythonIonFunction = "ion module function prefix"
|
||||
PythonIsFinite = "Check if x is finite"
|
||||
PythonIsInfinite = "Check if x is infinity"
|
||||
PythonIsNaN = "Check if x is a NaN"
|
||||
PythonIsKeyDown = "Return True if the k key is down"
|
||||
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 = "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"
|
||||
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 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"
|
||||
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"
|
||||
@@ -165,16 +170,16 @@ PythonSin = "Sine"
|
||||
PythonSinh = "Hyperbolic sine"
|
||||
PythonSleep = "Suspend the execution for t seconds"
|
||||
PythonSort = "Sort the list"
|
||||
PythonSqrt = "Square root"
|
||||
PythonSqrt = "Wurzel"
|
||||
PythonSum = "Sum the items of a list"
|
||||
PythonTan = "Tangent"
|
||||
PythonTan = "Tangens"
|
||||
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 = "Set the pen color"
|
||||
PythonTurtleColor = "Stiftfarbe setzen"
|
||||
PythonTurtleColorMode = "Set the color mode to 1.0 or 255"
|
||||
PythonTurtleForward = "Move forward by x pixels"
|
||||
PythonTurtleFunction = "turtle module function prefix"
|
||||
@@ -195,3 +200,23 @@ 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 = "Ist eine Datei durchsuchbar?"
|
||||
PythonFileSeek = "Dateicursor verschieben"
|
||||
PythonFileTell = "Cursorposition der Datei abrufen"
|
||||
PythonFileClose = "Schließt eine Datei"
|
||||
PythonFileClosed = "Wenn Datei geschlossen wurde"
|
||||
PythonFileRead = "Bis zu size Bytes lesen"
|
||||
PythonFileWrite = "Schreibe b in die Datei"
|
||||
PythonFileReadline = "Lies eine Zeile"
|
||||
PythonFileReadlines = "Liest eine Liste von Zeilen"
|
||||
PythonFileTruncate = "Größe der Datei ändern"
|
||||
PythonFileWritelines = "Schreibt eine Liste von Zeilen"
|
||||
PythonFileName = "Dateiname"
|
||||
PythonFileMode = "Dateiöffnungsmodus"
|
||||
PythonFileReadable = "Ist die Datei lesbar?"
|
||||
PythonFileWritable = "Ist die Datei beschreibbar?"
|
||||
|
||||
@@ -195,3 +195,28 @@ 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"
|
||||
PythonImportOs = "Import os module"
|
||||
PythonOsUname = "Get infos about the system"
|
||||
PythonOsRemove = "Remove file named filename"
|
||||
PythonOsRename = "Rename file oldname to newname"
|
||||
PythonOsListdir = "List files in memory"
|
||||
PythonTimePrefix = "time module function prefix"
|
||||
PythonTimeSleep = "Wait for n second"
|
||||
PythonMonotonic = "Return monotonic time"
|
||||
PythonFileOpen = "Opens a file"
|
||||
PythonFileSeekable = "Tells if seek can be used on a file"
|
||||
PythonFileSeek = "Move file's cursor"
|
||||
PythonFileTell = "Get file's cursor location"
|
||||
PythonFileClose = "Closes a file"
|
||||
PythonFileClosed = "True if file was closed"
|
||||
PythonFileRead = "Read up to size bytes"
|
||||
PythonFileWrite = "Write b into file"
|
||||
PythonFileReadline = "Reads a line or up to size bytes"
|
||||
PythonFileReadlines = "Reads a list of lines"
|
||||
PythonFileTruncate = "Resize the file to size"
|
||||
PythonFileWritelines = "Writes a list of lines"
|
||||
PythonFileName = "Contains file's name"
|
||||
PythonFileMode = "Contains file's open mode"
|
||||
PythonFileReadable = "Tells if read can be used on a file"
|
||||
PythonFileWritable = "Tells if write can be used on a file"
|
||||
|
||||
@@ -195,3 +195,28 @@ 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"
|
||||
PythonImportOs = "Import os module"
|
||||
PythonOsUname = " Información del sistema "
|
||||
PythonOsRemove = "Eliminar un archivo"
|
||||
PythonOsRename = "Renombrar archivo"
|
||||
PythonOsListdir = "Archivos de la lista"
|
||||
PythonTimePrefix = "time module function prefix"
|
||||
PythonTimeSleep = "Esperar n segundos"
|
||||
PythonMonotonic = "Tiempo monótono de retorno"
|
||||
PythonFileOpen = "Opens a file"
|
||||
PythonFileSeekable = "Tells if seek can be used on a file"
|
||||
PythonFileSeek = "Move file's internal cursor"
|
||||
PythonFileTell = "Get file's internal cursor location"
|
||||
PythonFileClose = "Closes a file"
|
||||
PythonFileClosed = "True if file was closed"
|
||||
PythonFileRead = "Read up to size bytes"
|
||||
PythonFileWrite = "Write b into file"
|
||||
PythonFileReadline = "Reads a line or up to size bytes"
|
||||
PythonFileReadlines = "Reads a list of lines"
|
||||
PythonFileTruncate = "Resize the file to size"
|
||||
PythonFileWritelines = "Writes a list of lines"
|
||||
PythonFileName = "Contains file's name"
|
||||
PythonFileMode = "Contains file's open mode"
|
||||
PythonFileReadable = "Tells if read can be used on a file"
|
||||
PythonFileWritable = "Tells if write can be used on a file"
|
||||
|
||||
@@ -195,3 +195,28 @@ PythonTurtleShowturtle = "Affiche la tortue"
|
||||
PythonTurtleSpeed = "Vitesse du tracé entre 0 et 10"
|
||||
PythonTurtleWrite = "Affiche un texte"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
PythonFileTruncate = "Redimensionne le fichier"
|
||||
PythonFileWritelines = "Écrit une liste de lignes"
|
||||
PythonFileName = "Nom du fichier"
|
||||
PythonFileMode = "Mode d'ouverture du fichier"
|
||||
PythonFileReadable = "Indique si read peut être utilisé"
|
||||
PythonFileWritable = "Indique si write peut être utilisé"
|
||||
|
||||
222
apps/code/catalog.hu.i18n
Normal file
222
apps/code/catalog.hu.i18n
Normal file
@@ -0,0 +1,222 @@
|
||||
PythonPound = "Megjegyzés"
|
||||
PythonPercent = "Modulo"
|
||||
Python1J = "Képzeletbeli i"
|
||||
PythonLF = "Enter"
|
||||
PythonTab = "Táblázat"
|
||||
PythonAmpersand = "Logikus és"
|
||||
PythonSymbolExp = "logikus exkluzív vagy pedig"
|
||||
PythonVerticalBar = "logikus vagy pedig"
|
||||
PythonImag = "z képzeletbeli része"
|
||||
PythonReal = "z valódi része"
|
||||
PythonSingleQuote = "apostróf"
|
||||
PythonAbs = "Abszolút érték/nagyság"
|
||||
PythonAcos = "Ív (arc) koszinusz"
|
||||
PythonAcosh = "Hiperbolikus arc koszinusz"
|
||||
PythonAppend = "Lista végére hozzáadni x-et"
|
||||
PythonArrow = "(x,y) nyíla (x+dx,y+dy) nyílához"
|
||||
PythonAsin = "Ív (arc) szinusz"
|
||||
PythonAsinh = "Hiperbolikus ív (arc) szinusz"
|
||||
PythonAtan = "Ív (arc) érintö (tan)"
|
||||
PythonAtan2 = "atan(y/x) sámolása"
|
||||
PythonAtanh = "Hiperbolikus ív (arc) érintö (atan)"
|
||||
PythonAxis = "Tengelyeket (xmin,xmax,ymin,ymax)-ra állitani"
|
||||
PythonBar = "Az x lista oszlopdiagramja"
|
||||
PythonBin = "Egész szám konvertálása binárisra"
|
||||
PythonCeil = "Mennyezet"
|
||||
PythonChoice = "Véletlenszerü szám a listában"
|
||||
PythonClear = "A lista ürítése"
|
||||
PythonCmathFunction = "cmath modul funkció elötag"
|
||||
PythonColor = "Rgb (pzk) szín allítása"
|
||||
PythonColorBlack = "Fekete szín"
|
||||
PythonColorBlue = "Kék szín"
|
||||
PythonColorBrown = "Barna szín"
|
||||
PythonColorGreen = "Zöld szín"
|
||||
PythonColorGray = "Szürke szín"
|
||||
PythonColorOrange = "Narancssárga szín"
|
||||
PythonColorPink = "Rózsaszín szín"
|
||||
PythonColorPurple = "Lila szín"
|
||||
PythonColorRed = "Piros szín"
|
||||
PythonColorWhite = "Fehér szín"
|
||||
PythonColorYellow = "Sárga szín"
|
||||
PythonComplex = "A + ib visszaadása"
|
||||
PythonCopySign = "X visszaadása y jelével"
|
||||
PythonCos = "Koszinusz"
|
||||
PythonCosh = "Hiperbolikus koszinusz"
|
||||
PythonCount = "Számolja az x elöfordulását"
|
||||
PythonDegrees = "x konvertálása radiánokrol fokokra"
|
||||
PythonDivMod = "Hányados és maradék"
|
||||
PythonDrawString = "Szöveg megjelenítése (x, y)-en"
|
||||
PythonErf = "Hiba funkció"
|
||||
PythonErfc = "Kiegészítö hiba funkció"
|
||||
PythonEval = "Visszaadja az értékelt kifejezést"
|
||||
PythonExp = "Exponenciális függvény"
|
||||
PythonExpm1 = "exp(x)-1 sámitása"
|
||||
PythonFabs = "Abszolút érték"
|
||||
PythonFillRect = "Téglalap töltése"
|
||||
PythonFloat = "Konvertálása tizedes számra"
|
||||
PythonFloor = "Egész része"
|
||||
PythonFmod = "a modulo b"
|
||||
PythonFrExp = "X mantissája és kiállítója"
|
||||
PythonGamma = "Gamma funkció"
|
||||
PythonGetPixel = "Visszatéríti (x,y) színét"
|
||||
PythonGetrandbits = "Váletlenszám visszatérítése k biten"
|
||||
PythonGrid = "Rács megjelenítése/elrejtése"
|
||||
PythonHex = "Decimális szám konvertálása hexadecimális számra"
|
||||
PythonHist = "x hisztográmiája"
|
||||
PythonImportCmath = "cmath modul importálása"
|
||||
PythonImportIon = "Ion modul importálása"
|
||||
PythonImportKandinsky = "Kandinsky modul importálása"
|
||||
PythonImportRandom = "Véletlenszerü modul importálása"
|
||||
PythonImportMath = "math modul importálása"
|
||||
PythonImportMatplotlibPyplot = "matplotlib.pyplot modul importálása"
|
||||
PythonImportTurtle = "turtle modul importálása"
|
||||
PythonImportTime = "time modul importálása"
|
||||
PythonIndex = "Az elsö x esemény indexe"
|
||||
PythonInput = "Irjon egy értéket (számot)"
|
||||
PythonInsert = "x-et i. pozícióra helyezze a listában"
|
||||
PythonInt = "egész számra konvertálás"
|
||||
PythonIonFunction = "ion modul funkció elötag"
|
||||
PythonIsFinite = "x véges-e"
|
||||
PythonIsInfinite = "x végtelen-e"
|
||||
PythonIsKeyDown = "True-t válaszol ha a k gomb le van nyomva"
|
||||
PythonIsNaN = "Ellenörizze hogy x nem NaN"
|
||||
PythonKandinskyFunction = "kandinsky modul funkció elötag"
|
||||
PythonKeyLeft = "BAL NYÍL gomb"
|
||||
PythonKeyUp = "FEL NYÍL gomb"
|
||||
PythonKeyDown = "LE NYÍL gomb"
|
||||
PythonKeyRight = "JOBB NYÍL gomb"
|
||||
PythonKeyOk = "OK gomb"
|
||||
PythonKeyBack = "VISSZA gomb"
|
||||
PythonKeyHome = "HOME gomb"
|
||||
PythonKeyOnOff = "ON/OFF gomb"
|
||||
PythonKeyShift = "SHIFT gomb"
|
||||
PythonKeyAlpha = "ALPHA gomb"
|
||||
PythonKeyXnt = "X,N,T gomb"
|
||||
PythonKeyVar = "VAR gomb"
|
||||
PythonKeyToolbox = "TOOLBOX gomb"
|
||||
PythonKeyBackspace = "TÖRLÉS gomb"
|
||||
PythonKeyExp = "EXPONENCIÁLIS gomb"
|
||||
PythonKeyLn = "NEPERIAI LOGARITHM gomb"
|
||||
PythonKeyLog = "DECIMÁLIS LOGARITHM gomb"
|
||||
PythonKeyImaginary = "KÉPZELETBELI I gomb"
|
||||
PythonKeyComma = "VESSZÖ gomb"
|
||||
PythonKeyPower = "KIÁLLÍTÓ gomb"
|
||||
PythonKeySine = "SZINUSZ gomb"
|
||||
PythonKeyCosine = "KOSZINUSZ gomb"
|
||||
PythonKeyTangent = "TANGENS gomb"
|
||||
PythonKeyPi = "PI gomb"
|
||||
PythonKeySqrt = "NÉGYZETGYÖK gomb"
|
||||
PythonKeySquare = "NÉGYZET gomb"
|
||||
PythonKeySeven = "7 gomb"
|
||||
PythonKeyEight = "8 gomb"
|
||||
PythonKeyNine = "9 gomb"
|
||||
PythonKeyLeftParenthesis = "BAL ZÁRÓJEL gomb"
|
||||
PythonKeyRightParenthesis = "JOB ZÁRÓJEL gomb"
|
||||
PythonKeyFour = "4 gomb"
|
||||
PythonKeyFive = "5 gomb"
|
||||
PythonKeySix = "6 gomb"
|
||||
PythonKeyMultiplication = "SZOZÁS gomb"
|
||||
PythonKeyDivision = "OSZTÁS gomb"
|
||||
PythonKeyOne = "1 gomb"
|
||||
PythonKeyTwo = "2 gomb"
|
||||
PythonKeyThree = "3 gomb"
|
||||
PythonKeyPlus = "PLUS gomb"
|
||||
PythonKeyMinus = "MINUS gomb"
|
||||
PythonKeyZero = "0 gomb"
|
||||
PythonKeyDot = "PONT gomb"
|
||||
PythonKeyEe = "10 X KITEVÖ gomb"
|
||||
PythonKeyAns = "ANS gomb"
|
||||
PythonKeyExe = "EXE gomb"
|
||||
PythonLdexp = "frexp ellentéte : x*(2**i)"
|
||||
PythonLength = "Egy targy hossza"
|
||||
PythonLgamma = "Gamma funkció logaritmusa"
|
||||
PythonLog = "a alapú logaritmus"
|
||||
PythonLog10 = "Decimális logaritmus"
|
||||
PythonLog2 = "Bináris logaritmus"
|
||||
PythonMathFunction = "math modul funkció elötag"
|
||||
PythonMatplotlibPyplotFunction = "matplotlib.pyplot elötag"
|
||||
PythonMax = "Maximum"
|
||||
PythonMin = "Minimum"
|
||||
PythonModf = "x-nek tört és egész részei"
|
||||
PythonMonotonic = "Az óra értékét adja vissza"
|
||||
PythonOct = "Decimális szám konvertálása octális számra"
|
||||
PythonPhase = "z fázisa"
|
||||
PythonPlot = "y-t jelöli x függvényében"
|
||||
PythonPolar = "Verctorizálni"
|
||||
PythonPop = "Az utolsó elemet el törölni"
|
||||
PythonPower = "x y. kitevö"
|
||||
PythonPrint = "Ki irni a elemeket"
|
||||
PythonRadians = "Fokról radiánra konvertálni"
|
||||
PythonRandint = "Véletlen egész szám [a;b] -ban"
|
||||
PythonRandom = "Decimális szám [0;1] -ban"
|
||||
PythonRandomFunction = "random modul funkció elötag"
|
||||
PythonRandrange = "Véletlen szám range(start,stop)-ban"
|
||||
PythonRangeStartStop = "start-tol stop-ig listája"
|
||||
PythonRangeStop = "0 tol stop-ig lista"
|
||||
PythonRect = "Algebrai számra konvertálni"
|
||||
PythonRemove = "Elsö x elöfordulását törolni"
|
||||
PythonReverse = "A lista elemeit megfordítani (másik irány)"
|
||||
PythonRound = "N számjegyre kerekítni"
|
||||
PythonScatter = "(x,y) halmaza"
|
||||
PythonSeed = "Inicializálni a véletlenszám-választót"
|
||||
PythonSetPixel = "Az (x,y) pixel-t ki szinezni"
|
||||
PythonShow = "Mutassa az ábrát"
|
||||
PythonSin = "Szinusz"
|
||||
PythonSinh = "Hiperbolikus szinusz"
|
||||
PythonSleep = "t másodpercre meg állitani a programmot"
|
||||
PythonSort = "A listát rendezni"
|
||||
PythonSqrt = "Négyzetgyök"
|
||||
PythonSum = "Összeadni a lista elemeit"
|
||||
PythonTan = "Érintö (tan)"
|
||||
PythonTanh = "Hiperbolikus érintö (tan)"
|
||||
PythonText = "(x,y) nél egy szöveget irni"
|
||||
PythonTimeFunction = "time funkció elötag"
|
||||
PythonTrunc = "Egész csonka (?)"
|
||||
PythonTurtleBackward = "x pixelt hátra"
|
||||
PythonTurtleCircle = "r pixel sugarú kört rajzolni"
|
||||
PythonTurtleColor = "Toll szinét beállitani"
|
||||
PythonTurtleColorMode = "Szin módot 1.0-ra vagy 255-ra állitani"
|
||||
PythonTurtleForward = "x pixelt elölre"
|
||||
PythonTurtleFunction = "turtle modul funkció elötag"
|
||||
PythonTurtleGoto = "Menjen a (x,y) koordinátákra"
|
||||
PythonTurtleHeading = "Visszaadja az aktuális irányt"
|
||||
PythonTurtleHideturtle = "A teknös elrejtése"
|
||||
PythonTurtleIsdown = "True-t válaszol ha a toll irás pozícióban van"
|
||||
PythonTurtleLeft = "a fokkot forduljon balra"
|
||||
PythonTurtlePendown = "Húzza le a tollat"
|
||||
PythonTurtlePensize = "Állítsa a vonalvastagságot x pixelre"
|
||||
PythonTurtlePenup = "Húzza fel a tollat"
|
||||
PythonTurtlePosition = "Az aktuális (x,y) pozíciót visszaadása"
|
||||
PythonTurtleReset = "Visszaállitani a rajzot (torléssel)"
|
||||
PythonTurtleRight = "a fokkot forduljon jobbra"
|
||||
PythonTurtleSetheading = "a fokokra állítja be az irányt"
|
||||
PythonTurtleSetposition = "A teknös pozicioját allitja"
|
||||
PythonTurtleShowturtle = "A teknöst meg mutatni"
|
||||
PythonTurtleSpeed = "Rajzolási sebesség 0 és 10 között"
|
||||
PythonTurtleWrite = "Szöveg irás"
|
||||
PythonUniform = "Lebegöpontos szám [a,b] -ban"
|
||||
PythonImportTime = "time modul importálása"
|
||||
PythonTimePrefix = "time funkció elötag"
|
||||
PythonTimeSleep = "n másodpercet várni"
|
||||
PythonMonotonic = "Meg fordítani a monoton idö"
|
||||
PythonFileOpen = "Fájl megnyitása"
|
||||
PythonFileSeekable = "Seek-et lehete használni"
|
||||
PythonFileSeek = "A kurzort áthelyezni"
|
||||
PythonFileTell = "Visszaadja a kurzor helye"
|
||||
PythonFileClose = "Bezárni egy fájlt"
|
||||
PythonFileClosed = "True ha a fájl bezárva"
|
||||
PythonFileRead = "Olvas 16 bájtig"
|
||||
PythonFileWrite = "b-t irjon a fájlba"
|
||||
PythonFileReadline = "Olvas egy sort vagy 16 bájtig"
|
||||
PythonFileReadlines = "Olvas több sort"
|
||||
PythonFileTruncate = "A fájl átméretezése"
|
||||
PythonFileWritelines = "Irjon több sort"
|
||||
PythonFileName = "A fájl neve"
|
||||
PythonFileMode = "A fájl nyitott módja"
|
||||
PythonFileReadable = "read-et lehete használni"
|
||||
PythonFileWritable = "write-ot lehete használni"
|
||||
PythonImportOs = "os modul importálása"
|
||||
PythonOsUname = "Rendszer informaciók"
|
||||
PythonOsRemove = "Fájl törlése"
|
||||
PythonOsRename = "Fájl átnevezése"
|
||||
PythonOsListdir = "Fájlok listája"
|
||||
@@ -71,6 +71,11 @@ PythonImportMath = "Importa modulo math"
|
||||
PythonImportMatplotlibPyplot = "Importa modulo matplotlib.pyplot"
|
||||
PythonImportTurtle = "Importa del modulo turtle"
|
||||
PythonImportTime = "Importa del modulo time"
|
||||
PythonImportOs = "Importa modulo os"
|
||||
PythonOsUname = "Ottieni informazioni sul sistema"
|
||||
PythonOsRemove = "Rimuovere un file"
|
||||
PythonOsRename = "Rinomina file"
|
||||
PythonOsListdir = "Elenca file"
|
||||
PythonIndex = "Indice prima occorrenza di x"
|
||||
PythonInput = "Inserire un valore"
|
||||
PythonInsert = "Inserire x in posizione i-esima"
|
||||
@@ -195,3 +200,23 @@ PythonTurtleShowturtle = "Mostra la tartaruga"
|
||||
PythonTurtleSpeed = "Velocità di disegno (x tra 0 e 10)"
|
||||
PythonTurtleWrite = "Mostra un testo"
|
||||
PythonUniform = "Numero decimale tra [a,b]"
|
||||
PythonImportTime = "Import time module"
|
||||
PythonTimePrefix = "time module function prefix"
|
||||
PythonTimeSleep = "Wait for n second"
|
||||
PythonMonotonic = "Return monotonic time"
|
||||
PythonFileOpen = "Opens a file"
|
||||
PythonFileSeekable = "Tells if seek can be used on a file"
|
||||
PythonFileSeek = "Move file's cursor"
|
||||
PythonFileTell = "Get file's cursor location"
|
||||
PythonFileClose = "Closes a file"
|
||||
PythonFileClosed = "True if file was closed"
|
||||
PythonFileRead = "Read up to size bytes"
|
||||
PythonFileWrite = "Write b into file"
|
||||
PythonFileReadline = "Reads a line or up to size bytes"
|
||||
PythonFileReadlines = "Reads a list of lines"
|
||||
PythonFileTruncate = "Resize the file to size"
|
||||
PythonFileWritelines = "Writes a list of lines"
|
||||
PythonFileName = "Contains file's name"
|
||||
PythonFileMode = "Contains file's open mode"
|
||||
PythonFileReadable = "Tells if read can be used on a file"
|
||||
PythonFileWritable = "Tells if write can be used on a file"
|
||||
|
||||
@@ -70,6 +70,11 @@ PythonImportRandom = "Importeer random module"
|
||||
PythonImportMath = "Importeer math module"
|
||||
PythonImportMatplotlibPyplot = "Importeer matplotlib.pyplot module"
|
||||
PythonImportTime = "Importeer time module"
|
||||
PythonImportOs = "Importeer os module"
|
||||
PythonOsUname = " Krijg systeeminfo"
|
||||
PythonOsRemove = "Een bestand verwijderen"
|
||||
PythonOsRename = "Hernoem bestand"
|
||||
PythonOsListdir = "Lijstbestanden"
|
||||
PythonImportTurtle = "Importeer turtle module"
|
||||
PythonIndex = "Index van de eerste x aanwezigheden"
|
||||
PythonInput = "Wijs een waarde toe"
|
||||
@@ -195,3 +200,23 @@ PythonTurtleShowturtle = "Laat de schildpad zien"
|
||||
PythonTurtleSpeed = "Tekensnelheid tussen 0 and 10"
|
||||
PythonTurtleWrite = "Display a text"
|
||||
PythonUniform = "Decimaal getal in [a,b]"
|
||||
PythonImportTime = "Import time module"
|
||||
PythonTimePrefix = "time module function prefix"
|
||||
PythonTimeSleep = "Wait for n second"
|
||||
PythonMonotonic = "Return monotonic time"
|
||||
PythonFileOpen = "Opens a file"
|
||||
PythonFileSeekable = "Tells if seek can be used on a file"
|
||||
PythonFileSeek = "Move file's cursor"
|
||||
PythonFileTell = "Get file's cursor location"
|
||||
PythonFileClose = "Closes a file"
|
||||
PythonFileClosed = "True if file was closed"
|
||||
PythonFileRead = "Read up to size bytes"
|
||||
PythonFileWrite = "Write b into file"
|
||||
PythonFileReadline = "Reads a line or up to size bytes"
|
||||
PythonFileReadlines = "Reads a list of lines"
|
||||
PythonFileTruncate = "Resize the file to size"
|
||||
PythonFileWritelines = "Writes a list of lines"
|
||||
PythonFileName = "Contains file's name"
|
||||
PythonFileMode = "Contains file's open mode"
|
||||
PythonFileReadable = "Tells if read can be used on a file"
|
||||
PythonFileWritable = "Tells if write can be used on a file"
|
||||
|
||||
@@ -195,3 +195,28 @@ PythonTurtleShowturtle = "Mostrar o turtle"
|
||||
PythonTurtleSpeed = "Velocidade do desenho entre 0 e 10"
|
||||
PythonTurtleWrite = "Mostrar um texto"
|
||||
PythonUniform = "Número decimal em [a,b]"
|
||||
PythonImportTime = "Import time module"
|
||||
PythonImportOs = "Import os module"
|
||||
PythonOsUname = " Obter informações do sistema"
|
||||
PythonOsRemove = "Remover um ficheiro"
|
||||
PythonOsRename = "Renomear ficheiro"
|
||||
PythonOsListdir = "Listar ficheiros"
|
||||
PythonTimePrefix = "time module function prefix"
|
||||
PythonTimeSleep = "Wait for n second"
|
||||
PythonMonotonic = "Return monotonic time"
|
||||
PythonFileOpen = "Opens a file"
|
||||
PythonFileSeekable = "Tells if seek can be used on a file"
|
||||
PythonFileSeek = "Move file's cursor"
|
||||
PythonFileTell = "Get file's cursor location"
|
||||
PythonFileClose = "Closes a file"
|
||||
PythonFileClosed = "True if file was closed"
|
||||
PythonFileRead = "Read up to size bytes"
|
||||
PythonFileWrite = "Write b into file"
|
||||
PythonFileReadline = "Reads a line or up to size bytes"
|
||||
PythonFileReadlines = "Reads a list of lines"
|
||||
PythonFileTruncate = "Resize the file to size"
|
||||
PythonFileWritelines = "Writes a list of lines"
|
||||
PythonFileName = "Contains file's name"
|
||||
PythonFileMode = "Contains file's open mode"
|
||||
PythonFileReadable = "Tells if read can be used on a file"
|
||||
PythonFileWritable = "Tells if write can be used on a file"
|
||||
|
||||
@@ -86,6 +86,8 @@ PythonCommandImportKandinsky = "import kandinsky"
|
||||
PythonCommandImportMath = "import math"
|
||||
PythonCommandImportMatplotlibPyplot = "import matplotlib.pyplot"
|
||||
PythonCommandImportRandom = "import random"
|
||||
PythonCommandImportOs = "import os"
|
||||
PythonCommandImportFromOs = "from os import *"
|
||||
PythonCommandImportTime = "import time"
|
||||
PythonCommandImportTurtle = "import turtle"
|
||||
PythonCommandIndex = "list.index(x)"
|
||||
@@ -212,6 +214,12 @@ PythonCommandTurtleFunctionWithoutArg = "turtle.\x11"
|
||||
PythonCommandUniform = "uniform(a,b)"
|
||||
PythonConstantE = "2.718281828459045"
|
||||
PythonConstantPi = "3.141592653589793"
|
||||
PythonOsCommandUname = "uname()"
|
||||
PythonOsCommandRemove = "remove(filename)"
|
||||
PythonOsCommandRename = "rename(oldname, newname)"
|
||||
PythonOsCommandRemoveWithoutArg = "remove(\x11)"
|
||||
PythonOsCommandRenameWithoutArg = "rename(\x11,)"
|
||||
PythonOsCommandListdir = "listdir()"
|
||||
PythonTurtleCommandBackward = "backward(x)"
|
||||
PythonTurtleCommandCircle = "circle(r)"
|
||||
PythonTurtleCommandColor = "color('c')"
|
||||
@@ -232,4 +240,43 @@ PythonTurtleCommandSetheading = "setheading(a)"
|
||||
PythonTurtleCommandSetposition = "setposition(x,[y])"
|
||||
PythonTurtleCommandShowturtle = "showturtle()"
|
||||
PythonTurtleCommandSpeed = "speed(x)"
|
||||
PythonTurtleCommandWhite = "'white'"
|
||||
PythonTurtleCommandYellow = "'yellow'"
|
||||
PythonTimeModule = "time"
|
||||
PythonTimeCommandImportFrom = "from time import *"
|
||||
PythonTimeCommandSleep = "sleep()"
|
||||
PythonTimeCommandSleepDemo = "sleep(n)"
|
||||
PythonTimeCommandMonotonic = "monotonic()"
|
||||
PythonCommandFileOpen = "open(name, [mode])"
|
||||
PythonCommandFileOpenWithoutArg = "open(\x11)"
|
||||
PythonCommandFileSeek = "file.seek(offset, [whence])"
|
||||
PythonCommandFileSeekWithoutArg = ".seek(\x11)"
|
||||
PythonCommandFileTell = "file.tell()"
|
||||
PythonCommandFileTellWithoutArg = ".tell()"
|
||||
PythonCommandFileSeekable = "file.seekable()"
|
||||
PythonCommandFileSeekableWithoutArg = ".seekable()"
|
||||
PythonCommandFileClose = "file.close()"
|
||||
PythonCommandFileCloseWithoutArg = ".close()"
|
||||
PythonCommandFileClosed = "file.closed"
|
||||
PythonCommandFileClosedWithoutArg = ".closed"
|
||||
PythonCommandFileRead = "file.read([size])"
|
||||
PythonCommandFileReadWithoutArg = ".read(\x11)"
|
||||
PythonCommandFileWrite = "file.write(b)"
|
||||
PythonCommandFileWriteWithoutArg = ".write(\x11)"
|
||||
PythonCommandFileReadline = "file.readline([size])"
|
||||
PythonCommandFileReadlineWithoutArg = ".readline(\x11)"
|
||||
PythonCommandFileReadlines = "file.readlines([hint])"
|
||||
PythonCommandFileReadlinesWithoutArg = ".readlines(\x11)"
|
||||
PythonCommandFileTruncate = "file.truncate([size])"
|
||||
PythonCommandFileTruncateWithoutArg = ".truncate(\x11)"
|
||||
PythonCommandFileWritelines = "file.writelines(lines)"
|
||||
PythonCommandFileWritelinesWithoutArg = ".writelines(\x11)"
|
||||
PythonCommandFileName = "file.name"
|
||||
PythonCommandFileNameWithoutArg = ".name"
|
||||
PythonCommandFileMode = "file.mode"
|
||||
PythonCommandFileModeWithoutArg = ".mode"
|
||||
PythonCommandFileReadable = "file.readable()"
|
||||
PythonCommandFileReadableWithoutArg = ".readable()"
|
||||
PythonCommandFileWritable = "file.writable()"
|
||||
PythonCommandFileWritableWithoutArg = ".writable()"
|
||||
PythonTurtleCommandWrite = "write(\"text\")"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <escher/metric.h>
|
||||
#include <poincare/preferences.h>
|
||||
#include <apps/global_preferences.h>
|
||||
#include <apps/apps_container.h>
|
||||
#include <python/port/helpers.h>
|
||||
@@ -39,7 +40,7 @@ ConsoleController::ConsoleController(Responder * parentResponder, App * pythonDe
|
||||
#endif
|
||||
{
|
||||
m_selectableTableView.setMargins(0, Metric::CommonRightMargin, 0, Metric::TitleBarExternHorizontalMargin);
|
||||
m_selectableTableView.setBackgroundColor(KDColorWhite);
|
||||
m_selectableTableView.setBackgroundColor(Palette::CodeBackground);
|
||||
m_editCell.setPrompt(sStandardPromptText);
|
||||
for (int i = 0; i < k_numberOfLineCells; i++) {
|
||||
m_cells[i].setParentResponder(&m_selectableTableView);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <escher.h>
|
||||
#include <python/port/port.h>
|
||||
#include <poincare/preferences.h>
|
||||
|
||||
#include "console_edit_cell.h"
|
||||
#include "console_line_cell.h"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <escher/text_field.h>
|
||||
#include <escher/text_field_delegate.h>
|
||||
#include <escher/pointer_text_view.h>
|
||||
#include <poincare/preferences.h>
|
||||
|
||||
namespace Code {
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ void ConsoleLineCell::ScrollableConsoleLineView::ConsoleLineView::setLine(Consol
|
||||
}
|
||||
|
||||
void ConsoleLineCell::ScrollableConsoleLineView::ConsoleLineView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
ctx->fillRect(bounds(), KDColorWhite);
|
||||
ctx->drawString(m_line->text(), KDPointZero, GlobalPreferences::sharedGlobalPreferences()->font(), textColor(m_line), isHighlighted()? Palette::Select : KDColorWhite);
|
||||
ctx->fillRect(bounds(), Palette::CodeBackground);
|
||||
ctx->drawString(m_line->text(), KDPointZero, GlobalPreferences::sharedGlobalPreferences()->font(), textColor(m_line), isHighlighted()? Palette::Select : Palette::BackgroundApps);
|
||||
}
|
||||
|
||||
KDSize ConsoleLineCell::ScrollableConsoleLineView::ConsoleLineView::minimalSizeForOptimalDisplay() const {
|
||||
|
||||
@@ -53,7 +53,7 @@ private:
|
||||
ConsoleLineView m_consoleLineView;
|
||||
};
|
||||
static KDColor textColor(ConsoleLine * line) {
|
||||
return line->isFromCurrentSession() ? KDColorBlack : Palette::GrayDark;
|
||||
return line->isFromCurrentSession() ? Palette::CodeText : Palette::SecondaryText;
|
||||
}
|
||||
MessageTextView m_promptView;
|
||||
ScrollableConsoleLineView m_scrollableView;
|
||||
|
||||
@@ -80,6 +80,7 @@ bool EditorController::textAreaDidReceiveEvent(TextArea * textArea, Ion::Events:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (event == Ion::Events::Backspace && textArea->selectionIsEmpty()) {
|
||||
/* If the cursor is on the left of the text of a line, backspace one
|
||||
* indentation space at a time. */
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <apps/global_preferences.h>
|
||||
#include <poincare/integer.h>
|
||||
#include <escher/app.h>
|
||||
#include <escher/palette.h>
|
||||
#include <poincare/preferences.h>
|
||||
|
||||
namespace Code {
|
||||
|
||||
@@ -57,8 +57,8 @@ void EditorView::layoutSubviews(bool force) {
|
||||
/* EditorView::GutterView */
|
||||
|
||||
void EditorView::GutterView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
KDColor textColor = Palette::BlueishGray;
|
||||
KDColor backgroundColor = KDColor::RGB24(0xE4E6E7);
|
||||
KDColor textColor = Palette::PrimaryText;
|
||||
KDColor backgroundColor = Palette::CodeGutterViewBackground;
|
||||
|
||||
ctx->fillRect(rect, backgroundColor);
|
||||
|
||||
@@ -102,7 +102,7 @@ void EditorView::GutterView::setOffset(KDCoordinate offset) {
|
||||
|
||||
KDSize EditorView::GutterView::minimalSizeForOptimalDisplay() const {
|
||||
int numberOfChars = 2; // TODO: Could be computed
|
||||
return KDSize(2 * k_margin + numberOfChars * m_font->glyphSize().width(), 0);
|
||||
return KDSize(2 * k_margin + numberOfChars * Poincare::Preferences::sharedPreferences()->KDPythonFont()->glyphSize().width(), 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "../apps_container.h"
|
||||
#include <assert.h>
|
||||
#include <escher/metric.h>
|
||||
#include <ion.h>
|
||||
#include <ion/events.h>
|
||||
#include <ion/unicode/utf8_decoder.h>
|
||||
|
||||
@@ -134,6 +135,18 @@ void MenuController::renameSelectedScript() {
|
||||
tf->setCursorLocation(tf->text() + strlen(previousText));
|
||||
}
|
||||
|
||||
void MenuController::duplicateScript(Script script) {
|
||||
assert(!script.isNull());
|
||||
|
||||
// Clone here
|
||||
char buffer[10];
|
||||
Script::DefaultName(buffer, 10);
|
||||
|
||||
Ion::Storage::sharedStorage()->createRecordWithExtension(buffer, Code::ScriptStore::k_scriptExtension, script.value().buffer, script.value().size);
|
||||
|
||||
updateAddScriptRowDisplay();
|
||||
}
|
||||
|
||||
void MenuController::deleteScript(Script script) {
|
||||
assert(!script.isNull());
|
||||
script.destroy();
|
||||
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
StackViewController * stackViewController();
|
||||
void willExitResponderChain(Responder * nextFirstResponder) override;
|
||||
void renameSelectedScript();
|
||||
void duplicateScript(Script script);
|
||||
void deleteScript(Script script);
|
||||
void reloadConsole();
|
||||
void openConsoleWithScript(Script script);
|
||||
|
||||
@@ -13,16 +13,15 @@ extern "C" {
|
||||
|
||||
namespace Code {
|
||||
|
||||
constexpr KDColor CommentColor = KDColor::RGB24(0x999988);
|
||||
constexpr KDColor NumberColor = KDColor::RGB24(0x009999);
|
||||
constexpr KDColor KeywordColor = KDColor::RGB24(0xFF000C);
|
||||
constexpr KDColor CommentColor = Palette::CodeComment;
|
||||
constexpr KDColor NumberColor = Palette::CodeNumber;
|
||||
constexpr KDColor KeywordColor = Palette::CodeKeyword;
|
||||
// constexpr KDColor BuiltinColor = KDColor::RGB24(0x0086B3);
|
||||
constexpr KDColor OperatorColor = KDColor::RGB24(0xd73a49);
|
||||
constexpr KDColor StringColor = KDColor::RGB24(0x032f62);
|
||||
constexpr KDColor AutocompleteColor = KDColor::RGB24(0xC6C6C6);
|
||||
constexpr KDColor BackgroundColor = KDColorWhite;
|
||||
constexpr KDColor HighlightColor = Palette::Select;
|
||||
constexpr KDColor DefaultColor = KDColorBlack;
|
||||
constexpr KDColor OperatorColor = Palette::CodeOperator;
|
||||
constexpr KDColor StringColor = Palette::CodeString;
|
||||
constexpr KDColor BackgroundColor = Palette::CodeBackground;
|
||||
constexpr KDColor HighlightColor = Palette::CodeBackgroundSelected;
|
||||
constexpr KDColor AutocompleteColor = KDColor::RGB24(0xC6C6C6); // TODO Palette change
|
||||
|
||||
static inline KDColor TokenColor(mp_token_kind_t tokenKind) {
|
||||
if (tokenKind == MP_TOKEN_STRING) {
|
||||
@@ -123,7 +122,7 @@ static inline KDColor TokenColor(mp_token_kind_t tokenKind) {
|
||||
{
|
||||
return OperatorColor;
|
||||
}
|
||||
return DefaultColor;
|
||||
return Palette::CodeText;
|
||||
}
|
||||
|
||||
static inline size_t TokenLength(mp_lexer_t * lex, const char * tokenPosition) {
|
||||
@@ -286,7 +285,7 @@ void PythonTextArea::ContentView::drawLine(KDContext * ctx, int line, const char
|
||||
tokenEnd = tokenFrom + tokenLength;
|
||||
|
||||
// If the token is being autocompleted, use DefaultColor
|
||||
KDColor color = (tokenFrom <= autocompleteStart && autocompleteStart < tokenEnd) ? DefaultColor : TokenColor(lex->tok_kind);
|
||||
KDColor color = (tokenFrom <= autocompleteStart && autocompleteStart < tokenEnd) ? Palette::CodeText : TokenColor(lex->tok_kind);
|
||||
|
||||
LOG_DRAW("Draw \"%.*s\" for token %d\n", tokenLength, tokenFrom, lex->tok_kind);
|
||||
drawStringAt(ctx, line,
|
||||
|
||||
@@ -256,6 +256,15 @@ const ToolboxMessageTree TimeModuleChildren[] = {
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandSleep, I18n::Message::PythonSleep)
|
||||
};
|
||||
|
||||
const ToolboxMessageTree OsModuleChildren[] = {
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportOs, I18n::Message::PythonImportOs, false),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportFromOs, I18n::Message::PythonImportOs, false),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonOsCommandUname, I18n::Message::PythonOsUname, false),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonOsCommandRemove, I18n::Message::PythonOsRemove, false, I18n::Message::PythonOsCommandRemoveWithoutArg),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonOsCommandRename, I18n::Message::PythonOsRename, false, I18n::Message::PythonOsCommandRenameWithoutArg),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonOsCommandListdir, I18n::Message::PythonOsListdir, false)
|
||||
};
|
||||
|
||||
const ToolboxMessageTree modulesChildren[] = {
|
||||
ToolboxMessageTree::Node(I18n::Message::MathModule, MathModuleChildren),
|
||||
ToolboxMessageTree::Node(I18n::Message::CmathModule, CMathModuleChildren),
|
||||
@@ -264,6 +273,7 @@ const ToolboxMessageTree modulesChildren[] = {
|
||||
ToolboxMessageTree::Node(I18n::Message::RandomModule, RandomModuleChildren),
|
||||
ToolboxMessageTree::Node(I18n::Message::KandinskyModule, KandinskyModuleChildren),
|
||||
ToolboxMessageTree::Node(I18n::Message::IonModule, IonModuleChildren),
|
||||
ToolboxMessageTree::Node(I18n::Message::OsModule, OsModuleChildren),
|
||||
ToolboxMessageTree::Node(I18n::Message::TimeModule, TimeModuleChildren)
|
||||
};
|
||||
|
||||
@@ -435,11 +445,39 @@ const ToolboxMessageTree functionsChildren[] = {
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandReturn, I18n::Message::Default)
|
||||
};
|
||||
|
||||
const ToolboxMessageTree fileChildren[] {
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileOpen, I18n::Message::PythonFileOpen, false, I18n::Message::PythonCommandFileOpenWithoutArg),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileClose, I18n::Message::PythonFileClose, false, I18n::Message::PythonCommandFileCloseWithoutArg),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileClosed, I18n::Message::PythonFileClosed, false, I18n::Message::PythonCommandFileClosedWithoutArg),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileMode, I18n::Message::PythonFileMode, false, I18n::Message::PythonCommandFileModeWithoutArg),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileName, I18n::Message::PythonFileName, false, I18n::Message::PythonCommandFileNameWithoutArg),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileRead, I18n::Message::PythonFileRead, false, I18n::Message::PythonCommandFileReadWithoutArg),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileReadable, I18n::Message::PythonFileReadable, false, I18n::Message::PythonCommandFileReadableWithoutArg),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileReadline, I18n::Message::PythonFileReadline, false, I18n::Message::PythonCommandFileReadlineWithoutArg),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileReadlines, I18n::Message::PythonFileReadlines, false, I18n::Message::PythonCommandFileReadlinesWithoutArg),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileSeek, I18n::Message::PythonFileSeek, false, I18n::Message::PythonCommandFileSeekWithoutArg),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileSeekable, I18n::Message::PythonFileSeekable, false, I18n::Message::PythonCommandFileSeekableWithoutArg),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileTell, I18n::Message::PythonFileTell, false, I18n::Message::PythonCommandFileTellWithoutArg),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileTruncate, I18n::Message::PythonFileTruncate, false, I18n::Message::PythonCommandFileTruncateWithoutArg),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileWrite, I18n::Message::PythonFileWrite, false, I18n::Message::PythonCommandFileWriteWithoutArg),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileWritable, I18n::Message::PythonFileWritable, false, I18n::Message::PythonCommandFileWritableWithoutArg),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFileWritelines, I18n::Message::PythonFileWritelines, false, I18n::Message::PythonCommandFileWritelinesWithoutArg),
|
||||
};
|
||||
|
||||
const ToolboxMessageTree exceptionsChildren[] = {
|
||||
ToolboxMessageTree::Leaf(I18n::Message::TryExcept1ErrorWithArg, I18n::Message::Default, false, I18n::Message::TryExcept1Error),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::TryExcept1ErrorElseWithArg, I18n::Message::Default, false, I18n::Message::TryExcept1ErrorElse),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::TryExcept2ErrorWithArg, I18n::Message::Default, false, I18n::Message::TryExcept2Error),
|
||||
ToolboxMessageTree::Leaf(I18n::Message::WithInstructionWithArg, I18n::Message::Default, false, I18n::Message::WithInstruction),
|
||||
};
|
||||
|
||||
const ToolboxMessageTree menu[] = {
|
||||
ToolboxMessageTree::Node(I18n::Message::LoopsAndTests, loopsAndTestsChildren),
|
||||
ToolboxMessageTree::Node(I18n::Message::Modules, modulesChildren),
|
||||
ToolboxMessageTree::Node(I18n::Message::Catalog, catalogChildren),
|
||||
ToolboxMessageTree::Node(I18n::Message::Functions, functionsChildren)
|
||||
ToolboxMessageTree::Node(I18n::Message::Functions, functionsChildren),
|
||||
ToolboxMessageTree::Node(I18n::Message::Files, fileChildren),
|
||||
ToolboxMessageTree::Node(I18n::Message::Exceptions, exceptionsChildren)
|
||||
};
|
||||
|
||||
const ToolboxMessageTree toolboxModel = ToolboxMessageTree::Node(I18n::Message::Toolbox, menu);
|
||||
@@ -479,7 +517,7 @@ bool PythonToolbox::handleEvent(Ion::Events::Event event) {
|
||||
}
|
||||
|
||||
KDCoordinate PythonToolbox::rowHeight(int j) {
|
||||
if (typeAtLocation(0, j) == Toolbox::LeafCellType && m_messageTreeModel->label() == I18n::Message::IfStatementMenu) {
|
||||
if (typeAtLocation(0, j) == Toolbox::LeafCellType && (m_messageTreeModel->label() == I18n::Message::IfStatementMenu || m_messageTreeModel->label() == I18n::Message::Exceptions)) {
|
||||
/* To get the exact height needed for each cell, we have to compute its
|
||||
* text size, which means scan the text char by char to look for '\n'
|
||||
* chars. This is very costly and ruins the speed performance when
|
||||
|
||||
@@ -16,10 +16,10 @@ public:
|
||||
|
||||
// Toolbox
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
const ToolboxMessageTree * rootModel() const override;
|
||||
protected:
|
||||
KDCoordinate rowHeight(int j) override;
|
||||
bool selectLeaf(int selectedRow) override;
|
||||
const ToolboxMessageTree * rootModel() const override;
|
||||
MessageTableCellWithMessage * leafCellAtIndex(int index) override;
|
||||
MessageTableCellWithChevron* nodeCellAtIndex(int index) override;
|
||||
int maxNumberOfDisplayedRows() override;
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Code {
|
||||
|
||||
SandboxController::SandboxController(Responder * parentResponder) :
|
||||
ViewController(parentResponder),
|
||||
m_solidColorView(KDColorWhite)
|
||||
m_solidColorView(Palette::CodeBackground)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ constexpr char ScriptNodeCell::k_parentheses[];
|
||||
constexpr char ScriptNodeCell::k_parenthesesWithEmpty[];
|
||||
|
||||
void ScriptNodeCell::ScriptNodeView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
const KDColor backgroundColor = isHighlighted()? Palette::Select : KDColorWhite;
|
||||
const KDColor backgroundColor = isHighlighted()? Palette::CodeBackgroundSelected : Palette::CodeBackground;
|
||||
|
||||
// If it exists, draw the description name.
|
||||
const char * descriptionName = m_scriptNode->description();
|
||||
@@ -32,7 +32,7 @@ void ScriptNodeCell::ScriptNodeView::drawRect(KDContext * ctx, KDRect rect) cons
|
||||
const char * sourceName = m_scriptNode->nodeSourceName();
|
||||
if (sourceName != nullptr) {
|
||||
KDSize sourceNameSize = k_font->stringSize(sourceName);
|
||||
ctx->drawString(sourceName, KDPoint(m_frame.width() - sourceNameSize.width(), nodeNameY), k_font, Palette::GrayDark, backgroundColor);
|
||||
ctx->drawString(sourceName, KDPoint(m_frame.width() - sourceNameSize.width(), nodeNameY), k_font, Palette::CodeText, backgroundColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "script_parameter_controller.h"
|
||||
#include "menu_controller.h"
|
||||
#include <poincare/integer.h>
|
||||
|
||||
namespace Code {
|
||||
|
||||
@@ -10,6 +11,8 @@ ScriptParameterController::ScriptParameterController(Responder * parentResponder
|
||||
m_renameScript(I18n::Message::Rename),
|
||||
m_autoImportScript(I18n::Message::AutoImportScript),
|
||||
m_deleteScript(I18n::Message::DeleteScript),
|
||||
m_duplicateScript(I18n::Message::DuplicateScript),
|
||||
m_size(I18n::Message::ScriptSize),
|
||||
m_selectableTableView(this),
|
||||
m_script(Ion::Storage::Record()),
|
||||
m_menuController(menuController)
|
||||
@@ -47,7 +50,18 @@ bool ScriptParameterController::handleEvent(Ion::Events::Event event) {
|
||||
m_menuController->reloadConsole();
|
||||
Container::activeApp()->setFirstResponder(&m_selectableTableView);
|
||||
return true;
|
||||
case 3:
|
||||
case 3:{
|
||||
MessageTableCellWithBuffer * myCell = (MessageTableCellWithBuffer *)m_selectableTableView.selectedCell();
|
||||
m_sizedisplaypercent = !m_sizedisplaypercent;
|
||||
GetScriptSize(myCell);
|
||||
return true;
|
||||
}
|
||||
case 4:
|
||||
dismissScriptParameterController();
|
||||
m_menuController->duplicateScript(s);
|
||||
m_menuController->reloadConsole();
|
||||
return true;
|
||||
case 5:
|
||||
dismissScriptParameterController();
|
||||
m_menuController->deleteScript(s);
|
||||
m_menuController->reloadConsole();
|
||||
@@ -74,7 +88,7 @@ void ScriptParameterController::didBecomeFirstResponder() {
|
||||
HighlightCell * ScriptParameterController::reusableCell(int index) {
|
||||
assert(index >= 0);
|
||||
assert(index < k_totalNumberOfCell);
|
||||
HighlightCell * cells[] = {&m_executeScript, &m_renameScript, &m_autoImportScript, &m_deleteScript};
|
||||
HighlightCell * cells[] = {&m_executeScript, &m_renameScript, &m_autoImportScript, &m_size, &m_duplicateScript, &m_deleteScript};
|
||||
return cells[index];
|
||||
}
|
||||
|
||||
@@ -82,6 +96,35 @@ void ScriptParameterController::willDisplayCellForIndex(HighlightCell * cell, in
|
||||
if (cell == &m_autoImportScript) {
|
||||
SwitchView * switchView = (SwitchView *)m_autoImportScript.accessoryView();
|
||||
switchView->setState(m_script.autoImportationStatus());
|
||||
} else if (cell == &m_size) {
|
||||
MessageTableCellWithBuffer * myCell = (MessageTableCellWithBuffer *)cell;
|
||||
GetScriptSize(myCell);
|
||||
myCell->setAccessoryFont(KDFont::SmallFont);
|
||||
myCell->setAccessoryTextColor(Palette::SecondaryText);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptParameterController::GetScriptSize(MessageTableCellWithBuffer* myCell){
|
||||
if(m_sizedisplaypercent){
|
||||
char size[18];
|
||||
int sizelen = Poincare::Integer((int)m_script.value().size).serialize(size, 6);
|
||||
size[sizelen] = ' ';
|
||||
size[sizelen+1] = 'o';
|
||||
size[sizelen+2] = ' ';
|
||||
size[sizelen+3] = '/';
|
||||
size[sizelen+4] = ' ';
|
||||
int sizelen2 = Poincare::Integer((int)Ion::Storage::k_storageSize).serialize(size+sizelen+5, 6) + sizelen + 5;
|
||||
size[sizelen2] = ' ';
|
||||
size[sizelen2+1] = 'o';
|
||||
size[sizelen2+2] = '\0';
|
||||
myCell->setAccessoryText(size);
|
||||
}else{
|
||||
char size[18];
|
||||
int sizelen = Poincare::Integer((int)(((float)((int)m_script.value().size)/((int)Ion::Storage::k_storageSize)) * 100.f)).serialize(size, 3);
|
||||
size[sizelen] = ' ';
|
||||
size[sizelen+1] = '%';
|
||||
size[sizelen+2] = '\0';
|
||||
myCell->setAccessoryText(size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,16 +31,20 @@ public:
|
||||
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
|
||||
|
||||
private:
|
||||
constexpr static int k_totalNumberOfCell = 4;
|
||||
constexpr static int k_totalNumberOfCell = 6;
|
||||
StackViewController * stackViewController();
|
||||
I18n::Message m_pageTitle;
|
||||
MessageTableCell m_executeScript;
|
||||
MessageTableCell m_renameScript;
|
||||
MessageTableCellWithSwitch m_autoImportScript;
|
||||
MessageTableCell m_deleteScript;
|
||||
MessageTableCell m_duplicateScript;
|
||||
MessageTableCellWithBuffer m_size;
|
||||
void GetScriptSize(MessageTableCellWithBuffer* myCell);
|
||||
SelectableTableView m_selectableTableView;
|
||||
Script m_script;
|
||||
MenuController * m_menuController;
|
||||
bool m_sizedisplaypercent = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ def mandelbrot(N_iteration):
|
||||
z = z*z+c
|
||||
# Choose the color of the dot from the Mandelbrot sequence
|
||||
rgb = int(255*i/N_iteration)
|
||||
col = kandinsky.color(int(rgb),int(rgb*0.75),int(rgb*0.25))
|
||||
col = kandinsky.color(int(rgb*0.82),int(rgb*0.13),int(rgb*0.18))
|
||||
# Draw a pixel colored in 'col' at position (x,y)
|
||||
kandinsky.set_pixel(x,y,col))");
|
||||
|
||||
|
||||
@@ -2,3 +2,5 @@ Functions = "Funktionen"
|
||||
Catalog = "Katalog"
|
||||
Modules = "Module"
|
||||
LoopsAndTests = "Schleifen und Tests"
|
||||
Files = "Dateien"
|
||||
Exceptions = "Ausnahmen"
|
||||
|
||||
@@ -2,3 +2,5 @@ Functions = "Functions"
|
||||
Catalog = "Catalog"
|
||||
Modules = "Modules"
|
||||
LoopsAndTests = "Loops and tests"
|
||||
Files = "Files"
|
||||
Exceptions = "Exceptions"
|
||||
|
||||
@@ -2,3 +2,5 @@ Functions = "Functions"
|
||||
Catalog = "Catalog"
|
||||
Modules = "Modules"
|
||||
LoopsAndTests = "Loops and tests"
|
||||
Files = "Files"
|
||||
Exceptions = "Exceptions"
|
||||
|
||||
@@ -2,3 +2,5 @@ Functions = "Fonctions"
|
||||
Catalog = "Catalogue"
|
||||
Modules = "Modules"
|
||||
LoopsAndTests = "Boucles et tests"
|
||||
Files = "Fichiers"
|
||||
Exceptions = "Exceptions"
|
||||
|
||||
6
apps/code/toolbox.hu.i18n
Normal file
6
apps/code/toolbox.hu.i18n
Normal file
@@ -0,0 +1,6 @@
|
||||
Functions = "Funkciók"
|
||||
Catalog = "Katalógus"
|
||||
Modules = "Modulok"
|
||||
LoopsAndTests = "Hurkok és tesztek"
|
||||
Files = "Fájlok"
|
||||
Exceptions = "Kivételek"
|
||||
@@ -2,3 +2,5 @@ Functions = "Funzioni"
|
||||
Catalog = "Catalogo"
|
||||
Modules = "Moduli"
|
||||
LoopsAndTests = "Cicli e test"
|
||||
Files = "Files"
|
||||
Exceptions = "Exceptions"
|
||||
|
||||
@@ -2,3 +2,5 @@ Functions = "Functies"
|
||||
Catalog = "Catalogus"
|
||||
Modules = "Modules"
|
||||
LoopsAndTests = "Herhalingen en testen"
|
||||
Files = "Files"
|
||||
Exceptions = "Exceptions"
|
||||
|
||||
@@ -2,3 +2,5 @@ Functions = "Funções"
|
||||
Catalog = "Catálogo"
|
||||
Modules = "Módulos"
|
||||
LoopsAndTests = "Laços e testes"
|
||||
Files = "Files"
|
||||
Exceptions = "Exceptions"
|
||||
|
||||
@@ -3,6 +3,7 @@ IonModule = "ion"
|
||||
KandinskyModule = "kandinsky"
|
||||
MathModule = "math"
|
||||
MatplotlibPyplotModule = "matplotlib.pyplot"
|
||||
OsModule = "os"
|
||||
TimeModule = "time"
|
||||
TurtleModule = "turtle"
|
||||
ForLoopMenu = "For"
|
||||
@@ -44,6 +45,14 @@ ForInRange2ArgsLoop = "for i in range(\x11,):\n "
|
||||
ForInRange2ArgsLoopWithArg = "for i in range(start, stop):\n instruction"
|
||||
ForInRange1ArgLoop = "for i in range(\x11):\n "
|
||||
ForInRange1ArgLoopWithArg = "for i in range(size):\n instruction"
|
||||
TryExcept1Error = "try:\n \nexcept \x11:\n "
|
||||
TryExcept1ErrorWithArg = "try:\n instruction\nexcept Error:\n reaction"
|
||||
TryExcept1ErrorElse = "try:\n \nexcept \x11:\n \nelse:\n "
|
||||
TryExcept1ErrorElseWithArg = "try:\n instruction\nexcept Error:\n reaction\nelse:\n clean"
|
||||
TryExcept2Error = "try:\n \nexcept (\x11):\n "
|
||||
TryExcept2ErrorWithArg = "try:\n instruction\nexcept (Error1, Error2):\n reaction"
|
||||
WithInstruction = "with \x11 as :\n "
|
||||
WithInstructionWithArg = "with expression as target:\n instructions"
|
||||
PythonCommandDef = "def \x11():\n "
|
||||
PythonCommandDefWithArg = "def function(x):"
|
||||
PythonCommandReturn = "return "
|
||||
|
||||
@@ -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::BlueishGray);
|
||||
m_subtitleCells[i].setTextColor(Palette::SecondaryText);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ I18n::Message examModeActivationWarningMessage(GlobalPreferences::ExamMode mode,
|
||||
|
||||
// Exam mode behaviour
|
||||
KDColor examModeColor(GlobalPreferences::ExamMode mode);
|
||||
bool appIsForbiddenInExamMode(I18n::Message appName, GlobalPreferences::ExamMode mode);
|
||||
bool appIsForbiddenInExamMode(App::Descriptor::ExaminationLevel appExaminationLevel, GlobalPreferences::ExamMode mode);
|
||||
bool exactExpressionsAreForbidden(GlobalPreferences::ExamMode mode);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
#include "exam_mode_configuration.h"
|
||||
|
||||
constexpr Shared::SettingsMessageTree ExamModeConfiguration::s_modelExamChildren[] = {Shared::SettingsMessageTree(I18n::Message::ActivateExamMode), Shared::SettingsMessageTree(I18n::Message::Default)};
|
||||
using namespace Poincare;
|
||||
|
||||
constexpr Shared::SettingsMessageTree s_examModeMode[] = {Shared::SettingsMessageTree(I18n::Message::ExamModeModeStandard), Shared::SettingsMessageTree(I18n::Message::ExamModeModeNoSym), Shared::SettingsMessageTree(I18n::Message::ExamModeModeNoSymNoText)};
|
||||
constexpr Shared::SettingsMessageTree ExamModeConfiguration::s_modelExamChildren[] = {Shared::SettingsMessageTree(I18n::Message::ExamModeMode, s_examModeMode), Shared::SettingsMessageTree(I18n::Message::ActivateExamMode)};
|
||||
|
||||
int ExamModeConfiguration::numberOfAvailableExamMode() {
|
||||
return 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
GlobalPreferences::ExamMode ExamModeConfiguration::examModeAtIndex(int index) {
|
||||
return GlobalPreferences::ExamMode::Standard;
|
||||
return (s_modelExamChildren[index].label() == I18n::Message::ExamModeModeStandard) ? GlobalPreferences::ExamMode::Standard : GlobalPreferences::ExamMode::NoSym;
|
||||
}
|
||||
|
||||
I18n::Message ExamModeConfiguration::examModeActivationMessage(int index) {
|
||||
@@ -19,20 +22,23 @@ I18n::Message ExamModeConfiguration::examModeActivationWarningMessage(GlobalPref
|
||||
I18n::Message warnings[] = {I18n::Message::ExitExamMode1, I18n::Message::ExitExamMode2, I18n::Message::Default};
|
||||
return warnings[line];
|
||||
}
|
||||
assert(mode == GlobalPreferences::ExamMode::Standard);
|
||||
assert(mode == GlobalPreferences::ExamMode::Standard || mode == GlobalPreferences::ExamMode::NoSym || mode == GlobalPreferences::ExamMode::NoSymNoText);
|
||||
I18n::Message warnings[] = {I18n::Message::ActiveExamModeMessage1, I18n::Message::ActiveExamModeMessage2, I18n::Message::ActiveExamModeMessage3};
|
||||
return warnings[line];
|
||||
}
|
||||
|
||||
KDColor ExamModeConfiguration::examModeColor(GlobalPreferences::ExamMode mode) {
|
||||
assert(mode == GlobalPreferences::ExamMode::Standard);
|
||||
assert(mode == GlobalPreferences::ExamMode::Standard || mode == GlobalPreferences::ExamMode::NoSym || mode == GlobalPreferences::ExamMode::NoSymNoText);
|
||||
return KDColorRed;
|
||||
}
|
||||
|
||||
bool ExamModeConfiguration::appIsForbiddenInExamMode(I18n::Message appName, GlobalPreferences::ExamMode mode) {
|
||||
bool ExamModeConfiguration::appIsForbiddenInExamMode(App::Descriptor::ExaminationLevel appExaminationLevel, GlobalPreferences::ExamMode mode) {
|
||||
if (mode == GlobalPreferences::ExamMode::NoSymNoText) {
|
||||
return appExaminationLevel == App::Descriptor::ExaminationLevel::Basic;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ExamModeConfiguration::exactExpressionsAreForbidden(GlobalPreferences::ExamMode mode) {
|
||||
return false;
|
||||
}
|
||||
return mode == GlobalPreferences::ExamMode::NoSymNoText ? true : false;
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
|
||||
// Caution: Dutch exam mode is subject to a compliance certification by a government agency. Distribution of a non-certified Dutch exam mode is illegal.
|
||||
|
||||
#include "exam_mode_configuration.h"
|
||||
|
||||
constexpr Shared::SettingsMessageTree ExamModeConfiguration::s_modelExamChildren[2] = {Shared::SettingsMessageTree(I18n::Message::ActivateExamMode), Shared::SettingsMessageTree(I18n::Message::ActivateDutchExamMode)};
|
||||
|
||||
int ExamModeConfiguration::numberOfAvailableExamMode() {
|
||||
if (GlobalPreferences::sharedGlobalPreferences()->availableExamModes() == CountryPreferences::AvailableExamModes::StandardOnly
|
||||
|| GlobalPreferences::sharedGlobalPreferences()->isInExamMode())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
assert(GlobalPreferences::sharedGlobalPreferences()->availableExamModes() == CountryPreferences::AvailableExamModes::All);
|
||||
return 2;
|
||||
}
|
||||
|
||||
GlobalPreferences::ExamMode ExamModeConfiguration::examModeAtIndex(int index) {
|
||||
return index == 0 ? GlobalPreferences::ExamMode::Standard : GlobalPreferences::ExamMode::Dutch;
|
||||
}
|
||||
|
||||
I18n::Message ExamModeConfiguration::examModeActivationMessage(int index) {
|
||||
return index == 0 ? I18n::Message::ActivateExamMode : I18n::Message::ActivateDutchExamMode;
|
||||
}
|
||||
|
||||
I18n::Message ExamModeConfiguration::examModeActivationWarningMessage(GlobalPreferences::ExamMode mode, int line) {
|
||||
if (mode == GlobalPreferences::ExamMode::Off) {
|
||||
I18n::Message warnings[] = {I18n::Message::ExitExamMode1, I18n::Message::ExitExamMode2, I18n::Message::Default};
|
||||
return warnings[line];
|
||||
} else if (mode == GlobalPreferences::ExamMode::Standard) {
|
||||
I18n::Message warnings[] = {I18n::Message::ActiveExamModeMessage1, I18n::Message::ActiveExamModeMessage2, I18n::Message::ActiveExamModeMessage3};
|
||||
return warnings[line];
|
||||
}
|
||||
assert(mode == GlobalPreferences::ExamMode::Dutch);
|
||||
I18n::Message warnings[] = {I18n::Message::ActiveDutchExamModeMessage1, I18n::Message::ActiveDutchExamModeMessage2, I18n::Message::ActiveDutchExamModeMessage3};
|
||||
return warnings[line];
|
||||
}
|
||||
|
||||
KDColor ExamModeConfiguration::examModeColor(GlobalPreferences::ExamMode mode) {
|
||||
/* The Dutch exam mode LED is supposed to be orange but we can only make
|
||||
* blink "pure" colors: with RGB leds on or off (as the PWM is used for
|
||||
* blinking). The closest "pure" color is Yellow. Moreover, Orange LED is
|
||||
* already used when the battery is charging. Using yellow, we can assert
|
||||
* that the yellow LED only means that Dutch exam mode is on and avoid
|
||||
* confusing states when the battery is charging and states when the Dutch
|
||||
* exam mode is on. */
|
||||
return mode == GlobalPreferences::ExamMode::Dutch ? KDColorYellow : KDColorRed;
|
||||
}
|
||||
|
||||
bool ExamModeConfiguration::appIsForbiddenInExamMode(I18n::Message appName, GlobalPreferences::ExamMode mode) {
|
||||
return appName == I18n::Message::CodeApp && mode == GlobalPreferences::ExamMode::Dutch;
|
||||
}
|
||||
|
||||
bool ExamModeConfiguration::exactExpressionsAreForbidden(GlobalPreferences::ExamMode mode) {
|
||||
return mode == GlobalPreferences::ExamMode::Dutch;
|
||||
}
|
||||
@@ -2,6 +2,9 @@
|
||||
#include "apps_container.h"
|
||||
#include "exam_mode_configuration.h"
|
||||
#include <assert.h>
|
||||
#include <poincare/preferences.h>
|
||||
|
||||
using namespace Poincare;
|
||||
|
||||
ExamPopUpController::ExamPopUpController(ExamPopUpControllerDelegate * delegate) :
|
||||
PopUpController(
|
||||
|
||||
53
apps/external/Makefile
vendored
Normal file
53
apps/external/Makefile
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
ifdef HOME_DISPLAY_EXTERNALS
|
||||
|
||||
app_external_src = $(addprefix apps/external/,\
|
||||
extapp_api.cpp \
|
||||
archive.cpp \
|
||||
)
|
||||
|
||||
$(eval $(call depends_on_image,apps/home/controller.cpp,apps/external/external_icon.png))
|
||||
|
||||
else
|
||||
|
||||
apps += External::App
|
||||
app_headers += apps/external/app.h
|
||||
|
||||
app_external_src = $(addprefix apps/external/,\
|
||||
app.cpp \
|
||||
extapp_api.cpp \
|
||||
archive.cpp \
|
||||
main_controller.cpp \
|
||||
pointer_text_table_cell.cpp \
|
||||
)
|
||||
|
||||
$(eval $(call depends_on_image,apps/external/app.cpp,apps/external/external_icon.png))
|
||||
|
||||
endif
|
||||
|
||||
SFLAGS += -Iapps/external/
|
||||
|
||||
EXTAPP_PATH ?= apps/external/app/
|
||||
ifeq ($(PLATFORM),device)
|
||||
SFLAGS += -DDEVICE
|
||||
else
|
||||
include $(EXTAPP_PATH)/sources.mak
|
||||
endif
|
||||
|
||||
ifdef EXTERNAL_BUILTIN
|
||||
SFLAGS += -DEXTERNAL_BUILTIN
|
||||
endif
|
||||
|
||||
apps_src += $(app_external_src)
|
||||
|
||||
i18n_files += $(addprefix apps/external/,\
|
||||
base.de.i18n\
|
||||
base.en.i18n\
|
||||
base.es.i18n\
|
||||
base.fr.i18n\
|
||||
base.pt.i18n\
|
||||
base.it.i18n\
|
||||
base.nl.i18n\
|
||||
base.hu.i18n\
|
||||
base.universal.i18n\
|
||||
)
|
||||
|
||||
48
apps/external/app.cpp
vendored
Normal file
48
apps/external/app.cpp
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "app.h"
|
||||
#include "external_icon.h"
|
||||
#include <apps/i18n.h>
|
||||
|
||||
namespace External {
|
||||
|
||||
I18n::Message App::Descriptor::name() {
|
||||
return I18n::Message::ExternalApp;
|
||||
}
|
||||
|
||||
I18n::Message App::Descriptor::upperName() {
|
||||
return I18n::Message::ExternalAppCapital;
|
||||
}
|
||||
|
||||
App::Descriptor::ExaminationLevel App::Descriptor::examinationLevel() {
|
||||
return App::Descriptor::ExaminationLevel::Basic;
|
||||
}
|
||||
|
||||
const Image * App::Descriptor::icon() {
|
||||
return ImageStore::ExternalIcon;
|
||||
}
|
||||
|
||||
App * App::Snapshot::unpack(Container * container) {
|
||||
return new (container->currentAppBuffer()) App(this);
|
||||
}
|
||||
|
||||
App::Descriptor * App::Snapshot::descriptor() {
|
||||
static Descriptor descriptor;
|
||||
return &descriptor;
|
||||
}
|
||||
|
||||
void App::didBecomeActive(Window * window) {
|
||||
::App::didBecomeActive(window);
|
||||
m_window = window;
|
||||
}
|
||||
|
||||
void App::redraw() {
|
||||
m_window->redraw(true);
|
||||
}
|
||||
|
||||
App::App(Snapshot * snapshot) :
|
||||
::App(snapshot, &m_stackViewController),
|
||||
m_mainController(&m_stackViewController, this),
|
||||
m_stackViewController(&m_modalViewController, &m_mainController)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
38
apps/external/app.h
vendored
Normal file
38
apps/external/app.h
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef EXTERNAL_APP_H
|
||||
#define EXTERNAL_APP_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "main_controller.h"
|
||||
|
||||
namespace External {
|
||||
|
||||
class App : public ::App {
|
||||
public:
|
||||
class Descriptor : public ::App::Descriptor {
|
||||
public:
|
||||
I18n::Message name() override;
|
||||
I18n::Message upperName() override;
|
||||
App::Descriptor::ExaminationLevel examinationLevel() override;
|
||||
const Image * icon() override;
|
||||
};
|
||||
class Snapshot : public ::App::Snapshot {
|
||||
public:
|
||||
App * unpack(Container * container) override;
|
||||
Descriptor * descriptor() override;
|
||||
};
|
||||
void redraw();
|
||||
virtual void didBecomeActive(Window * window);
|
||||
int heapSize() { return k_externalHeapSize; }
|
||||
char * heap() { return m_externalHeap; }
|
||||
private:
|
||||
App(Snapshot * snapshot);
|
||||
MainController m_mainController;
|
||||
StackViewController m_stackViewController;
|
||||
Window * m_window;
|
||||
static constexpr int k_externalHeapSize = 100000;
|
||||
char m_externalHeap[k_externalHeapSize];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
6
apps/external/app/sample.c
vendored
Normal file
6
apps/external/app/sample.c
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#include <extapp_api.h>
|
||||
|
||||
void extapp_main() {
|
||||
extapp_pushRectUniform(10, 10, LCD_WIDTH-20, LCD_HEIGHT-20, 0);
|
||||
extapp_msleep(1000);
|
||||
}
|
||||
3
apps/external/app/sources.mak
vendored
Normal file
3
apps/external/app/sources.mak
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
app_external_src += $(addprefix apps/external/app/,\
|
||||
sample.c \
|
||||
)
|
||||
212
apps/external/archive.cpp
vendored
Normal file
212
apps/external/archive.cpp
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
#include "archive.h"
|
||||
#include "extapp_api.h"
|
||||
#include "../global_preferences.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace External {
|
||||
namespace Archive {
|
||||
|
||||
#ifdef DEVICE
|
||||
|
||||
struct TarHeader
|
||||
{ /* byte offset */
|
||||
char name[100]; /* 0 */
|
||||
char mode[8]; /* 100 */
|
||||
char uid[8]; /* 108 */
|
||||
char gid[8]; /* 116 */
|
||||
char size[12]; /* 124 */
|
||||
char mtime[12]; /* 136 */
|
||||
char chksum[8]; /* 148 */
|
||||
char typeflag; /* 156 */
|
||||
char linkname[100]; /* 157 */
|
||||
char magic[8]; /* 257 */
|
||||
char uname[32]; /* 265 */
|
||||
char gname[32]; /* 297 */
|
||||
char devmajor[8]; /* 329 */
|
||||
char devminor[8]; /* 337 */
|
||||
char padding[167]; /* 345 */
|
||||
} __attribute__((packed));
|
||||
|
||||
static_assert(sizeof(TarHeader) == 512);
|
||||
|
||||
bool isSane(const TarHeader* tar) {
|
||||
return !memcmp(tar->magic, "ustar ", 8) && tar->name[0] != '\x00' && tar->name[0] != '\xFF';
|
||||
}
|
||||
|
||||
bool isExamModeAndFileNotExecutable(const TarHeader* tar) {
|
||||
return GlobalPreferences::sharedGlobalPreferences()->isInExamMode() && (tar->mode[4] & 0x01) == 0;
|
||||
}
|
||||
|
||||
bool fileAtIndex(size_t index, File &entry) {
|
||||
if (index == -1)
|
||||
return false;
|
||||
|
||||
const TarHeader* tar = reinterpret_cast<const TarHeader*>(0x90200000);
|
||||
unsigned size = 0;
|
||||
|
||||
// Sanity check.
|
||||
if (!isSane(tar) || isExamModeAndFileNotExecutable(tar)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* TAR files are comprised of a set of records aligned to 512 bytes boundary
|
||||
* followed by data.
|
||||
*/
|
||||
|
||||
for(;;) {
|
||||
// Calculate the size
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
index--;
|
||||
}
|
||||
|
||||
// Achievement unlock: How did we get there ?
|
||||
return false;
|
||||
}
|
||||
|
||||
extern "C" void (* const apiPointers[])(void);
|
||||
typedef uint32_t (*entrypoint)(const uint32_t, const void *, void *, const uint32_t);
|
||||
|
||||
uint32_t executeFile(const char *name, void * heap, const uint32_t heapSize) {
|
||||
File entry;
|
||||
if(fileAtIndex(indexFromName(name), entry)) {
|
||||
if(!entry.isExecutable) {
|
||||
return 0;
|
||||
}
|
||||
uint32_t ep = *reinterpret_cast<const uint32_t*>(entry.data);
|
||||
if(ep >= 0x90200000 && ep < 0x90800000) {
|
||||
return ((entrypoint)ep)(API_VERSION, apiPointers, heap, heapSize);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int indexFromName(const char *name) {
|
||||
File entry;
|
||||
|
||||
for (int i = 0; fileAtIndex(i, entry); i++) {
|
||||
if (strcmp(name, entry.name) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t numberOfFiles() {
|
||||
File dummy;
|
||||
size_t count;
|
||||
|
||||
for (count = 0; fileAtIndex(count, dummy); count++);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
bool executableAtIndex(size_t index, File &entry) {
|
||||
File dummy;
|
||||
size_t count;
|
||||
size_t final_count = 0;
|
||||
|
||||
for (count = 0; fileAtIndex(count, dummy); count++) {
|
||||
if (dummy.isExecutable) {
|
||||
if (final_count == index) {
|
||||
entry.name = dummy.name;
|
||||
entry.data = dummy.data;
|
||||
entry.dataLength = dummy.dataLength;
|
||||
entry.isExecutable = dummy.isExecutable;
|
||||
return true;
|
||||
}
|
||||
final_count++;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t numberOfExecutables() {
|
||||
File dummy;
|
||||
size_t count;
|
||||
size_t final_count = 0;
|
||||
|
||||
for (count = 0; fileAtIndex(count, dummy); count++)
|
||||
if (dummy.isExecutable)
|
||||
final_count++;
|
||||
|
||||
return final_count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#else
|
||||
|
||||
bool fileAtIndex(size_t index, File &entry) {
|
||||
if (index != 0)
|
||||
return false;
|
||||
|
||||
entry.name = "Built-in";
|
||||
entry.data = NULL;
|
||||
entry.dataLength = 0;
|
||||
entry.isExecutable = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool executableAtIndex(size_t index, File &entry) {
|
||||
return fileAtIndex(index, entry);
|
||||
}
|
||||
|
||||
size_t numberOfExecutables() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern "C" void extapp_main(void);
|
||||
|
||||
uint32_t executeFile(const char *name, void * heap, const uint32_t heapSize) {
|
||||
extapp_main();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int indexFromName(const char *name) {
|
||||
if (strcmp(name, "Built-in") == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t numberOfFiles() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user