mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[escher] XNT button is now cyclic
This commit is contained in:
@@ -60,6 +60,7 @@ apps_src += $(addprefix apps/,\
|
||||
suspend_timer.cpp \
|
||||
timer_manager.cpp \
|
||||
title_bar_view.cpp \
|
||||
xnt_loop.cpp \
|
||||
)
|
||||
|
||||
tests_src += $(addprefix apps/,\
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "shared/global_context.h"
|
||||
#include "clock_timer.h"
|
||||
#include "on_boarding/prompt_controller.h"
|
||||
#include "xnt_loop.h"
|
||||
|
||||
#include <ion/events.h>
|
||||
|
||||
@@ -48,6 +49,8 @@ public:
|
||||
void displayExamModePopUp(GlobalPreferences::ExamMode mode);
|
||||
void shutdownDueToLowBattery();
|
||||
void setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus newStatus);
|
||||
CodePoint XNT(CodePoint defaultXNT, bool * shouldRemoveLastCharacter) { m_XNTLoop.XNT(defaultXNT, shouldRemoveLastCharacter); }
|
||||
void resetXNT() { m_XNTLoop.reset(); }
|
||||
OnBoarding::PromptController * promptController();
|
||||
void redrawWindow(bool force = false);
|
||||
void activateExamMode(GlobalPreferences::ExamMode examMode);
|
||||
@@ -85,6 +88,7 @@ private:
|
||||
OnBoarding::App::Snapshot m_onBoardingSnapshot;
|
||||
HardwareTest::App::Snapshot m_hardwareTestSnapshot;
|
||||
USB::App::Snapshot m_usbConnectedSnapshot;
|
||||
XNTLoop m_XNTLoop;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -129,9 +129,10 @@ VariableBoxController * App::variableBoxForInputEventHandler(InputEventHandler *
|
||||
}
|
||||
|
||||
bool App::textInputDidReceiveEvent(InputEventHandler * textInput, Ion::Events::Event event) {
|
||||
const char * pythonText = Helpers::PythonTextForEvent(event);
|
||||
if (pythonText != nullptr) {
|
||||
textInput->handleEventWithText(pythonText);
|
||||
bool shouldRemoveLastCharacter = false;
|
||||
char buffer[CodePoint::MaxCodePointCharLength + 1];
|
||||
if (Helpers::PythonTextForEvent(event, buffer, &shouldRemoveLastCharacter)) {
|
||||
textInput->handleEventWithText(buffer, false, false, shouldRemoveLastCharacter);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <escher/metric.h>
|
||||
#include <ion.h>
|
||||
#include "../global_preferences.h"
|
||||
#include <apps/apps_container.h>
|
||||
|
||||
using namespace Shared;
|
||||
|
||||
@@ -72,6 +73,10 @@ void EditorController::viewDidDisappear() {
|
||||
m_menuController->scriptContentEditionDidFinish();
|
||||
}
|
||||
|
||||
void EditorController::textAreaDidReceiveNoneXNTEvent() {
|
||||
AppsContainer::sharedAppsContainer()->resetXNT();
|
||||
}
|
||||
|
||||
bool EditorController::textAreaDidReceiveEvent(TextArea * textArea, Ion::Events::Event event) {
|
||||
if (App::app()->textInputDidReceiveEvent(textArea, event)) {
|
||||
return true;
|
||||
@@ -81,7 +86,6 @@ bool EditorController::textAreaDidReceiveEvent(TextArea * textArea, Ion::Events:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (event == Ion::Events::Backspace && textArea->selectionIsEmpty()) {
|
||||
/* If the cursor is on the left of the text of a line, backspace one
|
||||
* indentation space at a time. */
|
||||
|
||||
@@ -30,6 +30,7 @@ public:
|
||||
TELEMETRY_ID("Editor");
|
||||
|
||||
/* TextAreaDelegate */
|
||||
void textAreaDidReceiveNoneXNTEvent() override;
|
||||
bool textAreaDidReceiveEvent(TextArea * textArea, Ion::Events::Event event) override;
|
||||
|
||||
/* InputEventHandlerDelegate */
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
#include "helpers.h"
|
||||
#include <escher/clipboard.h>
|
||||
#include <apps/apps_container.h>
|
||||
|
||||
namespace Code {
|
||||
namespace Helpers {
|
||||
|
||||
const char * PythonTextForEvent(Ion::Events::Event event) {
|
||||
bool PythonTextForEvent(Ion::Events::Event event, char * buffer, bool * shouldRemoveLastCharacter) {
|
||||
for (size_t i=0; i<NumberOfPythonTextPairs; i++) {
|
||||
UTF8Helper::TextPair pair = PythonTextPairs[i];
|
||||
if (event.text() == pair.firstString()) {
|
||||
return pair.secondString();
|
||||
strcpy(buffer, pair.secondString());
|
||||
return true;
|
||||
}
|
||||
if (event == Ion::Events::XNT) {
|
||||
return "x";
|
||||
CodePoint XNT = AppsContainer::sharedAppsContainer()->XNT('x', shouldRemoveLastCharacter);
|
||||
buffer[UTF8Decoder::CodePointToChars(XNT, buffer, CodePoint::MaxCodePointCharLength + 1)] = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
namespace Code {
|
||||
namespace Helpers {
|
||||
|
||||
const char * PythonTextForEvent(Ion::Events::Event event);
|
||||
bool PythonTextForEvent(Ion::Events::Event event, char * buffer, bool * shouldRemoveLastCharacter);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,14 +426,14 @@ bool PythonTextArea::handleEvent(Ion::Events::Event event) {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool PythonTextArea::handleEventWithText(const char * text, bool indentation, bool forceCursorRightOfText) {
|
||||
bool PythonTextArea::handleEventWithText(const char * text, bool indentation, bool forceCursorRightOfText, bool shouldRemoveLastCharacter) {
|
||||
if (*text == 0) {
|
||||
return false;
|
||||
}
|
||||
if (m_contentView.isAutocompleting()) {
|
||||
removeAutocompletion();
|
||||
}
|
||||
bool result = TextArea::handleEventWithText(text, indentation, forceCursorRightOfText);
|
||||
bool result = TextArea::handleEventWithText(text, indentation, forceCursorRightOfText, shouldRemoveLastCharacter);
|
||||
addAutocompletion();
|
||||
return result;
|
||||
}
|
||||
@@ -493,9 +493,10 @@ bool PythonTextArea::addAutocompletionTextAtIndex(int nextIndex, int * currentIn
|
||||
|
||||
if (textToInsertLength > 0) {
|
||||
// Try to insert the text (this might fail if the buffer is full)
|
||||
if (!m_contentView.insertTextAtLocation(textToInsert, const_cast<char *>(autocompletionLocation), textToInsertLength)) {
|
||||
if (!m_contentView.isAbleToInsertTextAt(textToInsertLength, autocompletionLocation, false)) {
|
||||
return false;
|
||||
}
|
||||
m_contentView.insertTextAtLocation(textToInsert, const_cast<char *>(autocompletionLocation), textToInsertLength);
|
||||
autocompletionLocation += textToInsertLength;
|
||||
m_contentView.setAutocompleting(true);
|
||||
m_contentView.setAutocompletionEnd(autocompletionLocation);
|
||||
@@ -507,7 +508,8 @@ bool PythonTextArea::addAutocompletionTextAtIndex(int nextIndex, int * currentIn
|
||||
assert(strlen(parentheses) == parenthesesLength);
|
||||
/* If couldInsertText is false, we should not try to add the parentheses as
|
||||
* there was already not enough space to add the autocompletion. */
|
||||
if (addParentheses && m_contentView.insertTextAtLocation(parentheses, const_cast<char *>(autocompletionLocation), parenthesesLength)) {
|
||||
if (addParentheses && m_contentView.isAbleToInsertTextAt(parenthesesLength, autocompletionLocation, false)) {
|
||||
m_contentView.insertTextAtLocation(parentheses, const_cast<char *>(autocompletionLocation), parenthesesLength);
|
||||
m_contentView.setAutocompleting(true);
|
||||
m_contentView.setAutocompletionEnd(autocompletionLocation + parenthesesLength);
|
||||
return true;
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
void loadSyntaxHighlighter() { m_contentView.loadSyntaxHighlighter(); }
|
||||
void unloadSyntaxHighlighter() { m_contentView.unloadSyntaxHighlighter(); }
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
bool handleEventWithText(const char * text, bool indentation = false, bool forceCursorRightOfText = false) override;
|
||||
bool handleEventWithText(const char * text, bool indentation = false, bool forceCursorRightOfText = false, bool shouldRemoveLastCharacter = false) override;
|
||||
/* autocompletionType returns:
|
||||
* - EndOfIdentifier if there is currently autocompletion, or if the cursor is
|
||||
* at the end of an identifier,
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace Shared {
|
||||
class ExpressionFieldDelegateApp : public TextFieldDelegateApp, public LayoutFieldDelegate {
|
||||
public:
|
||||
virtual ~ExpressionFieldDelegateApp() = default;
|
||||
void layoutFieldDidReceiveNoneXNTEvent() override { AppsContainer::sharedAppsContainer()->resetXNT(); }
|
||||
bool layoutFieldShouldFinishEditing(LayoutField * layoutField, Ion::Events::Event event) override;
|
||||
bool layoutFieldDidReceiveEvent(LayoutField * layoutField, Ion::Events::Event event) override;
|
||||
protected:
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
#define SHARED_LAYOUT_FIELD_DELEGATE_H
|
||||
|
||||
#include "expression_field_delegate_app.h"
|
||||
#include "../apps_container.h"
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class LayoutFieldDelegate : public ::LayoutFieldDelegate {
|
||||
public:
|
||||
void layoutFieldDidReceiveNoneXNTEvent() override { AppsContainer::sharedAppsContainer()->resetXNT(); }
|
||||
bool layoutFieldShouldFinishEditing(LayoutField * layoutField, Ion::Events::Event event) override;
|
||||
bool layoutFieldDidReceiveEvent(LayoutField * layoutField, Ion::Events::Event event) override;
|
||||
bool layoutFieldDidFinishEditing(LayoutField * layoutField, Poincare::Layout layoutR, Ion::Events::Event event) override;
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
#define SHARED_TEXT_FIELD_DELEGATE_H
|
||||
|
||||
#include "text_field_delegate_app.h"
|
||||
#include "../apps_container.h"
|
||||
|
||||
namespace Shared {
|
||||
|
||||
class TextFieldDelegate : public ::TextFieldDelegate {
|
||||
public:
|
||||
void textFieldDidReceiveNoneXNTEvent() override { AppsContainer::sharedAppsContainer()->resetXNT(); }
|
||||
bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override;
|
||||
bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override;
|
||||
protected:
|
||||
|
||||
@@ -72,10 +72,12 @@ bool TextFieldDelegateApp::fieldDidReceiveEvent(EditableField * field, Responder
|
||||
if (XNTCanBeOverriden()) {
|
||||
xnt = field->XNTCodePoint(xnt);
|
||||
}
|
||||
bool shouldRemoveLastCharacter = false;
|
||||
xnt = AppsContainer::sharedAppsContainer()->XNT(xnt, &shouldRemoveLastCharacter);
|
||||
size_t length = UTF8Decoder::CodePointToChars(xnt, buffer, bufferSize);
|
||||
assert(length < bufferSize - 1);
|
||||
buffer[length] = 0;
|
||||
return field->handleEventWithText(buffer);
|
||||
return field->handleEventWithText(buffer, false, false, shouldRemoveLastCharacter);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "input_event_handler_delegate_app.h"
|
||||
#include <escher/text_field_delegate.h>
|
||||
#include <apps/i18n.h>
|
||||
#include "../apps_container.h"
|
||||
|
||||
class EditableField;
|
||||
|
||||
@@ -16,6 +17,7 @@ public:
|
||||
Poincare::Context * localContext() override;
|
||||
virtual bool XNTCanBeOverriden() const { return true; }
|
||||
virtual CodePoint XNT() { return 'x'; }
|
||||
virtual void textFieldDidReceiveNoneXNTEvent() override { AppsContainer::sharedAppsContainer()->resetXNT(); }
|
||||
bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override;
|
||||
bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override;
|
||||
bool isAcceptableText(const char * text);
|
||||
|
||||
22
apps/xnt_loop.cpp
Normal file
22
apps/xnt_loop.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "xnt_loop.h"
|
||||
#include <assert.h>
|
||||
|
||||
CodePoint XNTLoop::XNT(CodePoint defaultCodePoint, bool * shouldRemoveLastCharacter) {
|
||||
assert(shouldRemoveLastCharacter != nullptr);
|
||||
static constexpr CodePoint XNTCodePoints[] = {'x', 'n', 't', UCodePointGreekSmallLetterTheta};
|
||||
int XNTCodePointSize = sizeof(XNTCodePoints) / sizeof(CodePoint);
|
||||
|
||||
if (m_loopIndex == -1) {
|
||||
for (int i = 0; i < XNTCodePointSize; i++) {
|
||||
if (XNTCodePoints[i] == defaultCodePoint) {
|
||||
m_loopIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
*shouldRemoveLastCharacter = true;
|
||||
m_loopIndex = (m_loopIndex + 1) % XNTCodePointSize;
|
||||
}
|
||||
|
||||
return XNTCodePoints[m_loopIndex];
|
||||
}
|
||||
15
apps/xnt_loop.h
Normal file
15
apps/xnt_loop.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef APPS_XNT_LOOP
|
||||
#define APPS_XNT_LOOP
|
||||
|
||||
#include <ion/unicode/code_point.h>
|
||||
|
||||
class XNTLoop {
|
||||
public:
|
||||
XNTLoop(): m_loopIndex(-1) {}
|
||||
void reset() { m_loopIndex = -1; }
|
||||
CodePoint XNT(CodePoint defaultCodePoint, bool * shouldRemoveLastCharacter);
|
||||
private:
|
||||
int m_loopIndex;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user