Add word wrap to console output and fix scrolling in console

Change-Id: Ibcf89952ee1391350c715f1ec82cf0cdb9b0ca7d
This commit is contained in:
Dees Troy
2014-02-26 08:52:05 -06:00
committed by Ethan Yonker
parent c62b34c3ba
commit 31218ec952
4 changed files with 77 additions and 42 deletions
+49 -41
View File
@@ -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:
+3 -1
View File
@@ -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<std::string> rConsole;
bool mRender;
protected:
virtual int RenderSlideout(void);
+24
View File
@@ -311,6 +311,30 @@ int gr_measureEx(const char *s, void* font)
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;
+1
View File
@@ -39,6 +39,7 @@ int twgr_text(int x, int y, const char *s);
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); }