text edit improvments
This commit is contained in:
		
							parent
							
								
									5bfeee91b2
								
							
						
					
					
						commit
						da6dfea03e
					
				|  | @ -69,7 +69,7 @@ void TextArea::draw() | |||
|         if(ticks - m_cursorTicks <= delay) { | ||||
|             Rect cursorRect; | ||||
|             // 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())) | ||||
|             if(m_cursorPos == 0 || m_cursorPos == m_startRenderPos) | ||||
|                 cursorRect = Rect(m_drawArea.left()-1, m_drawArea.top(), 1, m_font->getGlyphHeight()); | ||||
|             else | ||||
|                 cursorRect = Rect(m_glyphsCoords[m_cursorPos-1].right(), m_glyphsCoords[m_cursorPos-1].top(), 1, m_font->getGlyphHeight()); | ||||
|  | @ -90,7 +90,6 @@ void TextArea::recalculate() | |||
| 
 | ||||
|     m_glyphsCoords.clear(); | ||||
|     m_glyphsTexCoords.clear(); | ||||
| 
 | ||||
|     m_glyphsCoords.resize(textLenght); | ||||
|     m_glyphsTexCoords.resize(textLenght); | ||||
| 
 | ||||
|  | @ -99,36 +98,55 @@ void TextArea::recalculate() | |||
|     std::vector<Point> 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
 | ||||
| 
 | ||||
|     // readjust start view area based on cursor position
 | ||||
|     if(m_cursorPos >= 0 && textLenght > 0) { | ||||
|         // adjust when cursor reachs left
 | ||||
|         if(m_startRenderPos > m_cursorPos) { | ||||
|         if(m_cursorPos < m_startRenderPos) // cursor is before the previuos first rendered glyph, so we need to update
 | ||||
|         { | ||||
|             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()); | ||||
|             m_startRenderPos = m_cursorPos; | ||||
|         } else if(m_cursorPos > m_startRenderPos || // cursor is after the previuos first rendered glyph
 | ||||
|                   (m_cursorPos == m_startRenderPos && textLenght == m_cursorPos)) // cursor is at the previuos rendered element, and is the last text element
 | ||||
|         { | ||||
|             Rect virtualRect(m_startInternalPos, m_screenCoords.size()); // previus rendered virtual rect
 | ||||
|             int pos = m_cursorPos - 1; // element before cursor
 | ||||
|             int glyph = (uchar)m_text[pos]; | ||||
|             int glyph = (uchar)m_text[pos]; // glyph of the element before cursor
 | ||||
|             Rect glyphRect(glyphsPositions[pos], glyphsSize[glyph]); | ||||
|              | ||||
|             // if the cursor is after the start render pos, then the glyph before the cursor must visible
 | ||||
| 
 | ||||
|             // if the cursor is not on the previus rendered virtual rect we need to update it
 | ||||
|             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); | ||||
|                 // calculate where is the first glyph visible
 | ||||
|                 Point startGlyphPos; | ||||
|                 startGlyphPos.y = std::max(glyphRect.bottom() - virtualRect.height(), 0); | ||||
|                 startGlyphPos.x = std::max(glyphRect.right() - virtualRect.width(), 0); | ||||
| 
 | ||||
|                 // find that glyph
 | ||||
|                 for(pos = 0; pos < textLenght; ++pos) { | ||||
|                     glyph = (uchar)m_text[pos]; | ||||
|                     glyphRect = Rect(glyphsPositions[pos], glyphsSize[glyph]); | ||||
|                     glyphRect.setTop(std::max(glyphRect.top() - m_font->getTopMargin() - m_font->getGlyphSpacing().height(), 0)); | ||||
|                     glyphRect.setLeft(std::max(glyphRect.left() - m_font->getGlyphSpacing().width(), 0)); | ||||
| 
 | ||||
|                     // first glyph entirely visible found
 | ||||
|                     if(glyphRect.topLeft() >= startGlyphPos) { | ||||
|                         m_startInternalPos.x = glyphsPositions[pos].x; | ||||
|                         m_startInternalPos.y = glyphsPositions[pos].y - m_font->getTopMargin(); | ||||
|                         m_startRenderPos = pos; | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } 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(); | ||||
|  | @ -195,10 +213,6 @@ 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; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -230,6 +244,17 @@ void TextArea::setAlign(int align) | |||
|     recalculate(); | ||||
| } | ||||
| 
 | ||||
| void TextArea::setCursorPos(int pos) | ||||
| { | ||||
|     if(pos < 0) | ||||
|         m_cursorPos = 0; | ||||
|     else if((uint)pos >= m_text.length()) | ||||
|         m_cursorPos = m_text.length(); | ||||
|     else | ||||
|         m_cursorPos = pos; | ||||
|     recalculate(); | ||||
| } | ||||
| 
 | ||||
| void TextArea::enableCursor(bool enable) | ||||
| { | ||||
|     if(enable) { | ||||
|  | @ -284,14 +309,21 @@ void TextArea::moveCursor(bool right) | |||
| int TextArea::getTextPos(Point pos) | ||||
| { | ||||
|     int textLength = m_text.length(); | ||||
|     dump << " get pos: " << pos << m_drawArea; | ||||
| 
 | ||||
|     // find any glyph that is actually on the
 | ||||
|     int candidatePos = -1; | ||||
|     for(int i=0;i<textLength;++i) { | ||||
|         Rect clickGlyphRect = m_glyphsCoords[i]; | ||||
|         clickGlyphRect.addTop(m_font->getTopMargin() + m_font->getGlyphSpacing().height()); | ||||
|         clickGlyphRect.addLeft(m_font->getGlyphSpacing().width()+1); | ||||
|         dump << clickGlyphRect;  | ||||
|         if(m_glyphsCoords[i].contains(pos)) | ||||
|         if(clickGlyphRect.contains(pos)) | ||||
|             return i; | ||||
|         else if(pos.y >= clickGlyphRect.top() && pos.y <= clickGlyphRect.bottom()) { | ||||
|             if(pos.x <= clickGlyphRect.left()) | ||||
|                 candidatePos = i; | ||||
|             else if(pos.x >= clickGlyphRect.right()) | ||||
|                 candidatePos = i+1; | ||||
|         } | ||||
|     } | ||||
|     return -1; | ||||
|     return candidatePos; | ||||
| } | ||||
|  |  | |||
|  | @ -45,6 +45,7 @@ public: | |||
|     void setScreenCoords(Rect screenCoords); | ||||
|     void setAlign(int align); | ||||
|     void setColor(const Color& color) { m_color = color; } | ||||
|     void setCursorPos(int pos); | ||||
|     void enableCursor(bool enable = true); | ||||
|     void setCursorVisible(bool visible = true) { m_cursorVisible = visible; } | ||||
| 
 | ||||
|  |  | |||
|  | @ -49,8 +49,8 @@ void UITextEdit::onInputEvent(const InputEvent& event) | |||
|             m_textArea.moveCursor(false); | ||||
|     } else if(event.type == EV_MOUSE_LDOWN) { | ||||
|          | ||||
|     } else if(event.type == EV_MOUSE_LUP) { | ||||
|         dump << m_textArea.getTextPos(event.mousePos); | ||||
|     } else if(event.type == EV_MOUSE_LUP && getRect().contains(event.mousePos)) { | ||||
|         m_textArea.setCursorPos(m_textArea.getTextPos(event.mousePos)); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Eduardo Bart
						Eduardo Bart