O1.18 Merge

This commit is contained in:
Quentin Guidée
2019-12-28 14:45:48 +01:00
145 changed files with 5120 additions and 994 deletions

View File

@@ -14,11 +14,13 @@ jobs:
build-device-n0100:
runs-on: ubuntu-latest
steps:
- run: sudo apt-get install binutils-arm-none-eabi build-essential gcc-arm-none-eabi imagemagick libfreetype6-dev libjpeg-dev libpng-dev pkg-config
- run: sudo apt-get install build-essential imagemagick libfreetype6-dev libjpeg-dev libpng-dev pkg-config
- uses: numworks/setup-arm-toolchain@v1
- uses: actions/checkout@v1
- run: make -j2 MODEL=n0100 epsilon.dfu
- run: make -j2 MODEL=n0100 epsilon.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
- uses: actions/upload-artifact@master
@@ -29,11 +31,13 @@ jobs:
build-device-n0110:
runs-on: ubuntu-latest
steps:
- run: sudo apt-get install binutils-arm-none-eabi build-essential gcc-arm-none-eabi imagemagick libfreetype6-dev libjpeg-dev libpng-dev pkg-config
- run: sudo apt-get install build-essential imagemagick libfreetype6-dev libjpeg-dev libpng-dev pkg-config
- uses: numworks/setup-arm-toolchain@v1
- uses: actions/checkout@v1
- run: make -j2 epsilon.dfu
- run: make -j2 epsilon.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

1
.gitignore vendored
View File

@@ -2,3 +2,4 @@
build/device/**/*.pyc
epsilon.elf
.vscode
.DS_Store

3
.gitmodules vendored
View File

@@ -4,3 +4,6 @@
[submodule "apps/atom"]
path = apps/atom
url = https://github.com/Omega-Numworks/Omega-Atom.git
[submodule "themes"]
path = themes
url = https://github.com/Omega-Numworks/Omega-Themes.git

View File

@@ -35,6 +35,8 @@ info:
@echo "EPSILON_VERSION = $(EPSILON_VERSION)"
@echo "EPSILON_APPS = $(EPSILON_APPS)"
@echo "EPSILON_I18N = $(EPSILON_I18N)"
@echo "OMEGA_THEME = $(OMEGA_THEME)"
@echo "BUILD_DIR = $(BUILD_DIR)"
@echo "PLATFORM" = $(PLATFORM)
@echo "DEBUG" = $(DEBUG)
@echo "EPSILON_GETOPT" = $(EPSILON_GETOPT)
@@ -66,6 +68,17 @@ help:
@echo " make PLATFORM=simulator TARGET=web"
@echo " make PLATFORM=simulator TARGET=windows"
.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
# "output/foo/bar.o" because the directory "output/foo" doesn't exist).
@@ -103,6 +116,11 @@ include build/scenario/Makefile
include quiz/Makefile # Quiz needs to be included at the end
all_src = $(apps_all_src) $(escher_src) $(ion_all_src) $(kandinsky_src) $(liba_src) $(libaxx_src) $(poincare_src) $(python_src) $(epsilon_src) $(runner_src) $(ion_target_device_flasher_light_src) $(ion_target_device_flasher_verbose_src) $(ion_target_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_app_src)): $(BUILD_DIR)/escher/palette.h
all_objs = $(call object_for,$(all_src))
.SECONDARY: $(all_objs)
@@ -127,6 +145,11 @@ clean:
@echo "CLEAN"
$(Q) rm -rf $(BUILD_DIR)
.PHONY: cleanall
cleanall:
@echo "CLEANALL"
$(Q) rm -rf output
.PHONY: cowsay_%
cowsay_%:
@echo " -------"
@@ -141,3 +164,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)
.PHONY: clean_run
clean_run: cleanandcompile
${MAKE} start
.PHONY: run
run: compile
${MAKE} start

View File

@@ -79,18 +79,31 @@ $(eval $(call rule_for, \
$$(PYTHON) apps/i18n.py --header $$(subst .cpp,.h,$$@) --implementation $$@ --locales $$(EPSILON_I18N) --files $$^ \
))
$(BUILD_DIR)/apps/i18n.h: $(BUILD_DIR)/apps/i18n.cpp
# Handle PNG files
$(eval $(call depends_on_image,apps/title_bar_view.cpp,apps/exam_icon.png))
all_app_src = $(app_src) $(epsilon_src) $(apps_launch_on_boarding_src) $(apps_launch_default_src) $(apps_prompt_none_src) $(apps_container_prompt_update) $(apps_prompt_beta_src) $(tests_src)
all_app_src = $(app_src) $(epsilon_src) $(apps_launch_on_boarding_src) $(apps_launch_default_src) $(apps_prompt_none_src) $(apps_prompt_update_src) $(apps_prompt_beta_src) $(tests_src)
$(call object_for,$(all_app_src)): $(BUILD_DIR)/apps/i18n.h
$(call object_for,$(all_app_src)): $(BUILD_DIR)/python/port/genhdr/qstrdefs.generated.h
apps_tests_src = $(app_calculation_test_src) $(app_probability_test_src) $(app_regression_test_src) $(app_sequence_test_src) $(app_shared_test_src) $(app_statistics_test_src) $(app_solver_test_src)
apps_tests_src += $(addprefix apps/,\
global_preferences.cpp \
)
$(foreach img,$(image_list), $(eval $(call rule_for, \
ICON, \
$(img), \
$(addprefix themes/themes/, $(addsuffix .json, $(OMEGA_THEME))), \
$$(PYTHON) themes/themes_manager.py -i $(OMEGA_THEME) $$@ $(BUILD_DIR)/ \
)))
# Configure variants
apps_all_src = $(app_src)

View File

@@ -4,11 +4,14 @@
#include <ion.h>
#include <poincare/init.h>
#include <poincare/exception_checkpoint.h>
#include <ion/backlight.h>
#include <poincare/preferences.h>
extern "C" {
#include <assert.h>
}
using namespace Poincare;
using namespace Shared;
AppsContainer * AppsContainer::sharedAppsContainer() {
@@ -198,8 +201,8 @@ bool AppsContainer::processEvent(Ion::Events::Event event) {
// Warning: if the window is dirtied, you need to call window()->redraw()
if (event == Ion::Events::USBPlug) {
if (Ion::USB::isPlugged()) {
if (GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::Activate) {
displayExamModePopUp(false);
if (GlobalPreferences::sharedGlobalPreferences()->isInExamMode()) {
displayExamModePopUp(GlobalPreferences::ExamMode::Off);
window()->redraw();
} else {
Ion::USB::enable();
@@ -218,6 +221,11 @@ bool AppsContainer::processEvent(Ion::Events::Event event) {
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;
}
@@ -237,7 +245,15 @@ bool AppsContainer::switchTo(App::Snapshot * snapshot) {
}
void AppsContainer::run() {
window()->setFrame(KDRect(0, 0, Ion::Display::Width, Ion::Display::Height));
KDRect screenRect = KDRect(0, 0, Ion::Display::Width, Ion::Display::Height);
window()->setFrame(screenRect);
/* We push a white screen here, because fetching the exam mode takes some time
* and it is visible when reflashing a N0100 (there is some noise on the
* screen before the logo appears). */
Ion::Display::pushRectUniform(screenRect, KDColorWhite);
if (GlobalPreferences::sharedGlobalPreferences()->isInExamMode()) {
activateExamMode(GlobalPreferences::sharedGlobalPreferences()->examMode());
}
refreshPreferences();
/* ExceptionCheckpoint stores the value of the stack pointer when setjump is
@@ -297,8 +313,8 @@ void AppsContainer::reloadTitleBarView() {
m_window.reloadTitleBarView();
}
void AppsContainer::displayExamModePopUp(bool activate) {
m_examPopUpController.setActivatingExamMode(activate);
void AppsContainer::displayExamModePopUp(GlobalPreferences::ExamMode mode) {
m_examPopUpController.setTargetExamMode(mode);
s_activeApp->displayModalViewController(&m_examPopUpController, 0.f, 0.f, Metric::ExamPopUpTopMargin, Metric::PopUpRightMargin, Metric::ExamPopUpBottomMargin, Metric::PopUpLeftMargin);
}
@@ -313,7 +329,7 @@ void AppsContainer::shutdownDueToLowBattery() {
}
while (Ion::Battery::level() == Ion::Battery::Charge::EMPTY) {
Ion::Backlight::setBrightness(0);
if (GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::Deactivate) {
if (!GlobalPreferences::sharedGlobalPreferences()->isInExamMode()) {
/* Unless the LED is lit up for the exam mode, switch off the LED. IF the
* low battery event happened during the Power-On Self-Test, a LED might
* have stayed lit up. */
@@ -346,6 +362,35 @@ void AppsContainer::redrawWindow(bool force) {
m_window.redraw(force);
}
void AppsContainer::activateExamMode(GlobalPreferences::ExamMode examMode) {
assert(examMode == GlobalPreferences::ExamMode::Standard || examMode == GlobalPreferences::ExamMode::Dutch || examMode == GlobalPreferences::ExamMode::NoSym);
reset();
Preferences * preferences = Preferences::sharedPreferences();
switch ((int)preferences->colorOfLED()) {
case 0:
Ion::LED::setColor(KDColorWhite);
break;
case 1:
Ion::LED::setColor(KDColorGreen);
break;
case 2:
Ion::LED::setColor(KDColorBlue);
break;
case 3:
Ion::LED::setColor(KDColorYellow);
break;
}
/* 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);
}
void AppsContainer::examDeactivatingPopUpIsDismissed() {
if (Ion::USB::isPlugged()) {
Ion::USB::enable();

View File

@@ -13,6 +13,7 @@
#include "exam_pop_up_controller_delegate.h"
#include "battery_timer.h"
#include "suspend_timer.h"
#include "global_preferences.h"
#include "backlight_dimming_timer.h"
#include "shared/global_context.h"
#include "on_boarding/pop_up_controller.h"
@@ -41,11 +42,12 @@ public:
bool updateBatteryState();
void refreshPreferences();
void reloadTitleBarView();
void displayExamModePopUp(bool activate);
void displayExamModePopUp(GlobalPreferences::ExamMode mode);
void shutdownDueToLowBattery();
void setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus newStatus);
OnBoarding::PopUpController * promptController();
void redrawWindow(bool force = false);
void activateExamMode(GlobalPreferences::ExamMode examMode);
// Exam pop-up controller delegate
void examDeactivatingPopUpIsDismissed() override;
// Ion::StorageDelegate

View File

@@ -1,5 +1,6 @@
#include "calculation.h"
#include "../shared/poincare_helpers.h"
#include "../global_preferences.h"
#include <poincare/exception_checkpoint.h>
#include <poincare/undefined.h>
#include <poincare/unreal.h>
@@ -123,7 +124,9 @@ Calculation::DisplayOutput Calculation::displayOutput(Context * context) {
}
if (shouldOnlyDisplayExactOutput()) {
m_displayOutput = DisplayOutput::ExactOnly;
} else if (input().recursivelyMatches(
// Force all results to be ApproximateOnly in Dutch exam mode
} else if (GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::Dutch ||
input().recursivelyMatches(
[](const Expression e, Context * c) {
constexpr int approximateOnlyTypesCount = 9;
/* If the input contains the following types, we only display the

View File

@@ -1,5 +1,6 @@
#include "calculation_store.h"
#include "../shared/poincare_helpers.h"
#include "../global_preferences.h"
#include <poincare/rational.h>
#include <poincare/symbol.h>
#include <poincare/undefined.h>
@@ -91,7 +92,7 @@ ExpiringPointer<Calculation> CalculationStore::push(const char * text, Context *
// Compute and serialize the outputs
{
Expression outputs[] = {Expression(), Expression()};
PoincareHelpers::ParseAndSimplifyAndApproximate(inputSerialization, &(outputs[0]), &(outputs[1]), context, true); // Symbolic computation
PoincareHelpers::ParseAndSimplifyAndApproximate(inputSerialization, &(outputs[0]), &(outputs[1]), context, GlobalPreferences::sharedGlobalPreferences()->isInExamModeSymbolic()); // Symbolic computation
for (int i = 0; i < 2; i++) {
if (!serializeExpression(outputs[i], nextSerializationLocation, &newCalculationsLocation)) {
/* If the exat/approximate output does not fit in the store (event if the

View File

@@ -10,16 +10,14 @@ using namespace Poincare;
ExamPopUpController::ExamPopUpController(ExamPopUpControllerDelegate * delegate) :
ViewController(nullptr),
m_contentView(this),
m_isActivatingExamMode(false),
m_targetExamMode(GlobalPreferences::ExamMode::Unknown),
m_delegate(delegate)
{
}
void ExamPopUpController::setActivatingExamMode(bool activatingExamMode) {
if (m_isActivatingExamMode != activatingExamMode) {
m_isActivatingExamMode = activatingExamMode;
m_contentView.setMessages(activatingExamMode);
}
void ExamPopUpController::setTargetExamMode(GlobalPreferences::ExamMode mode) {
m_targetExamMode = mode;
m_contentView.setMessagesForExamMode(mode);
}
View * ExamPopUpController::view() {
@@ -27,7 +25,7 @@ View * ExamPopUpController::view() {
}
void ExamPopUpController::viewDidDisappear() {
if (m_isActivatingExamMode == false) {
if (m_targetExamMode == GlobalPreferences::ExamMode::Off) {
m_delegate->examDeactivatingPopUpIsDismissed();
}
}
@@ -55,30 +53,15 @@ ExamPopUpController::ContentView::ContentView(Responder * parentResponder) :
}, parentResponder), KDFont::SmallFont),
m_okButton(parentResponder, I18n::Message::Ok, Invocation([](void * context, void * sender) {
ExamPopUpController * controller = (ExamPopUpController *)context;
GlobalPreferences::ExamMode nextExamMode = controller->isActivatingExamMode() ? GlobalPreferences::ExamMode::Activate : GlobalPreferences::ExamMode::Deactivate;
GlobalPreferences::sharedGlobalPreferences()->setExamMode(nextExamMode);
Preferences * preferences = Preferences::sharedPreferences();
GlobalPreferences::ExamMode mode = controller->targetExamMode();
assert(mode != GlobalPreferences::ExamMode::Unknown);
GlobalPreferences::sharedGlobalPreferences()->setExamMode(mode);
AppsContainer * container = AppsContainer::sharedAppsContainer();
if (controller->isActivatingExamMode()) {
container->reset();
switch ((int)preferences->colorOfLED()) {
case 0:
Ion::LED::setColor(KDColorWhite);
break;
case 1:
Ion::LED::setColor(KDColorGreen);
break;
case 2:
Ion::LED::setColor(KDColorBlue);
break;
case 3:
Ion::LED::setColor(KDColorYellow);
break;
}
Ion::LED::setBlinking(1000, 0.1f);
} else {
if (mode == GlobalPreferences::ExamMode::Off) {
Ion::LED::setColor(KDColorBlack);
Ion::LED::updateColorWithPlugAndCharge();
} else {
container->activateExamMode(mode);
}
container->refreshPreferences();
Container::activeApp()->dismissModalViewController();
@@ -108,15 +91,20 @@ int ExamPopUpController::ContentView::selectedButton() {
return 1;
}
void ExamPopUpController::ContentView::setMessages(bool activingExamMode) {
if (activingExamMode) {
void ExamPopUpController::ContentView::setMessagesForExamMode(GlobalPreferences::ExamMode mode) {
if (mode == GlobalPreferences::ExamMode::Off) {
m_messageTextView1.setMessage(I18n::Message::ExitExamMode1);
m_messageTextView2.setMessage(I18n::Message::ExitExamMode2);
m_messageTextView3.setMessage(I18n::Message::Default);
} else if (mode == GlobalPreferences::ExamMode::Standard || mode == GlobalPreferences::ExamMode::NoSym) {
m_messageTextView1.setMessage(I18n::Message::ActiveExamModeMessage1);
m_messageTextView2.setMessage(I18n::Message::ActiveExamModeMessage2);
m_messageTextView3.setMessage(I18n::Message::ActiveExamModeMessage3);
} else {
m_messageTextView1.setMessage(I18n::Message::ExitExamMode1);
m_messageTextView2.setMessage(I18n::Message::ExitExamMode2);
m_messageTextView3.setMessage(I18n::Message::Default);
assert(mode == GlobalPreferences::ExamMode::Dutch);
m_messageTextView1.setMessage(I18n::Message::ActiveDutchExamModeMessage1);
m_messageTextView2.setMessage(I18n::Message::ActiveDutchExamModeMessage2);
m_messageTextView3.setMessage(I18n::Message::ActiveDutchExamModeMessage3);
}
}

View File

@@ -3,6 +3,7 @@
#include <escher.h>
#include "exam_pop_up_controller_delegate.h"
#include "global_preferences.h"
class HighContrastButton : public Button {
public:
@@ -13,8 +14,8 @@ public:
class ExamPopUpController : public ViewController {
public:
ExamPopUpController(ExamPopUpControllerDelegate * delegate);
void setActivatingExamMode(bool activingExamMode);
bool isActivatingExamMode() const { return m_isActivatingExamMode; }
void setTargetExamMode(GlobalPreferences::ExamMode mode);
GlobalPreferences::ExamMode targetExamMode() const { return m_targetExamMode; }
// View Controller
View * view() override;
void viewDidDisappear() override;
@@ -28,7 +29,7 @@ private:
void drawRect(KDContext * ctx, KDRect rect) const override;
void setSelectedButton(int selectedButton);
int selectedButton();
void setMessages(bool activingExamMode);
void setMessagesForExamMode(GlobalPreferences::ExamMode mode);
private:
constexpr static KDCoordinate k_buttonMargin = 10;
constexpr static KDCoordinate k_buttonHeight = 20;
@@ -45,7 +46,7 @@ private:
MessageTextView m_messageTextView3;
};
ContentView m_contentView;
bool m_isActivatingExamMode;
GlobalPreferences::ExamMode m_targetExamMode;
ExamPopUpControllerDelegate * m_delegate;
};

31
apps/external/Makefile vendored Normal file
View File

@@ -0,0 +1,31 @@
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 \
)
SFLAGS += -Iapps/external/
EXTAPP_PATH ?= apps/external/app/
ifeq ($(PLATFORM),device)
SFLAGS += -DDEVICE
else
include $(EXTAPP_PATH)/sources.mak
endif
app_src += $(app_external_src)
i18n_files += $(addprefix apps/external/,\
base.de.i18n\
base.en.i18n\
base.es.i18n\
base.fr.i18n\
base.pt.i18n\
)
$(eval $(call depends_on_image,apps/external/app.cpp,apps/external/external_icon.png))

44
apps/external/app.cpp vendored Normal file
View File

@@ -0,0 +1,44 @@
#include "app.h"
#include "external_icon.h"
#include <apps/i18n.h>
namespace External {
I18n::Message App::Descriptor::name() {
return I18n::Message::ExternalApp;
}
I18n::Message App::Descriptor::upperName() {
return I18n::Message::ExternalAppCapital;
}
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)
{
}
}

37
apps/external/app.h vendored Normal file
View File

@@ -0,0 +1,37 @@
#ifndef EXTERNAL_APP_H
#define EXTERNAL_APP_H
#include <escher.h>
#include "main_controller.h"
namespace External {
class App : public ::App {
public:
class Descriptor : public ::App::Descriptor {
public:
I18n::Message name() override;
I18n::Message upperName() override;
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 = 131072;
char m_externalHeap[k_externalHeapSize];
};
}
#endif

6
apps/external/app/sample.c vendored Normal file
View File

@@ -0,0 +1,6 @@
#include <extapp_api.h>
void extapp_main() {
extapp_pushRectUniform(10, 10, LCD_WIDTH-20, LCD_HEIGHT-20, 0);
extapp_msleep(1000);
}

3
apps/external/app/sources.mak vendored Normal file
View File

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

146
apps/external/archive.cpp vendored Normal file
View File

@@ -0,0 +1,146 @@
#include "archive.h"
#include "extapp_api.h"
#include "../global_preferences.h"
#include <string.h>
#include <stdlib.h>
namespace External {
namespace Archive {
#ifdef DEVICE
struct TarHeader
{ /* byte offset */
char name[100]; /* 0 */
char mode[8]; /* 100 */
char uid[8]; /* 108 */
char gid[8]; /* 116 */
char size[12]; /* 124 */
char mtime[12]; /* 136 */
char chksum[8]; /* 148 */
char typeflag; /* 156 */
char linkname[100]; /* 157 */
char magic[8]; /* 257 */
char uname[32]; /* 265 */
char gname[32]; /* 297 */
char devmajor[8]; /* 329 */
char devminor[8]; /* 337 */
char padding[167]; /* 345 */
} __attribute__((packed));
static_assert(sizeof(TarHeader) == 512);
bool isSane(const TarHeader* tar) {
return !memcmp(tar->magic, "ustar ", 8) && tar->name[0] != '\x00' && tar->name[0] != '\xFF';
}
bool isExamModeAndFileNotExecutable(const TarHeader* tar) {
return GlobalPreferences::sharedGlobalPreferences()->isInExamMode() && (tar->mode[4] & 0x01) == 0;
}
bool fileAtIndex(size_t index, File &entry) {
const TarHeader* tar = reinterpret_cast<const TarHeader*>(0x90200000);
unsigned size = 0;
// Sanity check.
if (!isSane(tar) || isExamModeAndFileNotExecutable(tar)) {
return false;
}
/**
* TAR files are comprised of a set of records aligned to 512 bytes boundary
* followed by data.
*/
while (index-- > 0) {
size = 0;
for (int i = 0; i < 11; i++)
size = size * 8 + (tar->size[i] - '0');
// Move to the next TAR header.
unsigned stride = (sizeof(TarHeader) + size + 511);
stride = (stride >> 9) << 9;
tar = reinterpret_cast<const TarHeader*>(reinterpret_cast<const char*>(tar) + stride);
// Sanity check.
if (!isSane(tar) || isExamModeAndFileNotExecutable(tar)) {
return false;
}
}
// File entry found, copy data out.
entry.name = tar->name;
entry.data = reinterpret_cast<const uint8_t*>(tar) + sizeof(TarHeader);
entry.dataLength = size;
entry.isExecutable = (tar->mode[4] & 0x01) == 1;
return true;
}
extern "C" void (* const apiPointers[])(void);
typedef uint32_t (*entrypoint)(const uint32_t, const void *, void *, const uint32_t);
uint32_t executeFile(const char *name, void * heap, const uint32_t heapSize) {
File entry;
if(fileAtIndex(indexFromName(name), entry)) {
if(!entry.isExecutable) {
return 0;
}
uint32_t ep = *reinterpret_cast<const uint32_t*>(entry.data);
if(ep >= 0x90200000 && ep < 0x90800000) {
return ((entrypoint)ep)(API_VERSION, apiPointers, heap, heapSize);
}
}
return -1;
}
int indexFromName(const char *name) {
File entry;
for (int i = 0; fileAtIndex(i, entry); i++) {
if (strcmp(name, entry.name) == 0) {
return i;
}
}
return -1;
}
size_t numberOfFiles() {
File dummy;
size_t count;
for (count = 0; fileAtIndex(count, dummy); count++);
return count;
}
#else
bool fileAtIndex(size_t index, File &entry) {
entry.name = "App";
entry.data = NULL;
entry.dataLength = 0;
entry.isExecutable = true;
return true;
}
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) {
return 0;
}
size_t numberOfFiles() {
return 1;
}
#endif
}
}

27
apps/external/archive.h vendored Normal file
View File

@@ -0,0 +1,27 @@
#ifndef EXTERNAL_ARCHIVE_H
#define EXTERNAL_ARCHIVE_H
#include <stddef.h>
#include <stdint.h>
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();
uint32_t executeFile(const char *name, void * heap, const uint32_t heapSize);
}
}
#endif

4
apps/external/base.de.i18n vendored Normal file
View File

@@ -0,0 +1,4 @@
ExternalApp = "External"
ExternalAppCapital = "EXTERNAL"
ExternalAppApiMismatch = "API mismatch"
ExternalAppExecError = "Cannot execute file"

4
apps/external/base.en.i18n vendored Normal file
View File

@@ -0,0 +1,4 @@
ExternalApp = "External"
ExternalAppCapital = "EXTERNAL"
ExternalAppApiMismatch = "API mismatch"
ExternalAppExecError = "Cannot execute file"

4
apps/external/base.es.i18n vendored Normal file
View File

@@ -0,0 +1,4 @@
ExternalApp = "External"
ExternalAppCapital = "EXTERNAL"
ExternalAppApiMismatch = "API mismatch"
ExternalAppExecError = "Cannot execute file"

4
apps/external/base.fr.i18n vendored Normal file
View File

@@ -0,0 +1,4 @@
ExternalApp = "External"
ExternalAppCapital = "EXTERNAL"
ExternalAppApiMismatch = "API mismatch"
ExternalAppExecError = "Cannot execute file"

4
apps/external/base.pt.i18n vendored Normal file
View File

@@ -0,0 +1,4 @@
ExternalApp = "External"
ExternalAppCapital = "EXTERNAL"
ExternalAppApiMismatch = "API mismatch"
ExternalAppExecError = "Cannot execute file"

309
apps/external/extapp_api.cpp vendored Normal file
View File

@@ -0,0 +1,309 @@
#include <ion.h>
#include <kandinsky.h>
#include <escher.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include "archive.h"
#include "extapp_api.h"
#include "../apps_container.h"
#include "../global_preferences.h"
#include <python/port/port.h>
extern "C" {
#include <python/port/mphalport.h>
}
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<const KDColor*>(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 = event.id();
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,
};

256
apps/external/extapp_api.h vendored Normal file
View File

@@ -0,0 +1,256 @@
#ifndef EXTERNAL_API_H
#define EXTERNAL_API_H
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#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

BIN
apps/external/external_icon.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

98
apps/external/main_controller.cpp vendored Normal file
View File

@@ -0,0 +1,98 @@
#include "main_controller.h"
#include <apps/i18n.h>
#include <apps/apps_container.h>
#include <assert.h>
#include "archive.h"
#include "app.h"
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 (numberOfRows() > 0 && (event == Ion::Events::OK || event == Ion::Events::EXE)) {
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;
struct File f;
if(fileAtIndex(index, f)) {
myTextCell->setText(f.name);
myTextCell->setTextColor(f.isExecutable ? KDColorBlack : Palette::GreyDark);
}
}
void MainController::viewWillAppear() {
int count = numberOfFiles();
k_numberOfCells = count <= k_maxNumberOfCells ? count : k_maxNumberOfCells;
m_selectableTableView.reloadData();
}
}

34
apps/external/main_controller.h vendored Normal file
View File

@@ -0,0 +1,34 @@
#ifndef EXTERNAL_MAIN_CONTROLLER_H
#define EXTERNAL_MAIN_CONTROLLER_H
#include <escher.h>
#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

View File

@@ -0,0 +1,38 @@
#include "pointer_text_table_cell.h"
#include <escher/buffer_text_view.h>
#include <escher/palette.h>
#include <assert.h>
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();
}

20
apps/external/pointer_text_table_cell.h vendored Normal file
View File

@@ -0,0 +1,20 @@
#ifndef ESCHER_POINTER_TEXT_TABLE_CELL_H
#define ESCHER_POINTER_TEXT_TABLE_CELL_H
#include <escher/pointer_text_view.h>
#include <escher/table_cell.h>
class PointerTextTableCell : public TableCell {
public:
PointerTextTableCell(const char * text = "", const KDFont * font = KDFont::SmallFont, Layout layout = Layout::Horizontal);
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

View File

@@ -5,6 +5,37 @@ GlobalPreferences * GlobalPreferences::sharedGlobalPreferences() {
return &globalPreferences;
}
GlobalPreferences::ExamMode GlobalPreferences::examMode() const {
if (m_examMode == ExamMode::Unknown) {
uint8_t mode = Ion::ExamMode::FetchExamMode();
assert(mode >= 0 && mode < 4); // mode can be cast in ExamMode (Off, Standard, NoSym or Dutch)
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) {
return;
}
assert(mode != ExamMode::Unknown);
int8_t deltaMode = (int8_t)mode - (int8_t)currentMode;
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;

View File

@@ -5,15 +5,22 @@
class GlobalPreferences {
public:
enum class ExamMode {
Activate,
Deactivate
enum class ExamMode : int8_t {
Unknown = -1,
Off = 0,
Standard = 1,
NoSym = 2,
Dutch = 3,
};
static GlobalPreferences * sharedGlobalPreferences();
I18n::Language language() const { return m_language; }
void setLanguage(I18n::Language language) { m_language = language; }
ExamMode examMode() const { return m_examMode; }
void setExamMode(ExamMode examMode) { m_examMode = examMode; }
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; }
@@ -22,11 +29,15 @@ public:
private:
GlobalPreferences() :
m_language(I18n::Language::EN),
m_examMode(ExamMode::Deactivate),
m_examMode(ExamMode::Unknown),
m_tempExamMode(ExamMode::Standard),
m_showPopUp(true),
m_brightnessLevel(Ion::Backlight::MaxBrightness) {}
I18n::Language m_language;
ExamMode m_examMode;
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;
};

View File

@@ -6,6 +6,7 @@ app_hardware_test_src = $(addprefix apps/hardware_test/,\
colors_lcd_test_controller.cpp \
dead_pixels_test_controller.cpp \
keyboard_test_controller.cpp \
keyboard_model.cpp \
keyboard_view.cpp \
lcd_data_test_controller.cpp \
lcd_timing_test_controller.cpp \

View File

@@ -0,0 +1,16 @@
#include "keyboard_model.h"
namespace HardwareTest {
constexpr Ion::Keyboard::Key KeyboardModel::TestedKeys[KeyboardModel::NumberOfTestedKeys];
bool KeyboardModel::belongsToTestedKeysSubset(Ion::Keyboard::Key key) const {
for (int i = 0; i < NumberOfTestedKeys; i++) {
if (TestedKeys[i] == key) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,37 @@
#ifndef HARDWARE_TEST_KEYBOARD_MODEL_H
#define HARDWARE_TEST_KEYBOARD_MODEL_H
#include <ion/keyboard.h>
namespace HardwareTest {
class KeyboardModel {
public:
KeyboardModel() : m_testedKeyIndex(0) {}
Ion::Keyboard::Key testedKey() const { return TestedKeys[m_testedKeyIndex]; }
int testedKeyIndex() const { return m_testedKeyIndex; }
void setTestedKeyIndex(int i) {
assert(i >= 0 && i < NumberOfTestedKeys);
m_testedKeyIndex = i;
}
bool belongsToTestedKeysSubset(Ion::Keyboard::Key key) const;
static constexpr int NumberOfTestedKeys = 20;
static constexpr Ion::Keyboard::Key TestedKeys[KeyboardModel::NumberOfTestedKeys] = {
Ion::Keyboard::Key::Left, Ion::Keyboard::Key::Up, Ion::Keyboard::Key::Down, Ion::Keyboard::Key::Right, Ion::Keyboard::Key::OK, Ion::Keyboard::Key::Back,
Ion::Keyboard::Key::Home, Ion::Keyboard::Key::OnOff,
Ion::Keyboard::Key::Shift, Ion::Keyboard::Key::Alpha, Ion::Keyboard::Key::XNT, Ion::Keyboard::Key::Var, Ion::Keyboard::Key::Toolbox, Ion::Keyboard::Key::Backspace,
Ion::Keyboard::Key::Power,
Ion::Keyboard::Key::Square,
Ion::Keyboard::Key::RightParenthesis,
Ion::Keyboard::Key::Division,
Ion::Keyboard::Key::Minus,
Ion::Keyboard::Key::EXE
};
private:
int m_testedKeyIndex;
};
}
#endif

View File

@@ -17,10 +17,10 @@ View * KeyboardTestController::view() {
bool KeyboardTestController::handleEvent(Ion::Events::Event event) {
Ion::Keyboard::State state = Ion::Keyboard::scan();
Ion::Keyboard::State onlyKeyDown = Ion::Keyboard::State(Ion::Keyboard::ValidKeys[m_keyboardView.testedKeyIndex()]);
Ion::Keyboard::State onlyKeyDown = Ion::Keyboard::State(KeyboardModel::TestedKeys[m_keyboardView.testedKeyIndex()]);
if (state == onlyKeyDown) {
m_keyboardView.setTestedKeyIndex(m_keyboardView.testedKeyIndex()+1);
if (m_keyboardView.testedKeyIndex() == Ion::Keyboard::NumberOfValidKeys) {
m_keyboardView.setTestedKeyIndex(m_keyboardView.testedKeyIndex() + 1);
if (m_keyboardView.testedKeyIndex() == KeyboardModel::NumberOfTestedKeys) {
// Returning false will go to the next step in the WizardViewController
return false;
}

View File

@@ -3,17 +3,8 @@
namespace HardwareTest {
KeyboardView::KeyboardView() :
m_testedKeyIndex(0)
{
}
int KeyboardView::testedKeyIndex() const {
return m_testedKeyIndex;
}
void KeyboardView::setTestedKeyIndex(int i) {
m_testedKeyIndex = i;
m_keyboardModel.setTestedKeyIndex(i);
markRectAsDirty(bounds());
}
@@ -26,11 +17,8 @@ void KeyboardView::drawRect(KDContext * ctx, KDRect rect) const {
}
void KeyboardView::drawKey(int keyIndex, KDContext * ctx, KDRect rect) const {
KDColor color = keyIndex < m_testedKeyIndex ? KDColorGreen: KDColorBlack;
if (keyIndex == m_testedKeyIndex) {
color = KDColorBlue;
}
Ion::Keyboard::Key key = Ion::Keyboard::ValidKeys[keyIndex];
KDColor color = keyColor(key);
/* the key is on the cross */
if ((uint8_t)key < 4) {
KDCoordinate x = (uint8_t)key == 1 || (uint8_t)key == 2 ? k_margin + k_smallSquareSize : k_margin;
@@ -69,4 +57,14 @@ 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::GreyBright;
}
if (m_keyboardModel.testedKey() == key) {
return KDColorBlue;
}
return (uint8_t)key < (uint8_t)m_keyboardModel.testedKey() ? KDColorGreen : KDColorBlack;
}
}

View File

@@ -2,17 +2,19 @@
#define HARDWARE_TEST_KEYBOARD_VIEW_H
#include <escher.h>
#include "keyboard_model.h"
namespace HardwareTest {
class KeyboardView : public View {
public:
KeyboardView();
int testedKeyIndex() const;
KeyboardView() : m_keyboardModel() {}
int testedKeyIndex() const { return m_keyboardModel.testedKeyIndex(); }
void setTestedKeyIndex(int i);
void drawRect(KDContext * ctx, KDRect rect) const override;
private:
void drawKey(int key, KDContext * ctx, KDRect rect) const;
KDColor keyColor(Ion::Keyboard::Key key) const;
constexpr static int k_margin = 4;
constexpr static int k_smallSquareSize = 8;
constexpr static int k_bigSquareSize = 14;
@@ -20,7 +22,7 @@ private:
constexpr static int k_smallRectWidth = 16;
constexpr static int k_bigRectHeight = 14;
constexpr static int k_bigRectWidth = 20;
int m_testedKeyIndex;
KeyboardModel m_keyboardModel;
};
}

View File

@@ -1,2 +1,4 @@
Apps = "Anwendungen"
AppsCapital = "OMEGA"
ForbidenAppInExamMode1 = "This application is"
ForbidenAppInExamMode2 = "forbidden in exam mode"

View File

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

View File

@@ -1,2 +1,4 @@
Apps = "Aplicaciones"
AppsCapital = "OMEGA"
ForbidenAppInExamMode1 = "This application is"
ForbidenAppInExamMode2 = "forbidden in exam mode"

View File

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

View File

@@ -1,2 +1,4 @@
Apps = "Aplicações"
AppsCapital = "OMEGA"
ForbidenAppInExamMode1 = "This application is"
ForbidenAppInExamMode2 = "forbidden in exam mode"

View File

@@ -58,9 +58,15 @@ Controller::Controller(Responder * parentResponder, SelectableTableViewDataSourc
bool Controller::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::OK || event == Ion::Events::EXE) {
AppsContainer * container = AppsContainer::sharedAppsContainer();
bool switched = container->switchTo(container->appSnapshotAtIndex(selectionDataSource()->selectedRow()*k_numberOfColumns+selectionDataSource()->selectedColumn()+1));
assert(switched);
(void) switched; // Silence compilation warning about unused variable.
::App::Snapshot * selectedSnapshot = container->appSnapshotAtIndex(selectionDataSource()->selectedRow()*k_numberOfColumns+selectionDataSource()->selectedColumn()+1);
if (GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::Dutch &&
(selectedSnapshot->descriptor()->name() == I18n::Message::CodeApp || selectedSnapshot->descriptor()->name() == I18n::Message::ExternalApp)) {
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.
}
return true;
}

View File

@@ -1,5 +1,7 @@
#include "logo_controller.h"
#include "power_on_self_test.h"
#include <apps/apps_container.h>
#include <apps/global_preferences.h>
#include <ion/led.h>
namespace OnBoarding {
@@ -45,6 +47,11 @@ void LogoController::viewWillAppear() {
void LogoController::viewDidDisappear() {
if (m_didPerformTests) {
Ion::LED::setColor(m_previousLEDColor);
/* TODO: instead of setting again the exam mode, put the previous led color
* AND BLINKING.*/
if (GlobalPreferences::sharedGlobalPreferences()->isInExamMode()) {
AppsContainer::sharedAppsContainer()->activateExamMode(GlobalPreferences::sharedGlobalPreferences()->examMode());
}
}
ViewController::viewDidDisappear();
}

View File

@@ -6,7 +6,7 @@ namespace OnBoarding {
KDColor PowerOnSelfTest::Perform() {
KDColor previousLEDColor = Ion::LED::getColor();
KDColor resultColor = KDColorGreen;
KDColor resultColor = KDColorWhite;
// Screen tests
bool screenTestsOK = Shared::POSTAndHardwareTests::VBlankOK() && (Shared::POSTAndHardwareTests::TextLCDGlyphFailures() <= k_textErrorsLimit);
@@ -20,7 +20,7 @@ KDColor PowerOnSelfTest::Perform() {
resultColor = KDColorRed;
}
} else {
resultColor = KDColorBlue;
resultColor = KDColorPurple;
}
Ion::LED::setColor(resultColor);
return previousLEDColor;

View File

@@ -15,7 +15,6 @@ app_settings_src = $(addprefix apps/settings/,\
sub_menu/preferences_controller.cpp \
sub_menu/contributors_controller.cpp \
sub_menu/math_options_controller.cpp \
sub_menu/symbol_controller.cpp \
)
app_src += $(app_settings_src)

View File

@@ -7,8 +7,8 @@ EditionLinear = "Linear "
Edition2D = "Natürlich "
ComplexFormat = "Komplex"
ExamMode = "Testmodus"
ActivateExamMode = "Start Testmodus"
ExamModeActive = "Testmodus: aktiv"
ActivateExamMode = "Starten Testmodus"
ExamModeActive = "Wieder starten Testmodus"
About = "Über"
Degrees = "Grad "
Gradians = "Gone "
@@ -24,10 +24,15 @@ Brightness = "Helligkeit"
SoftwareVersion = "Epsilon version"
CustomSoftwareVersion = "Omega version"
Username = "Name"
MicroPythonVersion = "µPythonversion"
SerialNumber = "Seriennummer"
UpdatePopUp = "Erinnerung: Update"
BetaPopUp = "Beta pop-up"
LEDColor = "LEDs farbe"
ExamModeMode = "Modus"
ExamModeModeStandard = "Standard "
ExamModeModeNoSym = "Ohne symbolisch "
ExamModeModeDutch = "Niederländisch "
ColorWhite = "Weiss "
ColorBlue = "Blau "
ColorGreen = "Grün "
@@ -41,8 +46,8 @@ AccessibilityGammaRed = "Rotes Gamma"
AccessibilityGammaGreen = "Grünes Gamma"
AccessibilityGammaBlue = "Blaues Gamma"
MathOptions = "Mathe-optionen"
SymbolMultiplication = "Multiplikationszeichen"
SymbolMultiplicationCross = "Kreuz"
SymbolMultiplicationMiddleDot = "Mittelpunkt"
SymbolMultiplicationStar = "Stern"
SymbolMultiplicationAutoSymbol = "automatisch"
SymbolMultiplication = "Multiplikation"
SymbolMultiplicationCross = "Kreuz "
SymbolMultiplicationMiddleDot = "Mittelpunkt "
SymbolMultiplicationStar = "Stern "
SymbolMultiplicationAutoSymbol = "automatisch "

View File

@@ -8,7 +8,7 @@ Edition2D = "Natural "
ComplexFormat = "Complex format"
ExamMode = "Exam mode"
ActivateExamMode = "Activate exam mode"
ExamModeActive = "Exam mode: active"
ExamModeActive = "Reactivate exam mode"
About = "About"
Degrees = "Degrees "
Gradians = "Gradians "
@@ -24,10 +24,15 @@ Brightness = "Brightness"
SoftwareVersion = "Epsilon version"
CustomSoftwareVersion = "Omega version"
Username = "Name"
MicroPythonVersion = "µPython version"
SerialNumber = "Serial number"
UpdatePopUp = "Update pop-up"
BetaPopUp = "Beta pop-up"
LEDColor = "LED color"
ExamModeMode = "Mode"
ExamModeModeStandard = "Standard "
ExamModeModeNoSym = "No sym "
ExamModeModeDutch = "Dutch "
ColorWhite = "White "
ColorBlue = "Blue "
ColorGreen = "Green "
@@ -41,8 +46,8 @@ AccessibilityGammaRed = "Red gamma"
AccessibilityGammaGreen = "Green gamma"
AccessibilityGammaBlue = "Blue gamma"
MathOptions = "Math options"
SymbolMultiplication = "Multiplication sign"
SymbolMultiplicationCross = "Cross"
SymbolMultiplicationMiddleDot = "Middle dot"
SymbolMultiplicationStar = "Star"
SymbolMultiplicationAutoSymbol = "Automatic"
SymbolMultiplication = "Multiply"
SymbolMultiplicationCross = "Cross "
SymbolMultiplicationMiddleDot = "Dot "
SymbolMultiplicationStar = "Star "
SymbolMultiplicationAutoSymbol = "Auto "

View File

@@ -8,7 +8,7 @@ Edition2D = "Natural "
ComplexFormat = "Forma compleja"
ExamMode = "Modo examen"
ActivateExamMode = "Activar el modo examen"
ExamModeActive = "Modo examen: activo"
ExamModeActive = "Reactivar el modo examen"
About = "Acerca"
Degrees = "Grados "
Gradians = "Gradianes "
@@ -24,10 +24,15 @@ Brightness = "Brillo"
SoftwareVersion = "Versión de Epsilon"
CustomSoftwareVersion = "Versión de Omega"
Username = "Apellido"
MicroPythonVersion = "Version de µPython"
SerialNumber = "Número serie"
UpdatePopUp = "Pop-up de actualización"
BetaPopUp = "Beta pop-up"
LEDColor = "Color del LED"
ExamModeMode = "Modo"
ExamModeModeStandard = "Estándar "
ExamModeModeNoSym = "Sin simbólico "
ExamModeModeDutch = "Holandés "
ColorWhite = "Blanco "
ColorBlue = "Azul "
ColorGreen = "Verde "
@@ -41,8 +46,8 @@ AccessibilityGammaRed = "Gamma roja"
AccessibilityGammaGreen = "Gamma verde"
AccessibilityGammaBlue = "Gamma azul"
MathOptions = "Matemáticas"
SymbolMultiplication = "signo de multiplicación"
SymbolMultiplicationCross = "contrariar"
SymbolMultiplicationMiddleDot = "punto medio"
SymbolMultiplicationStar = "estrella"
SymbolMultiplicationAutoSymbol = "automático"
SymbolMultiplication = "Multiplicación"
SymbolMultiplicationCross = "Contrariar "
SymbolMultiplicationMiddleDot = "Punto "
SymbolMultiplicationStar = "Estrella "
SymbolMultiplicationAutoSymbol = "Auto "

View File

@@ -8,7 +8,7 @@ Edition2D = "Naturelle "
ComplexFormat = "Forme complexe"
ExamMode = "Mode examen"
ActivateExamMode = "Activer le mode examen"
ExamModeActive = "Mode examen: actif"
ExamModeActive = "Réactiver le mode examen"
About = "À propos"
Degrees = "Degrés "
Gradians = "Grades "
@@ -24,10 +24,15 @@ Brightness = "Luminosité"
SoftwareVersion = "Version d'Epsilon"
CustomSoftwareVersion = "Version d'Omega"
Username = "Nom"
MicroPythonVersion = "Version de µPython"
SerialNumber = "Numéro série"
UpdatePopUp = "Rappel mise à jour"
BetaPopUp = "Rappel version bêta"
LEDColor = "Couleur LED"
ExamModeMode = "Mode"
ExamModeModeStandard = "Standard "
ExamModeModeNoSym = "Sans symbolique "
ExamModeModeDutch = "Néerlandais "
ColorWhite = "Blanc "
ColorBlue = "Bleu "
ColorGreen = "Vert "
@@ -41,8 +46,8 @@ AccessibilityGammaRed = "Gamma rouge"
AccessibilityGammaGreen = "Gamma vert"
AccessibilityGammaBlue = "Gamma bleu"
MathOptions = "Math"
SymbolMultiplication = "Signe de multiplication"
SymbolMultiplicationCross = "Croix"
SymbolMultiplicationMiddleDot = "Point"
SymbolMultiplicationStar = "Etoile"
SymbolMultiplicationAutoSymbol = "Automatique"
SymbolMultiplication = "Multiplication"
SymbolMultiplicationCross = "Croix "
SymbolMultiplicationMiddleDot = "Point "
SymbolMultiplicationStar = "Etoile "
SymbolMultiplicationAutoSymbol = "Automatique "

View File

@@ -6,9 +6,9 @@ EditionMode = "Formato escrita "
EditionLinear = "Em linha "
Edition2D = "Natural "
ComplexFormat = "Complexos"
ExamMode = "Modo de Exame"
ActivateExamMode = "Inicio modo de exame"
ExamModeActive = "Modo de exame : ativo"
ExamMode = "Modo de exame"
ActivateExamMode = "Ativar o modo de exame"
ExamModeActive = "Reativar o modo de exame"
About = "Acerca"
Degrees = "Graus "
Gradians = "Grados "
@@ -24,10 +24,15 @@ Brightness = "Brilho"
SoftwareVersion = "Versão do Epsilon"
CustomSoftwareVersion = "Versão do Omega"
Username = "Nome"
MicroPythonVersion = "Versao do µPython"
SerialNumber = "Número serie"
UpdatePopUp = "Alertas de atualização"
BetaPopUp = "Beta pop-up"
LEDColor = "Cor LED"
ExamModeMode = "Modo"
ExamModeModeStandard = "Padrão "
ExamModeModeNoSym = "Sem simbólico "
ExamModeModeDutch = "Holandês "
ColorWhite = "Branco "
ColorBlue = "Azul "
ColorGreen = "Verde "
@@ -41,8 +46,8 @@ AccessibilityGammaRed = "Gama vermelha"
AccessibilityGammaGreen = "Gama verde"
AccessibilityGammaBlue = "Gama azul"
MathOptions = "Matemática"
SymbolMultiplication = "Sinal de multiplicação"
SymbolMultiplicationCross = "crómio"
SymbolMultiplicationMiddleDot = "ponto médio"
SymbolMultiplicationStar = "estrela"
SymbolMultiplicationAutoSymbol = "automático"
SymbolMultiplication = "Multiplicação"
SymbolMultiplicationCross = "crómio "
SymbolMultiplicationMiddleDot = "ponto médio "
SymbolMultiplicationStar = "estrela "
SymbolMultiplicationAutoSymbol = "automático "

View File

@@ -2,6 +2,7 @@
#include "../global_preferences.h"
#include <apps/i18n.h>
#include <assert.h>
#include <ion/backlight.h>
using namespace Poincare;
@@ -36,6 +37,13 @@ void MainController::didBecomeFirstResponder() {
bool MainController::handleEvent(Ion::Events::Event event) {
GlobalPreferences * globalPreferences = GlobalPreferences::sharedGlobalPreferences();
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);
m_selectableTableView.reloadCellAtLocation(m_selectableTableView.selectedColumn(), 1);
return true;
}
if (model()->children(selectedRow())->numberOfChildren() == 0) {
if (model()->children(selectedRow())->label() == promptMessage()) {
if (event == Ion::Events::OK || event == Ion::Events::EXE) {

View File

@@ -8,7 +8,6 @@
#include "sub_menu/exam_mode_controller.h"
#include "sub_menu/language_controller.h"
#include "sub_menu/math_options_controller.h"
#include "sub_menu/symbol_controller.h"
namespace Settings {

View File

@@ -5,7 +5,8 @@ namespace Settings {
//sub-sub-menus
constexpr SettingsMessageTree s_ledColorChildren[4] = {SettingsMessageTree(I18n::Message::ColorWhite), SettingsMessageTree(I18n::Message::ColorGreen), SettingsMessageTree(I18n::Message::ColorBlue), SettingsMessageTree(I18n::Message::ColorYellow)};
constexpr SettingsMessageTree s_contributorsChildren[5] = {SettingsMessageTree(I18n::Message::QuentinGuidee), SettingsMessageTree(I18n::Message::DannySimmons), SettingsMessageTree(I18n::Message::JoachimLeFournis), SettingsMessageTree(I18n::Message::JeanBaptisteBoric), SettingsMessageTree(I18n::Message::MaximeFriess)};
constexpr SettingsMessageTree s_examModeMode[3] = {SettingsMessageTree(I18n::Message::ExamModeModeStandard), SettingsMessageTree(I18n::Message::ExamModeModeNoSym), SettingsMessageTree(I18n::Message::ExamModeModeDutch)};
constexpr SettingsMessageTree s_contributorsChildren[7] = {SettingsMessageTree(I18n::Message::QuentinGuidee), SettingsMessageTree(I18n::Message::DannySimmons), SettingsMessageTree(I18n::Message::JoachimLeFournis), SettingsMessageTree(I18n::Message::JeanBaptisteBoric), SettingsMessageTree(I18n::Message::MaximeFriess), SettingsMessageTree(I18n::Message::David),SettingsMessageTree(I18n::Message::DamienNicolet)};
constexpr SettingsMessageTree s_modelAngleChildren[3] = {SettingsMessageTree(I18n::Message::Degrees), SettingsMessageTree(I18n::Message::Radian), SettingsMessageTree(I18n::Message::Gradians)};
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)};
@@ -14,25 +15,25 @@ constexpr SettingsMessageTree s_symbolChildren[4] = {SettingsMessageTree(I18n::M
//sub-menus
constexpr SettingsMessageTree s_modelMathOptionsChildren[5] = {SettingsMessageTree(I18n::Message::AngleUnit, s_modelAngleChildren, 3), SettingsMessageTree(I18n::Message::DisplayMode, s_modelFloatDisplayModeChildren, 4), SettingsMessageTree(I18n::Message::EditionMode, s_modelEditionModeChildren, 2), SettingsMessageTree(I18n::Message::ComplexFormat, s_modelComplexFormatChildren, 3), SettingsMessageTree(I18n::Message::SymbolMultiplication, s_symbolChildren, 4)};
constexpr SettingsMessageTree s_modelExamChildren[2] = {SettingsMessageTree(I18n::Message::LEDColor, s_ledColorChildren, 4), SettingsMessageTree(I18n::Message::ActivateExamMode)};
constexpr SettingsMessageTree s_modelExamChildren[3] = {SettingsMessageTree(I18n::Message::LEDColor, s_ledColorChildren, 4), SettingsMessageTree(I18n::Message::ExamModeMode, s_examModeMode, 3), SettingsMessageTree(I18n::Message::ActivateExamMode)};
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)};
#ifdef USERNAME
constexpr SettingsMessageTree s_modelAboutChildren[6] = {SettingsMessageTree(I18n::Message::Username), SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::CustomSoftwareVersion), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren, 5)};
constexpr SettingsMessageTree s_modelAboutChildren[7] = {SettingsMessageTree(I18n::Message::Username), SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::CustomSoftwareVersion), SettingsMessageTree(I18n::Message::MicroPythonVersion), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren, 5)};
#else
constexpr SettingsMessageTree s_modelAboutChildren[5] = {SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::CustomSoftwareVersion), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren, 5)};
constexpr SettingsMessageTree s_modelAboutChildren[6] = {SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::CustomSoftwareVersion), SettingsMessageTree(I18n::Message::MicroPythonVersion), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren, 5)};
#endif
constexpr SettingsMessageTree s_modelMenu[] =
{SettingsMessageTree(I18n::Message::MathOptions, s_modelMathOptionsChildren, 5),
SettingsMessageTree(I18n::Message::Brightness),
SettingsMessageTree(I18n::Message::Language),
SettingsMessageTree(I18n::Message::ExamMode, s_modelExamChildren, 2),
SettingsMessageTree(I18n::Message::ExamMode, s_modelExamChildren, 4),
SettingsMessageTree(I18n::Message::BetaPopUp),
SettingsMessageTree(I18n::Message::Accessibility, s_accessibilityChildren, 6),
#ifdef USERNAME
SettingsMessageTree(I18n::Message::About, s_modelAboutChildren, 6)};
SettingsMessageTree(I18n::Message::About, s_modelAboutChildren, 7)};
#else
SettingsMessageTree(I18n::Message::About, s_modelAboutChildren, 5)};
SettingsMessageTree(I18n::Message::About, s_modelAboutChildren, 6)};
#endif
constexpr SettingsMessageTree s_model = SettingsMessageTree(I18n::Message::SettingsApp, s_modelMenu, 7);

View File

@@ -6,7 +6,8 @@ namespace Settings {
// TODO: factorize most parts of the final models with main_controller_prompt_beta and main_controller_prompt_update
//sub-sub-menus
constexpr SettingsMessageTree s_ledColorChildren[4] = {SettingsMessageTree(I18n::Message::ColorWhite), SettingsMessageTree(I18n::Message::ColorGreen), SettingsMessageTree(I18n::Message::ColorBlue), SettingsMessageTree(I18n::Message::ColorYellow)};
constexpr SettingsMessageTree s_contributorsChildren[5] = {SettingsMessageTree(I18n::Message::QuentinGuidee), SettingsMessageTree(I18n::Message::DannySimmons), SettingsMessageTree(I18n::Message::JoachimLeFournis), SettingsMessageTree(I18n::Message::JeanBaptisteBoric), SettingsMessageTree(I18n::Message::MaximeFriess)};
constexpr SettingsMessageTree s_examModeMode[3] = {SettingsMessageTree(I18n::Message::ExamModeModeStandard), SettingsMessageTree(I18n::Message::ExamModeModeNoSym), SettingsMessageTree(I18n::Message::ExamModeModeDutch)};
constexpr SettingsMessageTree s_contributorsChildren[7] = {SettingsMessageTree(I18n::Message::QuentinGuidee), SettingsMessageTree(I18n::Message::DannySimmons), SettingsMessageTree(I18n::Message::JoachimLeFournis), SettingsMessageTree(I18n::Message::JeanBaptisteBoric), SettingsMessageTree(I18n::Message::MaximeFriess), SettingsMessageTree(I18n::Message::David),SettingsMessageTree(I18n::Message::DamienNicolet)};
constexpr SettingsMessageTree s_modelAngleChildren[3] = {SettingsMessageTree(I18n::Message::Degrees), SettingsMessageTree(I18n::Message::Radian), SettingsMessageTree(I18n::Message::Gradians)};
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)};
@@ -15,24 +16,24 @@ constexpr SettingsMessageTree s_symbolChildren[4] = {SettingsMessageTree(I18n::M
//sub-menus
constexpr SettingsMessageTree s_modelMathOptionsChildren[5] = {SettingsMessageTree(I18n::Message::AngleUnit, s_modelAngleChildren, 3), SettingsMessageTree(I18n::Message::DisplayMode, s_modelFloatDisplayModeChildren, 4), SettingsMessageTree(I18n::Message::EditionMode, s_modelEditionModeChildren, 2), SettingsMessageTree(I18n::Message::ComplexFormat, s_modelComplexFormatChildren, 3), SettingsMessageTree(I18n::Message::SymbolMultiplication, s_symbolChildren, 4)};
constexpr SettingsMessageTree s_modelExamChildren[2] = {SettingsMessageTree(I18n::Message::LEDColor, s_ledColorChildren, 4), SettingsMessageTree(I18n::Message::ActivateExamMode)};
constexpr SettingsMessageTree s_modelExamChildren[3] = {SettingsMessageTree(I18n::Message::LEDColor, s_ledColorChildren, 4), SettingsMessageTree(I18n::Message::ExamModeMode, s_examModeMode, 3), SettingsMessageTree(I18n::Message::ActivateExamMode)};
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)};
#ifdef USERNAME
constexpr SettingsMessageTree s_modelAboutChildren[6] = {SettingsMessageTree(I18n::Message::Username), SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::CustomSoftwareVersion), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren, 5)};
constexpr SettingsMessageTree s_modelAboutChildren[7] = {SettingsMessageTree(I18n::Message::Username), SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::CustomSoftwareVersion), SettingsMessageTree(I18n::Message::MicroPythonVersion), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren, 7)};
#else
constexpr SettingsMessageTree s_modelAboutChildren[5] = {SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::CustomSoftwareVersion), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren, 5)};
constexpr SettingsMessageTree s_modelAboutChildren[6] = {SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::CustomSoftwareVersion), SettingsMessageTree(I18n::Message::MicroPythonVersion), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren, 5)};
#endif
constexpr SettingsMessageTree s_modelMenu[] =
{SettingsMessageTree(I18n::Message::MathOptions, s_modelMathOptionsChildren, 5),
SettingsMessageTree(I18n::Message::Brightness),
SettingsMessageTree(I18n::Message::Language),
SettingsMessageTree(I18n::Message::ExamMode, s_modelExamChildren, 2),
SettingsMessageTree(I18n::Message::ExamMode, s_modelExamChildren, 3),
SettingsMessageTree(I18n::Message::Accessibility, s_accessibilityChildren, 6),
#ifdef USERNAME
SettingsMessageTree(I18n::Message::About, s_modelAboutChildren, 6)};
SettingsMessageTree(I18n::Message::About, s_modelAboutChildren, 7)};
#else
SettingsMessageTree(I18n::Message::About, s_modelAboutChildren, 5)};
SettingsMessageTree(I18n::Message::About, s_modelAboutChildren, 6)};
#endif
constexpr SettingsMessageTree s_model = SettingsMessageTree(I18n::Message::SettingsApp, s_modelMenu, 6);

View File

@@ -5,7 +5,8 @@ namespace Settings {
//sub-sub-menus
constexpr SettingsMessageTree s_ledColorChildren[4] = {SettingsMessageTree(I18n::Message::ColorWhite), SettingsMessageTree(I18n::Message::ColorGreen), SettingsMessageTree(I18n::Message::ColorBlue), SettingsMessageTree(I18n::Message::ColorYellow)};
constexpr SettingsMessageTree s_contributorsChildren[5] = {SettingsMessageTree(I18n::Message::QuentinGuidee), SettingsMessageTree(I18n::Message::DannySimmons), SettingsMessageTree(I18n::Message::JoachimLeFournis), SettingsMessageTree(I18n::Message::JeanBaptisteBoric), SettingsMessageTree(I18n::Message::MaximeFriess)};
constexpr SettingsMessageTree s_examModeMode[3] = {SettingsMessageTree(I18n::Message::ExamModeModeStandard), SettingsMessageTree(I18n::Message::ExamModeModeNoSym), SettingsMessageTree(I18n::Message::ExamModeModeDutch)};
constexpr SettingsMessageTree s_contributorsChildren[7] = {SettingsMessageTree(I18n::Message::QuentinGuidee), SettingsMessageTree(I18n::Message::DannySimmons), SettingsMessageTree(I18n::Message::JoachimLeFournis), SettingsMessageTree(I18n::Message::JeanBaptisteBoric), SettingsMessageTree(I18n::Message::MaximeFriess), SettingsMessageTree(I18n::Message::David),SettingsMessageTree(I18n::Message::DamienNicolet)};
constexpr SettingsMessageTree s_modelAngleChildren[3] = {SettingsMessageTree(I18n::Message::Degrees), SettingsMessageTree(I18n::Message::Radian), SettingsMessageTree(I18n::Message::Gradians)};
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)};
@@ -14,25 +15,25 @@ constexpr SettingsMessageTree s_symbolChildren[4] = {SettingsMessageTree(I18n::M
//sub-menus
constexpr SettingsMessageTree s_modelMathOptionsChildren[5] = {SettingsMessageTree(I18n::Message::AngleUnit, s_modelAngleChildren, 3), SettingsMessageTree(I18n::Message::DisplayMode, s_modelFloatDisplayModeChildren, 4), SettingsMessageTree(I18n::Message::EditionMode, s_modelEditionModeChildren, 2), SettingsMessageTree(I18n::Message::ComplexFormat, s_modelComplexFormatChildren, 3), SettingsMessageTree(I18n::Message::SymbolMultiplication, s_symbolChildren, 4)};
constexpr SettingsMessageTree s_modelExamChildren[2] = {SettingsMessageTree(I18n::Message::LEDColor, s_ledColorChildren, 4), SettingsMessageTree(I18n::Message::ActivateExamMode)};
constexpr SettingsMessageTree s_modelExamChildren[3] = {SettingsMessageTree(I18n::Message::LEDColor, s_ledColorChildren, 4), SettingsMessageTree(I18n::Message::ExamModeMode, s_examModeMode, 3), SettingsMessageTree(I18n::Message::ActivateExamMode)};
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)};
#ifdef USERNAME
constexpr SettingsMessageTree s_modelAboutChildren[6] = {SettingsMessageTree(I18n::Message::Username), SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::CustomSoftwareVersion), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren, 5)};
constexpr SettingsMessageTree s_modelAboutChildren[7] = {SettingsMessageTree(I18n::Message::Username), SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::CustomSoftwareVersion), SettingsMessageTree(I18n::Message::MicroPythonVersion), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren, 5)};
#else
constexpr SettingsMessageTree s_modelAboutChildren[5] = {SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::CustomSoftwareVersion), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren, 5)};
constexpr SettingsMessageTree s_modelAboutChildren[6] = {SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::CustomSoftwareVersion), SettingsMessageTree(I18n::Message::MicroPythonVersion), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren, 5)};
#endif
constexpr SettingsMessageTree s_modelMenu[] =
{SettingsMessageTree(I18n::Message::MathOptions, s_modelMathOptionsChildren, 5),
SettingsMessageTree(I18n::Message::Brightness),
SettingsMessageTree(I18n::Message::Language),
SettingsMessageTree(I18n::Message::ExamMode, s_modelExamChildren, 2),
SettingsMessageTree(I18n::Message::ExamMode, s_modelExamChildren, 4),
SettingsMessageTree(I18n::Message::UpdatePopUp),
SettingsMessageTree(I18n::Message::Accessibility, s_accessibilityChildren, 6),
#ifdef USERNAME
SettingsMessageTree(I18n::Message::About, s_modelAboutChildren, 6)};
SettingsMessageTree(I18n::Message::About, s_modelAboutChildren, 7)};
#else
SettingsMessageTree(I18n::Message::About, s_modelAboutChildren, 5)};
SettingsMessageTree(I18n::Message::About, s_modelAboutChildren, 6)};
#endif
constexpr SettingsMessageTree s_model = SettingsMessageTree(I18n::Message::SettingsApp, s_modelMenu, 7);

View File

@@ -1,8 +1,12 @@
#include "about_controller.h"
#include "../../../python/src/py/mpconfig.h"
#include <assert.h>
#include <cmath>
#include <apps/settings/main_controller.h>
#define MP_STRINGIFY_HELPER(x) #x
#define MP_STRINGIFY(x) MP_STRINGIFY_HELPER(x)
namespace Settings {
AboutController::AboutController(Responder * parentResponder) :
@@ -93,12 +97,14 @@ void AboutController::willDisplayCellForIndex(HighlightCell * cell, int index) {
}
else {
MessageTableCellWithBuffer * myCell = (MessageTableCellWithBuffer *)cell;
static const char * mpVersion = MICROPY_VERSION_STRING;
static const char * messages[] = {
#ifdef USERNAME
Ion::username(),
#endif
Ion::softwareVersion(),
Ion::customSoftwareVersion(),
mpVersion,
Ion::serialNumber(),
Ion::fccId()
};

View File

@@ -17,9 +17,9 @@ public:
int typeAtLocation(int i, int j) override;
private:
#ifdef USERNAME
constexpr static int k_totalNumberOfCell = 6;
constexpr static int k_totalNumberOfCell = 7;
#else
constexpr static int k_totalNumberOfCell = 5;
constexpr static int k_totalNumberOfCell = 6;
#endif
ContributorsController m_contributorsController;
MessageTableCellWithChevronAndMessage m_contributorsCell;

View File

@@ -28,7 +28,19 @@ int ContributorsController::reusableCellCount(int type) {
return k_totalNumberOfCell;
}
constexpr static I18n::Message s_contributorsUsernames[7] = {
I18n::Message::PQuentinGuidee,
I18n::Message::PDannySimmons,
I18n::Message::PJoachimLeFournis,
I18n::Message::PJeanBaptisteBoric,
I18n::Message::PMaximeFriess,
I18n::Message::PDavid,
I18n::Message::PDamienNicolet
};
void ContributorsController::willDisplayCellForIndex(HighlightCell * cell, int index) {
MessageTableCellWithBuffer * myTextCell = (MessageTableCellWithBuffer *)cell;
myTextCell->setAccessoryText(I18n::translate(s_contributorsUsernames[index]));
GenericSubController::willDisplayCellForIndex(cell, index);
}

View File

@@ -14,7 +14,7 @@ public:
int reusableCellCount(int type) override;
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
private:
constexpr static int k_totalNumberOfCell = 5;
constexpr static int k_totalNumberOfCell = 7;
MessageTableCellWithBuffer m_cells[k_totalNumberOfCell];
};

View File

@@ -1,6 +1,7 @@
#include "exam_mode_controller.h"
#include "../../global_preferences.h"
#include "../../apps_container.h"
#include <apps/i18n.h>
#include <assert.h>
#include <cmath>
#include <poincare/preferences.h>
@@ -15,25 +16,28 @@ ExamModeController::ExamModeController(Responder * parentResponder) :
GenericSubController(parentResponder),
m_preferencesController(this),
m_examModeCell(I18n::Message::Default, KDFont::LargeFont),
m_ledCell(KDFont::LargeFont, KDFont::SmallFont)
m_ledCell(KDFont::LargeFont, KDFont::SmallFont),
m_modeCell(KDFont::LargeFont, KDFont::SmallFont)
{
}
void ExamModeController::didEnterResponderChain(Responder * previousFirstResponder) {
m_selectableTableView.reloadData();
}
bool ExamModeController::handleEvent(Ion::Events::Event event) {
I18n::Message childLabel = m_messageTreeModel->children(selectedRow())->label();
I18n::Message childLabel = m_messageTreeModel->children(selectedRow())->label();
if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) {
if (childLabel == I18n::Message::ActivateExamMode || childLabel == I18n::Message::ExamModeActive) {
if (GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::Activate) {
return false;
}
AppsContainer::sharedAppsContainer()->displayExamModePopUp(true);
if (GlobalPreferences::sharedGlobalPreferences()->isInExamMode()) {
// If the exam mode is already on, this re-activate the same exam mode
GlobalPreferences::ExamMode mode = GlobalPreferences::sharedGlobalPreferences()->examMode();
if (childLabel == I18n::Message::ActivateExamMode || childLabel == I18n::Message::ExamModeActive)
AppsContainer::sharedAppsContainer()->displayExamModePopUp(mode);
return true;
}
if (childLabel == I18n::Message::LEDColor) {
if (childLabel == I18n::Message::ActivateExamMode || childLabel == I18n::Message::ExamModeActive) {
GlobalPreferences::ExamMode mode = GlobalPreferences::ExamMode::Standard;
AppsContainer::sharedAppsContainer()->displayExamModePopUp(GlobalPreferences::sharedGlobalPreferences()->tempExamMode());
return true;
}
if (childLabel == I18n::Message::LEDColor || childLabel == I18n::Message::ExamModeMode) {
GenericSubController * subController = &m_preferencesController;
subController->setMessageTreeModel(m_messageTreeModel->children(selectedRow()));
StackViewController * stack = stackController();
@@ -45,23 +49,22 @@ bool ExamModeController::handleEvent(Ion::Events::Event event) {
}
HighlightCell * ExamModeController::reusableCell(int index, int type) {
assert(index == 0);
if (type == 0) {
return &m_ledCell;
assert(type == 0);
assert(index >= 0 && index < 3);
switch(index) {
case 0:
return &m_ledCell;
case 1:
return &m_modeCell;
case 2:
return &m_examModeCell;
}
return &m_examModeCell;
}
int ExamModeController::reusableCellCount(int type) {
switch (type) {
case 0:
return 1;
case 1:
return 1;
default:
assert(false);
return 0;
}
assert(type == 0);
return 3;
}
void ExamModeController::willDisplayCellForIndex(HighlightCell * cell, int index) {
@@ -69,7 +72,7 @@ void ExamModeController::willDisplayCellForIndex(HighlightCell * cell, int index
GenericSubController::willDisplayCellForIndex(cell, index);
I18n::Message thisLabel = m_messageTreeModel->children(index)->label();
if (GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::Activate && (thisLabel == I18n::Message::ActivateExamMode || thisLabel == I18n::Message::ExamModeActive)) {
if (GlobalPreferences::sharedGlobalPreferences()->isInExamMode() && (thisLabel == I18n::Message::ActivateExamMode || thisLabel == I18n::Message::ExamModeActive)) {
MessageTableCell * myCell = (MessageTableCell *)cell;
myCell->setMessage(I18n::Message::ExamModeActive);
}
@@ -78,17 +81,10 @@ void ExamModeController::willDisplayCellForIndex(HighlightCell * cell, int index
I18n::Message message = (I18n::Message) m_messageTreeModel->children(index)->children((int)preferences->colorOfLED())->label();
myTextCell->setSubtitle(message);
}
}
int ExamModeController::typeAtLocation(int i, int j) {
switch (j) {
case 0:
return 0;
case 1:
return 1;
default:
assert(false);
return 0;
if (thisLabel == I18n::Message::ExamModeMode) {
MessageTableCellWithChevronAndMessage * myTextCell = (MessageTableCellWithChevronAndMessage *)cell;
I18n::Message message = (I18n::Message) m_messageTreeModel->children(index)->children((uint8_t)GlobalPreferences::sharedGlobalPreferences()->tempExamMode() - 1)->label();
myTextCell->setSubtitle(message);
}
}

View File

@@ -9,15 +9,14 @@ namespace Settings {
class ExamModeController : public GenericSubController {
public:
ExamModeController(Responder * parentResponder);
void didEnterResponderChain(Responder * previousFirstResponder) override;
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:
MessageTableCell m_examModeCell;
MessageTableCellWithChevronAndMessage m_ledCell;
MessageTableCellWithChevronAndMessage m_modeCell;
PreferencesController m_preferencesController;
};

View File

@@ -26,8 +26,12 @@ View * GenericSubController::view() {
return &m_selectableTableView;
}
void GenericSubController::didEnterResponderChain(Responder * previousFirstResponder) {
selectCellAtLocation(0, initialSelectedRow());
m_selectableTableView.reloadData();
}
void GenericSubController::didBecomeFirstResponder() {
selectCellAtLocation(0, 0);
Container::activeApp()->setFirstResponder(&m_selectableTableView);
}
@@ -75,10 +79,6 @@ void GenericSubController::setMessageTreeModel(const MessageTree * messageTreeMo
m_messageTreeModel = (MessageTree *)messageTreeModel;
}
void GenericSubController::viewWillAppear() {
m_selectableTableView.reloadData();
}
void GenericSubController::viewDidDisappear() {
m_selectableTableView.deselectTable();
}

View File

@@ -11,6 +11,7 @@ public:
GenericSubController(Responder * parentResponder);
const char * title() override;
View * view() override;
void didEnterResponderChain(Responder * previousFirstResponder) override;
void didBecomeFirstResponder() override;
bool handleEvent(Ion::Events::Event event) override;
int numberOfRows() const override;
@@ -20,10 +21,10 @@ public:
virtual int typeAtLocation(int i, int j) override;
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
void setMessageTreeModel(const MessageTree * messageTreeModel);
void viewWillAppear() override;
void viewDidDisappear() override;
protected:
StackViewController * stackController() const;
virtual int initialSelectedRow() const { return 0; }
constexpr static KDCoordinate k_topBottomMargin = 13;
SelectableTableView m_selectableTableView;
MessageTree * m_messageTreeModel;

View File

@@ -9,8 +9,7 @@ namespace Settings {
MathOptionsController::MathOptionsController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate) :
GenericSubController(parentResponder),
m_preferencesController(this),
m_displayModeController(this, inputEventHandlerDelegate),
m_symbolController(this)
m_displayModeController(this, inputEventHandlerDelegate)
{
for (int i = 0; i < k_totalNumberOfCell; i++) {
m_cells[i].setMessageFont(KDFont::LargeFont);
@@ -22,8 +21,6 @@ bool MathOptionsController::handleEvent(Ion::Events::Event event) {
GenericSubController * subController = nullptr;
if (m_messageTreeModel->children(selectedRow())->label() == I18n::Message::DisplayMode)
subController = &m_displayModeController;
else if (m_messageTreeModel->children(selectedRow())->label() == I18n::Message::SymbolMultiplication)
subController = &m_symbolController;
else
subController = &m_preferencesController;
subController->setMessageTreeModel(m_messageTreeModel->children(selectedRow()));

View File

@@ -4,7 +4,6 @@
#include "generic_sub_controller.h"
#include <escher.h>
#include "display_mode_controller.h"
#include "symbol_controller.h"
#include "preferences_controller.h"
namespace Settings {
@@ -21,7 +20,6 @@ private:
MessageTableCellWithChevronAndMessage m_cells[k_totalNumberOfCell];
PreferencesController m_preferencesController;
DisplayModeController m_displayModeController;
SymbolController m_symbolController;
};
}

View File

@@ -23,7 +23,6 @@ PreferencesController::PreferencesController(Responder * parentResponder) :
}
void PreferencesController::didBecomeFirstResponder() {
selectCellAtLocation(0, valueIndexForPreference(m_messageTreeModel->label()));
Container::activeApp()->setFirstResponder(&m_selectableTableView);
}
@@ -129,6 +128,40 @@ Layout PreferencesController::layoutForPreferences(I18n::Message message) {
const char * text = " ";
return LayoutHelper::String(text, strlen(text), k_layoutFont);
}
// 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::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);
default:
assert(false);
@@ -167,10 +200,14 @@ void PreferencesController::setPreferenceWithValueIndex(I18n::Message message, i
preferences->setComplexFormat((Preferences::ComplexFormat)valueIndex);
} else if (message == I18n::Message::LEDColor) {
preferences->setColorOfLED((Preferences::LEDColor)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);
}
}
int PreferencesController::valueIndexForPreference(I18n::Message message) {
int PreferencesController::valueIndexForPreference(I18n::Message message) const {
Preferences * preferences = Preferences::sharedPreferences();
if (message == I18n::Message::AngleUnit) {
return (int)preferences->angleUnit();
@@ -187,6 +224,9 @@ int PreferencesController::valueIndexForPreference(I18n::Message message) {
if (message == I18n::Message::LEDColor) {
return (int)preferences->colorOfLED();
}
if (message == I18n::Message::SymbolMultiplication) {
return (int)preferences->symbolofMultiplication();
}
return 0;
}

View File

@@ -18,9 +18,10 @@ protected:
constexpr static int k_totalNumberOfCell = 4;
private:
constexpr static const KDFont * k_layoutFont = KDFont::SmallFont;
int initialSelectedRow() const override { return valueIndexForPreference(m_messageTreeModel->label()); }
Poincare::Layout layoutForPreferences(I18n::Message message);
void setPreferenceWithValueIndex(I18n::Message message, int valueIndex);
int valueIndexForPreference(I18n::Message message);
int valueIndexForPreference(I18n::Message message) const;
MessageTableCellWithExpression m_cells[k_totalNumberOfCell];
};

View File

@@ -1,136 +0,0 @@
#include "symbol_controller.h"
#include <assert.h>
#include <poincare/preferences.h>
using namespace Shared;
using namespace Poincare;
namespace Settings {
SymbolController::SymbolController(Responder * parentResponder) :
GenericSubController(parentResponder)
{
for (int i = 0; i < k_totalNumberOfSwitchCells; i++) {
m_switchCells[i].setMessageFont(KDFont::LargeFont);
}
}
bool SymbolController::handleEvent(Ion::Events::Event event) {
Preferences * preferences = Preferences::sharedPreferences();
Poincare::Preferences::SymbolMultiplication oldSymbolOfMultiplication = preferences->symbolofMultiplication();
Poincare::Preferences::SymbolMultiplication newSymbolOfMultiplication = preferences->symbolofMultiplication();
if (event == Ion::Events::OK || event == Ion::Events::EXE){
switch(selectedRow()){
case 0:
{
newSymbolOfMultiplication = Poincare::Preferences::SymbolMultiplication::Cross;
break;
}
case 1:
{
newSymbolOfMultiplication = Poincare::Preferences::SymbolMultiplication::MiddleDot;
break;
}
case 2:
{
newSymbolOfMultiplication = Poincare::Preferences::SymbolMultiplication::Star;
break;
}
case 3:
{
newSymbolOfMultiplication = Poincare::Preferences::SymbolMultiplication::Auto;
break;
}
default:
{
GenericSubController::handleEvent(event);
}
}
if (oldSymbolOfMultiplication == newSymbolOfMultiplication) {
if (newSymbolOfMultiplication == Poincare::Preferences::SymbolMultiplication::Auto) {
preferences->setSymbolMultiplication(Poincare::Preferences::SymbolMultiplication::Cross);
} else {
preferences->setSymbolMultiplication(Poincare::Preferences::SymbolMultiplication::Auto);
}
} else {
preferences->setSymbolMultiplication(newSymbolOfMultiplication);
}
m_selectableTableView.reloadData();
return true;
} else {
return GenericSubController::handleEvent(event);
}
}
HighlightCell * SymbolController::reusableCell(int index, int type) {
assert(type == 1 || type == 2);
if (type == 2) {
assert(index >= 0 && index < k_totalNumberOfSwitchCells);
return &m_switchCells[index];
}
return nullptr;
}
int SymbolController::reusableCellCount(int type) {
assert(type == 1 || type == 2);
if (type == 2) {
return k_totalNumberOfSwitchCells;
}
return 0;
}
void SymbolController::willDisplayCellForIndex(HighlightCell * cell, int index) {
GenericSubController::willDisplayCellForIndex(cell, index);
MessageTableCellWithSwitch * mySwitchCell = (MessageTableCellWithSwitch *)cell;
Preferences * preferences = Preferences::sharedPreferences();
Poincare::Preferences::SymbolMultiplication symbolofMultiplication = preferences->symbolofMultiplication();
if (index == 0) {
SwitchView * mySwitch = (SwitchView *)mySwitchCell->accessoryView();
if(symbolofMultiplication == Poincare::Preferences::SymbolMultiplication::Cross){
mySwitch->setState(true);
} else {
mySwitch->setState(false);
}
}
else if (index == 1) {
SwitchView * mySwitch = (SwitchView *)mySwitchCell->accessoryView();
if(symbolofMultiplication == Poincare::Preferences::SymbolMultiplication::MiddleDot){
mySwitch->setState(true);
} else {
mySwitch->setState(false);
}
}
else if (index == 2) {
SwitchView * mySwitch = (SwitchView *)mySwitchCell->accessoryView();
if (symbolofMultiplication == Poincare::Preferences::SymbolMultiplication::Star){
mySwitch->setState(true);
} else {
mySwitch->setState(false);
}
}
else if (index == 3){
SwitchView * mySwitch = (SwitchView *)mySwitchCell->accessoryView();
if(symbolofMultiplication == Poincare::Preferences::SymbolMultiplication::Auto){
mySwitch->setState(true);
} else {
mySwitch->setState(false);
}
}
}
int SymbolController::typeAtLocation(int i, int j) {
switch (j) {
case 0:
case 1:
case 2:
case 3:
return 2;
default:
return 1;
}
}
}

View File

@@ -1,23 +0,0 @@
#ifndef SETTINGS_SYMBOLCONTROLLER_CONTROLLER_H
#define SETTINGS_SYMBOLCONTROLLER_CONTROLLER_H
#include "generic_sub_controller.h"
namespace Settings {
class SymbolController : public GenericSubController {
public:
SymbolController(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 = 4;
MessageTableCellWithSwitch m_switchCells[k_totalNumberOfSwitchCells];
};
}
#endif

View File

@@ -2,6 +2,9 @@ ActivateDeactivate = "Aktivieren/Deaktivieren"
ActiveExamModeMessage1 = "Alle Ihre Daten werden "
ActiveExamModeMessage2 = "gelöscht, wenn Sie den "
ActiveExamModeMessage3 = "Testmodus einschalten."
ActiveDutchExamModeMessage1 = "All your data will be deleted when"
ActiveDutchExamModeMessage2 = "you activate the exam mode. Python"
ActiveDutchExamModeMessage3 = "application will be unavailable."
Axis = "Achsen"
Cancel = "Abbrechen"
ClearColumn = "Spalte löschen"
@@ -61,6 +64,7 @@ StorageMemoryFull1 = "Der Speicher ist voll. Löschen Sie"
StorageMemoryFull2 = "von Daten und versuchen Sie es erneut."
StoreExpressionNotAllowed = "'store' ist verboten"
SyntaxError = "Syntaxfehler"
Sym = "sym"
TEnd = "T Endwert"
ThetaEnd = "θ Endwert"
ThetaStart = "θ Startwert"

View File

@@ -2,6 +2,9 @@ ActivateDeactivate = "Turn on/off"
ActiveExamModeMessage1 = "All your data will be "
ActiveExamModeMessage2 = "deleted when you activate "
ActiveExamModeMessage3 = "the exam mode."
ActiveDutchExamModeMessage1 = "All your data will be deleted when"
ActiveDutchExamModeMessage2 = "you activate the exam mode. Python"
ActiveDutchExamModeMessage3 = "application will be unavailable."
Axis = "Axes"
Cancel = "Cancel"
ClearColumn = "Clear column"
@@ -61,6 +64,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"

View File

@@ -2,6 +2,9 @@ ActivateDeactivate = "Activar/Desactivar"
ActiveExamModeMessage1 = "Todos sus datos se "
ActiveExamModeMessage2 = "eliminaran al activar "
ActiveExamModeMessage3 = "el modo examen."
ActiveDutchExamModeMessage1 = "All your data will be deleted when"
ActiveDutchExamModeMessage2 = "you activate the exam mode. Python"
ActiveDutchExamModeMessage3 = "application will be unavailable."
Axis = "Ejes"
Cancel = "Cancelar"
ClearColumn = "Borrar la columna"
@@ -61,6 +64,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"

View File

@@ -2,6 +2,9 @@ ActivateDeactivate = "Activer/Désactiver"
ActiveExamModeMessage1 = "Toutes vos données seront "
ActiveExamModeMessage2 = "supprimées si vous activez "
ActiveExamModeMessage3 = "le mode examen."
ActiveDutchExamModeMessage1 = "All your data will be deleted when"
ActiveDutchExamModeMessage2 = "you activate the exam mode. Python"
ActiveDutchExamModeMessage3 = "application will be unavailable."
Axis = "Axes"
Cancel = "Annuler"
ClearColumn = "Effacer la colonne"
@@ -61,6 +64,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"

View File

@@ -2,6 +2,9 @@ ActivateDeactivate = "Activar/Desactivar"
ActiveExamModeMessage1 = "Todos os seus dados serão "
ActiveExamModeMessage2 = "apagados se você ligar "
ActiveExamModeMessage3 = "o modo de exame."
ActiveDutchExamModeMessage1 = "All your data will be deleted when"
ActiveDutchExamModeMessage2 = "you activate the exam mode. Python"
ActiveDutchExamModeMessage3 = "application will be unavailable."
Axis = "Eixos"
Cancel = "Cancelar"
ClearColumn = "Excluir coluna"
@@ -61,6 +64,7 @@ StorageMemoryFull1 = "A memoria 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 = "θ inicio"

View File

@@ -210,11 +210,20 @@ ElementTsMass = "294"
ElementOgMass = "294"
ElementUueMass = "295"
ElementUbnMass = "297"
QuentinGuidee = "Quentin Guidee "
QuentinGuidee = "Quentin Guidée "
PQuentinGuidee = "@quentinguidee"
DannySimmons = "Danny Simmons "
PDannySimmons = "@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"
SpeedOfLight = "2.998·10^8"
YearLight = "9.461·10^12"
Boltzmann = "1.38064852·10^-23"

View File

@@ -1,6 +1,7 @@
#include "equation_store.h"
#include "../constant.h"
#include "../shared/poincare_helpers.h"
#include "../global_preferences.h"
#include <limits.h>
#include <poincare/constant.h>
@@ -193,6 +194,8 @@ EquationStore::Error EquationStore::exactSolve(Poincare::Context * context) {
}
}
// Create the results' layouts
// In Dutch exam mode, display only approximate solutions
bool forbidExactSolutions = GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::Dutch;
int solutionIndex = 0;
int initialNumberOfSolutions = m_numberOfSolutions <= k_maxNumberOfExactSolutions ? m_numberOfSolutions : -1;
// We iterate through the solutions and the potential delta
@@ -211,7 +214,9 @@ EquationStore::Error EquationStore::exactSolve(Poincare::Context * context) {
char approximateBuffer[::Constant::MaxSerializedExpressionSize];
m_exactSolutionExactLayouts[solutionIndex].serializeForParsing(exactBuffer, ::Constant::MaxSerializedExpressionSize);
m_exactSolutionApproximateLayouts[solutionIndex].serializeForParsing(approximateBuffer, ::Constant::MaxSerializedExpressionSize);
m_exactSolutionIdentity[solutionIndex] = strcmp(exactBuffer, approximateBuffer) == 0;
/* Cheat: declare exact and approximate solutions to be identical in
* Dutch exam mode to display only the approximate solutions. */
m_exactSolutionIdentity[solutionIndex] = forbidExactSolutions || strcmp(exactBuffer, approximateBuffer) == 0;
if (!m_exactSolutionIdentity[solutionIndex]) {
char buffer[::Constant::MaxSerializedExpressionSize];
m_exactSolutionEquality[solutionIndex] = exactSolutions[i].isEqualToItsApproximationLayout(exactSolutionsApproximations[i], buffer, ::Constant::MaxSerializedExpressionSize, preferences->complexFormat(), preferences->angleUnit(), preferences->displayMode(), preferences->numberOfSignificantDigits(), context);

View File

@@ -71,7 +71,7 @@ void TitleBarView::layoutSubviews() {
m_preferenceView.setFrame(KDRect(Metric::TitleBarExternHorizontalMargin, 0, m_preferenceView.minimalSizeForOptimalDisplay().width(), bounds().height()));
KDSize batterySize = m_batteryView.minimalSizeForOptimalDisplay();
m_batteryView.setFrame(KDRect(bounds().width() - batterySize.width() - Metric::TitleBarExternHorizontalMargin, (bounds().height()- batterySize.height())/2, batterySize));
if (GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::Activate) {
if (GlobalPreferences::sharedGlobalPreferences()->isInExamMode()) {
m_examModeIconView.setFrame(KDRect(k_examIconMargin, (bounds().height() - k_examIconHeight)/2, k_examIconWidth, k_examIconHeight));
} else {
m_examModeIconView.setFrame(KDRectZero);
@@ -85,6 +85,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 +101,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++] = '/';
@@ -108,6 +116,7 @@ void TitleBarView::refreshPreferences() {
(angleUnit == Preferences::AngleUnit::Radian ? I18n::Message::Rad : I18n::Message::Gon);
numberOfChar += strlcpy(buffer+numberOfChar, I18n::translate(angleMessage), bufferSize - numberOfChar);
}
m_preferenceView.setText(buffer);
// Layout the exam mode icon if needed
layoutSubviews();

View File

@@ -4,13 +4,14 @@ PLATFORM ?= device
DEBUG ?= 0
EPSILON_VERSION ?= 12.0.0
EPSILON_CUSTOM_VERSION ?= 1.17.2-0
EPSILON_CUSTOM_VERSION ?= 1.18.0-0
# USERNAME ?= N/A
# Valid values are "none", "update", "beta"
EPSILON_APPS ?= calculation rpn graph code statistics probability solver atom sequence regression settings
EPSILON_APPS ?= calculation rpn graph code statistics probability solver atom sequence regression settings external
EPSILON_I18N ?= en fr es de pt
EPSILON_GETOPT ?= 0
ESCHER_LOG_EVENTS_BINARY ?= 0
OMEGA_THEME ?= omega_light
include build/defaults.mak
include build/platform.$(PLATFORM).mak

2546
build/doc/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -60,22 +60,3 @@ $(BUILD_DIR)/bench.flash.$(EXE): LDSCRIPT = ion/src/$(PLATFORM)/$(MODEL)/interna
bench_src = $(ion_xip_src) $(liba_src) $(kandinsky_src) $(poincare_src) $(libaxx_src) $(app_shared_src) $(ion_target_device_bench_src)
$(BUILD_DIR)/bench.ram.$(EXE): $(call object_for,$(bench_src))
$(BUILD_DIR)/bench.flash.$(EXE): $(call object_for,$(bench_src))
.PHONY: %.two_binaries
%.two_binaries: %.elf
@echo "Building an internal and an external binary for $<"
$(Q) $(OBJCOPY) -O binary -j .text.external -j .rodata.external $< $(basename $<).external.bin
$(Q) $(OBJCOPY) -O binary -R .text.external -R .rodata.external $< $(basename $<).internal.bin
@echo "Padding $(basename $<).external.bin and $(basename $<).internal.bin"
$(Q) printf "\xFF\xFF\xFF\xFF" >> $(basename $<).external.bin
$(Q) printf "\xFF\xFF\xFF\xFF" >> $(basename $<).internal.bin
.PHONY: binpack
binpack: $(BUILD_DIR)/flasher.light.bin $(BUILD_DIR)/epsilon.onboarding.two_binaries
rm -rf $(BUILD_DIR)/binpack
mkdir -p $(BUILD_DIR)/binpack
cp $(BUILD_DIR)/flasher.light.bin $(BUILD_DIR)/binpack
cp $(BUILD_DIR)/epsilon.onboarding.internal.bin $(BUILD_DIR)/epsilon.onboarding.external.bin $(BUILD_DIR)/binpack
cd $(BUILD_DIR) && for binary in flasher.light.bin epsilon.onboarding.internal.bin epsilon.onboarding.external.bin; do shasum -a 256 -b binpack/$${binary} > binpack/$${binary}.sha256;done
cd $(BUILD_DIR) && tar cvfz binpack-$(MODEL)-`git rev-parse HEAD | head -c 7`.tgz binpack/*

View File

@@ -19,3 +19,31 @@ $(BUILD_DIR)/test.external_flash.write.$(EXE): $(BUILD_DIR)/quiz/src/test_ion_ex
sleep 2; \
fi
$(Q) $(PYTHON) build/device/dfu.py -u $(word 1,$^)
.PHONY: %.two_binaries
%.two_binaries: %.elf
@echo "Building an internal and an external binary for $<"
$(Q) $(OBJCOPY) -O binary -j .text.external -j .rodata.external -j .exam_mode_buffer $(BUILD_DIR)/$< $(BUILD_DIR)/$(basename $<).external.bin
$(Q) $(OBJCOPY) -O binary -R .text.external -R .rodata.external -R .exam_mode_buffer $(BUILD_DIR)/$< $(BUILD_DIR)/$(basename $<).internal.bin
@echo "Padding $(basename $<).external.bin and $(basename $<).internal.bin"
$(Q) printf "\xFF\xFF\xFF\xFF" >> $(basename $<).external.bin
$(Q) printf "\xFF\xFF\xFF\xFF" >> $(basename $<).internal.bin
.PHONY: binpack
binpack:
rm -rf build/binpack
mkdir -p build/binpack
make clean
make -j8 $(BUILD_DIR)/flasher.light.bin
cp $(BUILD_DIR)/flasher.light.bin build/binpack
make clean
make -j8 $(BUILD_DIR)/bench.flash.bin
make -j8 $(BUILD_DIR)/bench.ram.bin
cp $(BUILD_DIR)/bench.ram.bin $(BUILD_DIR)/bench.flash.bin build/binpack
make clean
make -j8 $(BUILD_DIR)/epsilon.onboarding.update.two_binaries
cp $(BUILD_DIR)/epsilon.onboarding.update.internal.bin $(BUILD_DIR)/epsilon.onboarding.update.external.bin build/binpack
make clean
cd build && for binary in flasher.light.bin bench.flash.bin bench.ram.bin epsilon.onboarding.internal.bin epsilon.onboarding.external.bin; do shasum -a 256 -b binpack/$${binary} > binpack/$${binary}.sha256;done
cd build && tar cvfz binpack-`git rev-parse HEAD | head -c 7`.tgz binpack
rm -rf build/binpack

View File

@@ -95,13 +95,20 @@ $(eval $(call rule_for, \
$$(HOSTCC) -std=c99 `libpng-config --cflags` $$^ `libpng-config --ldflags` -o $$@ \
))
$(eval $(call rule_for, \
THEME, \
escher/palette.h, \
$(addprefix themes/themes/, $(addsuffix .json, $(OMEGA_THEME))), \
$$(PYTHON) themes/themes_manager.py $(OMEGA_THEME) $$@ \
))
INLINER := $(BUILD_DIR)/escher/image/inliner
.PRECIOUS: $(BUILD_DIR)/%.h $(BUILD_DIR)/%.cpp
$(eval $(call rule_for, \
INLINER, \
%.h %.cpp, \
%.png $$(INLINER), \
$(BUILD_DIR)/%.png $$(INLINER), \
$$(INLINER) $$< $$(basename $$@).h $$(basename $$@).cpp \
))
@@ -115,4 +122,5 @@ define depends_on_image
$(call object_for,$(1)): $(call object_for,$(2))
$(call object_for,$(1)): SFLAGS += $(foreach d,$(sort $(dir $(call object_for,$(1)))),-I$(d))
escher_src += $(2)
image_list += $(2)
endef

View File

@@ -1,139 +0,0 @@
#ifndef ESCHER_PALETTE_H
#define ESCHER_PALETTE_H
#include <kandinsky/color.h>
class Palette {
public:
constexpr static KDColor PrimaryText = KDColor::RGB24(0x000000);
constexpr static KDColor SecondaryText = KDColor::RGB24(0x6e6e6e);
constexpr static KDColor AccentText = KDColor::RGB24(0x00857f);
constexpr static KDColor ApproximateSignText = KDColor::RGB24(0x595959);
constexpr static KDColor ApproximateExpressionText = KDColor::RGB24(0x595959);
constexpr static KDColor BackgroundHard = KDColor::RGB24(0xffffff);
constexpr static KDColor BackgroundApps = KDColor::RGB24(0xfafafa);
constexpr static KDColor BackgroundAppsSecondary = KDColor::RGB24(0xf0f0f0);
constexpr static KDColor Toolbar = KDColor::RGB24(0xc03535);
constexpr static KDColor ToolbarText = KDColor::RGB24(0xffffff);
constexpr static KDColor ExpressionInputBackground = KDColor::RGB24(0xe0e0e0);
constexpr static KDColor ExpressionInputBorder = KDColor::RGB24(0xd9d9d9);
constexpr static KDColor GridPrimaryLine = KDColor::RGB24(0xd9d9d9);
constexpr static KDColor GridSecondaryLine = KDColor::RGB24(0xf5f5f5);
constexpr static KDColor Battery = KDColor::RGB24(0xffffff);
constexpr static KDColor BatteryInCharge = KDColor::RGB24(0x179e1f);
constexpr static KDColor BatteryLow = KDColor::RGB24(0x992321);
constexpr static KDColor ScrollBarForeground = KDColor::RGB24(0x4a4a4a);
constexpr static KDColor ScrollBarBackground = KDColor::RGB24(0xd9d9d9);
constexpr static KDColor Control = KDColor::RGB24(0x00857f);
constexpr static KDColor ControlEnabled = KDColor::RGB24(0x00b2b0);
constexpr static KDColor ControlDisabled = KDColor::RGB24(0x9e9e9e);
constexpr static KDColor CalculationBackgroundOdd = KDColor::RGB24(0xfafafa);
constexpr static KDColor CalculationBackgroundEven = KDColor::RGB24(0xffffff);
constexpr static KDColor CalculationEmptyBox = KDColor::RGB24(0xc4c4c4);
constexpr static KDColor CalculationEmptyBoxNeeded = KDColor::RGB24(0x00857f);
constexpr static KDColor CodeBackground = KDColor::RGB24(0xffffff);
constexpr static KDColor CodeBackgroundSelected = KDColor::RGB24(0xe0e0e0);
constexpr static KDColor CodeText = KDColor::RGB24(0x000000);
constexpr static KDColor CodeComment = KDColor::RGB24(0x999988);
constexpr static KDColor CodeNumber = KDColor::RGB24(0x009999);
constexpr static KDColor CodeKeyword = KDColor::RGB24(0xff000c);
constexpr static KDColor CodeOperator = KDColor::RGB24(0xd73a49);
constexpr static KDColor CodeString = KDColor::RGB24(0x032f62);
constexpr static KDColor ProbabilityCurve = KDColor::RGB24(0x00857f);
constexpr static KDColor ProbabilityCellBorder = KDColor::RGB24(0xececec);
constexpr static KDColor ProbabilityHistogramBar = KDColor::RGB24(0xd9d9d9);
constexpr static KDColor StatisticsBox = KDColor::RGB24(0x00857f);
constexpr static KDColor StatisticsBoxVerticalLine = KDColor::RGB24(0xd9d9d9);
constexpr static KDColor StatisticsSelected = KDColor::RGB24(0x00857f);
constexpr static KDColor StatisticsNotSelected = KDColor::RGB24(0xf5f5f5);
constexpr static KDColor GraphTangent = KDColor::RGB24(0x595959);
constexpr static KDColor SubMenuBackground = KDColor::RGB24(0xe0e0e0);
constexpr static KDColor SubMenuBorder = KDColor::RGB24(0xfafafa);
constexpr static KDColor SubMenuText = KDColor::RGB24(0x000000);
constexpr static KDColor ToolboxHeaderBackground = KDColor::RGB24(0x4a4a4a);
constexpr static KDColor ToolboxHeaderText = KDColor::RGB24(0xffffff);
constexpr static KDColor ToolboxHeaderBorder = KDColor::RGB24(0x4a4a4a);
constexpr static KDColor ToolboxBackground = KDColor::RGB24(0x000000);
constexpr static KDColor ListCellBackground = KDColor::RGB24(0xffffff);
constexpr static KDColor ListCellBackgroundSelected = KDColor::RGB24(0xe0e0e0);
constexpr static KDColor ListCellBorder = KDColor::RGB24(0xededef);
constexpr static KDColor ButtonBackground = KDColor::RGB24(0xe0e0e0);
constexpr static KDColor ButtonBackgroundSelected = KDColor::RGB24(0xd1d1d1);
constexpr static KDColor ButtonBackgroundSelectedHighContrast = KDColor::RGB24(0x00b2b0);
constexpr static KDColor ButtonBorder = KDColor::RGB24(0xadadad);
constexpr static KDColor ButtonRowBorder = KDColor::RGB24(0xd9d9d9);
constexpr static KDColor ButtonBorderOut = KDColor::RGB24(0xf5f5f5);
constexpr static KDColor ButtonShadow = KDColor::RGB24(0x003833);
constexpr static KDColor ButtonText = KDColor::RGB24(0x000000);
constexpr static KDColor TabBackground = KDColor::RGB24(0x4a4a4a);
constexpr static KDColor TabBackgroundSelected = KDColor::RGB24(0x757575);
constexpr static KDColor TabBackgroundActive = KDColor::RGB24(0xfafafa);
constexpr static KDColor TabBackgroundSelectedAndActive = KDColor::RGB24(0xe3e3e3);
constexpr static KDColor TabText = KDColor::RGB24(0xffffff);
constexpr static KDColor TabTextActive = KDColor::RGB24(0x000000);
constexpr static KDColor SubTabBackground = KDColor::RGB24(0xe0e0e0);
constexpr static KDColor SubTabBackgroundSelected = KDColor::RGB24(0xd1d1d1);
constexpr static KDColor SubTabText = KDColor::RGB24(0x000000);
constexpr static KDColor BannerFirstBackground = KDColor::RGB24(0x4a4a4a);
constexpr static KDColor BannerFirstBorder = KDColor::RGB24(0x4a4a4a);
constexpr static KDColor BannerFirstText = KDColor::RGB24(0xffffff);
constexpr static KDColor BannerFirstVariantBackground = KDColor::RGB24(0x4a4a4a);
constexpr static KDColor BannerFirstVariantBorder = KDColor::RGB24(0xfafafa);
constexpr static KDColor BannerFirstVariantText = KDColor::RGB24(0xffffff);
constexpr static KDColor BannerSecondBackground = KDColor::RGB24(0xe0e0e0);
constexpr static KDColor BannerSecondBorder = KDColor::RGB24(0xfafafa);
constexpr static KDColor BannerSecondText = KDColor::RGB24(0x000000);
constexpr static KDColor HomeBackground = KDColor::RGB24(0xffffff);
constexpr static KDColor HomeCellBackground = KDColor::RGB24(0xffffff);
constexpr static KDColor HomeCellBackgroundActive = KDColor::RGB24(0x4a4a4a);
constexpr static KDColor HomeCellText = KDColor::RGB24(0x000000);
constexpr static KDColor HomeCellTextActive = KDColor::RGB24(0xffffff);
constexpr static KDColor AtomUnknown = KDColor::RGB24(0xeeeeee);
constexpr static KDColor AtomText = KDColor::RGB24(0x000000);
constexpr static KDColor AtomAlkaliMetal = KDColor::RGB24(0xffaa00);
constexpr static KDColor AtomAlkaliEarthMetal = KDColor::RGB24(0xf6f200);
constexpr static KDColor AtomLanthanide = KDColor::RGB24(0xffaa8b);
constexpr static KDColor AtomActinide = KDColor::RGB24(0xdeaacd);
constexpr static KDColor AtomTransitionMetal = KDColor::RGB24(0xde999c);
constexpr static KDColor AtomPostTransitionMetal = KDColor::RGB24(0x9cbaac);
constexpr static KDColor AtomMetalloid = KDColor::RGB24(0x52ce8b);
constexpr static KDColor AtomHalogen = KDColor::RGB24(0x00debd);
constexpr static KDColor AtomReactiveNonmetal = KDColor::RGB24(0x00ee00);
constexpr static KDColor AtomNobleGas = KDColor::RGB24(0x8baaff);
constexpr static KDColor AtomTableLines = KDColor::RGB24(0x323532);
constexpr static KDColor YellowDark = KDColor::RGB24(0xffb734);
constexpr static KDColor YellowLight = KDColor::RGB24(0xffcc7b);
constexpr static KDColor PurpleBright = KDColor::RGB24(0x656975);
constexpr static KDColor PurpleDark = KDColor::RGB24(0x414147);
constexpr static KDColor GreyWhite = KDColor::RGB24(0xf5f5f5);
constexpr static KDColor GreyBright = KDColor::RGB24(0xececec);
constexpr static KDColor GreyMiddle = KDColor::RGB24(0xd9d9d9);
constexpr static KDColor GreyDark = KDColor::RGB24(0xa7a7a7);
constexpr static KDColor GreyVeryDark = KDColor::RGB24(0x8c8c8c);
constexpr static KDColor Select = KDColor::RGB24(0xd4d7e0);
constexpr static KDColor SelectDark = KDColor::RGB24(0xb0b8d8);
constexpr static KDColor WallScreen = KDColor::RGB24(0xf7f9fa);
constexpr static KDColor WallScreenDark = KDColor::RGB24(0xe0e6ed);
constexpr static KDColor SubTab = KDColor::RGB24(0xb8bbc5);
constexpr static KDColor LowBattery = KDColor::RGB24(0xf30211);
constexpr static KDColor Red = KDColor::RGB24(0xff000c);
constexpr static KDColor RedLight = KDColor::RGB24(0xfe6363);
constexpr static KDColor Magenta = KDColor::RGB24(0xff0588);
constexpr static KDColor Turquoise = KDColor::RGB24(0x60c1ec);
constexpr static KDColor Pink = KDColor::RGB24(0xffabb6);
constexpr static KDColor Blue = KDColor::RGB24(0x5075f2);
constexpr static KDColor BlueLight = KDColor::RGB24(0x718fee);
constexpr static KDColor Orange = KDColor::RGB24(0xfe871f);
constexpr static KDColor Green = KDColor::RGB24(0x50c102);
constexpr static KDColor GreenLight = KDColor::RGB24(0x52db8f);
constexpr static KDColor Brown = KDColor::RGB24(0x8d7350);
constexpr static KDColor Purple = KDColor::RGB24(0x6e2d79);
constexpr static KDColor DataColor[] = {Red, Blue, Green, YellowDark, Magenta, Turquoise, Pink, Orange};
constexpr static KDColor DataColorLight[] = {RedLight, BlueLight, GreenLight, YellowLight};
constexpr static KDColor AtomColor[] = {
AtomUnknown, AtomAlkaliMetal, AtomAlkaliEarthMetal, AtomLanthanide, AtomActinide, AtomTransitionMetal,
AtomPostTransitionMetal, AtomMetalloid, AtomHalogen, AtomReactiveNonmetal, AtomNobleGas
};
};
#endif

View File

@@ -5,16 +5,17 @@
class Responder {
public:
Responder(Responder * parentResponder);
Responder(Responder * parentResponder) : m_parentResponder(parentResponder) {}
virtual bool handleEvent(Ion::Events::Event event) { return false; }; // Default implementation does nothing
virtual void didBecomeFirstResponder();
virtual void willResignFirstResponder();
virtual void didEnterResponderChain(Responder * previousFirstResponder);
virtual void willExitResponderChain(Responder * nextFirstResponder);
Responder * parentResponder() const;
virtual void didBecomeFirstResponder() {}
virtual void willResignFirstResponder() {}
virtual void didEnterResponderChain(Responder * previousFirstResponder) {}
virtual void willExitResponderChain(Responder * nextFirstResponder) {}
Responder * parentResponder() const { return m_parentResponder; }
Responder * commonAncestorWith(Responder * responder);
void setParentResponder(Responder * responder);
void setParentResponder(Responder * responder) { m_parentResponder = responder; }
private:
bool hasAncestor(Responder * responder) const;
Responder * m_parentResponder;
};

View File

@@ -234,7 +234,11 @@ bool LayoutField::privateHandleEvent(Ion::Events::Event event) {
setEditing(true);
}
if (event.hasText()) {
handleEventWithText(event.text());
if(event.text() == "%" && Ion::Events::isLockActive() ){
m_contentView.cursor()->performBackspace();
} else {
handleEventWithText(event.text());
}
} else if (event == Ion::Events::Paste) {
handleEventWithText(Clipboard::sharedClipboard()->storedText(), false, true);
} else {

View File

@@ -2,62 +2,29 @@
#include <escher/container.h>
#include <assert.h>
Responder::Responder(Responder * parentResponder) :
m_parentResponder(parentResponder)
{
}
Responder * Responder::parentResponder() const {
return m_parentResponder;
}
void Responder::setParentResponder(Responder * responder) {
m_parentResponder = responder;
}
void Responder::didBecomeFirstResponder() {
}
void Responder::willResignFirstResponder() {
}
void Responder::didEnterResponderChain(Responder * previousFirstResponder) {
}
void Responder::willExitResponderChain(Responder * nextFirstResponder) {
}
Responder * Responder::commonAncestorWith(Responder * responder) {
if (responder == nullptr) {
return nullptr;
}
if (this == responder) {
return this;
Responder * p = this;
while (p != nullptr) {
if (responder->hasAncestor(p)) {
return p;
}
p = p->parentResponder();
}
Responder * rootResponder = this;
while (rootResponder->parentResponder() != responder && rootResponder->parentResponder() != nullptr) {
rootResponder = rootResponder->parentResponder();
}
if (rootResponder->parentResponder() == responder) {
return responder;
}
rootResponder = responder;
while (rootResponder->parentResponder() != this && rootResponder->parentResponder() != nullptr) {
rootResponder = rootResponder->parentResponder();
}
if (rootResponder->parentResponder() == this) {
return this;
}
Responder * r = nullptr;
if (parentResponder()) {
r = parentResponder()->commonAncestorWith(responder);
}
Responder * s = nullptr;
if (responder->parentResponder()) {
s = commonAncestorWith(responder->parentResponder());
}
if (r) {
return r;
}
return s;
return nullptr;
}
bool Responder::hasAncestor(Responder * responder) const {
assert(responder != nullptr);
Responder * p = const_cast<Responder *>(this);
while (p != nullptr) {
if (p == responder) {
return true;
}
p = p->parentResponder();
}
return false;
}

View File

@@ -112,8 +112,6 @@ bool TextArea::handleEvent(Ion::Events::Event event) {
contentView()->moveCursorGeo(INT_MAX/2, 0);
} else if (event == Ion::Events::Backspace) {
return removePreviousGlyph();
} else if (event.hasText()) {
return handleEventWithText(event.text());
} else if (event == Ion::Events::EXE) {
return handleEventWithText("\n");
} else if (event == Ion::Events::Clear) {
@@ -122,6 +120,14 @@ bool TextArea::handleEvent(Ion::Events::Event event) {
}
} else if (event == Ion::Events::Paste) {
return handleEventWithText(Clipboard::sharedClipboard()->storedText());
} else if (event == Ion::Events::Percent) {
return removePreviousGlyph();
} else if (event.hasText()) {
if(event.text() == "%" && Ion::Events::isLockActive()){
return removePreviousGlyph();
} else {
return handleEventWithText(event.text());
}
} else {
return false;
}

View File

@@ -6,6 +6,7 @@
#include <ion/console.h>
#include <ion/display.h>
#include <ion/events.h>
#include <ion/exam_mode.h>
#include <ion/keyboard.h>
#include <ion/led.h>
#include <ion/power.h>

View File

@@ -12,6 +12,7 @@ bool isInitialized();
void shutdown();
void setBrightness(uint8_t b);
uint8_t brightness();
const int NumberOfStepsPerShortcut = 4;
}
}

View File

@@ -55,6 +55,7 @@ ShiftAlphaStatus shiftAlphaStatus();
void setShiftAlphaStatus(ShiftAlphaStatus s);
bool isShiftActive();
bool isAlphaActive();
bool isLockActive();
void updateModifiersFromEvent(Event e);
// Plain
@@ -138,6 +139,30 @@ constexpr Event Arctangent = Event::ShiftKey(Keyboard::Key::Tangent);
constexpr Event Equal = Event::ShiftKey(Keyboard::Key::Pi);
constexpr Event Lower = Event::ShiftKey(Keyboard::Key::Sqrt);
constexpr Event Greater = Event::ShiftKey(Keyboard::Key::Square);
constexpr Event shiftans = Event::ShiftKey(Keyboard::Key::Ans);
constexpr Event shiftplus = Event::ShiftKey(Keyboard::Key::Plus);
constexpr Event shiftfois = Event::ShiftKey(Keyboard::Key::Multiplication);
constexpr Event shiftdiv = Event::ShiftKey(Keyboard::Key::Division);
constexpr Event shiftminus = Event::ShiftKey(Keyboard::Key::Minus);
constexpr Event shift1 = Event::ShiftKey(Keyboard::Key::One);
constexpr Event shift2 = Event::ShiftKey(Keyboard::Key::Two);
constexpr Event shift3 = Event::ShiftKey(Keyboard::Key::Three);
constexpr Event shift4 = Event::ShiftKey(Keyboard::Key::Four);
constexpr Event shift5 = Event::ShiftKey(Keyboard::Key::Five);
constexpr Event shift6 = Event::ShiftKey(Keyboard::Key::Six);
constexpr Event shift7 = Event::ShiftKey(Keyboard::Key::Seven);
constexpr Event shift8 = Event::ShiftKey(Keyboard::Key::Eight);
constexpr Event shift9 = Event::ShiftKey(Keyboard::Key::Nine);
constexpr Event shift0 = Event::ShiftKey(Keyboard::Key::Zero);
constexpr Event shiftdot = Event::ShiftKey(Keyboard::Key::Dot);
constexpr Event shiftee = Event::ShiftKey(Keyboard::Key::EE);
constexpr Event shiftlp = Event::ShiftKey(Keyboard::Key::LeftParenthesis);
constexpr Event shiftrp = Event::ShiftKey(Keyboard::Key::RightParenthesis);
constexpr Event BrightnessPlus = Event::ShiftKey(Keyboard::Key::Plus);
constexpr Event BrightnessMinus = Event::ShiftKey(Keyboard::Key::Minus);
constexpr Event DoubleParenthesis = Event::ShiftKey(Keyboard::Key::LeftParenthesis);
constexpr Event ShiftSeven = Event::ShiftKey(Keyboard::Key::Seven);
constexpr Event ShiftEight = Event::ShiftKey(Keyboard::Key::Eight);
@@ -156,7 +181,7 @@ constexpr Event ShiftThree = Event::ShiftKey(Keyboard::Key::Three);
constexpr Event Colon = Event::AlphaKey(Keyboard::Key::XNT);
constexpr Event SemiColon = Event::AlphaKey(Keyboard::Key::Var);
constexpr Event DoubleQuotes = Event::AlphaKey(Keyboard::Key::Toolbox);
constexpr Event Percent = Event::AlphaKey(Keyboard::Key::Backspace);
constexpr Event Percent = Event::AlphaKey(Keyboard::Key::Back);
constexpr Event LowerA = Event::AlphaKey(Keyboard::Key::Exp);
constexpr Event LowerB = Event::AlphaKey(Keyboard::Key::Ln);
@@ -192,8 +217,10 @@ constexpr Event Space = Event::AlphaKey(Keyboard::Key::Minus);
constexpr Event Question = Event::AlphaKey(Keyboard::Key::Zero);
constexpr Event Exclamation = Event::AlphaKey(Keyboard::Key::Dot);
constexpr Event alphaans = Event::AlphaKey(Keyboard::Key::Ans);
// Shift + Alpha
constexpr Event SimpleQuote = Event::ShiftAlphaKey(Keyboard::Key::Toolbox);
constexpr Event UpperA = Event::ShiftAlphaKey(Keyboard::Key::Exp);
constexpr Event UpperB = Event::ShiftAlphaKey(Keyboard::Key::Ln);
@@ -226,6 +253,7 @@ constexpr Event UpperX = Event::ShiftAlphaKey(Keyboard::Key::Two);
constexpr Event UpperY = Event::ShiftAlphaKey(Keyboard::Key::Three);
constexpr Event UpperZ = Event::ShiftAlphaKey(Keyboard::Key::Plus);
constexpr Event shiftalphaans = Event::ShiftAlphaKey(Keyboard::Key::Ans);
// Special
constexpr Event None = Event::Special(0);

View File

@@ -0,0 +1,17 @@
#ifndef ION_EXAM_MODE_H
#define ION_EXAM_MODE_H
extern "C" {
#include <stdint.h>
}
namespace Ion {
namespace ExamMode {
uint8_t FetchExamMode();
void IncrementExamMode(uint8_t delta);
}
}
#endif

View File

@@ -25,10 +25,10 @@ static constexpr EventData s_dataForEvent[4*Event::PageSize] = {
U(), U(), TL(), TL(), TL(), TL(),
T("["), T("]"), T("{"), T("}"), T("_"), T(""),
T("asin(\x11)"), T("acos(\x11)"), T("atan(\x11)"), T("="), T("<"), T(">"),
TL(), TL(), TL(), U(), U(), U(),
TL(), TL(), TL(), U(), U(), U(),
TL(), TL(), TL(), U(), U(), U(),
U(), U(), U(), U(), U(), U(),
TL(), TL(), TL(), T("()"), U(), U(),
TL(), TL(), TL(), TL(), T("%"), U(),
TL(), TL(), TL(), TL(), T("\\"), U(),
TL(), TL(), TL(), TL(), U(), U(),
// Alpha
U(), U(), U(), U(), U(), U(),
U(), U(), U(), U(), U(), U(),
@@ -38,17 +38,17 @@ static constexpr EventData s_dataForEvent[4*Event::PageSize] = {
T("m"), T("n"), T("o"), T("p"), T("q"), U(),
T("r"), T("s"), T("t"), T("u"), T("v"), U(),
T("w"), T("x"), T("y"), T("z"), T(" "), U(),
T("?"), T("!"), U(), U(), U(), U(),
T("?"), T("!"), U(), TL(), U(), U(),
// Shift+Alpha
U(), U(), U(), U(), U(), U(),
U(), U(), U(), U(), U(), U(),
U(), U(), U(), U(), U(), U(),
U(), U(), U(), U(), T("'"), T("%"),
T("A"), T("B"), T("C"), T("D"), T("E"), T("F"),
T("G"), T("H"), T("I"), T("J"), T("K"), T("L"),
T("M"), T("N"), T("O"), T("P"), T("Q"), U(),
T("R"), T("S"), T("T"), T("U"), T("V"), U(),
T("W"), T("X"), T("Y"), T("Z"), U(), U(),
U(), U(), U(), U(), U(), U(),
U(), U(), U(), TL(), U(), U(),
};
#if DEBUG
@@ -70,9 +70,9 @@ static constexpr const char * s_nameForEvent[255] = {
nullptr, "AlphaLock", "Cut", "Copy", "Paste", "Clear",
"LeftBracket", "RightBracket", "LeftBrace", "RightBrace", "Underscore", "Sto",
"Arcsine", "Arccosine", "Arctangent", "Equal", "Lower", "Greater",
nullptr, nullptr, nullptr, nullptr, "DoubleParenthesis", nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, "BrightnessPlus", "BrightnessMinus", nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
//Alpha,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
@@ -87,7 +87,7 @@ static constexpr const char * s_nameForEvent[255] = {
//Shift+Alpha,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, "Percent",
"UpperA", "UpperB", "UpperC", "UpperD", "UpperE", "UpperF",
"UpperG", "UpperH", "UpperI", "UpperJ", "UpperK", "UpperL",
"UpperM", "UpperN", "UpperO", "UpperP", "UpperQ", nullptr,

View File

@@ -25,10 +25,10 @@ static constexpr EventData s_dataForEvent[4*Event::PageSize] = {
U(), U(), TL(), TL(), TL(), TL(),
T("["), T("]"), T("{"), T("}"), T("_"), T(""),
T("asin(\x11)"), T("acos(\x11)"), T("atan(\x11)"), T("="), T("<"), T(">"),
TL(), TL(), TL(), U(), U(), U(),
TL(), TL(), TL(), U(), U(), U(),
TL(), TL(), TL(), U(), U(), U(),
U(), U(), U(), U(), U(), U(),
TL(), TL(), TL(), T("()"), U(), U(),
TL(), TL(), TL(), TL(), T("%"), U(),
TL(), TL(), TL(), TL(), T("\\"), U(),
TL(), TL(), TL(), TL(), U(), U(),
// Alpha
U(), U(), U(), U(), U(), U(),
U(), U(), U(), U(), U(), U(),
@@ -42,7 +42,7 @@ static constexpr EventData s_dataForEvent[4*Event::PageSize] = {
// Shift+Alpha
U(), U(), U(), U(), U(), U(),
U(), U(), U(), U(), U(), U(),
U(), U(), U(), U(), U(), U(),
U(), U(), U(), U(), T("'"), T("%"),
T("A"), T("B"), T("C"), T("D"), T("E"), T("F"),
T("G"), T("H"), T("I"), T("J"), T("K"), T("L"),
T("M"), T("N"), T("O"), T("P"), T("Q"), U(),
@@ -72,7 +72,7 @@ static constexpr const char * s_nameForEvent[255] = {
"Arcsine", "Arccosine", "Arctangent", "Equal", "Lower", "Greater",
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, "BrightnessPlus", "BrightnessMinus", nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
//Alpha,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
@@ -87,7 +87,7 @@ static constexpr const char * s_nameForEvent[255] = {
//Shift+Alpha,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, "Percent",
"UpperA", "UpperB", "UpperC", "UpperD", "UpperE", "UpperF",
"UpperG", "UpperH", "UpperI", "UpperJ", "UpperK", "UpperL",
"UpperM", "UpperN", "UpperO", "UpperP", "UpperQ", nullptr,

View File

@@ -16,7 +16,7 @@ class StorageDelegate;
class Storage {
public:
typedef uint16_t record_size_t;
constexpr static size_t k_storageSize = 16384;
constexpr static size_t k_storageSize = 20480;
static Storage * sharedStorage();
constexpr static char k_dotChar = '.';

View File

@@ -17,6 +17,7 @@ ion_src += $(addprefix ion/src/shared/, \
dummy/battery.cpp \
dummy/display.cpp \
dummy/events_modifier.cpp \
dummy/exam_mode.cpp \
dummy/fcc_id.cpp \
dummy/led.cpp \
dummy/keyboard.cpp \

View File

@@ -19,20 +19,5 @@ ion_src += $(addprefix ion/src/shared/, \
ION_DEVICE_SFLAGS = -Iion/src/device/$(MODEL) -Iion/src/device/shared
$(call object_for,$(ion_device_src) $(dfu_src) $(ion_target_device_flasher_light_src) $(ion_target_device_flasher_verbose_src) $(usb_src) $(ion_target_device_bench_src) $(ion_device_dfu_xip_src) $(ion_device_dfu_relocated_src) $(ion_console_uart_src)): SFLAGS += $(ION_DEVICE_SFLAGS)
$(call object_for,$(sort $(ion_device_src) $(dfu_src) $(ion_target_device_flasher_light_src) $(ion_target_device_flasher_verbose_src) $(usb_src) $(ion_target_device_bench_src) $(ion_device_dfu_xip_src) $(ion_device_dfu_relocated_src) $(ion_console_uart_src))): SFLAGS += $(ION_DEVICE_SFLAGS)
ion_src += $(ion_device_src)
# When using the register.h C++ file in production mode, we expect the compiler
# to completely inline all bit manipulations. For some reason, if we build using
# the -Os optimization flag, GCC doesn't inline everything and and ends up
# emitting calls to aeabi_llsl for 64-bits registers. This is very sub-optimal
# so we're enforcing -O3 for this specific file.
ifneq ($(DEBUG),1)
ifneq ($(COMPILER),llvm)
$(BUILD_DIR)/ion/src/device/led.o: SFLAGS+=-O3
$(BUILD_DIR)/ion/src/device/console.o: SFLAGS+=-O3
$(BUILD_DIR)/ion/src/device/display.o: SFLAGS+=-O3
$(BUILD_DIR)/ion/src/device/swd.o: SFLAGS+=-O3
endif
endif

View File

@@ -0,0 +1,32 @@
#ifndef ION_DEVICE_N0100_CONFIG_EXAM_MODE_H
#define ION_DEVICE_N0100_CONFIG_EXAM_MODE_H
namespace Ion {
namespace ExamMode {
namespace Config {
// TODO: factorize the macro with equivalent macro on N110
#define byte4 0xFF, 0xFF, 0xFF, 0xFF
#define byte8 byte4, byte4
#define byte16 byte8, byte8
#define byte32 byte16, byte16
#define byte64 byte32, byte32
#define byte128 byte64, byte64
#define byte256 byte128, byte128
#define byte512 byte256, byte256
#define byte1K byte512, byte512
#define byte2K byte1K, byte1K
#define byte4K byte2K, byte2K
#define byte8K byte4K, byte4K
#define byte16K byte8K, byte8K
#define EXAM_BUFFER_CONTENT byte16K
constexpr static int ExamModeBufferSize = 16*1024;
}
}
}
#endif

View File

@@ -22,7 +22,10 @@ using namespace Regs;
constexpr static uint32_t StartAddress = 0xFFFFFFFF;
constexpr static uint32_t EndAddress = 0xFFFFFFFF;
constexpr static int NumberOfSectors = 0;
constexpr static int NumberOf4KSectors = 0;
constexpr static int NumberOf32KSectors = 0;
constexpr static int NumberOf64KSectors = 0;
constexpr static int NumberOfSectors = NumberOf4KSectors + NumberOf32KSectors + NumberOf64KSectors;
constexpr static AFGPIOPin Pins[] = {};
}

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