diff --git a/apps/code/toolbox.cpp b/apps/code/toolbox.cpp index e5b4d2d43..ef707ccdb 100644 --- a/apps/code/toolbox.cpp +++ b/apps/code/toolbox.cpp @@ -1,7 +1,10 @@ #include "toolbox.h" #include "../shared/toolbox_helpers.h" #include +extern "C" { #include +#include +} namespace Code { @@ -211,6 +214,17 @@ void Toolbox::setAction(Action action) { m_action = action; } +bool Toolbox::handleEvent(Ion::Events::Event event) { + if (::Toolbox::handleEvent(event)) { + return true; + } + if (event.hasText() && strlen(event.text()) == 1) { + scrollToLetter(event.text()[0]); + return true; + } + return false; +} + KDCoordinate Toolbox::rowHeight(int j) { if (typeAtLocation(0, j) == ::Toolbox::LeafCellType) { if (m_messageTreeModel->label() != I18n::Message::IfStatementMenu) { @@ -260,5 +274,34 @@ int Toolbox::maxNumberOfDisplayedRows() { return k_maxNumberOfDisplayedRows; } +void Toolbox::scrollToLetter(char letter) { + char lowerLetter = tolower(letter); + // We look for a child MessageTree that starts with the wanted letter. + for (int i = 0; i < m_messageTreeModel->numberOfChildren(); i++) { + char currentFirstLetterLowered = tolower(I18n::translate(m_messageTreeModel->children(i)->label())[0]); + if (currentFirstLetterLowered == lowerLetter) { + scrollToAndSelectChild(i); + return; + } + } + // We did not find a child MessageTree that starts with the wanted letter. + // We scroll to the first child MessageTree that starts with a letter higher + // than the wanted letter. + for (int i = 0; i < m_messageTreeModel->numberOfChildren(); i++) { + char currentFirstLetterLowered = tolower(I18n::translate(m_messageTreeModel->children(i)->label())[0]); + if (currentFirstLetterLowered >= lowerLetter && currentFirstLetterLowered <= 'z') { + scrollToAndSelectChild(i); + return; + } + } +} + +void Toolbox::scrollToAndSelectChild(int i) { + assert(i >=0 && inumberOfChildren()); + m_selectableTableView.deselectTable(); + m_selectableTableView.scrollToCell(0, i); + m_selectableTableView.selectCellAtLocation(0, i); +} + } diff --git a/apps/code/toolbox.h b/apps/code/toolbox.h index baa85d541..79ca84569 100644 --- a/apps/code/toolbox.h +++ b/apps/code/toolbox.h @@ -1,8 +1,9 @@ #ifndef CODE_TOOLBOX_H #define CODE_TOOLBOX_H -#include #include +#include +#include #include namespace Code { @@ -12,6 +13,9 @@ public: typedef void (*Action)(void * sender, const char * text); Toolbox(); void setAction(Action action); + + // StackViewController + bool handleEvent(Ion::Events::Event event) override; protected: KDCoordinate rowHeight(int j) override; bool selectLeaf(ToolboxMessageTree * selectedMessageTree) override; @@ -26,6 +30,8 @@ private: constexpr static KDCoordinate k_nodeRowHeight = 40; constexpr static KDCoordinate k_leafRowHeight = 40; constexpr static KDText::FontSize k_fontSize = KDText::FontSize::Small; + void scrollToLetter(char letter); + void scrollToAndSelectChild(int i); Action m_action; MessageTableCellWithMessage m_leafCells[k_maxNumberOfDisplayedRows]; MessageTableCellWithChevron m_nodeCells[k_maxNumberOfDisplayedRows]; diff --git a/liba/include/ctype.h b/liba/include/ctype.h index a108cf3e0..0562491a1 100644 --- a/liba/include/ctype.h +++ b/liba/include/ctype.h @@ -4,5 +4,6 @@ int isupper(int c); int isxdigit(int c); int isdigit(int c); +int tolower(int c); #endif diff --git a/liba/src/ctype.c b/liba/src/ctype.c index 42ee7c082..bd01da061 100644 --- a/liba/src/ctype.c +++ b/liba/src/ctype.c @@ -11,3 +11,7 @@ int isxdigit(int c) { int isdigit(int c) { return (c >= '0' && c <= '9'); } + +int tolower(int c) { + return isupper(c) ? 'a' + c - 'A' : c; +}