From 31218ec952173a707f97cfb7c7211ab79d8471f1 Mon Sep 17 00:00:00 2001 From: Dees Troy Date: Tue, 25 Feb 2014 20:35:56 +0000 Subject: Add word wrap to console output and fix scrolling in console Change-Id: Ibcf89952ee1391350c715f1ec82cf0cdb9b0ca7d --- gui/console.cpp | 90 +++++++++++++++++++++++++++++++-------------------------- gui/objects.hpp | 4 ++- 2 files changed, 52 insertions(+), 42 deletions(-) (limited to 'gui') diff --git a/gui/console.cpp b/gui/console.cpp index 5d0ed3ec3..51ad21e59 100644 --- a/gui/console.cpp +++ b/gui/console.cpp @@ -117,7 +117,9 @@ GUIConsole::GUIConsole(xml_node<>* node) : GUIObject(node) mScrollColor.alpha = 255; mLastCount = 0; mSlideout = 0; + RenderCount = 0; mSlideoutState = hidden; + mRender = true; mRenderX = 0; mRenderY = 0; mRenderW = gr_fb_width(); mRenderH = gr_fb_height(); @@ -211,21 +213,42 @@ int GUIConsole::RenderConsole(void) gr_color(mForegroundColor.red, mForegroundColor.green, mForegroundColor.blue, mForegroundColor.alpha); // Don't try to continue to render without data + int prevCount = mLastCount; mLastCount = gConsole.size(); + mRender = false; if (mLastCount == 0) return (mSlideout ? RenderSlideout() : 0); + // 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 (int i = prevCount; i < mLastCount; i++) { + string curr_line = gConsole[i]; + int line_char_width; + for(;;) { + line_char_width = gr_maxExW(curr_line.c_str(), fontResource, mConsoleW); + if (line_char_width < curr_line.size()) { + rConsole.push_back(curr_line.substr(0, line_char_width)); + curr_line = curr_line.substr(line_char_width, curr_line.size() - line_char_width - 1); + } else { + rConsole.push_back(curr_line); + break; + } + } + } + RenderCount = rConsole.size(); + // Find the start point int start; int curLine = mCurrentLine; // Thread-safing (Another thread updates this value) if (curLine == -1) { - start = mLastCount - mMaxRows; + start = RenderCount - mMaxRows; } else { - if (curLine > (int) mLastCount) - curLine = (int) mLastCount; + if (curLine > (int) RenderCount) + curLine = (int) RenderCount; if ((int) mMaxRows > curLine) curLine = (int) mMaxRows; start = curLine - mMaxRows; @@ -234,8 +257,8 @@ int GUIConsole::RenderConsole(void) unsigned int line; for (line = 0; line < mMaxRows; line++) { - if ((start + (int) line) >= 0 && (start + (int) line) < (int) mLastCount) - gr_textExW(mConsoleX, mStartY + (line * mFontHeight), gConsole[start + line].c_str(), fontResource, mConsoleW + mConsoleX); + if ((start + (int) line) >= 0 && (start + (int) line) < (int) RenderCount) + gr_textExW(mConsoleX, mStartY + (line * mFontHeight), rConsole[start + line].c_str(), fontResource, mConsoleW + mConsoleX); } return (mSlideout ? RenderSlideout() : 0); } @@ -278,11 +301,10 @@ int GUIConsole::Update(void) Render(); return 2; } - else if (mLastTouchY >= 0) + else if (mRender) { // They're still touching, so re-render Render(); - mLastTouchY = -1; return 2; } return 0; @@ -354,7 +376,7 @@ int GUIConsole::NotifyTouch(TOUCH_STATE state, int x, int y) } // If we don't have enough lines to scroll, throw this away. - if (mLastCount < mMaxRows) return 1; + if (RenderCount < mMaxRows) return 1; // We are scrolling!!! switch (state) @@ -362,47 +384,33 @@ int GUIConsole::NotifyTouch(TOUCH_STATE state, int x, int y) case TOUCH_START: mLastTouchX = x; mLastTouchY = y; - if ((x - mConsoleX) > ((9 * mConsoleW) / 10)) - mSlideMultiplier = 10; - else - mSlideMultiplier = 1; break; case TOUCH_DRAG: - // This handles tapping - if (x == mLastTouchX && y == mLastTouchY) break; - mLastTouchX = -1; - - if (y > mLastTouchY + 5) - { - mLastTouchY = y; - if (mCurrentLine == -1) - mCurrentLine = mLastCount - 1; - else if (mCurrentLine > mSlideMultiplier) - mCurrentLine -= mSlideMultiplier; - else - mCurrentLine = mMaxRows; - - if (mCurrentLine < (int) mMaxRows) - mCurrentLine = mMaxRows; - } - else if (y < mLastTouchY - 5) - { - mLastTouchY = y; - if (mCurrentLine >= 0) - { - mCurrentLine += mSlideMultiplier; - if (mCurrentLine >= (int) mLastCount) - mCurrentLine = -1; + if (x < mConsoleX || x > mConsoleX + mConsoleW || y < mConsoleY || y > mConsoleY + mConsoleH) + break; // touch is outside of the console area -- do nothing + if (y > mLastTouchY + mFontHeight) { + while (y > mLastTouchY + mFontHeight) { + if (mCurrentLine == -1) + mCurrentLine = RenderCount - 1; + else if (mCurrentLine > mMaxRows) + mCurrentLine--; + mLastTouchY += mFontHeight; + } + mRender = true; + } else if (y < mLastTouchY - mFontHeight) { + while (y < mLastTouchY - mFontHeight) { + if (mCurrentLine >= 0) + mCurrentLine++; + mLastTouchY -= mFontHeight; } + if (mCurrentLine >= (int) RenderCount) + mCurrentLine = -1; + mRender = true; } break; case TOUCH_RELEASE: - // On a tap, we jump to the tail - if (mLastTouchX >= 0) - mCurrentLine = -1; - mLastTouchY = -1; case TOUCH_REPEAT: case TOUCH_HOLD: diff --git a/gui/objects.hpp b/gui/objects.hpp index f8a4e8ca8..4942cd7e6 100644 --- a/gui/objects.hpp +++ b/gui/objects.hpp @@ -339,15 +339,17 @@ protected: unsigned int mFontHeight; int mCurrentLine; unsigned int mLastCount; + unsigned int RenderCount; unsigned int mMaxRows; int mStartY; int mSlideoutX, mSlideoutY, mSlideoutW, mSlideoutH; int mSlideinX, mSlideinY, mSlideinW, mSlideinH; int mConsoleX, mConsoleY, mConsoleW, mConsoleH; int mLastTouchX, mLastTouchY; - int mSlideMultiplier; int mSlideout; SlideoutState mSlideoutState; + std::vector rConsole; + bool mRender; protected: virtual int RenderSlideout(void); -- cgit v1.2.3