Merge branch 'omega-dev' into DrawStringFont

This commit is contained in:
Maxime FRIESS
2021-03-15 19:31:16 +01:00
committed by GitHub
640 changed files with 38996 additions and 1307 deletions

View File

@@ -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
View File

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

View File

@@ -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
View File

@@ -0,0 +1,10 @@
---
name: Other
about: A question? A problem? ...
title: ''
labels: Triage
assignees: ''
---

View 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
View File

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

View File

@@ -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:

View File

@@ -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
View 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
View File

@@ -1,3 +1,8 @@
/output/
/build/artifacts/
build/device/**/*.pyc
epsilon.elf
epsilon.map
.vscode
.DS_Store
.gradle

26
.gitlab-ci.yml Normal file
View File

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

6
.gitmodules vendored Normal file
View 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
View File

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

View File

View File

@@ -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
View 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
View File

@@ -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>
[![Build Status](https://github.com/numworks/epsilon/workflows/Continuous%20integration/badge.svg)](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).

View File

@@ -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

View File

@@ -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];
}

View File

@@ -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;

View File

@@ -18,6 +18,6 @@ KDColor AppsContainer::k_promptColors[] = {
KDColorWhite,
KDColorBlack,
KDColorBlack,
Palette::YellowDark};
Palette::AccentText};
int AppsContainer::k_promptNumberOfMessages = 8;

View File

@@ -14,6 +14,6 @@ KDColor AppsContainer::k_promptColors[] = {
KDColorBlack,
KDColorWhite,
KDColorBlack,
Palette::YellowDark};
Palette::AccentText};
int AppsContainer::k_promptNumberOfMessages = 6;

View File

@@ -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());
}

View File

@@ -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

Submodule apps/atomic added at 69f7a06ba5

View File

@@ -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 {

View File

@@ -1,4 +1,5 @@
#include "complex_graph_cell.h"
#include <escher/palette.h>
using namespace Shared;
using namespace Poincare;
@@ -12,7 +13,7 @@ ComplexGraphView::ComplexGraphView(ComplexModel * complexModel) :
}
void ComplexGraphView::drawRect(KDContext * ctx, KDRect rect) const {
ctx->fillRect(rect, KDColorWhite);
ctx->fillRect(rect, Palette::BackgroundApps);
// Draw grid, axes and graduations
drawGrid(ctx, rect);
@@ -25,7 +26,7 @@ void ComplexGraphView::drawRect(KDContext * ctx, KDRect rect) const {
assert(!std::isnan(real) && !std::isnan(imag) && !std::isinf(real) && !std::isinf(imag));
// Draw the segment from the origin to the dot (real, imag)
drawSegment(ctx, rect, 0.0f, 0.0f, m_complex->real(), m_complex->imag(), Palette::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));
}, &parameters, &th, false, Palette::GrayDark, false);
}, &parameters, &th, false, Palette::SecondaryText, false);
// Draw dashed segment to indicate real and imaginary
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, real, 0.0f, imag, Palette::Red, 1, 3);
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Horizontal, imag, 0.0f, real, Palette::Red, 1, 3);
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, real, 0.0f, imag, Palette::CalculationTrigoAndComplexForeground, 1, 3);
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Horizontal, imag, 0.0f, real, Palette::CalculationTrigoAndComplexForeground, 1, 3);
// Draw complex position on the plan
drawDot(ctx, rect, real, imag, Palette::Red, Size::Large);
drawDot(ctx, rect, real, imag, Palette::CalculationTrigoAndComplexForeground, Size::Large);
// Draw labels
// 're(z)' label
drawLabel(ctx, rect, real, 0.0f, "re(z)", Palette::Red, CurveView::RelativePosition::None, imag >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After);
drawLabel(ctx, rect, real, 0.0f, "re(z)", Palette::CalculationTrigoAndComplexForeground, CurveView::RelativePosition::None, imag >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After);
// 'im(z)' label
drawLabel(ctx, rect, 0.0f, imag, "im(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);
}
}

View File

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

View File

@@ -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);
}
}

View File

@@ -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)
{

View File

@@ -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:

View File

@@ -1,4 +1,5 @@
#include "trigonometry_graph_cell.h"
#include <escher/palette.h>
using namespace Shared;
using namespace Poincare;
@@ -14,24 +15,24 @@ TrigonometryGraphView::TrigonometryGraphView(TrigonometryModel * model) :
void TrigonometryGraphView::drawRect(KDContext * ctx, KDRect rect) const {
float s = std::sin(m_model->angle());
float c = std::cos(m_model->angle());
ctx->fillRect(rect, KDColorWhite);
ctx->fillRect(rect, Palette::BackgroundApps);
drawGrid(ctx, rect);
drawAxes(ctx, rect);
// Draw the circle
drawCurve(ctx, rect, 0.0f, 2.0f*M_PI, M_PI/180.0f, [](float t, void * model, void * context) {
return Poincare::Coordinate2D<float>(std::cos(t), std::sin(t));
}, nullptr, nullptr, true, Palette::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);
}
}

View File

@@ -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;
}

View File

@@ -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 {

View File

@@ -11,4 +11,4 @@ AdditionalDeterminant = "Determinant"
AdditionalInverse = "Inverse"
AdditionalRowEchelonForm = "Row echelon form"
AdditionalReducedRowEchelonForm = "Reduced row echelon form"
AdditionalTrace = "Trace"
AdditionalTrace = "Trace"

View 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"

View File

@@ -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) {

View File

@@ -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();

View File

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

View File

@@ -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
View 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();

View File

@@ -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
View 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
View 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

View File

@@ -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;

View File

@@ -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:

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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
View 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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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?"

View 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 = "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"

View 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"

View 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
View 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"

View File

@@ -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"

View 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"

View 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"

View 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\")"

View File

@@ -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);

View File

@@ -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"

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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. */

View File

@@ -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);
}
}

View File

@@ -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();

View File

@@ -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);

View File

@@ -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,

View File

@@ -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

View File

@@ -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;

View File

@@ -9,7 +9,7 @@ namespace Code {
SandboxController::SandboxController(Responder * parentResponder) :
ViewController(parentResponder),
m_solidColorView(KDColorWhite)
m_solidColorView(Palette::CodeBackground)
{
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
};
}

View File

@@ -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))");

View File

@@ -2,3 +2,5 @@ Functions = "Funktionen"
Catalog = "Katalog"
Modules = "Module"
LoopsAndTests = "Schleifen und Tests"
Files = "Dateien"
Exceptions = "Ausnahmen"

View File

@@ -2,3 +2,5 @@ Functions = "Functions"
Catalog = "Catalog"
Modules = "Modules"
LoopsAndTests = "Loops and tests"
Files = "Files"
Exceptions = "Exceptions"

View File

@@ -2,3 +2,5 @@ Functions = "Functions"
Catalog = "Catalog"
Modules = "Modules"
LoopsAndTests = "Loops and tests"
Files = "Files"
Exceptions = "Exceptions"

View File

@@ -2,3 +2,5 @@ Functions = "Fonctions"
Catalog = "Catalogue"
Modules = "Modules"
LoopsAndTests = "Boucles et tests"
Files = "Fichiers"
Exceptions = "Exceptions"

View File

@@ -0,0 +1,6 @@
Functions = "Funkciók"
Catalog = "Katalógus"
Modules = "Modulok"
LoopsAndTests = "Hurkok és tesztek"
Files = "Fájlok"
Exceptions = "Kivételek"

View File

@@ -2,3 +2,5 @@ Functions = "Funzioni"
Catalog = "Catalogo"
Modules = "Moduli"
LoopsAndTests = "Cicli e test"
Files = "Files"
Exceptions = "Exceptions"

View File

@@ -2,3 +2,5 @@ Functions = "Functies"
Catalog = "Catalogus"
Modules = "Modules"
LoopsAndTests = "Herhalingen en testen"
Files = "Files"
Exceptions = "Exceptions"

View File

@@ -2,3 +2,5 @@ Functions = "Funções"
Catalog = "Catálogo"
Modules = "Módulos"
LoopsAndTests = "Laços e testes"
Files = "Files"
Exceptions = "Exceptions"

View File

@@ -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 "

View File

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

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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
View 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
View 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
View 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
View 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
View File

@@ -0,0 +1,3 @@
app_external_src += $(addprefix apps/external/app/,\
sample.c \
)

212
apps/external/archive.cpp vendored Normal file
View 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