diff options
-rw-r--r-- | gui/Android.mk | 3 | ||||
-rw-r--r-- | gui/console.cpp | 34 | ||||
-rw-r--r-- | gui/objects.hpp | 29 | ||||
-rw-r--r-- | gui/pages.cpp | 7 | ||||
-rw-r--r-- | gui/scrolllist.cpp | 40 | ||||
-rw-r--r-- | gui/textbox.cpp | 120 |
6 files changed, 199 insertions, 34 deletions
diff --git a/gui/Android.mk b/gui/Android.mk index 1d0d134ec..6633e9abc 100644 --- a/gui/Android.mk +++ b/gui/Android.mk @@ -27,7 +27,8 @@ LOCAL_SRC_FILES := \ partitionlist.cpp \ mousecursor.cpp \ scrolllist.cpp \ - patternpassword.cpp + patternpassword.cpp \ + textbox.cpp ifneq ($(TWRP_CUSTOM_KEYBOARD),) LOCAL_SRC_FILES += $(TWRP_CUSTOM_KEYBOARD) diff --git a/gui/console.cpp b/gui/console.cpp index 47caadb15..6b38d6137 100644 --- a/gui/console.cpp +++ b/gui/console.cpp @@ -158,39 +158,9 @@ int GUIConsole::RenderSlideout(void) return 0; } -bool GUIConsole::AddLines() -{ - if (mLastCount == gConsole.size()) - return false; // nothing to add - - size_t prevCount = mLastCount; - mLastCount = gConsole.size(); - - // Due to word wrap, figure out what / how the newly added text needs to be added to the render vector that is word wrapped - // Note, that multiple consoles on different GUI pages may be different widths or use different fonts, so the word wrapping - // may different in different console windows - for (size_t i = prevCount; i < mLastCount; i++) { - string curr_line = gConsole[i]; - string curr_color = gConsoleColor[i]; - for(;;) { - size_t line_char_width = gr_maxExW(curr_line.c_str(), mFont->GetResource(), mRenderW); - if (line_char_width < curr_line.size()) { - rConsole.push_back(curr_line.substr(0, line_char_width)); - rConsoleColor.push_back(curr_color); - curr_line = curr_line.substr(line_char_width); - } else { - rConsole.push_back(curr_line); - rConsoleColor.push_back(curr_color); - break; - } - } - } - return true; -} - int GUIConsole::RenderConsole(void) { - AddLines(); + AddLines(&gConsole, &gConsoleColor, &mLastCount, &rConsole, &rConsoleColor); GUIScrollList::Render(); // if last line is fully visible, keep tracking the last line when new lines are added @@ -241,7 +211,7 @@ int GUIConsole::Update(void) scrollToEnd = true; } - if (AddLines()) { + if (AddLines(&gConsole, &gConsoleColor, &mLastCount, &rConsole, &rConsoleColor)) { // someone added new text // at least the scrollbar must be updated, even if the new lines are currently not visible mUpdate = 1; diff --git a/gui/objects.hpp b/gui/objects.hpp index 73d8717d5..3d217c45f 100644 --- a/gui/objects.hpp +++ b/gui/objects.hpp @@ -545,6 +545,7 @@ protected: int lastY, last2Y; // last 2 touch locations, used for tracking kinetic scroll speed int fastScroll; // indicates that the inital touch was inside the fastscroll region - makes for easier fast scrolling as the touches don't have to stay within the fast scroll region and you drag your finger int mUpdate; // indicates that a change took place and we need to re-render + bool AddLines(std::vector<std::string>* origText, std::vector<std::string>* origColor, size_t* lastCount, std::vector<std::string>* rText, std::vector<std::string>* rColor); }; class GUIFileSelector : public GUIScrollList @@ -680,6 +681,33 @@ protected: bool updateList; }; +class GUITextBox : public GUIScrollList +{ +public: + GUITextBox(xml_node<>* node); + +public: + // Update - Update any UI component animations (called <= 30 FPS) + // Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error + virtual int Update(void); + + // NotifyVarChange - Notify of a variable change + virtual int NotifyVarChange(const std::string& varName, const std::string& value); + + // ScrollList interface + virtual size_t GetItemCount(); + virtual void RenderItem(size_t itemindex, int yPos, bool selected); + virtual void NotifySelect(size_t item_selected); +protected: + + size_t mLastCount; + bool mIsStatic; + std::vector<std::string> mLastValue; // Parsed text - parsed for variables but not word wrapped + std::vector<std::string> mText; // Original text - not parsed for variables and not word wrapped + std::vector<std::string> rText; // Rendered text - what we actually see + +}; + class GUIConsole : public GUIScrollList { public: @@ -725,7 +753,6 @@ protected: std::vector<std::string> rConsoleColor; protected: - bool AddLines(); int RenderSlideout(void); int RenderConsole(void); }; diff --git a/gui/pages.cpp b/gui/pages.cpp index 9bff289d3..3abd28785 100644 --- a/gui/pages.cpp +++ b/gui/pages.cpp @@ -444,6 +444,13 @@ bool Page::ProcessNode(xml_node<>* page, std::vector<xml_node<>*> *templates, in mRenders.push_back(element); mActions.push_back(element); } + else if (type == "textbox") + { + GUITextBox* element = new GUITextBox(child); + mObjects.push_back(element); + mRenders.push_back(element); + mActions.push_back(element); + } else if (type == "template") { if (!templates || !child->first_attribute("name")) diff --git a/gui/scrolllist.cpp b/gui/scrolllist.cpp index a033205bb..d857e06b3 100644 --- a/gui/scrolllist.cpp +++ b/gui/scrolllist.cpp @@ -607,3 +607,43 @@ void GUIScrollList::SetPageFocus(int inFocus) mUpdate = 1; } } + +bool GUIScrollList::AddLines(std::vector<std::string>* origText, std::vector<std::string>* origColor, size_t* lastCount, std::vector<std::string>* rText, std::vector<std::string>* rColor) +{ + if (*lastCount == origText->size()) + return false; // nothing to add + + size_t prevCount = *lastCount; + *lastCount = origText->size(); + + // Due to word wrap, figure out what / how the newly added text needs to be added to the render vector that is word wrapped + // Note, that multiple consoles on different GUI pages may be different widths or use different fonts, so the word wrapping + // may different in different console windows + for (size_t i = prevCount; i < *lastCount; i++) { + string curr_line = origText->at(i); + string curr_color; + if (origColor) + curr_color = origColor->at(i); + for(;;) { + size_t line_char_width = gr_ttf_maxExW(curr_line.c_str(), mFont->GetResource(), mRenderW); + if (line_char_width < curr_line.size()) { + //string left = curr_line.substr(0, line_char_width); + size_t wrap_pos = curr_line.find_last_of(" ,./:-_;", line_char_width - 1); + if (wrap_pos == string::npos) + wrap_pos = line_char_width; + else if (wrap_pos < line_char_width - 1) + wrap_pos++; + rText->push_back(curr_line.substr(0, wrap_pos)); + if (origColor) + rColor->push_back(curr_color); + curr_line = curr_line.substr(wrap_pos); + } else { + rText->push_back(curr_line); + if (origColor) + rColor->push_back(curr_color); + break; + } + } + } + return true; +} diff --git a/gui/textbox.cpp b/gui/textbox.cpp new file mode 100644 index 000000000..277297fec --- /dev/null +++ b/gui/textbox.cpp @@ -0,0 +1,120 @@ +/* + Copyright 2015 bigbiff/Dees_Troy/_that TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see <http://www.gnu.org/licenses/>. +*/ + +// textbox.cpp - GUITextBox object + +#include <string> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" + +GUITextBox::GUITextBox(xml_node<>* node) : GUIScrollList(node) +{ + xml_node<>* child; + + mLastCount = 0; + mIsStatic = true; + + allowSelection = false; // textbox doesn't support list item selections + + child = FindNode(node, "color"); + if (child) + { + mFontColor = LoadAttrColor(child, "foreground", mFontColor); + mBackgroundColor = LoadAttrColor(child, "background", mBackgroundColor); + //mScrollColor = LoadAttrColor(child, "scroll", mScrollColor); + } + child = FindNode(node, "text"); + while (child) { + string txt = child->value(); + mText.push_back(txt); + string lookup = gui_parse_text(txt); + if (lookup != txt) + mIsStatic = false; + mLastValue.push_back(lookup); + child = child->next_sibling("text"); + } +} + +int GUITextBox::Update(void) +{ + if (AddLines(&mLastValue, NULL, &mLastCount, &rText, NULL)) { + // someone added new text + // at least the scrollbar must be updated, even if the new lines are currently not visible + mUpdate = 1; + } + + GUIScrollList::Update(); + + if (mUpdate) { + mUpdate = 0; + if (Render() == 0) + return 2; + } + return 0; +} + +size_t GUITextBox::GetItemCount() +{ + return rText.size(); +} + +void GUITextBox::RenderItem(size_t itemindex, int yPos, bool selected __unused) +{ + // Set the color for the font + gr_color(mFontColor.red, mFontColor.green, mFontColor.blue, mFontColor.alpha); + + // render text + const char* text = rText[itemindex].c_str(); + gr_textEx(mRenderX, yPos, text, mFont->GetResource()); +} + +void GUITextBox::NotifySelect(size_t item_selected __unused) +{ + // do nothing - textbox ignores selections +} + +int GUITextBox::NotifyVarChange(const std::string& varName, const std::string& value) +{ + GUIScrollList::NotifyVarChange(varName, value); + + if(!isConditionTrue() || mIsStatic) + return 0; + + // Check to see if the variable exists in mText + for (size_t i = 0; i < mText.size(); i++) { + string lookup = gui_parse_text(mText.at(i)); + if (lookup != mText.at(i)) { + mLastValue.at(i) = lookup; + mUpdate = 1; + // There are ways to improve efficiency here, but I am not + // sure if we will even use this feature in the stock theme + // at all except for language translation. If we start using + // variables in textboxes in the stock theme, we can circle + // back and make improvements here. + mLastCount = 0; + rText.clear(); + } + } + return 0; +} |