diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index c9f1c1e8dbc..30b227d0415 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -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 +#### Describe the bug -#### 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} diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000000..3ba13e0cec6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 6bc39c490f2..eee03aa6ac5 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -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 diff --git a/.github/ISSUE_TEMPLATE/other.md b/.github/ISSUE_TEMPLATE/other.md new file mode 100644 index 00000000000..38b47c71fbd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/other.md @@ -0,0 +1,10 @@ +--- +name: Other +about: A question? A problem? ... +title: '' +labels: Triage +assignees: '' + +--- + + diff --git a/.github/ISSUE_TEMPLATE/problems-during-installation.md b/.github/ISSUE_TEMPLATE/problems-during-installation.md new file mode 100644 index 00000000000..347b6d9574a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/problems-during-installation.md @@ -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} diff --git a/.github/workflows/ci-docker.yml b/.github/workflows/ci-docker.yml new file mode 100644 index 00000000000..ef955c806c5 --- /dev/null +++ b/.github/workflows/ci-docker.yml @@ -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) diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml index ac3d0667dd7..c60b1180786 100644 --- a/.github/workflows/ci-workflow.yml +++ b/.github/workflows/ci-workflow.yml @@ -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: diff --git a/.github/workflows/metrics-workflow.yml b/.github/workflows/metric-workflow.yml similarity index 85% rename from .github/workflows/metrics-workflow.yml rename to .github/workflows/metric-workflow.yml index ad0082b8d1f..0cca6ba5360 100644 --- a/.github/workflows/metrics-workflow.yml +++ b/.github/workflows/metric-workflow.yml @@ -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, diff --git a/.github/workflows/unit-workflow.yml b/.github/workflows/unit-workflow.yml new file mode 100644 index 00000000000..e4076aa63cc --- /dev/null +++ b/.github/workflows/unit-workflow.yml @@ -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 + diff --git a/.gitignore b/.gitignore index b69802123ed..8645c08d24b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ /output/ /build/artifacts/ build/device/**/*.pyc +epsilon.elf +epsilon.map +.vscode +.DS_Store +.gradle diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 00000000000..d80d898590a --- /dev/null +++ b/.gitlab-ci.yml @@ -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 + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000000..02641c8d556 --- /dev/null +++ b/.gitmodules @@ -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 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000000..7540a495a46 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -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 \ No newline at end of file diff --git a/LICENSE b/LICENSE.md similarity index 100% rename from LICENSE rename to LICENSE.md diff --git a/Makefile b/Makefile index c5ed4b53de2..f83a5922f12 100644 --- a/Makefile +++ b/Makefile @@ -5,17 +5,39 @@ default: include build/config.mak +include build/pimp.mak include build/defaults.mak include build/platform.$(PLATFORM).mak include build/toolchain.$(TOOLCHAIN).mak include build/variants.mak include build/helpers.mk +ifeq (${MODEL}, n0110) + apps_list = ${EPSILON_APPS} +else + apps_list = $(foreach i, ${EPSILON_APPS}, $(if $(filter external, $(i)),,$(i))) +endif + +ifdef FORCE_EXTERNAL + apps_list = ${EPSILON_APPS} +endif + +ifdef HOME_DISPLAY_EXTERNALS + ifneq ($(filter external,$(apps_list)),) + SFLAGS += -DHOME_DISPLAY_EXTERNALS + else + $(warning HOME_DISPLAY_EXTERNALS is set but external isn't included, ignoring flag.) + endif +endif + .PHONY: info info: @echo "EPSILON_VERSION = $(EPSILON_VERSION)" @echo "EPSILON_APPS = $(EPSILON_APPS)" @echo "EPSILON_I18N = $(EPSILON_I18N)" + @echo "THEME_NAME = $(THEME_NAME)" + @echo "THEME_REPO = $(THEME_REPO)" + @echo "BUILD_DIR = $(BUILD_DIR)" @echo "PLATFORM" = $(PLATFORM) @echo "DEBUG" = $(DEBUG) @echo "EPSILON_GETOPT" = $(EPSILON_GETOPT) @@ -46,6 +68,18 @@ help: @echo " make PLATFORM=simulator TARGET=macos" @echo " make PLATFORM=simulator TARGET=web" @echo " make PLATFORM=simulator TARGET=windows" + @echo " make PLATFORM=simulator TARGET=3ds" + +.PHONY: doc +doc: + @echo "DOXYGEN" + @mkdir -p output/doc/ + $(Q) doxygen build/doc/Doxyfile + +.PHONY: print-% +print-%: + @echo $* = $($*) + @echo $*\'s origin is $(origin $*) # Since we're building out-of-tree, we need to make sure the output directories # are created, otherwise the receipes will fail (e.g. gcc will fail to create @@ -86,6 +120,10 @@ include build/scenario/Makefile include quiz/Makefile # Quiz needs to be included at the end all_src = $(apps_src) $(escher_src) $(ion_src) $(kandinsky_src) $(liba_src) $(libaxx_src) $(poincare_src) $(python_src) $(runner_src) $(ion_device_flasher_src) $(ion_device_bench_src) $(tests_src) +# Make palette.h a dep for every source-file. +# This ensures that the theming engine works correctly. +$(call object_for,$(all_src)): $(BUILD_DIR)/escher/palette.h $(BUILD_DIR)/apps/i18n.h + all_objs = $(call object_for,$(all_src)) .SECONDARY: $(all_objs) @@ -109,6 +147,11 @@ clean: @echo "CLEAN" $(Q) rm -rf $(BUILD_DIR) +.PHONY: cleanall +cleanall: + @echo "CLEANALL" + $(Q) rm -rf output + .PHONY: cowsay_% cowsay_%: @echo " -------" @@ -123,3 +166,23 @@ cowsay_%: .PHONY: clena clena: cowsay_CLENA clean +.PHONY: compile +compile: output/$(BUILD_TYPE)/simulator/$(HOST)/epsilon.$(EXE) + +.PHONY: cleanandcompile +cleanandcompile: + ${MAKE} cleanall + ${MAKE} compile + +.PHONY: start +start: + @echo "INFO Starting output/$(BUILD_TYPE)/simulator/$(HOST)/epsilon.$(EXE)" + @$(Q) output/$(BUILD_TYPE)/simulator/$(HOST)/epsilon.$(EXE) -v + +.PHONY: clean_run +clean_run: cleanandcompile + ${MAKE} start + +.PHONY: run +run: compile + ${MAKE} start diff --git a/README.fr.md b/README.fr.md new file mode 100644 index 00000000000..d7b1093d4b7 --- /dev/null +++ b/README.fr.md @@ -0,0 +1,177 @@ +

+ +

+ cc by-nc-sa 4.0 + Issues +
+ Discord +

+ +> 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". + +

Omega Banner Discord

+ +### Manuelle + +Tout d'abord, suivez **la première étape** [ici](https://www.numworks.com/resources/engineering/software/build/), puis : + +
+ Modèle n0100 + +(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`. + +
+ +
+ Modèle n0110 + +```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`. + +
+ +
+ Fichiers binaires + +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`. + +
+ +
+ Simulateur web + +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`. + +
+ +
+ Simulateur 3DS + +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 +``` + +
+ +Si vous avez besoin d'aide, n'hésitez pas à rejoindre notre serveur discord : https://discord.gg/X2TWhh9 + +

Omega Banner Discord

+--- + +## 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). diff --git a/README.md b/README.md index cdcbbcb0b4a..c9b6597d405 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,176 @@ -NumWorks Epsilon logo +

-[![Build Status](https://github.com/numworks/epsilon/workflows/Continuous%20integration/badge.svg)](https://github.com/numworks/epsilon/actions?workflow=Continuous+integration) +

+ cc by-nc-sa 4.0 + Issues +
+ Discord +

-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 + +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). + +### 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. + +

Omega Banner Discord

+ +### Manual + +First of all, follow **step 1** [here](https://www.numworks.com/resources/engineering/software/build/). Then: + +
+ Model n0100 + +(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. + +
+ +
+ Model n0110 + +```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. + +
+ +
+ Bin files + +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 +``` -## Diving in +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. + +
-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. +
+ Web simulator + +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. + +
+ +
+ 3DS Simulator + +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> +``` + +
+ +If you need help, you can join our Discord server here : https://discord.gg/X2TWhh9 + +

Omega Banner Discord

+--- ## 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) + +## 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) -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. +## 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). diff --git a/apps/Makefile b/apps/Makefile index da4dc6bbad3..69f88165e38 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -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 diff --git a/apps/apps_container.cpp b/apps/apps_container.cpp index d8631f3ac53..acf3feb383d 100644 --- a/apps/apps_container.cpp +++ b/apps/apps_container.cpp @@ -5,11 +5,16 @@ #include #include #include +#include +#include + +#include extern "C" { #include } +using namespace Poincare; using namespace Shared; AppsContainer * AppsContainer::sharedAppsContainer() { @@ -28,13 +33,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 +50,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 +172,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); } @@ -180,6 +220,13 @@ bool AppsContainer::dispatchEvent(Ion::Events::Event event) { return didProcessEvent || alphaLockWantsRedraw; } +static constexpr Ion::Events::Event switch_events[] = { + Ion::Events::ShiftSeven, Ion::Events::ShiftEight, Ion::Events::ShiftNine, + Ion::Events::ShiftFour, Ion::Events::ShiftFive, Ion::Events::ShiftSix, + Ion::Events::ShiftOne, Ion::Events::ShiftTwo, Ion::Events::ShiftThree, + Ion::Events::ShiftZero, Ion::Events::ShiftDot, Ion::Events::ShiftEE +}; + bool AppsContainer::processEvent(Ion::Events::Event event) { // Warning: if the window is dirtied, you need to call window()->redraw() if (event == Ion::Events::USBPlug) { @@ -200,10 +247,28 @@ bool AppsContainer::processEvent(Ion::Events::Event event) { switchTo(appSnapshotAtIndex(0)); return true; } + if (event == Ion::Events::ShiftHome) { + switchTo(appSnapshotAtIndex(1)); + return true; + } + + for(int i = 0; i < std::min((int) (sizeof(switch_events) / sizeof(Ion::Events::Event)), APPS_CONTAINER_SNAPSHOT_COUNT); i++) { + if (event == switch_events[i]) { + m_window.redraw(true); + switchTo(appSnapshotAtIndex(i+1)); + return true; + } + } + if (event == Ion::Events::OnOff) { suspend(true); return true; } + 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 +338,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 +405,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 +447,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]; } diff --git a/apps/apps_container.h b/apps/apps_container.h index e217f2495c4..ab945b6efec 100644 --- a/apps/apps_container.h +++ b/apps/apps_container.h @@ -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 @@ -39,6 +40,7 @@ class AppsContainer : public Container, ExamPopUpControllerDelegate, Ion::Storag 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 @@ class AppsContainer : public Container, ExamPopUpControllerDelegate, Ion::Storag 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 @@ class AppsContainer : public Container, ExamPopUpControllerDelegate, Ion::Storag 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; diff --git a/apps/apps_container_prompt_beta.cpp b/apps/apps_container_prompt_beta.cpp index 85be074d143..613acc99d9a 100644 --- a/apps/apps_container_prompt_beta.cpp +++ b/apps/apps_container_prompt_beta.cpp @@ -18,6 +18,6 @@ KDColor AppsContainer::k_promptColors[] = { KDColorWhite, KDColorBlack, KDColorBlack, - Palette::YellowDark}; + Palette::AccentText}; int AppsContainer::k_promptNumberOfMessages = 8; diff --git a/apps/apps_container_prompt_update.cpp b/apps/apps_container_prompt_update.cpp index 25fe11b646b..e837b592f27 100644 --- a/apps/apps_container_prompt_update.cpp +++ b/apps/apps_container_prompt_update.cpp @@ -14,6 +14,6 @@ KDColor AppsContainer::k_promptColors[] = { KDColorBlack, KDColorWhite, KDColorBlack, - Palette::YellowDark}; + Palette::AccentText}; int AppsContainer::k_promptNumberOfMessages = 6; diff --git a/apps/apps_window.cpp b/apps/apps_window.cpp index 68a1501333b..057152d9c53 100644 --- a/apps/apps_window.cpp +++ b/apps/apps_window.cpp @@ -3,6 +3,7 @@ extern "C" { #include } +#include 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()); } diff --git a/apps/apps_window.h b/apps/apps_window.h index 08f1bb651b0..9b930a8e5f6 100644 --- a/apps/apps_window.h +++ b/apps/apps_window.h @@ -9,6 +9,7 @@ class AppsWindow : public Window { AppsWindow(); void setTitle(I18n::Message title); bool updateBatteryLevel(); + bool updateClock(); bool updateIsChargingState(); bool updatePluggedState(); void refreshPreferences(); diff --git a/apps/atomic b/apps/atomic new file mode 160000 index 00000000000..69f7a06ba53 --- /dev/null +++ b/apps/atomic @@ -0,0 +1 @@ +Subproject commit 69f7a06ba53eaae9ba2ab8f0c0318e2f77455f4d diff --git a/apps/battery_view.cpp b/apps/battery_view.cpp index abd03c73121..28ab8d9794e 100644 --- a/apps/battery_view.cpp +++ b/apps/battery_view.cpp @@ -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 { diff --git a/apps/calculation/additional_outputs/complex_graph_cell.cpp b/apps/calculation/additional_outputs/complex_graph_cell.cpp index 3bd48645dde..fe38bf9105a 100644 --- a/apps/calculation/additional_outputs/complex_graph_cell.cpp +++ b/apps/calculation/additional_outputs/complex_graph_cell.cpp @@ -1,4 +1,5 @@ #include "complex_graph_cell.h" +#include 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(a*std::cos(t*th), b*std::sin(t*th)); - }, ¶meters, &th, false, Palette::GrayDark, false); + }, ¶meters, &th, false, Palette::SecondaryText, false); // Draw dashed segment to indicate real and imaginary - drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, real, 0.0f, imag, Palette::Red, 1, 3); - drawHorizontalOrVerticalSegment(ctx, rect, Axis::Horizontal, imag, 0.0f, real, Palette::Red, 1, 3); + drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, real, 0.0f, imag, Palette::CalculationTrigoAndComplexForeground, 1, 3); + drawHorizontalOrVerticalSegment(ctx, rect, Axis::Horizontal, imag, 0.0f, real, Palette::CalculationTrigoAndComplexForeground, 1, 3); // Draw complex position on the plan - drawDot(ctx, rect, real, imag, Palette::Red, Size::Large); + drawDot(ctx, rect, real, imag, Palette::CalculationTrigoAndComplexForeground, Size::Large); // Draw labels // 're(z)' label - drawLabel(ctx, rect, real, 0.0f, "re(z)", Palette::Red, CurveView::RelativePosition::None, imag >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After); + drawLabel(ctx, rect, real, 0.0f, "re(z)", Palette::CalculationTrigoAndComplexForeground, CurveView::RelativePosition::None, imag >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After); // 'im(z)' label - drawLabel(ctx, rect, 0.0f, imag, "im(z)", Palette::Red, real >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After, CurveView::RelativePosition::None); + drawLabel(ctx, rect, 0.0f, imag, "im(z)", Palette::CalculationTrigoAndComplexForeground, real >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After, CurveView::RelativePosition::None); // '|z|' label, the relative horizontal position of this label depends on the quadrant CurveView::RelativePosition verticalPosition = real*imag < 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After; if (real == 0.0f) { // Edge case: pure imaginary verticalPosition = CurveView::RelativePosition::None; } - drawLabel(ctx, rect, real/2.0f, imag/2.0f, "|z|", Palette::Red, CurveView::RelativePosition::None, verticalPosition); + drawLabel(ctx, rect, real/2.0f, imag/2.0f, "|z|", Palette::CalculationTrigoAndComplexForeground, CurveView::RelativePosition::None, verticalPosition); // 'arg(z)' label, the absolute and relative horizontal/vertical positions of this label depends on the quadrant CurveView::RelativePosition horizontalPosition = real >= 0.0f ? CurveView::RelativePosition::After : CurveView::RelativePosition::None; verticalPosition = imag >= 0.0f ? CurveView::RelativePosition::After : CurveView::RelativePosition::Before; @@ -87,7 +88,7 @@ void ComplexGraphView::drawRect(KDContext * ctx, KDRect rect) const { * and for the left half plan, we position the label at the half angle. The * relative position is chosen accordingly. */ float anglePositionRatio = real >= 0.0f ? 0.0f : 0.5f; - drawLabel(ctx, rect, a*std::cos(anglePositionRatio*th), b*std::sin(anglePositionRatio*th), "arg(z)", Palette::Red, horizontalPosition, verticalPosition); + drawLabel(ctx, rect, a*std::cos(anglePositionRatio*th), b*std::sin(anglePositionRatio*th), "arg(z)", Palette::CalculationTrigoAndComplexForeground, horizontalPosition, verticalPosition); } } diff --git a/apps/calculation/additional_outputs/expression_with_equal_sign_view.h b/apps/calculation/additional_outputs/expression_with_equal_sign_view.h index 865a7393fe7..359fbe46bde 100644 --- a/apps/calculation/additional_outputs/expression_with_equal_sign_view.h +++ b/apps/calculation/additional_outputs/expression_with_equal_sign_view.h @@ -4,13 +4,14 @@ #include #include #include +#include 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; diff --git a/apps/calculation/additional_outputs/illustration_cell.cpp b/apps/calculation/additional_outputs/illustration_cell.cpp index eb61b037b77..20249c7d808 100644 --- a/apps/calculation/additional_outputs/illustration_cell.cpp +++ b/apps/calculation/additional_outputs/illustration_cell.cpp @@ -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); } } diff --git a/apps/calculation/additional_outputs/list_controller.cpp b/apps/calculation/additional_outputs/list_controller.cpp index 16f9c9ef6b8..ea2b17d3c29 100644 --- a/apps/calculation/additional_outputs/list_controller.cpp +++ b/apps/calculation/additional_outputs/list_controller.cpp @@ -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) { diff --git a/apps/calculation/additional_outputs/scrollable_three_expressions_cell.h b/apps/calculation/additional_outputs/scrollable_three_expressions_cell.h index 792c65e1dc4..95ad648235d 100644 --- a/apps/calculation/additional_outputs/scrollable_three_expressions_cell.h +++ b/apps/calculation/additional_outputs/scrollable_three_expressions_cell.h @@ -5,6 +5,7 @@ #include "../../shared/scrollable_multiple_expressions_view.h" #include "../calculation.h" #include "expression_with_equal_sign_view.h" +#include namespace Calculation { @@ -16,7 +17,7 @@ class ScrollableThreeExpressionsView : public Shared::AbstractScrollableMultiple 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 @@ class ScrollableThreeExpressionsView : public Shared::AbstractScrollableMultiple 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(&m_leftExpressionView); } private: diff --git a/apps/calculation/additional_outputs/trigonometry_graph_cell.cpp b/apps/calculation/additional_outputs/trigonometry_graph_cell.cpp index 903674ce5ed..636ce588a80 100644 --- a/apps/calculation/additional_outputs/trigonometry_graph_cell.cpp +++ b/apps/calculation/additional_outputs/trigonometry_graph_cell.cpp @@ -1,4 +1,5 @@ #include "trigonometry_graph_cell.h" +#include 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(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); } } diff --git a/apps/calculation/app.cpp b/apps/calculation/app.cpp index 8cc0e3c9275..2c5c97d3c87 100644 --- a/apps/calculation/app.cpp +++ b/apps/calculation/app.cpp @@ -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; } diff --git a/apps/calculation/app.h b/apps/calculation/app.h index 56cb218541e..975989ffa36 100644 --- a/apps/calculation/app.h +++ b/apps/calculation/app.h @@ -16,6 +16,7 @@ class App : public Shared::ExpressionFieldDelegateApp { public: I18n::Message name() override; I18n::Message upperName() override; + App::Descriptor::ExaminationLevel examinationLevel() override; const Image * icon() override; }; class Snapshot : public ::SharedApp::Snapshot { diff --git a/apps/calculation/base.en.i18n b/apps/calculation/base.en.i18n index 0e54f24cfd4..967c0905063 100644 --- a/apps/calculation/base.en.i18n +++ b/apps/calculation/base.en.i18n @@ -11,4 +11,4 @@ AdditionalDeterminant = "Determinant" AdditionalInverse = "Inverse" AdditionalRowEchelonForm = "Row echelon form" AdditionalReducedRowEchelonForm = "Reduced row echelon form" -AdditionalTrace = "Trace" \ No newline at end of file +AdditionalTrace = "Trace" diff --git a/apps/calculation/base.hu.i18n b/apps/calculation/base.hu.i18n new file mode 100644 index 00000000000..39397adee2f --- /dev/null +++ b/apps/calculation/base.hu.i18n @@ -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" diff --git a/apps/calculation/calculation.cpp b/apps/calculation/calculation.cpp index c1ee3692ed1..c293cbbe841 100644 --- a/apps/calculation/calculation.cpp +++ b/apps/calculation/calculation.cpp @@ -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) { diff --git a/apps/calculation/calculation_store.cpp b/apps/calculation/calculation_store.cpp index be2055cedbf..e0dcc12f161 100644 --- a/apps/calculation/calculation_store.cpp +++ b/apps/calculation/calculation_store.cpp @@ -1,5 +1,6 @@ #include "calculation_store.h" #include "../shared/poincare_helpers.h" +#include "../global_preferences.h" #include #include #include @@ -87,7 +88,7 @@ ExpiringPointer 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(); diff --git a/apps/calculation/expression_field.cpp b/apps/calculation/expression_field.cpp index a190a9558d1..b96c4b1fed6 100644 --- a/apps/calculation/expression_field.cpp +++ b/apps/calculation/expression_field.cpp @@ -17,7 +17,8 @@ bool ExpressionField::handleEvent(Ion::Events::Event event) { event == Ion::Events::Power || event == Ion::Events::Square || event == Ion::Events::Division || - event == Ion::Events::Sto)) { + event == Ion::Events::Sto || + event == Ion::Events::EE)) { handleEventWithText(Poincare::Symbol::k_ans); } return(::ExpressionField::handleEvent(event)); diff --git a/apps/calculation/history_view_cell.cpp b/apps/calculation/history_view_cell.cpp index e30995750fb..71799403c26 100644 --- a/apps/calculation/history_view_cell.cpp +++ b/apps/calculation/history_view_cell.cpp @@ -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 { diff --git a/apps/calculation/history_view_cell.h b/apps/calculation/history_view_cell.h index 5e296f529f6..38d7e22f18c 100644 --- a/apps/calculation/history_view_cell.h +++ b/apps/calculation/history_view_cell.h @@ -49,7 +49,7 @@ class HistoryViewCell : public ::EvenOddCell, public Responder { 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(); } diff --git a/apps/calculation/test.py b/apps/calculation/test.py new file mode 100644 index 00000000000..84fb10c01f4 --- /dev/null +++ b/apps/calculation/test.py @@ -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(); diff --git a/apps/calculation/test/calculation_store.cpp b/apps/calculation/test/calculation_store.cpp index 1ce0c4fe1b4..b73a5143316 100644 --- a/apps/calculation/test/calculation_store.cpp +++ b/apps/calculation/test/calculation_store.cpp @@ -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); diff --git a/apps/clock_timer.cpp b/apps/clock_timer.cpp new file mode 100644 index 00000000000..e06a1e6b206 --- /dev/null +++ b/apps/clock_timer.cpp @@ -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(); +} diff --git a/apps/clock_timer.h b/apps/clock_timer.h new file mode 100644 index 00000000000..985af96e95d --- /dev/null +++ b/apps/clock_timer.h @@ -0,0 +1,16 @@ +#ifndef APPS_CLOCK_TIMER_H +#define APPS_CLOCK_TIMER_H + +#include + +class AppsContainer; + +class ClockTimer : public Timer { +public: + ClockTimer(AppsContainer * container); +private: + bool fire() override; + AppsContainer * m_container; +}; + +#endif diff --git a/apps/code/app.cpp b/apps/code/app.cpp index 661f650710d..f56559c7c84 100644 --- a/apps/code/app.cpp +++ b/apps/code/app.cpp @@ -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(UTF8Helper::CodePointSearch(value, ':')); if (*separator == 0) { return; diff --git a/apps/code/app.h b/apps/code/app.h index b6e859b1d49..82a0ad0dd11 100644 --- a/apps/code/app.h +++ b/apps/code/app.h @@ -20,6 +20,7 @@ class App : public Shared::InputEventHandlerDelegateApp { public: I18n::Message name() override; I18n::Message upperName() override; + App::Descriptor::ExaminationLevel examinationLevel() override; const Image * icon() override; }; class Snapshot : public SharedApp::Snapshot { @@ -35,6 +36,7 @@ class App : public Shared::InputEventHandlerDelegateApp { private: #if EPSILON_GETOPT bool m_lockOnConsole; + bool m_hasBeenWiped; #endif ScriptStore m_scriptStore; }; @@ -74,7 +76,7 @@ class App : public Shared::InputEventHandlerDelegateApp { VariableBoxController * variableBoxController() { return &m_variableBoxController; } - static constexpr int k_pythonHeapSize = 32768; + static constexpr int k_pythonHeapSize = 100000; Code::toolboxIonKeys * toolboxIonKeys(); diff --git a/apps/code/base.de.i18n b/apps/code/base.de.i18n index 15a39732e2f..40cf856fa34 100644 --- a/apps/code/base.de.i18n +++ b/apps/code/base.de.i18n @@ -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" diff --git a/apps/code/base.en.i18n b/apps/code/base.en.i18n index 4dcdfbd3be1..082bcfd7961 100644 --- a/apps/code/base.en.i18n +++ b/apps/code/base.en.i18n @@ -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" diff --git a/apps/code/base.es.i18n b/apps/code/base.es.i18n index ccceb896fec..f3db58624a2 100644 --- a/apps/code/base.es.i18n +++ b/apps/code/base.es.i18n @@ -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" diff --git a/apps/code/base.fr.i18n b/apps/code/base.fr.i18n index bd3179ee7a2..46d7109ad38 100644 --- a/apps/code/base.fr.i18n +++ b/apps/code/base.fr.i18n @@ -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" diff --git a/apps/code/base.hu.i18n b/apps/code/base.hu.i18n new file mode 100644 index 00000000000..07d0e297fb1 --- /dev/null +++ b/apps/code/base.hu.i18n @@ -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" diff --git a/apps/code/base.it.i18n b/apps/code/base.it.i18n index a3d5abcbb8a..cd99347a262 100644 --- a/apps/code/base.it.i18n +++ b/apps/code/base.it.i18n @@ -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" diff --git a/apps/code/base.nl.i18n b/apps/code/base.nl.i18n index e016172c246..769bdbb7203 100644 --- a/apps/code/base.nl.i18n +++ b/apps/code/base.nl.i18n @@ -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" diff --git a/apps/code/base.pt.i18n b/apps/code/base.pt.i18n index 3a4a8839cea..889c0fa3566 100644 --- a/apps/code/base.pt.i18n +++ b/apps/code/base.pt.i18n @@ -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" diff --git a/apps/code/catalog.de.i18n b/apps/code/catalog.de.i18n index 73eb3acecd7..9cb321ab8e4 100644 --- a/apps/code/catalog.de.i18n +++ b/apps/code/catalog.de.i18n @@ -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,22 @@ 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" +PythonDrawLine = "Draw a line" +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,25 +62,30 @@ 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" PythonLdexp = "Return x*(2**i), inverse of frexp" PythonLength = "Length of an object" @@ -119,16 +125,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" @@ -149,3 +155,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?" diff --git a/apps/code/catalog.en.i18n b/apps/code/catalog.en.i18n index ee27566c8c5..819887dbbef 100644 --- a/apps/code/catalog.en.i18n +++ b/apps/code/catalog.en.i18n @@ -45,6 +45,7 @@ PythonCosh = "Hyperbolic cosine" PythonCount = "Count the occurrences of x" PythonDegrees = "Convert x from radians to degrees" PythonDivMod = "Quotient and remainder" +PythonDrawLine = "Draw a line" PythonDrawString = "Display a text from pixel (x,y)" PythonErf = "Error function" PythonErfc = "Complementary error function" @@ -149,3 +150,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" diff --git a/apps/code/catalog.es.i18n b/apps/code/catalog.es.i18n index ee27566c8c5..960dd7eb9bc 100644 --- a/apps/code/catalog.es.i18n +++ b/apps/code/catalog.es.i18n @@ -45,6 +45,7 @@ PythonCosh = "Hyperbolic cosine" PythonCount = "Count the occurrences of x" PythonDegrees = "Convert x from radians to degrees" PythonDivMod = "Quotient and remainder" +PythonDrawLine = "Draw a line" PythonDrawString = "Display a text from pixel (x,y)" PythonErf = "Error function" PythonErfc = "Complementary error function" @@ -149,3 +150,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" diff --git a/apps/code/catalog.fr.i18n b/apps/code/catalog.fr.i18n index d1c7c6eeccf..756ef882e0f 100644 --- a/apps/code/catalog.fr.i18n +++ b/apps/code/catalog.fr.i18n @@ -45,6 +45,7 @@ PythonCosh = "Cosinus hyperbolique" PythonCount = "Compte les occurrences de x" PythonDegrees = "Conversion de radians en degrés" PythonDivMod = "Quotient et reste" +PythonDrawLine = "Trace une ligne" PythonDrawString = "Affiche un texte au pixel (x,y)" PythonErf = "Fonction d'erreur" PythonErfc = "Fonction d'erreur complémentaire" @@ -149,3 +150,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é" diff --git a/apps/code/catalog.hu.i18n b/apps/code/catalog.hu.i18n new file mode 100644 index 00000000000..4942f6c4f11 --- /dev/null +++ b/apps/code/catalog.hu.i18n @@ -0,0 +1,223 @@ +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" +PythonDrawLine = "Húzzon egy vonalat " +PythonDrawString = "Szöveg megjelenítése (x, y)-en" +PythonErf = "Hiba funkció" +PythonErfc = "Kiegészítö hiba funkció" +PythonEval = "Visszaadja az értékelt kifejezést" +PythonExp = "Exponenciális függvény" +PythonExpm1 = "exp(x)-1 sámitása" +PythonFabs = "Abszolút érték" +PythonFillRect = "Téglalap töltése" +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" diff --git a/apps/code/catalog.it.i18n b/apps/code/catalog.it.i18n index 0a2dbe02b35..94eacc262f0 100644 --- a/apps/code/catalog.it.i18n +++ b/apps/code/catalog.it.i18n @@ -45,6 +45,7 @@ PythonCosh = "Coseno iperbolico" PythonCount = "Conta le ricorrenze di x" PythonDegrees = "Conversione di radianti in gradi" PythonDivMod = "Quoziente e resto" +PythonDrawLine = "Disegna una linea" PythonDrawString = "Visualizza il testo dal pixel x,y" PythonErf = "Funzione d'errore" PythonErfc = "Funzione d'errore complementare" @@ -71,6 +72,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" @@ -149,3 +155,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" diff --git a/apps/code/catalog.nl.i18n b/apps/code/catalog.nl.i18n index 894a5f6bf2d..1ee1f667ccb 100644 --- a/apps/code/catalog.nl.i18n +++ b/apps/code/catalog.nl.i18n @@ -45,6 +45,7 @@ PythonCosh = "Cosinus hyperbolicus" PythonCount = "Tel voorkomen van x" PythonDegrees = "Zet x om van radialen naar graden" PythonDivMod = "Quotiënt en rest" +PythonDrawLine = "Teken een lijn" PythonDrawString = "Geef een tekst weer van pixel (x,y)" PythonErf = "Error functie" PythonErfc = "Complementaire error functie" @@ -70,6 +71,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" @@ -149,3 +155,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" diff --git a/apps/code/catalog.pt.i18n b/apps/code/catalog.pt.i18n index 58c898b78d8..a17ea0ad5c0 100644 --- a/apps/code/catalog.pt.i18n +++ b/apps/code/catalog.pt.i18n @@ -45,6 +45,7 @@ PythonCosh = "Cosseno hiperbólico" PythonCount = "Contar as ocorrências de x" PythonDegrees = "Converter x de radianos para graus" PythonDivMod = "Quociente e resto" +PythonDrawLine = "Desenhe uma linha" PythonDrawString = "Mostrar o texto do pixel (x,y)" PythonErf = "Função erro" PythonErfc = "Função erro complementar" @@ -149,3 +150,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" diff --git a/apps/code/catalog.universal.i18n b/apps/code/catalog.universal.i18n index ff0cfed7a3f..39d1ff3b494 100644 --- a/apps/code/catalog.universal.i18n +++ b/apps/code/catalog.universal.i18n @@ -50,6 +50,7 @@ PythonCommandCount = "list.count(x)" PythonCommandCountWithoutArg = ".count(\x11)" PythonCommandDegrees = "degrees(x)" PythonCommandDivMod = "divmod(a,b)" +PythonCommandDrawLine = "draw_line(x1,y1,x2,y2,color)" PythonCommandDrawString = "draw_string(\"text\",x,y)" PythonCommandConstantE = "e" PythonCommandErf = "erf(x)" @@ -86,6 +87,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 +215,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 +241,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\")" diff --git a/apps/code/console_controller.cpp b/apps/code/console_controller.cpp index ac0dc330d55..c550d19f39e 100644 --- a/apps/code/console_controller.cpp +++ b/apps/code/console_controller.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -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); diff --git a/apps/code/console_controller.h b/apps/code/console_controller.h index ff79e7b51b3..d4fa256f68a 100644 --- a/apps/code/console_controller.h +++ b/apps/code/console_controller.h @@ -3,6 +3,7 @@ #include #include +#include #include "console_edit_cell.h" #include "console_line_cell.h" diff --git a/apps/code/console_edit_cell.h b/apps/code/console_edit_cell.h index 3c076f9a1e7..18f16ba5582 100644 --- a/apps/code/console_edit_cell.h +++ b/apps/code/console_edit_cell.h @@ -6,6 +6,7 @@ #include #include #include +#include namespace Code { diff --git a/apps/code/console_line_cell.cpp b/apps/code/console_line_cell.cpp index 99042762be0..3cad12787ad 100644 --- a/apps/code/console_line_cell.cpp +++ b/apps/code/console_line_cell.cpp @@ -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 { diff --git a/apps/code/console_line_cell.h b/apps/code/console_line_cell.h index fc49f61876f..b6c32d6d3ea 100644 --- a/apps/code/console_line_cell.h +++ b/apps/code/console_line_cell.h @@ -53,7 +53,7 @@ class ConsoleLineCell : public HighlightCell, public Responder { 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; diff --git a/apps/code/editor_controller.cpp b/apps/code/editor_controller.cpp index 39348a1d412..ffc2a77685b 100644 --- a/apps/code/editor_controller.cpp +++ b/apps/code/editor_controller.cpp @@ -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. */ diff --git a/apps/code/editor_view.cpp b/apps/code/editor_view.cpp index 9ec48d7eb74..2541612d5be 100644 --- a/apps/code/editor_view.cpp +++ b/apps/code/editor_view.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include 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); } } diff --git a/apps/code/menu_controller.cpp b/apps/code/menu_controller.cpp index 0857a0499b9..a857fc539a2 100644 --- a/apps/code/menu_controller.cpp +++ b/apps/code/menu_controller.cpp @@ -4,6 +4,7 @@ #include "../apps_container.h" #include #include +#include #include #include @@ -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(); diff --git a/apps/code/menu_controller.h b/apps/code/menu_controller.h index 6d87672adca..72bb6313013 100644 --- a/apps/code/menu_controller.h +++ b/apps/code/menu_controller.h @@ -19,6 +19,7 @@ class MenuController : public ViewController, public TableViewDataSource, public StackViewController * stackViewController(); void willExitResponderChain(Responder * nextFirstResponder) override; void renameSelectedScript(); + void duplicateScript(Script script); void deleteScript(Script script); void reloadConsole(); void openConsoleWithScript(Script script); diff --git a/apps/code/python_text_area.cpp b/apps/code/python_text_area.cpp index d0242debb12..ab0615f3bf4 100644 --- a/apps/code/python_text_area.cpp +++ b/apps/code/python_text_area.cpp @@ -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, diff --git a/apps/code/python_toolbox.cpp b/apps/code/python_toolbox.cpp index 984bfaa1868..34aa96bfac3 100644 --- a/apps/code/python_toolbox.cpp +++ b/apps/code/python_toolbox.cpp @@ -193,6 +193,7 @@ const ToolboxMessageTree KandinskyModuleChildren[] = { ToolboxMessageTree::Leaf(I18n::Message::PythonCommandSetPixel, I18n::Message::PythonSetPixel), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColor, I18n::Message::PythonColor), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDrawString, I18n::Message::PythonDrawString), + ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDrawLine, I18n::Message::PythonDrawLine), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFillRect, I18n::Message::PythonFillRect) }; @@ -212,6 +213,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), @@ -220,6 +230,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) }; @@ -261,6 +272,7 @@ const ToolboxMessageTree catalogChildren[] = { ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCosh, I18n::Message::PythonCosh), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDegrees, I18n::Message::PythonDegrees), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDivMod, I18n::Message::PythonDivMod), + ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDrawLine, I18n::Message::PythonDrawLine), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDrawString, I18n::Message::PythonDrawString), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandConstantE, I18n::Message::PythonConstantE, false), ToolboxMessageTree::Leaf(I18n::Message::PythonCommandErf, I18n::Message::PythonErf), @@ -391,11 +403,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); @@ -435,7 +475,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 diff --git a/apps/code/python_toolbox.h b/apps/code/python_toolbox.h index 222a9de3a22..bfe6820584d 100644 --- a/apps/code/python_toolbox.h +++ b/apps/code/python_toolbox.h @@ -16,10 +16,10 @@ class PythonToolbox : public Toolbox { // 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; diff --git a/apps/code/sandbox_controller.cpp b/apps/code/sandbox_controller.cpp index 7282f0138df..48d29f247a7 100644 --- a/apps/code/sandbox_controller.cpp +++ b/apps/code/sandbox_controller.cpp @@ -9,7 +9,7 @@ namespace Code { SandboxController::SandboxController(Responder * parentResponder) : ViewController(parentResponder), - m_solidColorView(KDColorWhite) + m_solidColorView(Palette::CodeBackground) { } diff --git a/apps/code/script_node_cell.cpp b/apps/code/script_node_cell.cpp index 21c23f756b7..0dc8675c359 100644 --- a/apps/code/script_node_cell.cpp +++ b/apps/code/script_node_cell.cpp @@ -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); } } diff --git a/apps/code/script_parameter_controller.cpp b/apps/code/script_parameter_controller.cpp index 5332fddc3a8..1390fcd995f 100644 --- a/apps/code/script_parameter_controller.cpp +++ b/apps/code/script_parameter_controller.cpp @@ -1,5 +1,6 @@ #include "script_parameter_controller.h" #include "menu_controller.h" +#include 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); } } diff --git a/apps/code/script_parameter_controller.h b/apps/code/script_parameter_controller.h index 3f334d134df..e7065e7334f 100644 --- a/apps/code/script_parameter_controller.h +++ b/apps/code/script_parameter_controller.h @@ -31,16 +31,20 @@ class ScriptParameterController : public ViewController, public SimpleListViewDa 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; }; } diff --git a/apps/code/script_template.cpp b/apps/code/script_template.cpp index 971b4449629..8b59c912af1 100644 --- a/apps/code/script_template.cpp +++ b/apps/code/script_template.cpp @@ -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))"); diff --git a/apps/code/toolbox.de.i18n b/apps/code/toolbox.de.i18n index 41775c90cec..34840329bfb 100644 --- a/apps/code/toolbox.de.i18n +++ b/apps/code/toolbox.de.i18n @@ -2,3 +2,5 @@ Functions = "Funktionen" Catalog = "Katalog" Modules = "Module" LoopsAndTests = "Schleifen und Tests" +Files = "Dateien" +Exceptions = "Ausnahmen" diff --git a/apps/code/toolbox.en.i18n b/apps/code/toolbox.en.i18n index 178d42b7b19..81e60c7da2b 100644 --- a/apps/code/toolbox.en.i18n +++ b/apps/code/toolbox.en.i18n @@ -2,3 +2,5 @@ Functions = "Functions" Catalog = "Catalog" Modules = "Modules" LoopsAndTests = "Loops and tests" +Files = "Files" +Exceptions = "Exceptions" diff --git a/apps/code/toolbox.es.i18n b/apps/code/toolbox.es.i18n index 178d42b7b19..81e60c7da2b 100644 --- a/apps/code/toolbox.es.i18n +++ b/apps/code/toolbox.es.i18n @@ -2,3 +2,5 @@ Functions = "Functions" Catalog = "Catalog" Modules = "Modules" LoopsAndTests = "Loops and tests" +Files = "Files" +Exceptions = "Exceptions" diff --git a/apps/code/toolbox.fr.i18n b/apps/code/toolbox.fr.i18n index 6442521cc8c..724abb7a518 100644 --- a/apps/code/toolbox.fr.i18n +++ b/apps/code/toolbox.fr.i18n @@ -2,3 +2,5 @@ Functions = "Fonctions" Catalog = "Catalogue" Modules = "Modules" LoopsAndTests = "Boucles et tests" +Files = "Fichiers" +Exceptions = "Exceptions" diff --git a/apps/code/toolbox.hu.i18n b/apps/code/toolbox.hu.i18n new file mode 100644 index 00000000000..89015122024 --- /dev/null +++ b/apps/code/toolbox.hu.i18n @@ -0,0 +1,6 @@ +Functions = "Funkciók" +Catalog = "Katalógus" +Modules = "Modulok" +LoopsAndTests = "Hurkok és tesztek" +Files = "Fájlok" +Exceptions = "Kivételek" diff --git a/apps/code/toolbox.it.i18n b/apps/code/toolbox.it.i18n index d35b67cffa1..d7b219d872e 100644 --- a/apps/code/toolbox.it.i18n +++ b/apps/code/toolbox.it.i18n @@ -2,3 +2,5 @@ Functions = "Funzioni" Catalog = "Catalogo" Modules = "Moduli" LoopsAndTests = "Cicli e test" +Files = "Files" +Exceptions = "Exceptions" diff --git a/apps/code/toolbox.nl.i18n b/apps/code/toolbox.nl.i18n index 15c3ebb290b..849bd76a6ab 100644 --- a/apps/code/toolbox.nl.i18n +++ b/apps/code/toolbox.nl.i18n @@ -2,3 +2,5 @@ Functions = "Functies" Catalog = "Catalogus" Modules = "Modules" LoopsAndTests = "Herhalingen en testen" +Files = "Files" +Exceptions = "Exceptions" diff --git a/apps/code/toolbox.pt.i18n b/apps/code/toolbox.pt.i18n index 6bfd6c5da23..f7cfad07b03 100644 --- a/apps/code/toolbox.pt.i18n +++ b/apps/code/toolbox.pt.i18n @@ -2,3 +2,5 @@ Functions = "Funções" Catalog = "Catálogo" Modules = "Módulos" LoopsAndTests = "Laços e testes" +Files = "Files" +Exceptions = "Exceptions" diff --git a/apps/code/toolbox.universal.i18n b/apps/code/toolbox.universal.i18n index d1048eff9f0..4dd5345def6 100644 --- a/apps/code/toolbox.universal.i18n +++ b/apps/code/toolbox.universal.i18n @@ -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 " diff --git a/apps/code/variable_box_controller.cpp b/apps/code/variable_box_controller.cpp index c329fb7f17c..279c9c57c44 100644 --- a/apps/code/variable_box_controller.cpp +++ b/apps/code/variable_box_controller.cpp @@ -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); } } diff --git a/apps/exam_mode_configuration.h b/apps/exam_mode_configuration.h index 600f312d22b..7ec6e42011d 100644 --- a/apps/exam_mode_configuration.h +++ b/apps/exam_mode_configuration.h @@ -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); } diff --git a/apps/exam_mode_configuration_non_official.cpp b/apps/exam_mode_configuration_non_official.cpp index 96255a785ec..de8948911d2 100644 --- a/apps/exam_mode_configuration_non_official.cpp +++ b/apps/exam_mode_configuration_non_official.cpp @@ -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; +} \ No newline at end of file diff --git a/apps/exam_mode_configuration_official.cpp b/apps/exam_mode_configuration_official.cpp deleted file mode 100644 index 5cdc1fb8f75..00000000000 --- a/apps/exam_mode_configuration_official.cpp +++ /dev/null @@ -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; -} diff --git a/apps/exam_pop_up_controller.cpp b/apps/exam_pop_up_controller.cpp index 0bc5982ac68..75a998565ff 100644 --- a/apps/exam_pop_up_controller.cpp +++ b/apps/exam_pop_up_controller.cpp @@ -2,6 +2,9 @@ #include "apps_container.h" #include "exam_mode_configuration.h" #include +#include + +using namespace Poincare; ExamPopUpController::ExamPopUpController(ExamPopUpControllerDelegate * delegate) : PopUpController( diff --git a/apps/external/Makefile b/apps/external/Makefile new file mode 100644 index 00000000000..0929e8d218c --- /dev/null +++ b/apps/external/Makefile @@ -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\ +) + diff --git a/apps/external/app.cpp b/apps/external/app.cpp new file mode 100644 index 00000000000..fba8ffccc97 --- /dev/null +++ b/apps/external/app.cpp @@ -0,0 +1,48 @@ +#include "app.h" +#include "external_icon.h" +#include + +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) +{ +} + +} diff --git a/apps/external/app.h b/apps/external/app.h new file mode 100644 index 00000000000..8077289f5c2 --- /dev/null +++ b/apps/external/app.h @@ -0,0 +1,38 @@ +#ifndef EXTERNAL_APP_H +#define EXTERNAL_APP_H + +#include +#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 diff --git a/apps/external/app/sample.c b/apps/external/app/sample.c new file mode 100644 index 00000000000..dbc13fd9545 --- /dev/null +++ b/apps/external/app/sample.c @@ -0,0 +1,6 @@ +#include + +void extapp_main() { + extapp_pushRectUniform(10, 10, LCD_WIDTH-20, LCD_HEIGHT-20, 0); + extapp_msleep(1000); +} diff --git a/apps/external/app/sources.mak b/apps/external/app/sources.mak new file mode 100644 index 00000000000..3f285e23a47 --- /dev/null +++ b/apps/external/app/sources.mak @@ -0,0 +1,3 @@ +app_external_src += $(addprefix apps/external/app/,\ + sample.c \ +) \ No newline at end of file diff --git a/apps/external/archive.cpp b/apps/external/archive.cpp new file mode 100644 index 00000000000..8f3d000bf7c --- /dev/null +++ b/apps/external/archive.cpp @@ -0,0 +1,212 @@ +#include "archive.h" +#include "extapp_api.h" +#include "../global_preferences.h" + +#include +#include + +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(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(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(reinterpret_cast(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(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 + +} +} diff --git a/apps/external/archive.h b/apps/external/archive.h new file mode 100644 index 00000000000..670bd138f42 --- /dev/null +++ b/apps/external/archive.h @@ -0,0 +1,29 @@ +#ifndef EXTERNAL_ARCHIVE_H +#define EXTERNAL_ARCHIVE_H + +#include +#include + +namespace External { +namespace Archive { + +constexpr int MaxNameLength = 40; + +struct File { + const char *name; + const uint8_t *data; + size_t dataLength; + bool isExecutable; +}; + +bool fileAtIndex(size_t index, File &entry); +int indexFromName(const char *name); +size_t numberOfFiles(); +size_t numberOfExecutables(); +bool executableAtIndex(size_t index, File &entry); +uint32_t executeFile(const char *name, void * heap, const uint32_t heapSize); + +} +} + +#endif diff --git a/apps/external/base.de.i18n b/apps/external/base.de.i18n new file mode 100644 index 00000000000..fb566db7029 --- /dev/null +++ b/apps/external/base.de.i18n @@ -0,0 +1,9 @@ +ExternalApp = "External" +ExternalAppCapital = "EXTERNAL" +ExternalAppApiMismatch = "API mismatch" +ExternalAppExecError = "Cannot execute file" +ExternalNotCompatible = "External ist nicht kompatibel" +WithSimulator = "mit dem Simulator" +WithN0100 = "mit n0100" +GetMoreAppsAt = "Weitere Apps erhalten Sie auf" +NoAppsInstalled = "Keine Apps installiert" diff --git a/apps/external/base.en.i18n b/apps/external/base.en.i18n new file mode 100644 index 00000000000..49b8a217333 --- /dev/null +++ b/apps/external/base.en.i18n @@ -0,0 +1,9 @@ +ExternalApp = "External" +ExternalAppCapital = "EXTERNAL" +ExternalAppApiMismatch = "API mismatch" +ExternalAppExecError = "Cannot execute file" +ExternalNotCompatible = "External is not compatible" +WithSimulator = "with the simulator" +WithN0100 = "with n0100" +GetMoreAppsAt = "Get more apps at" +NoAppsInstalled = "No apps installed" diff --git a/apps/external/base.es.i18n b/apps/external/base.es.i18n new file mode 100644 index 00000000000..7513cd076f7 --- /dev/null +++ b/apps/external/base.es.i18n @@ -0,0 +1,9 @@ +ExternalApp = "External" +ExternalAppCapital = "EXTERNAL" +ExternalAppApiMismatch = "Discordancia de API" +ExternalAppExecError = "No se puede ejecutar el archivo" +ExternalNotCompatible = "Externo no es compatible" +WithSimulator = "con el simulador" +WithN0100 = "con n0100" +GetMoreAppsAt = "Obtenga más aplicaciones en" +NoAppsInstalled = "No hay aplicaciones instaladas" diff --git a/apps/external/base.fr.i18n b/apps/external/base.fr.i18n new file mode 100644 index 00000000000..626444a1b8c --- /dev/null +++ b/apps/external/base.fr.i18n @@ -0,0 +1,9 @@ +ExternalApp = "External" +ExternalAppCapital = "EXTERNAL" +ExternalAppApiMismatch = "Décalage API" +ExternalAppExecError = "Le fichier ne peut pas être exécuté" +ExternalNotCompatible = "External n'est pas compatible" +WithSimulator = "avec le simulateur" +WithN0100 = "avec n0100" +GetMoreAppsAt = "Télécharge d'autres apps sur" +NoAppsInstalled = "Aucune applications installées" diff --git a/apps/external/base.hu.i18n b/apps/external/base.hu.i18n new file mode 100644 index 00000000000..e984edc511d --- /dev/null +++ b/apps/external/base.hu.i18n @@ -0,0 +1,9 @@ +ExternalApp = "Külsö" +ExternalAppCapital = "KÜLSÖ" +ExternalAppApiMismatch = "API eltérés" +ExternalAppExecError = "A fájl nem futtatható" +ExternalNotCompatible = "Externál nem kompatibilis" +WithSimulator = "Szimulátorral" +WithN0100 = "n0100-al" +GetMoreAppsAt = "Mégtöbb alkalmazás itt :" +NoAppsInstalled = "Nincs letöltött externál" diff --git a/apps/external/base.it.i18n b/apps/external/base.it.i18n new file mode 100644 index 00000000000..49b8a217333 --- /dev/null +++ b/apps/external/base.it.i18n @@ -0,0 +1,9 @@ +ExternalApp = "External" +ExternalAppCapital = "EXTERNAL" +ExternalAppApiMismatch = "API mismatch" +ExternalAppExecError = "Cannot execute file" +ExternalNotCompatible = "External is not compatible" +WithSimulator = "with the simulator" +WithN0100 = "with n0100" +GetMoreAppsAt = "Get more apps at" +NoAppsInstalled = "No apps installed" diff --git a/apps/external/base.nl.i18n b/apps/external/base.nl.i18n new file mode 100644 index 00000000000..49b8a217333 --- /dev/null +++ b/apps/external/base.nl.i18n @@ -0,0 +1,9 @@ +ExternalApp = "External" +ExternalAppCapital = "EXTERNAL" +ExternalAppApiMismatch = "API mismatch" +ExternalAppExecError = "Cannot execute file" +ExternalNotCompatible = "External is not compatible" +WithSimulator = "with the simulator" +WithN0100 = "with n0100" +GetMoreAppsAt = "Get more apps at" +NoAppsInstalled = "No apps installed" diff --git a/apps/external/base.pt.i18n b/apps/external/base.pt.i18n new file mode 100644 index 00000000000..ae08d747879 --- /dev/null +++ b/apps/external/base.pt.i18n @@ -0,0 +1,9 @@ +ExternalApp = "External" +ExternalAppCapital = "EXTERNAL" +ExternalAppApiMismatch = "API mismatch" +ExternalAppExecError = "Cannot execute file" +ExternalNotCompatible = "Externo no es compatiblee" +WithSimulator = "con el simulador" +WithN0100 = "con n0100" +GetMoreAppsAt = "Obtenga más aplicaciones en" +NoAppsInstalled = "No hay aplicaciones instaladas" diff --git a/apps/external/base.universal.i18n b/apps/external/base.universal.i18n new file mode 100644 index 00000000000..bd64604ea1a --- /dev/null +++ b/apps/external/base.universal.i18n @@ -0,0 +1 @@ +URL = "zardam.github.io/nw-external-apps/" \ No newline at end of file diff --git a/apps/external/extapp_api.cpp b/apps/external/extapp_api.cpp new file mode 100644 index 00000000000..eefd19f5810 --- /dev/null +++ b/apps/external/extapp_api.cpp @@ -0,0 +1,309 @@ +#include +#include +#include +#include +#include +#include +#include "archive.h" +#include "extapp_api.h" +#include "../apps_container.h" +#include "../global_preferences.h" + +#include + +extern "C" { + #include +} + +uint64_t extapp_millis() { + return Ion::Timing::millis(); +} + +void extapp_msleep(uint32_t ms) { + Ion::Timing::msleep(ms); +} + +uint64_t extapp_scanKeyboard() { + return Ion::Keyboard::scan(); +} + +void extapp_pushRect(int16_t x, int16_t y, uint16_t w, uint16_t h, const uint16_t * pixels) { + KDRect rect(x, y, w, h); + + Ion::Display::pushRect(rect, reinterpret_cast(pixels)); +} + +void extapp_pushRectUniform(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t color) { + KDRect rect(x, y, w, h); + + Ion::Display::pushRectUniform(rect, KDColor::RGB16(color)); +} + +void extapp_pullRect(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t * pixels) { + KDRect rect(x, y, w, h); + + Ion::Display::pullRect(rect, (KDColor *) pixels); +} + +int16_t extapp_drawTextLarge(const char *text, int16_t x, int16_t y, uint16_t fg, uint16_t bg, bool fake) { + KDPoint point(x, y); + + auto ctx = KDIonContext::sharedContext(); + ctx->setClippingRect(KDRect(0, 0, 320, fake ? 0 : 240)); + ctx->setOrigin(KDPoint(0, 0)); + point = ctx->drawString(text, point, KDFont::LargeFont, KDColor::RGB16(fg), KDColor::RGB16(bg)); + + return point.x(); +} + +int16_t extapp_drawTextSmall(const char *text, int16_t x, int16_t y, uint16_t fg, uint16_t bg, bool fake) { + KDPoint point(x, y); + + auto ctx = KDIonContext::sharedContext(); + ctx->setClippingRect(KDRect(0, 0, 320, fake ? 0 : 240)); + ctx->setOrigin(KDPoint(0, 0)); + point = ctx->drawString(text, point, KDFont::SmallFont, KDColor::RGB16(fg), KDColor::RGB16(bg)); + + return point.x(); +} + +bool extapp_waitForVBlank() { + return Ion::Display::waitForVBlank(); +} + +void extapp_clipboardStore(const char *text) { + Clipboard::sharedClipboard()->store(text); +} + +const char * extapp_clipboardText() { + return Clipboard::sharedClipboard()->storedText(); +} + +int extapp_fileListWithExtension(const char ** filenames, int maxrecords, const char * extension, int storage) { + if(storage == EXTAPP_RAM_FILE_SYSTEM) { + int n = Ion::Storage::sharedStorage()->numberOfRecordsWithExtension(extension); + if (n > maxrecords) { + n = maxrecords; + } + for(int i = 0; i < n; i++) { + filenames[i] = Ion::Storage::sharedStorage()->recordWithExtensionAtIndex(extension, i).fullName(); + } + return n; + } else if(storage == EXTAPP_FLASH_FILE_SYSTEM) { + // TODO: filter by extension + int n = External::Archive::numberOfFiles(); + if (n > maxrecords) { + n = maxrecords; + } + for(int i = 0; i < n; i++) { + External::Archive::File entry; + External::Archive::fileAtIndex(i, entry); + filenames[i] = entry.name; + } + return n; + } else { + return 0; + } +} + +bool extapp_fileExists(const char * filename, int storage) { + if(storage == EXTAPP_RAM_FILE_SYSTEM) { + return !Ion::Storage::sharedStorage()->recordNamed(filename).isNull(); + } else if(storage == EXTAPP_FLASH_FILE_SYSTEM) { + return External::Archive::indexFromName(filename) >= 0; + } else { + return false; + } +} + +bool extapp_fileErase(const char * filename, int storage) { + if(storage == EXTAPP_RAM_FILE_SYSTEM) { + Ion::Storage::Record record = Ion::Storage::sharedStorage()->recordNamed(filename); + if(record.isNull()) { + return false; + } else { + record.destroy(); + return true; + } + } else { + return false; + } +} + +const char * extapp_fileRead(const char * filename, size_t *len, int storage) { + if(storage == EXTAPP_RAM_FILE_SYSTEM) { + const Ion::Storage::Record record = Ion::Storage::sharedStorage()->recordNamed(filename); + if (record.isNull()) { + return NULL; + } else { + if(len) { + *len = record.value().size; + } + return (const char *) record.value().buffer; + } + } else if(storage == EXTAPP_FLASH_FILE_SYSTEM) { + int index = External::Archive::indexFromName(filename); + if (index >= 0) { + External::Archive::File entry; + External::Archive::fileAtIndex(index, entry); + if(len) { + *len = entry.dataLength; + } + return (const char *)entry.data; + } else { + return NULL; + } + } else { + return NULL; + } +} + +bool extapp_fileWrite(const char * filename, const char * content, size_t len, int storage) { + if(storage == EXTAPP_RAM_FILE_SYSTEM) { + Ion::Storage::Record::ErrorStatus status = Ion::Storage::sharedStorage()->createRecordWithFullName(filename, content, len); + if (status == Ion::Storage::Record::ErrorStatus::NameTaken) { + Ion::Storage::Record::Data data; + data.buffer = content; + data.size = len; + return Ion::Storage::sharedStorage()->recordNamed(filename).setValue(data) == Ion::Storage::Record::ErrorStatus::None; + } else if (status == Ion::Storage::Record::ErrorStatus::None) { + return true; + } else { + return false; + } + } else { + return false; + } +} + +static void reloadTitleBar() { + AppsContainer::sharedAppsContainer()->setShiftAlphaStatus(Ion::Events::shiftAlphaStatus()); + AppsContainer::sharedAppsContainer()->refreshPreferences(); + AppsContainer::sharedAppsContainer()->updateBatteryState(); + AppsContainer::sharedAppsContainer()->reloadTitleBarView(); + AppsContainer::sharedAppsContainer()->redrawWindow(); +} + +void extapp_lockAlpha() { + Ion::Events::setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::AlphaLock); + reloadTitleBar(); +} + +void extapp_resetKeyboard() { + Ion::Events::setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::Default); + reloadTitleBar(); +} + +const int16_t translated_keys[] = +{ + // non shifted + KEY_CTRL_LEFT,KEY_CTRL_UP,KEY_CTRL_DOWN,KEY_CTRL_RIGHT,KEY_CTRL_OK,KEY_CTRL_EXIT, + KEY_CTRL_MENU,KEY_PRGM_ACON,KEY_PRGM_ACON,9,10,11, + KEY_CTRL_SHIFT,KEY_CTRL_ALPHA,KEY_CTRL_XTT,KEY_CTRL_VARS,KEY_CTRL_CATALOG,KEY_CTRL_DEL, + KEY_CHAR_EXPN,KEY_CHAR_LN,KEY_CHAR_LOG,KEY_CHAR_IMGNRY,',',KEY_CHAR_POW, + KEY_CHAR_SIN,KEY_CHAR_COS,KEY_CHAR_TAN,KEY_CHAR_PI,KEY_CHAR_ROOT,KEY_CHAR_SQUARE, + '7','8','9','(',')',-1, + '4','5','6','*','/',-1, + '1','2','3','+','-',-1, + '0','.',KEY_CHAR_EXPN10,KEY_CHAR_ANS,KEY_CTRL_EXE,-1, + // shifted + KEY_SHIFT_LEFT,KEY_CTRL_PAGEUP,KEY_CTRL_PAGEDOWN,KEY_SHIFT_RIGHT,KEY_CTRL_OK,KEY_CTRL_EXIT, + KEY_CTRL_MENU,KEY_PRGM_ACON,KEY_PRGM_ACON,9,10,11, + KEY_CTRL_SHIFT,KEY_CTRL_ALPHA,KEY_CTRL_CUT,KEY_CTRL_CLIP,KEY_CTRL_PASTE,KEY_CTRL_AC, + KEY_CHAR_LBRCKT,KEY_CHAR_RBRCKT,KEY_CHAR_LBRACE,KEY_CHAR_RBRACE,'_',KEY_CHAR_STORE, + KEY_CHAR_ASIN,KEY_CHAR_ACOS,KEY_CHAR_ATAN,'=','<','>', + KEY_CTRL_F7,KEY_CTRL_F8,KEY_CTRL_F9,KEY_CTRL_F13,KEY_CTRL_F14,-1, + KEY_CTRL_F4,KEY_CTRL_F5,KEY_CTRL_F6,KEY_CHAR_FACTOR,'%',-1, + KEY_CTRL_F1,KEY_CTRL_F2,KEY_CTRL_F3,KEY_CHAR_NORMAL,'\\',-1, + KEY_CTRL_F10,KEY_CTRL_F11,KEY_CTRL_F12,KEY_SHIFT_ANS,KEY_CTRL_EXE,-1, + // alpha + KEY_CTRL_LEFT,KEY_CTRL_UP,KEY_CTRL_DOWN,KEY_CTRL_RIGHT,KEY_CTRL_OK,KEY_CTRL_EXIT, + KEY_CTRL_MENU,KEY_PRGM_ACON,KEY_PRGM_ACON,9,10,11, + KEY_CTRL_SHIFT,KEY_CTRL_ALPHA,':',';','"',KEY_CTRL_DEL, + 'a','b','c','d','e','f', + 'g','h','i','j','k','l', + 'm','n','o','p','q',-1, + 'r','s','t','u','v',-1, + 'w','x','y','z',' ',-1, + '?','!',KEY_CHAR_EXPN10,KEY_CHAR_ANS,KEY_CTRL_EXE,-1, + // alpha shifted + KEY_SHIFT_LEFT,KEY_CTRL_PAGEUP,KEY_CTRL_PAGEDOWN,KEY_SHIFT_RIGHT,KEY_CTRL_OK,KEY_CTRL_EXIT, + KEY_CTRL_MENU,KEY_PRGM_ACON,KEY_PRGM_ACON,9,10,11, + KEY_CTRL_SHIFT,KEY_CTRL_ALPHA,':',';','\'','%', + 'A','B','C','D','E','F', + 'G','H','I','J','K','L', + 'M','N','O','P','Q',-1, + 'R','S','T','U','V',-1, + 'W','X','Y','Z',' ',-1, + '?','!',KEY_CHAR_EXPN10,KEY_CHAR_ANS,KEY_CTRL_EXE,-1, +}; + +#ifdef SIMULATOR +#define TICKS_PER_MINUTE 60000 +#else +#define TICKS_PER_MINUTE 11862 +#endif + +int extapp_getKey(bool allowSuspend, bool *alphaWasActive) { + int key = -1; + size_t t1 = Ion::Timing::millis(); + for (;;) { + int timeout = 10000; + if(alphaWasActive) { + *alphaWasActive = Ion::Events::isAlphaActive(); + } + Ion::Events::Event event = Ion::Events::getEvent(&timeout); + reloadTitleBar(); + if (event == Ion::Events::None) { + size_t t2 = Ion::Timing::millis(); + if (t2 - t1 > 2 * TICKS_PER_MINUTE) { + event = Ion::Events::OnOff; + } + } else { + t1 = Ion::Timing::millis(); + } + if (event.isKeyboardEvent()) { + Ion::Backlight::setBrightness(GlobalPreferences::sharedGlobalPreferences()->brightnessLevel()); + } + if (event == Ion::Events::Shift || event == Ion::Events::Alpha) { + continue; + } + if (event.isKeyboardEvent()) { + key = static_cast(event); + if (key == 17 || key == 4 || key == 5 || key == 52) { + extapp_resetKeyboard(); + } + if (allowSuspend && (key == 7 || key == 8)) { // power + Ion::Power::suspend(true); + extapp_pushRectUniform(0, 0, 320, 240, 65535); + Ion::Backlight::setBrightness(GlobalPreferences::sharedGlobalPreferences()->brightnessLevel()); + reloadTitleBar(); + } + break; + } + } + return translated_keys[key]; +} + +extern "C" void (* const apiPointers[])(void) = { + (void (*)(void)) extapp_millis, + (void (*)(void)) extapp_msleep, + (void (*)(void)) extapp_scanKeyboard, + (void (*)(void)) extapp_pushRect, + (void (*)(void)) extapp_pushRectUniform, + (void (*)(void)) extapp_pullRect, + (void (*)(void)) extapp_drawTextLarge, + (void (*)(void)) extapp_drawTextSmall, + (void (*)(void)) extapp_waitForVBlank, + (void (*)(void)) extapp_clipboardStore, + (void (*)(void)) extapp_clipboardText, + (void (*)(void)) extapp_fileListWithExtension, + (void (*)(void)) extapp_fileExists, + (void (*)(void)) extapp_fileErase, + (void (*)(void)) extapp_fileRead, + (void (*)(void)) extapp_fileWrite, + (void (*)(void)) extapp_lockAlpha, + (void (*)(void)) extapp_resetKeyboard, + (void (*)(void)) extapp_getKey, + (void (*)(void)) nullptr, +}; diff --git a/apps/external/extapp_api.h b/apps/external/extapp_api.h new file mode 100644 index 00000000000..b17b8643673 --- /dev/null +++ b/apps/external/extapp_api.h @@ -0,0 +1,256 @@ +#ifndef EXTERNAL_API_H +#define EXTERNAL_API_H + +#include +#include +#include + +#define API_VERSION 2 + +#ifdef __cplusplus +#define EXTERNC extern "C" +#else +#define EXTERNC +#endif + +#define LCD_WIDTH 320 +#define LCD_HEIGHT 240 + +#define EXTAPP_RAM_FILE_SYSTEM 0 +#define EXTAPP_FLASH_FILE_SYSTEM 1 + +#define SCANCODE_Left ((uint64_t)1 << 0) +#define SCANCODE_Up ((uint64_t)1 << 1) +#define SCANCODE_Down ((uint64_t)1 << 2) +#define SCANCODE_Right ((uint64_t)1 << 3) +#define SCANCODE_OK ((uint64_t)1 << 4) +#define SCANCODE_Back ((uint64_t)1 << 5) +#define SCANCODE_Home ((uint64_t)1 << 6) +#define SCANCODE_OnOff (((uint64_t)1 << 7) || ((uint64_t)1 << 8)) +#define SCANCODE_Shift ((uint64_t)1 << 12) +#define SCANCODE_Alpha ((uint64_t)1 << 13) +#define SCANCODE_XNT ((uint64_t)1 << 14) +#define SCANCODE_Var ((uint64_t)1 << 15) +#define SCANCODE_Toolbox ((uint64_t)1 << 16) +#define SCANCODE_Backspace ((uint64_t)1 << 17) +#define SCANCODE_Exp ((uint64_t)1 << 18) +#define SCANCODE_Ln ((uint64_t)1 << 19) +#define SCANCODE_Log ((uint64_t)1 << 20) +#define SCANCODE_Imaginary ((uint64_t)1 << 21) +#define SCANCODE_Comma ((uint64_t)1 << 22) +#define SCANCODE_Power ((uint64_t)1 << 23) +#define SCANCODE_Sine ((uint64_t)1 << 24) +#define SCANCODE_Cosine ((uint64_t)1 << 25) +#define SCANCODE_Tangent ((uint64_t)1 << 26) +#define SCANCODE_Pi ((uint64_t)1 << 27) +#define SCANCODE_Sqrt ((uint64_t)1 << 28) +#define SCANCODE_Square ((uint64_t)1 << 29) +#define SCANCODE_Seven ((uint64_t)1 << 30) +#define SCANCODE_Eight ((uint64_t)1 << 31) +#define SCANCODE_Nine ((uint64_t)1 << 32) +#define SCANCODE_LeftParenthesis ((uint64_t)1 << 33) +#define SCANCODE_RightParenthesis ((uint64_t)1 << 34) +#define SCANCODE_Four ((uint64_t)1 << 36) +#define SCANCODE_Five ((uint64_t)1 << 37) +#define SCANCODE_Six ((uint64_t)1 << 38) +#define SCANCODE_Multiplication ((uint64_t)1 << 39) +#define SCANCODE_Division ((uint64_t)1 << 40) +#define SCANCODE_One ((uint64_t)1 << 42) +#define SCANCODE_Two ((uint64_t)1 << 43) +#define SCANCODE_Three ((uint64_t)1 << 44) +#define SCANCODE_Plus ((uint64_t)1 << 45) +#define SCANCODE_Minus ((uint64_t)1 << 46) +#define SCANCODE_Zero ((uint64_t)1 << 48) +#define SCANCODE_Dot ((uint64_t)1 << 49) +#define SCANCODE_EE ((uint64_t)1 << 50) +#define SCANCODE_Ans ((uint64_t)1 << 51) +#define SCANCODE_EXE ((uint64_t)1 << 52) +#define SCANCODE_None ((uint64_t)1 << 54) + +// Character codes +#define KEY_CHAR_0 0x30 +#define KEY_CHAR_1 0x31 +#define KEY_CHAR_2 0x32 +#define KEY_CHAR_3 0x33 +#define KEY_CHAR_4 0x34 +#define KEY_CHAR_5 0x35 +#define KEY_CHAR_6 0x36 +#define KEY_CHAR_7 0x37 +#define KEY_CHAR_8 0x38 +#define KEY_CHAR_9 0x39 +#define KEY_CHAR_DP 0x2e +#define KEY_CHAR_EXP 0x0f +#define KEY_CHAR_PMINUS 30200 +#define KEY_CHAR_PLUS 43 +#define KEY_CHAR_MINUS 45 +#define KEY_CHAR_MULT 42 +#define KEY_CHAR_DIV 47 +#define KEY_CHAR_FRAC 0xbb +#define KEY_CHAR_LPAR 0x28 +#define KEY_CHAR_RPAR 0x29 +#define KEY_CHAR_COMMA 0x2c +#define KEY_CHAR_STORE 0x0e +#define KEY_CHAR_LOG 0x95 +#define KEY_CHAR_LN 0x85 +#define KEY_CHAR_SIN 0x81 +#define KEY_CHAR_COS 0x82 +#define KEY_CHAR_TAN 0x83 +#define KEY_CHAR_SQUARE 0x8b +#define KEY_CHAR_POW 0xa8 +#define KEY_CHAR_IMGNRY 0x7f50 +#define KEY_CHAR_LIST 0x7f51 +#define KEY_CHAR_MAT 0x7f40 +#define KEY_CHAR_EQUAL 0x3d +#define KEY_CHAR_PI 0xd0 +#define KEY_CHAR_ANS 0xc0 +#define KEY_SHIFT_ANS 0xc1 +#define KEY_CHAR_LBRCKT 0x5b +#define KEY_CHAR_RBRCKT 0x5d +#define KEY_CHAR_LBRACE 0x7b +#define KEY_CHAR_RBRACE 0x7d +#define KEY_CHAR_CR 0x0d +#define KEY_CHAR_CUBEROOT 0x96 +#define KEY_CHAR_RECIP 0x9b +#define KEY_CHAR_ANGLE 0x7f54 +#define KEY_CHAR_EXPN10 0xb5 +#define KEY_CHAR_EXPN 0xa5 +#define KEY_CHAR_ASIN 0x91 +#define KEY_CHAR_ACOS 0x92 +#define KEY_CHAR_ATAN 0x93 +#define KEY_CHAR_ROOT 0x86 +#define KEY_CHAR_POWROOT 0xb8 +#define KEY_CHAR_SPACE 0x20 +#define KEY_CHAR_DQUATE 0x22 +#define KEY_CHAR_VALR 0xcd +#define KEY_CHAR_THETA 0xce +#define KEY_CHAR_FACTOR 0xda +#define KEY_CHAR_NORMAL 0xdb +#define KEY_CHAR_A 0x41 +#define KEY_CHAR_B 0x42 +#define KEY_CHAR_C 0x43 +#define KEY_CHAR_D 0x44 +#define KEY_CHAR_E 0x45 +#define KEY_CHAR_F 0x46 +#define KEY_CHAR_G 0x47 +#define KEY_CHAR_H 0x48 +#define KEY_CHAR_I 0x49 +#define KEY_CHAR_J 0x4a +#define KEY_CHAR_K 0x4b +#define KEY_CHAR_L 0x4c +#define KEY_CHAR_M 0x4d +#define KEY_CHAR_N 0x4e +#define KEY_CHAR_O 0x4f +#define KEY_CHAR_P 0x50 +#define KEY_CHAR_Q 0x51 +#define KEY_CHAR_R 0x52 +#define KEY_CHAR_S 0x53 +#define KEY_CHAR_T 0x54 +#define KEY_CHAR_U 0x55 +#define KEY_CHAR_V 0x56 +#define KEY_CHAR_W 0x57 +#define KEY_CHAR_X 0x58 +#define KEY_CHAR_Y 0x59 +#define KEY_CHAR_Z 0x5a + +// Control codes +#define KEY_CTRL_NOP 30202 +#define KEY_CTRL_EXE 30201 +#define KEY_CTRL_DEL 30025 +#define KEY_CTRL_AC 30070 +#define KEY_CTRL_FD 30046 +#define KEY_CTRL_UNDO 30045 +#define KEY_CTRL_XTT 30001 +#define KEY_CTRL_EXIT 5 +#define KEY_CTRL_OK 4 +#define KEY_CTRL_SHIFT 30006 +#define KEY_CTRL_ALPHA 30007 +#define KEY_CTRL_OPTN 30008 +#define KEY_CTRL_VARS 30030 +#define KEY_CTRL_UP 1 +#define KEY_CTRL_DOWN 2 +#define KEY_CTRL_LEFT 0 +#define KEY_CTRL_RIGHT 3 +#define KEY_CTRL_F1 30009 +#define KEY_CTRL_F2 30010 +#define KEY_CTRL_F3 30011 +#define KEY_CTRL_F4 30012 +#define KEY_CTRL_F5 30013 +#define KEY_CTRL_F6 30014 +#define KEY_CTRL_F7 30015 +#define KEY_CTRL_F8 30016 +#define KEY_CTRL_F9 30017 +#define KEY_CTRL_F10 30018 +#define KEY_CTRL_F11 30019 +#define KEY_CTRL_F12 30020 +#define KEY_CTRL_F13 30021 +#define KEY_CTRL_F14 30022 +#define KEY_CTRL_CATALOG 30100 +#define KEY_CTRL_CAPTURE 30055 +#define KEY_CTRL_CLIP 30050 +#define KEY_CTRL_CUT 30250 +#define KEY_CTRL_PASTE 30036 +#define KEY_CTRL_INS 30033 +#define KEY_CTRL_MIXEDFRAC 30054 +#define KEY_CTRL_FRACCNVRT 30026 +#define KEY_CTRL_QUIT 30029 +#define KEY_CTRL_PRGM 30028 +#define KEY_CTRL_SETUP 30037 +#define KEY_CTRL_PAGEUP 30052 +#define KEY_CTRL_PAGEDOWN 30053 +#define KEY_CTRL_MENU 30003 +#define KEY_SHIFT_OPTN 30059 +#define KEY_CTRL_RESERVE1 30060 +#define KEY_CTRL_RESERVE2 30061 +#define KEY_SHIFT_LEFT 30062 +#define KEY_SHIFT_RIGHT 30063 + +#define KEY_PRGM_ACON 10 +#define KEY_PRGM_DOWN 37 +#define KEY_PRGM_EXIT 47 +#define KEY_PRGM_F1 79 +#define KEY_PRGM_F2 69 +#define KEY_PRGM_F3 59 +#define KEY_PRGM_F4 49 +#define KEY_PRGM_F5 39 +#define KEY_PRGM_F6 29 +#define KEY_PRGM_LEFT 38 +#define KEY_PRGM_NONE 0 +#define KEY_PRGM_RETURN 31 +#define KEY_PRGM_RIGHT 27 +#define KEY_PRGM_UP 28 +#define KEY_PRGM_1 72 +#define KEY_PRGM_2 62 +#define KEY_PRGM_3 52 +#define KEY_PRGM_4 73 +#define KEY_PRGM_5 63 +#define KEY_PRGM_6 53 +#define KEY_PRGM_7 74 +#define KEY_PRGM_8 64 +#define KEY_PRGM_9 54 +#define KEY_PRGM_A 76 +#define KEY_PRGM_F 26 +#define KEY_PRGM_ALPHA 77 +#define KEY_PRGM_SHIFT 78 +#define KEY_PRGM_MENU 48 + +EXTERNC uint64_t extapp_millis(); +EXTERNC void extapp_msleep(uint32_t ms); +EXTERNC uint64_t extapp_scanKeyboard(); +EXTERNC void extapp_pushRect(int16_t x, int16_t y, uint16_t w, uint16_t h, const uint16_t * pixels); +EXTERNC void extapp_pushRectUniform(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t color); +EXTERNC void extapp_pullRect(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t * pixels); +EXTERNC int16_t extapp_drawTextLarge(const char *text, int16_t x, int16_t y, uint16_t fg, uint16_t bg, bool fake); +EXTERNC int16_t extapp_drawTextSmall(const char *text, int16_t x, int16_t y, uint16_t fg, uint16_t bg, bool fake); +EXTERNC bool extapp_waitForVBlank(); +EXTERNC void extapp_clipboardStore(const char *text); +EXTERNC const char * extapp_clipboardText(); +EXTERNC int extapp_fileListWithExtension(const char ** filenames, int maxrecords, const char * extension, int storage); +EXTERNC bool extapp_fileExists(const char * filename, int storage); +EXTERNC bool extapp_fileErase(const char * filename, int storage); +EXTERNC const char * extapp_fileRead(const char * filename, size_t *len, int storage); +EXTERNC bool extapp_fileWrite(const char * filename, const char * content, size_t len, int storage); +EXTERNC void extapp_lockAlpha(); +EXTERNC void extapp_resetKeyboard(); +EXTERNC int extapp_getKey(bool allowSuspend, bool *alphaWasActive); + +#endif diff --git a/apps/external/external_icon.png b/apps/external/external_icon.png new file mode 100644 index 00000000000..297dc31c6cc Binary files /dev/null and b/apps/external/external_icon.png differ diff --git a/apps/external/main_controller.cpp b/apps/external/main_controller.cpp new file mode 100644 index 00000000000..acf837441ef --- /dev/null +++ b/apps/external/main_controller.cpp @@ -0,0 +1,151 @@ +#include "main_controller.h" +#include +#include +#include +#include "archive.h" +#include "app.h" +#include +#include + +using namespace Poincare; + +namespace External { + +using namespace Archive; + +MainController::MainController(Responder * parentResponder, ::App * app) : + ViewController(parentResponder), + m_selectableTableView(this) +{ + m_app = app; +} + +View * MainController::view() { + return &m_selectableTableView; +} + +void MainController::didBecomeFirstResponder() { + if (selectedRow() < 0) { + selectCellAtLocation(0, 0); + } + Container::activeApp()->setFirstResponder(&m_selectableTableView); +} + +bool MainController::handleEvent(Ion::Events::Event event) { + if ((event == Ion::Events::OK || event == Ion::Events::EXE) && ((selectedRow() < k_numberOfCells - 2) && numberOfFiles() > 0)) { + uint32_t res = executeFile(m_cells[selectedRow()].text(), ((App *)m_app)->heap(), ((App *)m_app)->heapSize()); + ((App*)m_app)->redraw(); + switch(res) { + case 0: + break; + case 1: + Container::activeApp()->displayWarning(I18n::Message::ExternalAppApiMismatch); + break; + case 2: + Container::activeApp()->displayWarning(I18n::Message::StorageMemoryFull1); + break; + default: + Container::activeApp()->displayWarning(I18n::Message::ExternalAppExecError); + break; + } + return true; + } + return false; +} + +int MainController::numberOfRows() const { + return k_numberOfCells; +}; + +KDCoordinate MainController::rowHeight(int j) { + return Metric::ParameterCellHeight; +} + +KDCoordinate MainController::cumulatedHeightFromIndex(int j) { + return j*rowHeight(0); +} + +int MainController::indexFromCumulatedHeight(KDCoordinate offsetY) { + return offsetY/rowHeight(0); +} + +HighlightCell * MainController::reusableCell(int index, int type) { + assert(index < k_numberOfCells); + return &m_cells[index]; +} + +int MainController::reusableCellCount(int type) { + return k_numberOfCells; +} + +int MainController::typeAtLocation(int i, int j) { + return 0; +} + +void MainController::willDisplayCellForIndex(HighlightCell * cell, int index) { + PointerTextTableCell * myTextCell = (PointerTextTableCell *)cell; + myTextCell->setHighlighted(myTextCell->isHighlighted()); + struct File f; + #if defined(DEVICE) || defined(EXTERNAL_BUILTIN) + #if defined(DEVICE_N0100) && !defined(EXTERNAL_BUILTIN) + if(index == 0){ + myTextCell->setText(I18n::translate(I18n::Message::ExternalNotCompatible)); + myTextCell->setTextColor(Palette::Red); + } else { + myTextCell->setText(I18n::translate(I18n::Message::WithN0100)); + myTextCell->setTextColor(Palette::Red); + } + #else + if(index == k_numberOfCells-1){ + myTextCell->setText(I18n::translate(I18n::Message::URL)); + myTextCell->setTextColor(Palette::AccentText); + return; + } + if(index == k_numberOfCells-2){ + myTextCell->setText(I18n::translate(I18n::Message::GetMoreAppsAt)); + myTextCell->setTextColor(Palette::AccentText); + return; + } + if(index == 0 && numberOfFiles() == 0){ + myTextCell->setText(I18n::translate(I18n::Message::NoAppsInstalled)); + myTextCell->setTextColor(Palette::Red); + } + if(numberOfFiles() > 0){ + if(fileAtIndex(index, f)) { + myTextCell->setText(f.name); + myTextCell->setTextColor(f.isExecutable ? Palette::PrimaryText : Palette::Palette::SecondaryText); + } + } + #endif + #else + if(index == 0){ + myTextCell->setText(I18n::translate(I18n::Message::ExternalNotCompatible)); + myTextCell->setTextColor(Palette::Red); + } else { + myTextCell->setText(I18n::translate(I18n::Message::WithSimulator)); + myTextCell->setTextColor(Palette::Red); + } + #endif +} + +void MainController::viewWillAppear() { + int count; + #if defined(DEVICE) || defined(EXTERNAL_BUILTIN) + #if !defined(DEVICE_N0110) && !defined(EXTERNAL_BUILTIN) + count = 2; + #else + if(numberOfFiles() > 0){ + count = numberOfFiles()+2; + } else { + count = 3; + } + #endif + + #else + count = 2; + #endif + k_numberOfCells = count <= k_maxNumberOfCells ? count : k_maxNumberOfCells; + m_selectableTableView.reloadData(); +} + +} diff --git a/apps/external/main_controller.h b/apps/external/main_controller.h new file mode 100644 index 00000000000..bdb6d275bd0 --- /dev/null +++ b/apps/external/main_controller.h @@ -0,0 +1,34 @@ +#ifndef EXTERNAL_MAIN_CONTROLLER_H +#define EXTERNAL_MAIN_CONTROLLER_H + +#include +#include "pointer_text_table_cell.h" + +namespace External { + +class MainController : public ViewController, public ListViewDataSource, public SelectableTableViewDataSource { +public: + MainController(Responder * parentResponder, App * app); + View * view() override; + bool handleEvent(Ion::Events::Event event) override; + void didBecomeFirstResponder() override; + int numberOfRows() const override; + KDCoordinate rowHeight(int j) override; + KDCoordinate cumulatedHeightFromIndex(int j) override; + int indexFromCumulatedHeight(KDCoordinate offsetY) override; + HighlightCell * reusableCell(int index, int type) override; + int reusableCellCount(int type) override; + int typeAtLocation(int i, int j) override; + void willDisplayCellForIndex(HighlightCell * cell, int index) override; + void viewWillAppear() override; +private: + App * m_app; + SelectableTableView m_selectableTableView; + int k_numberOfCells = 1; + constexpr static int k_maxNumberOfCells = 16; + PointerTextTableCell m_cells[k_maxNumberOfCells]; +}; + +} + +#endif diff --git a/apps/external/pointer_text_table_cell.cpp b/apps/external/pointer_text_table_cell.cpp new file mode 100644 index 00000000000..00967fafb60 --- /dev/null +++ b/apps/external/pointer_text_table_cell.cpp @@ -0,0 +1,38 @@ +#include "pointer_text_table_cell.h" +#include +#include +#include + +PointerTextTableCell::PointerTextTableCell(const char * text, const KDFont * font, Layout layout) : + TableCell(layout), + m_pointerTextView(font, text, 0, 0.5, KDColorBlack, KDColorWhite) +{ +} + +View * PointerTextTableCell::labelView() const { + return (View *)&m_pointerTextView; +} + +const char * PointerTextTableCell::text() const { + return m_pointerTextView.text(); +} + +void PointerTextTableCell::setHighlighted(bool highlight) { + HighlightCell::setHighlighted(highlight); + KDColor backgroundColor = highlight? Palette::ListCellBackgroundSelected : Palette::ListCellBackground; + m_pointerTextView.setBackgroundColor(backgroundColor); +} + +void PointerTextTableCell::setText(const char * text) { + m_pointerTextView.setText(text); + layoutSubviews(); +} + +void PointerTextTableCell::setTextColor(KDColor color) { + m_pointerTextView.setTextColor(color); +} + +void PointerTextTableCell::setTextFont(const KDFont * font) { + m_pointerTextView.setFont(font); + layoutSubviews(); +} diff --git a/apps/external/pointer_text_table_cell.h b/apps/external/pointer_text_table_cell.h new file mode 100644 index 00000000000..2ed0b9d5294 --- /dev/null +++ b/apps/external/pointer_text_table_cell.h @@ -0,0 +1,20 @@ +#ifndef ESCHER_POINTER_TEXT_TABLE_CELL_H +#define ESCHER_POINTER_TEXT_TABLE_CELL_H + +#include +#include + +class PointerTextTableCell : public TableCell { +public: + PointerTextTableCell(const char * text = "", const KDFont * font = KDFont::SmallFont, Layout layout = Layout::HorizontalLeftOverlap); + View * labelView() const override; + const char * text() const override; + virtual void setHighlighted(bool highlight) override; + void setText(const char * text); + virtual void setTextColor(KDColor color); + void setTextFont(const KDFont * font); +private: + PointerTextView m_pointerTextView; +}; + +#endif diff --git a/apps/global_preferences.cpp b/apps/global_preferences.cpp index c6644f5fdcb..938cff8616a 100644 --- a/apps/global_preferences.cpp +++ b/apps/global_preferences.cpp @@ -8,12 +8,17 @@ GlobalPreferences * GlobalPreferences::sharedGlobalPreferences() { GlobalPreferences::ExamMode GlobalPreferences::examMode() const { if (m_examMode == ExamMode::Unknown) { uint8_t mode = Ion::ExamMode::FetchExamMode(); - assert(mode >= 0 && mode < 3); // mode can be cast in ExamMode (Off, Standard or Dutch) + assert(mode >= 0 && mode < 5); // mode can be cast in ExamMode (Off, Standard, NoSym, Dutch or NoSymNoText) m_examMode = (ExamMode)mode; } return m_examMode; } +GlobalPreferences::ExamMode GlobalPreferences::tempExamMode() const { + return m_tempExamMode; +} + + void GlobalPreferences::setExamMode(ExamMode mode) { ExamMode currentMode = examMode(); if (currentMode == mode) { @@ -21,12 +26,16 @@ void GlobalPreferences::setExamMode(ExamMode mode) { } assert(mode != ExamMode::Unknown); int8_t deltaMode = (int8_t)mode - (int8_t)currentMode; - deltaMode = deltaMode < 0 ? deltaMode + 3 : deltaMode; + deltaMode = deltaMode < 0 ? deltaMode + 4 : deltaMode; assert(deltaMode > 0); Ion::ExamMode::IncrementExamMode(deltaMode); m_examMode = mode; } +void GlobalPreferences::setTempExamMode(ExamMode mode) { + m_tempExamMode = mode; +} + void GlobalPreferences::setBrightnessLevel(int brightnessLevel) { if (m_brightnessLevel != brightnessLevel) { brightnessLevel = brightnessLevel < 0 ? 0 : brightnessLevel; diff --git a/apps/global_preferences.h b/apps/global_preferences.h index 215824b8080..4367c20f788 100644 --- a/apps/global_preferences.h +++ b/apps/global_preferences.h @@ -9,7 +9,9 @@ class GlobalPreferences { Unknown = -1, Off = 0, Standard = 1, - Dutch = 2 + NoSym = 2, + NoSymNoText = 3, + Dutch = 4, }; static GlobalPreferences * sharedGlobalPreferences(); I18n::Language language() const { return m_language; } @@ -21,15 +23,18 @@ class GlobalPreferences { Poincare::Preferences::UnitFormat unitFormat() const { return I18n::CountryPreferencesArray[static_cast(m_country)].unitFormat(); } CountryPreferences::HomeAppsLayout homeAppsLayout() const { return I18n::CountryPreferencesArray[static_cast(m_country)].homeAppsLayout(); } bool isInExamMode() const { return (int8_t)examMode() > 0; } + bool isInExamModeSymbolic() const { return !((int8_t)examMode() > 1); } ExamMode examMode() const; + ExamMode tempExamMode() const; void setExamMode(ExamMode examMode); + void setTempExamMode(ExamMode examMode); bool showPopUp() const { return m_showPopUp; } void setShowPopUp(bool showPopUp) { m_showPopUp = showPopUp; } int brightnessLevel() const { return m_brightnessLevel; } void setBrightnessLevel(int brightnessLevel); const KDFont * font() const { return m_font; } void setFont(const KDFont * font) { m_font = font; } - constexpr static int NumberOfBrightnessStates = 12; + constexpr static int NumberOfBrightnessStates = 15; private: static_assert(I18n::NumberOfLanguages > 0, "I18n::NumberOfLanguages is not superior to 0"); // There should already have been an error when processing an empty EPSILON_I18N flag static_assert(I18n::NumberOfCountries > 0, "I18n::NumberOfCountries is not superior to 0"); // There should already have been an error when processing an empty EPSILON_COUNTRIES flag @@ -37,6 +42,7 @@ class GlobalPreferences { m_language((I18n::Language)0), m_country((I18n::Country)0), m_examMode(ExamMode::Unknown), + m_tempExamMode(ExamMode::Standard), m_showPopUp(true), m_brightnessLevel(Ion::Backlight::MaxBrightness), m_font(KDFont::LargeFont) {} @@ -45,6 +51,7 @@ class GlobalPreferences { static_assert((int8_t)GlobalPreferences::ExamMode::Off == 0, "GlobalPreferences::isInExamMode() is not right"); static_assert((int8_t)GlobalPreferences::ExamMode::Unknown < 0, "GlobalPreferences::isInExamMode() is not right"); mutable ExamMode m_examMode; + mutable ExamMode m_tempExamMode; bool m_showPopUp; int m_brightnessLevel; const KDFont * m_font; diff --git a/apps/graph/app.cpp b/apps/graph/app.cpp index 38918a61c01..68a4b4a9e7f 100644 --- a/apps/graph/app.cpp +++ b/apps/graph/app.cpp @@ -16,6 +16,10 @@ I18n::Message App::Descriptor::upperName() { return I18n::Message::FunctionAppCapital; } +App::Descriptor::ExaminationLevel App::Descriptor::examinationLevel() { + return App::Descriptor::ExaminationLevel::Strict; +} + const Image * App::Descriptor::icon() { return ImageStore::GraphIcon; } diff --git a/apps/graph/app.h b/apps/graph/app.h index 2d17f0ea72c..f9255732908 100644 --- a/apps/graph/app.h +++ b/apps/graph/app.h @@ -17,6 +17,7 @@ class App : public Shared::FunctionApp { public: I18n::Message name() override; I18n::Message upperName() override; + App::Descriptor::ExaminationLevel examinationLevel() override; const Image * icon() override; }; class Snapshot : public Shared::FunctionApp::Snapshot { diff --git a/apps/graph/base.hu.i18n b/apps/graph/base.hu.i18n new file mode 100644 index 00000000000..9b1c306fc57 --- /dev/null +++ b/apps/graph/base.hu.i18n @@ -0,0 +1,33 @@ +FunctionApp = "Funkciók" +FunctionAppCapital = "FUNKCIÓK" +FunctionTab = "Funkciók" +AddFunction = "Funkció hozzáadása" +DeleteFunction = "Funkció törlése" +CurveType = "Görbe típus" +CartesianType = "Kartéziánus " +PolarType = "Poláris " +ParametricType = "Parametrikus " +IntervalT = "t intervallum" +IntervalTheta = "θ intervallum" +IntervalX = "x intervallum" +FunctionDomain = "Tervtartomány" +FunctionColor = "Funkció színe" +NoFunction = "Nincs funkció" +NoActivatedFunction = "Nincs használt funkció" +PlotOptions = "Görbe beállítások" +Compute = "Kiszámolás" +Zeros = "Nullák" +Tangent = "Tangens" +Intersection = "Metszéspont" +Preimage = "Inverz kép" +SelectLowerBound = "Alsó határ kiválasztása" +SelectUpperBound = "Felsö határ kiválasztása" +NoMaximumFound = "Nem talált maximum-ot" +NoMinimumFound = "Nem talált minimum-ot" +NoZeroFound = "Nem talált nullát" +NoIntersectionFound = "Nem található keresztezödés" +NoPreimageFound = "Nem található inverz kép" +DerivativeFunctionColumn = "A derivált fügvény oszlopa" +HideDerivativeColumn = "A derivált függvény oszlop elrejtése" +AllowedCharactersAZaz09 = "Engedélyezett karakterek: A..Z, a..z, 0..9, _" +ReservedName = "Fenntartott név" diff --git a/apps/graph/graph/graph_view.cpp b/apps/graph/graph/graph_view.cpp index c0d36a18633..9d34bbf4d50 100644 --- a/apps/graph/graph/graph_view.cpp +++ b/apps/graph/graph/graph_view.cpp @@ -75,7 +75,7 @@ void GraphView::drawRect(KDContext * ctx, KDRect rect) const { // To represent the tangent, we draw segment from and to abscissas at the extremity of the drawn rect float minAbscissa = pixelToFloat(Axis::Horizontal, rect.left()); float maxAbscissa = pixelToFloat(Axis::Horizontal, rect.right()); - drawSegment(ctx, rect, minAbscissa, tangentParameterA*minAbscissa+tangentParameterB, maxAbscissa, tangentParameterA*maxAbscissa+tangentParameterB, Palette::GrayVeryDark, false); + drawSegment(ctx, rect, minAbscissa, tangentParameterA*minAbscissa+tangentParameterB, maxAbscissa, tangentParameterA*maxAbscissa+tangentParameterB, Palette::GraphTangent, false); } } else if (type == Shared::ContinuousFunction::PlotType::Polar) { // Polar diff --git a/apps/graph/list/list_controller.cpp b/apps/graph/list/list_controller.cpp index e211d3cc6cc..78261ded570 100644 --- a/apps/graph/list/list_controller.cpp +++ b/apps/graph/list/list_controller.cpp @@ -167,7 +167,7 @@ void ListController::willDisplayTitleCellAtIndex(HighlightCell * cell, int j) { // Set name and color if the name is not being edited ExpiringPointer function = modelStore()->modelForRecord(modelStore()->recordAtIndex(j)); setFunctionNameInTextField(function, titleCell->textField()); - KDColor functionNameColor = function->isActive() ? function->color() : Palette::GrayDark; + KDColor functionNameColor = function->isActive() ? function->color() : Palette::SecondaryText; titleCell->setColor(functionNameColor); } } @@ -178,7 +178,7 @@ void ListController::willDisplayExpressionCellAtIndex(HighlightCell * cell, int Shared::FunctionListController::willDisplayExpressionCellAtIndex(cell, j); FunctionExpressionCell * myCell = (FunctionExpressionCell *)cell; ExpiringPointer f = modelStore()->modelForRecord(modelStore()->recordAtIndex(j)); - KDColor textColor = f->isActive() ? KDColorBlack : Palette::GrayDark; + KDColor textColor = f->isActive() ? Palette::PrimaryText : Palette::SecondaryText; myCell->setTextColor(textColor); } diff --git a/apps/graph/list/text_field_with_max_length_and_extension.h b/apps/graph/list/text_field_with_max_length_and_extension.h index b14740788e1..a5da2f1afea 100644 --- a/apps/graph/list/text_field_with_max_length_and_extension.h +++ b/apps/graph/list/text_field_with_max_length_and_extension.h @@ -17,8 +17,8 @@ class TextFieldWithMaxLengthAndExtension : public Shared::TextFieldWithExtension const KDFont * size = KDFont::LargeFont, float horizontalAlignment = 0.0f, float verticalAlignment = 0.5f, - KDColor textColor = KDColorBlack, - KDColor backgroundColor = KDColorWhite) : + KDColor textColor = Palette::PrimaryText, + KDColor backgroundColor = Palette::BackgroundHard) : TextFieldWithExtension(extensionLength, parentResponder, textBuffer, textBufferSize, draftTextBufferSize, inputEventHandlerDelegate, delegate, size, horizontalAlignment, verticalAlignment, textColor, backgroundColor) {} void setDraftTextBufferSize(size_t size) { m_contentView.setDraftTextBufferSize(size); } }; diff --git a/apps/hardware_test/arrow_view.cpp b/apps/hardware_test/arrow_view.cpp index f745839868c..fbbb70339c2 100644 --- a/apps/hardware_test/arrow_view.cpp +++ b/apps/hardware_test/arrow_view.cpp @@ -30,7 +30,7 @@ const uint8_t arrowDownMask[10][9] = { ArrowView::ArrowView() : m_directionIsUp(true), - m_color(KDColorBlack) + m_color(Palette::PrimaryText) { } @@ -50,7 +50,7 @@ void ArrowView::setColor(KDColor color) { void ArrowView::drawRect(KDContext * ctx, KDRect rect) const { KDColor arrowWorkingBuffer[10*9]; - ctx->fillRect(bounds(), KDColorWhite); + ctx->fillRect(bounds(), Palette::BackgroundHard); KDCoordinate startLine = m_directionIsUp ? k_arrowHeight : 0; KDCoordinate startArrow = m_directionIsUp ? 0 : bounds().height()-k_arrowHeight; ctx->fillRect(KDRect((Ion::Display::Width-k_arrowThickness)/2, startLine, k_arrowThickness, bounds().height()-k_arrowHeight), m_color); diff --git a/apps/hardware_test/keyboard_view.cpp b/apps/hardware_test/keyboard_view.cpp index 0b7d69cefe7..9af6b916993 100644 --- a/apps/hardware_test/keyboard_view.cpp +++ b/apps/hardware_test/keyboard_view.cpp @@ -59,7 +59,7 @@ void KeyboardView::drawKey(int keyIndex, KDContext * ctx, KDRect rect) const { KDColor KeyboardView::keyColor(Ion::Keyboard::Key key) const { if (!m_keyboardModel.belongsToTestedKeysSubset(key)) { - return Palette::GrayBright; + return Palette::ListCellBorder; } if (m_keyboardModel.testedKey() == key) { return KDColorBlue; diff --git a/apps/home/app.cpp b/apps/home/app.cpp index 5c5cc8f9c29..51194e4f738 100644 --- a/apps/home/app.cpp +++ b/apps/home/app.cpp @@ -24,9 +24,18 @@ App::Descriptor * App::Snapshot::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_controller, I18n::Message::Warning), - m_controller(&m_modalViewController, snapshot) + m_controller(&m_modalViewController, snapshot, this) { } diff --git a/apps/home/app.h b/apps/home/app.h index 4d92c556426..50d55e7b7f0 100644 --- a/apps/home/app.h +++ b/apps/home/app.h @@ -19,6 +19,8 @@ class App : public ::App { App * unpack(Container * container) override; Descriptor * descriptor() override; }; + void redraw(); + virtual void didBecomeActive(Window * window); static App * app() { return static_cast(Container::activeApp()); } @@ -26,9 +28,18 @@ class App : public ::App { return static_cast(::App::snapshot()); } TELEMETRY_ID("Home"); +#if HOME_DISPLAY_EXTERNALS + int heapSize() { return k_externalHeapSize; } + char * heap() { return m_externalHeap; } +#endif private: App(Snapshot * snapshot); Controller m_controller; +#if HOME_DISPLAY_EXTERNALS + static constexpr int k_externalHeapSize = 80000; + char m_externalHeap[k_externalHeapSize]; +#endif + Window * m_window; }; } diff --git a/apps/home/app_cell.cpp b/apps/home/app_cell.cpp index cb287558969..a6e5a155478 100644 --- a/apps/home/app_cell.cpp +++ b/apps/home/app_cell.cpp @@ -1,19 +1,21 @@ #include "app_cell.h" #include +#include +#include namespace Home { AppCell::AppCell() : HighlightCell(), - m_nameView(KDFont::SmallFont, (I18n::Message)0, 0.5f, 0.5f, KDColorBlack, KDColorWhite), - m_visible(true) + m_nameView(KDFont::SmallFont, (I18n::Message)0, 0.5f, 0.5f, Palette::HomeCellText, Palette::HomeCellBackground), + m_visible(true), m_external_app(false) { } void AppCell::drawRect(KDContext * ctx, KDRect rect) const { KDSize nameSize = m_nameView.minimalSizeForOptimalDisplay(); - ctx->fillRect(KDRect(0, bounds().height()-nameSize.height() - 2*k_nameHeightMargin, bounds().width(), nameSize.height()+2*k_nameHeightMargin), KDColorWhite); + ctx->fillRect(KDRect(0, bounds().height()-nameSize.height() - 2*k_nameHeightMargin, bounds().width(), nameSize.height()+2*k_nameHeightMargin), Palette::HomeBackground); } int AppCell::numberOfSubviews() const { @@ -31,9 +33,33 @@ void AppCell::layoutSubviews(bool force) { m_nameView.setFrame(KDRect((bounds().width()-nameSize.width())/2-k_nameWidthMargin, bounds().height()-nameSize.height() - 2*k_nameHeightMargin, nameSize.width()+2*k_nameWidthMargin, nameSize.height()+2*k_nameHeightMargin), force); } +void AppCell::setExtAppDescriptor(const char* name, const uint8_t *icon, size_t iconLength) { + m_external_app = true; + m_iconView.setImage(icon, iconLength); + m_iconView.setImage(nullptr); + m_nameView.setText(name); + m_nameView.setTextColor(Palette::HomeCellTextExternal); + m_nameView.setMessage(I18n::Message::Default); + layoutSubviews(); +} + +void AppCell::setExtAppDescriptor(const char* name, const Image* icon) { + m_external_app = true; + m_iconView.setImage(icon); + m_iconView.setImage(nullptr, 0); + m_nameView.setText(name); + m_nameView.setTextColor(Palette::HomeCellTextExternal); + m_nameView.setMessage(I18n::Message::Default); + layoutSubviews(); +} + void AppCell::setAppDescriptor(::App::Descriptor * descriptor) { + m_external_app = false; m_iconView.setImage(descriptor->icon()); + m_iconView.setImage(nullptr, 0); m_nameView.setMessage(descriptor->name()); + m_nameView.setTextColor(Palette::HomeCellText); + m_nameView.setText(nullptr); layoutSubviews(); } @@ -45,8 +71,8 @@ void AppCell::setVisible(bool visible) { } void AppCell::reloadCell() { - m_nameView.setTextColor(isHighlighted() ? KDColorWhite : KDColorBlack); - m_nameView.setBackgroundColor(isHighlighted() ? Palette::YellowDark : KDColorWhite); + m_nameView.setTextColor(isHighlighted() ? (m_external_app ? Palette::HomeCellTextExternalActive : Palette::HomeCellTextActive) : (m_external_app ? Palette::HomeCellTextExternal : Palette::HomeCellText)); + m_nameView.setBackgroundColor(isHighlighted() ? Palette::HomeCellBackgroundActive : Palette::HomeCellBackground); } } diff --git a/apps/home/app_cell.h b/apps/home/app_cell.h index 73cb7e0f9fc..89c22e00848 100644 --- a/apps/home/app_cell.h +++ b/apps/home/app_cell.h @@ -17,6 +17,8 @@ class AppCell : public HighlightCell { void setVisible(bool visible); void reloadCell() override; void setAppDescriptor(::App::Descriptor * appDescriptor); + void setExtAppDescriptor(const char* name, const Image* icon); + void setExtAppDescriptor(const char* name, const uint8_t *icon, size_t iconLength); private: static constexpr KDCoordinate k_iconMargin = 22; static constexpr KDCoordinate k_iconWidth = 55; @@ -26,6 +28,7 @@ class AppCell : public HighlightCell { ImageView m_iconView; MessageTextView m_nameView; bool m_visible; + bool m_external_app; }; } diff --git a/apps/home/apps_layout.csv b/apps/home/apps_layout.csv index 3e2f967d331..77e47e4b882 100644 --- a/apps/home/apps_layout.csv +++ b/apps/home/apps_layout.csv @@ -1,2 +1,2 @@ -Default,calculation,graph,code,statistics,probability,solver,sequence,regression,settings -HidePython,calculation,graph,solver,statistics,probability,regression,sequence,code,settings +Default,calculation,rpn,graph,code,statistics,probability,solver,atomic,sequence,regression,settings +HidePython,calculation,rpn,graph,code,statistics,probability,solver,atomic,sequence,regression,settings diff --git a/apps/home/base.de.i18n b/apps/home/base.de.i18n index c6a24187c1a..30ac1c9c256 100644 --- a/apps/home/base.de.i18n +++ b/apps/home/base.de.i18n @@ -1,4 +1,4 @@ Apps = "Anwendungen" -AppsCapital = "ANWENDUNGEN" +AppsCapital = "OMEGA" ForbidenAppInExamMode1 = "Diese Anwendung ist im" ForbidenAppInExamMode2 = "Prüfungsmodus nicht erlaubt." diff --git a/apps/home/base.en.i18n b/apps/home/base.en.i18n index 158fa3bda75..dde4e21299b 100644 --- a/apps/home/base.en.i18n +++ b/apps/home/base.en.i18n @@ -1,4 +1,4 @@ Apps = "Applications" -AppsCapital = "APPLICATIONS" +AppsCapital = "OMEGA" ForbidenAppInExamMode1 = "This application is" ForbidenAppInExamMode2 = "forbidden in exam mode" diff --git a/apps/home/base.es.i18n b/apps/home/base.es.i18n index 9477043e258..93e7bdf4914 100644 --- a/apps/home/base.es.i18n +++ b/apps/home/base.es.i18n @@ -1,4 +1,4 @@ Apps = "Aplicaciones" -AppsCapital = "APLICACIONES" +AppsCapital = "OMEGA" ForbidenAppInExamMode1 = "Esta aplicación está prohibida" ForbidenAppInExamMode2 = "en el modo de examen" diff --git a/apps/home/base.fr.i18n b/apps/home/base.fr.i18n index 4a7f7130d95..8280b458409 100644 --- a/apps/home/base.fr.i18n +++ b/apps/home/base.fr.i18n @@ -1,4 +1,4 @@ Apps = "Applications" -AppsCapital = "APPLICATIONS" +AppsCapital = "OMEGA" ForbidenAppInExamMode1 = "Cette application n'est" ForbidenAppInExamMode2 = "pas autorisée en mode examen." diff --git a/apps/home/base.hu.i18n b/apps/home/base.hu.i18n new file mode 100644 index 00000000000..6b0b188157c --- /dev/null +++ b/apps/home/base.hu.i18n @@ -0,0 +1,4 @@ +Apps = "Alkalmazások" +AppsCapital = "OMEGA" +ForbidenAppInExamMode1 = "Ez az alkalmazás" +ForbidenAppInExamMode2 = "tilos vizsga módban" diff --git a/apps/home/base.it.i18n b/apps/home/base.it.i18n index cfd37f3df9a..95373c0401a 100644 --- a/apps/home/base.it.i18n +++ b/apps/home/base.it.i18n @@ -1,4 +1,4 @@ Apps = "Applicazioni" -AppsCapital = "APPLICAZIONI" +AppsCapital = "OMEGA" ForbidenAppInExamMode1 = "Questa applicazione è" ForbidenAppInExamMode2 = "proibita nella modalità d'esame" diff --git a/apps/home/base.nl.i18n b/apps/home/base.nl.i18n index 94900c4b14a..dd6a8991935 100644 --- a/apps/home/base.nl.i18n +++ b/apps/home/base.nl.i18n @@ -1,4 +1,4 @@ Apps = "Applicaties" -AppsCapital = "APPLICATIES" +AppsCapital = "OMEGA" ForbidenAppInExamMode1 = "Deze applicatie is" ForbidenAppInExamMode2 = "uitgesloten in examenstand" diff --git a/apps/home/base.pt.i18n b/apps/home/base.pt.i18n index d49cc0b7133..f3efc8ffdee 100644 --- a/apps/home/base.pt.i18n +++ b/apps/home/base.pt.i18n @@ -1,4 +1,4 @@ Apps = "Aplicações" -AppsCapital = "APLICAÇÕES" +AppsCapital = "OMEGA" ForbidenAppInExamMode1 = "Esta aplicação é" ForbidenAppInExamMode2 = "proibida no Modo de Exame" diff --git a/apps/home/controller.cpp b/apps/home/controller.cpp index 387cc5358ed..2724bd172e3 100644 --- a/apps/home/controller.cpp +++ b/apps/home/controller.cpp @@ -9,6 +9,12 @@ extern "C" { #include } +#ifdef HOME_DISPLAY_EXTERNALS +#include "../external/external_icon.h" +#include "../external/archive.h" +#include +#endif + namespace Home { Controller::ContentView::ContentView(Controller * controller, SelectableTableViewDataSource * selectionDataSource) : @@ -16,7 +22,7 @@ Controller::ContentView::ContentView(Controller * controller, SelectableTableVie { m_selectableTableView.setVerticalCellOverlap(0); m_selectableTableView.setMargins(0, k_sideMargin, k_bottomMargin, k_sideMargin); - m_selectableTableView.setBackgroundColor(KDColorWhite); + m_selectableTableView.setBackgroundColor(Palette::HomeBackground); static_cast(m_selectableTableView.decorator())->verticalBar()->setMargin(k_indicatorMargin); } @@ -25,7 +31,7 @@ SelectableTableView * Controller::ContentView::selectableTableView() { } void Controller::ContentView::drawRect(KDContext * ctx, KDRect rect) const { - ctx->fillRect(bounds(), KDColorWhite); + ctx->fillRect(bounds(), Palette::HomeBackground); } void Controller::ContentView::reloadBottomRow(SimpleTableViewDataSource * dataSource, int numberOfIcons, int numberOfColumns) { @@ -52,23 +58,56 @@ void Controller::ContentView::layoutSubviews(bool force) { m_selectableTableView.setFrame(bounds(), force); } -Controller::Controller(Responder * parentResponder, SelectableTableViewDataSource * selectionDataSource) : +Controller::Controller(Responder * parentResponder, SelectableTableViewDataSource * selectionDataSource, ::App * app) : ViewController(parentResponder), m_view(this, selectionDataSource) { + m_app = app; } bool Controller::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::OK || event == Ion::Events::EXE) { AppsContainer * container = AppsContainer::sharedAppsContainer(); - ::App::Snapshot * selectedSnapshot = container->appSnapshotAtIndex(PermutedAppSnapshotIndex(selectionDataSource()->selectedRow() * k_numberOfColumns + selectionDataSource()->selectedColumn() + 1)); - if (ExamModeConfiguration::appIsForbiddenInExamMode(selectedSnapshot->descriptor()->name(), GlobalPreferences::sharedGlobalPreferences()->examMode())) { + + int index = selectionDataSource()->selectedRow()*k_numberOfColumns+selectionDataSource()->selectedColumn()+1; +#ifdef HOME_DISPLAY_EXTERNALS + if (index >= container->numberOfApps()) { + if (GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::Dutch || GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::NoSymNoText || GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::NoSym) { + App::app()->displayWarning(I18n::Message::ForbidenAppInExamMode1, I18n::Message::ForbidenAppInExamMode2); + } else { + External::Archive::File executable; + if (External::Archive::executableAtIndex(index - container->numberOfApps(), executable)) { + uint32_t res = External::Archive::executeFile(executable.name, ((App *)m_app)->heap(), ((App *)m_app)->heapSize()); + ((App*)m_app)->redraw(); + switch(res) { + case 0: + break; + case 1: + Container::activeApp()->displayWarning(I18n::Message::ExternalAppApiMismatch); + break; + case 2: + Container::activeApp()->displayWarning(I18n::Message::StorageMemoryFull1); + break; + default: + Container::activeApp()->displayWarning(I18n::Message::ExternalAppExecError); + break; + } + return true; + } + } + } else { +#endif + ::App::Snapshot * selectedSnapshot = container->appSnapshotAtIndex(index); + if (ExamModeConfiguration::appIsForbiddenInExamMode(selectedSnapshot->descriptor()->examinationLevel(), GlobalPreferences::sharedGlobalPreferences()->examMode())) { App::app()->displayWarning(I18n::Message::ForbidenAppInExamMode1, I18n::Message::ForbidenAppInExamMode2); } else { bool switched = container->switchTo(selectedSnapshot); assert(switched); (void) switched; // Silence compilation warning about unused variable. } +#ifdef HOME_DISPLAY_EXTERNALS + } +#endif return true; } @@ -93,6 +132,16 @@ void Controller::didBecomeFirstResponder() { Container::activeApp()->setFirstResponder(m_view.selectableTableView()); } +void Controller::viewWillAppear() { + KDIonContext::sharedContext()->zoomInhibit = true; + KDIonContext::sharedContext()->updatePostProcessingEffects(); +} + +void Controller::viewDidDisappear() { + KDIonContext::sharedContext()->zoomInhibit = false; + KDIonContext::sharedContext()->updatePostProcessingEffects(); +} + View * Controller::view() { return &m_view; } @@ -126,7 +175,36 @@ void Controller::willDisplayCellAtLocation(HighlightCell * cell, int i, int j) { AppsContainer * container = AppsContainer::sharedAppsContainer(); int appIndex = (j * k_numberOfColumns + i) + 1; if (appIndex >= container->numberOfApps()) { +#ifdef HOME_DISPLAY_EXTERNALS + External::Archive::File app_file; + + + if (External::Archive::executableAtIndex(appIndex - container->numberOfApps(), app_file)) { + char temp_name_buffer[100]; + strlcpy(temp_name_buffer, app_file.name, 94); + strlcat(temp_name_buffer, ".icon", 99); + + int img_index = External::Archive::indexFromName(temp_name_buffer); + + if (img_index != -1) { + External::Archive::File image_file; + if (External::Archive::fileAtIndex(img_index, image_file)) { + // const Image* img = new Image(55, 56, image_file.data, image_file.dataLength); + appCell->setExtAppDescriptor(app_file.name, image_file.data, image_file.dataLength); + } else { + appCell->setExtAppDescriptor(app_file.name, ImageStore::ExternalIcon); + } + } else { + appCell->setExtAppDescriptor(app_file.name, ImageStore::ExternalIcon); + } + + appCell->setVisible(true); + } else { + appCell->setVisible(false); + } +#else appCell->setVisible(false); +#endif } else { appCell->setVisible(true); ::App::Descriptor * descriptor = container->appSnapshotAtIndex(PermutedAppSnapshotIndex(appIndex))->descriptor(); @@ -137,7 +215,11 @@ void Controller::willDisplayCellAtLocation(HighlightCell * cell, int i, int j) { int Controller::numberOfIcons() const { AppsContainer * container = AppsContainer::sharedAppsContainer(); assert(container->numberOfApps() > 0); +#ifdef HOME_DISPLAY_EXTERNALS + return container->numberOfApps() - 1 + External::Archive::numberOfExecutables(); +#else return container->numberOfApps() - 1; +#endif } void Controller::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) { @@ -149,16 +231,13 @@ void Controller::tableViewDidChangeSelection(SelectableTableView * t, int previo * unvisible. This trick does not create an endless loop as we ensure not to * stay on a unvisible cell and to initialize the first cell on a visible one * (so the previous one is always visible). */ - int appIndex = (t->selectedColumn() + t->selectedRow() * k_numberOfColumns) + 1; - if (appIndex >= AppsContainer::sharedAppsContainer()->numberOfApps()) { - t->selectCellAtLocation(previousSelectedCellX, previousSelectedCellY); + int appIndex = (t->selectedColumn()+t->selectedRow()*k_numberOfColumns)+1; + if (appIndex >= this->numberOfIcons()+1) { + t->selectCellAtLocation((this->numberOfIcons()%3)-1, (this->numberOfIcons() / k_numberOfColumns)); } } void Controller::tableViewDidChangeSelectionAndDidScroll(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) { - if (withinTemporarySelection) { - return; - } /* If the number of apps (including home) is != 3*n+1, when we display the * lowest icons, the other(s) are empty. As no icon is thus redrawn on the * previous ones, the cell is not cleaned. We need to redraw a white rect on @@ -167,8 +246,8 @@ void Controller::tableViewDidChangeSelectionAndDidScroll(SelectableTableView * t * redrawing takes time and is visible at scrolling. Here, we avoid the * background complete redrawing but the code is a bit * clumsy. */ - if (t->selectedRow() == numberOfRows() - 1) { - m_view.reloadBottomRow(this, AppsContainer::sharedAppsContainer()->numberOfApps() - 1, k_numberOfColumns); + if (t->selectedRow() == numberOfRows()-1) { + m_view.reloadBottomRow(this, this->numberOfIcons(), k_numberOfColumns); } } diff --git a/apps/home/controller.h b/apps/home/controller.h index 9fc7fb38129..90a5604a3e8 100644 --- a/apps/home/controller.h +++ b/apps/home/controller.h @@ -8,13 +8,14 @@ namespace Home { class Controller : public ViewController, public SimpleTableViewDataSource, public SelectableTableViewDelegate { public: - Controller(Responder * parentResponder, SelectableTableViewDataSource * selectionDataSource); + Controller(Responder * parentResponder, SelectableTableViewDataSource * selectionDataSource, App * app); View * view() override; bool handleEvent(Ion::Events::Event event) override; void didBecomeFirstResponder() override; - TELEMETRY_ID(""); + void viewWillAppear() override; + void viewDidDisappear() override; int numberOfRows() const override; int numberOfColumns() const override; @@ -49,6 +50,7 @@ class Controller : public ViewController, public SimpleTableViewDataSource, publ static constexpr int k_cellWidth = 104; ContentView m_view; AppCell m_cells[k_maxNumberOfCells]; + App * m_app; }; } diff --git a/apps/i18n.py b/apps/i18n.py index d03ec1ede0c..b883f557b41 100644 --- a/apps/i18n.py +++ b/apps/i18n.py @@ -107,7 +107,7 @@ def parse_files(files): else: messages.add(name) data[locale][name] = definition - check_redundancy(messages, data, args.locales) + #check_redundancy(messages, data, args.locales) # FIXME return {"messages": sorted(messages), "universal_messages": sorted(universal_messages), "data": data} def parse_codepoints(file): diff --git a/apps/language_hu.universal.i18n b/apps/language_hu.universal.i18n new file mode 100644 index 00000000000..6718a8d72e2 --- /dev/null +++ b/apps/language_hu.universal.i18n @@ -0,0 +1 @@ +LanguageHU = "Magyar " diff --git a/apps/language_hu_iso6391.universal.i18n b/apps/language_hu_iso6391.universal.i18n new file mode 100644 index 00000000000..98bc27af165 --- /dev/null +++ b/apps/language_hu_iso6391.universal.i18n @@ -0,0 +1 @@ +LanguageISO6391HU = "hu" diff --git a/apps/lock_view.cpp b/apps/lock_view.cpp index 9a011390741..7f832da8c5f 100644 --- a/apps/lock_view.cpp +++ b/apps/lock_view.cpp @@ -15,7 +15,7 @@ const uint8_t lockMask[LockView::k_lockHeight][LockView::k_lockWidth] = { void LockView::drawRect(KDContext * ctx, KDRect rect) const { KDRect frame((bounds().width() - k_lockWidth)/2, (bounds().height()-k_lockHeight)/2, k_lockWidth, k_lockHeight); KDColor lockWorkingBuffer[LockView::k_lockHeight*LockView::k_lockWidth]; - ctx->blendRectWithMask(frame, KDColorWhite, (const uint8_t *)lockMask, lockWorkingBuffer); + ctx->blendRectWithMask(frame, Palette::ToolbarText, (const uint8_t *)lockMask, lockWorkingBuffer); } KDSize LockView::minimalSizeForOptimalDisplay() const { diff --git a/apps/main.cpp b/apps/main.cpp index 3a22fda5c77..d501a0d9a57 100644 --- a/apps/main.cpp +++ b/apps/main.cpp @@ -53,8 +53,12 @@ void ion_main(int argc, const char * const argv[]) { const char * appNames[] = {"home", EPSILON_APPS_NAMES}; for (int j = 0; j < AppsContainer::sharedAppsContainer()->numberOfApps(); j++) { App::Snapshot * snapshot = AppsContainer::sharedAppsContainer()->appSnapshotAtIndex(j); - int cmp = strcmp(argv[i]+2, appNames[j]); - if (cmp == '-') { + // Compare name in order to find if the firsts chars which are different are NULL and '-' + // -> check if the app name is in the argv + const char * s1 = argv[i]+2; + const char * s2 = appNames[j]; + while (*s1 != '\0' && (*s1 == *s2)) {s1++; s2++;} + if (*s2 == '\0' && *s1 == '-') { snapshot->setOpt(argv[i]+2+strlen(appNames[j])+1, argv[i+1]); break; } diff --git a/apps/math_toolbox.cpp b/apps/math_toolbox.cpp index 49c4f584caa..ad82cb08158 100644 --- a/apps/math_toolbox.cpp +++ b/apps/math_toolbox.cpp @@ -24,7 +24,8 @@ const ToolboxMessageTree calculChildren[] = { ToolboxMessageTree::Leaf(I18n::Message::DiffCommandWithArg, I18n::Message::DerivateNumber, false, I18n::Message::DiffCommand), ToolboxMessageTree::Leaf(I18n::Message::IntCommandWithArg, I18n::Message::Integral, false, I18n::Message::IntCommand), ToolboxMessageTree::Leaf(I18n::Message::SumCommandWithArg, I18n::Message::Sum, false, I18n::Message::SumCommand), - ToolboxMessageTree::Leaf(I18n::Message::ProductCommandWithArg, I18n::Message::Product, false, I18n::Message::ProductCommand) + ToolboxMessageTree::Leaf(I18n::Message::ProductCommandWithArg, I18n::Message::Product, false, I18n::Message::ProductCommand), + ToolboxMessageTree::Leaf(I18n::Message::Infinity, I18n::Message::InfinityMessage, false, I18n::Message::Infinity), }; const ToolboxMessageTree complexChildren[] = { @@ -206,6 +207,19 @@ const ToolboxMessageTree unitAmountMoleChildren[] = { const ToolboxMessageTree unitLuminousIntensityChildren[] = { ToolboxMessageTree::Leaf(I18n::Message::UnitLuminousIntensityCandelaSymbol, I18n::Message::UnitLuminousIntensityCandela)}; + +const ToolboxMessageTree unitLuminousFluxChildren[] = { + ToolboxMessageTree::Leaf(I18n::Message::UnitLuminousFluxLumenSymbol, I18n::Message::UnitLuminousFluxLumen), +}; + +const ToolboxMessageTree unitSolidAngleChildren[] = { + ToolboxMessageTree::Leaf(I18n::Message::UnitSolidAngleSteradianSymbol, I18n::Message::UnitSolidAngleSteradian), +}; + +const ToolboxMessageTree unitIlluminanceChildren[] = { + ToolboxMessageTree::Leaf(I18n::Message::UnitIlluminanceLuxSymbol, I18n::Message::UnitIlluminanceLux), +}; + const ToolboxMessageTree unitFrequencyHertzChildren[] = { ToolboxMessageTree::Leaf(I18n::Message::UnitFrequencyHertzSymbol, I18n::Message::UnitFrequencyHertz), ToolboxMessageTree::Leaf(I18n::Message::UnitFrequencyHertzKiloSymbol, I18n::Message::UnitFrequencyHertzKilo), @@ -253,6 +267,7 @@ const ToolboxMessageTree unitElectricChargeCoulombChildren[] = { ToolboxMessageTree::Leaf(I18n::Message::UnitChargeCoulombSymbol, I18n::Message::UnitChargeCoulomb), }; + const ToolboxMessageTree unitPotentialVoltChildren[] = { ToolboxMessageTree::Leaf(I18n::Message::UnitPotentialVoltMicroSymbol, I18n::Message::UnitPotentialVoltMicro), ToolboxMessageTree::Leaf(I18n::Message::UnitPotentialVoltMilliSymbol, I18n::Message::UnitPotentialVoltMilli), @@ -343,6 +358,9 @@ const ToolboxMessageTree unitChildren[] = { ToolboxMessageTree::Node(I18n::Message::UnitTemperatureMenu, unitTemperatureChildren), ToolboxMessageTree::Node(I18n::Message::UnitAmountMenu, unitAmountMoleChildren), ToolboxMessageTree::Node(I18n::Message::UnitLuminousIntensityMenu, unitLuminousIntensityChildren), + ToolboxMessageTree::Node(I18n::Message::UnitLuminousFluxMenu, unitLuminousFluxChildren), + ToolboxMessageTree::Node(I18n::Message::UnitIlluminanceMenu, unitIlluminanceChildren), + ToolboxMessageTree::Node(I18n::Message::UnitSolidAngleMenu, unitSolidAngleChildren), ToolboxMessageTree::Node(I18n::Message::UnitFrequencyMenu, unitFrequencyHertzChildren), ToolboxMessageTree::Node(I18n::Message::UnitForceMenu, unitForceNewtonChildren), ToolboxMessageTree::Node(I18n::Message::UnitPressureMenu, unitPressureChildren), @@ -378,6 +396,409 @@ const ToolboxMessageTree predictionChildren[] = { ToolboxMessageTree::Leaf(I18n::Message::PredictionCommandWithArg, I18n::Message::Prediction), ToolboxMessageTree::Leaf(I18n::Message::ConfidenceCommandWithArg, I18n::Message::Confidence)}; +const ToolboxMessageTree chemistryMolarMassesByNumber[] = { + ToolboxMessageTree::Leaf(I18n::Message::NumberElementH, I18n::Message::ElementHMass, false, I18n::Message::ElementHMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementHe, I18n::Message::ElementHeMass, false, I18n::Message::ElementHeMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementLi, I18n::Message::ElementLiMass, false, I18n::Message::ElementLiMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementBe, I18n::Message::ElementBeMass, false, I18n::Message::ElementBeMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementB, I18n::Message::ElementBMass, false, I18n::Message::ElementBMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementC, I18n::Message::ElementCMass, false, I18n::Message::ElementCMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementN, I18n::Message::ElementNMass, false, I18n::Message::ElementNMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementO, I18n::Message::ElementOMass, false, I18n::Message::ElementOMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementF, I18n::Message::ElementFMass, false, I18n::Message::ElementFMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementNe, I18n::Message::ElementNeMass, false, I18n::Message::ElementNeMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementNa, I18n::Message::ElementNaMass, false, I18n::Message::ElementNaMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementMg, I18n::Message::ElementMgMass, false, I18n::Message::ElementMgMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementAl, I18n::Message::ElementAlMass, false, I18n::Message::ElementAlMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementSi, I18n::Message::ElementSiMass, false, I18n::Message::ElementSiMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementP, I18n::Message::ElementPMass, false, I18n::Message::ElementPMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementS, I18n::Message::ElementSMass, false, I18n::Message::ElementSMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementCl, I18n::Message::ElementClMass, false, I18n::Message::ElementClMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementAr, I18n::Message::ElementArMass, false, I18n::Message::ElementArMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementK, I18n::Message::ElementKMass, false, I18n::Message::ElementKMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementCa, I18n::Message::ElementCaMass, false, I18n::Message::ElementCaMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementSc, I18n::Message::ElementScMass, false, I18n::Message::ElementScMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementTi, I18n::Message::ElementTiMass, false, I18n::Message::ElementTiMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementV, I18n::Message::ElementVMass, false, I18n::Message::ElementVMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementCr, I18n::Message::ElementCrMass, false, I18n::Message::ElementCrMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementMn, I18n::Message::ElementMnMass, false, I18n::Message::ElementMnMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementFe, I18n::Message::ElementFeMass, false, I18n::Message::ElementFeMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementCo, I18n::Message::ElementCoMass, false, I18n::Message::ElementCoMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementNi, I18n::Message::ElementNiMass, false, I18n::Message::ElementNiMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementCu, I18n::Message::ElementCuMass, false, I18n::Message::ElementCuMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementZn, I18n::Message::ElementZnMass, false, I18n::Message::ElementZnMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementGa, I18n::Message::ElementGaMass, false, I18n::Message::ElementGaMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementGe, I18n::Message::ElementGeMass, false, I18n::Message::ElementGeMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementAs, I18n::Message::ElementAsMass, false, I18n::Message::ElementAsMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementSe, I18n::Message::ElementSeMass, false, I18n::Message::ElementSeMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementBr, I18n::Message::ElementBrMass, false, I18n::Message::ElementBrMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementKr, I18n::Message::ElementKrMass, false, I18n::Message::ElementKrMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementRb, I18n::Message::ElementRbMass, false, I18n::Message::ElementRbMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementSr, I18n::Message::ElementSrMass, false, I18n::Message::ElementSrMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementY, I18n::Message::ElementYMass, false, I18n::Message::ElementYMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementZr, I18n::Message::ElementZrMass, false, I18n::Message::ElementZrMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementNb, I18n::Message::ElementNbMass, false, I18n::Message::ElementNbMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementMo, I18n::Message::ElementMoMass, false, I18n::Message::ElementMoMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementTc, I18n::Message::ElementTcMass, false, I18n::Message::ElementTcMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementRu, I18n::Message::ElementRuMass, false, I18n::Message::ElementRuMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementRh, I18n::Message::ElementRhMass, false, I18n::Message::ElementRhMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementPd, I18n::Message::ElementPdMass, false, I18n::Message::ElementPdMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementAg, I18n::Message::ElementAgMass, false, I18n::Message::ElementAgMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementCd, I18n::Message::ElementCdMass, false, I18n::Message::ElementCdMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementIn, I18n::Message::ElementInMass, false, I18n::Message::ElementInMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementSn, I18n::Message::ElementSnMass, false, I18n::Message::ElementSnMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementSb, I18n::Message::ElementSbMass, false, I18n::Message::ElementSbMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementTe, I18n::Message::ElementTeMass, false, I18n::Message::ElementTeMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementI, I18n::Message::ElementIMass, false, I18n::Message::ElementIMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementXe, I18n::Message::ElementXeMass, false, I18n::Message::ElementXeMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementCs, I18n::Message::ElementCsMass, false, I18n::Message::ElementCsMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementBa, I18n::Message::ElementBaMass, false, I18n::Message::ElementBaMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementLa, I18n::Message::ElementLaMass, false, I18n::Message::ElementLaMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementCe, I18n::Message::ElementCeMass, false, I18n::Message::ElementCeMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementPr, I18n::Message::ElementPrMass, false, I18n::Message::ElementPrMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementNd, I18n::Message::ElementNdMass, false, I18n::Message::ElementNdMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementPm, I18n::Message::ElementPmMass, false, I18n::Message::ElementPmMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementSm, I18n::Message::ElementSmMass, false, I18n::Message::ElementSmMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementEu, I18n::Message::ElementEuMass, false, I18n::Message::ElementEuMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementGd, I18n::Message::ElementGdMass, false, I18n::Message::ElementGdMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementTb, I18n::Message::ElementTbMass, false, I18n::Message::ElementTbMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementDy, I18n::Message::ElementDyMass, false, I18n::Message::ElementDyMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementHo, I18n::Message::ElementHoMass, false, I18n::Message::ElementHoMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementEr, I18n::Message::ElementErMass, false, I18n::Message::ElementErMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementTm, I18n::Message::ElementTmMass, false, I18n::Message::ElementTmMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementYb, I18n::Message::ElementYbMass, false, I18n::Message::ElementYbMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementLu, I18n::Message::ElementLuMass, false, I18n::Message::ElementLuMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementHf, I18n::Message::ElementHfMass, false, I18n::Message::ElementHfMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementTa, I18n::Message::ElementTaMass, false, I18n::Message::ElementTaMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementW, I18n::Message::ElementWMass, false, I18n::Message::ElementWMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementRe, I18n::Message::ElementReMass, false, I18n::Message::ElementReMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementOs, I18n::Message::ElementOsMass, false, I18n::Message::ElementOsMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementIr, I18n::Message::ElementIrMass, false, I18n::Message::ElementIrMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementPt, I18n::Message::ElementPtMass, false, I18n::Message::ElementPtMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementAu, I18n::Message::ElementAuMass, false, I18n::Message::ElementAuMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementHg, I18n::Message::ElementHgMass, false, I18n::Message::ElementHgMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementTl, I18n::Message::ElementTlMass, false, I18n::Message::ElementTlMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementPb, I18n::Message::ElementPbMass, false, I18n::Message::ElementPbMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementBi, I18n::Message::ElementBiMass, false, I18n::Message::ElementBiMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementPo, I18n::Message::ElementPoMass, false, I18n::Message::ElementPoMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementAt, I18n::Message::ElementAtMass, false, I18n::Message::ElementAtMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementRn, I18n::Message::ElementRnMass, false, I18n::Message::ElementRnMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementFr, I18n::Message::ElementFrMass, false, I18n::Message::ElementFrMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementRa, I18n::Message::ElementRaMass, false, I18n::Message::ElementRaMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementAc, I18n::Message::ElementAcMass, false, I18n::Message::ElementAcMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementTh, I18n::Message::ElementThMass, false, I18n::Message::ElementThMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementPa, I18n::Message::ElementPaMass, false, I18n::Message::ElementPaMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementU, I18n::Message::ElementUMass, false, I18n::Message::ElementUMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementNp, I18n::Message::ElementNpMass, false, I18n::Message::ElementNpMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementPu, I18n::Message::ElementPuMass, false, I18n::Message::ElementPuMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementAm, I18n::Message::ElementAmMass, false, I18n::Message::ElementAmMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementCm, I18n::Message::ElementCmMass, false, I18n::Message::ElementCmMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementBk, I18n::Message::ElementBkMass, false, I18n::Message::ElementBkMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementCf, I18n::Message::ElementCfMass, false, I18n::Message::ElementCfMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementEs, I18n::Message::ElementEsMass, false, I18n::Message::ElementEsMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementFm, I18n::Message::ElementFmMass, false, I18n::Message::ElementFmMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementMd, I18n::Message::ElementMdMass, false, I18n::Message::ElementMdMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementNo, I18n::Message::ElementNoMass, false, I18n::Message::ElementNoMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementLr, I18n::Message::ElementLrMass, false, I18n::Message::ElementLrMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementRf, I18n::Message::ElementRfMass, false, I18n::Message::ElementRfMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementDb, I18n::Message::ElementDbMass, false, I18n::Message::ElementDbMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementSg, I18n::Message::ElementSgMass, false, I18n::Message::ElementSgMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementBh, I18n::Message::ElementBhMass, false, I18n::Message::ElementBhMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementHs, I18n::Message::ElementHsMass, false, I18n::Message::ElementHsMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementMt, I18n::Message::ElementMtMass, false, I18n::Message::ElementMtMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementDs, I18n::Message::ElementDsMass, false, I18n::Message::ElementDsMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementRg, I18n::Message::ElementRgMass, false, I18n::Message::ElementRgMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementCn, I18n::Message::ElementCnMass, false, I18n::Message::ElementCnMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementNh, I18n::Message::ElementNhMass, false, I18n::Message::ElementNhMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementFl, I18n::Message::ElementFlMass, false, I18n::Message::ElementFlMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementMc, I18n::Message::ElementMcMass, false, I18n::Message::ElementMcMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementLv, I18n::Message::ElementLvMass, false, I18n::Message::ElementLvMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementTs, I18n::Message::ElementTsMass, false, I18n::Message::ElementTsMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementOg, I18n::Message::ElementOgMass, false, I18n::Message::ElementOgMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementUue, I18n::Message::ElementUueMass, false, I18n::Message::ElementUueMass), + ToolboxMessageTree::Leaf(I18n::Message::NumberElementUbn, I18n::Message::ElementUbnMass, false, I18n::Message::ElementUbnMass) +}; + +const ToolboxMessageTree chemistryMolarMassesByAlpha[] = { + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementAc, I18n::Message::ElementAcMass, false, I18n::Message::ElementAcMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementAg, I18n::Message::ElementAgMass, false, I18n::Message::ElementAgMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementAl, I18n::Message::ElementAlMass, false, I18n::Message::ElementAlMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementAm, I18n::Message::ElementAmMass, false, I18n::Message::ElementAmMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementAr, I18n::Message::ElementArMass, false, I18n::Message::ElementArMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementAs, I18n::Message::ElementAsMass, false, I18n::Message::ElementAsMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementAt, I18n::Message::ElementAtMass, false, I18n::Message::ElementAtMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementAu, I18n::Message::ElementAuMass, false, I18n::Message::ElementAuMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementB, I18n::Message::ElementBMass, false, I18n::Message::ElementBMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementBa, I18n::Message::ElementBaMass, false, I18n::Message::ElementBaMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementBe, I18n::Message::ElementBeMass, false, I18n::Message::ElementBeMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementBh, I18n::Message::ElementBhMass, false, I18n::Message::ElementBhMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementBi, I18n::Message::ElementBiMass, false, I18n::Message::ElementBiMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementBk, I18n::Message::ElementBkMass, false, I18n::Message::ElementBkMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementBr, I18n::Message::ElementBrMass, false, I18n::Message::ElementBrMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementC, I18n::Message::ElementCMass, false, I18n::Message::ElementCMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementCa, I18n::Message::ElementCaMass, false, I18n::Message::ElementCaMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementCd, I18n::Message::ElementCdMass, false, I18n::Message::ElementCdMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementCe, I18n::Message::ElementCeMass, false, I18n::Message::ElementCeMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementCf, I18n::Message::ElementCfMass, false, I18n::Message::ElementCfMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementCl, I18n::Message::ElementClMass, false, I18n::Message::ElementClMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementCm, I18n::Message::ElementCmMass, false, I18n::Message::ElementCmMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementCn, I18n::Message::ElementCnMass, false, I18n::Message::ElementCnMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementCo, I18n::Message::ElementCoMass, false, I18n::Message::ElementCoMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementCs, I18n::Message::ElementCsMass, false, I18n::Message::ElementCsMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementCr, I18n::Message::ElementCrMass, false, I18n::Message::ElementCrMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementCu, I18n::Message::ElementCuMass, false, I18n::Message::ElementCuMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementDb, I18n::Message::ElementDbMass, false, I18n::Message::ElementDbMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementDs, I18n::Message::ElementDsMass, false, I18n::Message::ElementDsMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementDy, I18n::Message::ElementDyMass, false, I18n::Message::ElementDyMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementEr, I18n::Message::ElementErMass, false, I18n::Message::ElementErMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementEs, I18n::Message::ElementEsMass, false, I18n::Message::ElementEsMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementEu, I18n::Message::ElementEuMass, false, I18n::Message::ElementEuMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementF, I18n::Message::ElementFMass, false, I18n::Message::ElementFMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementFe, I18n::Message::ElementFeMass, false, I18n::Message::ElementFeMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementFl, I18n::Message::ElementFlMass, false, I18n::Message::ElementFlMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementFm, I18n::Message::ElementFmMass, false, I18n::Message::ElementFmMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementFr, I18n::Message::ElementFrMass, false, I18n::Message::ElementFrMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementGa, I18n::Message::ElementGaMass, false, I18n::Message::ElementGaMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementGd, I18n::Message::ElementGdMass, false, I18n::Message::ElementGdMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementGe, I18n::Message::ElementGeMass, false, I18n::Message::ElementGeMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementH, I18n::Message::ElementHMass, false, I18n::Message::ElementHMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementHe, I18n::Message::ElementHeMass, false, I18n::Message::ElementHeMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementHf, I18n::Message::ElementHfMass, false, I18n::Message::ElementHfMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementHg, I18n::Message::ElementHgMass, false, I18n::Message::ElementHgMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementHo, I18n::Message::ElementHoMass, false, I18n::Message::ElementHoMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementHs, I18n::Message::ElementHsMass, false, I18n::Message::ElementHsMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementI, I18n::Message::ElementIMass, false, I18n::Message::ElementIMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementIn, I18n::Message::ElementInMass, false, I18n::Message::ElementInMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementIr, I18n::Message::ElementIrMass, false, I18n::Message::ElementIrMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementK, I18n::Message::ElementKMass, false, I18n::Message::ElementKMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementKr, I18n::Message::ElementKrMass, false, I18n::Message::ElementKrMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementLa, I18n::Message::ElementLaMass, false, I18n::Message::ElementLaMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementLi, I18n::Message::ElementLiMass, false, I18n::Message::ElementLiMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementLr, I18n::Message::ElementLrMass, false, I18n::Message::ElementLrMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementLu, I18n::Message::ElementLuMass, false, I18n::Message::ElementLuMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementLv, I18n::Message::ElementLvMass, false, I18n::Message::ElementLvMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementMc, I18n::Message::ElementMcMass, false, I18n::Message::ElementMcMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementMd, I18n::Message::ElementMdMass, false, I18n::Message::ElementMdMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementMg, I18n::Message::ElementMgMass, false, I18n::Message::ElementMgMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementMn, I18n::Message::ElementMnMass, false, I18n::Message::ElementMnMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementMo, I18n::Message::ElementMoMass, false, I18n::Message::ElementMoMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementMt, I18n::Message::ElementMtMass, false, I18n::Message::ElementMtMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementN, I18n::Message::ElementNMass, false, I18n::Message::ElementNMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementNa, I18n::Message::ElementNaMass, false, I18n::Message::ElementNaMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementNb, I18n::Message::ElementNbMass, false, I18n::Message::ElementNbMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementNd, I18n::Message::ElementNdMass, false, I18n::Message::ElementNdMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementNe, I18n::Message::ElementNeMass, false, I18n::Message::ElementNeMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementNh, I18n::Message::ElementNhMass, false, I18n::Message::ElementNhMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementNi, I18n::Message::ElementNiMass, false, I18n::Message::ElementNiMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementNo, I18n::Message::ElementNoMass, false, I18n::Message::ElementNoMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementNp, I18n::Message::ElementNpMass, false, I18n::Message::ElementNpMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementO, I18n::Message::ElementOMass, false, I18n::Message::ElementOMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementOg, I18n::Message::ElementOgMass, false, I18n::Message::ElementOgMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementOs, I18n::Message::ElementOsMass, false, I18n::Message::ElementOsMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementP, I18n::Message::ElementPMass, false, I18n::Message::ElementPMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementPa, I18n::Message::ElementPaMass, false, I18n::Message::ElementPaMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementPb, I18n::Message::ElementPbMass, false, I18n::Message::ElementPbMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementPd, I18n::Message::ElementPdMass, false, I18n::Message::ElementPdMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementPm, I18n::Message::ElementPmMass, false, I18n::Message::ElementPmMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementPo, I18n::Message::ElementPoMass, false, I18n::Message::ElementPoMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementPr, I18n::Message::ElementPrMass, false, I18n::Message::ElementPrMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementPt, I18n::Message::ElementPtMass, false, I18n::Message::ElementPtMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementPu, I18n::Message::ElementPuMass, false, I18n::Message::ElementPuMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementRa, I18n::Message::ElementRaMass, false, I18n::Message::ElementRaMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementRb, I18n::Message::ElementRbMass, false, I18n::Message::ElementRbMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementRe, I18n::Message::ElementReMass, false, I18n::Message::ElementReMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementRf, I18n::Message::ElementRfMass, false, I18n::Message::ElementRfMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementRg, I18n::Message::ElementRgMass, false, I18n::Message::ElementRgMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementRh, I18n::Message::ElementRhMass, false, I18n::Message::ElementRhMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementRn, I18n::Message::ElementRnMass, false, I18n::Message::ElementRnMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementRu, I18n::Message::ElementRuMass, false, I18n::Message::ElementRuMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementS, I18n::Message::ElementSMass, false, I18n::Message::ElementSMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementSb, I18n::Message::ElementSbMass, false, I18n::Message::ElementSbMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementSc, I18n::Message::ElementScMass, false, I18n::Message::ElementScMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementSe, I18n::Message::ElementSeMass, false, I18n::Message::ElementSeMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementSg, I18n::Message::ElementSgMass, false, I18n::Message::ElementSgMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementSi, I18n::Message::ElementSiMass, false, I18n::Message::ElementSiMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementSm, I18n::Message::ElementSmMass, false, I18n::Message::ElementSmMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementSn, I18n::Message::ElementSnMass, false, I18n::Message::ElementSnMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementSr, I18n::Message::ElementSrMass, false, I18n::Message::ElementSrMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementTa, I18n::Message::ElementTaMass, false, I18n::Message::ElementTaMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementTb, I18n::Message::ElementTbMass, false, I18n::Message::ElementTbMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementTc, I18n::Message::ElementTcMass, false, I18n::Message::ElementTcMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementTe, I18n::Message::ElementTeMass, false, I18n::Message::ElementTeMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementTh, I18n::Message::ElementThMass, false, I18n::Message::ElementThMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementTi, I18n::Message::ElementTiMass, false, I18n::Message::ElementTiMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementTl, I18n::Message::ElementTlMass, false, I18n::Message::ElementTlMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementTm, I18n::Message::ElementTmMass, false, I18n::Message::ElementTmMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementTs, I18n::Message::ElementTsMass, false, I18n::Message::ElementTsMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementU, I18n::Message::ElementUMass, false, I18n::Message::ElementUMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementUue, I18n::Message::ElementUueMass, false, I18n::Message::ElementUueMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementUbn, I18n::Message::ElementUbnMass, false, I18n::Message::ElementUbnMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementV, I18n::Message::ElementVMass, false, I18n::Message::ElementVMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementW, I18n::Message::ElementWMass, false, I18n::Message::ElementWMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementXe, I18n::Message::ElementXeMass, false, I18n::Message::ElementXeMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementY, I18n::Message::ElementYMass, false, I18n::Message::ElementYMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementYb, I18n::Message::ElementYbMass, false, I18n::Message::ElementYbMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementZn, I18n::Message::ElementZnMass, false, I18n::Message::ElementZnMass), + ToolboxMessageTree::Leaf(I18n::Message::AlphaElementZr, I18n::Message::ElementZrMass, false, I18n::Message::ElementZrMass) +}; + +const ToolboxMessageTree Pka[] = { + ToolboxMessageTree::Leaf(I18n::Message::Pka01, I18n::Message::Pka01Value, false, I18n::Message::Pka01Value), + ToolboxMessageTree::Leaf(I18n::Message::Pka02, I18n::Message::Pka02Value, false, I18n::Message::Pka02Value), + ToolboxMessageTree::Leaf(I18n::Message::Pka03, I18n::Message::Pka03Value, false, I18n::Message::Pka03Value), + ToolboxMessageTree::Leaf(I18n::Message::Pka04, I18n::Message::Pka04Value, false, I18n::Message::Pka04Value), + ToolboxMessageTree::Leaf(I18n::Message::Pka05, I18n::Message::Pka05Value, false, I18n::Message::Pka05Value), + ToolboxMessageTree::Leaf(I18n::Message::Pka06, I18n::Message::Pka06Value, false, I18n::Message::Pka06Value), + ToolboxMessageTree::Leaf(I18n::Message::Pka07, I18n::Message::Pka07Value, false, I18n::Message::Pka07Value), + ToolboxMessageTree::Leaf(I18n::Message::Pka08, I18n::Message::Pka08Value, false, I18n::Message::Pka08Value), + ToolboxMessageTree::Leaf(I18n::Message::Pka09, I18n::Message::Pka09Value, false, I18n::Message::Pka09Value), + ToolboxMessageTree::Leaf(I18n::Message::Pka10, I18n::Message::Pka10Value, false, I18n::Message::Pka10Value), + ToolboxMessageTree::Leaf(I18n::Message::Pka11, I18n::Message::Pka11Value, false, I18n::Message::Pka11Value), + ToolboxMessageTree::Leaf(I18n::Message::Pka12, I18n::Message::Pka12Value, false, I18n::Message::Pka12Value), + ToolboxMessageTree::Leaf(I18n::Message::Pka13, I18n::Message::Pka13Value, false, I18n::Message::Pka13Value), + ToolboxMessageTree::Leaf(I18n::Message::Pka14, I18n::Message::Pka14Value, false, I18n::Message::Pka14Value), + ToolboxMessageTree::Leaf(I18n::Message::Pka15, I18n::Message::Pka15Value, false, I18n::Message::Pka15Value), + ToolboxMessageTree::Leaf(I18n::Message::Pka16, I18n::Message::Pka16Value, false, I18n::Message::Pka16Value), + ToolboxMessageTree::Leaf(I18n::Message::UltimateAnswer, I18n::Message::UltimateAnswerValue, false, I18n::Message::UltimateAnswerValue), +}; + +const ToolboxMessageTree chemistry[] = { + ToolboxMessageTree::Node(I18n::Message::MolarMassesByNumber, chemistryMolarMassesByNumber), + ToolboxMessageTree::Node(I18n::Message::MolarMassesByAlpha, chemistryMolarMassesByAlpha), + ToolboxMessageTree::Node(I18n::Message::Pka, Pka), +}; + +const ToolboxMessageTree FundamentalConstants[] = { + ToolboxMessageTree::Leaf(I18n::Message::SpeedOfLightTag, I18n::Message::SpeedOfLight, false, I18n::Message::SpeedOfLight), + ToolboxMessageTree::Leaf(I18n::Message::Vacuum_permittivityTag, I18n::Message::Vacuum_permittivity, false, I18n::Message::Vacuum_permittivity), + ToolboxMessageTree::Leaf(I18n::Message::Vacuum_permeabilityTag, I18n::Message::Vacuum_permeability, false, I18n::Message::Vacuum_permeability), + ToolboxMessageTree::Leaf(I18n::Message::PlanckTag, I18n::Message::Planck, false, I18n::Message::Planck), + ToolboxMessageTree::Leaf(I18n::Message::VacuumImpedanceTag, I18n::Message::VacuumImpedance, false, I18n::Message::VacuumImpedance), +}; + +const ToolboxMessageTree SpeedsOfSound[] = { + ToolboxMessageTree::Leaf(I18n::Message::SpeedOfSound0Tag, I18n::Message::SpeedOfSound0, false, I18n::Message::SpeedOfSound0), + ToolboxMessageTree::Leaf(I18n::Message::SpeedOfSoundWaterTag, I18n::Message::SpeedOfSoundWater, false, I18n::Message::SpeedOfSoundWater), + ToolboxMessageTree::Leaf(I18n::Message::SpeedOfSoundGlassTag, I18n::Message::SpeedOfSoundGlass, false, I18n::Message::SpeedOfSoundGlass), + ToolboxMessageTree::Leaf(I18n::Message::SpeedOfSoundSteelTag, I18n::Message::SpeedOfSoundSteel, false, I18n::Message::SpeedOfSoundSteel) +}; + +const ToolboxMessageTree EscapeVelocities[] = { + ToolboxMessageTree::Leaf(I18n::Message::EscapeVelocityFromMoon, I18n::Message::EscapeVelocityOfMoon, false, I18n::Message::EscapeVelocityOfMoon), + ToolboxMessageTree::Leaf(I18n::Message::EscapeVelocityFromEarth, I18n::Message::EscapeVelocityOfEarth, false, I18n::Message::EscapeVelocityOfEarth), + ToolboxMessageTree::Leaf(I18n::Message::EscapeVelocityFromSun, I18n::Message::EscapeVelocityOfSun, false, I18n::Message::EscapeVelocityOfSun), +}; + +const ToolboxMessageTree Speed[] = { + ToolboxMessageTree::Node(I18n::Message::SpeedOfSound, SpeedsOfSound), + ToolboxMessageTree::Node(I18n::Message::EscapeVelocity, EscapeVelocities) +}; + +const ToolboxMessageTree Thermodynamics[] = { + ToolboxMessageTree::Leaf(I18n::Message::BoltzmannTag,I18n::Message::Boltzmann, false, I18n::Message::Boltzmann), + ToolboxMessageTree::Leaf(I18n::Message::AvogadroTag, I18n::Message::Avogadro, false, I18n::Message::Avogadro), + ToolboxMessageTree::Leaf(I18n::Message::GasTag,I18n::Message::Gas, false, I18n::Message::Gas), + ToolboxMessageTree::Leaf(I18n::Message::StefanBoltzmannTag, I18n::Message::StefanBoltzmann, false, I18n::Message::StefanBoltzmann), + ToolboxMessageTree::Leaf(I18n::Message::WaterTriplePointTag, I18n::Message::WaterTriplePoint, false, I18n::Message::WaterTriplePoint), + ToolboxMessageTree::Leaf(I18n::Message::WienTag, I18n::Message::Wien, false, I18n::Message::Wien), + ToolboxMessageTree::Leaf(I18n::Message::AtmosphericPressureTag, I18n::Message::AtmosphericPressure, false, I18n::Message::AtmosphericPressure), +}; + +const ToolboxMessageTree Electromagnetism[] = { + ToolboxMessageTree::Leaf(I18n::Message::CoulombTag, I18n::Message::Coulomb, false, I18n::Message::Coulomb), + ToolboxMessageTree::Leaf(I18n::Message::ElementalChargeTag, I18n::Message::ElementalCharge, false, I18n::Message::ElementalCharge), + ToolboxMessageTree::Leaf(I18n::Message::FaradayConstantTag, I18n::Message::FaradayConstant, false, I18n::Message::FaradayConstant), + +}; + +const ToolboxMessageTree ParticleMass[] = { + ToolboxMessageTree::Leaf(I18n::Message::ElectronMassTag, I18n::Message::ElectronMass, false, I18n::Message::ElectronMass), + ToolboxMessageTree::Leaf(I18n::Message::MuonMassTag, I18n::Message::MuonMass, false, I18n::Message::MuonMass), + ToolboxMessageTree::Leaf(I18n::Message::NeutronMassTag, I18n::Message::NeutronMass, false, I18n::Message::NeutronMass), + ToolboxMessageTree::Leaf(I18n::Message::ProtonMassTag, I18n::Message::ProtonMass, false, I18n::Message::ProtonMass), + ToolboxMessageTree::Leaf(I18n::Message::TauonMassTag, I18n::Message::TauonMass, false, I18n::Message::TauonMass), + ToolboxMessageTree::Leaf(I18n::Message::WBosonMassTag, I18n::Message::WBosonMass, false, I18n::Message::WBosonMass), + ToolboxMessageTree::Leaf(I18n::Message::ZBosonMassTag, I18n::Message::ZBosonMass, false, I18n::Message::ZBosonMass), + ToolboxMessageTree::Leaf(I18n::Message::AtomicMassUnitTag, I18n::Message::AtomicMassUnit, false, I18n::Message::AtomicMassUnit), +}; + + +const ToolboxMessageTree Nuclear[] = { + ToolboxMessageTree::Leaf(I18n::Message::FineStructureTag, I18n::Message::FineStructure, false, I18n::Message::FineStructure), + ToolboxMessageTree::Leaf(I18n::Message::RydbergConstantTag, I18n::Message::RydbergConstant, false, I18n::Message::RydbergConstant), + ToolboxMessageTree::Leaf(I18n::Message::HartreeConstantTag, I18n::Message::HartreeConstant, false, I18n::Message::HartreeConstant), + ToolboxMessageTree::Leaf(I18n::Message::MagneticFluxQuantumTag, I18n::Message::MagneticFluxQuantum, false, I18n::Message::MagneticFluxQuantum), + ToolboxMessageTree::Leaf(I18n::Message::ConductanceQuantumTag, I18n::Message::ConductanceQuantum, false, I18n::Message::ConductanceQuantum), + ToolboxMessageTree::Leaf(I18n::Message::CirculationQuantumTag, I18n::Message::CirculationQuantum, false, I18n::Message::CirculationQuantum), + ToolboxMessageTree::Leaf(I18n::Message::BohrRadiusTag, I18n::Message::BohrRadius, false, I18n::Message::BohrRadius), + ToolboxMessageTree::Leaf(I18n::Message::BohrMagnetonTag, I18n::Message::BohrMagneton, false, I18n::Message::BohrMagneton), + ToolboxMessageTree::Leaf(I18n::Message::NuclearMagnetonTag, I18n::Message::NuclearMagneton, false, I18n::Message::NuclearMagneton), + ToolboxMessageTree::Node(I18n::Message::ParticleMass, ParticleMass), +}; + +const ToolboxMessageTree Gravitation[] = { + ToolboxMessageTree::Leaf(I18n::Message::GAccelerationTag, I18n::Message::GAcceleration, false, I18n::Message::GAcceleration), + ToolboxMessageTree::Leaf(I18n::Message::GConstantTag, I18n::Message::GConstant, false, I18n::Message::GConstant), +}; + + +const ToolboxMessageTree Radiuses[] = { + ToolboxMessageTree::Leaf(I18n::Message::SunMassTag, I18n::Message::SunRadius, false, I18n::Message::SunRadius), + ToolboxMessageTree::Leaf(I18n::Message::EarthMassTag, I18n::Message::EarthRadius, false, I18n::Message::EarthRadius), + ToolboxMessageTree::Leaf(I18n::Message::MoonMassTag, I18n::Message::MoonRadius, false, I18n::Message::MoonRadius), + +}; + +const ToolboxMessageTree Distances[] = { + ToolboxMessageTree::Leaf(I18n::Message::EarthMoonDistanceTag, I18n::Message::EarthMoonDistance, false, I18n::Message::EarthMoonDistance), + ToolboxMessageTree::Leaf(I18n::Message::EarthSunDistanceTag, I18n::Message::EarthSunDistance, false, I18n::Message::EarthSunDistance), +}; + +const ToolboxMessageTree Length[] = { + ToolboxMessageTree::Node(I18n::Message::Radiuses, Radiuses), + ToolboxMessageTree::Node(I18n::Message::Distances, Distances), +}; + +const ToolboxMessageTree Mass[] = { + ToolboxMessageTree::Leaf(I18n::Message::SunMassTag, I18n::Message::SunMass, false, I18n::Message::SunMass), + ToolboxMessageTree::Leaf(I18n::Message::EarthMassTag, I18n::Message::EarthMass, false, I18n::Message::EarthMass), + ToolboxMessageTree::Leaf(I18n::Message::MoonMassTag, I18n::Message::MoonMass, false, I18n::Message::MoonMass), +}; + + +const ToolboxMessageTree PlanckUnits[] = { + ToolboxMessageTree::Leaf(I18n::Message::PlanckReduceTag, I18n::Message::PlanckReduce, false, I18n::Message::PlanckReduce), + ToolboxMessageTree::Leaf(I18n::Message::PlanckMassTag, I18n::Message::PlanckMass, false, I18n::Message::PlanckMass), + ToolboxMessageTree::Leaf(I18n::Message::PlanckLengthTag, I18n::Message::PlanckLength, false, I18n::Message::PlanckLength), + ToolboxMessageTree::Leaf(I18n::Message::PlanckTimeTag, I18n::Message::PlanckTime, false, I18n::Message::PlanckTime), + ToolboxMessageTree::Leaf(I18n::Message::PlanckTemperatureTag, I18n::Message::PlanckTemperature, false, I18n::Message::PlanckTemperature), + ToolboxMessageTree::Leaf(I18n::Message::PlanckChargeTag, I18n::Message::PlanckCharge, false, I18n::Message::PlanckCharge), + ToolboxMessageTree::Leaf(I18n::Message::PlanckForceTag, I18n::Message::PlanckForce, false, I18n::Message::PlanckForce), + ToolboxMessageTree::Leaf(I18n::Message::PlanckEnergyTag, I18n::Message::PlanckEnergy, false, I18n::Message::PlanckEnergy), + ToolboxMessageTree::Leaf(I18n::Message::PlanckPowerTag, I18n::Message::PlanckPower, false, I18n::Message::PlanckPower), + ToolboxMessageTree::Leaf(I18n::Message::PlanckDensityTag, I18n::Message::PlanckDensity, false, I18n::Message::PlanckDensity), + ToolboxMessageTree::Leaf(I18n::Message::PlanckQuantityMovementTag, I18n::Message::PlanckQuantityMovement, false, I18n::Message::PlanckQuantityMovement), + ToolboxMessageTree::Leaf(I18n::Message::PlanckLinearMassTag, I18n::Message::PlanckLinearMass, false, I18n::Message::PlanckLinearMass), + ToolboxMessageTree::Leaf(I18n::Message::PlanckTensionTag, I18n::Message::PlanckTension, false, I18n::Message::PlanckTension), + ToolboxMessageTree::Leaf(I18n::Message::PlanckCurrentTag, I18n::Message::PlanckCurrent, false, I18n::Message::PlanckCurrent), + ToolboxMessageTree::Leaf(I18n::Message::PlanckPressureTag, I18n::Message::PlanckPressure, false, I18n::Message::PlanckPressure), + ToolboxMessageTree::Leaf(I18n::Message::PlanckImpedanceTag, I18n::Message::PlanckImpedance, false, I18n::Message::PlanckImpedance), +}; + +const ToolboxMessageTree Physics[] = { + ToolboxMessageTree::Node(I18n::Message::FundamentalConstants, FundamentalConstants), + ToolboxMessageTree::Node(I18n::Message::Electromagnetism, Electromagnetism), + ToolboxMessageTree::Node(I18n::Message::NuclearConstants, Nuclear), + ToolboxMessageTree::Node(I18n::Message::Thermodynamics, Thermodynamics), + ToolboxMessageTree::Node(I18n::Message::Gravitation, Gravitation), + ToolboxMessageTree::Node(I18n::Message::Speed, Speed), + ToolboxMessageTree::Node(I18n::Message::Mass, Mass), + ToolboxMessageTree::Node(I18n::Message::Length, Length), + ToolboxMessageTree::Node(I18n::Message::PlanckUnitsTag, PlanckUnits), +}; + + + const ToolboxMessageTree menu[] = { ToolboxMessageTree::Leaf(I18n::Message::AbsCommandWithArg, I18n::Message::AbsoluteValue), ToolboxMessageTree::Leaf(I18n::Message::RootCommandWithArg, I18n::Message::NthRoot), @@ -395,7 +816,10 @@ const ToolboxMessageTree menu[] = { ToolboxMessageTree::Node(I18n::Message::Unit, unitChildren), ToolboxMessageTree::Node(I18n::Message::RandomAndApproximation, randomAndApproximationChildren), ToolboxMessageTree::Node(I18n::Message::HyperbolicTrigonometry, trigonometryChildren), - ToolboxMessageTree::Node(I18n::Message::Fluctuation, predictionChildren)}; + ToolboxMessageTree::Node(I18n::Message::Fluctuation, predictionChildren), + ToolboxMessageTree::Node(I18n::Message::Chemistry, chemistry), + ToolboxMessageTree::Node(I18n::Message::Physics, Physics) + }; const ToolboxMessageTree toolboxModel = ToolboxMessageTree::Node(I18n::Message::Toolbox, menu); diff --git a/apps/math_toolbox.h b/apps/math_toolbox.h index 41eb996fa85..2ade3318f62 100644 --- a/apps/math_toolbox.h +++ b/apps/math_toolbox.h @@ -7,9 +7,9 @@ class MathToolbox : public Toolbox { public: MathToolbox(); + const ToolboxMessageTree * rootModel() const override; protected: bool selectLeaf(int selectedRow) override; - const ToolboxMessageTree * rootModel() const override; MessageTableCellWithMessage * leafCellAtIndex(int index) override; MessageTableCellWithChevron* nodeCellAtIndex(int index) override; int maxNumberOfDisplayedRows() override; diff --git a/apps/on_boarding/base.es.i18n b/apps/on_boarding/base.es.i18n index 45291d1ceee..1cc6f595480 100644 --- a/apps/on_boarding/base.es.i18n +++ b/apps/on_boarding/base.es.i18n @@ -3,11 +3,11 @@ UpdateMessage1 = "Hay mejoras importantes" UpdateMessage2 = "para su calculadora." UpdateMessage3 = "Visite nuestra página desde su ordenador" UpdateMessage4 = "www.numworks.com/update" -BetaVersion = "BETA VERSION" +BetaVersion = "VERSION BETA" BetaVersionMessage1 = "" -BetaVersionMessage2 = "Your device runs a beta software." -BetaVersionMessage3 = "You might run into bugs or glitches." +BetaVersionMessage2 = "Tu dispositivo está corriendo software en versión beta." +BetaVersionMessage3 = "Podrían ocurrir errores." BetaVersionMessage4 = "" -BetaVersionMessage5 = "Please send any feedback to" +BetaVersionMessage5 = "Por favor envía feedback a" BetaVersionMessage6 = "contact@numworks.com" Skip = "Saltar" diff --git a/apps/on_boarding/base.hu.i18n b/apps/on_boarding/base.hu.i18n new file mode 100644 index 00000000000..e97da92baf2 --- /dev/null +++ b/apps/on_boarding/base.hu.i18n @@ -0,0 +1,13 @@ +UpdateAvailable = "Elérhetö Frissítések!" +UpdateMessage1 = "Fontos frissítések vannak" +UpdateMessage2 = "a számológépéhez." +UpdateMessage3 = "Töltje le a weboldalunkról az utolso verziót" +UpdateMessage4 = "www.numworks.com/update" +BetaVersion = "BETA VERZIÓ" +BetaVersionMessage1 = "" +BetaVersionMessage2 = "Az eszköz béta szoftvert futtat." +BetaVersionMessage3 = "Lehet, hogy hibákat észlel." +BetaVersionMessage4 = "" +BetaVersionMessage5 = "Kérjük, küldjön minden visszajelzést a" +BetaVersionMessage6 = "contact@numworks.com email címre" +Skip = "Tovább" diff --git a/apps/on_boarding/logo_icon.png b/apps/on_boarding/logo_icon.png index fd51603fb90..0dc9c6174e3 100644 Binary files a/apps/on_boarding/logo_icon.png and b/apps/on_boarding/logo_icon.png differ diff --git a/apps/on_boarding/logo_view.cpp b/apps/on_boarding/logo_view.cpp index dd76b95b96b..2bc4867b941 100644 --- a/apps/on_boarding/logo_view.cpp +++ b/apps/on_boarding/logo_view.cpp @@ -11,7 +11,7 @@ LogoView::LogoView() : } void LogoView::drawRect(KDContext * ctx, KDRect rect) const { - ctx->fillRect(bounds(), KDColorWhite); + ctx->fillRect(bounds(), Palette::BackgroundHard); } int LogoView::numberOfSubviews() const { diff --git a/apps/probability/app.cpp b/apps/probability/app.cpp index f2b9f981c03..56fe17b42b9 100644 --- a/apps/probability/app.cpp +++ b/apps/probability/app.cpp @@ -15,6 +15,10 @@ I18n::Message App::Descriptor::upperName() { return I18n::Message::ProbaAppCapital; } +App::Descriptor::ExaminationLevel App::Descriptor::examinationLevel() { + return App::Descriptor::ExaminationLevel::Strict; +} + const Image * App::Descriptor::icon() { return ImageStore::ProbabilityIcon; } @@ -81,11 +85,11 @@ App::App(Snapshot * snapshot) : { switch (snapshot->activePage()) { case Snapshot::Page::Parameters: - m_stackViewController.push(&m_parametersController, KDColorWhite, Palette::PurpleBright, Palette::PurpleBright); + m_stackViewController.push(&m_parametersController, Palette::BannerFirstText, Palette::BannerFirstBackground, Palette::BannerFirstBorder); break; case Snapshot::Page::Calculations: - m_stackViewController.push(&m_parametersController, KDColorWhite, Palette::PurpleBright, Palette::PurpleBright); - m_stackViewController.push(&m_calculationController, KDColorWhite, Palette::SubTab, Palette::SubTab); + m_stackViewController.push(&m_parametersController, Palette::BannerFirstText, Palette::BannerFirstBackground, Palette::BannerFirstBorder); + m_stackViewController.push(&m_calculationController, Palette::BannerSecondText, Palette::BannerSecondBackground, Palette::BannerSecondBorder); default: break; } diff --git a/apps/probability/app.h b/apps/probability/app.h index 23071b707dd..d93905c4690 100644 --- a/apps/probability/app.h +++ b/apps/probability/app.h @@ -28,6 +28,7 @@ class App : public Shared::TextFieldDelegateApp { public: I18n::Message name() override; I18n::Message upperName() override; + App::Descriptor::ExaminationLevel examinationLevel() override; const Image * icon() override; }; class Snapshot : public ::SharedApp::Snapshot { diff --git a/apps/probability/base.hu.i18n b/apps/probability/base.hu.i18n new file mode 100644 index 00000000000..98fb7e74c2f --- /dev/null +++ b/apps/probability/base.hu.i18n @@ -0,0 +1,27 @@ +ProbaApp = "Valószínüség" +ProbaAppCapital = "VALÓSZÍNÜSÉG" +ChooseDistribution = "Válassza ki a disztribúciót" +Binomial = "Binomiális" +Geometric = "Geometriai" +Uniforme = "Állandó" +Normal = "Normál" +ChiSquared = "Chi-négyzet" +UniformDistribution = "Egységes eloszlás" +ExponentialDistribution = "Exponenciális eloszlás" +GeometricDistribution = "Geometriai eloszlás" +PoissonDistribution = "Poisson eloszlás" +ChiSquaredDistribution = "Chi-négyzet eloszlás" +StudentDistribution = "Student eloszlása" +FisherDistribution = "Fisher eloszlás" +ChooseParameters = "Paraméterek kiválasztása" +RepetitionNumber = "n: ismétlések száma" +SuccessProbability = "p: a siker valószínüsége" +IntervalDefinition = "[a, b]: intervallum" +LambdaExponentialDefinition = "λ: paraméter" +MeanDefinition = "μ: remény vagy atlag" +DeviationDefinition = "σ: szórás" +LambdaPoissonDefinition = "λ: paraméter" +DegreesOfFreedomDefinition = "k: szabadságfokok" +D1FisherDefinition = "d1: a számláló szabadságfokai" +D2FisherDefinition = "d2: a nevezó szabadságfokai" +ComputeProbability = "Számítsa ki a valószínüségeket" diff --git a/apps/probability/calculation_cell.cpp b/apps/probability/calculation_cell.cpp index ea686f9d9f4..3c2b3dc36ca 100644 --- a/apps/probability/calculation_cell.cpp +++ b/apps/probability/calculation_cell.cpp @@ -38,10 +38,10 @@ KDSize CalculationCell::minimalSizeForOptimalDisplay() const { } void CalculationCell::drawRect(KDContext * ctx, KDRect rect) const { - ctx->fillRect(bounds(), KDColorWhite); + ctx->fillRect(bounds(), Palette::BackgroundHard); if (m_isResponder) { KDSize textSize = m_text.minimalSizeForOptimalDisplay(); - ctx->strokeRect(KDRect(2*k_margin+textSize.width(), 0, calculationCellWidth()+2*ResponderImageCell::k_outline, ImageCell::k_height+2*ResponderImageCell::k_outline), Palette::GrayMiddle); + ctx->strokeRect(KDRect(2*k_margin+textSize.width(), 0, calculationCellWidth()+2*ResponderImageCell::k_outline, ImageCell::k_height+2*ResponderImageCell::k_outline), Palette::ProbabilityCellBorder); } } diff --git a/apps/probability/calculation_controller.cpp b/apps/probability/calculation_controller.cpp index 9ab3ed81261..2d4ddd1b639 100644 --- a/apps/probability/calculation_controller.cpp +++ b/apps/probability/calculation_controller.cpp @@ -26,7 +26,7 @@ namespace Probability { constexpr int CalculationController::k_titleBufferSize; CalculationController::ContentView::ContentView(SelectableTableView * selectableTableView, Distribution * distribution, Calculation * calculation) : - m_titleView(KDFont::SmallFont, I18n::Message::ComputeProbability, 0.5f, 0.5f, Palette::GrayDark, Palette::WallScreen), + m_titleView(KDFont::SmallFont, I18n::Message::ComputeProbability, 0.5f, 0.5f, Palette::SecondaryText, Palette::BackgroundApps), m_selectableTableView(selectableTableView), m_distributionCurveView(distribution, calculation) { @@ -68,7 +68,7 @@ CalculationController::CalculationController(Responder * parentResponder, InputE m_selectableTableView.setMargins(k_tableMargin); m_selectableTableView.setVerticalCellOverlap(0); m_selectableTableView.setDecoratorType(ScrollView::Decorator::Type::None); - m_selectableTableView.setBackgroundColor(KDColorWhite); + m_selectableTableView.setBackgroundColor(Palette::BackgroundHard); for (int i = 0; i < k_numberOfCalculationCells; i++) { diff --git a/apps/probability/cell.cpp b/apps/probability/cell.cpp index 8083fbb5bab..1c36ae1a2ea 100644 --- a/apps/probability/cell.cpp +++ b/apps/probability/cell.cpp @@ -5,7 +5,7 @@ namespace Probability { Cell::Cell() : HighlightCell(), - m_labelView(KDFont::LargeFont, (I18n::Message)0, 0, 0.5, KDColorBlack, KDColorWhite), + m_labelView(KDFont::LargeFont, (I18n::Message)0, 0, 0.5, Palette::PrimaryText, Palette::BackgroundHard), m_icon(nullptr), m_focusedIcon(nullptr) { @@ -36,7 +36,7 @@ void Cell::layoutSubviews(bool force) { void Cell::reloadCell() { HighlightCell::reloadCell(); - KDColor backgroundColor = isHighlighted()? Palette::Select : KDColorWhite; + KDColor backgroundColor = isHighlighted()? Palette::ListCellBackgroundSelected : Palette::ListCellBackground; m_labelView.setBackgroundColor(backgroundColor); if (isHighlighted()) { m_iconView.setImage(m_focusedIcon); @@ -57,12 +57,12 @@ void Cell::setImage(const Image * image, const Image * focusedImage) { void Cell::drawRect(KDContext * ctx, KDRect rect) const { KDCoordinate width = bounds().width(); KDCoordinate height = bounds().height(); - KDColor backgroundColor = isHighlighted() ? Palette::Select : KDColorWhite; + KDColor backgroundColor = isHighlighted() ? Palette::ListCellBackgroundSelected : Palette::ListCellBackground; ctx->fillRect(KDRect(1, 1, width-2, height-1), backgroundColor); - ctx->fillRect(KDRect(0, 0, width, 1), Palette::GrayBright); - ctx->fillRect(KDRect(0, 1, 1, height-1), Palette::GrayBright); - ctx->fillRect(KDRect(width-1, 1, 1, height-1), Palette::GrayBright); - ctx->fillRect(KDRect(0, height-1, width, 1), Palette::GrayBright); + ctx->fillRect(KDRect(0, 0, width, 1), Palette::ProbabilityCellBorder); + ctx->fillRect(KDRect(0, 1, 1, height-1), Palette::ProbabilityCellBorder); + ctx->fillRect(KDRect(width-1, 1, 1, height-1), Palette::ProbabilityCellBorder); + ctx->fillRect(KDRect(0, height-1, width, 1), Palette::ProbabilityCellBorder); } } diff --git a/apps/probability/distribution_controller.cpp b/apps/probability/distribution_controller.cpp index fd244bec62b..dedbd4d2941 100644 --- a/apps/probability/distribution_controller.cpp +++ b/apps/probability/distribution_controller.cpp @@ -90,7 +90,7 @@ bool Probability::DistributionController::handleEvent(Ion::Events::Event event) if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) { StackViewController * stack = (StackViewController *)parentResponder(); setDistributionAccordingToIndex(selectedRow()); - stack->push(m_parametersController, KDColorWhite, Palette::PurpleBright, Palette::PurpleBright); + stack->push(m_parametersController, Palette::BannerFirstText, Palette::BannerFirstBackground, Palette::BannerFirstBorder); return true; } return false; diff --git a/apps/probability/distribution_controller.h b/apps/probability/distribution_controller.h index db276e2492b..78b0c7c4a21 100644 --- a/apps/probability/distribution_controller.h +++ b/apps/probability/distribution_controller.h @@ -26,7 +26,7 @@ class DistributionController : public ViewController, public SimpleListViewDataS class ContentView : public View { public: ContentView(SelectableTableView * selectableTableView) : - m_titleView(KDFont::SmallFont, I18n::Message::ChooseDistribution, 0.5f, 0.5f, Palette::GrayDark, Palette::WallScreen), + m_titleView(KDFont::SmallFont, I18n::Message::ChooseDistribution, 0.5f, 0.5f, Palette::SecondaryText, Palette::BackgroundApps), m_selectableTableView(selectableTableView) {} constexpr static KDCoordinate k_titleMargin = 8; diff --git a/apps/probability/distribution_curve_view.cpp b/apps/probability/distribution_curve_view.cpp index eb82d5a9cdb..4cf8cf4075f 100644 --- a/apps/probability/distribution_curve_view.cpp +++ b/apps/probability/distribution_curve_view.cpp @@ -29,9 +29,9 @@ void DistributionCurveView::drawRect(KDContext * ctx, KDRect rect) const { return; } if (m_distribution->isContinuous()) { - drawCartesianCurve(ctx, rect, -INFINITY, INFINITY, EvaluateXYAtAbscissa, m_distribution, nullptr, Palette::YellowDark, true, true, lowerBound, upperBound); + drawCartesianCurve(ctx, rect, -INFINITY, INFINITY, EvaluateXYAtAbscissa, m_distribution, nullptr, Palette::ProbabilityCurve, true, true, lowerBound, upperBound); } else { - drawHistogram(ctx, rect, EvaluateAtAbscissa, m_distribution, nullptr, 0, 1, false, Palette::GrayMiddle, Palette::YellowDark, lowerBound, upperBound+0.5f); + drawHistogram(ctx, rect, EvaluateAtAbscissa, m_distribution, nullptr, 0, 1, false, Palette::ProbabilityHistogramBar, Palette::ProbabilityCurve, lowerBound, upperBound+0.5f); } } @@ -59,7 +59,7 @@ void DistributionCurveView::drawStandardNormal(KDContext * ctx, KDRect rect, flo // Draw a centered reduced normal curve NormalDistribution n; constCastedThis->setCurveViewRange(&n); - drawCartesianCurve(ctx, rect, -INFINITY, INFINITY, EvaluateXYAtAbscissa, &n, nullptr, Palette::YellowDark, true, true, pixelToFloat(Axis::Horizontal, colorLowerBoundPixel), pixelToFloat(Axis::Horizontal, colorUpperBoundPixel)); + drawCartesianCurve(ctx, rect, -INFINITY, INFINITY, EvaluateXYAtAbscissa, &n, nullptr, Palette::ProbabilityCurve, true, true, pixelToFloat(Axis::Horizontal, colorLowerBoundPixel), pixelToFloat(Axis::Horizontal, colorUpperBoundPixel)); // Put back the previous curve view range constCastedThis->setCurveViewRange(previousRange); diff --git a/apps/probability/distribution_curve_view.h b/apps/probability/distribution_curve_view.h index 68af5e3c3af..e1288c3beb0 100644 --- a/apps/probability/distribution_curve_view.h +++ b/apps/probability/distribution_curve_view.h @@ -30,7 +30,7 @@ class DistributionCurveView : public Shared::CurveView { private: static float EvaluateAtAbscissa(float abscissa, void * model, void * context); static Poincare::Coordinate2D EvaluateXYAtAbscissa(float abscissa, void * model, void * context); - static constexpr KDColor k_backgroundColor = Palette::WallScreen; + static constexpr KDColor k_backgroundColor = Palette::BackgroundApps; void drawStandardNormal(KDContext * ctx, KDRect rect, float colorLowerBound, float colorUpperBound) const; char m_labels[k_maxNumberOfXLabels][k_labelBufferMaxSize]; Distribution * m_distribution; diff --git a/apps/probability/parameters_controller.cpp b/apps/probability/parameters_controller.cpp index 53e3c981821..f3372dbe079 100644 --- a/apps/probability/parameters_controller.cpp +++ b/apps/probability/parameters_controller.cpp @@ -8,16 +8,16 @@ namespace Probability { ParametersController::ContentView::ContentView(SelectableTableView * selectableTableView) : m_numberOfParameters(1), - m_titleView(KDFont::SmallFont, I18n::Message::ChooseParameters, 0.5f, 0.5f, Palette::GrayDark, Palette::WallScreen), - m_firstParameterDefinition(KDFont::SmallFont, (I18n::Message)0, 0.5f, 0.5f, KDColorBlack, Palette::WallScreen), - m_secondParameterDefinition(KDFont::SmallFont, (I18n::Message)0, 0.5f, 0.5f, KDColorBlack, Palette::WallScreen), + m_titleView(KDFont::SmallFont, I18n::Message::ChooseParameters, 0.5f, 0.5f, Palette::SecondaryText, Palette::BackgroundApps), + m_firstParameterDefinition(KDFont::SmallFont, (I18n::Message)0, 0.5f, 0.5f, Palette::PrimaryText, Palette::BackgroundApps), + m_secondParameterDefinition(KDFont::SmallFont, (I18n::Message)0, 0.5f, 0.5f, Palette::PrimaryText, Palette::BackgroundApps), m_selectableTableView(selectableTableView) { } void ParametersController::ContentView::drawRect(KDContext * ctx, KDRect rect) const { int tableHeight = m_selectableTableView->minimalSizeForOptimalDisplay().height(); - ctx->fillRect(KDRect(0, tableHeight, bounds().width(), bounds().height() - tableHeight), Palette::WallScreen); + ctx->fillRect(KDRect(0, tableHeight, bounds().width(), bounds().height() - tableHeight), Palette::BackgroundApps); } MessageTextView * ParametersController::ContentView::parameterDefinitionAtIndex(int index) { @@ -161,7 +161,7 @@ bool ParametersController::textFieldDidFinishEditing(TextField * textField, cons void ParametersController::buttonAction() { StackViewController * stack = stackController(); - stack->push(m_calculationController, KDColorWhite, Palette::SubTab, Palette::SubTab); + stack->push(m_calculationController, Palette::BannerSecondText, Palette::BannerSecondBackground, Palette::BannerSecondBorder); } } diff --git a/apps/probability/responder_image_cell.cpp b/apps/probability/responder_image_cell.cpp index 50bde318feb..f9079077ecf 100644 --- a/apps/probability/responder_image_cell.cpp +++ b/apps/probability/responder_image_cell.cpp @@ -11,8 +11,8 @@ ResponderImageCell::ResponderImageCell(Responder * parentResponder, Distribution } void ResponderImageCell::drawRect(KDContext * ctx, KDRect rect) const { - ctx->fillRect(bounds(), KDColorWhite); - ctx->strokeRect(KDRect(0, 0, ImageCell::k_width+2*k_outline, ImageCell::k_height+2*k_outline), Palette::GrayMiddle); + ctx->fillRect(bounds(), Palette::BackgroundHard); + ctx->strokeRect(KDRect(0, 0, ImageCell::k_width+2*k_outline, ImageCell::k_height+2*k_outline), Palette::ProbabilityCellBorder); } KDSize ResponderImageCell::minimalSizeForOptimalDisplay() const { diff --git a/apps/regression/app.cpp b/apps/regression/app.cpp index c81fc75969c..80069de442e 100644 --- a/apps/regression/app.cpp +++ b/apps/regression/app.cpp @@ -15,6 +15,10 @@ I18n::Message App::Descriptor::upperName() { return I18n::Message::RegressionAppCapital; } +App::Descriptor::ExaminationLevel App::Descriptor::examinationLevel() { + return App::Descriptor::ExaminationLevel::Strict; +} + const Image * App::Descriptor::icon() { return ImageStore::RegressionIcon; } diff --git a/apps/regression/app.h b/apps/regression/app.h index 140b83114ec..c7ed772867a 100644 --- a/apps/regression/app.h +++ b/apps/regression/app.h @@ -18,6 +18,7 @@ class App : public Shared::TextFieldDelegateApp { public: I18n::Message name() override; I18n::Message upperName() override; + App::Descriptor::ExaminationLevel examinationLevel() override; const Image * icon() override; }; class Snapshot : public ::SharedApp::Snapshot, public TabViewDataSource { diff --git a/apps/regression/base.hu.i18n b/apps/regression/base.hu.i18n new file mode 100644 index 00000000000..e5d37d82553 --- /dev/null +++ b/apps/regression/base.hu.i18n @@ -0,0 +1,20 @@ +RegressionApp = "Regresszió" +RegressionAppCapital = "REGRESSZIÓ" +Regression = "Regresszió" +MeanDot = "Középérték" +RegressionCurve = "Regressziós görbe" +XPrediction = "Jóslás X megadva" +YPrediction = "Jóslás Y megadva" +ValueNotReachedByRegression = "Az ablakban az érték még nem volt elérve" +NumberOfDots = "Pontok száma" +Covariance = "Kovariancia" +Linear = "Lineáris" +Proportional = "Általános" +Quadratic = "Másodfokú" +Cubic = "Kockás" +Quartic = "Kvartikus" +Logarithmic = "Logaritmikus" +Power = "Teljesítmény" +Trigonometrical = "Trigonometrikus" +Logistic = "Logisztikai" +DataNotSuitableForRegression = "Ezek az adatok nem megfelelö ehhez a regressziós modellhez" diff --git a/apps/regression/calculation_controller.cpp b/apps/regression/calculation_controller.cpp index 1beae9b8189..14b68c105ea 100644 --- a/apps/regression/calculation_controller.cpp +++ b/apps/regression/calculation_controller.cpp @@ -26,18 +26,18 @@ CalculationController::CalculationController(Responder * parentResponder, Button { m_r2Layout = HorizontalLayout::Builder(CodePointLayout::Builder('r', KDFont::SmallFont), VerticalOffsetLayout::Builder(CodePointLayout::Builder('2', KDFont::SmallFont), VerticalOffsetLayoutNode::Position::Superscript)); m_selectableTableView.setVerticalCellOverlap(0); - m_selectableTableView.setBackgroundColor(Palette::WallScreenDark); + m_selectableTableView.setBackgroundColor(Palette::BackgroundAppsSecondary); m_selectableTableView.setMargins(k_margin, k_scrollBarMargin, k_scrollBarMargin, k_margin); m_r2TitleCell.setAlignment(1.0f, 0.5f); for (int i = 0; i < Store::k_numberOfSeries; i++) { m_columnTitleCells[i].setParentResponder(&m_selectableTableView); } for (int i = 0; i < k_numberOfDoubleCalculationCells; i++) { - m_doubleCalculationCells[i].setTextColor(Palette::GrayDark); + m_doubleCalculationCells[i].setTextColor(Palette::SecondaryText); m_doubleCalculationCells[i].setParentResponder(&m_selectableTableView); } for (int i = 0; i < k_numberOfCalculationCells;i++) { - m_calculationCells[i].setTextColor(Palette::GrayDark); + m_calculationCells[i].setTextColor(Palette::SecondaryText); } for (int i = 0; i < k_maxNumberOfDisplayableRows; i++) { m_titleCells[i].setMessageFont(KDFont::SmallFont); diff --git a/apps/regression/graph_view.cpp b/apps/regression/graph_view.cpp index bcd1bb8c9f3..fb2987e1568 100644 --- a/apps/regression/graph_view.cpp +++ b/apps/regression/graph_view.cpp @@ -15,7 +15,7 @@ GraphView::GraphView(Store * store, CurveViewCursor * cursor, BannerView * banne } void GraphView::drawRect(KDContext * ctx, KDRect rect) const { - ctx->fillRect(rect, KDColorWhite); + ctx->fillRect(rect, Palette::BackgroundHard); drawGrid(ctx, rect); drawAxes(ctx, rect); simpleDrawBothAxesLabels(ctx, rect); @@ -35,7 +35,7 @@ void GraphView::drawRect(KDContext * ctx, KDRect rect) const { drawDot(ctx, rect, m_store->get(series, 0, index), m_store->get(series, 1, index), color); } drawDot(ctx, rect, m_store->meanOfColumn(series, 0), m_store->meanOfColumn(series, 1), color, Size::Small); - drawDot(ctx, rect, m_store->meanOfColumn(series, 0), m_store->meanOfColumn(series, 1), KDColorWhite); + drawDot(ctx, rect, m_store->meanOfColumn(series, 0), m_store->meanOfColumn(series, 1), Palette::BackgroundHard); } } } diff --git a/apps/regression/store_controller.cpp b/apps/regression/store_controller.cpp index 703d08d1fb6..69293bf195b 100644 --- a/apps/regression/store_controller.cpp +++ b/apps/regression/store_controller.cpp @@ -38,7 +38,7 @@ void StoreController::willDisplayCellAtLocation(HighlightCell * cell, int i, int bool isValuesColumn = i%Store::k_numberOfColumnsPerSeries == 0; mytitleCell->setSeparatorLeft(isValuesColumn && i > 0); int seriesIndex = i/Store::k_numberOfColumnsPerSeries; - mytitleCell->setColor(m_store->numberOfPairsOfSeries(seriesIndex) == 0 ? Palette::GrayDark : Store::colorOfSeriesAtIndex(seriesIndex)); // TODO Share GrayDark with graph/list_controller and statistics/store_controller + mytitleCell->setColor(m_store->numberOfPairsOfSeries(seriesIndex) == 0 ? Palette::SecondaryText : Store::colorOfSeriesAtIndex(seriesIndex)); // TODO Share GreyDark with graph/list_controller and statistics/store_controller char name[] = {isValuesColumn ? 'X' : 'Y', static_cast('1' + seriesIndex), 0}; mytitleCell->setText(name); } diff --git a/apps/rpn b/apps/rpn new file mode 160000 index 00000000000..67d66295b0a --- /dev/null +++ b/apps/rpn @@ -0,0 +1 @@ +Subproject commit 67d66295b0a5a9bc5daf52412db9ae2ac87bbf57 diff --git a/apps/sequence/app.cpp b/apps/sequence/app.cpp index 1a07b99c161..d9ccf0931fd 100644 --- a/apps/sequence/app.cpp +++ b/apps/sequence/app.cpp @@ -15,6 +15,10 @@ I18n::Message App::Descriptor::upperName() { return I18n::Message::SequenceAppCapital; } +App::Descriptor::ExaminationLevel App::Descriptor::examinationLevel() { + return App::Descriptor::ExaminationLevel::Strict; +} + const Image * App::Descriptor::icon() { return ImageStore::SequenceIcon; } diff --git a/apps/sequence/app.h b/apps/sequence/app.h index be61dd8cbf0..57b192d5f01 100644 --- a/apps/sequence/app.h +++ b/apps/sequence/app.h @@ -21,6 +21,7 @@ class App : public Shared::FunctionApp { public: I18n::Message name() override; I18n::Message upperName() override; + App::Descriptor::ExaminationLevel examinationLevel() override; const Image * icon() override; }; class Snapshot : public Shared::FunctionApp::Snapshot { diff --git a/apps/sequence/base.hu.i18n b/apps/sequence/base.hu.i18n new file mode 100644 index 00000000000..f98ed2366d8 --- /dev/null +++ b/apps/sequence/base.hu.i18n @@ -0,0 +1,22 @@ +SequenceApp = "Szekvenciák" +SequenceAppCapital = "SZEKVENCIÁK" +SequenceTab = "Szekvenciák" +AddSequence = "Szekvencia hozzáadása" +ChooseSequenceType = "Válassza ki a sorozat típusát" +SequenceType = "Szekvencia típusa" +Explicit = "Explicit kifejezés" +SingleRecurrence = "Rekurzív elsö sorrend" +DoubleRecurrence = "Rekurzív második sorrend" +SequenceOptions = "Szekvencia opciók" +SequenceColor = "Szekvencia színe" +DeleteSequence = "Sorozat törlése" +NoSequence = "Nincs sorrend" +NoActivatedSequence = "Nincs szekvencia bekapcsolva" +NStart = "N start" +NEnd = "N vég" +TermSum = "A kifejezés összege" +SelectFirstTerm = "Elsö kifejezés kiválasztása " +SelectLastTerm = "Utolsó kifejezés kiválasztása " +ValueNotReachedBySequence = "Az értéket nem érte el a sorozat" +NColumn = "n oszlop" +FirstTermIndex = "Elsö kifejezés index" diff --git a/apps/sequence/graph/graph_view.cpp b/apps/sequence/graph/graph_view.cpp index 73d18fe5ed1..3f71d92a5c8 100644 --- a/apps/sequence/graph/graph_view.cpp +++ b/apps/sequence/graph/graph_view.cpp @@ -30,7 +30,7 @@ void GraphView::drawRect(KDContext * ctx, KDRect rect) const { } drawDot(ctx, rect, x, y, s->color()); if (x >= m_highlightedStart && x <= m_highlightedEnd && record == m_selectedRecord) { - KDColor color = m_shouldColorHighlighted ? s->color() : KDColorBlack; + KDColor color = m_shouldColorHighlighted ? s->color() : Palette::PrimaryText; if (y >= 0.0f) { drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, x, 0.0f, y, color, 1); } else { diff --git a/apps/sequence/list/list_controller.cpp b/apps/sequence/list/list_controller.cpp index b19d9954770..56f78b1d348 100644 --- a/apps/sequence/list/list_controller.cpp +++ b/apps/sequence/list/list_controller.cpp @@ -15,7 +15,7 @@ ListController::ListController(Responder * parentResponder, ::InputEventHandlerD m_expressionCells{}, m_parameterController(inputEventHandlerDelegate, this), m_typeParameterController(this, this, TableCell::Layout::Vertical), - m_typeStackController(nullptr, &m_typeParameterController, KDColorWhite, Palette::PurpleDark, Palette::PurpleDark), + m_typeStackController(nullptr, &m_typeParameterController, Palette::ToolboxHeaderText, Palette::ToolboxHeaderBackground, Palette::ToolboxHeaderBorder), m_sequenceToolbox() { for (int i = 0; i < k_maxNumberOfRows; i++) { @@ -191,7 +191,7 @@ void ListController::willDisplayTitleCellAtIndex(HighlightCell * cell, int j) { myCell->setLayout(sequence->secondInitialConditionName()); } // Set the color - KDColor nameColor = sequence->isActive() ? sequence->color() : Palette::GrayDark; + KDColor nameColor = sequence->isActive() ? sequence->color() : Palette::SecondaryText; myCell->setColor(nameColor); } @@ -209,7 +209,7 @@ void ListController::willDisplayExpressionCellAtIndex(HighlightCell * cell, int myCell->setLayout(sequence->secondInitialConditionLayout()); } bool active = sequence->isActive(); - KDColor textColor = active ? KDColorBlack : Palette::GrayDark; + KDColor textColor = active ? Palette::PrimaryText : Palette::SecondaryText; myCell->setTextColor(textColor); } diff --git a/apps/settings/Makefile b/apps/settings/Makefile index 0d38a7d188d..588b95c2f1c 100644 --- a/apps/settings/Makefile +++ b/apps/settings/Makefile @@ -10,18 +10,24 @@ app_settings_src = $(addprefix apps/settings/,\ main_controller_prompt_none.cpp:-update \ main_controller_prompt_update.cpp:+update \ sub_menu/about_controller.cpp \ + sub_menu/accessibility_controller.cpp \ sub_menu/about_controller_official.cpp:+official \ sub_menu/about_controller_non_official.cpp:-official \ - sub_menu/display_mode_controller.cpp \ sub_menu/exam_mode_controller_official.cpp:+official \ sub_menu/exam_mode_controller_non_official.cpp:-official \ + sub_menu/datetime_controller.cpp \ + sub_menu/display_mode_controller.cpp \ sub_menu/exam_mode_controller.cpp \ sub_menu/generic_sub_controller.cpp \ sub_menu/localization_controller.cpp \ sub_menu/preferences_controller.cpp \ + sub_menu/contributors_controller.cpp \ + sub_menu/math_options_controller.cpp \ sub_menu/selectable_view_with_messages.cpp \ ) +SFLAGS += -DOMEGA_STATE="$(OMEGA_STATE)" + app_settings_src += $(app_settings_test_src) apps_src += $(app_settings_src) diff --git a/apps/settings/app.cpp b/apps/settings/app.cpp index 36bb89d0082..7e341c3f5a1 100644 --- a/apps/settings/app.cpp +++ b/apps/settings/app.cpp @@ -12,6 +12,10 @@ I18n::Message App::Descriptor::upperName() { return I18n::Message::SettingsAppCapital; } +App::Descriptor::ExaminationLevel App::Descriptor::examinationLevel() { + return App::Descriptor::ExaminationLevel::Strict; +} + const Image * App::Descriptor::icon() { return ImageStore::SettingsIcon; } diff --git a/apps/settings/app.h b/apps/settings/app.h index 72967b40b7c..f67e758967a 100644 --- a/apps/settings/app.h +++ b/apps/settings/app.h @@ -3,7 +3,6 @@ #include "main_controller.h" #include "../shared/text_field_delegate_app.h" -#include "../shared/shared_app.h" namespace Settings { @@ -13,9 +12,10 @@ class App : public Shared::TextFieldDelegateApp { public: I18n::Message name() override; I18n::Message upperName() override; + App::Descriptor::ExaminationLevel examinationLevel() override; const Image * icon() override; }; - class Snapshot : public ::SharedApp::Snapshot { + class Snapshot : public ::App::Snapshot { public: App * unpack(Container * container) override; Descriptor * descriptor() override; diff --git a/apps/settings/base.de.i18n b/apps/settings/base.de.i18n index 679dcf2f13a..0f469929be3 100644 --- a/apps/settings/base.de.i18n +++ b/apps/settings/base.de.i18n @@ -14,7 +14,7 @@ ToDeactivateExamMode3 = "Computer oder eine Steckdose an." # --------------------- Please do not edit these messages --------------------- ExamModeWarning1 = "Caution: compliance of this" ExamModeWarning2 = "unofficial software's exam mode" -ExamModeWarning3 = "is not guaranteed by NumWorks." +ExamModeWarning3 = "is not guaranteed by NumWorks/Omega." AboutWarning1 = "Caution: you're using an" AboutWarning2 = "unofficial software version." AboutWarning3 = "NumWorks can't be held responsible" @@ -32,10 +32,39 @@ Real = "Reell " Cartesian = "Kartesisch " Polar = "Polar " Brightness = "Helligkeit" +SoftwareVersion = "Epsilon version" +OmegaVersion = "Omega version" +Username = "Name" +MicroPythonVersion = "µPythonversion" FontSizes = "Python-Schriftgröße" LargeFont = "Große " SmallFont = "Kleine " -SoftwareVersion = "Softwareversion" SerialNumber = "Seriennummer" UpdatePopUp = "Erinnerung: Update" BetaPopUp = "Beta pop-up" +Contributors = "Beiträger" +Accessibility = "Barrierefreiheit" +AccessibilityInvertColors = "Farbumkehrung" +AccessibilityMagnify = "Lupe" +AccessibilityGamma = "Gammakorrektur" +AccessibilityGammaRed = "Rotes Gamma" +AccessibilityGammaGreen = "Grünes Gamma" +AccessibilityGammaBlue = "Blaues Gamma" +MathOptions = "Berechnungseinstellungen" +SymbolMultiplication = "Multiplikation" +SymbolMultiplicationCross = "Kreuz " +SymbolMultiplicationMiddleDot = "Mittelpunkt " +SymbolMultiplicationStar = "Stern " +SymbolMultiplicationAutoSymbol = "automatisch " +SymbolFunction = "Ausdrucksformat " +SymbolDefaultFunction = "Standardl " +SymbolArgFunction = "Leer " +SymbolArgDefaultFunction = "Argument " +PythonFont = "Python Schriftart" +MemUse = "Speicher" +DateTime = "Date/time" +ActivateClock = "Activate clock" +Date = "Date" +Time = "Time" +RTCWarning1 = "Enabling the clock drains the battery faster" +RTCWarning2 = "when the calculator is powered off." diff --git a/apps/settings/base.en.i18n b/apps/settings/base.en.i18n index f7ea577dbf6..b5d07690485 100644 --- a/apps/settings/base.en.i18n +++ b/apps/settings/base.en.i18n @@ -14,7 +14,7 @@ ToDeactivateExamMode3 = "or to a power socket." # --------------------- Please do not edit these messages --------------------- ExamModeWarning1 = "Caution: compliance of this" ExamModeWarning2 = "unofficial software's exam mode" -ExamModeWarning3 = "is not guaranteed by NumWorks." +ExamModeWarning3 = "is not guaranteed by NumWorks/Omega." AboutWarning1 = "Caution: you're using an" AboutWarning2 = "unofficial software version." AboutWarning3 = "NumWorks can't be held responsible" @@ -32,10 +32,39 @@ Real = "Real " Cartesian = "Cartesian " Polar = "Polar " Brightness = "Brightness" +SoftwareVersion = "Epsilon version" +OmegaVersion = "Omega version" +Username = "Name" +MicroPythonVersion = "µPython version" FontSizes = "Python font size" LargeFont = "Large " SmallFont = "Small " -SoftwareVersion = "Software version" SerialNumber = "Serial number" UpdatePopUp = "Update pop-up" BetaPopUp = "Beta pop-up" +Contributors = "Contributors" +Accessibility = "Accessibility" +AccessibilityInvertColors = "Invert colors" +AccessibilityMagnify = "Magnify" +AccessibilityGamma = "Gamma correction" +AccessibilityGammaRed = "Red gamma" +AccessibilityGammaGreen = "Green gamma" +AccessibilityGammaBlue = "Blue gamma" +MathOptions = "Math options" +SymbolMultiplication = "Multiply" +SymbolMultiplicationCross = "Cross " +SymbolMultiplicationMiddleDot = "Dot " +SymbolMultiplicationStar = "Star " +SymbolMultiplicationAutoSymbol = "Auto " +SymbolFunction = "Expression format " +SymbolDefaultFunction = "Default " +SymbolArgFunction = "Empty " +SymbolArgDefaultFunction = "Argument " +PythonFont = "Python Font" +MemUse = "Memory" +DateTime = "Date/time" +ActivateClock = "Activate clock" +Date = "Date" +Time = "Time" +RTCWarning1 = "Enabling the clock drains the battery faster" +RTCWarning2 = "when the calculator is powered off." diff --git a/apps/settings/base.es.i18n b/apps/settings/base.es.i18n index d662cf31e48..944709570f0 100644 --- a/apps/settings/base.es.i18n +++ b/apps/settings/base.es.i18n @@ -14,7 +14,7 @@ ToDeactivateExamMode3 = "o a un enchufe eléctrico." # --------------------- Please do not edit these messages --------------------- ExamModeWarning1 = "Caution: compliance of this" ExamModeWarning2 = "unofficial software's exam mode" -ExamModeWarning3 = "is not guaranteed by NumWorks." +ExamModeWarning3 = "is not guaranteed by NumWorks/Omega." AboutWarning1 = "Caution: you're using an" AboutWarning2 = "unofficial software version." AboutWarning3 = "NumWorks can't be held responsible" @@ -32,10 +32,39 @@ Real = "Real " Cartesian = "Binómica " Polar = "Polar " Brightness = "Brillo" +SoftwareVersion = "Versión de Epsilon" +OmegaVersion = "Versión de Omega" +Username = "Apellido" +MicroPythonVersion = "Version de µPython" FontSizes = "Tipografía Python" LargeFont = "Grande " SmallFont = "Pequeño " -SoftwareVersion = "Versión de software" SerialNumber = "Número serie" UpdatePopUp = "Pop-up de actualización" BetaPopUp = "Beta pop-up" +Contributors = "Contribuyentes" +Accessibility = "Accesibilidad" +AccessibilityInvertColors = "Colores invertidos" +AccessibilityMagnify = "Lupa" +AccessibilityGamma = "Corrección gamma" +AccessibilityGammaRed = "Gamma roja" +AccessibilityGammaGreen = "Gamma verde" +AccessibilityGammaBlue = "Gamma azul" +MathOptions = "Matemáticas" +SymbolMultiplication = "Multiplicación" +SymbolMultiplicationCross = "Contrariar " +SymbolMultiplicationMiddleDot = "Punto " +SymbolMultiplicationStar = "Estrella " +SymbolMultiplicationAutoSymbol = "Auto " +SymbolFunction = "Formato expresión " +SymbolDefaultFunction = "Defecto " +SymbolArgFunction = "Vacío " +SymbolArgDefaultFunction = "Argumento " +PythonFont = "Fuente Python" +MemUse = "Memoria" +DateTime = "Fecha/Hora" +ActivateClock = "Activar el reloj" +Date = "Fecha" +Time = "Hora" +RTCWarning1 = "Activar el reloj gasta la batería más rápido" +RTCWarning2 = "cuando la calculadora está apagada." diff --git a/apps/settings/base.fr.i18n b/apps/settings/base.fr.i18n index 6d1f831f667..ac76c7dca0d 100644 --- a/apps/settings/base.fr.i18n +++ b/apps/settings/base.fr.i18n @@ -14,7 +14,7 @@ ToDeactivateExamMode3 = "ordinateur ou à une prise de courant." # --------------------- Please do not edit these messages --------------------- ExamModeWarning1 = "Attention, la conformité du mode" ExamModeWarning2 = "examen de ce logiciel non officiel" -ExamModeWarning3 = "n'est pas garantie par NumWorks." +ExamModeWarning3 = "n'est pas garantie par NumWorks/Omega." AboutWarning1 = "Attention, vous utilisez une version" AboutWarning2 = "non officielle du logiciel. NumWorks" AboutWarning3 = "ne saurait être tenu responsable des" @@ -32,10 +32,39 @@ Real = "Réel " Cartesian = "Algébrique " Polar = "Exponentielle " Brightness = "Luminosité" +SoftwareVersion = "Version d'Epsilon" +OmegaVersion = "Version d'Omega" +Username = "Nom" +MicroPythonVersion = "Version de µPython" FontSizes = "Police Python" LargeFont = "Grande " SmallFont = "Petite " -SoftwareVersion = "Version du logiciel" SerialNumber = "Numéro de série" UpdatePopUp = "Rappel de mise à jour" BetaPopUp = "Rappel de version bêta" +Contributors = "Contributeurs" +Accessibility = "Accessibilité" +AccessibilityInvertColors = "Inverser couleurs" +AccessibilityMagnify = "Loupe" +AccessibilityGamma = "Correction gamma" +AccessibilityGammaRed = "Gamma rouge" +AccessibilityGammaGreen = "Gamma vert" +AccessibilityGammaBlue = "Gamma bleu" +MathOptions = "Math" +SymbolMultiplication = "Multiplication" +SymbolMultiplicationCross = "Croix " +SymbolMultiplicationMiddleDot = "Point " +SymbolMultiplicationStar = "Etoile " +SymbolMultiplicationAutoSymbol = "Automatique " +SymbolFunction = "Format expression " +SymbolDefaultFunction = "Défaut " +SymbolArgFunction = "Vide " +SymbolArgDefaultFunction = "Arguments " +PythonFont = "Police Python" +MemUse = "Mémoire" +DateTime = "Date/heure" +ActivateClock = "Activer horloge" +Date = "Date" +Time = "Heure" +RTCWarning1 = "Activer l'horloge décharge la batterie plus" +RTCWarning2 = "vite quand la calculatrice est éteinte." diff --git a/apps/settings/base.hu.i18n b/apps/settings/base.hu.i18n new file mode 100644 index 00000000000..19ed3a67f63 --- /dev/null +++ b/apps/settings/base.hu.i18n @@ -0,0 +1,70 @@ +SettingsApp = "Beállítások" +SettingsAppCapital = "BEÁLLÍTÁSOK" +AngleUnit = "Szögmérö" +DisplayMode = "Eredmény formátuma" +EditionMode = "Írás formátuma" +EditionLinear = "Lineáris" +Edition2D = "Természetes" +ComplexFormat = "Komplex formátum" +ExamMode = "Vizsga mód" +ExamModeActive = "A vizsgamód újraaktiválása" +ToDeactivateExamMode1 = "a vizsga mód kikapcsoláshoz" +ToDeactivateExamMode2 = "csatlakoztassa a számológépet a számítógéphez" +ToDeactivateExamMode3 = "vagy egy konnektorhoz." +# --------------------- Please do not edit these messages --------------------- +ExamModeWarning1 = "Vigyázat: a használt szoftver nem" +ExamModeWarning2 = "hivatalos, Numworks nem garantálja" +ExamModeWarning3 = "a vizsgálati mód megfelelőségét." +AboutWarning1 = "Vigyázat: a használt szoftver" +AboutWarning2 = "nem hivatalos. A NumWorks nem" +AboutWarning3 = "vállal felelösséget az" +AboutWarning4 = "esetleges károkért." +# ----------------------------------------------------------------------------- +About = "Apropó" +Degrees = "Fokok " +Gradians = "Gradiens " +Radian = "Radián " +Decimal = "Tizedes " +Scientific = "Tudományos " +Engineering = "Mérnökség " +SignificantFigures = "Tizedes számok " +Real = "Valódi " +Cartesian = "Kartéziánus " +Polar = "Poláris " +Brightness = "Fényerö" +SoftwareVersion = "Epsilon verzió" +OmegaVersion = "Omega verzió" +Username = "Felhasználónév" +MicroPythonVersion = "µPython verzió" +FontSizes = "Python betü méret" +LargeFont = "Nagy " +SmallFont = "Kicsi " +SerialNumber = "Sorozatszám" +UpdatePopUp = "Frissítés figyelmeztetés" +BetaPopUp = "Béta figyelmeztetés" +Contributors = "Közremüködök" +Accessibility = "Több vizuális beállitások" +AccessibilityInvertColors = "Invertált színek" +AccessibilityMagnify = "Nagyító" +AccessibilityGamma = "Gamma korrekció" +AccessibilityGammaRed = "Piros gamma" +AccessibilityGammaGreen = "Zöld gamma" +AccessibilityGammaBlue = "Kék gamma" +MathOptions = "Matematikai beállítások" +SymbolMultiplication = "Szorzás" +SymbolMultiplicationCross = "Kereszt " +SymbolMultiplicationMiddleDot = "Pont " +SymbolMultiplicationStar = "Csillag " +SymbolMultiplicationAutoSymbol = "Automatitus " +SymbolFunction = "Kifejezés " +SymbolDefaultFunction = "Alap " +SymbolArgFunction = "Üres " +SymbolArgDefaultFunction = "Argumentummal " +PythonFont = "Python Betütipus" +MemUse = "Memória" +DateTime = "Dátum/óra" +ActivateClock = "Óra bekapcsolása" +Date = "Datum" +Time = "Óra" +RTCWarning1 = "Amikor a számológép alvómódban van, az óra" +RTCWarning2 = "használása az elemet gyorsabban meríti ki." diff --git a/apps/settings/base.it.i18n b/apps/settings/base.it.i18n index e21e01ecac2..5c4dcc0a47c 100644 --- a/apps/settings/base.it.i18n +++ b/apps/settings/base.it.i18n @@ -14,7 +14,7 @@ ToDeactivateExamMode3 = "computer o a una presa di corrente." # --------------------- Please do not edit these messages --------------------- ExamModeWarning1 = "Attenzione, la conformità della modalità" ExamModeWarning2 = "esame di questo software non ufficiale" -ExamModeWarning3 = "non è garantita da NumWorks." +ExamModeWarning3 = "non è garantita da NumWorks/Omega." AboutWarning1 = "Attenzione, voi utilizzate una versione" AboutWarning2 = "non ufficiale del software. NumWorks" AboutWarning3 = "non potrà essere ritenuto responsabile dei" @@ -32,10 +32,39 @@ Real = "Reale " Cartesian = "Algebrico " Polar = "Esponenziale " Brightness = "Luminosità" +SoftwareVersion = "Epsilon version" +OmegaVersion = "Omega version" +Username = "Name" +MicroPythonVersion = "µPython version" FontSizes = "Carattere Python" LargeFont = "Grande " SmallFont = "Piccolo " -SoftwareVersion = "Versione software" SerialNumber = "Numero di serie" UpdatePopUp = "Promemoria aggiornamento" BetaPopUp = "Promemoria beta" +Contributors = "Contributors" +Accessibility = "Accessibility" +AccessibilityInvertColors = "Invert colors" +AccessibilityMagnify = "Magnify" +AccessibilityGamma = "Gamma correction" +AccessibilityGammaRed = "Red gamma" +AccessibilityGammaGreen = "Green gamma" +AccessibilityGammaBlue = "Blue gamma" +MathOptions = "Math options" +SymbolMultiplication = "Multiply" +SymbolMultiplicationCross = "Cross " +SymbolMultiplicationMiddleDot = "Dot " +SymbolMultiplicationStar = "Star " +SymbolMultiplicationAutoSymbol = "Auto " +SymbolFunction = "Expression format " +SymbolDefaultFunction = "Default " +SymbolArgFunction = "Empty " +SymbolArgDefaultFunction = "Argument " +PythonFont = "Python Font" +MemUse = "Memory" +DateTime = "Date/time" +ActivateClock = "Activate clock" +Date = "Date" +Time = "Time" +RTCWarning1 = "Enabling the clock drains the battery faster" +RTCWarning2 = "when the calculator is powered off." diff --git a/apps/settings/base.nl.i18n b/apps/settings/base.nl.i18n index 3c6e2752406..75939d6a877 100644 --- a/apps/settings/base.nl.i18n +++ b/apps/settings/base.nl.i18n @@ -1,7 +1,7 @@ SettingsApp = "Instellingen" SettingsAppCapital = "INSTELLINGEN" AngleUnit = "Hoekmaat" -DisplayMode = "Resultaatformaat" +DisplayMode = "Resultaat formaat" EditionMode = "Schrijfformaat" EditionLinear = "Lineair " Edition2D = "Natuurlijk " @@ -14,7 +14,7 @@ ToDeactivateExamMode3 = "een computer of stopcontact." # --------------------- Please do not edit these messages - Discuss with Leo (remove this later) --------------------- ExamModeWarning1 = "Let op: naleving van de examenstand" ExamModeWarning2 = "op deze onofficiële software wordt" -ExamModeWarning3 = "door NumWorks niet gegarandeerd." +ExamModeWarning3 = "door NumWorks/Omega niet gegarandeerd." AboutWarning1 = "Let op: je gebruikt een" AboutWarning2 = "onofficiële softwareversie." AboutWarning3 = "NumWorks is niet verantwoordelijk" @@ -32,10 +32,39 @@ Real = "Reëel " Cartesian = "Cartesisch " Polar = "Polair " Brightness = "Helderheid" +SoftwareVersion = "Epsilon version" +OmegaVersion = "Omega version" +Username = "Name" +MicroPythonVersion = "µPython version" FontSizes = "Python lettergrootte" LargeFont = "Groot " SmallFont = "Klein " -SoftwareVersion = "Softwareversie" SerialNumber = "Serienummer" UpdatePopUp = "Update pop-up" BetaPopUp = "Bèta pop-up" +Contributors = "Contributors" +Accessibility = "Accessibility" +AccessibilityInvertColors = "Invert colors" +AccessibilityMagnify = "Magnify" +AccessibilityGamma = "Gamma correction" +AccessibilityGammaRed = "Red gamma" +AccessibilityGammaGreen = "Green gamma" +AccessibilityGammaBlue = "Blue gamma" +MathOptions = "Math options" +SymbolMultiplication = "Multiply" +SymbolMultiplicationCross = "Cross " +SymbolMultiplicationMiddleDot = "Dot " +SymbolMultiplicationStar = "Star " +SymbolMultiplicationAutoSymbol = "Auto " +SymbolFunction = "Expression format " +SymbolDefaultFunction = "Default " +SymbolArgFunction = "Empty " +SymbolArgDefaultFunction = "Argument " +PythonFont = "Python Font" +MemUse = "Memory" +DateTime = "Date/time" +ActivateClock = "Activate clock" +Date = "Date" +Time = "Time" +RTCWarning1 = "Enabling the clock drains the battery faster" +RTCWarning2 = "when the calculator is powered off." diff --git a/apps/settings/base.pt.i18n b/apps/settings/base.pt.i18n index 5117db5761e..f33006f4ad6 100644 --- a/apps/settings/base.pt.i18n +++ b/apps/settings/base.pt.i18n @@ -14,7 +14,7 @@ ToDeactivateExamMode3 = "ou a uma tomada elétrica." # --------------------- Please do not edit these messages --------------------- ExamModeWarning1 = "Cuidado: o software que está a utilizar" ExamModeWarning2 = "não é oficial. A sua conformidade com o" -ExamModeWarning3 = "Modo de Exame não é garantida pela NumWorks." +ExamModeWarning3 = "Modo de Exame não é garantida pela NumWorks/Omega." AboutWarning1 = "Cuidado: está a usar uma" AboutWarning2 = "versão não oficial do software." AboutWarning3 = "A NumWorks não pode ser responsável" @@ -32,10 +32,39 @@ Real = "Real " Cartesian = "Cartesiana " Polar = "Polar " Brightness = "Brilho" +SoftwareVersion = "Versão do Epsilon" +OmegaVersion = "Versão do Omega" +Username = "Nome" +MicroPythonVersion = "Versao do µPython" FontSizes = "Tipografia Python" LargeFont = "Grande " SmallFont = "Pequeno " -SoftwareVersion = "Versão do software" SerialNumber = "Número serie" UpdatePopUp = "Alertas de atualização" BetaPopUp = "Beta pop-up" +Contributors = "Contribuidores" +Accessibility = "Acessibilidade" +AccessibilityInvertColors = "Cores invertidas" +AccessibilityMagnify = "Lupa" +AccessibilityGamma = "Correção gama" +AccessibilityGammaRed = "Gama vermelha" +AccessibilityGammaGreen = "Gama verde" +AccessibilityGammaBlue = "Gama azul" +MathOptions = "Matemática" +SymbolMultiplication = "Multiplicação" +SymbolMultiplicationCross = "crómio " +SymbolMultiplicationMiddleDot = "ponto médio " +SymbolMultiplicationStar = "estrela " +SymbolMultiplicationAutoSymbol = "automático " +SymbolFunction = "Formato expressão " +SymbolDefaultFunction = "Padrão " +SymbolArgFunction = "Vazio " +SymbolArgDefaultFunction = "Argumento " +PythonFont = "Fonte Python" +MemUse = "Memória" +DateTime = "Date/time" +ActivateClock = "Activate clock" +Date = "Date" +Time = "Time" +RTCWarning1 = "Enabling the clock drains the battery faster" +RTCWarning2 = "when the calculator is powered off." diff --git a/apps/settings/cell_with_separator.cpp b/apps/settings/cell_with_separator.cpp index 7f421ce2895..8e8bb17b82d 100644 --- a/apps/settings/cell_with_separator.cpp +++ b/apps/settings/cell_with_separator.cpp @@ -8,7 +8,7 @@ void CellWithSeparator::setHighlighted(bool highlight) { } void CellWithSeparator::drawRect(KDContext * ctx, KDRect rect) const { - ctx->fillRect(KDRect(0, Metric::CellSeparatorThickness, bounds().width(), k_margin), Palette::WallScreen); + ctx->fillRect(KDRect(0, Metric::CellSeparatorThickness, bounds().width(), k_margin), Palette::BackgroundApps); } int CellWithSeparator::numberOfSubviews() const { diff --git a/apps/settings/main_controller.cpp b/apps/settings/main_controller.cpp index 2c6b8069803..6b65f15d3ea 100644 --- a/apps/settings/main_controller.cpp +++ b/apps/settings/main_controller.cpp @@ -2,6 +2,7 @@ #include "../global_preferences.h" #include #include +#include using namespace Poincare; using namespace Shared; @@ -12,19 +13,27 @@ constexpr SettingsMessageTree s_modelAngleChildren[3] = {SettingsMessageTree(I18 constexpr SettingsMessageTree s_modelEditionModeChildren[2] = {SettingsMessageTree(I18n::Message::Edition2D), SettingsMessageTree(I18n::Message::EditionLinear)}; constexpr SettingsMessageTree s_modelFloatDisplayModeChildren[4] = {SettingsMessageTree(I18n::Message::Decimal), SettingsMessageTree(I18n::Message::Scientific), SettingsMessageTree(I18n::Message::Engineering), SettingsMessageTree(I18n::Message::SignificantFigures)}; constexpr SettingsMessageTree s_modelComplexFormatChildren[3] = {SettingsMessageTree(I18n::Message::Real), SettingsMessageTree(I18n::Message::Cartesian), SettingsMessageTree(I18n::Message::Polar)}; +constexpr SettingsMessageTree s_modelDateTimeChildren[3] = {SettingsMessageTree(I18n::Message::ActivateClock), SettingsMessageTree(I18n::Message::Date), SettingsMessageTree(I18n::Message::Time)}; +constexpr SettingsMessageTree s_symbolChildren[4] = {SettingsMessageTree(I18n::Message::SymbolMultiplicationCross),SettingsMessageTree(I18n::Message::SymbolMultiplicationMiddleDot),SettingsMessageTree(I18n::Message::SymbolMultiplicationStar),SettingsMessageTree(I18n::Message::SymbolMultiplicationAutoSymbol)}; +constexpr SettingsMessageTree s_symbolFunctionChildren[3] = {SettingsMessageTree(I18n::Message::SymbolDefaultFunction), SettingsMessageTree(I18n::Message::SymbolArgDefaultFunction), SettingsMessageTree(I18n::Message::SymbolArgFunction)}; +constexpr SettingsMessageTree s_modelMathOptionsChildren[6] = {SettingsMessageTree(I18n::Message::AngleUnit, s_modelAngleChildren), SettingsMessageTree(I18n::Message::DisplayMode, s_modelFloatDisplayModeChildren), SettingsMessageTree(I18n::Message::EditionMode, s_modelEditionModeChildren), SettingsMessageTree(I18n::Message::SymbolFunction, s_symbolFunctionChildren), SettingsMessageTree(I18n::Message::ComplexFormat, s_modelComplexFormatChildren), SettingsMessageTree(I18n::Message::SymbolMultiplication, s_symbolChildren)}; constexpr SettingsMessageTree s_modelFontChildren[2] = {SettingsMessageTree(I18n::Message::LargeFont), SettingsMessageTree(I18n::Message::SmallFont)}; -constexpr SettingsMessageTree s_modelAboutChildren[3] = {SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId)}; +constexpr SettingsMessageTree s_accessibilityChildren[6] = {SettingsMessageTree(I18n::Message::AccessibilityInvertColors), SettingsMessageTree(I18n::Message::AccessibilityMagnify),SettingsMessageTree(I18n::Message::AccessibilityGamma),SettingsMessageTree(I18n::Message::AccessibilityGammaRed),SettingsMessageTree(I18n::Message::AccessibilityGammaGreen),SettingsMessageTree(I18n::Message::AccessibilityGammaBlue)}; +constexpr SettingsMessageTree s_contributorsChildren[23] = {SettingsMessageTree(I18n::Message::Developers), SettingsMessageTree(I18n::Message::QuentinGuidee), SettingsMessageTree(I18n::Message::JoachimLeFournis), SettingsMessageTree(I18n::Message::MaximeFriess), SettingsMessageTree(I18n::Message::JeanBaptisteBoric), SettingsMessageTree(I18n::Message::SandraSimmons), SettingsMessageTree(I18n::Message::David), SettingsMessageTree(I18n::Message::DamienNicolet), SettingsMessageTree(I18n::Message::EvannDreumont), SettingsMessageTree(I18n::Message::SzaboLevente), SettingsMessageTree(I18n::Message::VenceslasDuet), SettingsMessageTree(I18n::Message::CharlotteThomas), SettingsMessageTree(I18n::Message::AntoninLoubiere), SettingsMessageTree(I18n::Message::CyprienMejat), SettingsMessageTree(I18n::Message::BetaTesters), SettingsMessageTree(I18n::Message::TimeoArnouts), SettingsMessageTree(I18n::Message::JulieC), SettingsMessageTree(I18n::Message::LelahelHideux), SettingsMessageTree(I18n::Message::Madil), SettingsMessageTree(I18n::Message::HilaireLeRoux), SettingsMessageTree(I18n::Message::HectorNussbaumer), SettingsMessageTree(I18n::Message::RaphaelDyda), SettingsMessageTree(I18n::Message::ThibautC)}; +constexpr SettingsMessageTree s_modelAboutChildren[8] = {SettingsMessageTree(I18n::Message::Username), SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::OmegaVersion), SettingsMessageTree(I18n::Message::MicroPythonVersion), SettingsMessageTree(I18n::Message::MemUse), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren)}; MainController::MainController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate) : ViewController(parentResponder), m_brightnessCell(I18n::Message::Default, KDFont::LargeFont), m_popUpCell(I18n::Message::Default, KDFont::LargeFont), m_selectableTableView(this), - m_preferencesController(this), - m_displayModeController(this, inputEventHandlerDelegate), + m_mathOptionsController(this, inputEventHandlerDelegate), m_localizationController(this, Metric::CommonTopMargin, LocalizationController::Mode::Language), + m_accessibilityController(this), + m_dateTimeController(this), m_examModeController(this), - m_aboutController(this) + m_aboutController(this), + m_preferencesController(this) { for (int i = 0; i < k_numberOfSimpleChevronCells; i++) { m_cells[i].setMessageFont(KDFont::LargeFont); @@ -44,64 +53,64 @@ void MainController::didBecomeFirstResponder() { bool MainController::handleEvent(Ion::Events::Event event) { GlobalPreferences * globalPreferences = GlobalPreferences::sharedGlobalPreferences(); - int rowIndex = selectedRow(); - - if (hasPrompt() && rowIndex == k_indexOfPopUpCell) { - if (event == Ion::Events::OK || event == Ion::Events::EXE) { - globalPreferences->setShowPopUp(!globalPreferences->showPopUp()); - m_selectableTableView.reloadCellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()); - return true; - } - return false; - } - - if (rowIndex == k_indexOfBrightnessCell - && (event == Ion::Events::Left || event == Ion::Events::Right || event == Ion::Events::Minus || event == Ion::Events::Plus)) { + if (event == Ion::Events::BrightnessPlus || event == Ion::Events::BrightnessMinus){ int delta = Ion::Backlight::MaxBrightness/GlobalPreferences::NumberOfBrightnessStates; - int direction = (event == Ion::Events::Right || event == Ion::Events::Plus) ? delta : -delta; - globalPreferences->setBrightnessLevel(globalPreferences->brightnessLevel()+direction); - m_selectableTableView.reloadCellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()); + int direction = (event == Ion::Events::BrightnessPlus) ? Ion::Backlight::NumberOfStepsPerShortcut*delta : -delta*Ion::Backlight::NumberOfStepsPerShortcut; + GlobalPreferences::sharedGlobalPreferences()->setBrightnessLevel(GlobalPreferences::sharedGlobalPreferences()->brightnessLevel()+direction); + m_selectableTableView.reloadCellAtLocation(m_selectableTableView.selectedColumn(), 1); return true; } - - if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) { - if (rowIndex == k_indexOfBrightnessCell) { - /* Nothing is supposed to happen when OK or EXE are pressed on the - * brightness cell. The case of pressing Right has been handled above. */ - return true; + if (model()->childAtIndex(selectedRow())->numberOfChildren() == 0) { + if (model()->childAtIndex(selectedRow())->label() == promptMessage()) { + if (event == Ion::Events::OK || event == Ion::Events::EXE) { + globalPreferences->setShowPopUp(!globalPreferences->showPopUp()); + m_selectableTableView.reloadCellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()); + return true; + } + return false; } - - if (rowIndex == k_indexOfLanguageCell) { - m_localizationController.setMode(LocalizationController::Mode::Language); - } else if (rowIndex == k_indexOfCountryCell) { - m_localizationController.setMode(LocalizationController::Mode::Country); + if (model()->childAtIndex(selectedRow())->label() == I18n::Message::Brightness) { + if (event == Ion::Events::Right || event == Ion::Events::Left || event == Ion::Events::Plus || event == Ion::Events::Minus) { + int delta = Ion::Backlight::MaxBrightness/GlobalPreferences::NumberOfBrightnessStates; + int direction = (event == Ion::Events::Right || event == Ion::Events::Plus) ? delta : -delta; + globalPreferences->setBrightnessLevel(globalPreferences->brightnessLevel()+direction); + m_selectableTableView.reloadCellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()); + return true; + } + return false; + } + if (model()->childAtIndex(selectedRow())->label() == I18n::Message::Language || model()->childAtIndex(selectedRow())->label() == I18n::Message::Country) { + if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) { + m_localizationController.setMode(model()->childAtIndex(selectedRow())->label() == I18n::Message::Language ? LocalizationController::Mode::Language : LocalizationController::Mode::Country); + stackController()->push(&m_localizationController); + return true; + } + return false; } - /* The About cell can either be found at index k_indexOfExamModeCell + 1 or - * k_indexOfExamModeCell + 2, depending on whether there is a Pop-Up cell. - * Since the Pop-Up cell has been handled above, we can use those two - * indices for the About cell. */ - ViewController * subControllers[k_indexOfAboutCell + 2] = { - &m_preferencesController, - &m_displayModeController, - &m_preferencesController, - &m_preferencesController, - nullptr, //&m_brightnessController - &m_preferencesController, - &m_localizationController, - &m_localizationController, - &m_examModeController, - &m_aboutController, - &m_aboutController - }; - ViewController * selectedSubController = subControllers[rowIndex]; - assert(selectedSubController); - if (model()->childAtIndex(rowIndex)->numberOfChildren() != 0) { - static_cast(selectedSubController)->setMessageTreeModel(model()->childAtIndex(rowIndex)); + } + if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) { + GenericSubController * subController = nullptr; + I18n::Message title = model()->childAtIndex(selectedRow())->label(); + if (title == I18n::Message::Brightness || title == I18n::Message::Language) { + assert(false); + } else if (title == I18n::Message::ExamMode) { + subController = &m_examModeController; + } else if (title == I18n::Message::About) { + subController = &m_aboutController; + } else if (title == I18n::Message::Accessibility) { + subController = &m_accessibilityController; + } else if (title == I18n::Message::DateTime) { + subController = &m_dateTimeController; + } else if (title == I18n::Message::MathOptions) { + subController = &m_mathOptionsController; + } else { + subController = &m_preferencesController; } - stackController()->push(selectedSubController); + subController->setMessageTreeModel(model()->childAtIndex(selectedRow())); + StackViewController * stack = stackController(); + stack->push(subController); return true; } - return false; } @@ -110,7 +119,7 @@ int MainController::numberOfRows() const { }; KDCoordinate MainController::rowHeight(int j) { - if (j == k_indexOfBrightnessCell) { + if (model()->childAtIndex(j)->label() == I18n::Message::Brightness) { return Metric::ParameterCellHeight + CellWithSeparator::k_margin; } return Metric::ParameterCellHeight; @@ -153,10 +162,10 @@ int MainController::reusableCellCount(int type) { } int MainController::typeAtLocation(int i, int j) { - if (j == k_indexOfBrightnessCell) { + if (model()->childAtIndex(j)->label() == I18n::Message::Brightness) { return 1; } - if (hasPrompt() && j == k_indexOfPopUpCell) { + if (model()->childAtIndex(j)->label() == I18n::Message::UpdatePopUp || model()->childAtIndex(j)->label() == I18n::Message::BetaPopUp) { return 2; } return 0; @@ -164,9 +173,8 @@ int MainController::typeAtLocation(int i, int j) { void MainController::willDisplayCellForIndex(HighlightCell * cell, int index) { GlobalPreferences * globalPreferences = GlobalPreferences::sharedGlobalPreferences(); - Preferences * preferences = Preferences::sharedPreferences(); I18n::Message title = model()->childAtIndex(index)->label(); - if (index == k_indexOfBrightnessCell) { + if (model()->childAtIndex(index)->label() == I18n::Message::Brightness) { MessageTableCellWithGaugeWithSeparator * myGaugeCell = (MessageTableCellWithGaugeWithSeparator *)cell; myGaugeCell->setMessage(title); GaugeView * myGauge = (GaugeView *)myGaugeCell->accessoryView(); @@ -175,17 +183,17 @@ void MainController::willDisplayCellForIndex(HighlightCell * cell, int index) { } MessageTableCell * myCell = (MessageTableCell *)cell; myCell->setMessage(title); - if (index == k_indexOfLanguageCell) { + if (model()->childAtIndex(index)->label() == I18n::Message::Language) { int index = (int)(globalPreferences->language()); static_cast(cell)->setSubtitle(I18n::LanguageNames[index]); return; } - if (index == k_indexOfCountryCell) { + if (model()->childAtIndex(index)->label() == I18n::Message::Country) { int index = (int)(globalPreferences->country()); static_cast(cell)->setSubtitle(I18n::CountryNames[index]); return; } - if (hasPrompt() && index == k_indexOfPopUpCell) { + if (model()->childAtIndex(index)->label() == I18n::Message::UpdatePopUp || model()->childAtIndex(index)->label() == I18n::Message::BetaPopUp) { MessageTableCellWithSwitch * mySwitchCell = (MessageTableCellWithSwitch *)cell; SwitchView * mySwitch = (SwitchView *)mySwitchCell->accessoryView(); mySwitch->setState(globalPreferences->showPopUp()); @@ -193,22 +201,12 @@ void MainController::willDisplayCellForIndex(HighlightCell * cell, int index) { } MessageTableCellWithChevronAndMessage * myTextCell = (MessageTableCellWithChevronAndMessage *)cell; int childIndex = -1; - switch (index) { - case k_indexOfAngleUnitCell: - childIndex = (int)preferences->angleUnit(); - break; - case k_indexOfDisplayModeCell: - childIndex = (int)preferences->displayMode(); - break; - case k_indexOfEditionModeCell: - childIndex = (int)preferences->editionMode(); - break; - case k_indexOfComplexFormatCell: - childIndex = (int)preferences->complexFormat(); - break; - case k_indexOfFontCell: + switch (model()->childAtIndex(index)->label()) { + case I18n::Message::FontSizes: childIndex = GlobalPreferences::sharedGlobalPreferences()->font() == KDFont::LargeFont ? 0 : 1; break; + default: + break; } I18n::Message message = childIndex >= 0 ? model()->childAtIndex(index)->childAtIndex(childIndex)->label() : I18n::Message::Default; myTextCell->setSubtitle(message); diff --git a/apps/settings/main_controller.h b/apps/settings/main_controller.h index f9675455fd1..fd638a0cd9e 100644 --- a/apps/settings/main_controller.h +++ b/apps/settings/main_controller.h @@ -5,9 +5,11 @@ #include #include "message_table_cell_with_gauge_with_separator.h" #include "sub_menu/about_controller.h" -#include "sub_menu/display_mode_controller.h" +#include "sub_menu/accessibility_controller.h" +#include "sub_menu/datetime_controller.h" #include "sub_menu/exam_mode_controller.h" #include "sub_menu/localization_controller.h" +#include "sub_menu/math_options_controller.h" #include "sub_menu/preferences_controller.h" namespace Settings { @@ -16,9 +18,14 @@ extern const Shared::SettingsMessageTree s_modelAngleChildren[3]; extern const Shared::SettingsMessageTree s_modelEditionModeChildren[2]; extern const Shared::SettingsMessageTree s_modelFloatDisplayModeChildren[4]; extern const Shared::SettingsMessageTree s_modelComplexFormatChildren[3]; +extern const Shared::SettingsMessageTree s_symbolChildren[4]; +extern const Shared::SettingsMessageTree s_symbolFunctionChildren[3]; +extern const Shared::SettingsMessageTree s_modelMathOptionsChildren[6]; extern const Shared::SettingsMessageTree s_modelFontChildren[2]; -extern const Shared::SettingsMessageTree s_modelExamChildren[2]; -extern const Shared::SettingsMessageTree s_modelAboutChildren[3]; +extern const Shared::SettingsMessageTree s_modelDateTimeChildren[3]; +extern const Shared::SettingsMessageTree s_accessibilityChildren[6]; +extern const Shared::SettingsMessageTree s_contributorsChildren[23]; +extern const Shared::SettingsMessageTree s_modelAboutChildren[8]; extern const Shared::SettingsMessageTree s_model; class MainController : public ViewController, public ListViewDataSource, public SelectableTableViewDataSource { @@ -38,36 +45,34 @@ class MainController : public ViewController, public ListViewDataSource, public void viewWillAppear() override; TELEMETRY_ID(""); private: - constexpr static int k_indexOfAngleUnitCell = 0; - constexpr static int k_indexOfDisplayModeCell = k_indexOfAngleUnitCell + 1; - constexpr static int k_indexOfEditionModeCell = k_indexOfDisplayModeCell + 1; - constexpr static int k_indexOfComplexFormatCell = k_indexOfEditionModeCell + 1; - constexpr static int k_indexOfBrightnessCell = k_indexOfComplexFormatCell + 1; - constexpr static int k_indexOfFontCell = k_indexOfBrightnessCell + 1; - constexpr static int k_indexOfLanguageCell = k_indexOfFontCell + 1; - constexpr static int k_indexOfCountryCell = k_indexOfLanguageCell + 1; - constexpr static int k_indexOfExamModeCell = k_indexOfCountryCell + 1; + constexpr static int k_indexOfMathOptionsChildren = 0; + constexpr static int k_indexOfBrightnessCell = k_indexOfMathOptionsChildren + 1; + constexpr static int k_indexOfLanguageCell = k_indexOfBrightnessCell + 1; + constexpr static int k_indexOfExamModeCell = k_indexOfLanguageCell + 1; + constexpr static int k_indexOfFontCell = k_indexOfExamModeCell + 1; /* Pop-up cell and About cell are located at the same index because pop-up * cell is optional. We must always correct k_indexOfAboutCell with * hasPrompt() (TODO: make hasPrompt() constexpr and correct * k_indexOfAboutCell) */ - constexpr static int k_indexOfPopUpCell = k_indexOfExamModeCell + 1; - constexpr static int k_indexOfAboutCell = k_indexOfExamModeCell + 1; + constexpr static int k_indexOfPopUpCell = k_indexOfFontCell + 1; + constexpr static int k_indexOfAboutCell = k_indexOfFontCell + 1; static const Shared::SettingsMessageTree * model(); +private: StackViewController * stackController() const; I18n::Message promptMessage() const; bool hasPrompt() const { return promptMessage() != I18n::Message::Default; } - constexpr static int k_numberOfSimpleChevronCells = (Ion::Display::Height - Metric::TitleBarHeight) / Metric::ParameterCellHeight + 1; + constexpr static int k_numberOfSimpleChevronCells = 9; MessageTableCellWithChevronAndMessage m_cells[k_numberOfSimpleChevronCells]; MessageTableCellWithGaugeWithSeparator m_brightnessCell; MessageTableCellWithSwitch m_popUpCell; SelectableTableView m_selectableTableView; - PreferencesController m_preferencesController; - DisplayModeController m_displayModeController; + MathOptionsController m_mathOptionsController; LocalizationController m_localizationController; + AccessibilityController m_accessibilityController; + DateTimeController m_dateTimeController; ExamModeController m_examModeController; AboutController m_aboutController; - + PreferencesController m_preferencesController; }; } diff --git a/apps/settings/main_controller_prompt_beta.cpp b/apps/settings/main_controller_prompt_beta.cpp index 65e2a1d242f..b462cc14b3a 100644 --- a/apps/settings/main_controller_prompt_beta.cpp +++ b/apps/settings/main_controller_prompt_beta.cpp @@ -7,17 +7,16 @@ using namespace Shared; namespace Settings { constexpr SettingsMessageTree s_modelMenu[] = - {SettingsMessageTree(I18n::Message::AngleUnit, s_modelAngleChildren), - SettingsMessageTree(I18n::Message::DisplayMode, s_modelFloatDisplayModeChildren), - SettingsMessageTree(I18n::Message::EditionMode, s_modelEditionModeChildren), - SettingsMessageTree(I18n::Message::ComplexFormat, s_modelComplexFormatChildren), + {SettingsMessageTree(I18n::Message::MathOptions, s_modelMathOptionsChildren), SettingsMessageTree(I18n::Message::Brightness), + SettingsMessageTree(I18n::Message::DateTime, s_modelDateTimeChildren), SettingsMessageTree(I18n::Message::FontSizes, s_modelFontChildren), SettingsMessageTree(I18n::Message::Language), SettingsMessageTree(I18n::Message::Country), SettingsMessageTree(I18n::Message::ExamMode, ExamModeConfiguration::s_modelExamChildren), SettingsMessageTree(I18n::Message::BetaPopUp), - SettingsMessageTree(I18n::Message::About, s_modelAboutChildren)}; + SettingsMessageTree(I18n::Message::About, s_modelAboutChildren), + SettingsMessageTree(I18n::Message::Accessibility, s_accessibilityChildren)}; constexpr SettingsMessageTree s_model = SettingsMessageTree(I18n::Message::SettingsApp, s_modelMenu); diff --git a/apps/settings/main_controller_prompt_none.cpp b/apps/settings/main_controller_prompt_none.cpp index f3c0e0ef80d..965fffe0706 100644 --- a/apps/settings/main_controller_prompt_none.cpp +++ b/apps/settings/main_controller_prompt_none.cpp @@ -7,15 +7,14 @@ using namespace Shared; namespace Settings { constexpr SettingsMessageTree s_modelMenu[] = - {SettingsMessageTree(I18n::Message::AngleUnit, s_modelAngleChildren), - SettingsMessageTree(I18n::Message::DisplayMode, s_modelFloatDisplayModeChildren), - SettingsMessageTree(I18n::Message::EditionMode, s_modelEditionModeChildren), - SettingsMessageTree(I18n::Message::ComplexFormat, s_modelComplexFormatChildren), + {SettingsMessageTree(I18n::Message::MathOptions, s_modelMathOptionsChildren), SettingsMessageTree(I18n::Message::Brightness), - SettingsMessageTree(I18n::Message::FontSizes, s_modelFontChildren), + SettingsMessageTree(I18n::Message::DateTime, s_modelDateTimeChildren), SettingsMessageTree(I18n::Message::Language), SettingsMessageTree(I18n::Message::Country), SettingsMessageTree(I18n::Message::ExamMode, ExamModeConfiguration::s_modelExamChildren), + SettingsMessageTree(I18n::Message::FontSizes, s_modelFontChildren), + SettingsMessageTree(I18n::Message::Accessibility, s_accessibilityChildren), SettingsMessageTree(I18n::Message::About, s_modelAboutChildren)}; constexpr SettingsMessageTree s_model = SettingsMessageTree(I18n::Message::SettingsApp, s_modelMenu); diff --git a/apps/settings/main_controller_prompt_update.cpp b/apps/settings/main_controller_prompt_update.cpp index b9eeafb31be..3c74faffc1a 100644 --- a/apps/settings/main_controller_prompt_update.cpp +++ b/apps/settings/main_controller_prompt_update.cpp @@ -7,16 +7,15 @@ namespace Settings { using namespace Shared; constexpr SettingsMessageTree s_modelMenu[] = - {SettingsMessageTree(I18n::Message::AngleUnit, s_modelAngleChildren), - SettingsMessageTree(I18n::Message::DisplayMode, s_modelFloatDisplayModeChildren), - SettingsMessageTree(I18n::Message::EditionMode, s_modelEditionModeChildren), - SettingsMessageTree(I18n::Message::ComplexFormat, s_modelComplexFormatChildren), + {SettingsMessageTree(I18n::Message::MathOptions, s_modelMathOptionsChildren), SettingsMessageTree(I18n::Message::Brightness), + SettingsMessageTree(I18n::Message::DateTime, s_modelDateTimeChildren), SettingsMessageTree(I18n::Message::FontSizes, s_modelFontChildren), SettingsMessageTree(I18n::Message::Language), SettingsMessageTree(I18n::Message::Country), SettingsMessageTree(I18n::Message::ExamMode, ExamModeConfiguration::s_modelExamChildren), SettingsMessageTree(I18n::Message::UpdatePopUp), + SettingsMessageTree(I18n::Message::Accessibility, s_accessibilityChildren), SettingsMessageTree(I18n::Message::About, s_modelAboutChildren)}; constexpr SettingsMessageTree s_model = SettingsMessageTree(I18n::Message::SettingsApp, s_modelMenu); diff --git a/apps/settings/sub_menu/about_controller.cpp b/apps/settings/sub_menu/about_controller.cpp index 790a36382ed..e2fe3f5a611 100644 --- a/apps/settings/sub_menu/about_controller.cpp +++ b/apps/settings/sub_menu/about_controller.cpp @@ -1,63 +1,172 @@ #include "about_controller.h" +#include "../../../python/src/py/mpconfig.h" #include #include +#include +#include +#include + +#define MP_STRINGIFY_HELPER(x) #x +#define MP_STRINGIFY(x) MP_STRINGIFY_HELPER(x) + +#ifndef OMEGA_STATE +#error This file expects OMEGA_STATE to be defined +#endif namespace Settings { AboutController::AboutController(Responder * parentResponder) : GenericSubController(parentResponder), - m_view(&m_selectableTableView) + m_contributorsController(this), + m_contributorsCell(KDFont::LargeFont, KDFont::SmallFont) + //m_view(&m_selectableTableView) { for (int i = 0; i < k_totalNumberOfCell; i++) { m_cells[i].setMessageFont(KDFont::LargeFont); m_cells[i].setAccessoryFont(KDFont::SmallFont); - m_cells[i].setAccessoryTextColor(Palette::GrayDark); + m_cells[i].setAccessoryTextColor(Palette::SecondaryText); } } bool AboutController::handleEvent(Ion::Events::Event event) { + I18n::Message childLabel = m_messageTreeModel->childAtIndex(selectedRow()+(!hasUsernameCell()))->label(); /* We hide here the activation hardware test app: in the menu "about", by * clicking on '6' on the last row. */ - if ((event == Ion::Events::Six || event == Ion::Events::LowerT || event == Ion::Events::UpperT) && m_messageTreeModel->label() == I18n::Message::About && selectedRow() == numberOfRows()-1) { + if ((event == Ion::Events::Six || event == Ion::Events::LowerT || event == Ion::Events::UpperT) && childLabel == I18n::Message::FccId) { Container::activeApp()->displayModalViewController(&m_hardwareTestPopUpController, 0.f, 0.f, Metric::ExamPopUpTopMargin, Metric::PopUpRightMargin, Metric::ExamPopUpBottomMargin, Metric::PopUpLeftMargin); return true; } - if (event == Ion::Events::OK || event == Ion::Events::EXE) { - if (selectedRow() == 0) { - MessageTableCellWithBuffer * myCell = (MessageTableCellWithBuffer *)m_selectableTableView.selectedCell(); - if (strcmp(myCell->accessoryText(), Ion::patchLevel()) == 0) { - myCell->setAccessoryText(Ion::softwareVersion()); + if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) { + if (childLabel == I18n::Message::Contributors) { + GenericSubController * subController = &m_contributorsController; + subController->setMessageTreeModel(m_messageTreeModel->childAtIndex(selectedRow()+(!hasUsernameCell()))); + StackViewController * stack = stackController(); + m_lastSelect = selectedRow(); + stack->push(subController); + return true; + } + if (!(event == Ion::Events::Right)) { + if (childLabel == I18n::Message::SoftwareVersion) { + MessageTableCellWithBuffer * myCell = (MessageTableCellWithBuffer *)m_selectableTableView.selectedCell(); + if (strcmp(myCell->accessoryText(), Ion::patchLevel()) == 0) { + myCell->setAccessoryText(Ion::softwareVersion()); + return true; + } + myCell->setAccessoryText(Ion::patchLevel()); + return true; + } + if (childLabel == I18n::Message::OmegaVersion) { + MessageTableCellWithBuffer * myCell = (MessageTableCellWithBuffer *)m_selectableTableView.selectedCell(); + if (strcmp(myCell->accessoryText(), Ion::omegaVersion()) == 0) { + myCell->setAccessoryText(MP_STRINGIFY(OMEGA_STATE)); //Change for public/dev + return true; + } + myCell->setAccessoryText(Ion::omegaVersion()); + return true; + } + if (childLabel == I18n::Message::MemUse) { + MessageTableCellWithBuffer * myCell = (MessageTableCellWithBuffer *)m_selectableTableView.selectedCell(); + + char memUseBuffer[15]; + + if (strchr(myCell->accessoryText(), '%') == NULL) { + int len = Poincare::Integer((int)((float)(Ion::Storage::k_storageSize - Ion::Storage::sharedStorage()->availableSize()) / (float)(Ion::Storage::k_storageSize) * 100.0f)).serialize(memUseBuffer, 4); + memUseBuffer[len] = '%'; + memUseBuffer[len+1] = '\0'; + + myCell->setAccessoryText(memUseBuffer); + } else { + int len = Poincare::Integer((int)((float) (Ion::Storage::k_storageSize - Ion::Storage::sharedStorage()->availableSize()) / 1024.f)).serialize(memUseBuffer, 4); + memUseBuffer[len] = 'k'; + memUseBuffer[len+1] = 'B'; + memUseBuffer[len+2] = '/'; + + len = Poincare::Integer((int)((float) Ion::Storage::k_storageSize / 1024.f)).serialize(memUseBuffer + len + 3, 4) + len + 3; + memUseBuffer[len] = 'k'; + memUseBuffer[len+1] = 'B'; + memUseBuffer[len+2] = '\0'; + + myCell->setAccessoryText(memUseBuffer); + } + return true; } - myCell->setAccessoryText(Ion::patchLevel()); - return true; } return false; } return GenericSubController::handleEvent(event); } +int AboutController::numberOfRows() const { + return m_messageTreeModel->numberOfChildren() - (!hasUsernameCell()); +} + HighlightCell * AboutController::reusableCell(int index, int type) { - assert(type == 0); - assert(index >= 0 && index < k_totalNumberOfCell); - return &m_cells[index]; + assert(index >= 0); + if (type == 0) { + assert(index < k_totalNumberOfCell-1-(!hasUsernameCell())); + return &m_cells[index+(!hasUsernameCell())]; + } + assert(index == 0); + return &m_contributorsCell; +} + +int AboutController::typeAtLocation(int i, int j) { + return (j == numberOfRows() - 1 ? 1 : 0); } int AboutController::reusableCellCount(int type) { - assert(type == 0); - return k_totalNumberOfCell; + switch (type) { + case 0: + return k_totalNumberOfCell-1-(!hasUsernameCell()); + case 1: + return 1; + default: + assert(false); + return 0; + } +} + +bool AboutController::hasUsernameCell() const { + return (*Ion::username()) != 0; } void AboutController::willDisplayCellForIndex(HighlightCell * cell, int index) { - GenericSubController::willDisplayCellForIndex(cell, index); - MessageTableCellWithBuffer * myCell = (MessageTableCellWithBuffer *)cell; - static const char * messages[] = { - Ion::softwareVersion(), - Ion::serialNumber(), - Ion::fccId() - }; - assert(index >= 0 && index < 3); - myCell->setAccessoryText(messages[index]); + int i = index + (!hasUsernameCell()); + GenericSubController::willDisplayCellForIndex(cell, i); + assert(index >= 0 && index < k_totalNumberOfCell); + if (m_messageTreeModel->childAtIndex(i)->label() == I18n::Message::Contributors) { + MessageTableCellWithChevronAndMessage * myTextCell = (MessageTableCellWithChevronAndMessage *)cell; + myTextCell->setSubtitle(I18n::Message::Default); + } else if (m_messageTreeModel->childAtIndex(i)->label() == I18n::Message::MemUse) { + char memUseBuffer[15]; + int len = Poincare::Integer((int)((float) (Ion::Storage::k_storageSize - Ion::Storage::sharedStorage()->availableSize()) / 1024.f)).serialize(memUseBuffer, 4); + memUseBuffer[len] = 'k'; + memUseBuffer[len+1] = 'B'; + memUseBuffer[len+2] = '/'; + + len = Poincare::Integer((int)((float) Ion::Storage::k_storageSize / 1024.f)).serialize(memUseBuffer + len + 3, 4) + len + 3; + memUseBuffer[len] = 'k'; + memUseBuffer[len+1] = 'B'; + memUseBuffer[len+2] = '\0'; + + MessageTableCellWithBuffer * myCell = (MessageTableCellWithBuffer *)cell; + myCell->setAccessoryText(memUseBuffer); + } else { + MessageTableCellWithBuffer * myCell = (MessageTableCellWithBuffer *)cell; + static const char * mpVersion = MICROPY_VERSION_STRING; + static const char * messages[] = { + Ion::username(), + Ion::softwareVersion(), + Ion::omegaVersion(), + mpVersion, + "", + Ion::serialNumber(), + Ion::fccId(), + "" + }; + myCell->setAccessoryText(messages[i]); + } } } diff --git a/apps/settings/sub_menu/about_controller.h b/apps/settings/sub_menu/about_controller.h index c5e4d503b3a..beef15d95cb 100644 --- a/apps/settings/sub_menu/about_controller.h +++ b/apps/settings/sub_menu/about_controller.h @@ -4,22 +4,29 @@ #include "generic_sub_controller.h" #include "selectable_view_with_messages.h" #include "../../hardware_test/pop_up_controller.h" +#include "contributors_controller.h" namespace Settings { class AboutController : public GenericSubController { public: AboutController(Responder * parentResponder); - View * view() override { return &m_view; } + //View * view() override { return &m_view; } + View * view() override { return &m_selectableTableView; } void viewWillAppear() override; TELEMETRY_ID("About"); bool handleEvent(Ion::Events::Event event) override; HighlightCell * reusableCell(int index, int type) override; int reusableCellCount(int type) override; void willDisplayCellForIndex(HighlightCell * cell, int index) override; + int typeAtLocation(int i, int j) override; + int numberOfRows() const override; private: - constexpr static int k_totalNumberOfCell = 3; - SelectableViewWithMessages m_view; + constexpr static int k_totalNumberOfCell = 8; + bool hasUsernameCell() const; + ContributorsController m_contributorsController; + MessageTableCellWithChevronAndMessage m_contributorsCell; + //SelectableViewWithMessages m_view; MessageTableCellWithBuffer m_cells[k_totalNumberOfCell]; HardwareTest::PopUpController m_hardwareTestPopUpController; }; diff --git a/apps/settings/sub_menu/about_controller_non_official.cpp b/apps/settings/sub_menu/about_controller_non_official.cpp index 84995e4a4df..52e111eb513 100644 --- a/apps/settings/sub_menu/about_controller_non_official.cpp +++ b/apps/settings/sub_menu/about_controller_non_official.cpp @@ -5,9 +5,10 @@ namespace Settings { void AboutController::viewWillAppear() { GenericSubController::viewWillAppear(); + // IN OMEGA, THE FOLLOWING LINES ARE ADDED IN A SUBMENU "LEGAL INFORMATION", BECAUSE MESSAGES DELETE THE SCROLLBAR. // --------------------- Please don't edit these lines ---------------------- I18n::Message cautionMessages[] = {I18n::Message::AboutWarning1, I18n::Message::AboutWarning2, I18n::Message::AboutWarning3, I18n::Message::AboutWarning4}; - m_view.setMessages(cautionMessages, sizeof(cautionMessages)/sizeof(I18n::Message)); + // m_view.setMessages(cautionMessages, sizeof(cautionMessages)/sizeof(I18n::Message)); // -------------------------------------------------------------------------- } diff --git a/apps/settings/sub_menu/about_controller_official.cpp b/apps/settings/sub_menu/about_controller_official.cpp index f46c96d2e62..a5b94d4d323 100644 --- a/apps/settings/sub_menu/about_controller_official.cpp +++ b/apps/settings/sub_menu/about_controller_official.cpp @@ -4,7 +4,7 @@ namespace Settings { void AboutController::viewWillAppear() { GenericSubController::viewWillAppear(); - m_view.setMessages(nullptr, 0); + //m_view.setMessages(nullptr, 0); } } diff --git a/apps/settings/sub_menu/accessibility_controller.cpp b/apps/settings/sub_menu/accessibility_controller.cpp new file mode 100644 index 00000000000..1df981f379d --- /dev/null +++ b/apps/settings/sub_menu/accessibility_controller.cpp @@ -0,0 +1,141 @@ +#include "accessibility_controller.h" +#include "../../global_preferences.h" +#include "../../apps_container.h" +#include + +using namespace Shared; + +namespace Settings { + +AccessibilityController::AccessibilityController(Responder * parentResponder) : + GenericSubController(parentResponder) +{ + for (int i = 0; i < k_totalNumberOfSwitchCells; i++) { + m_switchCells[i].setMessageFont(KDFont::LargeFont); + } + for (int i = 0; i < k_totalNumberOfGaugeCells; i++) { + m_gaugeCells[i].setMessageFont(KDFont::LargeFont); + } +} + +bool AccessibilityController::handleEvent(Ion::Events::Event event) { + bool invertEnabled = KDIonContext::sharedContext()->invertEnabled; + bool zoomEnabled = KDIonContext::sharedContext()->zoomEnabled; + bool gammaEnabled = KDIonContext::sharedContext()->gammaEnabled; + int redGamma, greenGamma, blueGamma; + KDIonContext::sharedContext()->gamma.gamma(redGamma, greenGamma, blueGamma); + + if (event == Ion::Events::OK || event == Ion::Events::EXE) { + if (selectedRow() == 0) { + invertEnabled = !invertEnabled; + } + else if (selectedRow() == 1) { + zoomEnabled = !zoomEnabled; + } + else if (selectedRow() == 2) { + gammaEnabled = !gammaEnabled; + } + else { + GenericSubController::handleEvent(event); + } + } + else if (event == Ion::Events::Right || event == Ion::Events::Left || event == Ion::Events::Plus || event == Ion::Events::Minus) { + int direction = (event == Ion::Events::Right || event == Ion::Events::Plus) ? 1 : -1; + if (selectedRow() == 3) { + redGamma += direction; + } + else if (selectedRow() == 4) { + greenGamma += direction; + } + else if (selectedRow() == 5) { + blueGamma += direction; + } + else { + return GenericSubController::handleEvent(event); + } + } + else { + return GenericSubController::handleEvent(event); + } + KDIonContext::sharedContext()->invertEnabled = invertEnabled; + KDIonContext::sharedContext()->zoomEnabled = zoomEnabled; + KDIonContext::sharedContext()->gammaEnabled = gammaEnabled; + KDIonContext::sharedContext()->gamma.setGamma(redGamma, greenGamma, blueGamma); + KDIonContext::sharedContext()->updatePostProcessingEffects(); + m_selectableTableView.reloadCellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()); + AppsContainer::sharedAppsContainer()->redrawWindow(true); + return true; +} + +HighlightCell * AccessibilityController::reusableCell(int index, int type) { + assert(type == 1 || type == 2); + if (type == 2) { + assert(index >= 0 && index < k_totalNumberOfSwitchCells); + return &m_switchCells[index]; + } + else if (type == 1) { + assert(index >= 0 && index < k_totalNumberOfGaugeCells); + return &m_gaugeCells[index]; + } + return nullptr; +} + +int AccessibilityController::reusableCellCount(int type) { + assert(type == 1 || type == 2); + if (type == 2) { + return k_totalNumberOfSwitchCells; + } + else if (type == 1) { + return k_totalNumberOfGaugeCells; + } + return 0; +} + +void AccessibilityController::willDisplayCellForIndex(HighlightCell * cell, int index) { + GenericSubController::willDisplayCellForIndex(cell, index); + + MessageTableCellWithSwitch * mySwitchCell = (MessageTableCellWithSwitch *)cell; + + if (index == 0) { + SwitchView * mySwitch = (SwitchView *)mySwitchCell->accessoryView(); + mySwitch->setState(KDIonContext::sharedContext()->invertEnabled); + } + else if (index == 1) { + SwitchView * mySwitch = (SwitchView *)mySwitchCell->accessoryView(); + mySwitch->setState(KDIonContext::sharedContext()->zoomEnabled); + } + else if (index == 2) { + SwitchView * mySwitch = (SwitchView *)mySwitchCell->accessoryView(); + mySwitch->setState(KDIonContext::sharedContext()->gammaEnabled); + } + else { + MessageTableCellWithGauge * myGaugeCell = (MessageTableCellWithGauge *)cell; + GaugeView * myGauge = (GaugeView *)myGaugeCell->accessoryView(); + + float redGamma, greenGamma, blueGamma, level; + KDIonContext::sharedContext()->gamma.gamma(redGamma, greenGamma, blueGamma); + if (index == 3) { + level = redGamma; + } + else if (index == 4) { + level = greenGamma; + } + else { + level = blueGamma; + } + myGauge->setLevel(level); + } +} + +int AccessibilityController::typeAtLocation(int i, int j) { + switch (j) { + case 0: + case 1: + case 2: + return 2; + default: + return 1; + } +} + +} diff --git a/apps/settings/sub_menu/accessibility_controller.h b/apps/settings/sub_menu/accessibility_controller.h new file mode 100644 index 00000000000..1d42ff6c37a --- /dev/null +++ b/apps/settings/sub_menu/accessibility_controller.h @@ -0,0 +1,26 @@ +#ifndef SETTINGS_ACCESSIBILITY_CONTROLLER_H +#define SETTINGS_ACCESSIBILITY_CONTROLLER_H + +#include "generic_sub_controller.h" +#include "../../hardware_test/pop_up_controller.h" + +namespace Settings { + +class AccessibilityController : public GenericSubController { +public: + AccessibilityController(Responder * parentResponder); + bool handleEvent(Ion::Events::Event event) override; + HighlightCell * reusableCell(int index, int type) override; + int reusableCellCount(int type) override; + void willDisplayCellForIndex(HighlightCell * cell, int index) override; + int typeAtLocation(int i, int j) override; +private: + constexpr static int k_totalNumberOfSwitchCells = 3; + constexpr static int k_totalNumberOfGaugeCells = 3; + MessageTableCellWithGauge m_gaugeCells[k_totalNumberOfGaugeCells]; + MessageTableCellWithSwitch m_switchCells[k_totalNumberOfSwitchCells]; +}; + +} + +#endif diff --git a/apps/settings/sub_menu/contributors_controller.cpp b/apps/settings/sub_menu/contributors_controller.cpp new file mode 100644 index 00000000000..26bab3326a5 --- /dev/null +++ b/apps/settings/sub_menu/contributors_controller.cpp @@ -0,0 +1,79 @@ +#include "contributors_controller.h" +#include + +namespace Settings { + +ContributorsController::ContributorsController(Responder * parentResponder) : + GenericSubController(parentResponder) +{ + for (int i = 0; i < k_totalNumberOfCell; i++) { + m_cells[i].setMessageFont(KDFont::LargeFont); + m_cells[i].setAccessoryFont(KDFont::SmallFont); + m_cells[i].setAccessoryTextColor(Palette::SecondaryText); + } +} + +bool ContributorsController::handleEvent(Ion::Events::Event event) { + return GenericSubController::handleEvent(event); +} + +HighlightCell * ContributorsController::reusableCell(int index, int type) { + assert(type == 0); + assert(index >= 0 && index < k_totalNumberOfCell); + return &m_cells[index]; +} + +int ContributorsController::reusableCellCount(int type) { + assert(type == 0); + return k_totalNumberOfCell; +} + +constexpr static int s_numberOfDevelopers = 13; +constexpr static I18n::Message s_developersUsernames[s_numberOfDevelopers] = { + I18n::Message::PQuentinGuidee, + I18n::Message::PJoachimLeFournis, + I18n::Message::PMaximeFriess, + I18n::Message::PJeanBaptisteBoric, + I18n::Message::PSandraSimmons, + I18n::Message::PDavid, + I18n::Message::PDamienNicolet, + I18n::Message::PEvannDreumont, + I18n::Message::PSzaboLevente, + I18n::Message::PVenceslasDuet, + I18n::Message::PCharlotteThomas, + I18n::Message::PAntoninLoubiere, + I18n::Message::PCyprienMejat, +}; + +constexpr static int s_numberOfBetaTesters = 8; +constexpr static I18n::Message s_betaTestersUsernames[s_numberOfBetaTesters] = { + I18n::Message::PTimeoArnouts, + I18n::Message::PJulieC, + I18n::Message::PLelahelHideux, + I18n::Message::PMadil, + I18n::Message::PHilaireLeRoux, + I18n::Message::PHectorNussbaumer, + I18n::Message::PRaphaelDyda, + I18n::Message::PThibautC, +}; + +void ContributorsController::willDisplayCellForIndex(HighlightCell * cell, int index) { + MessageTableCellWithBuffer * myTextCell = (MessageTableCellWithBuffer *)cell; + if (index == 0) { + myTextCell->setAccessoryText(""); + myTextCell->setTextColor(KDColor::RGB24(0xC03535)); + } else if (index > 0 && index <= s_numberOfDevelopers) { + myTextCell->setAccessoryText(I18n::translate(s_developersUsernames[index - 1])); + myTextCell->setTextColor(Palette::PrimaryText); + } else if (index == s_numberOfDevelopers + 1) { + myTextCell->setAccessoryText(""); + myTextCell->setTextColor(KDColor::RGB24(0x1ABC9A)); + } else { + myTextCell->setAccessoryText(I18n::translate(s_betaTestersUsernames[index - 2 - s_numberOfDevelopers])); + myTextCell->setTextColor(Palette::PrimaryText); + } + myTextCell->setAccessoryTextColor(Palette::SecondaryText); + GenericSubController::willDisplayCellForIndex(cell, index); +} + +} diff --git a/apps/settings/sub_menu/contributors_controller.h b/apps/settings/sub_menu/contributors_controller.h new file mode 100644 index 00000000000..71674836caa --- /dev/null +++ b/apps/settings/sub_menu/contributors_controller.h @@ -0,0 +1,23 @@ +#ifndef SETTINGS_CONTRIBUTORS_CONTROLLER_H +#define SETTINGS_CONTRIBUTORS_CONTROLLER_H + +#include "generic_sub_controller.h" +#include + +namespace Settings { + +class ContributorsController : public GenericSubController { +public: + ContributorsController(Responder * parentResponder); + bool handleEvent(Ion::Events::Event event) override; + HighlightCell * reusableCell(int index, int type) override; + int reusableCellCount(int type) override; + void willDisplayCellForIndex(HighlightCell * cell, int index) override; +private: + constexpr static int k_totalNumberOfCell = 7; + MessageTableCellWithBuffer m_cells[k_totalNumberOfCell]; +}; + +} + +#endif diff --git a/apps/settings/sub_menu/datetime_controller.cpp b/apps/settings/sub_menu/datetime_controller.cpp new file mode 100644 index 00000000000..f3ca0576049 --- /dev/null +++ b/apps/settings/sub_menu/datetime_controller.cpp @@ -0,0 +1,141 @@ +#include "../app.h" +#include "datetime_controller.h" +#include "../../global_preferences.h" +#include "../../apps_container.h" +#include + +using namespace Shared; + +namespace Settings { + +DateTimeController::DateTimeController(Responder * parentResponder) : + GenericSubController(parentResponder), + m_textCells{ + MessageTableCellWithEditableText{this, nullptr, this}, + MessageTableCellWithEditableText{this, nullptr, this}, + } +{ + for (int i = 0; i < k_totalNumberOfSwitchCells; i++) { + m_switchCells[i].setMessageFont(KDFont::LargeFont); + } + for (int i = 0; i < k_totalNumberOfTextCells; i++) { + m_textCells[i].setMessageFont(KDFont::LargeFont); + } +} + +bool DateTimeController::handleEvent(Ion::Events::Event event) { + bool clockEnabled = Ion::RTC::mode() != Ion::RTC::Mode::Disabled; + + if (event == Ion::Events::OK || event == Ion::Events::EXE) { + if (selectedRow() == 0) { + clockEnabled = !clockEnabled; + if (clockEnabled) { + Container::activeApp()->displayWarning(I18n::Message::RTCWarning1, I18n::Message::RTCWarning2); + } + Ion::RTC::setMode(clockEnabled ? Ion::RTC::Mode::HSE : Ion::RTC::Mode::Disabled); + } + } + else { + return GenericSubController::handleEvent(event); + } + for (int i = 0; i < numberOfRows(); i++) { + m_selectableTableView.reloadCellAtLocation(0, i); + } + AppsContainer::sharedAppsContainer()->redrawWindow(); + return true; +} + +HighlightCell * DateTimeController::reusableCell(int index, int type) { + assert(type == 1 || type == 2); + if (type == 2) { + assert(index >= 0 && index < k_totalNumberOfSwitchCells); + return &m_switchCells[index]; + } + else if (type == 1) { + assert(index >= 0 && index < k_totalNumberOfTextCells); + return &m_textCells[index]; + } + return nullptr; +} + +int DateTimeController::reusableCellCount(int type) { + assert(type == 1 || type == 2); + if (type == 2) { + return k_totalNumberOfSwitchCells; + } + else if (type == 1) { + return k_totalNumberOfTextCells; + } + return 0; +} + +void DateTimeController::willDisplayCellForIndex(HighlightCell * cell, int index) { + GenericSubController::willDisplayCellForIndex(cell, index); + + MessageTableCellWithSwitch * mySwitchCell = (MessageTableCellWithSwitch *)cell; + + if (index == 0) { + SwitchView * mySwitch = (SwitchView *)mySwitchCell->accessoryView(); + mySwitch->setState(Ion::RTC::mode() != Ion::RTC::Mode::Disabled); + } + else { + TextField * myTextField = (TextField *)mySwitchCell->accessoryView(); + Ion::RTC::DateTime dateTime = Ion::RTC::dateTime(); + if (index == 1) { + Ion::RTC::toStringDate(dateTime, m_timeBuffer); + myTextField->setText(m_timeBuffer); + } + else { + Ion::RTC::toStringTime(dateTime, m_dateBuffer); + myTextField->setText(m_dateBuffer); + } + } +} + +int DateTimeController::typeAtLocation(int i, int j) { + switch (j) { + case 0: + return 2; + default: + return 1; + } +} + +bool DateTimeController::textFieldShouldFinishEditing(TextField * view, Ion::Events::Event event) { + return event == Ion::Events::Up || event == Ion::Events::Down || event == Ion::Events::EXE || event == Ion::Events::OK; +} + +bool DateTimeController::textFieldDidReceiveEvent(TextField * view, Ion::Events::Event event) { + if (view->isEditing() && view->shouldFinishEditing(event)) { + Ion::RTC::DateTime dateTime = Ion::RTC::dateTime(); + + if (((TextField*)m_textCells[0].accessoryView()) == view) { + if (!Ion::RTC::parseDate(view->text(), dateTime)) { + Container::activeApp()->displayWarning(I18n::Message::SyntaxError); + return true; + } + } + else { + if (!Ion::RTC::parseTime(view->text(), dateTime)) { + Container::activeApp()->displayWarning(I18n::Message::SyntaxError); + return true; + } + } + Ion::RTC::setDateTime(dateTime); + } + if (event == Ion::Events::Up || event == Ion::Events::Down) { + m_selectableTableView.handleEvent(event); + return true; + } + return false; +} + +bool DateTimeController::textFieldDidFinishEditing(TextField * view, const char * text, Ion::Events::Event event) +{ + for (int i = 0; i < numberOfRows(); i++) { + m_selectableTableView.reloadCellAtLocation(0, i); + } + return true; +} + +} diff --git a/apps/settings/sub_menu/datetime_controller.h b/apps/settings/sub_menu/datetime_controller.h new file mode 100644 index 00000000000..7296819404c --- /dev/null +++ b/apps/settings/sub_menu/datetime_controller.h @@ -0,0 +1,30 @@ +#ifndef SETTINGS_DATETIME_CONTROLLER_H +#define SETTINGS_DATETIME_CONTROLLER_H + +#include "generic_sub_controller.h" + +namespace Settings { + +class DateTimeController : public GenericSubController, public TextFieldDelegate { +public: + DateTimeController(Responder * parentResponder); + bool handleEvent(Ion::Events::Event event) override; + HighlightCell * reusableCell(int index, int type) override; + int reusableCellCount(int type) override; + void willDisplayCellForIndex(HighlightCell * cell, int index) override; + int typeAtLocation(int i, int j) override; + bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override; + bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override; + bool textFieldDidFinishEditing(TextField * view, const char * text, Ion::Events::Event event) override; +private: + constexpr static int k_totalNumberOfSwitchCells = 1; + constexpr static int k_totalNumberOfTextCells = 2; + MessageTableCellWithEditableText m_textCells[k_totalNumberOfTextCells]; + MessageTableCellWithSwitch m_switchCells[k_totalNumberOfSwitchCells]; + char m_timeBuffer[9]; + char m_dateBuffer[11]; +}; + +} + +#endif diff --git a/apps/settings/sub_menu/exam_mode_controller.cpp b/apps/settings/sub_menu/exam_mode_controller.cpp index 561da5e83fa..33a853eaab1 100644 --- a/apps/settings/sub_menu/exam_mode_controller.cpp +++ b/apps/settings/sub_menu/exam_mode_controller.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include using namespace Poincare; using namespace Shared; @@ -14,7 +16,10 @@ namespace Settings { ExamModeController::ExamModeController(Responder * parentResponder) : GenericSubController(parentResponder), m_contentView(&m_selectableTableView), - m_cell{} + m_cell{}, + m_ledController(this), + m_examModeModeController(this), + m_examModeCell(KDFont::LargeFont, KDFont::SmallFont) { for (int i = 0; i < k_maxNumberOfCells; i++) { m_cell[i].setMessage(ExamModeConfiguration::examModeActivationMessage(i)); @@ -23,9 +28,17 @@ ExamModeController::ExamModeController(Responder * parentResponder) : } bool ExamModeController::handleEvent(Ion::Events::Event event) { - if (event == Ion::Events::OK || event == Ion::Events::EXE) { - AppsContainer::sharedAppsContainer()->displayExamModePopUp(examMode()); - return true; + if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) { + if (m_messageTreeModel->childAtIndex(selectedRow())->label() == I18n::Message::ExamModeMode) { + (&m_examModeModeController)->setMessageTreeModel(m_messageTreeModel->childAtIndex(selectedRow())); + StackViewController * stack = stackController(); + stack->push(&m_examModeModeController); + return true; + } + else { + AppsContainer::sharedAppsContainer()->displayExamModePopUp(examMode()); + return true; + } } return GenericSubController::handleEvent(event); } @@ -54,20 +67,35 @@ int ExamModeController::numberOfRows() const { HighlightCell * ExamModeController::reusableCell(int index, int type) { assert(type == 0); - assert(index >= 0 && index < k_maxNumberOfCells); + assert(index >= 0 && index < 3); + if (m_messageTreeModel->childAtIndex(index)->label() == I18n::Message::ExamModeMode) { + return &m_examModeCell; + } return &m_cell[index]; } int ExamModeController::reusableCellCount(int type) { - return k_maxNumberOfCells; + assert(type == 0); + return 3; } void ExamModeController::willDisplayCellForIndex(HighlightCell * cell, int index) { + if(index == 0){ + m_cell[2].setHighlighted(false); + } + Preferences * preferences = Preferences::sharedPreferences(); GenericSubController::willDisplayCellForIndex(cell, index); - if (GlobalPreferences::sharedGlobalPreferences()->isInExamMode()) { + I18n::Message thisLabel = m_messageTreeModel->childAtIndex(index)->label(); + + if (GlobalPreferences::sharedGlobalPreferences()->isInExamMode() && (thisLabel == I18n::Message::ActivateExamMode || thisLabel == I18n::Message::ExamModeActive)) { MessageTableCell * myCell = (MessageTableCell *)cell; myCell->setMessage(I18n::Message::ExamModeActive); } + if (thisLabel == I18n::Message::ExamModeMode) { + MessageTableCellWithChevronAndMessage * myTextCell = (MessageTableCellWithChevronAndMessage *)cell; + I18n::Message message = (I18n::Message) m_messageTreeModel->childAtIndex(index)->childAtIndex((uint8_t)GlobalPreferences::sharedGlobalPreferences()->tempExamMode() - 1)->label(); + myTextCell->setSubtitle(message); + } } int ExamModeController::initialSelectedRow() const { @@ -81,7 +109,7 @@ int ExamModeController::initialSelectedRow() const { } GlobalPreferences::ExamMode ExamModeController::examMode() { - GlobalPreferences::ExamMode mode = ExamModeConfiguration::examModeAtIndex(selectedRow()); + GlobalPreferences::ExamMode mode = GlobalPreferences::sharedGlobalPreferences()->tempExamMode(); if (GlobalPreferences::sharedGlobalPreferences()->isInExamMode()) { // If the exam mode is already on, this re-activate the same exam mode mode = GlobalPreferences::sharedGlobalPreferences()->examMode(); diff --git a/apps/settings/sub_menu/exam_mode_controller.h b/apps/settings/sub_menu/exam_mode_controller.h index 880d37c374c..e7abb1b1298 100644 --- a/apps/settings/sub_menu/exam_mode_controller.h +++ b/apps/settings/sub_menu/exam_mode_controller.h @@ -4,6 +4,7 @@ #include "generic_sub_controller.h" #include "selectable_view_with_messages.h" #include "../../global_preferences.h" +#include "preferences_controller.h" namespace Settings { @@ -24,9 +25,12 @@ class ExamModeController : public GenericSubController { int numberOfCautionLines() const; int initialSelectedRow() const override; GlobalPreferences::ExamMode examMode(); - static constexpr int k_maxNumberOfCells = 2; + static constexpr int k_maxNumberOfCells = 4; SelectableViewWithMessages m_contentView; MessageTableCell m_cell[k_maxNumberOfCells]; + PreferencesController m_ledController; + PreferencesController m_examModeModeController; + MessageTableCellWithChevronAndMessage m_examModeCell; }; } diff --git a/apps/settings/sub_menu/generic_sub_controller.h b/apps/settings/sub_menu/generic_sub_controller.h index 8c9e42487af..d48336d9fe5 100644 --- a/apps/settings/sub_menu/generic_sub_controller.h +++ b/apps/settings/sub_menu/generic_sub_controller.h @@ -18,13 +18,14 @@ class GenericSubController : public ViewController, public ListViewDataSource, p KDCoordinate rowHeight(int j) override; KDCoordinate cumulatedHeightFromIndex(int j) override; int indexFromCumulatedHeight(KDCoordinate offsetY) override; - int typeAtLocation(int i, int j) override; + virtual int typeAtLocation(int i, int j) override; void willDisplayCellForIndex(HighlightCell * cell, int index) override; void setMessageTreeModel(const MessageTree * messageTreeModel); void viewDidDisappear() override; protected: + int m_lastSelect = 0; StackViewController * stackController() const; - virtual int initialSelectedRow() const { return 0; } + virtual int initialSelectedRow() const { return m_lastSelect; } constexpr static KDCoordinate k_topBottomMargin = 13; SelectableTableView m_selectableTableView; MessageTree * m_messageTreeModel; diff --git a/apps/settings/sub_menu/math_options_controller.cpp b/apps/settings/sub_menu/math_options_controller.cpp new file mode 100644 index 00000000000..50566ba60ff --- /dev/null +++ b/apps/settings/sub_menu/math_options_controller.cpp @@ -0,0 +1,80 @@ +#include "math_options_controller.h" +#include +#include "../../global_preferences.h" + +using namespace Poincare; + +namespace Settings { + +MathOptionsController::MathOptionsController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate) : + GenericSubController(parentResponder), + m_preferencesController(this), + m_displayModeController(this, inputEventHandlerDelegate) +{ + for (int i = 0; i < k_totalNumberOfCell; i++) { + m_cells[i].setMessageFont(KDFont::LargeFont); + } +} + +bool MathOptionsController::handleEvent(Ion::Events::Event event) { + if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) { + GenericSubController * subController = nullptr; + if (m_messageTreeModel->childAtIndex(selectedRow())->label() == I18n::Message::DisplayMode) + subController = &m_displayModeController; + else + subController = &m_preferencesController; + subController->setMessageTreeModel(m_messageTreeModel->childAtIndex(selectedRow())); + StackViewController * stack = stackController(); + m_lastSelect = selectedRow(); + stack->push(subController); + return true; + } + return GenericSubController::handleEvent(event); +} + +HighlightCell * MathOptionsController::reusableCell(int index, int type) { + assert(type == 0); + assert(index >= 0 && index < k_totalNumberOfCell); + return &m_cells[index]; +} + +int MathOptionsController::reusableCellCount(int type) { + assert(type == 0); + return k_totalNumberOfCell; +} + +void MathOptionsController::willDisplayCellForIndex(HighlightCell * cell, int index) { + MessageTableCellWithChevronAndMessage * myTextCell = (MessageTableCellWithChevronAndMessage *)cell; + Preferences * preferences = Preferences::sharedPreferences(); + I18n::Message thisLabel = m_messageTreeModel->childAtIndex(index)->label(); + myTextCell->setMessage(thisLabel); + + //add text for preferences + int childIndex = -1; + switch (thisLabel) { + case I18n::Message::AngleUnit: + childIndex = (int)preferences->angleUnit(); + break; + case I18n::Message::DisplayMode: + childIndex = (int)preferences->displayMode(); + break; + case I18n::Message::EditionMode: + childIndex = (int)preferences->editionMode(); + break; + case I18n::Message::ComplexFormat: + childIndex = (int)preferences->complexFormat(); + break; + case I18n::Message::SymbolMultiplication: + childIndex = (int)preferences->symbolOfMultiplication(); + break; + case I18n::Message::SymbolFunction: + childIndex = (int)preferences->symbolOfFunction(); + break; + default: + break; + } + I18n::Message message = childIndex >= 0 ? m_messageTreeModel->childAtIndex(index)->childAtIndex(childIndex)->label() : I18n::Message::Default; + myTextCell->setSubtitle(message); +} + +} diff --git a/apps/settings/sub_menu/math_options_controller.h b/apps/settings/sub_menu/math_options_controller.h new file mode 100644 index 00000000000..47a59758d1a --- /dev/null +++ b/apps/settings/sub_menu/math_options_controller.h @@ -0,0 +1,27 @@ +#ifndef SETTINGS_MATH_OPTIONS_CONTROLLER_H +#define SETTINGS_MATH_OPTIONS_CONTROLLER_H + +#include "generic_sub_controller.h" +#include +#include "display_mode_controller.h" +#include "preferences_controller.h" + +namespace Settings { + +class MathOptionsController : public GenericSubController { +public: + MathOptionsController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate); + bool handleEvent(Ion::Events::Event event) override; + HighlightCell * reusableCell(int index, int type) override; + int reusableCellCount(int type) override; + void willDisplayCellForIndex(HighlightCell * cell, int index) override; +private: + constexpr static int k_totalNumberOfCell = 7; + MessageTableCellWithChevronAndMessage m_cells[k_totalNumberOfCell]; + PreferencesController m_preferencesController; + DisplayModeController m_displayModeController; +}; + +} + +#endif diff --git a/apps/settings/sub_menu/message_table_cell_with_editable_text_with_separator.cpp b/apps/settings/sub_menu/message_table_cell_with_editable_text_with_separator.cpp new file mode 100644 index 00000000000..d4685cfe1c1 --- /dev/null +++ b/apps/settings/sub_menu/message_table_cell_with_editable_text_with_separator.cpp @@ -0,0 +1,34 @@ +#include "message_table_cell_with_editable_text_with_separator.h" + +namespace Settings { + +MessageTableCellWithEditableTextWithSeparator::MessageTableCellWithEditableTextWithSeparator(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, I18n::Message message) : + HighlightCell(), + m_cell(parentResponder, inputEventHandlerDelegate, textFieldDelegate, message) +{ +} + +void MessageTableCellWithEditableTextWithSeparator::setHighlighted(bool highlight) { + m_cell.setHighlighted(highlight); + HighlightCell::setHighlighted(highlight); +} + +void MessageTableCellWithEditableTextWithSeparator::drawRect(KDContext * ctx, KDRect rect) const { + ctx->fillRect(KDRect(0, 0, bounds().width(), k_separatorThickness), Palette::ListCellBorder); + ctx->fillRect(KDRect(0, k_separatorThickness, bounds().width(), k_margin-k_separatorThickness), Palette::BackgroundApps); +} + +int MessageTableCellWithEditableTextWithSeparator::numberOfSubviews() const { + return 1; +} + +View * MessageTableCellWithEditableTextWithSeparator::subviewAtIndex(int index) { + assert(index == 0); + return &m_cell; +} + +void MessageTableCellWithEditableTextWithSeparator::layoutSubviews() { + m_cell.setFrame(KDRect(0, k_margin, bounds().width(), bounds().height()-k_margin)); +} + +} diff --git a/apps/settings/sub_menu/preferences_controller.cpp b/apps/settings/sub_menu/preferences_controller.cpp index 7145f5c05b6..2aba6a8691f 100644 --- a/apps/settings/sub_menu/preferences_controller.cpp +++ b/apps/settings/sub_menu/preferences_controller.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include using namespace Poincare; @@ -106,6 +107,60 @@ Layout PreferencesController::layoutForPreferences(I18n::Message message) { ); } + // Exam mode modes + case I18n::Message::ExamModeModeStandard: + { + const char * text = " "; + return LayoutHelper::String(text, strlen(text), k_layoutFont); + } + case I18n::Message::ExamModeModeNoSym: + { + const char * text = " "; + return LayoutHelper::String(text, strlen(text), k_layoutFont); + } + case I18n::Message::ExamModeModeNoSymNoText: + { + const char * text = " "; + return LayoutHelper::String(text, strlen(text), k_layoutFont); + } + case I18n::Message::ExamModeModeDutch: + { + const char * text = " "; + return LayoutHelper::String(text, strlen(text), k_layoutFont); + } + + + // Symbol controller + case I18n::Message::SymbolMultiplicationCross: // × and · aren't single characters, so they cannot be constructed into codepoints..? + { + const char * text = "×"; + return LayoutHelper::String(text, strlen(text), k_layoutFont); + } + case I18n::Message::SymbolMultiplicationMiddleDot: + { + const char * text = "·"; + return LayoutHelper::String(text, strlen(text), k_layoutFont); + } + case I18n::Message::SymbolMultiplicationStar: + return CodePointLayout::Builder('*', k_layoutFont); + case I18n::Message::SymbolMultiplicationAutoSymbol: + return CodePointLayout::Builder(' ', k_layoutFont); + + + // Symbol function + case I18n::Message::SymbolDefaultFunction: + { + return NthRootLayout::Builder(CodePointLayout::Builder('x')); + } + case I18n::Message::SymbolArgDefaultFunction: + { + return NthRootLayout::Builder(CodePointLayout::Builder('x'), CodePointLayout::Builder('2')); + } + case I18n::Message::SymbolArgFunction: + { + return NthRootLayout::Builder(CodePointLayout::Builder('x'), CodePointLayout::Builder('y')); + } + // Font size case I18n::Message::LargeFont: case I18n::Message::SmallFont: @@ -150,10 +205,15 @@ void PreferencesController::setPreferenceWithValueIndex(I18n::Message message, i preferences->setEditionMode((Preferences::EditionMode)valueIndex); } else if (message == I18n::Message::ComplexFormat) { preferences->setComplexFormat((Preferences::ComplexFormat)valueIndex); + } else if (message == I18n::Message::ExamModeMode) { + GlobalPreferences::sharedGlobalPreferences()->setTempExamMode((GlobalPreferences::ExamMode)((uint8_t)valueIndex + 1)); + } else if (message == I18n::Message::SymbolMultiplication) { + preferences->setSymbolMultiplication((Preferences::SymbolMultiplication)valueIndex); + } else if (message == I18n::Message::SymbolFunction) { + preferences->setSymbolOfFunction((Preferences::SymbolFunction)valueIndex); } else if (message == I18n::Message::FontSizes) { GlobalPreferences::sharedGlobalPreferences()->setFont(valueIndex == 0 ? KDFont::LargeFont : KDFont::SmallFont); } - } int PreferencesController::valueIndexForPreference(I18n::Message message) const { @@ -170,6 +230,12 @@ int PreferencesController::valueIndexForPreference(I18n::Message message) const if (message == I18n::Message::ComplexFormat) { return (int)preferences->complexFormat(); } + if (message == I18n::Message::SymbolMultiplication) { + return (int)preferences->symbolOfMultiplication(); + } + if (message == I18n::Message::SymbolFunction) { + return (int)preferences->symbolOfFunction(); + } if (message == I18n::Message::FontSizes) { return GlobalPreferences::sharedGlobalPreferences()->font() == KDFont::LargeFont ? 0 : 1; } diff --git a/apps/settings/sub_menu/preferences_controller.h b/apps/settings/sub_menu/preferences_controller.h index da15a6d93a4..6230b4cfd03 100644 --- a/apps/settings/sub_menu/preferences_controller.h +++ b/apps/settings/sub_menu/preferences_controller.h @@ -16,7 +16,7 @@ class PreferencesController : public GenericSubController { KDCoordinate rowHeight(int j) override; TELEMETRY_ID("Other"); protected: - constexpr static int k_totalNumberOfCell = 3; + constexpr static int k_totalNumberOfCell = 7; int initialSelectedRow() const override { return valueIndexForPreference(m_messageTreeModel->label()); } private: constexpr static const KDFont * k_layoutFont = KDFont::SmallFont; diff --git a/apps/settings/sub_menu/selectable_view_with_messages.cpp b/apps/settings/sub_menu/selectable_view_with_messages.cpp index 08ede69b5ec..8e64acce4a4 100644 --- a/apps/settings/sub_menu/selectable_view_with_messages.cpp +++ b/apps/settings/sub_menu/selectable_view_with_messages.cpp @@ -14,12 +14,12 @@ SelectableViewWithMessages::SelectableViewWithMessages(SelectableTableView * sel for (int i = 0; i < k_maxNumberOfLines; i++) { m_messageLines[i].setFont(KDFont::SmallFont); m_messageLines[i].setAlignment(0.5f, 0.5f); - m_messageLines[i].setBackgroundColor(Palette::WallScreen); + m_messageLines[i].setBackgroundColor(Palette::BackgroundApps); } } void SelectableViewWithMessages::drawRect(KDContext * ctx, KDRect rect) const { - ctx->fillRect(bounds(), Palette::WallScreen); + ctx->fillRect(bounds(), Palette::BackgroundApps); } void SelectableViewWithMessages::setMessages(I18n::Message * m, int numberOfMessages) { diff --git a/apps/shared.de.i18n b/apps/shared.de.i18n index 80bb683d824..9d3c2927bed 100644 --- a/apps/shared.de.i18n +++ b/apps/shared.de.i18n @@ -80,6 +80,7 @@ StorageMemoryFull1 = "Der Speicher ist voll. Löschen Sie" StorageMemoryFull2 = "einige Daten und versuchen Sie es erneut." StoreExpressionNotAllowed = "'store' ist verboten" SyntaxError = "Syntaxfehler" +Sym = "sym" TEnd = "T Endwert" ThetaEnd = "θ Endwert" ThetaStart = "θ Startwert" @@ -90,3 +91,11 @@ ValuesTab = "Tabelle" Warning = "Achtung" XEnd = "X Endwert" XStart = "X Startwert" +Zoom = "Zoom" +Developers = "Entwickler" +BetaTesters = "Beta-Tester" +ExamModeMode = "Modus" +ExamModeModeStandard = "Standard " +ExamModeModeNoSym = "Kein Symbol " +ExamModeModeNoSymNoText = "Kein Symbol kein Text " +ExamModeModeDutch = "Niederländisch " diff --git a/apps/shared.en.i18n b/apps/shared.en.i18n index 8436f6ffa1c..d61df44e108 100644 --- a/apps/shared.en.i18n +++ b/apps/shared.en.i18n @@ -80,6 +80,7 @@ Step = "Step" StorageMemoryFull1 = "The memory is full." StorageMemoryFull2 = "Erase data and try again." SyntaxError = "Syntax error" +Sym = "sym" TEnd = "T end" ThetaEnd = "θ end" ThetaStart = "θ start" @@ -90,3 +91,11 @@ ValuesTab = "Table" Warning = "Warning" XEnd = "X end" XStart = "X start" +Zoom = "Zoom" +Developers = "Developers" +BetaTesters = "Beta testers" +ExamModeMode = "Mode" +ExamModeModeStandard = "Standard " +ExamModeModeNoSym = "No sym " +ExamModeModeNoSymNoText = "No sym no text " +ExamModeModeDutch = "Dutch " diff --git a/apps/shared.es.i18n b/apps/shared.es.i18n index 8b9f366cf0c..e542571edab 100644 --- a/apps/shared.es.i18n +++ b/apps/shared.es.i18n @@ -80,6 +80,7 @@ StorageMemoryFull1 = "La memoria está llena." StorageMemoryFull2 = "Borre datos e intente de nuevo." StoreExpressionNotAllowed = "'store' no está permitido" SyntaxError = "Error sintáctico" +Sym = "sim" TEnd = "T fin" ThetaEnd = "θ fin" ThetaStart = "θ inicio" @@ -90,3 +91,11 @@ ValuesTab = "Tabla" Warning = "Cuidado" XEnd = "X fin" XStart = "X inicio" +Zoom = "Zoom" +Developers = "Desarrolladores" +BetaTesters = "Probadores beta" +ExamModeMode = "Modo" +ExamModeModeStandard = "Estándar " +ExamModeModeNoSym = "Sin simbólico " +ExamModeModeNoSymNoText = "Sin simbólico sin texto " +ExamModeModeDutch = "Holandés " diff --git a/apps/shared.fr.i18n b/apps/shared.fr.i18n index df8873c706c..46b76202d59 100644 --- a/apps/shared.fr.i18n +++ b/apps/shared.fr.i18n @@ -80,6 +80,7 @@ StorageMemoryFull1 = "La mémoire est pleine." StorageMemoryFull2 = "Effacez des données et réessayez." StoreExpressionNotAllowed = "'store' n'est pas autorisé" SyntaxError = "Attention à la syntaxe" +Sym = "sym" TEnd = "T fin" ThetaEnd = "θ fin" ThetaStart = "θ début" @@ -90,3 +91,11 @@ ValuesTab = "Tableau" Warning = "Attention" XEnd = "X fin" XStart = "X début" +Zoom = "Zoom" +Developers = "Développeurs" +BetaTesters = "Beta testeurs" +ExamModeMode = "Mode" +ExamModeModeStandard = "Standard " +ExamModeModeNoSym = "Sans symbolique " +ExamModeModeNoSymNoText = "Sans symbolique ni texte " +ExamModeModeDutch = "Dutch " diff --git a/apps/shared.hu.i18n b/apps/shared.hu.i18n new file mode 100644 index 00000000000..60ba0754b34 --- /dev/null +++ b/apps/shared.hu.i18n @@ -0,0 +1,101 @@ +ActivateDeactivate = "Ki/Be kapcsolás" +ActivateExamMode = "A vizsgálati mód aktiválása" +ActivateDutchExamMode = "A holland vizsga mód aktiválása" +ActiveExamModeMessage1 = "Az összes adatod" +ActiveExamModeMessage2 = "törölve lesz ha" +ActiveExamModeMessage3 = "a vizsga módot aktiválja." +ActiveDutchExamModeMessage1 = "Az összes adatod törölve lesz" +ActiveDutchExamModeMessage2 = "ha a vizsga módot aktiválja. A" +ActiveDutchExamModeMessage3 = "Python alkalmazás használhatatlan lesz." +Axis = "Tengelyek" +Cancel = "Mégse" +ClearColumn = "Oszlop törlése" +ColumnOptions = "Oszlop opciók" +ConfirmDiscard1 = "Minden változtatást elvetünk" +ConfirmDiscard2 = "" +CopyColumnInList = "Az oszlopot egy listába másolni" +Country = "Ország" +CountryCA = "Kanada " +CountryDE = "Németország " +CountryES = "Spanyolország " +CountryFR = "Franciaország " +CountryGB = "Egyesült Királyság " +CountryIT = "Olaszország " +CountryNL = "Hollandia " +CountryPT = "Portugália " +CountryUS = "Egyesült Államok " +CountryWW = "Nemzetközi " +CountryWarning1 = "Ez a beállítás meghatározza az" +CountryWarning2 = "alkalmazott tematikus konvenciókat." +DataNotSuitable = "Az adatok nem felelnek meg" +DataTab = "Adatok" +Deg = "deg" +Deviation = "Varianca" +DisplayValues = "Értékek mutatása" +Empty = "Üres" +Eng = "eng" +ExitExamMode1 = "Kilépni a vizsga " +ExitExamMode2 = "módból?" +Exponential = "Exponenciális" +FillWithFormula = "Töltse ki egy képlettel" +ForbiddenValue = "Tiltott érték" +FunctionColumn = "0(0) oszlop" +FunctionOptions = "Funkció opciók" +Goto = "Menj ..." +GraphTab = "Grafikon" +HardwareTestLaunch1 = "A hardverteszt indítása :" +HardwareTestLaunch2 = "Nyomjon a reset gombra a" +HardwareTestLaunch3 = "teszt megállításához (ez" +HardwareTestLaunch4 = "az adatokat törölni fogja)" +IntervalSet = "Állítsa be az intervallumot" +Language = "Nyelv" +LowBattery = "Majdnem kimerült az elem" +Mean = "középérték" +Move = " Odébb rakni: " +NameCannotStartWithNumber = "Egy név nem kezdöthet számmal" +NameTaken = "Ez a név foglalt" +NameTooLong = "Ez a név túl hosszú" +Navigate = "Hajózik" +Next = "következö" +NEnd = "N vége" +NoDataToPlot = "Nincs rajzolható adat" +NoFunctionToDelete = "Nincs törölhetö függvény" +NoValueToCompute = "Nincs számítható érték" +NStart = "N kezdete" +Ok = "Érvényesítés" +Or = " vagy " +Orthonormal = "Ortonormált" +Plot = "Grafikon rajzolása" +PoolMemoryFull1 = "A memória megtelt." +PoolMemoryFull2 = "Kérem próbálja újra." +Rename = "Átnevezés" +Sci = "sci" +SortValues = "Rendezés értékek növelésével" +SortSizes = "Rendezés növekvő frekvenciák szerint" +SquareSum = "Négyzetek összege" +StandardDeviation = "Alap eltérés" +StatTab = "Statisztikák" +Step = "Lépés" +StorageMemoryFull1 = "A memória megtelt." +StorageMemoryFull2 = "Törlöljön adatokat és próbálkozzon újra." +StoreExpressionNotAllowed = "'szore' nem engedélyezett" +SyntaxError = "Szintaxis hiba" +Sym = "sym" +TEnd = "T vég" +ThetaEnd = "θ vége" +ThetaStart = "θ kezdete" +TStart = "T kezdete" +ToZoom = "Nagyítani : " +UndefinedValue = "Meghatározatlan adat" +ValuesTab = "Táblázat" +Warning = "Figyelem" +XEnd = "X vége" +XStart = "X kezdete" +Zoom = "Nagyítás" +Developers = "Kifejlesztök" +BetaTesters = "Béta tesztelök" +ExamModeMode = "Üzemmód" +ExamModeModeStandard = "Normál " +ExamModeModeNoSym = "Szimbólikus nélkül " +ExamModeModeNoSymNoText = "Szimbólikus és szöveg nélkül " +ExamModeModeDutch = "Holland " diff --git a/apps/shared.it.i18n b/apps/shared.it.i18n index b00d97b08a2..3322800c8c5 100644 --- a/apps/shared.it.i18n +++ b/apps/shared.it.i18n @@ -80,6 +80,7 @@ StorageMemoryFull1 = "La memoria è piena." StorageMemoryFull2 = "Cancellate i dati e riprovate." StoreExpressionNotAllowed = "'store' non è consentito" SyntaxError = "Sintassi errata" +Sym = "sym" TEnd = "T finale" ThetaEnd = "θ finale" ThetaStart = "θ iniziale" @@ -90,3 +91,11 @@ ValuesTab = "Tabella" Warning = "Attenzione" XEnd = "X finale" XStart = "X iniziale" +Zoom = "Zoom" +Developers = "Developers" +BetaTesters = "Beta testers" +ExamModeMode = "Modalità" +ExamModeModeStandard = "Standard " +ExamModeModeNoSym = "Nessun simbolo " +ExamModeModeNoSymNoText = "Nessun simbolo nessun testo " +ExamModeModeDutch = "Olandese " diff --git a/apps/shared.nl.i18n b/apps/shared.nl.i18n index 30cde4aeacf..b3971aa6cfe 100644 --- a/apps/shared.nl.i18n +++ b/apps/shared.nl.i18n @@ -80,6 +80,7 @@ Step = "Stap" StorageMemoryFull1 = "Het geheugen is vol." StorageMemoryFull2 = "Wis de gegevens en probeer opnieuw." SyntaxError = "Syntaxisfout" +Sym = "sym" TEnd = "T einde" ThetaEnd = "θ einde" ThetaStart = "θ begin" @@ -90,3 +91,11 @@ ValuesTab = "Tabel" Warning = "Waarschuwing" XEnd = "X einde" XStart = "X begin" +Zoom = "Zoom" +Developers = "Developers" +BetaTesters = "Beta testers" +ExamModeMode = "Mode" +ExamModeModeStandard = "Standaard " +ExamModeModeNoSym = "Geen sym " +ExamModeModeNoSymNoText = "Geen sym geen tekst " +ExamModeModeDutch = "Nederlands " diff --git a/apps/shared.pt.i18n b/apps/shared.pt.i18n index 80009b7d942..39fa24c1261 100644 --- a/apps/shared.pt.i18n +++ b/apps/shared.pt.i18n @@ -80,6 +80,7 @@ StorageMemoryFull1 = "A memória esta cheia." StorageMemoryFull2 = "Apage dados e tente novamente." StoreExpressionNotAllowed = "'store' não está permitido" SyntaxError = "Erro de sintaxe" +Sym = "sim" TEnd = "T fim" ThetaEnd = "θ fim" ThetaStart = "θ início" @@ -90,3 +91,11 @@ ValuesTab = "Tabela" Warning = "Atenção" XEnd = "X fim" XStart = "X início" +Zoom = "Zoom" +Developers = "Desenvolvedores" +BetaTesters = "Testadores beta" +ExamModeMode = "Modo" +ExamModeModeStandard = "Padrão " +ExamModeModeNoSym = "Sem sym " +ExamModeModeNoSymNoText = "Sem sym sem texto " +ExamModeModeDutch = "holandês " diff --git a/apps/shared.universal.i18n b/apps/shared.universal.i18n index 03f8b3f03c8..fb927a65962 100644 --- a/apps/shared.universal.i18n +++ b/apps/shared.universal.i18n @@ -41,6 +41,9 @@ UnitAmountMoleSymbol = "_mol" UnitAmountMoleMilliSymbol = "_mmol" UnitAmountMoleMicroSymbol = "_μmol" UnitLuminousIntensityCandelaSymbol = "_cd" +UnitLuminousFluxLumenSymbol = "_lm" +UnitIlluminanceLuxSymbol = "_lx" +UnitSolidAngleSteradianSymbol = "_sr" UnitFrequencyHertzGigaSymbol = "_GHz" UnitFrequencyHertzMegaSymbol = "_MHz" UnitFrequencyHertzKiloSymbol = "_kHz" @@ -131,6 +134,7 @@ GcdCommandWithArg = "gcd(p,q)" Gon = "gon" ImCommandWithArg = "im(z)" IndentityCommandWithArg = "identity(n)" +Infinity = "infinity" IntCommand = "int(\x11,x,\x11,\x11)" IntCommandWithArg = "int(f(x),x,a,b)" InvBinomialCommandWithArg = "invbinom(a,n,p)" @@ -191,3 +195,266 @@ X = "x" YMax = "Ymax" YMin = "Ymin" Y = "y" +ElementHMass = "1.00794" +ElementHeMass = "4.002602" +ElementLiMass = "6.941" +ElementBeMass = "9.0121831" +ElementBMass = "10.81" +ElementCMass = "12.01074" +ElementNMass = "14.0067" +ElementOMass = "15.9994" +ElementFMass = "18.998403163" +ElementNeMass = "20.1797" +ElementNaMass = "22.98976928" +ElementMgMass = "24.3050" +ElementAlMass = "26.9815386" +ElementSiMass = "28.0855" +ElementPMass = "30.973761998" +ElementSMass = "32.065" +ElementClMass = "35.453" +ElementArMass = "39.948" +ElementKMass = "39.0983" +ElementCaMass = "40.078" +ElementScMass = "44.955908" +ElementTiMass = "47.867" +ElementVMass = "50.9415" +ElementCrMass = "51.9961" +ElementMnMass = "54.938044" +ElementFeMass = "55.845" +ElementCoMass = "58.933194" +ElementNiMass = "58.6934" +ElementCuMass = "63.546" +ElementZnMass = "65.409" +ElementGaMass = "69.723" +ElementGeMass = "72.64" +ElementAsMass = "74.921595" +ElementSeMass = "78.971" +ElementBrMass = "79.904" +ElementKrMass = "83.798" +ElementRbMass = "85.4678" +ElementSrMass = "87.62" +ElementYMass = "88.90584" +ElementZrMass = "91.224" +ElementNbMass = "92.90637" +ElementMoMass = "95.95" +ElementTcMass = "98" +ElementRuMass = "101.07" +ElementRhMass = "102.90550" +ElementPdMass = "106.42" +ElementAgMass = "107.8682" +ElementCdMass = "112.414" +ElementInMass = "114.818" +ElementSnMass = "118.710" +ElementSbMass = "121.760" +ElementTeMass = "127.60" +ElementIMass = "126.90447" +ElementXeMass = "131.293" +ElementCsMass = "132.90545196" +ElementBaMass = "137.327" +ElementLaMass = "138.90547" +ElementCeMass = "140.116" +ElementPrMass = "140.90766" +ElementNdMass = "144.242" +ElementPmMass = "145" +ElementSmMass = "150.36" +ElementEuMass = "151.964" +ElementGdMass = "157.25" +ElementTbMass = "158.92534" +ElementDyMass = "162.500" +ElementHoMass = "164.93033" +ElementErMass = "167.259" +ElementTmMass = "168.93422" +ElementYbMass = "173.04" +ElementLuMass = "174.9668" +ElementHfMass = "178.49" +ElementTaMass = "180.94788" +ElementWMass = "183.84" +ElementReMass = "186.207" +ElementOsMass = "190.23" +ElementIrMass = "192.217" +ElementPtMass = "195.084" +ElementAuMass = "196.966569" +ElementHgMass = "200.59" +ElementTlMass = "204.3833" +ElementPbMass = "207.2" +ElementBiMass = "208.98040" +ElementPoMass = "209" +ElementAtMass = "210" +ElementRnMass = "222" +ElementFrMass = "223" +ElementRaMass = "226.0254" +ElementAcMass = "227" +ElementThMass = "232.0377" +ElementPaMass = "231.03588" +ElementUMass = "238.02891" +ElementNpMass = "237" +ElementPuMass = "244.06" +ElementAmMass = "241.06" +ElementCmMass = "247" +ElementBkMass = "247" +ElementCfMass = "251" +ElementEsMass = "252" +ElementFmMass = "257" +ElementMdMass = "258" +ElementNoMass = "259" +ElementLrMass = "266" +ElementRfMass = "267" +ElementDbMass = "268" +ElementSgMass = "269" +ElementBhMass = "270" +ElementHsMass = "277" +ElementMtMass = "278" +ElementDsMass = "281" +ElementRgMass = "282" +ElementCnMass = "285" +ElementNhMass = "286" +ElementFlMass = "289" +ElementMcMass = "289" +ElementLvMass = "293" +ElementTsMass = "294" +ElementOgMass = "294" +ElementUueMass = "295" +ElementUbnMass = "297" +QuentinGuidee = "Quentin Guidée" +PQuentinGuidee = "@quentinguidee" +SandraSimmons = "Sandra Simmons" +PSandraSimmons = "@MixedMatched" +JoachimLeFournis = "Joachim Le Fournis" +PJoachimLeFournis = "@RedGl0w" +JeanBaptisteBoric = "Jean-Baptiste Boric" +PJeanBaptisteBoric = "@boricj" +MaximeFriess = "Maxime Friess" +PMaximeFriess = "@M4x1m3" +David = "David" +PDavid = "@0b101" +DamienNicolet = "Damien Nicolet" +PDamienNicolet = "@zardam" +EvannDreumont = "Evann Dreumont" +PEvannDreumont = "@LeGmask" +SzaboLevente = "Szabó Levente" +PSzaboLevente = "@Gegenter" +CharlotteThomas = "Charlotte Thomas" +PCharlotteThomas = "@coco33920" +AntoninLoubiere = "Antonin L." +PAntoninLoubiere = "@AntoninLoubiere" +VenceslasDuet = "Venceslas Duet" +PVenceslasDuet = "@Citorva" +CyprienMejat = "Cyprien Méjat" +PCyprienMejat = "@A2drien" +TimeoArnouts = "Timéo Arnouts" +PTimeoArnouts = "@Dogm" +JulieC = "Julie C." +PJulieC = "@windows9x95" +LelahelHideux = "Lélahel Hideux" +PLelahelHideux = "@Lelahelry" +Madil = "Madil" +PMadil = "@le-grand-mannitout" +HilaireLeRoux = "Hilaire Le Roux" +PHilaireLeRoux = "@0Babass2" +HectorNussbaumer = "Hector Nussbaumer" +PHectorNussbaumer = "@Sycorax" +RaphaelDyda = "Raphaël Dyda" +PRaphaelDyda = "@Trixciel" +ThibautC = "Thibaut C." +PThibautC = "@Tibo_C" +SpeedOfLight = "2.99792458·10^8_m_s^-1" +YearLight = "9.461·10^15_m" +Boltzmann = "1.380649·10^-23_J_K^-1" +StefanBoltzmann = "5.670374419·10^-8_W_m^-2_K^-4" +VacuumImpedance = "376.730313668_Ω" +WaterTriplePoint = "273.16_K" +AtmosphericPressure = "101325_Pa" +AtomicMassUnit = "1.66053906660·10^-27_kg" +Wien = "2.897771955·10^-3_K_m" +BohrRadius = "5.29177210903·10^-11_m" +BohrMagneton = "9.2740100783·10^-24_A_m^2" +NuclearMagneton = "5.0507837461·10^-27_A_m^2" +MuonMass = "1.883531627·10^-28_kg" +Avogadro = "6.02214076·10^23_mol^-1" +Gas = "8.314462618_J_mol^-1_K^-1" +Coulomb = "8.9875517923·10^9_N_m^2_C^-2" +Vacuum_permittivity = "8.8541878128·10^-12_F_m^-1" +Vacuum_permeability = "1.25663706212·10^-6_H_m^-1" +Planck = "6.62607015·10^-34_J_s" +ElectronMass = "9.1093837015·10^-31_kg" +ProtonMass = "1.67262192369·10^-27_kg" +NeutronMass = "1.67492749804·10^-27_kg" +ElementalCharge = "1.602176634·10^-19_C" +GAcceleration = "9.80665_m_s^-2" +GConstant = "6.67430·10^-11_m^3_kg^-1_s^-2" +SpeedOfSound0 = "343.4_m_s^-1" +SpeedOfSoundWater = "1480_m_s^-1" +SpeedOfSoundSteel = "5600_m_s^-1" +SpeedOfSoundGlass = "5300_m_s^-1" +SunMass = "1.989·10^30_kg" +EarthMass = "5.972·10^24_kg" +MoonMass = "7.342·10^22_kg" +SunRadius = "696000000_m" +EarthRadius = "6378140_m" +MoonRadius = "3474600_m" +EarthMoonDistance = "384400000_m" +EarthSunDistance = "149597870000_m" +FaradayConstant = "96485.33212_C_mol^-1" +EscapeVelocityOfEarth = "11186_m_s^-1" +EscapeVelocityOfMoon = "2380_m_s^-1" +EscapeVelocityOfSun = "42100_m_s^-1" +UltimateAnswer = "Ultimate Answer" +UltimateAnswerValue = "42" +Pka01 = "H20/OH-" +Pka02 = "HS-/S(2-)" +Pka03 = "HPO4(2-)/PO4(3-)" +Pka04 = "HCO3-/CO3(2-)" +Pka05 = "C6H5OH/C6H5O-" +Pka06 = "NH4+/NH3" +Pka07 = "HBrO/BrO-" +Pka08 = "H2PO4-/HP04(2-)" +Pka09 = "H2S/HS-" +Pka10 = "H2C03/HC03-" +Pka11 = "CH3COOH/CH3COO-" +Pka12 = "C6H5COOH/C6H5COO-" +Pka13 = "HN02/NO2-" +Pka14 = "H3PO4/H2PO4-" +Pka15 = "HS04-/S04(2-)" +Pka16 = "H30+/H20" +Pka01Value = "14" +Pka02Value = "13.0" +Pka03Value = "12.7" +Pka04Value = "10.2" +Pka05Value = "9.9" +Pka06Value = "9.2" +Pka07Value = "8.7" +Pka08Value = "7.2" +Pka09Value = "7.0" +Pka10Value = "6.4" +Pka11Value = "4.7" +Pka12Value = "4.2" +Pka13Value = "3.4" +Pka14Value = "2.1" +Pka15Value = "1.9" +Pka16Value = "0" +Pka = "pKa" +PlanckReduce = "1.054571817·10^-34_J_s" +PlanckMass = "2.176434·10^-8_kg" +PlanckLength = "1.616255·10^-35_m" +PlanckTime = "5.391247·10^-44_s" +PlanckTemperature = "1.416784·10^32_K" +PlanckCharge = "1.875·10^-18_C" +PlanckForce = "1.210·10^44_N" +PlanckEnergy = "1.956·10^9_J" +PlanckPower = "3.629·10^52_W" +PlanckDensity = "5.1·10^96_kg_m^-3" +PlanckQuantityMovement = "6.5_N_s" +PlanckLinearMass = "1.34664·10^27_kg_m^-1" +PlanckTension = "1.0432·10^27_V" +PlanckCurrent = "3.479·10^25_A" +PlanckPressure = "4.635·10^113_Pa" +PlanckImpedance = "29.986_Ω" +TauonMass = "3.16754·10^-27_kg" +WBosonMass = "1.4334·10^-25_kg" +ZBosonMass = "1.62556·10^-25_kg" +FineStructure = "7.2973525693·10^-3" +RydbergConstant = "10973731.568160_m^-1" +HartreeConstant = "4.3597447222071·10^-18_J" +MagneticFluxQuantum = "2.067833848·10^-15_Wb" +ConductanceQuantum = "7.748091729·10^-5_S" +CirculationQuantum = "3.6369475516·10^-4_m^2_s^-1" diff --git a/apps/shared/banner_view.h b/apps/shared/banner_view.h index 601f0e9c851..b1ad6e5fc5d 100644 --- a/apps/shared/banner_view.h +++ b/apps/shared/banner_view.h @@ -13,8 +13,8 @@ class BannerView : public View { KDCoordinate minimalHeightForOptimalDisplayGivenWidth(KDCoordinate width) const; void reload() { layoutSubviews(); } static constexpr const KDFont * Font() { return KDFont::SmallFont; } - static constexpr KDColor TextColor() { return KDColorBlack; } - static constexpr KDColor BackgroundColor() { return Palette::GrayMiddle; } + static constexpr KDColor TextColor() { return Palette::PrimaryText; } + static constexpr KDColor BackgroundColor() { return Palette::SubMenuBackground; } private: static constexpr KDCoordinate LineSpacing = 2; int numberOfSubviews() const override = 0; diff --git a/apps/shared/buffer_text_view_with_text_field.cpp b/apps/shared/buffer_text_view_with_text_field.cpp index 30008741d81..e6740cb2f46 100644 --- a/apps/shared/buffer_text_view_with_text_field.cpp +++ b/apps/shared/buffer_text_view_with_text_field.cpp @@ -24,18 +24,18 @@ void BufferTextViewWithTextField::drawRect(KDContext * ctx, KDRect rect) const { // Fill margins with white // Left margin - ctx->fillRect(KDRect(0, 0, Metric::TitleBarExternHorizontalMargin, bounds().height()), KDColorWhite); - ctx->fillRect(KDRect(bounds().width() - Metric::TitleBarExternHorizontalMargin, 0, Metric::TitleBarExternHorizontalMargin, bounds().height()), KDColorWhite); + ctx->fillRect(KDRect(0, 0, Metric::TitleBarExternHorizontalMargin, bounds().height()), Palette::BackgroundHard); + ctx->fillRect(KDRect(bounds().width() - Metric::TitleBarExternHorizontalMargin, 0, Metric::TitleBarExternHorizontalMargin, bounds().height()), Palette::BackgroundHard); // Right margin - ctx->fillRect(KDRect(bounds().width() - Metric::TitleBarExternHorizontalMargin, 0, Metric::TitleBarExternHorizontalMargin, bounds().height()), KDColorWhite); + ctx->fillRect(KDRect(bounds().width() - Metric::TitleBarExternHorizontalMargin, 0, Metric::TitleBarExternHorizontalMargin, bounds().height()), Palette::BackgroundHard); // Above the text field - ctx->fillRect(KDRect(textFieldRect.x() - k_borderWidth, 0, textFieldRect.width() + 2*k_borderWidth, bounds().height()), KDColorWhite); + ctx->fillRect(KDRect(textFieldRect.x() - k_borderWidth, 0, textFieldRect.width() + 2*k_borderWidth, bounds().height()), Palette::BackgroundHard); // Under the text field - ctx->fillRect(KDRect(textFieldRect.x() - k_borderWidth, textFieldRect.bottom() + k_borderWidth, textFieldRect.width() + 2*k_borderWidth, bounds().height()), KDColorWhite); + ctx->fillRect(KDRect(textFieldRect.x() - k_borderWidth, textFieldRect.bottom() + k_borderWidth, textFieldRect.width() + 2*k_borderWidth, bounds().height()), Palette::BackgroundHard); // Draw the text field border KDRect borderRect = KDRect(textFieldRect.x()-k_borderWidth, textFieldRect.y()-k_borderWidth, textFieldRect.width()+2*k_borderWidth, textFieldRect.height()+2*k_borderWidth); - ctx->strokeRect(borderRect, Palette::GrayMiddle); + ctx->strokeRect(borderRect, Palette::ListCellBorder); } void BufferTextViewWithTextField::didBecomeFirstResponder() { diff --git a/apps/shared/button_with_separator.cpp b/apps/shared/button_with_separator.cpp index 0dabce4249c..3b3d1b69f63 100644 --- a/apps/shared/button_with_separator.cpp +++ b/apps/shared/button_with_separator.cpp @@ -1,22 +1,22 @@ #include "button_with_separator.h" ButtonWithSeparator::ButtonWithSeparator(Responder * parentResponder, I18n::Message message, Invocation invocation) : - Button(parentResponder, message, invocation, KDFont::LargeFont, KDColorBlack) + Button(parentResponder, message, invocation, KDFont::LargeFont, Palette::ButtonText) { } void ButtonWithSeparator::drawRect(KDContext * ctx, KDRect rect) const { KDCoordinate width = bounds().width(); KDCoordinate height = bounds().height(); - ctx->fillRect(KDRect(0, 0, width, k_lineThickness), Palette::GrayBright); - ctx->fillRect(KDRect(0, k_lineThickness, width, k_margin-k_lineThickness), Palette::WallScreen); + ctx->fillRect(KDRect(0, 0, width, k_lineThickness), Palette::ListCellBorder); + ctx->fillRect(KDRect(0, k_lineThickness, width, k_margin-k_lineThickness), Palette::BackgroundApps); // Draw rectangle around cell - ctx->fillRect(KDRect(0, k_margin, width, k_lineThickness), Palette::GrayBright); - ctx->fillRect(KDRect(0, k_margin+k_lineThickness, k_lineThickness, height-k_margin), Palette::GrayBright); - ctx->fillRect(KDRect(width-k_lineThickness, k_lineThickness+k_margin, k_lineThickness, height-k_margin), Palette::GrayBright); - ctx->fillRect(KDRect(0, height-3*k_lineThickness, width, k_lineThickness), Palette::GrayWhite); - ctx->fillRect(KDRect(0, height-2*k_lineThickness, width, k_lineThickness), Palette::GrayBright); - ctx->fillRect(KDRect(k_lineThickness, height-k_lineThickness, width-2*k_lineThickness, k_lineThickness), Palette::GrayMiddle); + ctx->fillRect(KDRect(0, k_margin, width, k_lineThickness), Palette::ListCellBorder); + ctx->fillRect(KDRect(0, k_margin+k_lineThickness, k_lineThickness, height-k_margin), Palette::ListCellBorder); + ctx->fillRect(KDRect(width-k_lineThickness, k_lineThickness+k_margin, k_lineThickness, height-k_margin), Palette::ListCellBorder); + ctx->fillRect(KDRect(0, height-3*k_lineThickness, width, k_lineThickness), Palette::ButtonBorderOut); + ctx->fillRect(KDRect(0, height-2*k_lineThickness, width, k_lineThickness), Palette::ListCellBorder); + ctx->fillRect(KDRect(k_lineThickness, height-k_lineThickness, width-2*k_lineThickness, k_lineThickness), Palette::ButtonShadow); } diff --git a/apps/shared/cursor_view.cpp b/apps/shared/cursor_view.cpp index 792606be78f..90886b81ca1 100644 --- a/apps/shared/cursor_view.cpp +++ b/apps/shared/cursor_view.cpp @@ -5,8 +5,8 @@ namespace Shared { void CursorView::drawRect(KDContext * ctx, KDRect rect) const { KDCoordinate width = bounds().width(); KDCoordinate height = bounds().height(); - ctx->fillRect(KDRect((width-1)/2, 0, 1, height), KDColorBlack); - ctx->fillRect(KDRect(0, (height-1)/2, width, 1), KDColorBlack); + ctx->fillRect(KDRect((width-1)/2, 0, 1, height), Palette::PrimaryText); + ctx->fillRect(KDRect(0, (height-1)/2, width, 1), Palette::PrimaryText); } KDSize CursorView::minimalSizeForOptimalDisplay() const { diff --git a/apps/shared/cursor_view.h b/apps/shared/cursor_view.h index c0f5c60624f..830473c2403 100644 --- a/apps/shared/cursor_view.h +++ b/apps/shared/cursor_view.h @@ -2,6 +2,7 @@ #define SHARED_CURSOR_VIEW_H #include +#include namespace Shared { diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index e5f516ad0ba..25c22b796fb 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -285,7 +286,7 @@ void CurveView::drawLabel(KDContext * ctx, KDRect rect, float xPosition, float y KDPoint position = positionLabel(xCoordinate, yCoordinate, labelSize, horizontalPosition, verticalPosition); if (rect.intersects(KDRect(position, labelSize))) { // TODO: should we blend? - ctx->drawString(label, position, k_font, color, KDColorWhite); + ctx->drawString(label, position, k_font, color, Palette::BackgroundApps); } } @@ -368,7 +369,7 @@ void CurveView::drawLabelsAndGraduations(KDContext * ctx, KDRect rect, Axis axis labelPosition, k_labelGraduationLength, 1); - ctx->fillRect(graduation, KDColorBlack); + ctx->fillRect(graduation, Palette::PrimaryText); } } @@ -413,7 +414,7 @@ void CurveView::drawLabelsAndGraduations(KDContext * ctx, KDRect rect, Axis axis DrawLabel: if (rect.intersects(KDRect(position, textSize))) { - ctx->drawString(labelI, position, k_font, KDColorBlack, backgroundColor); + ctx->drawString(labelI, position, k_font, Palette::PrimaryText, backgroundColor); } } } @@ -556,8 +557,8 @@ void CurveView::drawArrow(KDContext * ctx, KDRect rect, float x, float y, float } void CurveView::drawGrid(KDContext * ctx, KDRect rect) const { - KDColor boldColor = Palette::GrayMiddle; - KDColor lightColor = Palette::GrayWhite; + KDColor boldColor = Palette::GridPrimaryLine; + KDColor lightColor = Palette::GridSecondaryLine; drawGridLines(ctx, rect, Axis::Vertical, m_curveViewRange->xGridUnit(), boldColor, lightColor); drawGridLines(ctx, rect, Axis::Horizontal, m_curveViewRange->yGridUnit(), boldColor, lightColor); } @@ -568,7 +569,7 @@ void CurveView::drawAxes(KDContext * ctx, KDRect rect) const { } void CurveView::drawAxis(KDContext * ctx, KDRect rect, Axis axis) const { - drawLine(ctx, rect, axis, 0.0f, KDColorBlack, 1); + drawLine(ctx, rect, axis, 0.0f, Palette::PrimaryText, 1); } constexpr KDCoordinate thinCircleDiameter = 1; diff --git a/apps/shared/curve_view.h b/apps/shared/curve_view.h index faf17ea5720..91e73c5b3c1 100644 --- a/apps/shared/curve_view.h +++ b/apps/shared/curve_view.h @@ -122,7 +122,7 @@ class CurveView : public View { }; // Draw the label at the above/below and to the left/right of the given position void drawLabel(KDContext * ctx, KDRect rect, float xPosition, float yPosition, const char * label, KDColor color, RelativePosition horizontalPosition, RelativePosition verticalPosition) const; - void drawLabelsAndGraduations(KDContext * ctx, KDRect rect, Axis axis, bool shiftOrigin, bool graduationOnly = false, bool fixCoordinate = false, KDCoordinate fixedCoordinate = 0, KDColor backgroundColor = KDColorWhite) const; + void drawLabelsAndGraduations(KDContext * ctx, KDRect rect, Axis axis, bool shiftOrigin, bool graduationOnly = false, bool fixCoordinate = false, KDCoordinate fixedCoordinate = 0, KDColor backgroundColor = Palette::BackgroundHard) const; View * m_bannerView; CurveViewCursor * m_curveViewCursor; private: diff --git a/apps/shared/function_expression_cell.cpp b/apps/shared/function_expression_cell.cpp index 72c4ada5b03..c4ea7924425 100644 --- a/apps/shared/function_expression_cell.cpp +++ b/apps/shared/function_expression_cell.cpp @@ -8,7 +8,7 @@ KDSize FunctionExpressionCell::minimalSizeForOptimalDisplay() const { } void FunctionExpressionCell::drawRect(KDContext * ctx, KDRect rect) const { - KDColor separatorColor = m_even ? Palette::WallScreen : KDColorWhite; + KDColor separatorColor = m_even ? Palette::BackgroundApps : Palette::BackgroundHard; // Color the horizontal separator ctx->fillRect(KDRect(0, bounds().height()-k_separatorThickness, bounds().width(), k_separatorThickness), separatorColor); // Color the left margin diff --git a/apps/shared/function_graph_view.cpp b/apps/shared/function_graph_view.cpp index 7e111f2bf84..cc8a532bf1a 100644 --- a/apps/shared/function_graph_view.cpp +++ b/apps/shared/function_graph_view.cpp @@ -18,7 +18,7 @@ FunctionGraphView::FunctionGraphView(InteractiveCurveViewRange * graphRange, } void FunctionGraphView::drawRect(KDContext * ctx, KDRect rect) const { - ctx->fillRect(rect, KDColorWhite); + ctx->fillRect(rect, Palette::BackgroundHard); drawGrid(ctx, rect); drawAxes(ctx, rect); simpleDrawBothAxesLabels(ctx, rect); diff --git a/apps/shared/function_list_controller.cpp b/apps/shared/function_list_controller.cpp index e6a0ab109e2..d8dbf2ad7a3 100644 --- a/apps/shared/function_list_controller.cpp +++ b/apps/shared/function_list_controller.cpp @@ -17,13 +17,13 @@ FunctionListController::FunctionListController(Responder * parentResponder, Butt TabViewController * tabController = list->tabController(); tabController->setActiveTab(1); return true; - }, this), KDFont::SmallFont, Palette::PurpleBright), + }, this), KDFont::SmallFont, Palette::ButtonText), m_valuesButton(this, I18n::Message::DisplayValues, Invocation([](void * context, void * sender) { FunctionListController * list = (FunctionListController *)context; TabViewController * tabController = list->tabController(); tabController->setActiveTab(2); return true; - }, this), KDFont::SmallFont, Palette::PurpleBright), + }, this), KDFont::SmallFont, Palette::ButtonText), m_titlesColumnWidth(k_minTitleColumnWidth) { /* m_memoizedCellBaseline is not initialized by the call to diff --git a/apps/shared/function_title_cell.cpp b/apps/shared/function_title_cell.cpp index 007ff72371c..c57120bfb06 100644 --- a/apps/shared/function_title_cell.cpp +++ b/apps/shared/function_title_cell.cpp @@ -23,8 +23,8 @@ void FunctionTitleCell::setBaseline(KDCoordinate baseline) { void FunctionTitleCell::drawRect(KDContext * ctx, KDRect rect) const { if (m_orientation == Orientation::VerticalIndicator){ - KDColor separatorColor = m_even ? Palette::WallScreen : KDColorWhite; - KDColor backgroundColor = m_even ? KDColorWhite : Palette::WallScreen; + KDColor separatorColor = m_even ? Palette::BackgroundApps : Palette::BackgroundHard; + KDColor backgroundColor = m_even ? Palette::BackgroundHard : Palette::BackgroundApps; // Draw the color indicator ctx->fillRect(KDRect(0, 0, k_colorIndicatorThickness, bounds().height()), m_functionColor); // Draw the horizontal separator diff --git a/apps/shared/function_title_cell.h b/apps/shared/function_title_cell.h index efb3480efef..39ea199acf8 100644 --- a/apps/shared/function_title_cell.h +++ b/apps/shared/function_title_cell.h @@ -15,7 +15,7 @@ class FunctionTitleCell : public EvenOddCell { EvenOddCell(), m_orientation(orientation), m_baseline(-1), - m_functionColor(KDColorBlack) + m_functionColor(Palette::PrimaryText) {} virtual void setOrientation(Orientation orientation); virtual void setColor(KDColor color); diff --git a/apps/shared/function_zoom_and_pan_curve_view_controller.cpp b/apps/shared/function_zoom_and_pan_curve_view_controller.cpp index d32e102e8f3..2b6ab38af6f 100644 --- a/apps/shared/function_zoom_and_pan_curve_view_controller.cpp +++ b/apps/shared/function_zoom_and_pan_curve_view_controller.cpp @@ -105,7 +105,7 @@ FunctionZoomAndPanCurveViewController::ContentView::LegendView::LegendView() for (int i = 0; i < k_numberOfLegends; i++) { m_legends[i].setFont(KDFont::SmallFont); m_legends[i].setMessage(messages[i]); - m_legends[i].setBackgroundColor(Palette::GrayBright); + m_legends[i].setBackgroundColor(Palette::SubMenuBackground); m_legends[i].setAlignment(horizontalAlignments[i], 0.5f); } KeyView::Type tokenTypes[k_numberOfTokens] = {KeyView::Type::Up, KeyView::Type::Down, KeyView::Type::Left, KeyView::Type::Right, KeyView::Type::Plus, KeyView::Type::Minus}; @@ -115,7 +115,7 @@ FunctionZoomAndPanCurveViewController::ContentView::LegendView::LegendView() } void FunctionZoomAndPanCurveViewController::ContentView::LegendView::drawRect(KDContext * ctx, KDRect rect) const { - ctx->fillRect(KDRect(0, bounds().height() - k_legendHeight, bounds().width(), k_legendHeight), Palette::GrayBright); + ctx->fillRect(KDRect(0, bounds().height() - k_legendHeight, bounds().width(), k_legendHeight), Palette::SubMenuBackground); } int FunctionZoomAndPanCurveViewController::ContentView::LegendView::numberOfSubviews() const { diff --git a/apps/shared/hideable.h b/apps/shared/hideable.h index 94ff3b998df..12d54d006d8 100644 --- a/apps/shared/hideable.h +++ b/apps/shared/hideable.h @@ -10,7 +10,7 @@ class Hideable { Hideable() : m_hide(false) {} - static KDColor hideColor() { return Palette::WallScreenDark; } + static KDColor hideColor() { return Palette::BackgroundAppsSecondary; } bool hidden() const { return m_hide; } virtual void setHide(bool hide) { m_hide = hide; } virtual void reinit() {} diff --git a/apps/shared/localization_controller.cpp b/apps/shared/localization_controller.cpp index a0a99d43ee0..ad7da122b4e 100644 --- a/apps/shared/localization_controller.cpp +++ b/apps/shared/localization_controller.cpp @@ -11,7 +11,7 @@ LocalizationController::ContentView::ContentView(LocalizationController * contro m_controller(controller), m_selectableTableView(controller, controller, dataSource), m_countryTitleMessage(KDFont::LargeFont, I18n::Message::Country), - m_borderView(Palette::GrayBright) + m_borderView(Palette::BackgroundApps) { m_countryTitleMessage.setBackgroundColor(Palette::WallScreen); m_countryTitleMessage.setAlignment(0.5f, 0.5f); diff --git a/apps/shared/message_view.cpp b/apps/shared/message_view.cpp index 819c8dafe3f..3bc257ab0f4 100644 --- a/apps/shared/message_view.cpp +++ b/apps/shared/message_view.cpp @@ -12,7 +12,7 @@ MessageView::MessageView(I18n::Message * messages, KDColor * colors, uint8_t num } void MessageView::drawRect(KDContext * ctx, KDRect rect) const { - ctx->fillRect(bounds(), KDColorWhite); + ctx->fillRect(bounds(), Palette::BackgroundHard); } View * MessageView::subviewAtIndex(int index) { diff --git a/apps/shared/ok_view.cpp b/apps/shared/ok_view.cpp index 0f531cd04ea..7a11f3a56a7 100644 --- a/apps/shared/ok_view.cpp +++ b/apps/shared/ok_view.cpp @@ -30,7 +30,7 @@ void OkView::drawRect(KDContext * ctx, KDRect rect) const { KDCoordinate height = bounds().height(); KDRect frame((width-k_okSize)/2, (height-k_okSize)/2, k_okSize, k_okSize); KDColor okWorkingBuffer[OkView::k_okSize*OkView::k_okSize]; - ctx->blendRectWithMask(frame, KDColorBlack, (const uint8_t *)okMask, okWorkingBuffer); + ctx->blendRectWithMask(frame, Palette::PrimaryText, (const uint8_t *)okMask, okWorkingBuffer); } KDSize OkView::minimalSizeForOptimalDisplay() const { diff --git a/apps/shared/range_parameter_controller.cpp b/apps/shared/range_parameter_controller.cpp index 38d00d3652d..3f05c4dcc76 100644 --- a/apps/shared/range_parameter_controller.cpp +++ b/apps/shared/range_parameter_controller.cpp @@ -41,7 +41,7 @@ void RangeParameterController::willDisplayCellForIndex(HighlightCell * cell, int MessageTableCellWithEditableText * myCell = (MessageTableCellWithEditableText *)cell; I18n::Message labels[k_numberOfTextCell] = {I18n::Message::XMin, I18n::Message::XMax, I18n::Message::YMin, I18n::Message::YMax}; myCell->setMessage(labels[index]); - myCell->setTextColor(KDColorBlack); + myCell->setTextColor(Palette::PrimaryText); FloatParameterController::willDisplayCellForIndex(cell, index); } diff --git a/apps/shared/round_cursor_view.cpp b/apps/shared/round_cursor_view.cpp index e8bdd205179..fbd9a68eb36 100644 --- a/apps/shared/round_cursor_view.cpp +++ b/apps/shared/round_cursor_view.cpp @@ -77,4 +77,4 @@ bool RoundCursorView::eraseCursorIfPossible() { } #endif -} +} \ No newline at end of file diff --git a/apps/shared/round_cursor_view.h b/apps/shared/round_cursor_view.h index eff1f93c340..930cea4602c 100644 --- a/apps/shared/round_cursor_view.h +++ b/apps/shared/round_cursor_view.h @@ -10,7 +10,7 @@ namespace Shared { class RoundCursorView : public CursorView { public: - RoundCursorView(KDColor color = KDColorBlack) : + RoundCursorView(KDColor color = Palette::PrimaryText) : m_color(color) #ifdef GRAPH_CURSOR_SPEEDUP , m_underneathPixelBufferLoaded(false) diff --git a/apps/shared/scrollable_exact_approximate_expressions_view.cpp b/apps/shared/scrollable_exact_approximate_expressions_view.cpp new file mode 100644 index 00000000000..05377dd6d22 --- /dev/null +++ b/apps/shared/scrollable_exact_approximate_expressions_view.cpp @@ -0,0 +1,176 @@ +#include "scrollable_exact_approximate_expressions_view.h" +#include +#include +using namespace Poincare; + +namespace Shared { + +static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } + +ScrollableExactApproximateExpressionsView::ContentCell::ContentCell() : + m_rightExpressionView(), + m_approximateSign(KDFont::LargeFont, I18n::Message::AlmostEqual, 0.5f, 0.5f, Palette::ApproximateSignText), + m_leftExpressionView(), + m_selectedSubviewPosition((SubviewPosition)0), + m_displayLeftExpression(true) +{ +} + +KDColor ScrollableExactApproximateExpressionsView::ContentCell::backgroundColor() const { + KDColor background = m_even ? Palette::CalculationBackgroundEven : Palette::CalculationBackgroundOdd; + return background; +} + +void ScrollableExactApproximateExpressionsView::ContentCell::setHighlighted(bool highlight) { + // Do not call HighlightCell::setHighlighted to avoid marking all cell as dirty + m_highlighted = highlight; + m_leftExpressionView.setBackgroundColor(backgroundColor()); + m_rightExpressionView.setBackgroundColor(backgroundColor()); + m_approximateSign.setBackgroundColor(backgroundColor()); + if (highlight) { + if (m_selectedSubviewPosition == SubviewPosition::Left) { + m_leftExpressionView.setBackgroundColor(Palette::ListCellBackgroundSelected); + } else { + m_rightExpressionView.setBackgroundColor(Palette::ListCellBackgroundSelected); + } + } +} + +void ScrollableExactApproximateExpressionsView::ContentCell::setEven(bool even) { + EvenOddCell::setEven(even); + m_leftExpressionView.setBackgroundColor(backgroundColor()); + m_rightExpressionView.setBackgroundColor(backgroundColor()); + m_approximateSign.setBackgroundColor(backgroundColor()); +} + +void ScrollableExactApproximateExpressionsView::ContentCell::reloadTextColor() { + if (numberOfSubviews() == 1) { + m_rightExpressionView.setTextColor(Palette::PrimaryText); + } else { + m_rightExpressionView.setTextColor(Palette::ApproximateExpressionText); + } +} + +KDSize ScrollableExactApproximateExpressionsView::ContentCell::minimalSizeForOptimalDisplay() const { + KDSize rightExpressionSize = m_rightExpressionView.minimalSizeForOptimalDisplay(); + if (numberOfSubviews() == 1) { + return rightExpressionSize; + } + KDSize leftExpressionSize = m_leftExpressionView.minimalSizeForOptimalDisplay(); + KDCoordinate leftBaseline = m_leftExpressionView.layout().baseline(); + KDCoordinate rightBaseline = m_rightExpressionView.layout().baseline(); + KDCoordinate height = maxCoordinate(leftBaseline, rightBaseline) + maxCoordinate(leftExpressionSize.height()-leftBaseline, rightExpressionSize.height()-rightBaseline); + KDSize approximateSignSize = m_approximateSign.minimalSizeForOptimalDisplay(); + return KDSize(leftExpressionSize.width()+approximateSignSize.width()+rightExpressionSize.width()+2*Metric::CommonLargeMargin, height); +} + +void ScrollableExactApproximateExpressionsView::ContentCell::setSelectedSubviewPosition(ScrollableExactApproximateExpressionsView::SubviewPosition subviewPosition) { + m_selectedSubviewPosition = subviewPosition; + setHighlighted(isHighlighted()); +} + +void ScrollableExactApproximateExpressionsView::ContentCell::setDisplayLeftExpression(bool display) { + m_displayLeftExpression = display; + reloadTextColor(); +} + +Poincare::Layout ScrollableExactApproximateExpressionsView::ContentCell::layout() const { + if (m_selectedSubviewPosition == SubviewPosition::Left) { + return m_leftExpressionView.layout(); + } else { + return m_rightExpressionView.layout(); + } +} + +int ScrollableExactApproximateExpressionsView::ContentCell::numberOfSubviews() const { + if (!m_displayLeftExpression || m_leftExpressionView.layout().isUninitialized()) { + return 1; + } + return 3; +} + +View * ScrollableExactApproximateExpressionsView::ContentCell::subviewAtIndex(int index) { + View * views[3] = {&m_rightExpressionView, &m_approximateSign, &m_leftExpressionView}; + return views[index]; +} + +void ScrollableExactApproximateExpressionsView::ContentCell::layoutSubviews() { + KDCoordinate height = bounds().height(); + KDSize rightExpressionSize = m_rightExpressionView.minimalSizeForOptimalDisplay(); + if (numberOfSubviews() == 1) { + m_rightExpressionView.setFrame(KDRect(0, 0, rightExpressionSize.width(), height)); + return; + } + KDCoordinate leftBaseline = m_leftExpressionView.layout().baseline(); + KDCoordinate rightBaseline = m_rightExpressionView.layout().baseline(); + KDCoordinate baseline = maxCoordinate(leftBaseline, rightBaseline); + KDSize leftExpressionSize = m_leftExpressionView.minimalSizeForOptimalDisplay(); + KDSize approximateSignSize = m_approximateSign.minimalSizeForOptimalDisplay(); + m_leftExpressionView.setFrame(KDRect(0, baseline-leftBaseline, leftExpressionSize)); + m_rightExpressionView.setFrame(KDRect(2*Metric::CommonLargeMargin+leftExpressionSize.width()+approximateSignSize.width(), baseline-rightBaseline, rightExpressionSize)); + m_approximateSign.setFrame(KDRect(Metric::CommonLargeMargin+leftExpressionSize.width(), baseline-approximateSignSize.height()/2, approximateSignSize)); +} + +ScrollableExactApproximateExpressionsView::ScrollableExactApproximateExpressionsView(Responder * parentResponder) : + ScrollableView(parentResponder, &m_contentCell, this), + m_contentCell() +{ + setDecoratorType(ScrollView::Decorator::Type::Arrows); + setMargins( + Metric::CommonSmallMargin, + Metric::CommonLargeMargin, + Metric::CommonSmallMargin, + Metric::CommonLargeMargin + ); +} + +void ScrollableExactApproximateExpressionsView::setLayouts(Poincare::Layout rightLayout, Poincare::Layout leftLayout) { + bool updateRightLayout = m_contentCell.rightExpressionView()->setLayout(rightLayout); + bool updateLeftLayout = m_contentCell.leftExpressionView()->setLayout(leftLayout); + if (updateRightLayout || updateLeftLayout) { + m_contentCell.reloadTextColor(); + m_contentCell.layoutSubviews(); + reloadScroll(); + } +} + +void ScrollableExactApproximateExpressionsView::setEqualMessage(I18n::Message equalSignMessage) { + m_contentCell.approximateSign()->setMessage(equalSignMessage); +} + +void ScrollableExactApproximateExpressionsView::reloadScroll() { + if (selectedSubviewPosition() == SubviewPosition::Left) { + // Scroll to the left extremity + ScrollableView::reloadScroll(); + } else { + // Scroll to the right extremity + scrollToContentPoint(KDPoint(m_contentCell.bounds().width(), 0), true); + } +} + +void ScrollableExactApproximateExpressionsView::didBecomeFirstResponder() { + if (m_contentCell.leftExpressionView()->layout().isUninitialized()) { + setSelectedSubviewPosition(SubviewPosition::Right); + } + if (m_contentCell.rightExpressionView()->layout().isUninitialized()) { + setSelectedSubviewPosition(SubviewPosition::Left); + } +} + +bool ScrollableExactApproximateExpressionsView::handleEvent(Ion::Events::Event event) { + if (!m_contentCell.displayLeftExpression()) { + return ScrollableView::handleEvent(event); + } + bool rightExpressionIsVisible = minimalSizeForOptimalDisplay().width() - m_contentCell.rightExpressionView()->minimalSizeForOptimalDisplay().width() - contentOffset().x() < bounds().width() +; + bool leftExpressionIsVisible = m_contentCell.leftExpressionView()->minimalSizeForOptimalDisplay().width() - contentOffset().x() > 0; + if ((event == Ion::Events::Right && selectedSubviewPosition() == SubviewPosition::Left && rightExpressionIsVisible) || + (event == Ion::Events::Left && selectedSubviewPosition() == SubviewPosition::Right && leftExpressionIsVisible)) { + SubviewPosition otherSubviewPosition = selectedSubviewPosition() == SubviewPosition::Left ? SubviewPosition::Right : SubviewPosition::Left; + setSelectedSubviewPosition(otherSubviewPosition); + return true; + } + return ScrollableView::handleEvent(event); +} + +} diff --git a/apps/shared/scrollable_multiple_expressions_view.cpp b/apps/shared/scrollable_multiple_expressions_view.cpp index 1ea21525c20..5d0331f5422 100644 --- a/apps/shared/scrollable_multiple_expressions_view.cpp +++ b/apps/shared/scrollable_multiple_expressions_view.cpp @@ -8,7 +8,7 @@ namespace Shared { AbstractScrollableMultipleExpressionsView::ContentCell::ContentCell() : m_rightExpressionView(), - m_approximateSign(k_font, k_defaultApproximateMessage, 0.5f, 0.5f, Palette::GrayVeryDark), + m_approximateSign(k_font, k_defaultApproximateMessage, 0.5f, 0.5f, Palette::SecondaryText), m_centeredExpressionView(), m_selectedSubviewPosition(SubviewPosition::Center), m_displayCenter(true) @@ -16,7 +16,7 @@ AbstractScrollableMultipleExpressionsView::ContentCell::ContentCell() : } KDColor AbstractScrollableMultipleExpressionsView::ContentCell::backgroundColor() const { - KDColor background = m_even ? KDColorWhite : Palette::WallScreen; + KDColor background = m_even ? Palette::CalculationBackgroundEven : Palette::CalculationBackgroundOdd; return background; } @@ -24,13 +24,13 @@ void AbstractScrollableMultipleExpressionsView::ContentCell::setHighlighted(bool // Do not call HighlightCell::setHighlighted to avoid marking all cell as dirty m_highlighted = highlight; KDColor defaultColor = backgroundColor(); - KDColor color = highlight && m_selectedSubviewPosition == SubviewPosition::Center ? Palette::Select : defaultColor; + KDColor color = highlight && m_selectedSubviewPosition == SubviewPosition::Center ? Palette::ExpressionInputBackground : defaultColor; m_centeredExpressionView.setBackgroundColor(color); - color = highlight && m_selectedSubviewPosition == SubviewPosition::Right ? Palette::Select : defaultColor; + color = highlight && m_selectedSubviewPosition == SubviewPosition::Right ? Palette::ExpressionInputBackground : defaultColor; m_rightExpressionView.setBackgroundColor(color); m_approximateSign.setBackgroundColor(defaultColor); if (leftExpressionView()) { - color = highlight && m_selectedSubviewPosition == SubviewPosition::Left ? Palette::Select : defaultColor; + color = highlight && m_selectedSubviewPosition == SubviewPosition::Left ? Palette::ExpressionInputBackground : defaultColor; leftExpressionView()->setBackgroundColor(color); } } @@ -48,9 +48,9 @@ void AbstractScrollableMultipleExpressionsView::ContentCell::setEven(bool even) void AbstractScrollableMultipleExpressionsView::ContentCell::reloadTextColor() { if (displayCenter()) { - m_rightExpressionView.setTextColor(Palette::GrayVeryDark); + m_rightExpressionView.setTextColor(Palette::SecondaryText); } else { - m_rightExpressionView.setTextColor(KDColorBlack); + m_rightExpressionView.setTextColor(Palette::PrimaryText); } } diff --git a/apps/shared/store_controller.cpp b/apps/shared/store_controller.cpp index fc56453c7cd..ee4244f3bbd 100644 --- a/apps/shared/store_controller.cpp +++ b/apps/shared/store_controller.cpp @@ -17,7 +17,7 @@ StoreController::ContentView::ContentView(DoublePairStore * store, Responder * p m_formulaInputView(this, inputEventHandlerDelegate, textFieldDelegate), m_displayFormulaInputView(false) { - m_dataView.setBackgroundColor(Palette::WallScreenDark); + m_dataView.setBackgroundColor(Palette::BackgroundAppsSecondary); m_dataView.setVerticalCellOverlap(0); m_dataView.setMargins(k_margin, k_scrollBarMargin, k_scrollBarMargin, k_margin); } diff --git a/apps/shared/text_field_with_extension.h b/apps/shared/text_field_with_extension.h index 688762ade72..dc1f46d8185 100644 --- a/apps/shared/text_field_with_extension.h +++ b/apps/shared/text_field_with_extension.h @@ -17,8 +17,8 @@ class TextFieldWithExtension : public TextField { const KDFont * size = KDFont::LargeFont, float horizontalAlignment = 0.0f, float verticalAlignment = 0.5f, - KDColor textColor = KDColorBlack, - KDColor backgroundColor = KDColorWhite) : + KDColor textColor = Palette::PrimaryText, + KDColor backgroundColor = Palette::BackgroundHard) : TextField(parentResponder, textBuffer, textBufferSize, draftTextBufferSize, inputEventHandlerDelegate, delegate, size, horizontalAlignment, verticalAlignment, textColor, backgroundColor), m_extensionLength(extensionLength) {} diff --git a/apps/shared/values_controller.cpp b/apps/shared/values_controller.cpp index 864b38f3e6f..6b52621163e 100644 --- a/apps/shared/values_controller.cpp +++ b/apps/shared/values_controller.cpp @@ -30,7 +30,7 @@ ValuesController::ValuesController(Responder * parentResponder, ButtonRowControl void ValuesController::setupSelectableTableViewAndCells(InputEventHandlerDelegate * inputEventHandlerDelegate) { selectableTableView()->setVerticalCellOverlap(0); selectableTableView()->setMargins(k_margin, k_scrollBarMargin, k_scrollBarMargin, k_margin); - selectableTableView()->setBackgroundColor(Palette::WallScreenDark); + selectableTableView()->setBackgroundColor(Palette::BackgroundAppsSecondary); int numberOfAbscissaCells = abscissaCellsCount(); for (int i = 0; i < numberOfAbscissaCells; i++) { diff --git a/apps/shared/vertical_cursor_view.cpp b/apps/shared/vertical_cursor_view.cpp index 05eb2b225c5..a4366911df9 100644 --- a/apps/shared/vertical_cursor_view.cpp +++ b/apps/shared/vertical_cursor_view.cpp @@ -4,7 +4,7 @@ namespace Shared { void VerticalCursorView::drawRect(KDContext * ctx, KDRect rect) const { KDCoordinate height = bounds().height(); - ctx->fillRect(KDRect(0, 0, 1, height), KDColorBlack); + ctx->fillRect(KDRect(0, 0, 1, height), Palette::PrimaryText); } KDSize VerticalCursorView::minimalSizeForOptimalDisplay() const { diff --git a/apps/shift_alpha_lock_view.cpp b/apps/shift_alpha_lock_view.cpp index 246ae8ab4db..7809c7d108b 100644 --- a/apps/shift_alpha_lock_view.cpp +++ b/apps/shift_alpha_lock_view.cpp @@ -2,13 +2,13 @@ ShiftAlphaLockView::ShiftAlphaLockView() : View(), - m_shiftAlphaView(KDFont::SmallFont, I18n::Message::Default, 1.0f, 0.5f, KDColorWhite, Palette::YellowDark), + m_shiftAlphaView(KDFont::SmallFont, I18n::Message::Default, 1.0f, 0.5f, Palette::ToolbarText, Palette::Toolbar), m_status(Ion::Events::ShiftAlphaStatus::Default) { } void ShiftAlphaLockView::drawRect(KDContext * ctx, KDRect rect) const { - ctx->fillRect(bounds(), Palette::YellowDark); + ctx->fillRect(bounds(), Palette::Toolbar); } bool ShiftAlphaLockView::setStatus(Ion::Events::ShiftAlphaStatus status) { diff --git a/apps/solver/app.cpp b/apps/solver/app.cpp index 7718fcad111..11f96a32ae6 100644 --- a/apps/solver/app.cpp +++ b/apps/solver/app.cpp @@ -14,6 +14,10 @@ I18n::Message App::Descriptor::upperName() { return I18n::Message::SolverAppCapital; } +App::Descriptor::ExaminationLevel App::Descriptor::examinationLevel() { + return App::Descriptor::ExaminationLevel::Strict; +} + const Image * App::Descriptor::icon() { return ImageStore::SolverIcon; } diff --git a/apps/solver/app.h b/apps/solver/app.h index f5a002ce8e1..a4919978e1b 100644 --- a/apps/solver/app.h +++ b/apps/solver/app.h @@ -17,6 +17,7 @@ class App : public Shared::ExpressionFieldDelegateApp { public: I18n::Message name() override; I18n::Message upperName() override; + App::Descriptor::ExaminationLevel examinationLevel() override; const Image * icon() override; }; class Snapshot : public ::SharedApp::Snapshot { diff --git a/apps/solver/base.hu.i18n b/apps/solver/base.hu.i18n new file mode 100644 index 00000000000..baba451b794 --- /dev/null +++ b/apps/solver/base.hu.i18n @@ -0,0 +1,29 @@ +SolverApp = "Egyenletek" +SolverAppCapital = "EGYENLETEK" +AddEquation = "Egyenlet hozzáadás" +ResolveEquation = "Egyenletet megoldása" +ResolveSystem = "Rendszer megoldása" +UseEquationModel = "Használjon egyenleti sablont" +RequireEquation = "A bemenetnek csak egyenlet lehet" +UnrealEquation = "Irreális egyenlet" +UndefinedEquation = "Egy egyenlet meghatározatlan " +TooManyVariables = "Túl sok ismeretlen van" +NonLinearSystem = "A rendszer nem lineáris" +Solution = "Megoldás" +ApproximateSolution = "Hozzávetöleges megoldás" +SearchInverval = "Keresési intervallum" +NoSolutionSystem = "A rendszernek nincs megoldása" +NoSolutionEquation = "Az egyenletnek nincs megoldása" +NoSolutionInterval = "Nincs megoldás ebben az intervallumban" +EnterEquation = "Írjon be egy egyenletet" +InfiniteNumberOfSolutions = "Végtelen menyi megoldások léteznek" +ApproximateSolutionIntervalInstruction0 = "Irja be a keresés intervallumot" +ApproximateSolutionIntervalInstruction1 = "amelyikbe egy hozzávetöleges megoldást keressen" +OnlyFirstSolutionsDisplayed0 = "Csak a 10 elsö megoldások" +OnlyFirstSolutionsDisplayed1 = "jelennek meg" +PolynomeHasNoRealSolution0 = "A polinomnak nincs" +PolynomeHasNoRealSolution1 = "valódi gyökére" +PredefinedVariablesUsedLeft = "Alkalmazott elöre-" +PredefinedVariablesUsedRight = "meghatározott változók" +PredefinedVariablesIgnoredLeft = "Mellözött" +PredefinedVariablesIgnoredRight = "elöre-meghatározott változók" diff --git a/apps/solver/equation_list_view.cpp b/apps/solver/equation_list_view.cpp index f4a4d18f3b7..6ed4befa784 100644 --- a/apps/solver/equation_list_view.cpp +++ b/apps/solver/equation_list_view.cpp @@ -19,7 +19,7 @@ EquationListView::EquationListView(ListController * listController) : listController->setScrollViewDelegate(this); m_scrollBraceView.setMargins(k_margin, k_margin, k_margin, k_margin); m_scrollBraceView.setDecoratorType(ScrollView::Decorator::Type::None); - m_scrollBraceView.setBackgroundColor(KDColorWhite); + m_scrollBraceView.setBackgroundColor(Palette::BackgroundHard); } void EquationListView::setBraceStyle(BraceStyle style) { @@ -106,15 +106,15 @@ const uint8_t bottomBrace[braceExtremumHeight][braceExtremumWidth] = { }; void EquationListView::BraceView::drawRect(KDContext * ctx, KDRect rect) const { - ctx->fillRect(bounds(), KDColorWhite); + ctx->fillRect(bounds(), Palette::BackgroundHard); KDCoordinate height = bounds().height(); KDCoordinate margin = 3; KDColor braceWorkingBuffer[60]; - ctx->blendRectWithMask(KDRect(margin, 0, braceExtremumWidth, braceExtremumHeight), KDColorBlack, (const uint8_t *)topBrace, (KDColor *)(braceWorkingBuffer)); - ctx->blendRectWithMask(KDRect(0, height/2-braceCenterHeight/2, braceCenterWidth, braceCenterHeight), KDColorBlack, (const uint8_t *)middleBrace, (KDColor *)(braceWorkingBuffer)); - ctx->blendRectWithMask(KDRect(margin, height-braceExtremumHeight, braceExtremumWidth, braceExtremumHeight), KDColorBlack, (const uint8_t *)bottomBrace, (KDColor *)(braceWorkingBuffer)); - ctx->fillRect(KDRect(margin, braceExtremumHeight, 1, height/2-braceCenterHeight/2-braceExtremumHeight), KDColorBlack); - ctx->fillRect(KDRect(margin, height/2+braceCenterHeight/2, 1, height/2-braceExtremumHeight/2-braceExtremumHeight), KDColorBlack); + ctx->blendRectWithMask(KDRect(margin, 0, braceExtremumWidth, braceExtremumHeight), Palette::PrimaryText, (const uint8_t *)topBrace, (KDColor *)(braceWorkingBuffer)); + ctx->blendRectWithMask(KDRect(0, height/2-braceCenterHeight/2, braceCenterWidth, braceCenterHeight), Palette::PrimaryText, (const uint8_t *)middleBrace, (KDColor *)(braceWorkingBuffer)); + ctx->blendRectWithMask(KDRect(margin, height-braceExtremumHeight, braceExtremumWidth, braceExtremumHeight), Palette::PrimaryText, (const uint8_t *)bottomBrace, (KDColor *)(braceWorkingBuffer)); + ctx->fillRect(KDRect(margin, braceExtremumHeight, 1, height/2-braceCenterHeight/2-braceExtremumHeight), Palette::PrimaryText); + ctx->fillRect(KDRect(margin, height/2+braceCenterHeight/2, 1, height/2-braceExtremumHeight/2-braceExtremumHeight), Palette::PrimaryText); } KDSize EquationListView::BraceView::minimalSizeForOptimalDisplay() const { diff --git a/apps/solver/interval_controller.cpp b/apps/solver/interval_controller.cpp index 9086e4686cc..986f5b4cf4b 100644 --- a/apps/solver/interval_controller.cpp +++ b/apps/solver/interval_controller.cpp @@ -7,14 +7,14 @@ namespace Solver { IntervalController::ContentView::ContentView(SelectableTableView * selectableTableView) : - m_instructions0(KDFont::SmallFont, I18n::Message::ApproximateSolutionIntervalInstruction0, 0.5f, 0.5f, KDColorBlack, Palette::WallScreen), - m_instructions1(KDFont::SmallFont, I18n::Message::ApproximateSolutionIntervalInstruction1, 0.5f, 0.5f, KDColorBlack, Palette::WallScreen), + m_instructions0(KDFont::SmallFont, I18n::Message::ApproximateSolutionIntervalInstruction0, 0.5f, 0.5f, Palette::PrimaryText, Palette::BackgroundApps), + m_instructions1(KDFont::SmallFont, I18n::Message::ApproximateSolutionIntervalInstruction1, 0.5f, 0.5f, Palette::PrimaryText, Palette::BackgroundApps), m_selectableTableView(selectableTableView) { } void IntervalController::ContentView::drawRect(KDContext * ctx, KDRect rect) const { - ctx->fillRect(KDRect(0, 0, bounds().width(), k_topMargin), Palette::WallScreen); + ctx->fillRect(KDRect(0, 0, bounds().width(), k_topMargin), Palette::BackgroundApps); } int IntervalController::ContentView::numberOfSubviews() const { @@ -103,8 +103,8 @@ bool IntervalController::textFieldDidFinishEditing(TextField * textField, const void IntervalController::buttonAction() { StackViewController * stack = stackController(); - m_equationStore->approximateSolve(textFieldDelegateApp()->localContext(), m_shouldReplaceFunctionsButNotSymbols); - stack->push(App::app()->solutionsControllerStack(), KDColorWhite, Palette::SubTab, Palette::SubTab); + m_equationStore->approximateSolve(textFieldDelegateApp()->localContext(), m_shouldReplaceFunctionsButNotSymbols); + stack->push(App::app()->solutionsControllerStack(), Palette::BannerSecondText, Palette::BannerSecondBackground, Palette::BannerSecondBorder); } } diff --git a/apps/solver/list_controller.cpp b/apps/solver/list_controller.cpp index 0c84e55553b..376b2be52a4 100644 --- a/apps/solver/list_controller.cpp +++ b/apps/solver/list_controller.cpp @@ -17,9 +17,9 @@ ListController::ListController(Responder * parentResponder, EquationStore * equa ListController * list = (ListController *)context; list->resolveEquations(); return true; - }, this), KDFont::LargeFont, Palette::PurpleBright), + }, this), KDFont::LargeFont, Palette::ButtonText), m_modelsParameterController(this, equationStore, this), - m_modelsStackController(nullptr, &m_modelsParameterController, KDColorWhite, Palette::PurpleDark, Palette::PurpleDark) + m_modelsStackController(nullptr, &m_modelsParameterController, Palette::BannerFirstVariantText, Palette::BannerFirstVariantBackground, Palette::BannerFirstVariantBorder) { m_addNewModel.setAlignment(0.3f, 0.5f); // (EquationListView::k_braceTotalWidth+k_expressionMargin) / (Ion::Display::Width-m_addNewModel.text().size()) = (30+5)/(320-200) for (int i = 0; i < k_maxNumberOfRows; i++) { @@ -191,7 +191,7 @@ void ListController::resolveEquations() { case EquationStore::Error::RequireApproximateSolution: { reinterpret_cast(App::app()->intervalController())->setShouldReplaceFuncionsButNotSymbols(resultWithoutUserDefinedSymbols); - stackController()->push(App::app()->intervalController(), KDColorWhite, Palette::PurpleBright, Palette::PurpleBright); + stackController()->push(App::app()->intervalController(), Palette::BannerFirstText, Palette::BannerFirstBackground, Palette::BannerFirstBorder); return; } default: @@ -199,7 +199,7 @@ void ListController::resolveEquations() { assert(e == EquationStore::Error::NoError); StackViewController * stack = stackController(); reinterpret_cast(App::app()->intervalController())->setShouldReplaceFuncionsButNotSymbols(resultWithoutUserDefinedSymbols); - stack->push(App::app()->solutionsControllerStack(), KDColorWhite, Palette::PurpleBright, Palette::PurpleBright); + stack->push(App::app()->solutionsControllerStack(), Palette::BannerFirstText, Palette::BannerFirstBackground, Palette::BannerFirstBorder); } } } diff --git a/apps/solver/solutions_controller.h b/apps/solver/solutions_controller.h index b78d8b960a3..4fac929a191 100644 --- a/apps/solver/solutions_controller.h +++ b/apps/solver/solutions_controller.h @@ -42,7 +42,7 @@ class SolutionsController : public ViewController, public AlternateEmptyViewDefa class ContentView : public View { public: constexpr static KDCoordinate k_topMargin = 50; - constexpr static KDColor k_backgroundColor = Palette::WallScreenDark; + constexpr static KDColor k_backgroundColor = Palette::BackgroundAppsSecondary; ContentView(SolutionsController * controller); void drawRect(KDContext * ctx, KDRect rect) const override; void setWarning(bool warning); diff --git a/apps/statistics/app.cpp b/apps/statistics/app.cpp index e6d5236f160..2960d27f1ce 100644 --- a/apps/statistics/app.cpp +++ b/apps/statistics/app.cpp @@ -15,6 +15,10 @@ I18n::Message App::Descriptor::upperName() { return I18n::Message::StatsAppCapital; } +App::Descriptor::ExaminationLevel App::Descriptor::examinationLevel() { + return App::Descriptor::ExaminationLevel::Strict; +} + const Image * App::Descriptor::icon() { return ImageStore::StatIcon; } diff --git a/apps/statistics/app.h b/apps/statistics/app.h index ef5b4cfa8fb..76eef943846 100644 --- a/apps/statistics/app.h +++ b/apps/statistics/app.h @@ -18,6 +18,7 @@ class App : public Shared::TextFieldDelegateApp { public: I18n::Message name() override; I18n::Message upperName() override; + App::Descriptor::ExaminationLevel examinationLevel() override; const Image * icon() override; }; class Snapshot : public ::SharedApp::Snapshot, public TabViewDataSource { diff --git a/apps/statistics/base.en.i18n b/apps/statistics/base.en.i18n index a25f566febb..4bb66972991 100644 --- a/apps/statistics/base.en.i18n +++ b/apps/statistics/base.en.i18n @@ -24,4 +24,4 @@ StandardDeviationSigma = "Standard deviation σ" SampleStandardDeviationS = "Sample std deviation s" SumValues = "Sum of values" SumSquareValues = "Sum of squared values" -InterquartileRange = "Interquartile range" \ No newline at end of file +InterquartileRange = "Interquartile range" diff --git a/apps/statistics/base.hu.i18n b/apps/statistics/base.hu.i18n new file mode 100644 index 00000000000..097a28b2224 --- /dev/null +++ b/apps/statistics/base.hu.i18n @@ -0,0 +1,27 @@ +StatsApp = "Statisztika" +StatsAppCapital = "STATISZTIKA" +HistogramTab = "Hisztogram" +BoxTab = "Doboz" +Values1 = "V1 értékek" +Values2 = "V2 értékek" +Values3 = "V3 értékek" +Frequencies1 = "N1 Frekvencia" +Frequencies2 = "N2 Frekvencia" +Frequencies3 = "N3 Frekvencia" +ImportList = "Importálás egy listáról" +Interval = "Intervallum" +Frequency = "Frekvencia:" +RelativeFrequency = "Relatív:" +HistogramSet = "Hisztogram beállítások" +RectangleWidth = "Tálca szélessége" +BarStart = "X kezdet" +FirstQuartile = "Elsö kvartilis" +Median = "Medián" +ThirdQuartile = "Harmadik kvartilis" +TotalFrequency = "Adatpontok száma " +Range = "Intervallum" +StandardDeviationSigma = "σ szórás" +SampleStandardDeviationS = "Minta std eltérés σ" +SumValues = "Értékek összege" +SumSquareValues = "Négyzetértékek összege" +InterquartileRange = "Interkvartilis tartomány" diff --git a/apps/statistics/box_axis_view.cpp b/apps/statistics/box_axis_view.cpp index 3d898c7383a..c36ab417595 100644 --- a/apps/statistics/box_axis_view.cpp +++ b/apps/statistics/box_axis_view.cpp @@ -6,9 +6,9 @@ using namespace Shared; namespace Statistics { void BoxAxisView::drawRect(KDContext * ctx, KDRect rect) const { - ctx->fillRect(rect, KDColorWhite); + ctx->fillRect(rect, Palette::BackgroundHard); KDRect lineRect = KDRect(0, k_axisMargin, bounds().width(), 1); - ctx->fillRect(lineRect, KDColorBlack); + ctx->fillRect(lineRect, Palette::PrimaryText); drawLabelsAndGraduations(ctx, rect, Axis::Horizontal, false, false, true, k_axisMargin); } diff --git a/apps/statistics/box_view.cpp b/apps/statistics/box_view.cpp index eb7d0088635..b2e2a101d79 100644 --- a/apps/statistics/box_view.cpp +++ b/apps/statistics/box_view.cpp @@ -52,7 +52,7 @@ void BoxView::reload() { } void BoxView::drawRect(KDContext * ctx, KDRect rect) const { - ctx->fillRect(rect, KDColorWhite); + ctx->fillRect(rect, Palette::BackgroundHard); KDCoordinate lowBoundPixel = boxLowerBoundPixel(); KDCoordinate upBoundPixel = boxUpperBoundPixel(); @@ -63,7 +63,7 @@ void BoxView::drawRect(KDContext * ctx, KDRect rect) const { double thirdQuart = m_store->thirdQuartile(m_series); double maxVal = m_store->maxValue(m_series); - KDColor boxColor = isMainViewSelected() ? m_selectedHistogramLightColor : Palette::GrayWhite; + KDColor boxColor = isMainViewSelected() ? m_selectedHistogramLightColor : Palette::StatisticsNotSelected; // Draw the main box KDCoordinate firstQuartilePixels = std::round(floatToPixel(Axis::Horizontal, firstQuart)); KDCoordinate thirdQuartilePixels = std::round(floatToPixel(Axis::Horizontal, thirdQuart)); @@ -71,7 +71,7 @@ void BoxView::drawRect(KDContext * ctx, KDRect rect) const { upBoundPixel-lowBoundPixel), boxColor); // Draw the horizontal lines linking the box to the extreme bounds - KDColor horizontalColor = isMainViewSelected() ? m_selectedHistogramColor : Palette::GrayDark; + KDColor horizontalColor = isMainViewSelected() ? m_selectedHistogramColor : Palette::SecondaryText; float segmentOrd = (lowBound + upBound)/ 2.0f; drawHorizontalOrVerticalSegment(ctx, rect, Axis::Horizontal, segmentOrd, minVal, firstQuart, horizontalColor); drawHorizontalOrVerticalSegment(ctx, rect, Axis::Horizontal, segmentOrd, thirdQuart, maxVal, horizontalColor); @@ -83,10 +83,10 @@ void BoxView::drawRect(KDContext * ctx, KDRect rect) const { * lines. This solution could hide the highlighted line by coloring the next * quantile if it has the same value. */ for (int k = 0; k < 5; k++) { - drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, calculations[k], lowBound, upBound, Palette::GrayMiddle, k_quantileBarWidth); + drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, calculations[k], lowBound, upBound, Palette::StatisticsBoxVerticalLine, k_quantileBarWidth); } if (isMainViewSelected()) { - drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, calculations[(int)*m_selectedQuantile], lowBound, upBound, Palette::YellowDark, k_quantileBarWidth); + drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, calculations[(int)*m_selectedQuantile], lowBound, upBound, Palette::StatisticsBox, k_quantileBarWidth); } } diff --git a/apps/statistics/calculation_controller.cpp b/apps/statistics/calculation_controller.cpp index a44598c9219..fe21be45812 100644 --- a/apps/statistics/calculation_controller.cpp +++ b/apps/statistics/calculation_controller.cpp @@ -19,7 +19,7 @@ CalculationController::CalculationController(Responder * parentResponder, Button m_hideableCell(), m_store(store) { - m_selectableTableView.setBackgroundColor(Palette::WallScreenDark); + m_selectableTableView.setBackgroundColor(Palette::BackgroundAppsSecondary); m_selectableTableView.setVerticalCellOverlap(0); m_selectableTableView.setMargins(k_margin, k_scrollBarMargin, k_scrollBarMargin, k_margin); for (int i = 0; i < k_numberOfSeriesTitleCells; i++) { @@ -30,7 +30,7 @@ CalculationController::CalculationController(Responder * parentResponder, Button m_calculationTitleCells[i].setMessageFont(KDFont::SmallFont); } for (int i = 0; i < k_numberOfCalculationCells; i++) { - m_calculationCells[i].setTextColor(Palette::GrayDark); + m_calculationCells[i].setTextColor(Palette::SecondaryText); } m_hideableCell.setHide(true); } diff --git a/apps/statistics/histogram_view.cpp b/apps/statistics/histogram_view.cpp index 9b1d028f4a0..66250b87254 100644 --- a/apps/statistics/histogram_view.cpp +++ b/apps/statistics/histogram_view.cpp @@ -39,7 +39,7 @@ void HistogramView::reloadSelectedBar() { void HistogramView::drawRect(KDContext * ctx, KDRect rect) const { m_controller->setCurrentDrawnSeries(m_series); - ctx->fillRect(rect, KDColorWhite); + ctx->fillRect(rect, Palette::BackgroundHard); drawAxis(ctx, rect, Axis::Horizontal); drawLabelsAndGraduations(ctx, rect, Axis::Horizontal, false, !m_displayLabels); /* We memoize the total size to avoid recomputing it in double precision at diff --git a/apps/statistics/histogram_view.h b/apps/statistics/histogram_view.h index a2b050c4647..94bb8a9bfd9 100644 --- a/apps/statistics/histogram_view.h +++ b/apps/statistics/histogram_view.h @@ -13,7 +13,7 @@ class HistogramController; class HistogramView : public Shared::HorizontallyLabeledCurveView { public: - HistogramView(HistogramController * controller, Store * store, int series, Shared::BannerView * bannerView, KDColor selectedHistogramColor = Palette::Select, KDColor notSelectedHistogramColor = Palette::GrayMiddle, KDColor selectedBarColor = Palette::YellowDark); + HistogramView(HistogramController * controller, Store * store, int series, Shared::BannerView * bannerView, KDColor selectedHistogramColor = Palette::StatisticsSelected, KDColor notSelectedHistogramColor = Palette::StatisticsNotSelected, KDColor selectedBarColor = Palette::StatisticsSelected); int series() const { return m_series; } void reload() override; void reloadSelectedBar(); diff --git a/apps/statistics/multiple_data_view.cpp b/apps/statistics/multiple_data_view.cpp index c8ad4f1b537..569d7827dbe 100644 --- a/apps/statistics/multiple_data_view.cpp +++ b/apps/statistics/multiple_data_view.cpp @@ -112,7 +112,7 @@ void MultipleDataView::layoutBanner(bool force) { void MultipleDataView::drawRect(KDContext * ctx, KDRect rect) const { if (!m_displayBanner) { - ctx->fillRect(bannerFrame(), KDColorWhite); + ctx->fillRect(bannerFrame(), Palette::BackgroundHard); } } diff --git a/apps/statistics/store_controller.cpp b/apps/statistics/store_controller.cpp index dce6f5d760c..c982705799e 100644 --- a/apps/statistics/store_controller.cpp +++ b/apps/statistics/store_controller.cpp @@ -49,7 +49,7 @@ void StoreController::willDisplayCellAtLocation(HighlightCell * cell, int i, int I18n::Message sizesMessages[] = {I18n::Message::Frequencies1, I18n::Message::Frequencies2, I18n::Message::Frequencies3}; mytitleCell->setText(I18n::translate(sizesMessages[seriesIndex])); } - mytitleCell->setColor(m_store->numberOfPairsOfSeries(seriesIndex) == 0 ? Palette::GrayDark : Store::colorOfSeriesAtIndex(seriesIndex)); // TODO Share GrayDark with graph/list_controller + mytitleCell->setColor(m_store->numberOfPairsOfSeries(seriesIndex) == 0 ? Palette::SecondaryText : Store::colorOfSeriesAtIndex(seriesIndex)); // TODO Share GreyDark with graph/list_controller } HighlightCell * StoreController::titleCells(int index) { diff --git a/apps/title_bar_view.cpp b/apps/title_bar_view.cpp index 3295a0f5e43..a842b394e50 100644 --- a/apps/title_bar_view.cpp +++ b/apps/title_bar_view.cpp @@ -9,22 +9,57 @@ using namespace Poincare; TitleBarView::TitleBarView() : View(), - m_titleView(KDFont::SmallFont, I18n::Message::Default, 0.5f, 0.5f, KDColorWhite, Palette::YellowDark), - m_preferenceView(KDFont::SmallFont, 1.0f, 0.5, KDColorWhite, Palette::YellowDark) + m_titleView(KDFont::SmallFont, I18n::Message::Default, 0.5f, 0.5f, Palette::ToolbarText, Palette::Toolbar), + m_preferenceView(KDFont::SmallFont, 1.0f, 0.5, Palette::ToolbarText, Palette::Toolbar), + m_clockView(KDFont::SmallFont, 0.5f, 0.5f, Palette::ToolbarText, Palette::Toolbar), + m_hours(-1), + m_mins(-1), + m_clockEnabled(Ion::RTC::mode() != Ion::RTC::Mode::Disabled) { + setClock(Ion::RTC::dateTime().tm_hour, Ion::RTC::dateTime().tm_min, m_clockEnabled); m_examModeIconView.setImage(ImageStore::ExamIcon); } void TitleBarView::drawRect(KDContext * ctx, KDRect rect) const { /* As we cheated to layout the title view, we have to fill a very thin * rectangle at the top with the background color. */ - ctx->fillRect(KDRect(0, 0, bounds().width(), 2), Palette::YellowDark); + ctx->fillRect(KDRect(0, 0, bounds().width(), 2), Palette::Toolbar); } void TitleBarView::setTitle(I18n::Message title) { m_titleView.setMessage(title); } +bool TitleBarView::setClock(int hours, int mins, bool enabled) { + bool changed = m_clockEnabled != enabled; + + if (!enabled) { + m_clockView.setText(""); + hours = -1; + mins = -1; + } + else if (m_hours != hours || m_mins != mins) { + char buf[6], *ptr = buf; + *ptr++ = (hours / 10) + '0'; + *ptr++ = (hours % 10) + '0'; + *ptr++ = ':'; + *ptr++ = (mins / 10) + '0'; + *ptr++ = (mins % 10) + '0'; + *ptr = '\0'; + m_clockView.setText(buf); + + changed = true; + } + if (m_clockEnabled != enabled) { + layoutSubviews(); + m_clockEnabled = enabled; + } + + m_hours = hours; + m_mins = mins; + return changed; +} + bool TitleBarView::setChargeState(Ion::Battery::Charge chargeState) { return m_batteryView.setChargeState(chargeState); } @@ -42,7 +77,7 @@ bool TitleBarView::setShiftAlphaLockStatus(Ion::Events::ShiftAlphaStatus status) } int TitleBarView::numberOfSubviews() const { - return 5; + return 6; } View * TitleBarView::subviewAtIndex(int index) { @@ -58,6 +93,9 @@ View * TitleBarView::subviewAtIndex(int index) { if (index == 3) { return &m_shiftAlphaLockView; } + if (index == 4) { + return &m_clockView; + } return &m_batteryView; } @@ -69,15 +107,25 @@ void TitleBarView::layoutSubviews(bool force) { * translate the frame of the title downwards.*/ m_titleView.setFrame(KDRect(0, 2, bounds().width(), bounds().height()-2), force); m_preferenceView.setFrame(KDRect(Metric::TitleBarExternHorizontalMargin, 0, m_preferenceView.minimalSizeForOptimalDisplay().width(), bounds().height()), force); + KDSize clockSize = m_clockView.minimalSizeForOptimalDisplay(); + m_clockView.setFrame(KDRect(bounds().width() - clockSize.width() - Metric::TitleBarExternHorizontalMargin, (bounds().height()- clockSize.height())/2, clockSize), force); + if (clockSize.width() != 0) { + clockSize = KDSize(clockSize.width() + k_alphaRightMargin, clockSize.height()); + } KDSize batterySize = m_batteryView.minimalSizeForOptimalDisplay(); - m_batteryView.setFrame(KDRect(bounds().width() - batterySize.width() - Metric::TitleBarExternHorizontalMargin, (bounds().height()- batterySize.height())/2, batterySize), force); + m_batteryView.setFrame(KDRect(bounds().width() - clockSize.width() - batterySize.width() - Metric::TitleBarExternHorizontalMargin, (bounds().height()- batterySize.height())/2, batterySize), force); if (GlobalPreferences::sharedGlobalPreferences()->isInExamMode()) { - m_examModeIconView.setFrame(KDRect(k_examIconMargin, (bounds().height() - k_examIconHeight)/2, k_examIconWidth, k_examIconHeight), force); + m_examModeIconView.setFrame(KDRect(bounds().width() - clockSize.width() - batterySize.width() - k_examIconWidth - k_alphaRightMargin - Metric::TitleBarExternHorizontalMargin, (bounds().height() - k_examIconHeight)/2, k_examIconWidth, k_examIconHeight), force); } else { m_examModeIconView.setFrame(KDRectZero, force); } KDSize shiftAlphaLockSize = m_shiftAlphaLockView.minimalSizeForOptimalDisplay(); - m_shiftAlphaLockView.setFrame(KDRect(bounds().width()-batterySize.width()-Metric::TitleBarExternHorizontalMargin-k_alphaRightMargin-shiftAlphaLockSize.width(), (bounds().height()- shiftAlphaLockSize.height())/2, shiftAlphaLockSize), force); + if (GlobalPreferences::sharedGlobalPreferences()->isInExamMode()) { + // The Shift/Alpha frame is shifted when examination mode is active + m_shiftAlphaLockView.setFrame(KDRect(bounds().width()-clockSize.width()-batterySize.width()-k_examIconWidth-Metric::TitleBarExternHorizontalMargin-2*k_alphaRightMargin-shiftAlphaLockSize.width(), (bounds().height()- shiftAlphaLockSize.height())/2, shiftAlphaLockSize), force); + } else { + m_shiftAlphaLockView.setFrame(KDRect(bounds().width()-clockSize.width()-batterySize.width()-Metric::TitleBarExternHorizontalMargin-k_alphaRightMargin-shiftAlphaLockSize.width(), (bounds().height()- shiftAlphaLockSize.height())/2, shiftAlphaLockSize), force); + } } void TitleBarView::refreshPreferences() { @@ -85,6 +133,14 @@ void TitleBarView::refreshPreferences() { char buffer[bufferSize]; int numberOfChar = 0; Preferences * preferences = Preferences::sharedPreferences(); + if (GlobalPreferences::sharedGlobalPreferences()->isInExamModeSymbolic()) { + // Display "cas" if in exam mode with symbolic computation enabled + numberOfChar += strlcpy(buffer+numberOfChar, I18n::translate(I18n::Message::Sym), bufferSize - numberOfChar); + assert(numberOfChar < bufferSize-1); + assert(UTF8Decoder::CharSizeOfCodePoint('/') == 1); + buffer[numberOfChar++] = '/'; + } + assert(numberOfChar <= bufferSize); { // Display Sci/ or Eng/ if the print float mode is not decimal const Preferences::PrintFloatMode printFloatMode = preferences->displayMode(); @@ -93,7 +149,7 @@ void TitleBarView::refreshPreferences() { assert(printFloatMode == Preferences::PrintFloatMode::Scientific || printFloatMode == Preferences::PrintFloatMode::Engineering); I18n::Message printMessage = printFloatMode == Preferences::PrintFloatMode::Scientific ? I18n::Message::Sci : I18n::Message::Eng; - numberOfChar += strlcpy(buffer, I18n::translate(printMessage), bufferSize); + numberOfChar += strlcpy(buffer+numberOfChar, I18n::translate(printMessage), bufferSize - numberOfChar); assert(numberOfChar < bufferSize-1); assert(UTF8Decoder::CharSizeOfCodePoint('/') == 1); buffer[numberOfChar++] = '/'; @@ -109,6 +165,7 @@ void TitleBarView::refreshPreferences() { numberOfChar += strlcpy(buffer+numberOfChar, I18n::translate(angleMessage), bufferSize - numberOfChar); assert(numberOfChar < bufferSize-1); } + m_preferenceView.setText(buffer); // Layout the exam mode icon if needed layoutSubviews(); diff --git a/apps/title_bar_view.h b/apps/title_bar_view.h index c0b6517f6a3..fdc618f3b48 100644 --- a/apps/title_bar_view.h +++ b/apps/title_bar_view.h @@ -11,6 +11,7 @@ class TitleBarView : public View { TitleBarView(); void drawRect(KDContext * ctx, KDRect rect) const override; void setTitle(I18n::Message title); + bool setClock(int hours, int mins, bool enabled); bool setChargeState(Ion::Battery::Charge chargeState); bool setIsCharging(bool isCharging); bool setIsPlugged(bool isPlugged); @@ -30,6 +31,10 @@ class TitleBarView : public View { ShiftAlphaLockView m_shiftAlphaLockView; BufferTextView m_preferenceView; ImageView m_examModeIconView; + BufferTextView m_clockView; + int m_hours; + int m_mins; + bool m_clockEnabled; }; #endif diff --git a/apps/toolbox.de.i18n b/apps/toolbox.de.i18n index 5cbe2768e02..c0745498a69 100644 --- a/apps/toolbox.de.i18n +++ b/apps/toolbox.de.i18n @@ -21,6 +21,7 @@ UnitDistanceMeterNano = "Nanometer" UnitDistanceMeterPico = "Pikometer" UnitDistanceAstronomicalUnit = "Astronomische Einheit" UnitDistanceLightYear = "Lichtjahr" +UnitDistanceParsec = "Parsec" UnitDistanceMile = "Meile" UnitDistanceYard = "Yard" UnitDistanceFoot = "Fuß" @@ -31,6 +32,8 @@ UnitMassGram = "Gramm" UnitMassGramMilli = "Milligramm" UnitMassGramMicro = "Mikrogramm" UnitMassGramNano = "Nanogramm" +UnitDistanceImperialMenu = "US Customary" +UnitMassImperialMenu = "US Customary" UnitMassTonne = "Tonne" UnitMassOunce = "Unze" UnitMassPound = "Pfund" @@ -72,7 +75,7 @@ UnitCapacitanceMenu = "Elektrische Kapazität" UnitCapacitanceFaradMilli = "Millifarad" UnitCapacitanceFaradMicro = "Mikrofarad" UnitResistanceMenu = "Elektrischer Widerstand" -UnitConductanceMenu = "Electrical conductance" +UnitConductanceMenu = "Elektrische Leitfähigkeit" UnitConductanceSiemensMilli = "Millisiemens" UnitMagneticFieldMenu = "Magnetfeld" InductanceMenu = "Elektrische Induktivität" @@ -107,6 +110,7 @@ Identity = "Einheitsmatrix der Größe n" Lists = "Listen" HyperbolicTrigonometry = "Hyperbelfunktionen" Fluctuation = "Konfidenzintervall" +InfinityMessage = "Unendlich" DerivateNumber = "Ableitung" Integral = "Integral" Sum = "Summe" @@ -164,3 +168,331 @@ InvBinomial = "m wo P(X<=m)=a und X folgt B(n,p)" Probability = "Wahrscheinlichkeit" BinomialDistribution = "Binomialverteilung" NormalDistribution = "Normalverteilung" +Chemistry = "Chemie" +Physics = "Physikalisch" +MolarMassesByNumber = "Molmassen (1,2...)" +MolarMassesByAlpha = "Molmassen (A,B...)" +NumberElementH = "1 - Wasserstoff (H)" +AlphaElementH = "H - Wasserstoff (1)" +NumberElementHe = "2 - Helium (He)" +AlphaElementHe = "He - Helium (2)" +NumberElementLi = "3 - Lithium (Li)" +AlphaElementLi = "Li - Lithium (3)" +NumberElementBe = "4 - Beryllium (Be)" +AlphaElementBe = "Be - Beryllium (4)" +NumberElementB = "5 - Bor (B)" +AlphaElementB = "B - Bor (5)" +NumberElementC = "6 - Kohlenstoff (C)" +AlphaElementC = "C - Kohlenstoff (6)" +NumberElementN = "7 - Stickstoff (N)" +AlphaElementN = "N - Stickstoff (7)" +NumberElementO = "8 - Sauerstoff (O)" +AlphaElementO = "O - Sauerstoff (8)" +NumberElementF = "9 - Fluor (F)" +AlphaElementF = "F - Fluor (9)" +NumberElementNe = "10 - Neon (Ne)" +AlphaElementNe = "Ne - Neon (10)" +NumberElementNa = "11 - Natrium (Na)" +AlphaElementNa = "Na - Natrium (11)" +NumberElementMg = "12 - Magnesium (Mg)" +AlphaElementMg = "Mg - Magnesium (12)" +NumberElementAl = "13 - Aluminium (Al)" +AlphaElementAl = "Al - Aluminium (13)" +NumberElementSi = "14 - Silizium (Si)" +AlphaElementSi = "Si - Silizium (14)" +NumberElementP = "15 - Phosphor (P)" +AlphaElementP = "P - Phosphor (15)" +NumberElementS = "16 - Schwefel (S)" +AlphaElementS = "S - Schwefel (16)" +NumberElementCl = "17 - Chlor (Cl)" +AlphaElementCl = "Cl - Chlor (17)" +NumberElementAr = "18 - Argon (Ar)" +AlphaElementAr = "Ar - Argon (18)" +NumberElementK = "19 - Kalium (K)" +AlphaElementK = "K - Kalium (19)" +NumberElementCa = "20 - Kalzium (Ca)" +AlphaElementCa = "Ca - Kalzium (20)" +NumberElementSc = "21 - Scandium (Sc)" +AlphaElementSc = "Sc - Scandium (21)" +NumberElementTi = "22 - Titan (Ti)" +AlphaElementTi = "Ti - Titan (22)" +NumberElementV = "23 - Vanadium (V)" +AlphaElementV = "V - Vanadium (23)" +NumberElementCr = "24 - Chrom (Cr)" +AlphaElementCr = "Cr - Chrom (24)" +NumberElementMn = "25 - Mangan (Mn)" +AlphaElementMn = "Mn - Mangan (25)" +NumberElementFe = "26 - Eisen (Fe)" +AlphaElementFe = "Fe - Eisen (26)" +NumberElementCo = "27 - Kobalt (Co)" +AlphaElementCo = "Co - Kobalt (27)" +NumberElementNi = "28 - Nickel (Ni)" +AlphaElementNi = "Ni - Nickel (28)" +NumberElementCu = "29 - Kupfer (Cu)" +AlphaElementCu = "Cu - Kupfer (29)" +NumberElementZn = "30 - Zink (Zn)" +AlphaElementZn = "Zn - Zink (30)" +NumberElementGa = "31 - Gallium (Ga)" +AlphaElementGa = "Ga - Gallium (32)" +NumberElementGe = "32 - Germanium (Ge)" +AlphaElementGe = "Ge - Germanium (32)" +NumberElementAs = "33 - Arsen (As)" +AlphaElementAs = "As - Arsen (33)" +NumberElementSe = "34 - Selen (Se)" +AlphaElementSe = "Se - Selen (34)" +NumberElementBr = "35 - Brom (Br)" +AlphaElementBr = "Br - Brom (35)" +NumberElementKr = "36 - Krypton (Kr)" +AlphaElementKr = "Kr - Krypton (36)" +NumberElementRb = "37 - Rubidium (Rb)" +AlphaElementRb = "Rb - Rubidium (37)" +NumberElementSr = "38 - Strontium (Sr)" +AlphaElementSr = "Sr - Strontium (38)" +NumberElementY = "39 - Yttrium (Y)" +AlphaElementY = "Y - Yttrium (39)" +NumberElementZr = "40 - Zirkonium (Zr)" +AlphaElementZr = "Zr - Zirkonium (40)" +NumberElementNb = "41 - Niob (Nb)" +AlphaElementNb = "Nb - Niob (41)" +NumberElementMo = "42 - Molybdän (Mo)" +AlphaElementMo = "Mo - Molybdän (42)" +NumberElementTc = "43 - Technetium (Tc)" +AlphaElementTc = "Tc - Technetium (43)" +NumberElementRu = "44 - Ruthenium (Ru)" +AlphaElementRu = "Ru - Ruthenium (44)" +NumberElementRh = "45 - Rhodium (Rh)" +AlphaElementRh = "Rh - Rhodium (45)" +NumberElementPd = "46 - Palladium (Pd)" +AlphaElementPd = "Pd - Palladium (46)" +NumberElementAg = "47 - Geld (Ag)" +AlphaElementAg = "Ag - Geld (47)" +NumberElementCd = "48 - Cadmium (Cd)" +AlphaElementCd = "Cd - Cadmium (48)" +NumberElementIn = "49 - Indium (In)" +AlphaElementIn = "In - Indium (49)" +NumberElementSn = "50 - Zinn (Sn)" +AlphaElementSn = "Sn - Zinn (50)" +NumberElementSb = "51 - Antimon (Sb)" +AlphaElementSb = "Sb - Antimon (51)" +NumberElementTe = "52 - Tellur (Te)" +AlphaElementTe = "Te - Tellur (52)" +NumberElementI = "53 - Jod (I)" +AlphaElementI = "I - Jod (53)" +NumberElementXe = "54 - Xenon (Xe)" +AlphaElementXe = "Xe - Xenon (54)" +NumberElementCs = "55 - Cäsium (Cs)" +AlphaElementCs = "Cs - Cäsium (55)" +NumberElementBa = "56 - Barium (Ba)" +AlphaElementBa = "Ba - Barium (56)" +NumberElementLa = "57 - Lanthan (La)" +AlphaElementLa = "La - Lanthan (57)" +NumberElementCe = "58 - Cer (Ce)" +AlphaElementCe = "Ce - Cer (58)" +NumberElementPr = "59 - Praseodym (Pr)" +AlphaElementPr = "Pr - Praseodym (59)" +NumberElementNd = "60 - Neodym (Nd)" +AlphaElementNd = "Nd - Neodym (60)" +NumberElementPm = "61 - Promethium (Pm)" +AlphaElementPm = "Pm - Promethium (61)" +NumberElementSm = "62 - Samarium (Sm)" +AlphaElementSm = "Sm - Samarium (62)" +NumberElementEu = "63 - Europium (Eu)" +AlphaElementEu = "Eu - Europium (63)" +NumberElementGd = "64 - Gadolinium (Gd)" +AlphaElementGd = "Gd - Gadolinium (64)" +NumberElementTb = "65 - Terbium (Tb)" +AlphaElementTb = "Tb - Terbium (65)" +NumberElementDy = "66 - Dysprosium (Dy)" +AlphaElementDy = "Dy - Dysprosium (66)" +NumberElementHo = "67 - Holmium (Ho)" +AlphaElementHo = "Ho - Holmium (67)" +NumberElementEr = "68 - Erbium (Er)" +AlphaElementEr = "Er - Erbium (68)" +NumberElementTm = "69 - Thulium (Tm)" +AlphaElementTm = "Tm - Thulium (69)" +NumberElementYb = "70 - Ytterbium (Yb)" +AlphaElementYb = "Yb - Ytterbium (70)" +NumberElementLu = "71 - Lutetium (Lu)" +AlphaElementLu = "Lu - Lutetium (71)" +NumberElementHf = "72 - Hafnium (Hf)" +AlphaElementHf = "Hf - Hafnium (72)" +NumberElementTa = "73 - Tantal (Ta)" +AlphaElementTa = "Ta - Tantal (73)" +NumberElementW = "74 - Wolfram (W)" +AlphaElementW = "W - Wolfram (74)" +NumberElementRe = "75 - Rhenium (Re)" +AlphaElementRe = "Re - Rhenium (75)" +NumberElementOs = "76 - Osmium (Os)" +AlphaElementOs = "Os - Osmium (76)" +NumberElementIr = "77 - Iridium (Ir)" +AlphaElementIr = "Ir - Iridium (77)" +NumberElementPt = "78 - Platin (Pt)" +AlphaElementPt = "Pt - Platin (78)" +NumberElementAu = "79 - Gold (O)" +AlphaElementAu = "Au - Gold (79)" +NumberElementHg = "80 - Quecksilber (Hg)" +AlphaElementHg = "Hg - Quecksilber (80)" +NumberElementTl = "81 - Thallium (Tl)" +AlphaElementTl = "Tl - Thallium (81)" +NumberElementPb = "82 - führen (Pb)" +AlphaElementPb = "Pb - führen (82)" +NumberElementBi = "83 - Wismut (Bi)" +AlphaElementBi = "Bi - Wismut (83)" +NumberElementPo = "84 - Polonium (Po)" +AlphaElementPo = "Po - Polonium (84)" +NumberElementAt = "85 - Astat (At)" +AlphaElementAt = "At - Astat (85)" +NumberElementRn = "86 - Radon (Rn)" +AlphaElementRn = "Rn - Radon (86)" +NumberElementFr = "87 - Francium (Fr)" +AlphaElementFr = "Fr - Francium (223)" +NumberElementRa = "88 - Radium (Ra)" +AlphaElementRa = "Ra - Radium (88)" +NumberElementAc = "89 - Aktinium (Ac)" +AlphaElementAc = "Ac - Aktinium (89)" +NumberElementTh = "90 - Thorium (Th)" +AlphaElementTh = "Th - Thorium (90)" +NumberElementPa = "91 - Protaktinium (Pa)" +AlphaElementPa = "Pa - Protaktinium (91)" +NumberElementU = "92 - Uran (U)" +AlphaElementU = "U - Uran (92)" +NumberElementNp = "93 - Neptunium (Np)" +AlphaElementNp = "Np - Neptunium (93)" +NumberElementPu = "94 - Plutonium (Pu)" +AlphaElementPu = "Pu - Plutonium (94)" +NumberElementAm = "95 - Americium (Am)" +AlphaElementAm = "Am - Americium (95)" +NumberElementCm = "96 - Curium (Cm)" +AlphaElementCm = "Cm - Curium (96)" +NumberElementBk = "97 - Berkelium (Bk)" +AlphaElementBk = "Bk - Berkelium (97)" +NumberElementCf = "98 - Californium (Cf)" +AlphaElementCf = "Cf - Californium (98)" +NumberElementEs = "99 - Einsteinium (Es)" +AlphaElementEs = "Es - Einsteinium (99)" +NumberElementFm = "100 - Fermium (Fm)" +AlphaElementFm = "Fm - Fermium (100)" +NumberElementMd = "101 - Mendelevium (Md)" +AlphaElementMd = "Md - Mendelevium (101)" +NumberElementNo = "102 - nobelium (No)" +AlphaElementNo = "No - nobelium (102)" +NumberElementLr = "103 - lawrencium (Lr)" +AlphaElementLr = "Lr - lawrencium (103)" +NumberElementRf = "104 - rutherfordium (Rf)" +AlphaElementRf = "Rf - rutherfordium (104)" +NumberElementDb = "105 - Dubnium (Db)" +AlphaElementDb = "Db - Dubnium (105)" +NumberElementSg = "106 - Seaborgium (Sg)" +AlphaElementSg = "Sg - Seaborgium (106)" +NumberElementBh = "107 - Bohrium (Bh)" +AlphaElementBh = "Bh - Bohrium (107)" +NumberElementHs = "108 - Hassium (Hs)" +AlphaElementHs = "Hs - Hassium (108)" +NumberElementMt = "109 - Meitnerium (Mt)" +AlphaElementMt = "Mt - Meitnerium (109)" +NumberElementDs = "110 - Darmstadtium (Ds)" +AlphaElementDs = "Ds - Darmstadtium (110)" +NumberElementRg = "111 - Roentgenium (Rg)" +AlphaElementRg = "Rg - Roentgenium (111)" +NumberElementCn = "112 - Copernicium (Cn)" +AlphaElementCn = "Cn - Copernicium (112)" +NumberElementNh = "113 - Nihonium (Nh)" +AlphaElementNh = "Nh - Nihonium (113)" +NumberElementFl = "114 - Flerovium (Fl)" +AlphaElementFl = "Fl - Flerovium (114)" +NumberElementMc = "115 - Moscovium (Mc)" +AlphaElementMc = "Mc - Moscovium (115)" +NumberElementLv = "116 - Livermorium (Lv)" +AlphaElementLv = "Lv - Livermorium (116)" +NumberElementTs = "117 - Tennesse (Ts)" +AlphaElementTs = "Ts - Tennesse (117)" +NumberElementOg = "118 - Oganesson (Og)" +AlphaElementOg = "Og - Oganesson (118)" +NumberElementUue = "119 - Ununennium (Uue)" +AlphaElementUue = "Uue - Ununennium (119)" +NumberElementUbn = "120 - Unbinilium (Ubn)" +AlphaElementUbn = "Ubn - Unbinilium (120)" +Speed = "Geschwindigkeit" +SpeedOfSound = "Schallgeschwindigkeit" +SpeedOfLightTag = "Lichtgeschwindigkeit" +SpeedOfSound0Tag = "Meeresspiegel, 20 ° C" +SpeedOfSoundWaterTag = "In Wasser" +SpeedOfSoundSteelTag = "In Stahl" +SpeedOfSoundGlassTag = "In Glas" +EscapeVelocity = "Fluchtgeschwindigkeit" +EscapeVelocityFromEarth = "Von der Erde" +EscapeVelocityFromMoon = "Vom Mond" +EscapeVelocityFromSun = "Von der Sonne" +YearLightTag = "Lichtjahr" +Thermodynamics = "Thermodynamik" +BoltzmannTag = "Boltzmann Konstante" +AvogadroTag = "Avogadro-Konstante" +GasTag = "Gaskonstante" +Electromagnetism = "Elektromagnetismus" +CoulombTag = "Coulomb-Konstante" +Vacuum_permittivityTag = "Vakuum-Durchlässigkeit" +Vacuum_permeabilityTag = "Vakuumdurchlässigkeit" +PlanckTag = "Planck - Konstante" +ElectronMassTag = "Elektrons" +ProtonMassTag = "Protons" +NeutronMassTag = "Neutrons" +Gravitation = "Gravitation" +ElementalChargeTag = "Elementarladung" +GAccelerationTag = "Beschleunigung" +GConstantTag = "Konstant" +Mass = "Messe" +MoonMassTag = "Mond" +EarthMassTag = "Erde" +SunMassTag = "Sonne" +ParticleMass = "Partikel Masse" +AstronomicalMass = "Astronomische" +Radiuses = "Radien" +Length = "Länge" +Distances = "Entfernungen" +EarthMoonDistanceTag = "Erde - Mond" +EarthSunDistanceTag = "Erde - Sonne" +FaradayConstantTag = "Faraday-Konstante" +StefanBoltzmannTag = "Stefan-Boltzmann-Konstante" +WaterTriplePointTag = "Wasser-Tripelpunkt" +WienTag = "Wien-Konstante" +AtmosphericPressureTag = "Atmosphärischer Druck" +VacuumImpedanceTag = "Vakuum-Impedanz" +BohrMagnetonTag = "Bohrmegneton" +NuclearMagnetonTag = "Kernmagneton" +MuonMassTag = "Muon" +AtomicMassUnitTag = "Atomare Masseneinheit" +BohrRadiusTag = "Bohr-Radius" +PlanckUnitsTag = "Planck-Einheiten" +PlanckReduceTag = "Reduzierte Planck-Konstante" +PlanckMassTag = "Planck-Masse" +PlanckLengthTag = "Planck-Länge" +PlanckTimeTag = "Planck-Zeit" +PlanckTemperatureTag = "Planck-Temperatur" +PlanckChargeTag = "Planck-Gebühr" +PlanckForceTag = "Planck-Kraft" +PlanckEnergyTag = "Planck-Energie" +PlanckPowerTag = "Planck-Leistung" +FundamentalConstants = "Fundamentale Konstanten" +NuclearConstants = "Nukleare und atomare Konstanten" +UnitSolidAngleSteradian = "Steradiant" +UnitLuminousFluxLumen = "Lumen" +UnitIlluminanceLux = "Lux" +UnitSolidAngleMenu = "Raumwinkel" +UnitLuminousFluxMenu = "Lichtstrom" +UnitIlluminanceMenu = "Beleuchtungsstärke" +PlanckDensityTag = "Planck-Dichte" +PlanckQuantityMovementTag = "Planck-Menge der Bewegung" +PlanckLinearMassTag = "Lineare Masse nach Planck" +PlanckTensionTag = "Planck-Spannung" +PlanckCurrentTag = "Planck-Strom" +PlanckPressureTag = "Planck-Druck" +PlanckImpedanceTag = "Planck-Impedanz" +TauonMassTag = "Tauon" +WBosonMassTag = "W Boson" +ZBosonMassTag = "Z Boson" +FineStructureTag = "Feinstrukturkonstante" +RydbergConstantTag = "Rydberg-Konstante" +HartreeConstantTag = "Hartbaum-Konstante" +MagneticFluxQuantumTag = "Magnetisches Fluss-Quantum" +ConductanceQuantumTag = "Leitwertquantum" +CirculationQuantumTag = "Auflage-Quantum" diff --git a/apps/toolbox.en.i18n b/apps/toolbox.en.i18n index 32a26a0c70b..7e28841366a 100644 --- a/apps/toolbox.en.i18n +++ b/apps/toolbox.en.i18n @@ -19,12 +19,15 @@ UnitDistanceMeterMilli = "Millimeter" UnitDistanceMeterMicro = "Micrometer" UnitDistanceMeterNano = "Nanometer" UnitDistanceMeterPico = "Picometer" +UnitDistanceImperialMenu = "US Customary" +UnitDistanceInch = "Inch" +UnitDistanceFoot = "Foot" +UnitDistanceYard = "Yard" +UnitDistanceMile = "Mile" UnitDistanceAstronomicalUnit = "Astronomical unit" UnitDistanceLightYear = "Light year" -UnitDistanceMile = "Mile" -UnitDistanceYard = "Yard" -UnitDistanceFoot = "Foot" -UnitDistanceInch = "Inch" +UnitDistanceParsec = "Parsec" +UnitMassImperialMenu = "US Customary" UnitMassMenu = "Mass" UnitMassGramKilo = "Kilogram" UnitMassGram = "Gram" @@ -107,6 +110,7 @@ Identity = "Identity matrix of size n" Lists = "List" HyperbolicTrigonometry = "Hyperbolic trigonometry" Fluctuation = "Prediction Interval" +InfinityMessage = "Infinity" DerivateNumber = "Derivative" Integral = "Integral" Sum = "Sum" @@ -164,3 +168,331 @@ InvBinomial = "m where P(X<=m)=a, X follows B(n,p)" Probability = "Probability" BinomialDistribution = "Binomial distribution" NormalDistribution = "Normal distribution" +Chemistry = "Chemistry" +Physics = "Physics" +MolarMassesByNumber = "Molar masses (1,2...)" +MolarMassesByAlpha = "Molar masses (A,B...)" +NumberElementH = "1 - Hydrogen (H)" +AlphaElementH = "H - Hydrogen (1)" +NumberElementHe = "2 - Helium (He)" +AlphaElementHe = "He - Helium (2)" +NumberElementLi = "3 - Lithium (Li)" +AlphaElementLi = "Li - Lithium (3)" +NumberElementBe = "4 - Beryllium (Be)" +AlphaElementBe = "Be - Beryllium (4)" +NumberElementB = "5 - Boron (B)" +AlphaElementB = "B - Boron (5)" +NumberElementC = "6 - Carbon (C)" +AlphaElementC = "C - Carbon (6)" +NumberElementN = "7 - Nitrogen (N)" +AlphaElementN = "N - Nitrogen (7)" +NumberElementO = "8 - Oxygen (O)" +AlphaElementO = "O - Oxygen (8)" +NumberElementF = "9 - Fluorine (F)" +AlphaElementF = "F - Fluorine (9)" +NumberElementNe = "10 - Neon (Ne)" +AlphaElementNe = "Ne - Neon (10)" +NumberElementNa = "11 - Sodium (Na)" +AlphaElementNa = "Na - Sodium (11)" +NumberElementMg = "12 - Magnesium (Mg)" +AlphaElementMg = "Mg - Magnesium (12)" +NumberElementAl = "13 - Aluminum (Al)" +AlphaElementAl = "Al - Aluminum (13)" +NumberElementSi = "14 - Silicon (Si)" +AlphaElementSi = "Si - Silicon (14)" +NumberElementP = "15 - Phosphorus (P)" +AlphaElementP = "P - Phosphorus (15)" +NumberElementS = "16 - Sulfur (S)" +AlphaElementS = "S - Sulfur (16)" +NumberElementCl = "17 - Chlorine (Cl)" +AlphaElementCl = "Cl - Chlorine (17)" +NumberElementAr = "18 - Argon (Ar)" +AlphaElementAr = "Ar - Argon (18)" +NumberElementK = "19 - Potassium (K)" +AlphaElementK = "K - Potassium (19)" +NumberElementCa = "20 - Calcium (Ca)" +AlphaElementCa = "Ca - Calcium (20)" +NumberElementSc = "21 - Scandium (Sc)" +AlphaElementSc = "Sc - Scandium (21)" +NumberElementTi = "22 - Titanium (Ti)" +AlphaElementTi = "Ti - Titanium (22)" +NumberElementV = "23 - Vanadium (V)" +AlphaElementV = "V - Vanadium (23)" +NumberElementCr = "24 - Chromium (Cr)" +AlphaElementCr = "Cr - Chromium (24)" +NumberElementMn = "25 - Manganese (Mn)" +AlphaElementMn = "Mn - Manganese (25)" +NumberElementFe = "26 - Iron (Fe)" +AlphaElementFe = "Fe - Iron (26)" +NumberElementCo = "27 - Cobalt (Co)" +AlphaElementCo = "Co - Cobalt (27)" +NumberElementNi = "28 - Nickel (Ni)" +AlphaElementNi = "Ni - Nickel (28)" +NumberElementCu = "29 - Copper (Cu)" +AlphaElementCu = "Cu - Copper (29)" +NumberElementZn = "30 - Zinc (Zn)" +AlphaElementZn = "Zn - Zinc (30)" +NumberElementGa = "31 - Gallium (Ga)" +AlphaElementGa = "Ga - Gallium (32)" +NumberElementGe = "32 - Germanium (Ge)" +AlphaElementGe = "Ge - Germanium (32)" +NumberElementAs = "33 - Arsenic (As)" +AlphaElementAs = "As - Arsenic (33)" +NumberElementSe = "34 - Selenium (Se)" +AlphaElementSe = "Se - Selenium (34)" +NumberElementBr = "35 - Bromine (Br)" +AlphaElementBr = "Br - Bromine (35)" +NumberElementKr = "36 - Krypton (Kr)" +AlphaElementKr = "Kr - Krypton (36)" +NumberElementRb = "37 - Rubidium (Rb)" +AlphaElementRb = "Rb - Rubidium (37)" +NumberElementSr = "38 - Strontium (Sr)" +AlphaElementSr = "Sr - Strontium (38)" +NumberElementY = "39 - Yttrium (Y)" +AlphaElementY = "Y - Yttrium (39)" +NumberElementZr = "40 - Zirconium (Zr)" +AlphaElementZr = "Zr - Zirconium (40)" +NumberElementNb = "41 - Niobium (Nb)" +AlphaElementNb = "Nb - Niobium (41)" +NumberElementMo = "42 - Molybdenum (Mo)" +AlphaElementMo = "Mo - Molybdenum (42)" +NumberElementTc = "43 - Technetium (Tc)" +AlphaElementTc = "Tc - Technetium (43)" +NumberElementRu = "44 - Ruthenium (Ru)" +AlphaElementRu = "Ru - Ruthenium (44)" +NumberElementRh = "45 - rhodium (Rh)" +AlphaElementRh = "Rh - rhodium (45)" +NumberElementPd = "46 - Palladium (Pd)" +AlphaElementPd = "Pd - Palladium (46)" +NumberElementAg = "47 - Money (Ag)" +AlphaElementAg = "Ag - Money (47)" +NumberElementCd = "48 - Cadmium (Cd)" +AlphaElementCd = "Cd - Cadmium (48)" +NumberElementIn = "49 - Indium (In)" +AlphaElementIn = "In - Indium (49)" +NumberElementSn = "50 - Tin (Sn)" +AlphaElementSn = "Sn - Tin (50)" +NumberElementSb = "51 - Antimony (Sb)" +AlphaElementSb = "Sb - Antimony (51)" +NumberElementTe = "52 - Tellurium (Te)" +AlphaElementTe = "Te - Tellurium (52)" +NumberElementI = "53 - Iodine (I)" +AlphaElementI = "I - Iodine (53)" +NumberElementXe = "54 - Xenon (Xe)" +AlphaElementXe = "Xe - Xenon (54)" +NumberElementCs = "55 - cesium (Cs)" +AlphaElementCs = "Cs - cesium (55)" +NumberElementBa = "56 - Barium (Ba)" +AlphaElementBa = "Ba - Barium (56)" +NumberElementLa = "57 - Lanthanum (La)" +AlphaElementLa = "La - Lanthanum (57)" +NumberElementCe = "58 - Cerium (Ce)" +AlphaElementCe = "Ce - Cerium (58)" +NumberElementPr = "59 - praseodymium (Pr)" +AlphaElementPr = "Pr - praseodymium (59)" +NumberElementNd = "60 - Neodymium (Nd)" +AlphaElementNd = "Nd - Neodymium (60)" +NumberElementPm = "61 - Promethium (Pm)" +AlphaElementPm = "Pm - Promethium (61)" +NumberElementSm = "62 - Samarium (Sm)" +AlphaElementSm = "Sm - Samarium (62)" +NumberElementEu = "63 - Europium (Eu)" +AlphaElementEu = "Eu - Europium (63)" +NumberElementGd = "64 - Gadolinium (Gd)" +AlphaElementGd = "Gd - Gadolinium (64)" +NumberElementTb = "65 - Terbium (Tb)" +AlphaElementTb = "Tb - Terbium (65)" +NumberElementDy = "66 - Dysprosium (Dy)" +AlphaElementDy = "Dy - Dysprosium (66)" +NumberElementHo = "67 - holmium (Ho)" +AlphaElementHo = "Ho - holmium (67)" +NumberElementEr = "68 - Erbium (Er)" +AlphaElementEr = "Er - Erbium (68)" +NumberElementTm = "69 - Thulium (Tm)" +AlphaElementTm = "Tm - Thulium (69)" +NumberElementYb = "70 - Ytterbium (Yb)" +AlphaElementYb = "Yb - Ytterbium (70)" +NumberElementLu = "71 - Lutecium (Lu)" +AlphaElementLu = "Lu - Lutecium (71)" +NumberElementHf = "72 - Hafnium (Hf)" +AlphaElementHf = "Hf - Hafnium (72)" +NumberElementTa = "73 - Tantalum (Ta)" +AlphaElementTa = "Ta - Tantalum (73)" +NumberElementW = "74 - Tungsten (W)" +AlphaElementW = "W - Tungsten (74)" +NumberElementRe = "75 - Rhenium (Re)" +AlphaElementRe = "Re - Rhenium (75)" +NumberElementOs = "76 - Osmium (Os)" +AlphaElementOs = "Os - Osmium (76)" +NumberElementIr = "77 - Iridium (Ir)" +AlphaElementIr = "Ir - Iridium (77)" +NumberElementPt = "78 - Platinum (Pt)" +AlphaElementPt = "Pt - Platinum (78)" +NumberElementAu = "79 - Gold (Au)" +AlphaElementAu = "Au - Gold (79)" +NumberElementHg = "80 - Mercury (Hg)" +AlphaElementHg = "Hg - Mercury (80)" +NumberElementTl = "81 - Thallium (Tl)" +AlphaElementTl = "Tl - Thallium (81)" +NumberElementPb = "82 - Lead (Pb)" +AlphaElementPb = "Pb - Lead (82)" +NumberElementBi = "83 - Bismuth (Bi)" +AlphaElementBi = "Bi - Bismuth (83)" +NumberElementPo = "84 - Polonium (Po)" +AlphaElementPo = "Po - Polonium (84)" +NumberElementAt = "85 - astatine (At)" +AlphaElementAt = "At - astatine (85)" +NumberElementRn = "86 - Radon (Rn)" +AlphaElementRn = "Rn - Radon (86)" +NumberElementFr = "87 - francium (Fr)" +AlphaElementFr = "Fr - francium (223)" +NumberElementRa = "88 - Radium (Ra)" +AlphaElementRa = "Ra - Radium (88)" +NumberElementAc = "89 - Actinium (Ac)" +AlphaElementAc = "Ac - Actinium (89)" +NumberElementTh = "90 - Thorium (Th)" +AlphaElementTh = "Th - Thorium (90)" +NumberElementPa = "91 - Protactinium (Pa)" +AlphaElementPa = "Pa - Protactinium (91)" +NumberElementU = "92 - Uranium (U)" +AlphaElementU = "U - Uranium (92)" +NumberElementNp = "93 - Neptunium (Np)" +AlphaElementNp = "Np - Neptunium (93)" +NumberElementPu = "94 - Plutonium (Pu)" +AlphaElementPu = "Pu - Plutonium (94)" +NumberElementAm = "95 - Americium (Am)" +AlphaElementAm = "Am - Americium (95)" +NumberElementCm = "96 - Curium (Cm)" +AlphaElementCm = "Cm - Curium (96)" +NumberElementBk = "97 - Berkelium (Bk)" +AlphaElementBk = "Bk - Berkelium (97)" +NumberElementCf = "98 - Californium (Cf)" +AlphaElementCf = "Cf - Californium (98)" +NumberElementEs = "99 - Einsteinium (Es)" +AlphaElementEs = "Es - Einsteinium (99)" +NumberElementFm = "100 - Fermium (Fm)" +AlphaElementFm = "Fm - Fermium (100)" +NumberElementMd = "101 - Mendélévium (Md)" +AlphaElementMd = "Md - Mendélévium (101)" +NumberElementNo = "102 - Nobelium (No)" +AlphaElementNo = "No - Nobelium (102)" +NumberElementLr = "103 - Lawrencium (Lr)" +AlphaElementLr = "Lr - Lawrencium (103)" +NumberElementRf = "104 - Rutherfordium (Rf)" +AlphaElementRf = "Rf - Rutherfordium (104)" +NumberElementDb = "105 - Dubnium (Db)" +AlphaElementDb = "Db - Dubnium (105)" +NumberElementSg = "106 - Seaborgium (Sg)" +AlphaElementSg = "Sg - Seaborgium (106)" +NumberElementBh = "107 - Bohrium (Bh)" +AlphaElementBh = "Bh - Bohrium (107)" +NumberElementHs = "108 - Hassium (Hs)" +AlphaElementHs = "Hs - Hassium (108)" +NumberElementMt = "109 - Meitnerium (Mt)" +AlphaElementMt = "Mt - Meitnerium (109)" +NumberElementDs = "110 - Darmstadtium (Ds)" +AlphaElementDs = "Ds - Darmstadtium (110)" +NumberElementRg = "111 - Roentgenium (Rg)" +AlphaElementRg = "Rg - Roentgenium (111)" +NumberElementCn = "112 - Copernicium (Cn)" +AlphaElementCn = "Cn - Copernicium (112)" +NumberElementNh = "113 - Nihonium (Nh)" +AlphaElementNh = "Nh - Nihonium (113)" +NumberElementFl = "114 - Flerovium (Fl)" +AlphaElementFl = "Fl - Flerovium (114)" +NumberElementMc = "115 - Moscovium (Mc)" +AlphaElementMc = "Mc - Moscovium (115)" +NumberElementLv = "116 - Livermorium (Lv)" +AlphaElementLv = "Lv - Livermorium (116)" +NumberElementTs = "117 - Tennesse (Ts)" +AlphaElementTs = "Ts - Tennesse (117)" +NumberElementOg = "118 - Oganesson (Og)" +AlphaElementOg = "Og - Oganesson (118)" +NumberElementUue = "119 - Ununennium (Uue)" +AlphaElementUue = "Uue - Ununennium (119)" +NumberElementUbn = "120 - Unbinilium (Ubn)" +AlphaElementUbn = "Ubn - Unbinilium (120)" +Speed = "Speed" +SpeedOfSound = "Speed of sound" +SpeedOfSound0Tag = "Sea level, 20°C" +SpeedOfSoundWaterTag = "In water" +SpeedOfSoundSteelTag = "In steel" +SpeedOfSoundGlassTag = "In glass" +EscapeVelocity = "Escape Velocity" +EscapeVelocityFromEarth = "Of Earth" +EscapeVelocityFromMoon = "Of Moon" +EscapeVelocityFromSun = "Of Sun" +SpeedOfLightTag = "Speed of light" +YearLightTag = "One year light" +Thermodynamics = "Thermodynamics" +BoltzmannTag = "Boltzmann Constant" +AvogadroTag = "Avogadro Constant" +GasTag = "Gas Constant" +Electromagnetism = "Electromagnetism" +CoulombTag = "Coulomb Constant" +Vacuum_permittivityTag = "Vacuum permittivity" +Vacuum_permeabilityTag = "Vacuum permeability" +PlanckTag = "Planck Constant" +ElectronMassTag = "Electron" +ProtonMassTag = "Proton" +NeutronMassTag = "Neutron" +Gravitation = "Gravitation" +ElementalChargeTag = "Elementary Charge" +GAccelerationTag = "Acceleration" +GConstantTag = "Constant" +Mass = "Mass" +MoonMassTag = "Moon" +EarthMassTag = "Earth" +SunMassTag = "Sun" +ParticleMass = "Particles Mass" +AstronomicalMass = "Astronomical" +Radiuses = "Radiuses" +Length = "Length" +Distances = "Distances" +EarthMoonDistanceTag = "Earth - Moon" +EarthSunDistanceTag = "Earth - Sun" +FaradayConstantTag = "Faraday Constant" +StefanBoltzmannTag = "Stefan-Boltzmann Constant" +WaterTriplePointTag = "Water Triple Point" +WienTag = "Wien Constant" +AtmosphericPressureTag = "Atmospheric Pressure" +VacuumImpedanceTag = "Vacuum Impedance" +BohrMagnetonTag = "Bohr Magneton" +NuclearMagnetonTag = "Nuclear Magneton" +MuonMassTag = "Muon" +AtomicMassUnitTag = "Atomic Mass Unit" +BohrRadiusTag = "Bohr Radius" +PlanckUnitsTag = "Planck Units" +PlanckReduceTag = "Reduced Planck Constant" +PlanckMassTag = "Planck Mass" +PlanckLengthTag = "Planck Length" +PlanckTimeTag = "Planck Time" +PlanckTemperatureTag = "Planck Temperature" +PlanckChargeTag = "Planck Charge" +PlanckForceTag = "Planck Force" +PlanckEnergyTag = "Planck Energy" +PlanckPowerTag = "Planck Power" +FundamentalConstants = "Fundamental Constants" +NuclearConstants = "Nuclear and Atomic Constants" +UnitSolidAngleSteradian = "Steradian" +UnitLuminousFluxLumen = "Lumen" +UnitIlluminanceLux = "Lux" +UnitSolidAngleMenu = "Solid Angle" +UnitLuminousFluxMenu = "Luminous Flux" +UnitIlluminanceMenu = "Illuminance" +PlanckDensityTag = "Planck Density" +PlanckQuantityMovementTag = "Planck Quantity of Movement" +PlanckLinearMassTag = "Planck Linear Mass" +PlanckTensionTag = "Planck Tension" +PlanckCurrentTag = "Planck Current" +PlanckPressureTag = "Planck Pressure" +PlanckImpedanceTag = "Planck Impedance" +TauonMassTag = "Tauon" +WBosonMassTag = "W Boson" +ZBosonMassTag = "Z Boson" +FineStructureTag = "Fine Structure Constant" +RydbergConstantTag = "Rydberg Constant" +HartreeConstantTag = "Hartree Constant" +MagneticFluxQuantumTag = "Magnetic Flux Quantum" +ConductanceQuantumTag = "Conductance Quantum" +CirculationQuantumTag = "Circulation Quantum" diff --git a/apps/toolbox.es.i18n b/apps/toolbox.es.i18n index 7b665f55aa0..a61c44d33a8 100644 --- a/apps/toolbox.es.i18n +++ b/apps/toolbox.es.i18n @@ -19,8 +19,11 @@ UnitDistanceMeterMilli = "Millimeter" UnitDistanceMeterMicro = "Micrometer" UnitDistanceMeterNano = "Nanometer" UnitDistanceMeterPico = "Picometer" +UnitDistanceImperialMenu = "US Customary" UnitDistanceAstronomicalUnit = "Astronomical unit" UnitDistanceLightYear = "Light year" +UnitDistanceParsec = "Parsec" +UnitMassImperialMenu = "US Customary" UnitDistanceMile = "Milla" UnitDistanceYard = "Yardas" UnitDistanceFoot = "Pie" @@ -107,6 +110,7 @@ Identity = "Matriz identidad de tamaño n" Lists = "Listas" HyperbolicTrigonometry = "Trigonometría hiperbólica" Fluctuation = "Interval de predicción" +InfinityMessage = "Infinito" DerivateNumber = "Derivada" Integral = "Integral" Sum = "Suma" @@ -164,3 +168,331 @@ InvBinomial = "m donde P(X<=m)=a y X sigue B(n,p)" Probability = "Probabilidad" BinomialDistribution = "Distribución binomial" NormalDistribution = "Distribución normal" +Chemistry = "Química" +Physics = "Físico" +MolarMassesByNumber = "Masas molares (1,2...)" +MolarMassesByAlpha = "Masas molares (A,B...)" +NumberElementH = "1 - Hidrógeno (H)" +AlphaElementH = "H - Hidrógeno (1)" +NumberElementHe = "2 - Helio (He)" +AlphaElementHe = "He - Helio (2)" +NumberElementLi = "3 - Litio (Li)" +AlphaElementLi = "Li - Litio (3)" +NumberElementBe = "4 - Berilio (Be)" +AlphaElementBe = "Be - Berilio (4)" +NumberElementB = "5 - Boro (B)" +AlphaElementB = "B - Boro (5)" +NumberElementC = "6 - Carbono (C)" +AlphaElementC = "C - Carbono (6)" +NumberElementN = "7 - Nitrógeno (N)" +AlphaElementN = "N - Nitrógeno (7)" +NumberElementO = "8 - Oxígeno (O)" +AlphaElementO = "O - Oxígeno (8)" +NumberElementF = "9 - Flúor (F)" +AlphaElementF = "F - Flúor (9)" +NumberElementNe = "10 - Neón (Ne)" +AlphaElementNe = "Ne - Neón (10)" +NumberElementNa = "11 - Sodio (Na)" +AlphaElementNa = "Na - Sodio (11)" +NumberElementMg = "12 - Magnesio (Mg)" +AlphaElementMg = "Mg - Magnesio (12)" +NumberElementAl = "13 - Aluminio (Al)" +AlphaElementAl = "Al - Aluminio (13)" +NumberElementSi = "14 - Silicio (Si)" +AlphaElementSi = "Si - Silicio (14)" +NumberElementP = "15 - Fósforo (P)" +AlphaElementP = "P - Fósforo (15)" +NumberElementS = "16 - Azufre (S)" +AlphaElementS = "S - Azufre (16)" +NumberElementCl = "17 - Cloro (Cl)" +AlphaElementCl = "Cl - Cloro (17)" +NumberElementAr = "18 - Argón (Ar)" +AlphaElementAr = "Ar - Argón (18)" +NumberElementK = "19 - Potasio (K)" +AlphaElementK = "K - Potasio (19)" +NumberElementCa = "20 - Calcio (Ca)" +AlphaElementCa = "Ca - Calcio (20)" +NumberElementSc = "21 - Escandio (Sc)" +AlphaElementSc = "Sc - Escandio (21)" +NumberElementTi = "22 - Titanio (Ti)" +AlphaElementTi = "Ti - Titanio (22)" +NumberElementV = "23 - Vanadio (V)" +AlphaElementV = "V - Vanadio (23)" +NumberElementCr = "24 - Cromo (Cr)" +AlphaElementCr = "Cr - Cromo (24)" +NumberElementMn = "25 - Manganeso (Mn)" +AlphaElementMn = "Mn - Manganeso (25)" +NumberElementFe = "26 - Hierro (Fe)" +AlphaElementFe = "Fe - Hierro (26)" +NumberElementCo = "27 - Cobalto (Co)" +AlphaElementCo = "Co - Cobalto (27)" +NumberElementNi = "28 - Níquel (Ni)" +AlphaElementNi = "Ni - Níquel (28)" +NumberElementCu = "29 - Cobre (Cu)" +AlphaElementCu = "Cu - Cobre (29)" +NumberElementZn = "30 - Zinc (Zn)" +AlphaElementZn = "Zn - Zinc (30)" +NumberElementGa = "31 - Galio (Ga)" +AlphaElementGa = "Ga - Galio (32)" +NumberElementGe = "32 - Germanio (Ge)" +AlphaElementGe = "Ge - Germanio (32)" +NumberElementAs = "33 - Arsénico (As)" +AlphaElementAs = "As - Arsénico (33)" +NumberElementSe = "34 - Selenio (Se)" +AlphaElementSe = "Se - Selenio (34)" +NumberElementBr = "35 - Bromo (Br)" +AlphaElementBr = "Br - Bromo (35)" +NumberElementKr = "36 - Criptón (Kr)" +AlphaElementKr = "Kr - Criptón (36)" +NumberElementRb = "37 - Rubidio (Rb)" +AlphaElementRb = "Rb - Rubidio (37)" +NumberElementSr = "38 - Estroncio (Sr)" +AlphaElementSr = "Sr - Estroncio (38)" +NumberElementY = "39 - Itrio (Y)" +AlphaElementY = "Y - Itrio (39)" +NumberElementZr = "40 - Circonio (Zr)" +AlphaElementZr = "Zr - Circonio (40)" +NumberElementNb = "41 - Niobio (Nb)" +AlphaElementNb = "Nb - Niobio (41)" +NumberElementMo = "42 - Molibdeno (Mo)" +AlphaElementMo = "Mo - Molibdeno (42)" +NumberElementTc = "43 - Tecnecio (Tc)" +AlphaElementTc = "Tc - Tecnecio (43)" +NumberElementRu = "44 - Rutenio (Ru)" +AlphaElementRu = "Ru - Rutenio (44)" +NumberElementRh = "45 - Rodio (Rh)" +AlphaElementRh = "Rh - Rodio (45)" +NumberElementPd = "46 - Paladio (Pd)" +AlphaElementPd = "Pd - Paladio (46)" +NumberElementAg = "47 - Dinero (Ag)" +AlphaElementAg = "Ag - Dinero (47)" +NumberElementCd = "48 - Cadmio (Cd)" +AlphaElementCd = "Cd - Cadmio (48)" +NumberElementIn = "49 - Indio (In)" +AlphaElementIn = "In - Indio (49)" +NumberElementSn = "50 - Estaño (Sn)" +AlphaElementSn = "Sn - Estaño (50)" +NumberElementSb = "51 - Antimonio (Sb)" +AlphaElementSb = "Sb - Antimonio (51)" +NumberElementTe = "52 - Telurio (Te)" +AlphaElementTe = "Te - Telurio (52)" +NumberElementI = "53 - Yodo (I)" +AlphaElementI = "I - Yodo (53)" +NumberElementXe = "54 - Cenón (Xe)" +AlphaElementXe = "Xe - Cenón (54)" +NumberElementCs = "55 - Cesio (Cs)" +AlphaElementCs = "Cs - Cesio (55)" +NumberElementBa = "56 - Bario (Ba)" +AlphaElementBa = "Ba - Bario (56)" +NumberElementLa = "57 - Lantano (La)" +AlphaElementLa = "La - Lantano (57)" +NumberElementCe = "58 - Cerio (Ce)" +AlphaElementCe = "Ce - Cerio (58)" +NumberElementPr = "59 - Praseodimio (Pr)" +AlphaElementPr = "Pr - Praseodimio (59)" +NumberElementNd = "60 - Neodimio (Nd)" +AlphaElementNd = "Nd - Neodimio (60)" +NumberElementPm = "61 - Prometeo (Pm)" +AlphaElementPm = "Pm - Prometeo (61)" +NumberElementSm = "62 - Samario (Sm)" +AlphaElementSm = "Sm - Samario (62)" +NumberElementEu = "63 - Europio (Eu)" +AlphaElementEu = "Eu - Europio (63)" +NumberElementGd = "64 - Gadolinio (Gd)" +AlphaElementGd = "Gd - Gadolinio (64)" +NumberElementTb = "65 - Terbio (Tb)" +AlphaElementTb = "Tb - Terbio (65)" +NumberElementDy = "66 - Disprosio (Dy)" +AlphaElementDy = "Dy - Disprosio (66)" +NumberElementHo = "67 - Holmio (Ho)" +AlphaElementHo = "Ho - Holmio (67)" +NumberElementEr = "68 - Erbio (Er)" +AlphaElementEr = "Er - Erbio (68)" +NumberElementTm = "69 - Tulio (Tm)" +AlphaElementTm = "Tm - Tulio (69)" +NumberElementYb = "70 - Iterbio (Yb)" +AlphaElementYb = "Yb - Iterbio (70)" +NumberElementLu = "71 - Lutecio (Lu)" +AlphaElementLu = "Lu - Lutecio (71)" +NumberElementHf = "72 - Hafnio (Hf)" +AlphaElementHf = "Hf - Hafnio (72)" +NumberElementTa = "73 - Tantalio (Ta)" +AlphaElementTa = "Ta - Tantalio (73)" +NumberElementW = "74 - Tungsteno (W)" +AlphaElementW = "W - Tungsteno (74)" +NumberElementRe = "75 - Renio (Re)" +AlphaElementRe = "Re - Renio (75)" +NumberElementOs = "76 - Osmio (Os)" +AlphaElementOs = "Os - Osmio (76)" +NumberElementIr = "77 - Iridio (Ir)" +AlphaElementIr = "Ir - Iridio (77)" +NumberElementPt = "78 - Platino (Pt)" +AlphaElementPt = "Pt - Platino (78)" +NumberElementAu = "79 - Oro (O)" +AlphaElementAu = "Au - Oro (79)" +NumberElementHg = "80 - Mercurio (Hg)" +AlphaElementHg = "Hg - Mercurio (80)" +NumberElementTl = "81 - Talio (Tl)" +AlphaElementTl = "Tl - Talio (81)" +NumberElementPb = "82 - Conducir (Pb)" +AlphaElementPb = "Pb - Conducir (82)" +NumberElementBi = "83 - Bismuto (Bi)" +AlphaElementBi = "Bi - Bismuto (83)" +NumberElementPo = "84 - Polonio (Po)" +AlphaElementPo = "Po - Polonio (84)" +NumberElementAt = "85 - Astato (At)" +AlphaElementAt = "At - Astato (85)" +NumberElementRn = "86 - Radón (Rn)" +AlphaElementRn = "Rn - Radón (86)" +NumberElementFr = "87 - Francio (Fr)" +AlphaElementFr = "Fr - Francio (223)" +NumberElementRa = "88 - Radio (Ra)" +AlphaElementRa = "Ra - Radio (88)" +NumberElementAc = "89 - Actinio (Ac)" +AlphaElementAc = "Ac - Actinio (89)" +NumberElementTh = "90 - Torio (Th)" +AlphaElementTh = "Th - Torio (90)" +NumberElementPa = "91 - Protactinio (Pa)" +AlphaElementPa = "Pa - Protactinio (91)" +NumberElementU = "92 - Uranio (U)" +AlphaElementU = "U - Uranio (92)" +NumberElementNp = "93 - Neptunio (Np)" +AlphaElementNp = "Np - Neptunio (93)" +NumberElementPu = "94 - Plutonio (Pu)" +AlphaElementPu = "Pu - Plutonio (94)" +NumberElementAm = "95 - Americio (Am)" +AlphaElementAm = "Am - Americio (95)" +NumberElementCm = "96 - Curio (Cm)" +AlphaElementCm = "Cm - Curio (96)" +NumberElementBk = "97 - Berkelio (Bk)" +AlphaElementBk = "Bk - Berkelio (97)" +NumberElementCf = "98 - Californio (Cf)" +AlphaElementCf = "Cf - Californio (98)" +NumberElementEs = "99 - Einstenio (Es)" +AlphaElementEs = "Es - Einstenio (99)" +NumberElementFm = "100 - Fermio (Fm)" +AlphaElementFm = "Fm - Fermio (100)" +NumberElementMd = "101 - Mendelevio (Md)" +AlphaElementMd = "Md - Mendelevio (101)" +NumberElementNo = "102 - Nobelio (No)" +AlphaElementNo = "No - Nobelio (102)" +NumberElementLr = "103 - Lawrencio (Lr)" +AlphaElementLr = "Lr - Lawrencio (103)" +NumberElementRf = "104 - Rutherfordio (Rf)" +AlphaElementRf = "Rf - Rutherfordio (104)" +NumberElementDb = "105 - dubnio (Db)" +AlphaElementDb = "Db - dubnio (105)" +NumberElementSg = "106 - Seaborgio (Sg)" +AlphaElementSg = "Sg - Seaborgio (106)" +NumberElementBh = "107 - Bohrio (Bh)" +AlphaElementBh = "Bh - Bohrio (107)" +NumberElementHs = "108 - Hassio (Hs)" +AlphaElementHs = "Hs - Hassio (108)" +NumberElementMt = "109 - Meitnerio (Mt)" +AlphaElementMt = "Mt - Meitnerio (109)" +NumberElementDs = "110 - Darmstadtium (Ds)" +AlphaElementDs = "Ds - Darmstadtium (110)" +NumberElementRg = "111 - Roentgenio (Rg)" +AlphaElementRg = "Rg - Roentgenio (111)" +NumberElementCn = "112 - Copernicio (Cn)" +AlphaElementCn = "Cn - Copernicio (112)" +NumberElementNh = "113 - Nihonium (Nh)" +AlphaElementNh = "Nh - Nihonium (113)" +NumberElementFl = "114 - Flerovium (Fl)" +AlphaElementFl = "Fl - Flerovium (114)" +NumberElementMc = "115 - Moscovium (Mc)" +AlphaElementMc = "Mc - Moscovium (115)" +NumberElementLv = "116 - Livermorium (Lv)" +AlphaElementLv = "Lv - Livermorium (116)" +NumberElementTs = "117 - Tennesse (Ts)" +AlphaElementTs = "Ts - Tennesse (117)" +NumberElementOg = "118 - Oganesson (Og)" +AlphaElementOg = "Og - Oganesson (118)" +NumberElementUue = "119 - Ununennio (Uue)" +AlphaElementUue = "Uue - Ununennio (119)" +NumberElementUbn = "120 - Unbinilio (Ubn)" +AlphaElementUbn = "Ubn - Unbinilio (120)" +Speed = "Velocidad" +SpeedOfLightTag = "Velocidad de la luz" +SpeedOfSound = "La velocidad del sonido" +YearLightTag = "Un año de luz" +Thermodynamics = "Termodinámica" +SpeedOfSound0Tag = "Nivel del mar, 20 ° C" +SpeedOfSoundWaterTag = "En el agua" +SpeedOfSoundSteelTag = "En acero" +SpeedOfSoundGlassTag = "En vidrio" +EscapeVelocity = "Velocidad de escape" +EscapeVelocityFromEarth = "De La Tierra" +EscapeVelocityFromMoon = "De la Luna" +EscapeVelocityFromSun = "De el Sol" +BoltzmannTag = "Constante Boltzmann" +AvogadroTag = "Constante de Avogadro" +GasTag = "Constante de gas" +Electromagnetism = "Electromagnetismo" +CoulombTag = "Constante de Coulomb" +Vacuum_permittivityTag = "Permisividad de vacío" +Vacuum_permeabilityTag = "Permeabilidad al vacío" +PlanckTag = "Constante de Planck" +ElectronMassTag = "Electrón" +ProtonMassTag = "Protón" +NeutronMassTag = "Neutrón" +Gravitation = "Gravitación" +ElementalChargeTag = "Carga elemental" +GAccelerationTag = "Aceleración" +GConstantTag = "Constante" +Mass = "Masa" +MoonMassTag = "Luna" +EarthMassTag = "Tierra" +SunMassTag = "Sol" +ParticleMass = "Misa de las partículas" +AstronomicalMass = "Astronómica" +Radiuses = "Radios" +Length = "Lenght" +Distances = "Distancias" +EarthMoonDistanceTag = "Tierra - Luna" +EarthSunDistanceTag = "Tierra - Sol" +FaradayConstantTag = "Constante de Faraday" +StefanBoltzmannTag = "Constante de Stefan-Boltzmann" +WaterTriplePointTag = "Punto Triple de Agua" +WienTag = "Constante de Wien" +AtmosphericPressureTag = "Presión Atmosférica" +VacuumImpedanceTag = "Impedancia de vacío" +BohrMagnetonTag = "Magnéton de Bohr" +NuclearMagnetonTag = "Magnetón nuclear" +MuonMassTag = "Muon" +AtomicMassUnitTag = "Unidad de Masa Atómica" +BohrRadiusTag = "Radio de Bohr" +PlanckUnitsTag = "Unidades de Planck" +PlanckReduceTag = "Constante reducida de Planck" +PlanckMassTag = "Masa de Planck" +PlanckLengthTag = "Longitud de Planck" +PlanckTimeTag = "La hora de Planck" +PlanckTemperatureTag = "Temperatura de Planck" +PlanckChargeTag = "Carga de Planck" +PlanckForceTag = "Fuerza de Planck" +PlanckEnergyTag = "Energía de Planck" +PlanckPowerTag = "El poder de Planck" +FundamentalConstants = "Constantes fundamentales" +NuclearConstants = "Constantes nucleares y atómicas" +UnitSolidAngleSteradian = "Estereorradián" +UnitLuminousFluxLumen = "Lumen" +UnitIlluminanceLux = "Lux" +UnitSolidAngleMenu = "Ángulo sólido" +UnitLuminousFluxMenu = "Flujo luminoso" +UnitIlluminanceMenu = "Luz Iluminada" +PlanckDensityTag = "Densidad de Planck" +PlanckQuantityMovementTag = "Cantidad de movimiento de Planck" +PlanckLinearMassTag = "Masa lineal de Planck" +PlanckTensionTag = "Tensión de Planck" +PlanckCurrentTag = "Corriente de Planck" +PlanckPressureTag = "Presión de Planck" +PlanckImpedanceTag = "Impedancia de Planck" +TauonMassTag = "Tauon" +WBosonMassTag = "W Boson" +ZBosonMassTag = "Z Boson" +FineStructureTag = "Constante de la estructura fina" +RydbergConstantTag = "Constante de Rydberg" +HartreeConstantTag = "Constante de Hartree" +MagneticFluxQuantumTag = "Flujo Magnético Cuántico" +ConductanceQuantumTag = "Conductancia Quantum" +CirculationQuantumTag = "Circulación Quantum" diff --git a/apps/toolbox.fr.i18n b/apps/toolbox.fr.i18n index 1b74fe81817..f33aa140fb2 100644 --- a/apps/toolbox.fr.i18n +++ b/apps/toolbox.fr.i18n @@ -19,8 +19,15 @@ UnitDistanceMeterMilli = "Millimètre" UnitDistanceMeterMicro = "Micromètre" UnitDistanceMeterNano = "Nanomètre" UnitDistanceMeterPico = "Picomètre" +UnitDistanceImperialMenu = "US Customary" +UnitDistanceInch = "Inch" +UnitDistanceFoot = "Foot" +UnitDistanceYard = "Yard" +UnitDistanceMile = "Mile" UnitDistanceAstronomicalUnit = "Unité astronomique" UnitDistanceLightYear = "Année-lumière" +UnitDistanceParsec = "Parsec" +UnitMassImperialMenu = "US Customary" UnitDistanceMile = "Mile" UnitDistanceYard = "Yard" UnitDistanceFoot = "Pied" @@ -107,6 +114,7 @@ Identity = "Matrice identité de taille n" Lists = "Listes" HyperbolicTrigonometry = "Trigonométrie hyperbolique" Fluctuation = "Intervalle de fluctuation" +InfinityMessage = "Infini" DerivateNumber = "Nombre derivé de f en a" Integral = "Intégrale de f sur [a;b]" Sum = "Somme" @@ -164,3 +172,331 @@ InvBinomial = "m où P(X<=m)=a et X suit B(n,p)" Probability = "Probabilités" BinomialDistribution = "Loi binomiale" NormalDistribution = "Loi normale" +Chemistry = "Chimie" +Physics = "Physique" +MolarMassesByNumber = "Masses molaires (1,2...)" +MolarMassesByAlpha = "Masses molaires (A,B...)" +NumberElementH = "1 - Hydrogène (H)" +AlphaElementH = "H - Hydrogène (1)" +NumberElementHe = "2 - Hélium (He)" +AlphaElementHe = "He - Hélium (2)" +NumberElementLi = "3 - Lithium (Li)" +AlphaElementLi = "Li - Lithium (3)" +NumberElementBe = "4 - Béryllium (Be)" +AlphaElementBe = "Be - Béryllium (4)" +NumberElementB = "5 - Bore (B)" +AlphaElementB = "B - Bore (5)" +NumberElementC = "6 - Carbone (C)" +AlphaElementC = "C - Carbone (6)" +NumberElementN = "7 - Azote (N)" +AlphaElementN = "N - Azote (7)" +NumberElementO = "8 - Oxygène (O)" +AlphaElementO = "O - Oxygène (8)" +NumberElementF = "9 - Fluor (F)" +AlphaElementF = "F - Fluor (9)" +NumberElementNe = "10 - Néon (Ne)" +AlphaElementNe = "Ne - Néon (10)" +NumberElementNa = "11 - Sodium (Na)" +AlphaElementNa = "Na - Sodium (11)" +NumberElementMg = "12 - Magnésium (Mg)" +AlphaElementMg = "Mg - Magnésium (12)" +NumberElementAl = "13 - Aluminium (Al)" +AlphaElementAl = "Al - Aluminium (13)" +NumberElementSi = "14 - Silicium (Si)" +AlphaElementSi = "Si - Silicium (14)" +NumberElementP = "15 - Phosphore (P)" +AlphaElementP = "P - Phosphore (15)" +NumberElementS = "16 - Soufre (S)" +AlphaElementS = "S - Soufre (16)" +NumberElementCl = "17 - Chlore (Cl)" +AlphaElementCl = "Cl - Chlore (17)" +NumberElementAr = "18 - Argon (Ar)" +AlphaElementAr = "Ar - Argon (18)" +NumberElementK = "19 - Potassium (K)" +AlphaElementK = "K - Potassium (19)" +NumberElementCa = "20 - Calcium (Ca)" +AlphaElementCa = "Ca - Calcium (20)" +NumberElementSc = "21 - Scandium (Sc)" +AlphaElementSc = "Sc - Scandium (21)" +NumberElementTi = "22 - Titane (Ti)" +AlphaElementTi = "Ti - Titane (22)" +NumberElementV = "23 - Vanadium (V)" +AlphaElementV = "V - Vanadium (23)" +NumberElementCr = "24 - Chrome (Cr)" +AlphaElementCr = "Cr - Chrome (24)" +NumberElementMn = "25 - Manganèse (Mn)" +AlphaElementMn = "Mn - Manganèse (25)" +NumberElementFe = "26 - Fer (Fe)" +AlphaElementFe = "Fe - Fer (26)" +NumberElementCo = "27 - Cobalt (Co)" +AlphaElementCo = "Co - Cobalt (27)" +NumberElementNi = "28 - Nickel (Ni)" +AlphaElementNi = "Ni - Nickel (28)" +NumberElementCu = "29 - Cuivre (Cu)" +AlphaElementCu = "Cu - Cuivre (29)" +NumberElementZn = "30 - Zinc (Zn)" +AlphaElementZn = "Zn - Zinc (30)" +NumberElementGa = "31 - Gallium (Ga)" +AlphaElementGa = "Ga - Gallium (32)" +NumberElementGe = "32 - Germanium (Ge)" +AlphaElementGe = "Ge - Germanium (32)" +NumberElementAs = "33 - Arsenic (As)" +AlphaElementAs = "As - Arsenic (33)" +NumberElementSe = "34 - Sélénium (Se)" +AlphaElementSe = "Se - Sélénium (34)" +NumberElementBr = "35 - Brome (Br)" +AlphaElementBr = "Br - Brome (35)" +NumberElementKr = "36 - Krypton (Kr)" +AlphaElementKr = "Kr - Krypton (36)" +NumberElementRb = "37 - Rubidium (Rb)" +AlphaElementRb = "Rb - Rubidium (37)" +NumberElementSr = "38 - Strontium (Sr)" +AlphaElementSr = "Sr - Strontium (38)" +NumberElementY = "39 - Yttrium (Y)" +AlphaElementY = "Y - Yttrium (39)" +NumberElementZr = "40 - Zirconium (Zr)" +AlphaElementZr = "Zr - Zirconium (40)" +NumberElementNb = "41 - Niobium (Nb)" +AlphaElementNb = "Nb - Niobium (41)" +NumberElementMo = "42 - Molybdène (Mo)" +AlphaElementMo = "Mo - Molybdène (42)" +NumberElementTc = "43 - Technétium (Tc)" +AlphaElementTc = "Tc - Technétium (43)" +NumberElementRu = "44 - Ruthénium (Ru)" +AlphaElementRu = "Ru - Ruthénium (44)" +NumberElementRh = "45 - Rhodium (Rh)" +AlphaElementRh = "Rh - Rhodium (45)" +NumberElementPd = "46 - Palladium (Pd)" +AlphaElementPd = "Pd - Palladium (46)" +NumberElementAg = "47 - Argent (Ag)" +AlphaElementAg = "Ag - Argent (47)" +NumberElementCd = "48 - Cadmium (Cd)" +AlphaElementCd = "Cd - Cadmium (48)" +NumberElementIn = "49 - Indium (In)" +AlphaElementIn = "In - Indium (49)" +NumberElementSn = "50 - Etain (Sn)" +AlphaElementSn = "Sn - Etain (50)" +NumberElementSb = "51 - Antimoine (Sb)" +AlphaElementSb = "Sb - Antimoine (51)" +NumberElementTe = "52 - Tellure (Te)" +AlphaElementTe = "Te - Tellure (52)" +NumberElementI = "53 - Iode (I)" +AlphaElementI = "I - Iode (53)" +NumberElementXe = "54 - Xénon (Xe)" +AlphaElementXe = "Xe - Xénon (54)" +NumberElementCs = "55 - Césium (Cs)" +AlphaElementCs = "Cs - Césium (55)" +NumberElementBa = "56 - Baryum (Ba)" +AlphaElementBa = "Ba - Baryum (56)" +NumberElementLa = "57 - Lanthane (La)" +AlphaElementLa = "La - Lanthane (57)" +NumberElementCe = "58 - Cérium (Ce)" +AlphaElementCe = "Ce - Cérium (58)" +NumberElementPr = "59 - Praséodyme (Pr)" +AlphaElementPr = "Pr - Praséodyme (59)" +NumberElementNd = "60 - Néodyme (Nd)" +AlphaElementNd = "Nd - Néodyme (60)" +NumberElementPm = "61 - Prométhium (Pm)" +AlphaElementPm = "Pm - Prométhium (61)" +NumberElementSm = "62 - Samarium (Sm)" +AlphaElementSm = "Sm - Samarium (62)" +NumberElementEu = "63 - Europium (Eu)" +AlphaElementEu = "Eu - Europium (63)" +NumberElementGd = "64 - Gadolinium (Gd)" +AlphaElementGd = "Gd - Gadolinium (64)" +NumberElementTb = "65 - Terbium (Tb)" +AlphaElementTb = "Tb - Terbium (65)" +NumberElementDy = "66 - Dysprosium (Dy)" +AlphaElementDy = "Dy - Dysprosium (66)" +NumberElementHo = "67 - Holmium (Ho)" +AlphaElementHo = "Ho - Holmium (67)" +NumberElementEr = "68 - Erbium (Er)" +AlphaElementEr = "Er - Erbium (68)" +NumberElementTm = "69 - Thulium (Tm)" +AlphaElementTm = "Tm - Thulium (69)" +NumberElementYb = "70 - Ytterbium (Yb)" +AlphaElementYb = "Yb - Ytterbium (70)" +NumberElementLu = "71 - Lutécium (Lu)" +AlphaElementLu = "Lu - Lutécium (71)" +NumberElementHf = "72 - Hafnium (Hf)" +AlphaElementHf = "Hf - Hafnium (72)" +NumberElementTa = "73 - Tantale (Ta)" +AlphaElementTa = "Ta - Tantale (73)" +NumberElementW = "74 - Tungstène (W)" +AlphaElementW = "W - Tungstène (74)" +NumberElementRe = "75 - Rhénium (Re)" +AlphaElementRe = "Re - Rhénium (75)" +NumberElementOs = "76 - Osmium (Os)" +AlphaElementOs = "Os - Osmium (76)" +NumberElementIr = "77 - Iridium (Ir)" +AlphaElementIr = "Ir - Iridium (77)" +NumberElementPt = "78 - Platine (Pt)" +AlphaElementPt = "Pt - Platine (78)" +NumberElementAu = "79 - Or (O)" +AlphaElementAu = "Au - Or (79)" +NumberElementHg = "80 - Mercure (Hg)" +AlphaElementHg = "Hg - Mercure (80)" +NumberElementTl = "81 - Thallium (Tl)" +AlphaElementTl = "Tl - Thallium (81)" +NumberElementPb = "82 - Plomb (Pb)" +AlphaElementPb = "Pb - Plomb (82)" +NumberElementBi = "83 - Bismuth (Bi)" +AlphaElementBi = "Bi - Bismuth (83)" +NumberElementPo = "84 - Polonium (Po)" +AlphaElementPo = "Po - Polonium (84)" +NumberElementAt = "85 - Astate (At)" +AlphaElementAt = "At - Astate (85)" +NumberElementRn = "86 - Radon (Rn)" +AlphaElementRn = "Rn - Radon (86)" +NumberElementFr = "87 - Francium (Fr)" +AlphaElementFr = "Fr - Francium (223)" +NumberElementRa = "88 - Radium (Ra)" +AlphaElementRa = "Ra - Radium (88)" +NumberElementAc = "89 - Actinium (Ac)" +AlphaElementAc = "Ac - Actinium (89)" +NumberElementTh = "90 - Thorium (Th)" +AlphaElementTh = "Th - Thorium (90)" +NumberElementPa = "91 - Protactinium (Pa)" +AlphaElementPa = "Pa - Protactinium (91)" +NumberElementU = "92 - Uranium (U)" +AlphaElementU = "U - Uranium (92)" +NumberElementNp = "93 - Neptunium (Np)" +AlphaElementNp = "Np - Neptunium (93)" +NumberElementPu = "94 - Plutonium (Pu)" +AlphaElementPu = "Pu - Plutonium (94)" +NumberElementAm = "95 - Américium (Am)" +AlphaElementAm = "Am - Américium (95)" +NumberElementCm = "96 - Curium (Cm)" +AlphaElementCm = "Cm - Curium (96)" +NumberElementBk = "97 - Berkélium (Bk)" +AlphaElementBk = "Bk - Berkélium (97)" +NumberElementCf = "98 - Californium (Cf)" +AlphaElementCf = "Cf - Californium (98)" +NumberElementEs = "99 - Einsteinium (Es)" +AlphaElementEs = "Es - Einsteinium (99)" +NumberElementFm = "100 - Fermium (Fm)" +AlphaElementFm = "Fm - Fermium (100)" +NumberElementMd = "101 - Mendélévium (Md)" +AlphaElementMd = "Md - Mendélévium (101)" +NumberElementNo = "102 - Nobélium (No)" +AlphaElementNo = "No - Nobélium (102)" +NumberElementLr = "103 - Lawrencium (Lr)" +AlphaElementLr = "Lr - Lawrencium (103)" +NumberElementRf = "104 - Rutherfordium (Rf)" +AlphaElementRf = "Rf - Rutherfordium (104)" +NumberElementDb = "105 - Dubnium (Db)" +AlphaElementDb = "Db - Dubnium (105)" +NumberElementSg = "106 - Seaborgium (Sg)" +AlphaElementSg = "Sg - Seaborgium (106)" +NumberElementBh = "107 - Bohrium (Bh)" +AlphaElementBh = "Bh - Bohrium (107)" +NumberElementHs = "108 - Hassium (Hs)" +AlphaElementHs = "Hs - Hassium (108)" +NumberElementMt = "109 - Meitnérium (Mt)" +AlphaElementMt = "Mt - Meitnérium (109)" +NumberElementDs = "110 - Darmstadtium (Ds)" +AlphaElementDs = "Ds - Darmstadtium (110)" +NumberElementRg = "111 - Roentgenium (Rg)" +AlphaElementRg = "Rg - Roentgenium (111)" +NumberElementCn = "112 - Copernicium (Cn)" +AlphaElementCn = "Cn - Copernicium (112)" +NumberElementNh = "113 - Nihonium (Nh)" +AlphaElementNh = "Nh - Nihonium (113)" +NumberElementFl = "114 - Flérovium (Fl)" +AlphaElementFl = "Fl - Flérovium (114)" +NumberElementMc = "115 - Moscovium (Mc)" +AlphaElementMc = "Mc - Moscovium (115)" +NumberElementLv = "116 - Livermorium (Lv)" +AlphaElementLv = "Lv - Livermorium (116)" +NumberElementTs = "117 - Tennesse (Ts)" +AlphaElementTs = "Ts - Tennesse (117)" +NumberElementOg = "118 - Oganesson (Og)" +AlphaElementOg = "Og - Oganesson (118)" +NumberElementUue = "119 - Ununennium (Uue)" +AlphaElementUue = "Uue - Ununennium (119)" +NumberElementUbn = "120 - Unbinilium (Ubn)" +AlphaElementUbn = "Ubn - Unbinilium (120)" +Speed = "Vitesse" +SpeedOfSound = "Vitesse du son" +SpeedOfSound0Tag = "Niveau de la mer, 20°C" +SpeedOfSoundWaterTag = "Dans l'eau" +SpeedOfSoundSteelTag = "Dans l'acier" +SpeedOfSoundGlassTag = "Dans le verre" +SpeedOfLightTag = "Vitesse de la lumière" +YearLightTag = "Année lumière" +Thermodynamics = "Thermodynamique" +BoltzmannTag = "Constante de Boltzmann" +AvogadroTag = "Constante d'Avogadro" +GasTag = "Constante des gaz parfaits" +Electromagnetism = "Electromagnétisme" +CoulombTag = "Constante de Coulomb" +EscapeVelocity = "Vitesse de libération" +EscapeVelocityFromEarth = "De la Terre" +EscapeVelocityFromMoon = "De la Lune" +EscapeVelocityFromSun = "Du Soleil" +Vacuum_permittivityTag = "Permittivité du vide" +Vacuum_permeabilityTag = "Perméabilité du vide" +PlanckTag = "Constante de Planck" +ElectronMassTag = "Electron" +ProtonMassTag = "Proton" +NeutronMassTag = "Neutron" +Gravitation = "Gravitation" +ElementalChargeTag = "Charge élémentaire" +GAccelerationTag = "Accélération" +GConstantTag = "Constante" +Mass = "Masse" +MoonMassTag = "Lune" +EarthMassTag = "Terre" +SunMassTag = "Soleil" +ParticleMass = "Masses des Particules" +AstronomicalMass = "Astronomiques" +Radiuses = "Rayons" +Length = "Longueur" +Distances = "Distances" +EarthMoonDistanceTag = "Terre - Lune" +EarthSunDistanceTag = "Terre - Soleil" +FaradayConstantTag = "Constante de Faraday" +StefanBoltzmannTag = "Constante de Stefan-Boltzmann" +WaterTriplePointTag = "Point Triple de l'eau" +WienTag = "Constante de Wien" +AtmosphericPressureTag = "Pression Atmosphérique" +VacuumImpedanceTag = "Impédance du Vide" +BohrMagnetonTag = "Magnéton de Bohr" +NuclearMagnetonTag = "Magnéton Nucléaire" +MuonMassTag = "Muon" +AtomicMassUnitTag = "Unité de Masse Atomique" +BohrRadiusTag = "Rayon de Bohr" +PlanckUnitsTag = "Unités de Planck" +PlanckReduceTag = "Constante de Planck réduite" +PlanckMassTag = "Masse de Planck" +PlanckLengthTag = "Longueur de Planck" +PlanckTimeTag = "Temps de Planck" +PlanckTemperatureTag = "Température de Planck" +PlanckChargeTag = "Charge de Planck" +PlanckForceTag = "Force de Planck" +PlanckEnergyTag = "Énergie de Planck" +PlanckPowerTag = "Puissance de Planck" +FundamentalConstants = "Constantes Fondamentales" +NuclearConstants = "Constantes Atomiques/Nucléaires" +UnitSolidAngleSteradian = "Stéradian" +UnitLuminousFluxLumen = "Lumen" +UnitIlluminanceLux = "Lux" +UnitSolidAngleMenu = "Angle Solide" +UnitLuminousFluxMenu = "Flux Lumineux" +UnitIlluminanceMenu = "Eclairement Lumineux" +PlanckDensityTag = "Densité de Planck" +PlanckQuantityMovementTag = "Quantité de Mouvement de Planck" +PlanckLinearMassTag = "Masse Linéique de Planck" +PlanckTensionTag = "Tension de Planck" +PlanckCurrentTag = "Courant de Planck" +PlanckPressureTag = "Pression de Planck" +PlanckImpedanceTag = "Impédance de Planck" +TauonMassTag = "Tauon" +WBosonMassTag = "Boson W" +ZBosonMassTag = "Boson Z" +FineStructureTag = "Constante de Structure Fine" +RydbergConstantTag = "Constante de Rydberg" +HartreeConstantTag = "Constante de Hartree" +MagneticFluxQuantumTag = "Quantum de Flux Magnétique" +ConductanceQuantumTag = "Quantum de Conductance" +CirculationQuantumTag = "Quantum de Circulation" diff --git a/apps/toolbox.hu.i18n b/apps/toolbox.hu.i18n new file mode 100644 index 00000000000..4cb79e66647 --- /dev/null +++ b/apps/toolbox.hu.i18n @@ -0,0 +1,498 @@ +Unit = "Mértékegység" +UnitTimeMenu = "Idö" +UnitTimeSecondMenu = "Másodperc" +UnitTimeSecond = "Másodperc" +UnitTimeSecondMilli = "Miliszekundum" +UnitTimeSecondMicro = "Mikroszekundum" +UnitTimeSecondNano = "Nanoszekundum" +UnitTimeMinute = "Perc" +UnitTimeHour = "Óra" +UnitTimeDay = "Nap" +UnitTimeWeek = "hét" +UnitTimeMonth = "Hónap" +UnitTimeYear = "Év" +UnitDistanceMenu = "Távolság" +UnitDistanceMeterMenu = "Méter" +UnitDistanceMeterKilo = "Kilométer" +UnitDistanceMeter = "Méter" +UnitDistanceMeterMilli = "Milliméter" +UnitDistanceMeterMicro = "Mikrométer" +UnitDistanceMeterNano = "Nanométer" +UnitDistanceMeterPico = "Pikométer" +UnitDistanceImperialMenu = "Angolszász mértékegységek" +UnitDistanceInch = "Hüvelyk" +UnitDistanceFoot = "Láb" +UnitDistanceYard = "Yard" +UnitDistanceMile = "Mérföld" +UnitDistanceAstronomicalUnit = "Csillagászati egység" +UnitDistanceLightYear = "Fény év" +UnitDistanceParsec = "Parsec" +UnitMassShortTon = "Rövid tonna" +UnitMassLongTon = "Hosszú tonna" +UnitMassImperialMenu = "Angolszász mértékegységek" +UnitMassPound = "Font" +UnitMassOunce = "Uncia" +UnitMassMenu = "Tömeg" +UnitMassGramKilo = "Kilogramm" +UnitMassGram = "Gramm" +UnitMassGramMilli = "Milligramm" +UnitMassGramMicro = "Mikrogramm" +UnitMassGramNano = "Nanogramm" +UnitMassTonne = "Tonna" +UnitCurrentMenu = "Áram" +UnitCurrentAmpere = "Amper" +UnitCurrentAmpereMilli = "Milliamper" +UnitCurrentAmpereMicro = "Mikroamper" +UnitTemperatureMenu = "Hömérséklet" +UnitAmountMenu = "Az anyag mennyisége" +UnitAmountMole = "Mól" +UnitAmountMoleMilli = "Millimól" +UnitAmountMoleMicro = "Mikromól" +UnitLuminousIntensityMenu = "Fényerö" +UnitFrequencyMenu = "Frekvencia" +UnitFrequencyHertzMega = "Megahertz" +UnitForceMenu = "Erö" +UnitForceNewtonMilli = "Millinewton" +UnitPressureMenu = "Nyomás" +UnitPressurePascalHecto = "Hectopascal" +UnitPressureAtm = "Légkör" +UnitEnergyMenu = "Energia" +UnitEnergyJouleMilli = "Millijoule" +UnitEnergyEletronVoltMenu = "Electronvolt" +UnitEnergyElectronVoltMega = "Megaelectronvolt" +UnitEnergyElectronVoltKilo = "Kiloelectronvolt" +UnitEnergyElectronVolt = "Electronvolt" +UnitEnergyElectronVoltMilli = "Millielectronvolt" +UnitPowerMenu = "Teljesítmény" +UnitPowerWattMega = "Megawatt" +UnitPowerWattMilli = "Milliwatt" +UnitPowerWattMicro = "Microwatt" +UnitElectricChargeMenu = "Elektromos töltés" +UnitPotentialMenu = "Elektromos potenciál" +UnitPotentialVoltMilli = "Millivolt" +UnitPotentialVoltMicro = "Microvolt" +UnitCapacitanceMenu = "Elektromos kapacitás" +UnitCapacitanceFaradMilli = "Millifarad" +UnitCapacitanceFaradMicro = "Microfarad" +UnitResistanceMenu = "Elektromos ellenállás" +UnitConductanceMenu = "Elektromos vezetöképesség" +UnitConductanceSiemensMilli = "Millisiemens" +UnitMagneticFieldMenu = "Mágneses mezö" +InductanceMenu = "Elektromos induktivitás" +UnitSurfaceMenu = "Terület" +UnitSurfaceAcre = "Acre" +UnitSurfaceHectar = "Hektár" +UnitVolumeMenu = "Kötet" +UnitVolumeLiter = "Liter" +UnitVolumeLiterDeci = "Deciliter" +UnitVolumeLiterCenti = "Centiliter" +UnitVolumeLiterMilli = "Milliliter" +UnitVolumeTeaspoon = "Teáskanál" +UnitVolumeTablespoon = "evőkanál" +UnitVolumeFluidOunce = "Folyadék uncia" +UnitVolumeCup = "Kupa" +UnitVolumePint = "Pint" +UnitVolumeQuart = "Quart" +UnitVolumeGallon = "Gallon" +UnitMetricMenu = "Metrikus" +UnitImperialMenu = "Birodalmi" +Toolbox = "Eszköztár" +AbsoluteValue = "Abszolút érték" +NthRoot = "n-gyökér" +BasedLogarithm = "Logaritmus az alap" +Calculation = "Számítás" +ComplexNumber = "Komplex számok" +Combinatorics = "Kombinatorika" +Arithmetic = "számtani" +Matrices = "Mátrix" +NewMatrix = "Új mátrix" +Identity = "n méretü azonosító mátrix" +Lists = "Lista" +HyperbolicTrigonometry = "Hiperbolikus trigonometria" +Fluctuation = "Jósolt intervallum" +InfinityMessage = "Végtelen" +DerivateNumber = "Származékos" +Integral = "Integral" +Sum = "Összeg" +Product = "Termék" +ComplexAbsoluteValue = "Abszolút érték" +Agument = "érv" +RealPart = "Igazi rész" +ImaginaryPart = "Képzeletbeli rész" +Conjugate = "Konjugátum" +Combination = "Kombináció" +Permutation = "Permutáció" +GreatCommonDivisor = "GCD" +LeastCommonMultiple = "LCM" +Remainder = "P maradékos osztás q-val" +Quotient = "P hányados osztás q-val" +Inverse = "Inverz" +Determinant = "determináns" +Transpose = "Átültetés" +Trace = "Trace" +Dimension = "Méret" +RowEchelonForm = "Sor echelon forma" +ReducedRowEchelonForm = "Csökkentett sorú echelon forma" +Vectors = "Vektorok" +Dot = "Pont termék" +Cross = "Kereszt termék" +NormVector = "Norm" +Sort = "Növekvö sorrend" +InvSort = "Csökkenö rendezés" +Maximum = "Maximum" +Minimum = "Minimum" +Floor = "Emelet" +FracPart = "Frakciós rész" +Ceiling = "Plafon" +Rounding = "N számjegyre kerekítés" +HyperbolicCosine = "Hiperbolikus koszinusz" +HyperbolicSine = "Hiperbolikus szinusz" +HyperbolicTangent = "Hiperbolikus érintö" +InverseHyperbolicCosine = "Inverz hiperbolikus koszinusz" +InverseHyperbolicSine = "Inverz hiperbolikus szinusz" +InverseHyperbolicTangent = "Inverz hiperbolikus érintö" +Prediction95 = "Jóslási intervallum 95%" +Prediction = "Egyszerü elörejelzési intervallum" +Confidence = "Bizalmi intervallum" +RandomAndApproximation = "Véletlen és közelítés" +RandomFloat = "Lebegöpontos szám [0,1-ben [" +RandomInteger = "Véletlen egész szám [a, b] -ben" +PrimeFactorDecomposition = "Egész szám tényezö" +NormCDF = "P (X +#include +#include + +using namespace Poincare; +using namespace Ion; + +VariableBoxEmptyController::VariableBoxEmptyView::VariableBoxEmptyView() : + m_layoutExample(0.5f, 0.5f, Palette::PrimaryText, Palette::BackgroundApps) +{ + for (int i = 0; i < k_numberOfMessages; i++) { + m_messages[i].setFont(k_font); + m_messages[i].setAlignment(0.5f, 0.5f); + m_messages[i].setBackgroundColor(Palette::BackgroundApps); + } + m_messages[0].setAlignment(0.5f,1.0f); + m_messages[k_numberOfMessages-1].setAlignment(0.5f,0.0f); +} + +void VariableBoxEmptyController::VariableBoxEmptyView::setMessages(I18n::Message * message) { + for (int i = 0; i < k_numberOfMessages; i++) { + m_messages[i].setMessage(message[i]); + } +} + +void VariableBoxEmptyController::VariableBoxEmptyView::setLayout(Poincare::Layout layout) { + m_layoutExample.setLayout(layout); +} + +void VariableBoxEmptyController::VariableBoxEmptyView::drawRect(KDContext * ctx, KDRect rect) const { + drawBorderOfRect(ctx, bounds(), Palette::ListCellBorder); +} + +int VariableBoxEmptyController::VariableBoxEmptyView::numberOfSubviews() const { + return k_numberOfMessages+1; +} + +View * VariableBoxEmptyController::VariableBoxEmptyView::subviewAtIndex(int index) { + if (index == k_layoutRowIndex) { + return &m_layoutExample; + } + if (index < k_layoutRowIndex) { + return &m_messages[index]; + } + return &m_messages[index-1]; +} + +void VariableBoxEmptyController::VariableBoxEmptyView::layoutSubviews(bool force) { + KDCoordinate width = bounds().width() - 2*k_separatorThickness; + KDCoordinate height = bounds().height() - 2*k_separatorThickness; + KDCoordinate textHeight = k_font->glyphSize().height(); + KDCoordinate layoutHeight = m_layoutExample.minimalSizeForOptimalDisplay().height(); + KDCoordinate margin = (height - k_numberOfMessages*textHeight-layoutHeight)/2; + m_layoutExample.setFrame(KDRect(k_separatorThickness, k_separatorThickness+margin+k_layoutRowIndex*textHeight, width, layoutHeight), force); + KDCoordinate currentHeight = k_separatorThickness; + for (uint8_t i = 0; i < k_numberOfMessages; i++) { + if (i == k_layoutRowIndex) { + currentHeight += layoutHeight; + } + KDCoordinate h = i == 0 || i == k_numberOfMessages - 1 ? textHeight+margin : textHeight; + m_messages[i].setFrame(KDRect(k_separatorThickness, currentHeight, width, h), force); + currentHeight += h; + } +} + +VariableBoxEmptyController::VariableBoxEmptyController() : + ViewController(nullptr), + m_view() +{ +} + +View * VariableBoxEmptyController::view() { + return &m_view; +} + +void VariableBoxEmptyController::viewDidDisappear() { + m_view.setLayout(Layout()); +} + +void VariableBoxEmptyController::setType(Type type) { + I18n::Message messages[VariableBoxEmptyView::k_numberOfMessages] = {I18n::Message::Default, I18n::Message::Default, I18n::Message::Default, I18n::Message::EnableCharacters}; + Layout layout; + switch (type) { + case Type::Expressions: + { + messages[0] = I18n::Message::EmptyExpressionBox0; + messages[1] = I18n::Message::EmptyExpressionBox1; + messages[2] = I18n::Message::EmptyExpressionBox2; + const char * storeExpression = "3→A"; + layout = LayoutHelper::String(storeExpression, strlen(storeExpression), VariableBoxEmptyView::k_font); + break; + } + case Type::Functions: + { + messages[0] = I18n::Message::EmptyFunctionBox0; + messages[1] = I18n::Message::EmptyFunctionBox1; + messages[2] = I18n::Message::EmptyFunctionBox2; + const char * storeFunction = "3+x→f(x)"; + layout = LayoutHelper::String(storeFunction, strlen(storeFunction), VariableBoxEmptyView::k_font); + break; + } + default: + assert(false); + } + m_view.setMessages(messages); + m_view.setLayout(layout); +} diff --git a/apps/variables.hu.i18n b/apps/variables.hu.i18n new file mode 100644 index 00000000000..123a3b597d2 --- /dev/null +++ b/apps/variables.hu.i18n @@ -0,0 +1,13 @@ +Variables = "Változók" +Expressions = "Kifejezések" +Functions = "Funciók" +Sequences = "Szekvenciák" +EmptyExpressionBox0 = "Nincs meghatározott változó." +EmptyFunctionBox0 = "Nincs meghatározott funkció." +EmptySequenceBox0 = "Még nem definiált szekvenciákat." +EmptyExpressionBox1 = "A változó meghatározásához írja be:" +EmptyFunctionBox1 = "Funkció meghatározásához írja be:" +EmptySequenceBox1 = "" +EmptyExpressionBox2 = "A változó neve tartalmazhat:" +EmptyFunctionBox2 = "A funkció neve tartalmazhat:" +EnableCharacters = "A..Z, a..z, 0..9 és _" diff --git a/build/config.mak b/build/config.mak index 5a2b9d3196a..29fa167625a 100644 --- a/build/config.mak +++ b/build/config.mak @@ -3,10 +3,17 @@ PLATFORM ?= device DEBUG ?= 0 +HOME_DISPLAY_EXTERNALS ?= 1 EPSILON_VERSION ?= 15.3.1 -EPSILON_APPS ?= calculation graph code statistics probability solver sequence regression settings -EPSILON_I18N ?= en fr nl pt it de es +OMEGA_VERSION ?= 1.21.0 +# OMEGA_USERNAME ?= N/A +OMEGA_STATE ?= dev +EPSILON_APPS ?= calculation rpn graph code statistics probability solver atomic sequence regression settings external +SUBMODULES_APPS = atomic rpn +EPSILON_I18N ?= en fr nl pt it de es hu EPSILON_COUNTRIES ?= WW CA DE ES FR GB IT NL PT US EPSILON_GETOPT ?= 0 EPSILON_TELEMETRY ?= 0 ESCHER_LOG_EVENTS_BINARY ?= 0 +THEME_NAME ?= omega_light +THEME_REPO ?= local diff --git a/build/defaults.mak b/build/defaults.mak index 237a9a6daab..11a7f9edd20 100644 --- a/build/defaults.mak +++ b/build/defaults.mak @@ -2,6 +2,9 @@ HOSTCC = gcc HOSTCXX = g++ PYTHON = python3 +ifdef OMEGA_USERNAME + SFLAGS += -DOMEGA_USERNAME="$(OMEGA_USERNAME)" +endif SFLAGS += -DEPSILON_GETOPT=$(EPSILON_GETOPT) SFLAGS += -DEPSILON_TELEMETRY=$(EPSILON_TELEMETRY) SFLAGS += -DESCHER_LOG_EVENTS_BINARY=$(ESCHER_LOG_EVENTS_BINARY) @@ -54,6 +57,11 @@ endif ifeq ("$(PLATFORM)", "device") SFLAGS += -DPLATFORM_DEVICE + ifeq ("$(MODEL)", "n0100") + SFLAGS += -DDEVICE_N0100 + else + SFLAGS += -DDEVICE_N0110 + endif endif # Host detection diff --git a/build/doc/Doxyfile b/build/doc/Doxyfile new file mode 100644 index 00000000000..8f9c49eebbf --- /dev/null +++ b/build/doc/Doxyfile @@ -0,0 +1,2559 @@ +# Doxyfile 1.8.18 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = Omega + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = build/doc/logo.png + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = output/doc + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all generated output in the proper direction. +# Possible values are: None, LTR, RTL and Context. +# The default value is: None. + +OUTPUT_TEXT_DIRECTION = None + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines (in the resulting output). You can put ^^ in the value part of an +# alias to insert a newline as if a physical newline was in the original file. +# When you need a literal { or } or , in the value part of an alias you have to +# escape them by means of a backslash (\), this can lead to conflicts with the +# commands \{ and \} for these it is advised to use the version @{ and @} or use +# a double escape (\\{ and \\}) + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL, +# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 5. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 5 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# declarations. If set to NO, these declarations will be included in the +# documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# (including Cygwin) ands Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = NO + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = NO + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = NO + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. If +# EXTRACT_ALL is set to YES then this flag will automatically be disabled. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = apps \ + ion/src \ + escher/src \ + ion/include \ + escher/include \ + kandinsky/src \ + kandinsky/include \ + poincare/src \ + poincare/include + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: https://www.gnu.org/software/libiconv/) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), +# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen +# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, +# *.vhdl, *.ucf, *.qsf and *.ice. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f \ + *.for \ + *.tcl \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.ice + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = build/doc/header.html + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = build/doc/footer.html + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = build/doc/customdoxygen.css + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: https://developer.apple.com/xcode/), introduced with OSX +# 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png The default and svg Looks nicer but requires the +# pdf2svg tool. +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. + +FORMULA_MACROFILE = + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side JavaScript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. +# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/ + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /