performance improvments
This commit is contained in:
		
							parent
							
								
									da6dfea03e
								
							
						
					
					
						commit
						9b02312bf8
					
				|  | @ -30,6 +30,7 @@ | |||
| #include "dispatcher.h" | ||||
| #include "net/connections.h" | ||||
| #include "ui/uicontainer.h" | ||||
| #include "graphics/fonts.h" | ||||
| 
 | ||||
| Engine g_engine; | ||||
| 
 | ||||
|  | @ -52,7 +53,10 @@ void Engine::terminate() | |||
| 
 | ||||
| void Engine::run() | ||||
| { | ||||
|     std::string fpsText; | ||||
|     Size fpsTextSize; | ||||
|     Font *defaultFont = g_fonts.getDefaultFont(); | ||||
| 
 | ||||
|     m_lastFrameTicks = Platform::getTicks(); | ||||
|     int lastFpsTicks = m_lastFrameTicks; | ||||
|     int frameCount = 0; | ||||
|  | @ -60,14 +64,14 @@ void Engine::run() | |||
|     m_running = true; | ||||
| 
 | ||||
|     while(!m_stopping) { | ||||
|         m_lastFrameTicks = Platform::getTicks(); | ||||
| 
 | ||||
|         // poll platform events
 | ||||
|         Platform::poll(); | ||||
| 
 | ||||
|         // poll network events
 | ||||
|         g_connections.poll(); | ||||
| 
 | ||||
|         m_lastFrameTicks = Platform::getTicks(); | ||||
| 
 | ||||
|         // poll diaptcher tasks
 | ||||
|         g_dispatcher.poll(); | ||||
| 
 | ||||
|  | @ -80,17 +84,18 @@ void Engine::run() | |||
|                     lastFpsTicks = m_lastFrameTicks; | ||||
|                     fps = frameCount; | ||||
|                     frameCount = 0; | ||||
| 
 | ||||
|                     // update fps text
 | ||||
|                     fpsText = format("FPS: %d", fps); | ||||
|                     fpsTextSize = defaultFont->calculateTextRectSize(fpsText); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             render(); | ||||
| 
 | ||||
|             // render fps
 | ||||
|             if(m_calculateFps) { | ||||
|                 std::string fpsText = format("FPS: %d", fps); | ||||
|                 Size textSize = defaultFont->calculateTextRectSize(fpsText); | ||||
|                 defaultFont->renderText(fpsText, Point(g_graphics.getScreenSize().width() - textSize.width() - 10, 10)); | ||||
|             } | ||||
|             if(m_calculateFps) | ||||
|                 defaultFont->renderText(fpsText, Point(g_graphics.getScreenSize().width() - fpsTextSize.width() - 10, 10)); | ||||
| 
 | ||||
|             // swap buffers
 | ||||
|             Platform::swapBuffers(); | ||||
|  |  | |||
|  | @ -26,7 +26,6 @@ | |||
| #include "core/resources.h" | ||||
| #include "textures.h" | ||||
| #include "graphics.h" | ||||
| #include "textarea.h" | ||||
| 
 | ||||
| void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize) | ||||
| { | ||||
|  | @ -136,7 +135,7 @@ void Font::renderText(const std::string& text, | |||
| { | ||||
|     Size boxSize = g_graphics.getScreenSize() - startPos.toSize(); | ||||
|     Rect screenCoords(startPos, boxSize); | ||||
|     Font::renderText(text, screenCoords, ALIGN_TOP_LEFT, color); | ||||
|     renderText(text, screenCoords, ALIGN_TOP_LEFT, color); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -145,34 +144,100 @@ void Font::renderText(const std::string& text, | |||
|                     int align, | ||||
|                     const Color& color) | ||||
| { | ||||
|     TextArea textArea(this, text, screenCoords, align, color); | ||||
|     textArea.draw(); | ||||
| } | ||||
|     // prevent glitches from invalid rects
 | ||||
|     if(!screenCoords.isValid()) | ||||
|         return; | ||||
| 
 | ||||
| std::vector<Point> Font::calculateGlyphsPositions(const std::string& text, int align, Size *textBoxSize) | ||||
| { | ||||
|     int numGlyphs = text.length(); | ||||
|     std::vector<Point> glyphsPositions(numGlyphs); | ||||
|     if(numGlyphs == 0) { | ||||
|         if(textBoxSize) | ||||
|             textBoxSize->setSize(0,0); | ||||
|         return glyphsPositions; | ||||
|     int textLenght = text.length(); | ||||
| 
 | ||||
|     // map glyphs positions
 | ||||
|     Size textBoxSize; | ||||
|     const std::vector<Point>& glyphsPositions = calculateGlyphsPositions(text, align, &textBoxSize); | ||||
| 
 | ||||
|     for(int i = 0; i < textLenght; ++i) { | ||||
|         int glyph = (uchar)text[i]; | ||||
| 
 | ||||
|         // skip invalid glyphs
 | ||||
|         if(glyph < 32) | ||||
|             continue; | ||||
| 
 | ||||
|         // calculate initial glyph rect and texture coords
 | ||||
|         Rect glyphScreenCoords(glyphsPositions[i], m_glyphsSize[glyph]); | ||||
|         Rect glyphTextureCoords = m_glyphsTextureCoords[glyph]; | ||||
| 
 | ||||
|         // first translate to align position
 | ||||
|         if(align & ALIGN_BOTTOM) { | ||||
|             glyphScreenCoords.translate(0, screenCoords.height() - textBoxSize.height()); | ||||
|         } else if(align & ALIGN_VERTICAL_CENTER) { | ||||
|             glyphScreenCoords.translate(0, (screenCoords.height() - textBoxSize.height()) / 2); | ||||
|         } else { // ALIGN_TOP
 | ||||
|             // nothing to do
 | ||||
|         } | ||||
| 
 | ||||
|     std::vector<int> lineWidths(numGlyphs); | ||||
|         if(align & ALIGN_RIGHT) { | ||||
|             glyphScreenCoords.translate(screenCoords.width() - textBoxSize.width(), 0); | ||||
|         } else if(align & ALIGN_HORIZONTAL_CENTER) { | ||||
|             glyphScreenCoords.translate((screenCoords.width() - textBoxSize.width()) / 2, 0); | ||||
|         } else { // ALIGN_TOP
 | ||||
|             // nothing to do
 | ||||
|         } | ||||
| 
 | ||||
|         // translate rect to screen coords
 | ||||
|         glyphScreenCoords.translate(screenCoords.topLeft()); | ||||
| 
 | ||||
|         // only render if glyph rect is visible on screenCoords
 | ||||
|         if(!screenCoords.intersects(glyphScreenCoords)) | ||||
|             continue; | ||||
| 
 | ||||
|         // bound glyph bottomRight to screenCoords bottomRight
 | ||||
|         if(glyphScreenCoords.bottom() > screenCoords.bottom()) { | ||||
|             glyphTextureCoords.setBottom(glyphTextureCoords.bottom() + (screenCoords.bottom() - glyphScreenCoords.bottom())); | ||||
|             glyphScreenCoords.setBottom(screenCoords.bottom()); | ||||
|         } | ||||
|         if(glyphScreenCoords.right() > screenCoords.right()) { | ||||
|             glyphTextureCoords.setRight(glyphTextureCoords.right() + (screenCoords.right() - glyphScreenCoords.right())); | ||||
|             glyphScreenCoords.setRight(screenCoords.right()); | ||||
|         } | ||||
| 
 | ||||
|         // render glyph
 | ||||
|         g_graphics.drawTexturedRect(glyphScreenCoords, m_texture, glyphTextureCoords, color); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text, int align, Size *textBoxSize) const | ||||
| { | ||||
|     // for performance reasons we use statics vectors that are allocated on demand
 | ||||
|     static std::vector<Point> glyphsPositions(1); | ||||
|     static std::vector<int> lineWidths(1); | ||||
| 
 | ||||
|     int textLength = text.length(); | ||||
|     int maxLineWidth = 0; | ||||
|     int lines = 0; | ||||
|     int glyph; | ||||
|     int i; | ||||
| 
 | ||||
|     // return if there is no text
 | ||||
|     if(textLength == 0) { | ||||
|         if(textBoxSize) | ||||
|             textBoxSize->setSize(0,0); | ||||
|         return glyphsPositions; | ||||
|     } | ||||
| 
 | ||||
|     // resize glyphsPositions vector, if needed
 | ||||
|     if(textLength > (int)glyphsPositions.size()) | ||||
|         glyphsPositions.resize(textLength); | ||||
| 
 | ||||
|     // calculate lines width
 | ||||
|     if((align & ALIGN_RIGHT || align & ALIGN_HORIZONTAL_CENTER) || textBoxSize) { | ||||
|         lineWidths[0] = 0; | ||||
|         for(i = 0; i< numGlyphs; ++i) { | ||||
|         for(i = 0; i< textLength; ++i) { | ||||
|             glyph = (uchar)text[i]; | ||||
| 
 | ||||
|             if(glyph == (uchar)'\n') { | ||||
|                 lineWidths[++lines] = 0; | ||||
|                 lines++; | ||||
|                 if(lines+1 > (int)lineWidths.size()) | ||||
|                     lineWidths.resize(lines+1); | ||||
|                 lineWidths[lines] = 0; | ||||
|             } else if(glyph >= 32) { | ||||
|                 lineWidths[lines] += m_glyphsSize[glyph].width() + m_glyphSpacing.width(); | ||||
|                 maxLineWidth = std::max(maxLineWidth, lineWidths[lines]); | ||||
|  | @ -182,7 +247,7 @@ std::vector<Point> Font::calculateGlyphsPositions(const std::string& text, int a | |||
| 
 | ||||
|     Point virtualPos(0, m_topMargin); | ||||
|     lines = 0; | ||||
|     for(i = 0; i < numGlyphs; ++i) { | ||||
|     for(i = 0; i < textLength; ++i) { | ||||
|         glyph = (uchar)text[i]; | ||||
| 
 | ||||
|         // store current glyph topLeft
 | ||||
|  |  | |||
|  | @ -42,8 +42,6 @@ enum EAlign { | |||
|     ALIGN_BOTTOM_LEFT = ALIGN_BOTTOM | ALIGN_LEFT | ||||
| }; | ||||
| 
 | ||||
| class TextArea; | ||||
| 
 | ||||
| class Font | ||||
| { | ||||
| public: | ||||
|  | @ -55,22 +53,19 @@ public: | |||
|     /// Load font from file
 | ||||
|     bool load(const std::string &file); | ||||
| 
 | ||||
|     /// Simple text render starting at pos
 | ||||
|     /// Simple text render starting at startPos
 | ||||
|     void renderText(const std::string& text, | ||||
|                     const Point& startPos, | ||||
|                     const Color& color = Color::white); | ||||
| 
 | ||||
|     /** Advanced text render
 | ||||
|      * screenCoords is the rect that will be filled on the screen | ||||
|      * startRenderPosition is the postion to start rendering relative to the text rect | ||||
|      */ | ||||
|     /// Advanced text render
 | ||||
|     void renderText(const std::string& text, | ||||
|                     const Rect& screenCoords, | ||||
|                     int align = ALIGN_TOP_LEFT, | ||||
|                     const Color& color = Color::white); | ||||
| 
 | ||||
|     /// Calculate glyphs positions to use on render, also calculates textBoxSize if wanted
 | ||||
|     std::vector<Point> calculateGlyphsPositions(const std::string& text, int align = ALIGN_TOP_LEFT, Size *textBoxSize = NULL); | ||||
|     const std::vector<Point>& calculateGlyphsPositions(const std::string& text, int align = ALIGN_TOP_LEFT, Size *textBoxSize = NULL) const; | ||||
| 
 | ||||
|     /// Simulate render and calculate text size
 | ||||
|     Size calculateTextRectSize(const std::string& text); | ||||
|  |  | |||
|  | @ -48,7 +48,7 @@ void Graphics::init() | |||
| 
 | ||||
| void Graphics::terminate() | ||||
| { | ||||
| 
 | ||||
|     m_bindedTexture = TexturePtr(); | ||||
| } | ||||
| 
 | ||||
| bool Graphics::isExtensionSupported(const char *extension) | ||||
|  | @ -88,6 +88,8 @@ void Graphics::resize(const Size& size) | |||
| 
 | ||||
| void Graphics::restoreViewport() | ||||
| { | ||||
|     disableDrawing(); | ||||
| 
 | ||||
|     const int& width = m_screenSize.width(); | ||||
|     const int& height = m_screenSize.height(); | ||||
| 
 | ||||
|  | @ -116,11 +118,23 @@ void Graphics::beginRender() | |||
|     glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | ||||
|     glClear(GL_COLOR_BUFFER_BIT); | ||||
|     glLoadIdentity(); | ||||
| 
 | ||||
|     // quads is the default drawing mode
 | ||||
|     glBegin(GL_QUADS); | ||||
|     m_drawMode = DRAW_QUADS; | ||||
| } | ||||
| 
 | ||||
| void Graphics::endRender() | ||||
| { | ||||
|     // end last drawing
 | ||||
|     glEnd(); | ||||
|     m_drawMode = DRAW_NONE; | ||||
| } | ||||
| 
 | ||||
| void Graphics::disableDrawing() | ||||
| { | ||||
|     glEnd(); | ||||
|     m_drawMode = DRAW_NONE; | ||||
| } | ||||
| 
 | ||||
| void Graphics::drawTexturedRect(const Rect& screenCoords, const TexturePtr& texture, const Rect& textureCoords, const Color& color) | ||||
|  | @ -128,8 +142,6 @@ void Graphics::drawTexturedRect(const Rect& screenCoords, const TexturePtr& text | |||
|     if(screenCoords.isEmpty()) | ||||
|         return; | ||||
| 
 | ||||
|     glColor4ubv(color.rgbaPtr()); | ||||
| 
 | ||||
|     // rect correction for opengl
 | ||||
|     int right = screenCoords.right() + 1; | ||||
|     int bottom = screenCoords.bottom() + 1; | ||||
|  | @ -149,15 +161,11 @@ void Graphics::drawTexturedRect(const Rect& screenCoords, const TexturePtr& text | |||
|         textureLeft = (float)textureCoords.left() / textureSize.width(); | ||||
|     } | ||||
| 
 | ||||
|     glBindTexture(GL_TEXTURE_2D, texture->getTextureId()); | ||||
|     glBegin(GL_QUADS); | ||||
| 
 | ||||
|     bindTexture(texture, color); | ||||
|     glTexCoord2f(textureLeft,  textureTop);    glVertex2i(left,  top); | ||||
|     glTexCoord2f(textureLeft,  textureBottom); glVertex2i(left,  bottom); | ||||
|     glTexCoord2f(textureRight, textureBottom); glVertex2i(right, bottom); | ||||
|     glTexCoord2f(textureRight, textureTop);    glVertex2i(right, top); | ||||
| 
 | ||||
|     glEnd(); | ||||
| } | ||||
| 
 | ||||
| void Graphics::drawRepeatedTexturedRect(const Rect& screenCoords, const TexturePtr& texture, const Rect& textureCoords, const Color& color) | ||||
|  | @ -193,24 +201,17 @@ void Graphics::drawFilledRect(const Rect& screenCoords, const Color& color) | |||
|     if(screenCoords.isEmpty()) | ||||
|         return; | ||||
| 
 | ||||
|     glDisable(GL_TEXTURE_2D); | ||||
| 
 | ||||
|     glColor4ubv(color.rgbaPtr()); | ||||
| 
 | ||||
|     // rect correction for opengl
 | ||||
|     int right = screenCoords.right() + 1; | ||||
|     int bottom = screenCoords.bottom() + 1; | ||||
|     int top = screenCoords.top(); | ||||
|     int left = screenCoords.left(); | ||||
| 
 | ||||
|     glBegin(GL_QUADS); | ||||
|     bindColor(color); | ||||
|     glVertex2i(left,  top); | ||||
|     glVertex2i(left,  bottom); | ||||
|     glVertex2i(right, bottom); | ||||
|     glVertex2i(right, top); | ||||
|     glEnd(); | ||||
| 
 | ||||
|     glEnable(GL_TEXTURE_2D); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -219,17 +220,14 @@ void Graphics::drawBoundingRect(const Rect& screenCoords, const Color& color, in | |||
|     if(2 * innerLineWidth > screenCoords.height() || screenCoords.isEmpty()) | ||||
|         return; | ||||
| 
 | ||||
|     glDisable(GL_TEXTURE_2D); | ||||
| 
 | ||||
|     glColor4ubv(color.rgbaPtr()); | ||||
| 
 | ||||
|     // rect correction for opengl
 | ||||
|     int right = screenCoords.right()+1; | ||||
|     int bottom = screenCoords.bottom()+1; | ||||
|     int top = screenCoords.top(); | ||||
|     int left = screenCoords.left(); | ||||
| 
 | ||||
|     glBegin(GL_QUADS); | ||||
|     bindColor(color); | ||||
| 
 | ||||
|     // top line
 | ||||
|     glVertex2i(left,  top); | ||||
|     glVertex2i(left,  top + innerLineWidth); | ||||
|  | @ -253,7 +251,40 @@ void Graphics::drawBoundingRect(const Rect& screenCoords, const Color& color, in | |||
|     glVertex2i(right                 , bottom - innerLineWidth); | ||||
|     glVertex2i(right - innerLineWidth, bottom - innerLineWidth); | ||||
|     glVertex2i(right - innerLineWidth, top + innerLineWidth); | ||||
|     glEnd(); | ||||
| 
 | ||||
|     glEnable(GL_TEXTURE_2D); | ||||
| } | ||||
| 
 | ||||
| void Graphics::bindColor(const Color& color) | ||||
| { | ||||
|     // switch drawing to colored quads
 | ||||
|     if(m_drawMode != DRAW_COLOR_QUADS || m_bindedColor != color) { | ||||
|         if(m_drawMode != DRAW_NONE) | ||||
|             glEnd(); | ||||
|         glDisable(GL_TEXTURE_2D); | ||||
|         if(m_bindedColor != color) { | ||||
|             glColor4ubv(color.rgbaPtr()); | ||||
|             m_bindedColor = color; | ||||
|         } | ||||
|         glBegin(GL_QUADS); | ||||
|         m_drawMode = DRAW_COLOR_QUADS; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Graphics::bindTexture(const TexturePtr& texture, const Color& color) | ||||
| { | ||||
|     // switch drawing to textured quads
 | ||||
|     if(m_drawMode != DRAW_TEXTURE_QUADS || m_bindedTexture != texture) { | ||||
|         if(m_drawMode != DRAW_NONE) | ||||
|             glEnd(); | ||||
|         glEnable(GL_TEXTURE_2D); | ||||
|         if(m_bindedTexture != texture) { | ||||
|             glBindTexture(GL_TEXTURE_2D, texture->getTextureId()); | ||||
|             m_bindedTexture = texture; | ||||
|         } | ||||
|         if(m_bindedColor != color) { | ||||
|             glColor4ubv(color.rgbaPtr()); | ||||
|             m_bindedColor = color; | ||||
|         } | ||||
|         glBegin(GL_QUADS); | ||||
|         m_drawMode = DRAW_TEXTURE_QUADS; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -30,8 +30,17 @@ | |||
| 
 | ||||
| class Graphics | ||||
| { | ||||
|     enum EDrawMode { | ||||
|         DRAW_NONE = 0, | ||||
|         DRAW_QUADS = 1, | ||||
|         DRAW_TEXTURE = 2, | ||||
|         DRAW_COLORED = 4, | ||||
|         DRAW_COLOR_QUADS = DRAW_QUADS | DRAW_COLORED, | ||||
|         DRAW_TEXTURE_QUADS = DRAW_QUADS | DRAW_TEXTURE | DRAW_COLORED | ||||
|     }; | ||||
| 
 | ||||
| public: | ||||
|     Graphics() { } | ||||
|     Graphics() : m_drawMode(DRAW_NONE) { } | ||||
| 
 | ||||
|     /// Initialize graphics
 | ||||
|     void init(); | ||||
|  | @ -56,13 +65,23 @@ public: | |||
| 
 | ||||
|     const Size& getScreenSize() const { return m_screenSize; } | ||||
| 
 | ||||
|     void disableDrawing(); | ||||
|     void enableDrawing(); | ||||
| 
 | ||||
|     void drawTexturedRect(const Rect& screenCoords, const TexturePtr& texture, const Rect& textureCoords = Rect(), const Color& color = Color::white); | ||||
|     void drawRepeatedTexturedRect(const Rect& screenCoords, const TexturePtr& texture, const Rect& textureCoords, const Color& color = Color::white); | ||||
|     void drawFilledRect(const Rect& screenCoords, const Color& color); | ||||
|     void drawBoundingRect(const Rect& screenCoords, const Color& color = Color::green, int innerLineWidth = 1); | ||||
| 
 | ||||
| private: | ||||
|     void bindTexture(const TexturePtr& texture, const Color& color = Color::white); | ||||
|     void bindColor(const Color& color); | ||||
| 
 | ||||
|     TexturePtr m_bindedTexture; | ||||
|     Color m_bindedColor; | ||||
|     Size m_screenSize; | ||||
|     EDrawMode m_drawMode; | ||||
|     EDrawMode m_lastDrawMode; | ||||
| }; | ||||
| 
 | ||||
| extern Graphics g_graphics; | ||||
|  |  | |||
|  | @ -82,22 +82,24 @@ void TextArea::draw() | |||
| 
 | ||||
| void TextArea::recalculate() | ||||
| { | ||||
|     // prevent glitches from invalid rects
 | ||||
|     if(!m_screenCoords.isValid()) | ||||
|         return; | ||||
| 
 | ||||
|     int textLenght = m_text.length(); | ||||
| 
 | ||||
|     m_glyphsCoords.clear(); | ||||
|     m_glyphsTexCoords.clear(); | ||||
|     m_glyphsCoords.resize(textLenght); | ||||
|     m_glyphsTexCoords.resize(textLenght); | ||||
|     // prevent glitches
 | ||||
|     if(!m_screenCoords.isValid() || !m_font) | ||||
|         return; | ||||
| 
 | ||||
|     // map glyphs positions
 | ||||
|     Size textBoxSize; | ||||
|     std::vector<Point> glyphsPositions = m_font->calculateGlyphsPositions(m_text, m_align, &textBoxSize); | ||||
|     const std::vector<Point>& glyphsPositions = m_font->calculateGlyphsPositions(m_text, m_align, &textBoxSize); | ||||
|     const Rect *glyphsTextureCoords = m_font->getGlyphsTextureCoords(); | ||||
|     const Size *glyphsSize = m_font->getGlyphsSize(); | ||||
|     int glyph; | ||||
| 
 | ||||
|     // resize just on demand
 | ||||
|     if(textLenght > (int)m_glyphsCoords.size()) { | ||||
|         m_glyphsCoords.resize(textLenght); | ||||
|         m_glyphsTexCoords.resize(textLenght); | ||||
|     } | ||||
| 
 | ||||
|     // readjust start view area based on cursor position
 | ||||
|     if(m_cursorPos >= 0 && textLenght > 0) { | ||||
|  | @ -111,7 +113,7 @@ void TextArea::recalculate() | |||
|         { | ||||
|             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]; // glyph of the element before cursor
 | ||||
|             glyph = (uchar)m_text[pos]; // glyph of the element before cursor
 | ||||
|             Rect glyphRect(glyphsPositions[pos], glyphsSize[glyph]); | ||||
| 
 | ||||
|             // if the cursor is not on the previus rendered virtual rect we need to update it
 | ||||
|  | @ -148,8 +150,8 @@ void TextArea::recalculate() | |||
|     m_drawArea.setBottom(m_screenCoords.bottom()); | ||||
| 
 | ||||
|     for(int i = 0; i < textLenght; ++i) { | ||||
|         int glyph = (uchar)m_text[i]; | ||||
|         m_glyphsCoords[i] = Rect(); | ||||
|         glyph = (uchar)m_text[i]; | ||||
|         m_glyphsCoords[i].clear(); | ||||
| 
 | ||||
|         // skip invalid glyphs
 | ||||
|         if(glyph < 32) | ||||
|  | @ -218,34 +220,43 @@ void TextArea::recalculate() | |||
| 
 | ||||
| void TextArea::setFont(Font* font) | ||||
| { | ||||
|     if(m_font != font) { | ||||
|         m_font = font; | ||||
|         recalculate(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void TextArea::setText(const std::string& text) | ||||
| { | ||||
|     if(m_text != text) { | ||||
|         m_text = text; | ||||
|         if(m_cursorPos >= 0) { | ||||
|             m_cursorPos = 0; | ||||
|             m_cursorTicks = g_engine.getLastFrameTicks(); | ||||
|         } | ||||
|         recalculate(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void TextArea::setScreenCoords(Rect screenCoords) | ||||
| void TextArea::setScreenCoords(const Rect& screenCoords) | ||||
| { | ||||
|     if(screenCoords != m_screenCoords) { | ||||
|         m_screenCoords = screenCoords; | ||||
|         recalculate(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void TextArea::setAlign(int align) | ||||
| { | ||||
|     if(m_align != align) { | ||||
|         m_align = align; | ||||
|         recalculate(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void TextArea::setCursorPos(int pos) | ||||
| { | ||||
|     if(pos != m_cursorPos) { | ||||
|         if(pos < 0) | ||||
|             m_cursorPos = 0; | ||||
|         else if((uint)pos >= m_text.length()) | ||||
|  | @ -253,6 +264,7 @@ void TextArea::setCursorPos(int pos) | |||
|         else | ||||
|             m_cursorPos = pos; | ||||
|         recalculate(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void TextArea::enableCursor(bool enable) | ||||
|  |  | |||
|  | @ -42,7 +42,7 @@ public: | |||
| 
 | ||||
|     void setFont(Font *font); | ||||
|     void setText(const std::string& text); | ||||
|     void setScreenCoords(Rect screenCoords); | ||||
|     void setScreenCoords(const Rect& screenCoords); | ||||
|     void setAlign(int align); | ||||
|     void setColor(const Color& color) { m_color = color; } | ||||
|     void setCursorPos(int pos); | ||||
|  | @ -55,6 +55,7 @@ public: | |||
| 
 | ||||
|     const std::string& getText() const { return m_text; } | ||||
| 
 | ||||
|     Font *getFont() const { return m_font; } | ||||
|     int getTextPos(Point pos); | ||||
| 
 | ||||
| private: | ||||
|  | @ -76,4 +77,6 @@ private: | |||
|     std::vector<Rect> m_glyphsTexCoords; | ||||
| }; | ||||
| 
 | ||||
| typedef boost::shared_ptr<TextArea> TextAreaPtr; | ||||
| 
 | ||||
| #endif // TEXTAREA_H
 | ||||
|  |  | |||
|  | @ -25,7 +25,7 @@ | |||
| #include "uielement.h" | ||||
| #include "uiskins.h" | ||||
| #include "uielementskin.h" | ||||
| #include <graphics/graphics.h> | ||||
| #include "graphics/graphics.h" | ||||
| 
 | ||||
| UIElement::UIElement(UI::EElementType type) : | ||||
|     UILayout(), | ||||
|  | @ -35,9 +35,7 @@ UIElement::UIElement(UI::EElementType type) : | |||
|     m_enabled(true), | ||||
|     m_focused(false) | ||||
| { | ||||
|     // set default skin
 | ||||
|     if(type > UI::Container) | ||||
|         setSkin(g_uiSkins.getElementSkin(type)); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| bool UIElement::setSkin(const std::string& skinName) | ||||
|  | @ -48,10 +46,11 @@ bool UIElement::setSkin(const std::string& skinName) | |||
| 
 | ||||
| void UIElement::setSkin(UIElementSkin* skin) | ||||
| { | ||||
|     m_skin = skin; | ||||
|     if(skin && !getRect().isValid()) { | ||||
|         setSize(skin->getDefaultSize()); | ||||
|         skin->onSkinApply(this); | ||||
|     } | ||||
|     m_skin = skin; | ||||
| } | ||||
| 
 | ||||
| void UIElement::render() | ||||
|  |  | |||
|  | @ -40,6 +40,7 @@ public: | |||
|     virtual ~UIElementSkin() { } | ||||
| 
 | ||||
|     virtual void load(const YAML::Node& node); | ||||
|     virtual void onSkinApply(UIElement *element) { } | ||||
|     virtual void draw(UIElement *element); | ||||
| 
 | ||||
|     const std::string& getName() const { return m_name; } | ||||
|  |  | |||
|  | @ -28,8 +28,6 @@ | |||
| #include "prerequisites.h" | ||||
| #include "uielement.h" | ||||
| 
 | ||||
| class Font; | ||||
| 
 | ||||
| class UILabel : public UIElement | ||||
| { | ||||
| public: | ||||
|  |  | |||
|  | @ -50,9 +50,13 @@ UIElementPtr UILoader::createElementFromId(const std::string& id) | |||
|         element = UIElementPtr(new UITextEdit); | ||||
|     } | ||||
| 
 | ||||
|     if(element) | ||||
|     if(element) { | ||||
|         element->setId(elementId); | ||||
| 
 | ||||
|         // apply default skin
 | ||||
|         element->setSkin(g_uiSkins.getElementSkin(element->getElementType())); | ||||
|     } | ||||
| 
 | ||||
|     return element; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -29,8 +29,6 @@ | |||
| UITextEdit::UITextEdit() : | ||||
|     UIElement(UI::TextEdit) | ||||
| { | ||||
|     UITextEditSkin *skin = static_cast<UITextEditSkin*>(getSkin()); | ||||
|     m_textArea.setFont(skin->getFont()); | ||||
|     m_textArea.enableCursor(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -40,7 +40,6 @@ public: | |||
| 
 | ||||
|     void setText(const std::string& text); | ||||
|     const std::string& getText() const { return m_textArea.getText(); } | ||||
| 
 | ||||
|     TextArea& getTextArea() { return m_textArea; } | ||||
| 
 | ||||
|     void onLayoutRectChange(const Rect& rect); | ||||
|  |  | |||
|  | @ -46,6 +46,12 @@ void UITextEditSkin::load(const YAML::Node& node) | |||
|         m_textMargin = 2; | ||||
| } | ||||
| 
 | ||||
| void UITextEditSkin::onSkinApply(UIElement* element) | ||||
| { | ||||
|     UITextEdit *textEdit = static_cast<UITextEdit*>(element); | ||||
|     textEdit->getTextArea().setFont(m_font); | ||||
| } | ||||
| 
 | ||||
| void UITextEditSkin::draw(UIElement* element) | ||||
| { | ||||
|     UIElementSkin::draw(element); | ||||
|  |  | |||
|  | @ -38,6 +38,7 @@ public: | |||
|         UIElementSkin(name, UI::TextEdit) { } | ||||
| 
 | ||||
|     void load(const YAML::Node& node); | ||||
|     void onSkinApply(UIElement *element); | ||||
|     void draw(UIElement *element); | ||||
| 
 | ||||
|     Font *getFont() const { return m_font; } | ||||
|  |  | |||
|  | @ -64,6 +64,7 @@ public: | |||
|     inline T width() const { return  x2 - x1 + 1; } | ||||
|     inline T height() const { return  y2 - y1 + 1; } | ||||
|     inline TSize<T> size() const { return TSize<T>(width(), height()); } | ||||
|     inline void clear() { x1 = y1 = 0; x2 = y2 = -1; } | ||||
| 
 | ||||
|     inline void setLeft(T pos) { x1 = pos; } | ||||
|     inline void setTop(T pos) { y1 = pos; } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Eduardo Bart
						Eduardo Bart