From 43c9c5de7c1e6992d772953d816df6f1cd370baf Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Fri, 15 Apr 2011 12:46:30 -0300 Subject: [PATCH] text edit almost done --- src/framework/graphics/graphics.cpp | 8 ++--- src/framework/graphics/textarea.cpp | 48 +++++++++++++++++++++++------ src/framework/graphics/textarea.h | 4 +-- 3 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/framework/graphics/graphics.cpp b/src/framework/graphics/graphics.cpp index 8684929f..ee648e35 100644 --- a/src/framework/graphics/graphics.cpp +++ b/src/framework/graphics/graphics.cpp @@ -125,7 +125,7 @@ void Graphics::endRender() void Graphics::drawTexturedRect(const Rect& screenCoords, const TexturePtr& texture, const Rect& textureCoords, const Color& color) { - if(screenCoords.size().isEmpty()) + if(screenCoords.isEmpty()) return; glColor4ubv(color.rgbaPtr()); @@ -162,7 +162,7 @@ void Graphics::drawTexturedRect(const Rect& screenCoords, const TexturePtr& text void Graphics::drawRepeatedTexturedRect(const Rect& screenCoords, const TexturePtr& texture, const Rect& textureCoords, const Color& color) { - if(screenCoords.size().isEmpty()) + if(screenCoords.isEmpty()) return; // render many repeated texture rects @@ -190,7 +190,7 @@ void Graphics::drawRepeatedTexturedRect(const Rect& screenCoords, const TextureP void Graphics::drawFilledRect(const Rect& screenCoords, const Color& color) { - if(screenCoords.size().isEmpty()) + if(screenCoords.isEmpty()) return; glDisable(GL_TEXTURE_2D); @@ -216,7 +216,7 @@ void Graphics::drawFilledRect(const Rect& screenCoords, const Color& color) void Graphics::drawBoundingRect(const Rect& screenCoords, const Color& color, int innerLineWidth) { - if(2 * innerLineWidth > screenCoords.height()) + if(2 * innerLineWidth > screenCoords.height() || screenCoords.isEmpty()) return; glDisable(GL_TEXTURE_2D); diff --git a/src/framework/graphics/textarea.cpp b/src/framework/graphics/textarea.cpp index 61cc6825..44fee80a 100644 --- a/src/framework/graphics/textarea.cpp +++ b/src/framework/graphics/textarea.cpp @@ -31,6 +31,7 @@ TextArea::TextArea() : m_align(ALIGN_TOP_LEFT), m_color(Color::white), m_cursorPos(-1), + m_startRenderPos(0), m_cursorVisible(false) { } @@ -46,6 +47,7 @@ TextArea::TextArea(Font* font, m_align(align), m_color(color), m_cursorPos(-1), + m_startRenderPos(0), m_cursorVisible(false) { recalculate(); @@ -66,10 +68,9 @@ void TextArea::draw() // draw every 500ms if(ticks - m_cursorTicks <= delay) { Rect cursorRect; - if(m_cursorPos == 0) + // when cursor is at 0 or is the first visible element + if(m_cursorPos == 0 || (m_cursorPos < numGlyphs && m_glyphsCoords[m_cursorPos].topLeft() == m_drawArea.topLeft())) cursorRect = Rect(m_drawArea.left()-1, m_drawArea.top(), 1, m_font->getGlyphHeight()); - else if(m_cursorPos == numGlyphs) - cursorRect = Rect(m_glyphsCoords[m_cursorPos-1].right(), m_glyphsCoords[m_cursorPos-1].top(), 1, m_font->getGlyphHeight()); else cursorRect = Rect(m_glyphsCoords[m_cursorPos-1].right(), m_glyphsCoords[m_cursorPos-1].top(), 1, m_font->getGlyphHeight()); g_graphics.drawFilledRect(cursorRect, m_color); @@ -98,14 +99,39 @@ void TextArea::recalculate() std::vector glyphsPositions = m_font->calculateGlyphsPositions(m_text, m_align, &textBoxSize); const Rect *glyphsTextureCoords = m_font->getGlyphsTextureCoords(); const Size *glyphsSize = m_font->getGlyphsSize(); - + + // adjust start view area when cursor is enabled and has text + if(m_cursorPos >= 0 && textLenght > 0) { + // adjust when cursor reachs left + if(m_startRenderPos > m_cursorPos) { + m_startInternalPos.x = glyphsPositions[m_cursorPos].x; + m_startInternalPos.y = glyphsPositions[m_cursorPos].y - m_font->getTopMargin(); + // adjust when cursor reachs right + } else if(m_cursorPos > m_startRenderPos) { + Rect virtualRect(m_startInternalPos, m_screenCoords.size()); + int pos = m_cursorPos - 1; // element before cursor + int glyph = (uchar)m_text[pos]; + Rect glyphRect(glyphsPositions[pos], glyphsSize[glyph]); + + // if the cursor is after the start render pos, then the glyph before the cursor must visible + if(!virtualRect.contains(glyphRect.topLeft()) || !virtualRect.contains(glyphRect.bottomRight())) { + m_startInternalPos.y = std::max(glyphRect.bottom() - virtualRect.height(), 0); + m_startInternalPos.x = std::max(glyphRect.right() - virtualRect.width() + 1, 0); + } + } + } else { + m_startInternalPos = Point(0,0); + } + m_drawArea.setLeft(m_screenCoords.left()); m_drawArea.setTop(m_screenCoords.top()+m_font->getTopMargin()); m_drawArea.setRight(m_screenCoords.right()); m_drawArea.setBottom(m_screenCoords.bottom()); + m_startRenderPos = -1; for(int i = 0; i < textLenght; ++i) { int glyph = (uchar)m_text[i]; + m_glyphsCoords[i] = Rect(); // skip invalid glyphs if(glyph < 32) @@ -169,6 +195,10 @@ void TextArea::recalculate() // render glyph m_glyphsCoords[i] = glyphScreenCoords; m_glyphsTexCoords[i] = glyphTextureCoords; + + // set who was the first complete glyph rendered + if(m_startRenderPos == -1 && glyphScreenCoords.size() == glyphsSize[glyph]) + m_startRenderPos = i; } } @@ -200,12 +230,6 @@ void TextArea::setAlign(int align) recalculate(); } -void TextArea::setStartInternalPos(Point startPos) -{ - m_startInternalPos = startPos; - recalculate(); -} - void TextArea::enableCursor(bool enable) { if(enable) { @@ -213,6 +237,7 @@ void TextArea::enableCursor(bool enable) m_cursorTicks = g_engine.getLastFrameTicks(); } else m_cursorPos = -1; + recalculate(); } void TextArea::appendCharacter(char c) @@ -253,4 +278,7 @@ void TextArea::moveCursor(bool right) m_cursorTicks = g_engine.getLastFrameTicks(); } } + recalculate(); } + + diff --git a/src/framework/graphics/textarea.h b/src/framework/graphics/textarea.h index 1536a625..75a0f3b2 100644 --- a/src/framework/graphics/textarea.h +++ b/src/framework/graphics/textarea.h @@ -45,7 +45,6 @@ public: void setScreenCoords(Rect screenCoords); void setAlign(int align); void setColor(const Color& color) { m_color = color; } - void setStartInternalPos(Point startPos); void enableCursor(bool enable = true); void setCursorVisible(bool visible = true) { m_cursorVisible = visible; } @@ -64,8 +63,9 @@ private: Rect m_drawArea; int m_align; Color m_color; - Point m_startInternalPos; int m_cursorPos; + Point m_startInternalPos; + int m_startRenderPos; int m_cursorTicks; bool m_cursorVisible;