[code] Python toolbox.

Change-Id: I4028b05c662cae04a5ac3af5021f3438bb22dcd0
This commit is contained in:
Léa Saviot
2017-10-31 16:42:29 +01:00
committed by Romain Goyet
parent a19377ad5e
commit 13bf8c2d62
38 changed files with 1001 additions and 49 deletions

View File

@@ -14,6 +14,7 @@ app_objs += $(addprefix apps/code/,\
script_parameter_controller.o\
script_store.o\
script_template.o\
toolbox.o\
)
i18n_files += $(addprefix apps/code/,\
@@ -23,6 +24,18 @@ i18n_files += $(addprefix apps/code/,\
base.fr.i18n\
base.pt.i18n\
base.universal.i18n\
catalog.de.i18n\
catalog.en.i18n\
catalog.es.i18n\
catalog.fr.i18n\
catalog.pt.i18n\
catalog.universal.i18n\
toolbox.de.i18n\
toolbox.en.i18n\
toolbox.es.i18n\
toolbox.fr.i18n\
toolbox.pt.i18n\
toolbox.universal.i18n\
)
app_images += apps/code/code_icon.png

View File

@@ -1,6 +1,7 @@
#include "app.h"
#include "../apps_container.h"
#include "code_icon.h"
#include "../shared/toolbox_helpers.h"
#include "../i18n.h"
namespace Code {
@@ -38,7 +39,25 @@ App::App(Container * container, Snapshot * snapshot) :
::App(container, snapshot, &m_codeStackViewController, I18n::Message::Warning),
m_listFooter(&m_codeStackViewController, &m_menuController, &m_menuController, ButtonRowController::Position::Bottom, ButtonRowController::Style::EmbossedGrey),
m_menuController(&m_listFooter, snapshot->scriptStore(), &m_listFooter),
m_codeStackViewController(&m_modalViewController, &m_listFooter)
m_codeStackViewController(&m_modalViewController, &m_listFooter),
m_toolboxActionForTextArea([](void * sender, const char * text) {
TextArea * textArea = static_cast<TextArea *>(sender);
textArea->insertText(text);
// insertText() also moves the cursor. We need to remove it to the
// position we want (which is after the first parenthesis or before the
// first point).
int deltaCursorLocation = - (strlen(text) - Shared::ToolboxHelpers::CursorIndexInCommand(text));
textArea->moveCursor(deltaCursorLocation);
}),
m_toolboxActionForTextField([](void * sender, const char * text) {
TextField * textField = static_cast<TextField *>(sender);
if (!textField->isEditing()) {
textField->setEditing(true);
}
int newCursorLocation = textField->cursorLocation() + Shared::ToolboxHelpers::CursorIndexInCommand(text);
textField->insertTextAtLocation(text, textField->cursorLocation());
textField->setCursorLocation(newCursorLocation);
})
{
}

View File

@@ -6,6 +6,8 @@
#include "../shared/message_controller.h"
#include "menu_controller.h"
#include "script_store.h"
#include "toolbox.h"
namespace Code {
@@ -27,11 +29,17 @@ public:
ScriptStore m_scriptStore;
};
StackViewController * stackViewController() { return &m_codeStackViewController; }
Toolbox * pythonToolbox() { return &m_toolbox; }
Toolbox::Action toolboxActionForTextArea() { return m_toolboxActionForTextArea; }
Toolbox::Action toolboxActionForTextField() { return m_toolboxActionForTextField; }
private:
App(Container * container, Snapshot * snapshot);
ButtonRowController m_listFooter;
MenuController m_menuController;
StackViewController m_codeStackViewController;
Toolbox m_toolbox;
Toolbox::Action m_toolboxActionForTextArea;
Toolbox::Action m_toolboxActionForTextField;
};
}

74
apps/code/catalog.de.i18n Normal file
View File

@@ -0,0 +1,74 @@
PythonPound = "Comment"
PythonPercent = "Modulo"
Python1J = "Imaginary i"
PythonLF = "Line feed"
PythonTab = "Tabulation"
PythonAmpersand = "Bitwise and"
PythonSymbolExp = "Bitwise exclusive or"
PythonVerticalBar = "Bitwise or"
PythonImag = "Imaginary part of z"
PythonReal = "Real part of z"
PythonAbs = "Absolute value/Magnitude"
PythonAcos = "Arc cosine"
PythonAcosh = "Arc hyperbolic cosine"
PythonAsin = "Arc sine"
PythonAsinh = "Arc hyperbolic sine"
PythonAtan = "Arc tangent"
PythonAtan2 = "Return arctan(y/x)"
PythonAtanh = "Arc hyperbolic tangent"
PythonBin = "Convert integer to binary"
PythonCeil = "Ceiling"
PythonComplex = "Return a+ib"
PythonCopySign = "Return x with the sign of y"
PythonCos = "Cosine"
PythonCosh = "Hyperbolic cosine"
PythonDegrees = "Convert x from radians to degrees"
PythonDivMod = "Quotient and remainder"
PythonConstantE = "2.718281828459046"
PythonErf = "Error function"
PythonErfc = "Complementary error function"
PythonExp = "Exponential function"
PythonExpm1 = "Compute exp(x)-1"
PythonFabs = "Absolute value"
PythonFloor = "Floor"
PythonFmod = "a modulo b"
PythonFrExp = "Mantissa and exponent of x"
PythonImportFromCmath = "Import cmath module"
PythonImportFromMath = "Import math module"
PythonGamma = "Gamma function"
PythonHex = "Convert integer to hexadecimal"
PythonImportCmath = "Import cmath module"
PythonImportMath = "Import math module"
PythonInput = "Ask an input"
PythonInt = "Convert x to an integer"
PythonIsFinite = "Check if x is finite"
PythonIsInfinite = "Check if x is infinity"
PythonIsNaN = "Check if x is a NaN"
PythonLdexp = "Return x*(2**i), inverse of frexp"
PythonLength = "Length of an object"
PythonLgamma = "Log-gamma function"
PythonLog = "Logarithm to base a"
PythonLog10 = "Logarithm to base 10"
PythonLog2 = "Logarithm to base 2"
PythonMax = "Maximum"
PythonMin = "Minimum"
PythonModf = "Fractional and integer parts of x"
PythonOct = "Convert integer to octal"
PythonPhase = "Phase of z"
PythonConstantPi = "3.141592653589794"
PythonPolar = "z in polar coordinates"
PythonPower = "x raised to the power y"
PythonPrint = "Print object"
PythonRadians = "Convert x from degrees to radians"
PythonRangeStartStop = "List from start to stop-1"
PythonRangeStop = "List from 0 to stop-1"
PythonRect = "z in cartesian coordinates"
PythonRound = "Round to n digits"
PythonSin = "Sine"
PythonSinh = "Hyperbolic sine"
PythonSorted = "Sort a list"
PythonSqrt = "Square root"
PythonSum = "Sum the items of a list"
PythonTan = "Tangent"
PythonTanh = "Hyperbolic tangent"
PythonTrunc = "x truncated to an integer"

74
apps/code/catalog.en.i18n Normal file
View File

@@ -0,0 +1,74 @@
PythonPound = "Comment"
PythonPercent = "Modulo"
Python1J = "Imaginary i"
PythonLF = "Line feed"
PythonTab = "Tabulation"
PythonAmpersand = "Bitwise and"
PythonSymbolExp = "Bitwise exclusive or"
PythonVerticalBar = "Bitwise or"
PythonImag = "Imaginary part of z"
PythonReal = "Real part of z"
PythonAbs = "Absolute value/Magnitude"
PythonAcos = "Arc cosine"
PythonAcosh = "Arc hyperbolic cosine"
PythonAsin = "Arc sine"
PythonAsinh = "Arc hyperbolic sine"
PythonAtan = "Arc tangent"
PythonAtan2 = "Return arctan(y/x)"
PythonAtanh = "Arc hyperbolic tangent"
PythonBin = "Convert integer to binary"
PythonCeil = "Ceiling"
PythonComplex = "Return a+ib"
PythonCopySign = "Return x with the sign of y"
PythonCos = "Cosine"
PythonCosh = "Hyperbolic cosine"
PythonDegrees = "Convert x from radians to degrees"
PythonDivMod = "Quotient and remainder"
PythonConstantE = "2.718281828459046"
PythonErf = "Error function"
PythonErfc = "Complementary error function"
PythonExp = "Exponential function"
PythonExpm1 = "Compute exp(x)-1"
PythonFabs = "Absolute value"
PythonFloor = "Floor"
PythonFmod = "a modulo b"
PythonFrExp = "Mantissa and exponent of x"
PythonImportFromCmath = "Import cmath module"
PythonImportFromMath = "Import math module"
PythonGamma = "Gamma function"
PythonHex = "Convert integer to hexadecimal"
PythonImportCmath = "Import cmath module"
PythonImportMath = "Import math module"
PythonInput = "Ask an input"
PythonInt = "Convert x to an integer"
PythonIsFinite = "Check if x is finite"
PythonIsInfinite = "Check if x is infinity"
PythonIsNaN = "Check if x is a NaN"
PythonLdexp = "Return x*(2**i), inverse of frexp"
PythonLength = "Length of an object"
PythonLgamma = "Log-gamma function"
PythonLog = "Logarithm to base a"
PythonLog10 = "Logarithm to base 10"
PythonLog2 = "Logarithm to base 2"
PythonMax = "Maximum"
PythonMin = "Minimum"
PythonModf = "Fractional and integer parts of x"
PythonOct = "Convert integer to octal"
PythonPhase = "Phase of z"
PythonConstantPi = "3.141592653589794"
PythonPolar = "z in polar coordinates"
PythonPower = "x raised to the power y"
PythonPrint = "Print object"
PythonRadians = "Convert x from degrees to radians"
PythonRangeStartStop = "List from start to stop-1"
PythonRangeStop = "List from 0 to stop-1"
PythonRect = "z in cartesian coordinates"
PythonRound = "Round to n digits"
PythonSin = "Sine"
PythonSinh = "Hyperbolic sine"
PythonSorted = "Sort a list"
PythonSqrt = "Square root"
PythonSum = "Sum the items of a list"
PythonTan = "Tangent"
PythonTanh = "Hyperbolic tangent"
PythonTrunc = "x truncated to an integer"

74
apps/code/catalog.es.i18n Normal file
View File

@@ -0,0 +1,74 @@
PythonPound = "Comment"
PythonPercent = "Modulo"
Python1J = "Imaginary i"
PythonLF = "Line feed"
PythonTab = "Tabulation"
PythonAmpersand = "Bitwise and"
PythonSymbolExp = "Bitwise exclusive or"
PythonVerticalBar = "Bitwise or"
PythonImag = "Imaginary part of z"
PythonReal = "Real part of z"
PythonAbs = "Absolute value/Magnitude"
PythonAcos = "Arc cosine"
PythonAcosh = "Arc hyperbolic cosine"
PythonAsin = "Arc sine"
PythonAsinh = "Arc hyperbolic sine"
PythonAtan = "Arc tangent"
PythonAtan2 = "Return arctan(y/x)"
PythonAtanh = "Arc hyperbolic tangent"
PythonBin = "Convert integer to binary"
PythonCeil = "Ceiling"
PythonComplex = "Return a+ib"
PythonCopySign = "Return x with the sign of y"
PythonCos = "Cosine"
PythonCosh = "Hyperbolic cosine"
PythonDegrees = "Convert x from radians to degrees"
PythonDivMod = "Quotient and remainder"
PythonConstantE = "2.718281828459046"
PythonErf = "Error function"
PythonErfc = "Complementary error function"
PythonExp = "Exponential function"
PythonExpm1 = "Compute exp(x)-1"
PythonFabs = "Absolute value"
PythonFloor = "Floor"
PythonFmod = "a modulo b"
PythonFrExp = "Mantissa and exponent of x"
PythonImportFromCmath = "Import cmath module"
PythonImportFromMath = "Import math module"
PythonGamma = "Gamma function"
PythonHex = "Convert integer to hexadecimal"
PythonImportCmath = "Import cmath module"
PythonImportMath = "Import math module"
PythonInput = "Ask an input"
PythonInt = "Convert x to an integer"
PythonIsFinite = "Check if x is finite"
PythonIsInfinite = "Check if x is infinity"
PythonIsNaN = "Check if x is a NaN"
PythonLdexp = "Return x*(2**i), inverse of frexp"
PythonLength = "Length of an object"
PythonLgamma = "Log-gamma function"
PythonLog = "Logarithm to base a"
PythonLog10 = "Logarithm to base 10"
PythonLog2 = "Logarithm to base 2"
PythonMax = "Maximum"
PythonMin = "Minimum"
PythonModf = "Fractional and integer parts of x"
PythonOct = "Convert integer to octal"
PythonPhase = "Phase of z"
PythonConstantPi = "3.141592653589794"
PythonPolar = "z in polar coordinates"
PythonPower = "x raised to the power y"
PythonPrint = "Print object"
PythonRadians = "Convert x from degrees to radians"
PythonRangeStartStop = "List from start to stop-1"
PythonRangeStop = "List from 0 to stop-1"
PythonRect = "z in cartesian coordinates"
PythonRound = "Round to n digits"
PythonSin = "Sine"
PythonSinh = "Hyperbolic sine"
PythonSorted = "Sort a list"
PythonSqrt = "Square root"
PythonSum = "Sum the items of a list"
PythonTan = "Tangent"
PythonTanh = "Hyperbolic tangent"
PythonTrunc = "x truncated to an integer"

74
apps/code/catalog.fr.i18n Normal file
View File

@@ -0,0 +1,74 @@
PythonPound = "Commentaire"
PythonPercent = "Modulo"
Python1J = "i complexe"
PythonLF = "Saut à la ligne"
PythonTab = "Tabulation"
PythonAmpersand = "Et logique"
PythonSymbolExp = "Ou exclusif logique"
PythonVerticalBar = "Ou logique"
PythonImag = "Partie imaginaire de z"
PythonReal = "Partie réelle de z"
PythonAbs = "Valeur absolue/Module"
PythonAcos = "Arc cosinus"
PythonAcosh = "Arc cosinus hyperbolique"
PythonAsin = "Arc sinus"
PythonAsinh = "Arc sinus hyperbolique"
PythonAtan = "Arc tangente"
PythonAtan2 = "Calcul de arctan(y/x)"
PythonAtanh = "Arc tangente hyperbolique"
PythonBin = "Conversion d'un entier en binaire"
PythonCeil = "Plafond"
PythonComplex = "Retourne a+ib"
PythonCopySign = "Retourne x avec le signe de y"
PythonCos = "Cosinus"
PythonCosh = "Cosinus hyperbolique"
PythonDegrees = "Conversion de radians en degrés"
PythonDivMod = "Quotient et reste"
PythonConstantE = "2.718281828459045"
PythonErf = "Fonction d'erreur"
PythonErfc = "Fonction d'erreur complémentaire"
PythonExp = "Fonction exponentielle"
PythonExpm1 = "Calcul de exp(x)-1"
PythonFabs = "Valeur absolue"
PythonFloor = "Partie entière"
PythonFmod = "a modulo b"
PythonFrExp = "Mantisse et exposant de x : (m,e)"
PythonImportFromCmath = "Importation du module cmath"
PythonImportFromMath = "Importation du module math"
PythonGamma = "Fonction gamma"
PythonHex = "Conversion entier en hexadécimal"
PythonImportCmath = "Importation du module cmath"
PythonImportMath = "Importation du module math"
PythonInput = "Demande de saisie"
PythonInt = "Conversion en entier"
PythonIsFinite = "Teste si x est fini"
PythonIsInfinite = "Teste si x est infini"
PythonIsNaN = "Teste si x est NaN"
PythonLdexp = "Inverse de frexp : x*(2**i)"
PythonLength = "Longueur d'un objet"
PythonLgamma = "Logarithme de la fonction gamma"
PythonLog = "Logarithme base a"
PythonLog10 = "Logarithme base 10"
PythonLog2 = "Logarithme base 2"
PythonMax = "Maximum"
PythonMin = "Minimum"
PythonModf = "Parties fractionnaire et entière"
PythonOct = "Conversion en octal"
PythonPhase = "Argument de z"
PythonConstantPi = "3.141592653589793"
PythonPolar = "Conversion en polaire"
PythonPower = "x à la puissance y"
PythonPrint = "Affiche l'objet"
PythonRadians = "Conversion de degrés en radians"
PythonRangeStartStop = "Liste de start à stop-1"
PythonRangeStop = "Liste de 0 à stop-1"
PythonRect = "Conversion en algébrique"
PythonRound = "Arrondi n chiffres"
PythonSin = "Sinus"
PythonSinh = "Sinus hyperbolique"
PythonSorted = "Tri d'une liste"
PythonSqrt = "Racine carrée"
PythonSum = "Somme des éléments d'une liste"
PythonTan = "Tangente"
PythonTanh = "Tangente hyperbolique"
PythonTrunc = "Troncature entière"

74
apps/code/catalog.pt.i18n Normal file
View File

@@ -0,0 +1,74 @@
PythonPound = "Comment"
PythonPercent = "Modulo"
Python1J = "Imaginary i"
PythonLF = "Line feed"
PythonTab = "Tabulation"
PythonAmpersand = "Bitwise and"
PythonSymbolExp = "Bitwise exclusive or"
PythonVerticalBar = "Bitwise or"
PythonImag = "Imaginary part of z"
PythonReal = "Real part of z"
PythonAbs = "Absolute value/Magnitude"
PythonAcos = "Arc cosine"
PythonAcosh = "Arc hyperbolic cosine"
PythonAsin = "Arc sine"
PythonAsinh = "Arc hyperbolic sine"
PythonAtan = "Arc tangent"
PythonAtan2 = "Return arctan(y/x)"
PythonAtanh = "Arc hyperbolic tangent"
PythonBin = "Convert integer to binary"
PythonCeil = "Ceiling"
PythonComplex = "Return a+ib"
PythonCopySign = "Return x with the sign of y"
PythonCos = "Cosine"
PythonCosh = "Hyperbolic cosine"
PythonDegrees = "Convert x from radians to degrees"
PythonDivMod = "Quotient and remainder"
PythonConstantE = "2.718281828459046"
PythonErf = "Error function"
PythonErfc = "Complementary error function"
PythonExp = "Exponential function"
PythonExpm1 = "Compute exp(x)-1"
PythonFabs = "Absolute value"
PythonFloor = "Floor"
PythonFmod = "a modulo b"
PythonFrExp = "Mantissa and exponent of x"
PythonImportFromCmath = "Import cmath module"
PythonImportFromMath = "Import math module"
PythonGamma = "Gamma function"
PythonHex = "Convert integer to hexadecimal"
PythonImportCmath = "Import cmath module"
PythonImportMath = "Import math module"
PythonInput = "Ask an input"
PythonInt = "Convert x to an integer"
PythonIsFinite = "Check if x is finite"
PythonIsInfinite = "Check if x is infinity"
PythonIsNaN = "Check if x is a NaN"
PythonLdexp = "Return x*(2**i), inverse of frexp"
PythonLength = "Length of an object"
PythonLgamma = "Log-gamma function"
PythonLog = "Logarithm to base a"
PythonLog10 = "Logarithm to base 10"
PythonLog2 = "Logarithm to base 2"
PythonMax = "Maximum"
PythonMin = "Minimum"
PythonModf = "Fractional and integer parts of x"
PythonOct = "Convert integer to octal"
PythonPhase = "Phase of z"
PythonConstantPi = "3.141592653589794"
PythonPolar = "z in polar coordinates"
PythonPower = "x raised to the power y"
PythonPrint = "Print object"
PythonRadians = "Convert x from degrees to radians"
PythonRangeStartStop = "List from start to stop-1"
PythonRangeStop = "List from 0 to stop-1"
PythonRect = "z in cartesian coordinates"
PythonRound = "Round to n digits"
PythonSin = "Sine"
PythonSinh = "Hyperbolic sine"
PythonSorted = "Sort a list"
PythonSqrt = "Square root"
PythonSum = "Sum the items of a list"
PythonTan = "Tangent"
PythonTanh = "Hyperbolic tangent"
PythonTrunc = "x truncated to an integer"

View File

@@ -0,0 +1,79 @@
PythonCommandLF = "\\n"
PythonCommandTab = "\\t"
PythonCommandAmpersand = "&"
PythonCommandPound = "#"
PythonCommandPercent = "%"
PythonCommandSymbolExp = "^"
PythonCommandVerticalBar = "|"
PythonCommand1J = "1j"
PythonCommandAbs = "abs(x)"
PythonCommandAcos = "acos(x)"
PythonCommandAcosh = "acosh(x)"
PythonCommandAsin = "asin(x)"
PythonCommandAsinh = "asinh(x)"
PythonCommandAtan = "atan(x)"
PythonCommandAtan2 = "atan2(y,x)"
PythonCommandAtanh = "atanh(x)"
PythonCommandBin = "bin(x)"
PythonCommandCeil = "ceil(x)"
PythonCommandComplex = "complex(a,b)"
PythonCommandCopySign = "copysign(x,y)"
PythonCommandCos = "cos(x)"
PythonCommandCosComplex = "cos(z)"
PythonCommandCosh = "cosh(x)"
PythonCommandDegrees = "degrees(x)"
PythonCommandDivMod = "divmod(a,b)"
PythonCommandConstantE = "e"
PythonCommandErf = "erf(x)"
PythonCommandErfc = "erfc(x)"
PythonCommandExp = "exp(x)"
PythonCommandExpComplex = "exp(z)"
PythonCommandExpm1 = "expm1(x)"
PythonCommandFabs = "fabs(x)"
PythonCommandFloor = "floor(x)"
PythonCommandFmod = "fmod(a,b)"
PythonCommandFrExp = "frexp(x)"
PythonCommandGamma = "gamma(x)"
PythonCommandImportFromCmath = "from cmath import *"
PythonCommandImportFromMath = "from math import *"
PythonCommandHex = "hex(x)"
PythonCommandImportCmath = "import cmath"
PythonCommandImportMath = "import math"
PythonCommandInput = "input('text')"
PythonCommandInt = "int(x)"
PythonCommandIsFinite = "isfinite(x)"
PythonCommandIsInfinite = "isinf(x)"
PythonCommandIsNaN = "isnan(x)"
PythonCommandLdexp = "ldexp(x,i)"
PythonCommandLgamma = "lgamma(x)"
PythonCommandLength = "len(object)"
PythonCommandLog = "log(x,a)"
PythonCommandLog10 = "log10(x)"
PythonCommandLog2 = "log2(x)"
PythonCommandLogComplex = "log(z,a)"
PythonCommandMax = "max(list)"
PythonCommandMin = "min(list)"
PythonCommandModf = "modf(x)"
PythonCommandOct = "oct(x)"
PythonCommandPhase = "phase(z)"
PythonCommandConstantPi = "pi"
PythonCommandPolar = "polar(z)"
PythonCommandPower = "pow(x,y)"
PythonCommandPrint = "print(object)"
PythonCommandRadians = "radians(x)"
PythonCommandRangeStartStop = "range(start, stop)"
PythonCommandRangeStop = "range(stop)"
PythonCommandRect = "rect(r, arg)"
PythonCommandRound = "round(x, n)"
PythonCommandSin = "sin(x)"
PythonCommandSinComplex = "sin(z)"
PythonCommandSinh = "sinh(x)"
PythonCommandSorted = "sorted(list)"
PythonCommandSqrt = "sqrt(x)"
PythonCommandSqrtComplex = "sqrt(z)"
PythonCommandSum = "sum(list)"
PythonCommandTan = "tan(x)"
PythonCommandTanh = "tanh(x)"
PythonCommandTrunc = "trunc(x)"
PythonCommandImag = "z.imag"
PythonCommandReal = "z.real"

View File

@@ -1,4 +1,5 @@
#include "console_controller.h"
#include "app.h"
#include "script.h"
#include "helpers.h"
#include <apps/i18n.h>
@@ -219,8 +220,10 @@ bool ConsoleController::textFieldDidAbortEditing(TextField * textField, const ch
return true;
}
Toolbox * ConsoleController::toolboxForTextField(TextField * textFied) {
return nullptr;
::Toolbox * ConsoleController::toolboxForTextField(TextField * textField) {
Code::App * codeApp = static_cast<Code::App *>(app());
codeApp->pythonToolbox()->setAction(codeApp->toolboxActionForTextField());
return codeApp->pythonToolbox();
}
/* printText is called by the Python machine.

View File

@@ -55,8 +55,7 @@ public:
bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override;
bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override;
bool textFieldDidAbortEditing(TextField * textField, const char * text) override;
Toolbox * toolboxForTextField(TextField * textFied) override;
::Toolbox * toolboxForTextField(TextField * textField) override;
// MicroPython::ExecutionEnvironment
void printText(const char * text, size_t length) override;
@@ -65,7 +64,7 @@ private:
static constexpr int EditCellType = 1;
static constexpr int k_numberOfLineCells = 15; // May change depending on the screen height
static constexpr int k_pythonHeapSize = 16384;
static constexpr int k_outputAccumulationBufferSize = 40;
static constexpr int k_outputAccumulationBufferSize = 100;
void autoImportScriptAtIndex(int index);
void flushOutputAccumulationBufferToStore();
void appendTextToOutputAccumulationBuffer(const char * text, size_t length);

View File

@@ -112,6 +112,12 @@ bool EditorController::textAreaDidReceiveEvent(TextArea * textArea, Ion::Events:
return false;
}
::Toolbox * EditorController::toolboxForTextArea(TextArea * textArea) {
Code::App * codeApp = static_cast<Code::App *>(app());
codeApp->pythonToolbox()->setAction(codeApp->toolboxActionForTextArea());
return codeApp->pythonToolbox();
}
StackViewController * EditorController::stackController() {
return static_cast<StackViewController *>(parentResponder());
}

View File

@@ -23,7 +23,7 @@ public:
/* TextAreaDelegate */
bool textAreaShouldFinishEditing(TextArea * textArea, Ion::Events::Event event) override;
bool textAreaDidReceiveEvent(TextArea * textArea, Ion::Events::Event event) override;
Toolbox * toolboxForTextArea(TextArea * textArea) override { return nullptr; }
::Toolbox * toolboxForTextArea(TextArea * textArea) override;
private:
static constexpr int k_indentationSpacesNumber = 2;

View File

@@ -1,4 +1,5 @@
#include "helpers.h"
#include <string.h>
namespace Code {
namespace Helpers {

View File

@@ -4,17 +4,19 @@
namespace Code {
class ScriptTemplate {
public:
constexpr ScriptTemplate(const char * name, const char * content) : m_name(name), m_content(content) {}
static const ScriptTemplate * Empty();
static const ScriptTemplate * Factorial();
static const ScriptTemplate * Fibonacci();
static const ScriptTemplate * Mandelbrot();
const char * name() const { return m_name; }
const char * content() const { return m_content; }
private:
const char * m_name;
const char * m_content;
};}
public:
constexpr ScriptTemplate(const char * name, const char * content) : m_name(name), m_content(content) {}
static const ScriptTemplate * Empty();
static const ScriptTemplate * Factorial();
static const ScriptTemplate * Fibonacci();
static const ScriptTemplate * Mandelbrot();
const char * name() const { return m_name; }
const char * content() const { return m_content; }
private:
const char * m_name;
const char * m_content;
};
}
#endif

264
apps/code/toolbox.cpp Normal file
View File

@@ -0,0 +1,264 @@
#include "toolbox.h"
#include "../shared/toolbox_helpers.h"
#include <assert.h>
#include <string.h>
namespace Code {
static constexpr int catalogChildrenCount = 74;
static constexpr int MathModuleChildrenCount = 42;
static constexpr int CMathModuleChildrenCount = 12;
static constexpr int conditionsChildrenCount = 9;
static constexpr int forLoopChildrenCount = 4;
static constexpr int functionsChildrenCount = 2;
static constexpr int ifStatementChildrenCount = 5;
static constexpr int loopsAndTestsChildrenCount = 4;
static constexpr int menuChildrenCount = 4;
static constexpr int modulesChildrenCount = 2;
static constexpr int whileLoopChildrenCount = 1;
const ToolboxMessageTree forLoopChildren[forLoopChildrenCount] = {
ToolboxMessageTree(I18n::Message::ForInRange1ArgLoopWithArg, I18n::Message::Default, I18n::Message::ForInRange1ArgLoop),
ToolboxMessageTree(I18n::Message::ForInRange2ArgsLoopWithArg, I18n::Message::Default, I18n::Message::ForInRange2ArgsLoop),
ToolboxMessageTree(I18n::Message::ForInRange3ArgsLoopWithArg, I18n::Message::Default, I18n::Message::ForInRange3ArgsLoop),
ToolboxMessageTree(I18n::Message::ForInListLoopWithArg, I18n::Message::Default, I18n::Message::ForInListLoop)};
const ToolboxMessageTree ifStatementChildren[ifStatementChildrenCount] = {
ToolboxMessageTree(I18n::Message::IfElseStatementWithArg, I18n::Message::Default, I18n::Message::IfElseStatement),
ToolboxMessageTree(I18n::Message::IfThenStatementWithArg, I18n::Message::Default, I18n::Message::IfThenStatement),
ToolboxMessageTree(I18n::Message::IfElifElseStatementWithArg, I18n::Message::Default, I18n::Message::IfElifElseStatement),
ToolboxMessageTree(I18n::Message::IfAndIfElseStatementWithArg, I18n::Message::Default, I18n::Message::IfAndIfElseStatement),
ToolboxMessageTree(I18n::Message::IfOrIfElseStatementWithArg, I18n::Message::Default, I18n::Message::IfOrIfElseStatement)};
const ToolboxMessageTree whileLoopChildren[whileLoopChildrenCount] = {
ToolboxMessageTree(I18n::Message::WhileLoopWithArg, I18n::Message::Default, I18n::Message::WhileLoop)};
const ToolboxMessageTree conditionsChildren[conditionsChildrenCount] = {
ToolboxMessageTree(I18n::Message::EqualityConditionWithArg, I18n::Message::Default, I18n::Message::EqualityCondition),
ToolboxMessageTree(I18n::Message::NonEqualityConditionWithArg, I18n::Message::Default, I18n::Message::NonEqualityCondition),
ToolboxMessageTree(I18n::Message::SuperiorStrictConditionWithArg, I18n::Message::Default, I18n::Message::SuperiorStrictCondition),
ToolboxMessageTree(I18n::Message::InferiorStrictConditionWithArg, I18n::Message::Default, I18n::Message::InferiorStrictCondition),
ToolboxMessageTree(I18n::Message::SuperiorConditionWithArg, I18n::Message::Default, I18n::Message::SuperiorCondition),
ToolboxMessageTree(I18n::Message::InferiorConditionWithArg, I18n::Message::Default, I18n::Message::InferiorCondition),
ToolboxMessageTree(I18n::Message::ConditionAnd, I18n::Message::Default, I18n::Message::ConditionAnd),
ToolboxMessageTree(I18n::Message::ConditionOr, I18n::Message::Default, I18n::Message::ConditionOr),
ToolboxMessageTree(I18n::Message::ConditionNot, I18n::Message::Default, I18n::Message::ConditionNot)};
const ToolboxMessageTree loopsAndTestsChildren[loopsAndTestsChildrenCount] = {
ToolboxMessageTree(I18n::Message::ForLoopMenu, I18n::Message::Default, I18n::Message::Default, forLoopChildren, forLoopChildrenCount),
ToolboxMessageTree(I18n::Message::IfStatementMenu, I18n::Message::Default, I18n::Message::Default, ifStatementChildren, ifStatementChildrenCount),
ToolboxMessageTree(I18n::Message::WhileLoopMenu, I18n::Message::Default, I18n::Message::Default, whileLoopChildren, whileLoopChildrenCount),
ToolboxMessageTree(I18n::Message::ConditionsMenu, I18n::Message::Default, I18n::Message::Default, conditionsChildren, conditionsChildrenCount)};
const ToolboxMessageTree MathModuleChildren[MathModuleChildrenCount] = {
ToolboxMessageTree(I18n::Message::PythonCommandImportMath, I18n::Message::PythonImportMath, I18n::Message::PythonCommandImportMath),
ToolboxMessageTree(I18n::Message::PythonCommandImportFromMath, I18n::Message::PythonImportFromMath, I18n::Message::PythonCommandImportFromMath),
ToolboxMessageTree(I18n::Message::PythonCommandConstantE, I18n::Message::PythonConstantE, I18n::Message::PythonCommandConstantE),
ToolboxMessageTree(I18n::Message::PythonCommandConstantPi, I18n::Message::PythonConstantPi, I18n::Message::PythonCommandConstantPi),
ToolboxMessageTree(I18n::Message::PythonCommandSqrt, I18n::Message::PythonSqrt, I18n::Message::PythonCommandSqrt),
ToolboxMessageTree(I18n::Message::PythonCommandPower, I18n::Message::PythonPower, I18n::Message::PythonCommandPower),
ToolboxMessageTree(I18n::Message::PythonCommandExp, I18n::Message::PythonExp, I18n::Message::PythonCommandExp),
ToolboxMessageTree(I18n::Message::PythonCommandExpm1, I18n::Message::PythonExpm1, I18n::Message::PythonCommandExpm1),
ToolboxMessageTree(I18n::Message::PythonCommandLog, I18n::Message::PythonLog, I18n::Message::PythonCommandLog),
ToolboxMessageTree(I18n::Message::PythonCommandLog2, I18n::Message::PythonLog2, I18n::Message::PythonCommandLog2),
ToolboxMessageTree(I18n::Message::PythonCommandLog10, I18n::Message::PythonLog10, I18n::Message::PythonCommandLog10),
ToolboxMessageTree(I18n::Message::PythonCommandCosh, I18n::Message::PythonCosh, I18n::Message::PythonCommandCosh),
ToolboxMessageTree(I18n::Message::PythonCommandSinh, I18n::Message::PythonSinh, I18n::Message::PythonCommandSinh),
ToolboxMessageTree(I18n::Message::PythonCommandTanh, I18n::Message::PythonTanh, I18n::Message::PythonCommandTanh),
ToolboxMessageTree(I18n::Message::PythonCommandAcosh, I18n::Message::PythonAcosh, I18n::Message::PythonCommandAcosh),
ToolboxMessageTree(I18n::Message::PythonCommandAsinh, I18n::Message::PythonAsinh, I18n::Message::PythonCommandAsinh),
ToolboxMessageTree(I18n::Message::PythonCommandAtanh, I18n::Message::PythonAtanh, I18n::Message::PythonCommandAtanh),
ToolboxMessageTree(I18n::Message::PythonCommandCos, I18n::Message::PythonCos, I18n::Message::PythonCommandCos),
ToolboxMessageTree(I18n::Message::PythonCommandSin, I18n::Message::PythonSin, I18n::Message::PythonCommandSin),
ToolboxMessageTree(I18n::Message::PythonCommandTan, I18n::Message::PythonTan, I18n::Message::PythonCommandTan),
ToolboxMessageTree(I18n::Message::PythonCommandAcos, I18n::Message::PythonAcos, I18n::Message::PythonCommandAcos),
ToolboxMessageTree(I18n::Message::PythonCommandAsin, I18n::Message::PythonAsin, I18n::Message::PythonCommandAsin),
ToolboxMessageTree(I18n::Message::PythonCommandAtan, I18n::Message::PythonAtan, I18n::Message::PythonCommandAtan),
ToolboxMessageTree(I18n::Message::PythonCommandAtan2, I18n::Message::PythonAtan2, I18n::Message::PythonCommandAtan2),
ToolboxMessageTree(I18n::Message::PythonCommandCeil, I18n::Message::PythonCeil, I18n::Message::PythonCommandCeil),
ToolboxMessageTree(I18n::Message::PythonCommandCopySign, I18n::Message::PythonCopySign, I18n::Message::PythonCommandCopySign),
ToolboxMessageTree(I18n::Message::PythonCommandFabs, I18n::Message::PythonFabs, I18n::Message::PythonCommandFabs),
ToolboxMessageTree(I18n::Message::PythonCommandFloor, I18n::Message::PythonFloor, I18n::Message::PythonCommandFloor),
ToolboxMessageTree(I18n::Message::PythonCommandFmod, I18n::Message::PythonFmod, I18n::Message::PythonCommandFmod),
ToolboxMessageTree(I18n::Message::PythonCommandFrExp, I18n::Message::PythonFrExp, I18n::Message::PythonCommandFrExp),
ToolboxMessageTree(I18n::Message::PythonCommandLdexp, I18n::Message::PythonLdexp, I18n::Message::PythonCommandLdexp),
ToolboxMessageTree(I18n::Message::PythonCommandModf, I18n::Message::PythonModf, I18n::Message::PythonCommandModf),
ToolboxMessageTree(I18n::Message::PythonCommandIsFinite, I18n::Message::PythonIsFinite, I18n::Message::PythonCommandIsFinite),
ToolboxMessageTree(I18n::Message::PythonCommandIsInfinite, I18n::Message::PythonIsInfinite, I18n::Message::PythonCommandIsInfinite),
ToolboxMessageTree(I18n::Message::PythonCommandIsNaN, I18n::Message::PythonIsNaN, I18n::Message::PythonCommandIsNaN),
ToolboxMessageTree(I18n::Message::PythonCommandTrunc, I18n::Message::PythonTrunc, I18n::Message::PythonCommandTrunc),
ToolboxMessageTree(I18n::Message::PythonCommandRadians, I18n::Message::PythonRadians, I18n::Message::PythonCommandRadians),
ToolboxMessageTree(I18n::Message::PythonCommandDegrees, I18n::Message::PythonDegrees, I18n::Message::PythonCommandDegrees),
ToolboxMessageTree(I18n::Message::PythonCommandErf, I18n::Message::PythonErf, I18n::Message::PythonCommandErf),
ToolboxMessageTree(I18n::Message::PythonCommandErfc, I18n::Message::PythonErfc, I18n::Message::PythonCommandErfc),
ToolboxMessageTree(I18n::Message::PythonCommandGamma, I18n::Message::PythonGamma, I18n::Message::PythonCommandGamma),
ToolboxMessageTree(I18n::Message::PythonCommandLgamma, I18n::Message::PythonLgamma, I18n::Message::PythonCommandLgamma)};
const ToolboxMessageTree CMathModuleChildren[CMathModuleChildrenCount] = {
ToolboxMessageTree(I18n::Message::PythonCommandImportCmath, I18n::Message::PythonImportCmath, I18n::Message::PythonCommandImportCmath),
ToolboxMessageTree(I18n::Message::PythonCommandImportFromCmath, I18n::Message::PythonImportFromCmath, I18n::Message::PythonCommandImportFromCmath),
ToolboxMessageTree(I18n::Message::PythonCommandConstantE, I18n::Message::PythonConstantE, I18n::Message::PythonCommandConstantE),
ToolboxMessageTree(I18n::Message::PythonCommandConstantPi, I18n::Message::PythonConstantPi, I18n::Message::PythonCommandConstantPi),
ToolboxMessageTree(I18n::Message::PythonCommandPhase, I18n::Message::PythonPhase, I18n::Message::PythonCommandPhase),
ToolboxMessageTree(I18n::Message::PythonCommandPolar, I18n::Message::PythonPolar, I18n::Message::PythonCommandPolar),
ToolboxMessageTree(I18n::Message::PythonCommandRect, I18n::Message::PythonRect, I18n::Message::PythonCommandRect),
ToolboxMessageTree(I18n::Message::PythonCommandExpComplex, I18n::Message::PythonExp, I18n::Message::PythonCommandExp),
ToolboxMessageTree(I18n::Message::PythonCommandLogComplex, I18n::Message::PythonLog, I18n::Message::PythonCommandLog),
ToolboxMessageTree(I18n::Message::PythonCommandSqrtComplex, I18n::Message::PythonSqrt, I18n::Message::PythonCommandSqrt),
ToolboxMessageTree(I18n::Message::PythonCommandCosComplex, I18n::Message::PythonCos, I18n::Message::PythonCommandCos),
ToolboxMessageTree(I18n::Message::PythonCommandSinComplex, I18n::Message::PythonSin, I18n::Message::PythonCommandSin)};
const ToolboxMessageTree modulesChildren[modulesChildrenCount] = {
ToolboxMessageTree(I18n::Message::MathModule, I18n::Message::Default, I18n::Message::Default, MathModuleChildren, MathModuleChildrenCount),
ToolboxMessageTree(I18n::Message::CmathModule, I18n::Message::Default, I18n::Message::Default, CMathModuleChildren, CMathModuleChildrenCount)};
const ToolboxMessageTree catalogChildren[catalogChildrenCount] = {
ToolboxMessageTree(I18n::Message::PythonCommandPound, I18n::Message::PythonPound, I18n::Message::PythonCommandPound),
ToolboxMessageTree(I18n::Message::PythonCommandPercent, I18n::Message::PythonPercent, I18n::Message::PythonCommandPercent),
ToolboxMessageTree(I18n::Message::PythonCommand1J, I18n::Message::Python1J, I18n::Message::PythonCommand1J),
ToolboxMessageTree(I18n::Message::PythonCommandLF, I18n::Message::PythonLF, I18n::Message::PythonCommandLF),
ToolboxMessageTree(I18n::Message::PythonCommandTab, I18n::Message::PythonTab, I18n::Message::PythonCommandTab),
ToolboxMessageTree(I18n::Message::PythonCommandAmpersand, I18n::Message::PythonAmpersand, I18n::Message::PythonCommandAmpersand),
ToolboxMessageTree(I18n::Message::PythonCommandSymbolExp, I18n::Message::PythonSymbolExp, I18n::Message::PythonCommandSymbolExp),
ToolboxMessageTree(I18n::Message::PythonCommandVerticalBar, I18n::Message::PythonVerticalBar, I18n::Message::PythonCommandVerticalBar),
ToolboxMessageTree(I18n::Message::PythonCommandImag, I18n::Message::PythonImag, I18n::Message::PythonCommandImag),
ToolboxMessageTree(I18n::Message::PythonCommandReal, I18n::Message::PythonReal, I18n::Message::PythonCommandReal),
ToolboxMessageTree(I18n::Message::PythonCommandAbs, I18n::Message::PythonAbs, I18n::Message::PythonCommandAbs),
ToolboxMessageTree(I18n::Message::PythonCommandAcos, I18n::Message::PythonAcos, I18n::Message::PythonCommandAcos),
ToolboxMessageTree(I18n::Message::PythonCommandAcosh, I18n::Message::PythonAcosh, I18n::Message::PythonCommandAcosh),
ToolboxMessageTree(I18n::Message::PythonCommandAsin, I18n::Message::PythonAsin, I18n::Message::PythonCommandAsin),
ToolboxMessageTree(I18n::Message::PythonCommandAsinh, I18n::Message::PythonAsinh, I18n::Message::PythonCommandAsinh),
ToolboxMessageTree(I18n::Message::PythonCommandAtan, I18n::Message::PythonAtan, I18n::Message::PythonCommandAtan),
ToolboxMessageTree(I18n::Message::PythonCommandAtan2, I18n::Message::PythonAtan2, I18n::Message::PythonCommandAtan2),
ToolboxMessageTree(I18n::Message::PythonCommandAtanh, I18n::Message::PythonAtanh, I18n::Message::PythonCommandAtanh),
ToolboxMessageTree(I18n::Message::PythonCommandBin, I18n::Message::PythonBin, I18n::Message::PythonCommandBin),
ToolboxMessageTree(I18n::Message::PythonCommandCeil, I18n::Message::PythonCeil, I18n::Message::PythonCommandCeil),
ToolboxMessageTree(I18n::Message::PythonCommandComplex, I18n::Message::PythonComplex, I18n::Message::PythonCommandComplex),
ToolboxMessageTree(I18n::Message::PythonCommandCopySign, I18n::Message::PythonCopySign, I18n::Message::PythonCommandCopySign),
ToolboxMessageTree(I18n::Message::PythonCommandCos, I18n::Message::PythonCos, I18n::Message::PythonCommandCos),
ToolboxMessageTree(I18n::Message::PythonCommandCosh, I18n::Message::PythonCosh, I18n::Message::PythonCommandCosh),
ToolboxMessageTree(I18n::Message::PythonCommandDegrees, I18n::Message::PythonDegrees, I18n::Message::PythonCommandDegrees),
ToolboxMessageTree(I18n::Message::PythonCommandDivMod, I18n::Message::PythonDivMod, I18n::Message::PythonCommandDivMod),
ToolboxMessageTree(I18n::Message::PythonCommandConstantE, I18n::Message::PythonConstantE, I18n::Message::PythonCommandConstantE),
ToolboxMessageTree(I18n::Message::PythonCommandErf, I18n::Message::PythonErf, I18n::Message::PythonCommandErf),
ToolboxMessageTree(I18n::Message::PythonCommandErfc, I18n::Message::PythonErfc, I18n::Message::PythonCommandErfc),
ToolboxMessageTree(I18n::Message::PythonCommandExp, I18n::Message::PythonExp, I18n::Message::PythonCommandExp),
ToolboxMessageTree(I18n::Message::PythonCommandExpm1, I18n::Message::PythonExpm1, I18n::Message::PythonCommandExpm1),
ToolboxMessageTree(I18n::Message::PythonCommandFabs, I18n::Message::PythonFabs, I18n::Message::PythonCommandFabs),
ToolboxMessageTree(I18n::Message::PythonCommandFloor, I18n::Message::PythonFloor, I18n::Message::PythonCommandFloor),
ToolboxMessageTree(I18n::Message::PythonCommandFmod, I18n::Message::PythonFmod, I18n::Message::PythonCommandFmod),
ToolboxMessageTree(I18n::Message::PythonCommandFrExp, I18n::Message::PythonFrExp, I18n::Message::PythonCommandFrExp),
ToolboxMessageTree(I18n::Message::PythonCommandImportFromCmath, I18n::Message::PythonImportFromCmath, I18n::Message::PythonCommandImportFromCmath),
ToolboxMessageTree(I18n::Message::PythonCommandImportFromMath, I18n::Message::PythonImportFromMath, I18n::Message::PythonCommandImportFromMath),
ToolboxMessageTree(I18n::Message::PythonCommandGamma, I18n::Message::PythonGamma, I18n::Message::PythonCommandGamma),
ToolboxMessageTree(I18n::Message::PythonCommandHex, I18n::Message::PythonHex, I18n::Message::PythonCommandHex),
ToolboxMessageTree(I18n::Message::PythonCommandImportCmath, I18n::Message::PythonImportCmath, I18n::Message::PythonCommandImportCmath),
ToolboxMessageTree(I18n::Message::PythonCommandImportMath, I18n::Message::PythonImportMath, I18n::Message::PythonCommandImportMath),
ToolboxMessageTree(I18n::Message::PythonCommandInput, I18n::Message::PythonInput, I18n::Message::PythonCommandInput),
ToolboxMessageTree(I18n::Message::PythonCommandInt, I18n::Message::PythonInt, I18n::Message::PythonCommandInt),
ToolboxMessageTree(I18n::Message::PythonCommandIsFinite, I18n::Message::PythonIsFinite, I18n::Message::PythonCommandIsFinite),
ToolboxMessageTree(I18n::Message::PythonCommandIsInfinite, I18n::Message::PythonIsInfinite, I18n::Message::PythonCommandIsInfinite),
ToolboxMessageTree(I18n::Message::PythonCommandIsNaN, I18n::Message::PythonIsNaN, I18n::Message::PythonCommandIsNaN),
ToolboxMessageTree(I18n::Message::PythonCommandLdexp, I18n::Message::PythonLdexp, I18n::Message::PythonCommandLdexp),
ToolboxMessageTree(I18n::Message::PythonCommandLength, I18n::Message::PythonLength, I18n::Message::PythonCommandLength),
ToolboxMessageTree(I18n::Message::PythonCommandLgamma, I18n::Message::PythonLgamma, I18n::Message::PythonCommandLgamma),
ToolboxMessageTree(I18n::Message::PythonCommandLog, I18n::Message::PythonLog, I18n::Message::PythonCommandLog),
ToolboxMessageTree(I18n::Message::PythonCommandLog10, I18n::Message::PythonLog10, I18n::Message::PythonCommandLog10),
ToolboxMessageTree(I18n::Message::PythonCommandLog2, I18n::Message::PythonLog2, I18n::Message::PythonCommandLog2),
ToolboxMessageTree(I18n::Message::PythonCommandMax, I18n::Message::PythonMax, I18n::Message::PythonCommandMax),
ToolboxMessageTree(I18n::Message::PythonCommandMin, I18n::Message::PythonMin, I18n::Message::PythonCommandMin),
ToolboxMessageTree(I18n::Message::PythonCommandModf, I18n::Message::PythonModf, I18n::Message::PythonCommandModf),
ToolboxMessageTree(I18n::Message::PythonCommandOct, I18n::Message::PythonOct, I18n::Message::PythonCommandOct),
ToolboxMessageTree(I18n::Message::PythonCommandPhase, I18n::Message::PythonPhase, I18n::Message::PythonCommandPhase),
ToolboxMessageTree(I18n::Message::PythonCommandConstantPi, I18n::Message::PythonConstantPi, I18n::Message::PythonCommandConstantPi),
ToolboxMessageTree(I18n::Message::PythonCommandPolar, I18n::Message::PythonPolar, I18n::Message::PythonCommandPolar),
ToolboxMessageTree(I18n::Message::PythonCommandPower, I18n::Message::PythonPower, I18n::Message::PythonCommandPower),
ToolboxMessageTree(I18n::Message::PythonCommandPrint, I18n::Message::PythonPrint, I18n::Message::PythonCommandPrint),
ToolboxMessageTree(I18n::Message::PythonCommandRadians, I18n::Message::PythonRadians, I18n::Message::PythonCommandRadians),
ToolboxMessageTree(I18n::Message::PythonCommandRangeStartStop, I18n::Message::PythonRangeStartStop, I18n::Message::PythonCommandRangeStartStop),
ToolboxMessageTree(I18n::Message::PythonCommandRangeStop, I18n::Message::PythonRangeStop, I18n::Message::PythonCommandRangeStop),
ToolboxMessageTree(I18n::Message::PythonCommandRect, I18n::Message::PythonRect, I18n::Message::PythonCommandRect),
ToolboxMessageTree(I18n::Message::PythonCommandRound, I18n::Message::PythonRound, I18n::Message::PythonCommandRound),
ToolboxMessageTree(I18n::Message::PythonCommandSin, I18n::Message::PythonSin, I18n::Message::PythonCommandSin),
ToolboxMessageTree(I18n::Message::PythonCommandSinh, I18n::Message::PythonSinh, I18n::Message::PythonCommandSinh),
ToolboxMessageTree(I18n::Message::PythonCommandSorted, I18n::Message::PythonSorted, I18n::Message::PythonCommandSorted),
ToolboxMessageTree(I18n::Message::PythonCommandSqrt, I18n::Message::PythonSqrt, I18n::Message::PythonCommandSqrt),
ToolboxMessageTree(I18n::Message::PythonCommandSum, I18n::Message::PythonSum, I18n::Message::PythonCommandSum),
ToolboxMessageTree(I18n::Message::PythonCommandTan, I18n::Message::PythonTan, I18n::Message::PythonCommandTan),
ToolboxMessageTree(I18n::Message::PythonCommandTanh, I18n::Message::PythonTanh, I18n::Message::PythonCommandTanh),
ToolboxMessageTree(I18n::Message::PythonCommandTrunc, I18n::Message::PythonTrunc, I18n::Message::PythonCommandTrunc)};
const ToolboxMessageTree functionsChildren[functionsChildrenCount] = {
ToolboxMessageTree(I18n::Message::PythonCommandDefWithArg, I18n::Message::Default, I18n::Message::PythonCommandDef),
ToolboxMessageTree(I18n::Message::PythonCommandReturn, I18n::Message::Default, I18n::Message::PythonCommandReturn)};
const ToolboxMessageTree menu[menuChildrenCount] = {
ToolboxMessageTree(I18n::Message::LoopsAndTests, I18n::Message::Default, I18n::Message::Default, loopsAndTestsChildren, loopsAndTestsChildrenCount),
ToolboxMessageTree(I18n::Message::Modules, I18n::Message::Default, I18n::Message::Default, modulesChildren, modulesChildrenCount),
ToolboxMessageTree(I18n::Message::Catalog, I18n::Message::Default, I18n::Message::Default, catalogChildren, catalogChildrenCount),
ToolboxMessageTree(I18n::Message::Functions, I18n::Message::Default, I18n::Message::Default, functionsChildren, functionsChildrenCount)};
const ToolboxMessageTree toolboxModel = ToolboxMessageTree(I18n::Message::Toolbox, I18n::Message::Default, I18n::Message::Default, menu, menuChildrenCount);
Toolbox::Toolbox() :
::Toolbox(nullptr, I18n::translate(rootModel()->label()))
{
}
void Toolbox::setAction(Action action) {
m_action = action;
}
KDCoordinate Toolbox::rowHeight(int j) {
if (typeAtLocation(0, j) == ::Toolbox::LeafCellType) {
if (m_messageTreeModel->label() != I18n::Message::IfStatementMenu) {
/* To get the exact height needed for each cell, we have to compute its
* text size, which means scan the text char by char to look for '\n'
* chars. This is very costly and ruins the speed performance when
* scrolling at the bottom of a long table: to compute a position on the
* kth row, we call cumulatedHeightFromIndex(k), which calls rowHeight k
* times.
* We thus decided to compute the real height only for the ifStatement
* children of the toolbox, which is the only menu that has special height
* rows. */
return k_leafRowHeight;
}
const ToolboxMessageTree * messageTree = static_cast<const ToolboxMessageTree *>(m_messageTreeModel->children(j));
return KDText::stringSize(I18n::translate(messageTree->label()), k_fontSize).height() + 2*Metric::TableCellLabelTopMargin + (messageTree->text() == I18n::Message::Default ? 0 : k_leafRowHeight);
}
return k_nodeRowHeight;
}
bool Toolbox::selectLeaf(ToolboxMessageTree * selectedMessageTree) {
m_selectableTableView.deselectTable();
ToolboxMessageTree * node = selectedMessageTree;
const char * editedText = I18n::translate(node->insertedText());
char strippedEditedText[strlen(editedText)];
Shared::ToolboxHelpers::TextToInsertForCommandMessage(node->insertedText(), strippedEditedText);
m_action(sender(), const_cast<const char *>(strippedEditedText));
app()->dismissModalViewController();
return true;
}
const ToolboxMessageTree * Toolbox::rootModel() {
return &toolboxModel;
}
MessageTableCellWithMessage * Toolbox::leafCellAtIndex(int index) {
assert(index >= 0 && index < k_maxNumberOfDisplayedRows);
return &m_leafCells[index];
}
MessageTableCellWithChevron* Toolbox::nodeCellAtIndex(int index) {
assert(index >= 0 && index < k_maxNumberOfDisplayedRows);
return &m_nodeCells[index];
}
int Toolbox::maxNumberOfDisplayedRows() {
return k_maxNumberOfDisplayedRows;
}
}

View File

@@ -0,0 +1,4 @@
Functions = "Functions"
Catalog = "Catalog"
Modules = "Modules"
LoopsAndTests = "Loops and tests"

View File

@@ -0,0 +1,4 @@
Functions = "Functions"
Catalog = "Catalog"
Modules = "Modules"
LoopsAndTests = "Loops and tests"

View File

@@ -0,0 +1,4 @@
Functions = "Functions"
Catalog = "Catalog"
Modules = "Modules"
LoopsAndTests = "Loops and tests"

View File

@@ -0,0 +1,4 @@
Functions = "Fonctions"
Catalog = "Catalogue"
Modules = "Modules"
LoopsAndTests = "Boucles et tests"

36
apps/code/toolbox.h Normal file
View File

@@ -0,0 +1,36 @@
#ifndef CODE_TOOLBOX_H
#define CODE_TOOLBOX_H
#include <escher.h>
#include <apps/i18n.h>
#include <kandinsky/text.h>
namespace Code {
class Toolbox : public ::Toolbox {
public:
typedef void (*Action)(void * sender, const char * text);
Toolbox();
void setAction(Action action);
protected:
KDCoordinate rowHeight(int j) override;
bool selectLeaf(ToolboxMessageTree * selectedMessageTree) override;
const ToolboxMessageTree * rootModel() override;
MessageTableCellWithMessage * leafCellAtIndex(int index) override;
MessageTableCellWithChevron* nodeCellAtIndex(int index) override;
int maxNumberOfDisplayedRows() override;
constexpr static int k_maxNumberOfDisplayedRows = 13; // = 240/(13+2*3)
// 13 = minimal string height size
// 3 = vertical margins
private:
constexpr static KDCoordinate k_nodeRowHeight = 40;
constexpr static KDCoordinate k_leafRowHeight = 40;
constexpr static KDText::FontSize k_fontSize = KDText::FontSize::Small;
Action m_action;
MessageTableCellWithMessage m_leafCells[k_maxNumberOfDisplayedRows];
MessageTableCellWithChevron m_nodeCells[k_maxNumberOfDisplayedRows];
};
}
#endif

View File

@@ -0,0 +1,4 @@
Functions = "Functions"
Catalog = "Catalog"
Modules = "Modules"
LoopsAndTests = "Loops and tests"

View File

@@ -0,0 +1,45 @@
MathModule = "math"
CmathModule = "cmath"
RandomModule = "RandomModule"
ForLoopMenu = "For"
IfStatementMenu = "If"
WhileLoopMenu = "While"
ConditionsMenu = "Conditions"
ConditionNot = "not"
ConditionOr = "or"
ConditionAnd = "and"
InferiorCondition = "<="
InferiorConditionWithArg = "x<=y"
SuperiorCondition = ">="
SuperiorConditionWithArg = "x>=y"
InferiorStrictCondition = "<"
InferiorStrictConditionWithArg = "x<y"
SuperiorStrictCondition = ">"
SuperiorStrictConditionWithArg = "x>y"
NonEqualityCondition = "!="
NonEqualityConditionWithArg = "x!=y"
EqualityCondition = "=="
EqualityConditionWithArg = "x==y"
WhileLoop = "while ():"
WhileLoopWithArg = "while condition:\n instruction"
IfOrIfElseStatement = "if () or ():\n \nelse:\n "
IfOrIfElseStatementWithArg = "if condition1 or condition2:\n instruction1\nelse:\n instruction2"
IfAndIfElseStatement = "if () and ():\n \nelse:\n "
IfAndIfElseStatementWithArg = "if condition1 and condition2:\n instruction1\nelse:\n instruction2"
IfElifElseStatement = "if ():\n \nelif ():\n \nelse:"
IfElifElseStatementWithArg = "if condition1:\n instruction1\nelif condition2:\n instruction2\nelse:\n instruction3"
IfThenStatement= "if ():"
IfThenStatementWithArg = "if condition:\n instruction"
IfElseStatement = "if ():\n \nelse:\n "
IfElseStatementWithArg = "if condition:\n instruction1\nelse:\n instruction2"
ForInListLoop = "for i in ():"
ForInListLoopWithArg = "for i in list:\n instruction"
ForInRange3ArgsLoop = "for i in range(,,):"
ForInRange3ArgsLoopWithArg = "for i in range(start, stop, step):\n instruction"
ForInRange2ArgsLoop = "for i in range(,):"
ForInRange2ArgsLoopWithArg = "for i in range(start, stop):\n instruction"
ForInRange1ArgLoop = "for i in range():"
ForInRange1ArgLoopWithArg = "for i in range(size):\n instruction"
PythonCommandDef = "def ():"
PythonCommandDefWithArg = "def function(x):"
PythonCommandReturn = "return"

View File

@@ -28,8 +28,16 @@ def ion_char(i18n_letter):
def source_definition(i18n_string):
ion_characters = []
for i18n_letter in i18n_string.decode('utf8'):
ion_characters.append(ion_char(i18n_letter))
letters = i18n_string.decode('utf8')
i = 0
while i < len(letters):
if letters[i] == '\\':
i = i+1
newChar = "'\\"+letters[i]+"'"
ion_characters.append(newChar)
else:
ion_characters.append(ion_char(letters[i]))
i = i+1
ion_characters.append("0")
return "{" + ", ".join(ion_characters) + "}"

View File

@@ -1,4 +1,5 @@
#include "math_toolbox.h"
#include "./shared/toolbox_helpers.h"
#include <assert.h>
#include <string.h>
@@ -74,15 +75,8 @@ bool MathToolbox::selectLeaf(ToolboxMessageTree * selectedMessageTree) {
sender()->setEditing(true);
}
sender()->insertTextAtLocation(editedText, sender()->cursorLocation());
int cursorDelta = 0;
int editedTextLength = strlen(editedText);
for (int i = 0; i < editedTextLength; i++) {
if (editedText[i] == '(') {
cursorDelta = i + 1;
break;
}
}
sender()->setCursorLocation(sender()->cursorLocation()+cursorDelta);
int newCursorLocation = sender()->cursorLocation() + Shared::ToolboxHelpers::CursorIndexInCommand(editedText);
sender()->setCursorLocation(newCursorLocation);
app()->dismissModalViewController();
return true;
}
@@ -92,12 +86,12 @@ const ToolboxMessageTree * MathToolbox::rootModel() {
}
MessageTableCellWithMessage * MathToolbox::leafCellAtIndex(int index) {
assert(index > 0 && index < k_maxNumberOfDisplayedRows);
assert(index >= 0 && index < k_maxNumberOfDisplayedRows);
return &m_leafCells[index];
}
MessageTableCellWithChevron* MathToolbox::nodeCellAtIndex(int index) {
assert(index > 0 && index < k_maxNumberOfDisplayedRows);
assert(index >= 0 && index < k_maxNumberOfDisplayedRows);
return &m_nodeCells[index];
}

View File

@@ -38,6 +38,7 @@ app_objs += $(addprefix apps/shared/,\
tab_table_controller.o\
text_field_delegate.o\
text_field_delegate_app.o\
toolbox_helpers.o\
values_function_parameter_controller.o\
values_parameter_controller.o\
values_controller.o\

View File

@@ -0,0 +1,44 @@
#include "toolbox_helpers.h"
#include <string.h>
namespace Shared {
namespace ToolboxHelpers {
int CursorIndexInCommand(const char * text) {
for (int i = 0; i < strlen(text); i++) {
if (text[i] == '(') {
return i + 1;
} else if (text[i] == '.') {
return i;
}
}
return strlen(text);
}
void TextToInsertForCommandMessage(I18n::Message message, char * buffer) {
const char * messageText = I18n::translate(message);
int currentNewTextIndex = 0;
int numberOfOpenBrackets = 0;
for (int i = 0; i < strlen(messageText); i++) {
if (messageText[i] == '.') {
currentNewTextIndex = 0;
numberOfOpenBrackets = 0;
} else if (messageText[i] == '(') {
numberOfOpenBrackets++;
} else if (messageText[i] == ')') {
numberOfOpenBrackets--;
}
if (numberOfOpenBrackets == 0
|| messageText[i] == ','
|| messageText[i] == '('
|| messageText[i] == ')')
{
buffer[currentNewTextIndex] = messageText[i];
buffer[currentNewTextIndex + 1] = 0;
currentNewTextIndex++;
}
}
}
}
}

View File

@@ -0,0 +1,25 @@
#ifndef SHARED_TOOLBOX_HELPERS_H
#define SHARED_TOOLBOX_HELPERS_H
#include <escher/i18n.h>
namespace Shared {
namespace ToolboxHelpers {
int CursorIndexInCommand(const char * text);
/* Returns the index of the cursor position in a Command, which is the smallest
* index between :
* - After the first open parenthesis
* - Before the first point
* - The end of the text */
void TextToInsertForCommandMessage(I18n::Message message, char * buffer);
/* Removes the arguments from a command message in two ways:
* - Removes text between parentheses, except commas
* - Removes text before a point */
}
}
#endif

View File

@@ -14,6 +14,7 @@ public:
constexpr static KDCoordinate ParameterCellHeight = 35;
constexpr static KDCoordinate ModalTopMargin = 5;
constexpr static KDCoordinate ModalBottomMargin = 18;
constexpr static KDCoordinate TableCellLabelTopMargin = 3;
constexpr static KDCoordinate TabHeight = 27;
constexpr static KDCoordinate ScrollStep = 10;
constexpr static KDCoordinate PopUpLeftMargin = 32;

View File

@@ -18,7 +18,7 @@ public:
Responder * commonAncestorWith(Responder * responder);
void setParentResponder(Responder * responder);
App * app();
virtual Toolbox * toolbox();
virtual Toolbox * toolbox() { return nullptr; }
private:
Responder * m_parentResponder;
};

View File

@@ -22,7 +22,6 @@ protected:
private:
constexpr static KDCoordinate k_labelMargin = 10;
constexpr static KDCoordinate k_accessoryMargin = 10;
constexpr static KDCoordinate k_labelTopMargin = 3;
constexpr static KDCoordinate k_accessoryBottomMargin = 3;
Layout m_layout;
};

View File

@@ -12,8 +12,8 @@ public:
TextArea(Responder * parentResponder, char * textBuffer = nullptr, size_t textBufferSize = 0,
TextAreaDelegate * delegate = nullptr, KDText::FontSize fontSize = KDText::FontSize::Large,
KDColor textColor = KDColorBlack, KDColor backgroundColor = KDColorWhite);
void setDelegate(TextAreaDelegate * delegate) { m_delegate = delegate; }
Toolbox * toolbox() override;
bool handleEvent(Ion::Events::Event event) override;
void setText(char * textBuffer, size_t textBufferSize);
void insertText(const char * textBuffer) { m_contentView.insertText(textBuffer); }

View File

@@ -1,5 +1,6 @@
#include <escher/message_table_cell_with_message.h>
#include <escher/palette.h>
#include <string.h>
MessageTableCellWithMessage::MessageTableCellWithMessage(I18n::Message message, Layout layout) :
MessageTableCell(message, KDText::FontSize::Small, layout),
@@ -16,6 +17,9 @@ void MessageTableCellWithMessage::setAccessoryMessage(I18n::Message textBody) {
}
View * MessageTableCellWithMessage::accessoryView() const {
if (strlen(m_accessoryView.text()) == 0) {
return nullptr;
}
return (View *)&m_accessoryView;
}

View File

@@ -86,7 +86,3 @@ App * Responder::app() {
assert(result->m_magic == App::Magic); // Poor man's RTTI
return result;
}
Toolbox * Responder::toolbox() {
return nullptr;
}

View File

@@ -1,5 +1,6 @@
#include <escher/table_cell.h>
#include <escher/palette.h>
#include <escher/metric.h>
TableCell::TableCell(Layout layout) :
HighlightCell(),
@@ -41,7 +42,7 @@ void TableCell::layoutSubviews() {
KDSize labelSize = label->minimalSizeForOptimalDisplay();
switch (m_layout) {
case Layout::Vertical:
label->setFrame(KDRect(k_separatorThickness+k_labelMargin, k_separatorThickness+k_labelTopMargin, width-2*k_separatorThickness-k_labelMargin, labelSize.height()));
label->setFrame(KDRect(k_separatorThickness+k_labelMargin, k_separatorThickness+Metric::TableCellLabelTopMargin, width-2*k_separatorThickness-k_labelMargin, labelSize.height()));
break;
default:
label->setFrame(KDRect(k_separatorThickness+k_labelMargin, k_separatorThickness, labelSize.width(), height - 2*k_separatorThickness));

View File

@@ -325,8 +325,19 @@ TextArea::TextArea(Responder * parentResponder, char * textBuffer,
assert(textBufferSize < INT_MAX/2);
}
bool TextArea::TextArea::handleEvent(Ion::Events::Event event) {
Toolbox * TextArea::toolbox() {
if (m_delegate != nullptr) {
return m_delegate->toolboxForTextArea(this);
}
return nullptr;
}
bool TextArea::handleEvent(Ion::Events::Event event) {
if (m_delegate != nullptr && m_delegate->textAreaDidReceiveEvent(this, event)) {
return true;
} else if (Responder::handleEvent(event)) {
// The only event Responder handles is 'Toolbox' displaying.
return true;
} else if (event == Ion::Events::Left) {
m_contentView.moveCursorIndex(-1);
} else if (event == Ion::Events::Right) {
@@ -370,5 +381,9 @@ void TextArea::setText(char * textBuffer, size_t textBufferSize) {
}
void TextArea::moveCursor(int deltaX) {
m_contentView.moveCursorIndex(deltaX);
int sign = deltaX > 0? 1 : -1;
int numberSteps = deltaX * sign;
for (int i = 0; i < numberSteps; i++) {
m_contentView.moveCursorIndex(sign);
}
}

View File

@@ -297,6 +297,9 @@ bool TextField::textFieldShouldFinishEditing(Ion::Events::Event event) {
bool TextField::handleEvent(Ion::Events::Event event) {
assert(m_delegate != nullptr);
if (m_delegate->textFieldDidReceiveEvent(this, event)) {
return true;
}
if (Responder::handleEvent(event)) {
/* The only event Responder handles is 'Toolbox' displaying. In that case,
* the text field is forced into editing mode. */
@@ -305,9 +308,6 @@ bool TextField::handleEvent(Ion::Events::Event event) {
}
return true;
}
if (m_delegate->textFieldDidReceiveEvent(this, event)) {
return true;
}
if (event == Ion::Events::Left && isEditing() && cursorLocation() > 0) {
setCursorLocation(cursorLocation()-1);
return true;

View File

@@ -202,7 +202,7 @@ bool Toolbox::handleEventForRow(Ion::Events::Event event, int selectedRow) {
}
bool Toolbox::selectSubMenu(ToolboxMessageTree * selectedMessageTree) {
m_stack.push(selectedRow(), m_selectableTableView.contentOffset().y());
m_stack.push(selectedRow(), m_selectableTableView.contentOffset().y());
m_selectableTableView.deselectTable();
m_messageTreeModel = selectedMessageTree;
m_listController.setFirstSelectedRow(0);
@@ -211,8 +211,7 @@ bool Toolbox::selectSubMenu(ToolboxMessageTree * selectedMessageTree) {
}
bool Toolbox::returnToPreviousMenu() {
m_selectableTableView.deselectTable();
int depth = m_stack.depth();
int currentDepth = m_stack.depth();
int index = 0;
// We want to get the current ToolboxMessageTree's parent ToolboxMessageTree,
// but there is no ToolboxMessageTree::getParent() method. We thus have to
@@ -220,7 +219,7 @@ bool Toolbox::returnToPreviousMenu() {
// child until it has the wanted depth.
ToolboxMessageTree * parentMessageTree = (ToolboxMessageTree *)rootModel();
Stack::State * previousState = m_stack.stateAtIndex(index++);;
while (depth-- > 1) {
while (currentDepth-- > 1) {
parentMessageTree = (ToolboxMessageTree *)parentMessageTree->children(previousState->selectedRow());
previousState = m_stack.stateAtIndex(index++);
}