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;
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Point> Font::calculateGlyphsPositions(const std::string& text, int align, Size *textBoxSize)
|
||||
const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text, int align, Size *textBoxSize) const
|
||||
{
|
||||
int numGlyphs = text.length();
|
||||
std::vector<Point> glyphsPositions(numGlyphs);
|
||||
if(numGlyphs == 0) {
|
||||
if(textBoxSize)
|
||||
textBoxSize->setSize(0,0);
|
||||
return glyphsPositions;
|
||||
}
|
||||
// for performance reasons we use statics vectors that are allocated on demand
|
||||
static std::vector<Point> glyphsPositions(1);
|
||||
static std::vector<int> lineWidths(1);
|
||||
|
||||
std::vector<int> lineWidths(numGlyphs);
|
||||
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,41 +220,71 @@ 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);
|
||||
// top line
|
||||
glVertex2i(left, top);
|
||||
glVertex2i(left, top + innerLineWidth);
|
||||
glVertex2i(right, top + innerLineWidth);
|
||||
glVertex2i(right, top);
|
||||
bindColor(color);
|
||||
|
||||
// left
|
||||
glVertex2i(left, screenCoords.top() + innerLineWidth);
|
||||
glVertex2i(left, bottom - innerLineWidth);
|
||||
glVertex2i(left + innerLineWidth, bottom - innerLineWidth);
|
||||
glVertex2i(left + innerLineWidth, screenCoords.top() + innerLineWidth);
|
||||
// top line
|
||||
glVertex2i(left, top);
|
||||
glVertex2i(left, top + innerLineWidth);
|
||||
glVertex2i(right, top + innerLineWidth);
|
||||
glVertex2i(right, top);
|
||||
|
||||
// bottom line
|
||||
glVertex2i(left, bottom);
|
||||
glVertex2i(left, bottom - innerLineWidth);
|
||||
glVertex2i(right, bottom - innerLineWidth);
|
||||
glVertex2i(right, bottom);
|
||||
// left
|
||||
glVertex2i(left, screenCoords.top() + innerLineWidth);
|
||||
glVertex2i(left, bottom - innerLineWidth);
|
||||
glVertex2i(left + innerLineWidth, bottom - innerLineWidth);
|
||||
glVertex2i(left + innerLineWidth, screenCoords.top() + innerLineWidth);
|
||||
|
||||
// right line
|
||||
glVertex2i(right , top + innerLineWidth);
|
||||
glVertex2i(right , bottom - innerLineWidth);
|
||||
glVertex2i(right - innerLineWidth, bottom - innerLineWidth);
|
||||
glVertex2i(right - innerLineWidth, top + innerLineWidth);
|
||||
glEnd();
|
||||
// bottom line
|
||||
glVertex2i(left, bottom);
|
||||
glVertex2i(left, bottom - innerLineWidth);
|
||||
glVertex2i(right, bottom - innerLineWidth);
|
||||
glVertex2i(right, bottom);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
// right line
|
||||
glVertex2i(right , top + innerLineWidth);
|
||||
glVertex2i(right , bottom - innerLineWidth);
|
||||
glVertex2i(right - innerLineWidth, bottom - innerLineWidth);
|
||||
glVertex2i(right - innerLineWidth, top + innerLineWidth);
|
||||
}
|
||||
|
||||
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,41 +220,51 @@ void TextArea::recalculate()
|
|||
|
||||
void TextArea::setFont(Font* font)
|
||||
{
|
||||
m_font = font;
|
||||
recalculate();
|
||||
if(m_font != font) {
|
||||
m_font = font;
|
||||
recalculate();
|
||||
}
|
||||
}
|
||||
|
||||
void TextArea::setText(const std::string& text)
|
||||
{
|
||||
m_text = text;
|
||||
if(m_cursorPos >= 0) {
|
||||
m_cursorPos = 0;
|
||||
m_cursorTicks = g_engine.getLastFrameTicks();
|
||||
if(m_text != text) {
|
||||
m_text = text;
|
||||
if(m_cursorPos >= 0) {
|
||||
m_cursorPos = 0;
|
||||
m_cursorTicks = g_engine.getLastFrameTicks();
|
||||
}
|
||||
recalculate();
|
||||
}
|
||||
recalculate();
|
||||
}
|
||||
|
||||
void TextArea::setScreenCoords(Rect screenCoords)
|
||||
void TextArea::setScreenCoords(const Rect& screenCoords)
|
||||
{
|
||||
m_screenCoords = screenCoords;
|
||||
recalculate();
|
||||
if(screenCoords != m_screenCoords) {
|
||||
m_screenCoords = screenCoords;
|
||||
recalculate();
|
||||
}
|
||||
}
|
||||
|
||||
void TextArea::setAlign(int align)
|
||||
{
|
||||
m_align = align;
|
||||
recalculate();
|
||||
if(m_align != align) {
|
||||
m_align = 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();
|
||||
if(pos != m_cursorPos) {
|
||||
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)
|
||||
|
|
|
@ -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,8 +55,9 @@ public:
|
|||
|
||||
const std::string& getText() const { return m_text; }
|
||||
|
||||
Font *getFont() const { return m_font; }
|
||||
int getTextPos(Point pos);
|
||||
|
||||
|
||||
private:
|
||||
void recalculate();
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -48,7 +46,7 @@ void UITextEdit::onInputEvent(const InputEvent& event)
|
|||
else if(event.keycode == KC_LEFT)
|
||||
m_textArea.moveCursor(false);
|
||||
} else if(event.type == EV_MOUSE_LDOWN) {
|
||||
|
||||
|
||||
} else if(event.type == EV_MOUSE_LUP && getRect().contains(event.mousePos)) {
|
||||
m_textArea.setCursorPos(m_textArea.getTextPos(event.mousePos));
|
||||
}
|
||||
|
|
|
@ -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