Add word wrap to console output and fix scrolling in console
Change-Id: Ibcf89952ee1391350c715f1ec82cf0cdb9b0ca7d
diff --git a/gui/console.cpp b/gui/console.cpp
index 5d0ed3e..51ad21e 100644
--- a/gui/console.cpp
+++ b/gui/console.cpp
@@ -117,7 +117,9 @@
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 @@
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 @@
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 @@
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 @@
}
// 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 @@
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 f8a4e8c..4942cd7 100644
--- a/gui/objects.hpp
+++ b/gui/objects.hpp
@@ -339,15 +339,17 @@
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<std::string> rConsole;
+ bool mRender;
protected:
virtual int RenderSlideout(void);
diff --git a/minuitwrp/graphics.c b/minuitwrp/graphics.c
index ddff571..3a35c58 100644
--- a/minuitwrp/graphics.c
+++ b/minuitwrp/graphics.c
@@ -311,6 +311,30 @@
return total;
}
+int gr_maxExW(const char *s, void* font, int max_width)
+{
+ GRFont* fnt = (GRFont*) font;
+ int total = 0;
+ unsigned pos;
+ unsigned off;
+
+ if (!fnt) fnt = gr_font;
+
+ while ((off = *s++))
+ {
+ off -= 32;
+ if (off < 96) {
+ max_width -= (fnt->offset[off+1] - fnt->offset[off]);
+ if (max_width > 0) {
+ total++;
+ } else {
+ return total;
+ }
+ }
+ }
+ return total;
+}
+
unsigned character_width(const char *s, void* pFont)
{
GRFont *font = (GRFont*) pFont;
diff --git a/minuitwrp/minui.h b/minuitwrp/minui.h
index bbdfdfb..cf90532 100644
--- a/minuitwrp/minui.h
+++ b/minuitwrp/minui.h
@@ -39,6 +39,7 @@
static inline int gr_text(int x, int y, const char *s) { return gr_textEx(x, y, s, NULL); }
int gr_measureEx(const char *s, void* font);
static inline int gr_measure(const char *s) { return gr_measureEx(s, NULL); }
+int gr_maxExW(const char *s, void* font, int max_width);
int gr_getFontDetails(void* font, unsigned* cheight, unsigned* maxwidth);
static inline void gr_font_size(int *x, int *y) { gr_getFontDetails(NULL, (unsigned*) y, (unsigned*) x); }