diff --git a/modules/core/core.otmod b/modules/core/core.otmod index 27229214..ad5566d8 100644 --- a/modules/core/core.otmod +++ b/modules/core/core.otmod @@ -14,6 +14,7 @@ Module require 'util' require 'widget' require 'messagebox' + require 'dispatcher' rootWidget = getRootWidget() return true diff --git a/modules/core/dispatcher.lua b/modules/core/dispatcher.lua new file mode 100644 index 00000000..ef8a3baf --- /dev/null +++ b/modules/core/dispatcher.lua @@ -0,0 +1,28 @@ +local eventId = 1 +local events = { } +local orig = { scheduleEvent = scheduleEvent, + addEvent = addEvent } + +-- fix original scheduleEvent +function scheduleEvent(func, delay) + eventId = eventId + 1 + local id = eventId + 1 + local function proxyFunc() + func() + table[id] = nil + end + table[id] = proxyFunc + orig.scheduleEvent(proxyFunc, delay) +end + +-- fix original addEvent +function addEvent(func) + eventId = eventId + 1 + local id = eventId + 1 + local function proxyFunc() + func() + table[id] = nil + end + table[id] = proxyFunc + orig.addEvent(proxyFunc) +end \ No newline at end of file diff --git a/modules/core_ui/buttons.otui b/modules/core_ui/buttons.otui index c71f04b6..17ed10fd 100644 --- a/modules/core_ui/buttons.otui +++ b/modules/core_ui/buttons.otui @@ -1,6 +1,6 @@ Button < UIButton font: helvetica-11px-bold - color: 240 173 77 255 + font-color: 240 173 77 size: 106 24 border-image: source: /core_ui/images/button.png diff --git a/modules/core_ui/panels.otui b/modules/core_ui/panels.otui index 37cae238..29f51bc9 100644 --- a/modules/core_ui/panels.otui +++ b/modules/core_ui/panels.otui @@ -5,7 +5,8 @@ FlatPanel < Panel source: /core_ui/images/panel_flat.png border: 4 -RoundedGridPanel < Panel +RoundedPanel < Panel + color: 255 255 255 192 border-image: source: /core_ui/images/panel_rounded.png border: 4 diff --git a/modules/core_ui/windows.otui b/modules/core_ui/windows.otui index 2e84bf64..1b671237 100644 --- a/modules/core_ui/windows.otui +++ b/modules/core_ui/windows.otui @@ -1,5 +1,5 @@ Window < UIWindow - size: 200 100 + size: 200 200 head: height: 20 border-image: diff --git a/modules/gfx/gfx.lua b/modules/gfx/gfx.lua new file mode 100644 index 00000000..c112776a --- /dev/null +++ b/modules/gfx/gfx.lua @@ -0,0 +1,26 @@ +GFX = { } + +function GFX.fadeIn(widget, time, elapsed) + if not elapsed then elapsed = 0 end + if not time then time = 750 end + widget.opacity = math.min((255*elapsed)/time, 255) + if elapsed < time then + scheduleEvent(function() + GFX.fadeIn(widget, time, elapsed + 30) + end, 30) + end +end + +function GFX.fadeOut(widget, time, elapsed) + if not elapsed then elapsed = 0 end + if not time then time = 750 end + widget.opacity = (255*(time - elapsed))/time + if elapsed < time then + scheduleEvent(function() + GFX.fadeOut(widget, time, elapsed + 30) + end, 30) + else + widget:destroy() + end +end + diff --git a/modules/gfx/gfx.otmod b/modules/gfx/gfx.otmod new file mode 100644 index 00000000..4b0b43c9 --- /dev/null +++ b/modules/gfx/gfx.otmod @@ -0,0 +1,15 @@ +Module + name: gfx + description: Contains utilities for generating graphics effects + author: OTClient team + website: https://github.com/edubart/otclient + version: 0.2 + autoLoad: true + dependencies: + - core + + onLoad: | + require 'gfx' + return true + + diff --git a/modules/mainmenu/ui/entergamewindow.otui b/modules/mainmenu/ui/entergamewindow.otui index 54e101d7..b7d0c6f4 100644 --- a/modules/mainmenu/ui/entergamewindow.otui +++ b/modules/mainmenu/ui/entergamewindow.otui @@ -50,4 +50,4 @@ MainWindow anchors.bottom: parent.bottom margin.bottom: 16 margin.right: 16 - onClick: function(self) self.parent:destroy() end + onClick: function(self) GFX.fadeOut(self.parent) end diff --git a/modules/mainmenu/ui/mainmenu.otui b/modules/mainmenu/ui/mainmenu.otui index 17eba56c..51aaeef3 100644 --- a/modules/mainmenu/ui/mainmenu.otui +++ b/modules/mainmenu/ui/mainmenu.otui @@ -10,7 +10,7 @@ Panel smooth: true anchors.fill: parent - RoundedGridPanel + RoundedPanel id: mainMenu size: 144 162 anchors.left: parent.left @@ -23,7 +23,10 @@ Panel anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter margin.top: 18 - onClick: rootWidget:addChild(loadUI("/mainmenu/ui/entergamewindow.otui")) + onClick: | + local enterGameWindow = loadUI("/mainmenu/ui/entergamewindow.otui") + rootWidget:addChild(enterGameWindow) + GFX.fadeIn(enterGameWindow) MenuButton text: Options diff --git a/src/framework/graphics/animatedtexture.cpp b/src/framework/graphics/animatedtexture.cpp index 65c50541..e9cc1660 100644 --- a/src/framework/graphics/animatedtexture.cpp +++ b/src/framework/graphics/animatedtexture.cpp @@ -28,8 +28,6 @@ AnimatedTexture::AnimatedTexture(int width, int height, int channels, int numFra AnimatedTexture::~AnimatedTexture() { - g_graphics.disableDrawing(); - glDeleteTextures(m_numFrames, m_framesTextureId); delete[] m_framesTextureId; delete[] m_framesDelay; @@ -38,8 +36,6 @@ AnimatedTexture::~AnimatedTexture() void AnimatedTexture::enableBilinearFilter() { - g_graphics.disableDrawing(); - for(int i=0;i 0) { rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width(), @@ -175,4 +178,6 @@ void BorderImage::draw(const Rect& screenCoords) screenCoords.top() + m_topRightCornerTexCoords.height() + centerSize.height(), m_bottomRightCornerTexCoords.size()); g_graphics.drawTexturedRect(rectCoords, m_texture, m_bottomRightCornerTexCoords); + + g_graphics.stopDrawing(); } \ No newline at end of file diff --git a/src/framework/graphics/font.cpp b/src/framework/graphics/font.cpp index dedc99b0..30d33ad6 100644 --- a/src/framework/graphics/font.cpp +++ b/src/framework/graphics/font.cpp @@ -62,6 +62,10 @@ void Font::renderText(const std::string& text, Size textBoxSize; const std::vector& glyphsPositions = calculateGlyphsPositions(text, align, &textBoxSize); + g_graphics.bindColor(color); + g_graphics.bindTexture(m_texture); + g_graphics.startDrawing(); + for(int i = 0; i < textLenght; ++i) { int glyph = (uchar)text[i]; @@ -122,8 +126,12 @@ void Font::renderText(const std::string& text, } // render glyph - g_graphics.drawTexturedRect(glyphScreenCoords, m_texture, glyphTextureCoords, color); + g_graphics.drawTexturedRect(glyphScreenCoords, m_texture, glyphTextureCoords); } + + g_graphics.stopDrawing(); + + g_graphics.bindColor(Color::white); } const std::vector& Font::calculateGlyphsPositions(const std::string& text, diff --git a/src/framework/graphics/framebuffer.cpp b/src/framework/graphics/framebuffer.cpp index 0d82824c..4eef35ce 100644 --- a/src/framework/graphics/framebuffer.cpp +++ b/src/framework/graphics/framebuffer.cpp @@ -13,8 +13,6 @@ PFNGLCHECKFRAMEBUFFERSTATUSPROC oglCheckFramebufferStatus = 0; FrameBuffer::FrameBuffer(int width, int height) { - g_graphics.disableDrawing(); - m_fbo = 0; m_width = width; m_height = height; @@ -68,8 +66,6 @@ FrameBuffer::FrameBuffer(int width, int height) FrameBuffer::~FrameBuffer() { - g_graphics.disableDrawing(); - glDeleteTextures(1, &m_fboTexture); if(m_fbo) oglDeleteFramebuffers(1, &m_fbo); @@ -77,8 +73,6 @@ FrameBuffer::~FrameBuffer() void FrameBuffer::bind() { - g_graphics.disableDrawing(); - if(!m_fallbackOldImp) { // bind framebuffer oglBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo); @@ -101,8 +95,6 @@ void FrameBuffer::bind() void FrameBuffer::unbind() { - g_graphics.disableDrawing(); - if(!m_fallbackOldImp) { // bind back buffer again oglBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); @@ -127,9 +119,6 @@ void FrameBuffer::unbind() void FrameBuffer::draw(int x, int y, int width, int height) { - g_graphics.disableDrawing(); - - glEnable(GL_TEXTURE_2D); glColor4ubv(Color::white.rgbaPtr()); glBindTexture(GL_TEXTURE_2D, m_fboTexture); glBegin(GL_QUADS); diff --git a/src/framework/graphics/graphics.cpp b/src/framework/graphics/graphics.cpp index 0dba2dbe..61db5863 100644 --- a/src/framework/graphics/graphics.cpp +++ b/src/framework/graphics/graphics.cpp @@ -10,13 +10,11 @@ Graphics g_graphics; void Graphics::init() { - m_drawMode = DRAW_NONE; - // setup opengl glEnable(GL_ALPHA_TEST); // enable alpha by default glAlphaFunc(GL_GREATER, 0.0f); // default alpha func glDisable(GL_DEPTH_TEST); // we are rendering 2D only, we don't need depth buffer - //glEnable(GL_TEXTURE_2D); // enable textures by default + glEnable(GL_TEXTURE_2D); // enable textures by default glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glShadeModel(GL_SMOOTH); glEnable(GL_BLEND); @@ -25,6 +23,10 @@ void Graphics::init() logInfo("GPU ", glGetString(GL_RENDERER)); logInfo("OpenGL ", glGetString(GL_VERSION)); + + m_drawing = false; + bindColor(Color::white); + m_opacity = 255; } void Graphics::terminate() @@ -69,8 +71,6 @@ void Graphics::resize(const Size& size) void Graphics::restoreViewport() { - disableDrawing(); - const int& width = m_screenSize.width(); const int& height = m_screenSize.height(); @@ -98,35 +98,16 @@ void Graphics::beginRender() { glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); - - // bind white color by default - glColor4ubv(Color::white.rgbaPtr()); - m_boundColor = Color::white; } void Graphics::endRender() { - disableDrawing(); - - // clear any bound texture - m_boundTexture.reset(); -} - -void Graphics::disableDrawing() -{ - if(m_drawMode != DRAW_NONE) { - glEnd(); - m_drawMode = DRAW_NONE; - - m_boundTexture.reset(); - glColor4ubv(Color::white.rgbaPtr()); - } + assert(!m_drawing); } void Graphics::drawTexturedRect(const Rect& screenCoords, const TexturePtr& texture, - const Rect& textureCoords, - const Color& color) + const Rect& textureCoords) { if(screenCoords.isEmpty() || textureCoords.isEmpty()) return; @@ -150,21 +131,33 @@ void Graphics::drawTexturedRect(const Rect& screenCoords, textureLeft = (float)textureCoords.left() / textureSize.width(); } - bindTexture(texture, color); + if(!m_drawing) { + bindTexture(texture); + glBegin(GL_QUADS); + } + glTexCoord2f(textureLeft, textureTop); glVertex2i(left, top); glTexCoord2f(textureLeft, textureBottom); glVertex2i(left, bottom); glTexCoord2f(textureRight, textureBottom); glVertex2i(right, bottom); glTexCoord2f(textureRight, textureTop); glVertex2i(right, top); + + if(!m_drawing) + glEnd(); + } void Graphics::drawRepeatedTexturedRect(const Rect& screenCoords, const TexturePtr& texture, - const Rect& textureCoords, - const Color& color) + const Rect& textureCoords) { if(screenCoords.isEmpty() || textureCoords.isEmpty()) return; + if(!m_drawing) { + bindTexture(texture); + startDrawing(); + } + // render many repeated texture rects Rect virtualScreenCoords(0,0,screenCoords.size()); for(int y = 0; y <= virtualScreenCoords.height(); y += textureCoords.height()) { @@ -185,14 +178,19 @@ void Graphics::drawRepeatedTexturedRect(const Rect& screenCoords, } partialCoords.translate(screenCoords.topLeft()); - drawTexturedRect(partialCoords, texture, partialTextureCoords, color); + drawTexturedRect(partialCoords, texture, partialTextureCoords); } } + + if(!m_drawing) + stopDrawing(); } void Graphics::drawFilledRect(const Rect& screenCoords, const Color& color) { + assert(!m_drawing); + if(screenCoords.isEmpty()) return; @@ -202,11 +200,18 @@ void Graphics::drawFilledRect(const Rect& screenCoords, int top = screenCoords.top(); int left = screenCoords.left(); - bindColor(color); + + glColor4ubv(color.rgbaPtr()); + glDisable(GL_TEXTURE_2D); + glBegin(GL_QUADS); + glVertex2i(left, top); glVertex2i(left, bottom); glVertex2i(right, bottom); glVertex2i(right, top); + + glEnd(); + glEnable(GL_TEXTURE_2D); } @@ -214,6 +219,8 @@ void Graphics::drawBoundingRect(const Rect& screenCoords, const Color& color, int innerLineWidth) { + assert(!m_drawing); + if(2 * innerLineWidth > screenCoords.height() || screenCoords.isEmpty()) return; @@ -223,7 +230,9 @@ void Graphics::drawBoundingRect(const Rect& screenCoords, int top = screenCoords.top(); int left = screenCoords.left(); - bindColor(color); + glColor4ubv(color.rgbaPtr()); + glDisable(GL_TEXTURE_2D); + glBegin(GL_QUADS); // top line glVertex2i(left, top); @@ -248,40 +257,34 @@ void Graphics::drawBoundingRect(const Rect& screenCoords, glVertex2i(right , bottom - innerLineWidth); glVertex2i(right - innerLineWidth, bottom - innerLineWidth); glVertex2i(right - innerLineWidth, top + innerLineWidth); + + glEnd(); } void Graphics::bindColor(const Color& color) { - // switch drawing to colored quads - if(m_drawMode != DRAW_COLOR_QUADS || m_boundColor != color) { - if(m_drawMode != DRAW_NONE) - glEnd(); - glDisable(GL_TEXTURE_2D); - if(m_boundColor != color) { - glColor4ubv(color.rgbaPtr()); - m_boundColor = color; - } - glBegin(GL_QUADS); - m_drawMode = DRAW_COLOR_QUADS; - } + Color tmp = color; + tmp.setAlpha(std::min((uint8)m_opacity, color.a())); + glColor4ubv(tmp.rgbaPtr()); } -void Graphics::bindTexture(const TexturePtr& texture, const Color& color) +void Graphics::bindTexture(const TexturePtr& texture) { - // switch drawing to textured quads - if(m_drawMode != DRAW_TEXTURE_QUADS || m_boundTexture != texture || m_boundColor != color) { - if(m_drawMode != DRAW_NONE) - glEnd(); - glEnable(GL_TEXTURE_2D); - if(m_boundTexture != texture) { - glBindTexture(GL_TEXTURE_2D, texture->getTextureId()); - m_boundTexture = texture; - } - if(m_boundColor != color) { - glColor4ubv(color.rgbaPtr()); - m_boundColor = color; - } - glBegin(GL_QUADS); - m_drawMode = DRAW_TEXTURE_QUADS; + glBindTexture(GL_TEXTURE_2D, texture->getTextureId()); +} + +void Graphics::startDrawing() +{ + assert(!m_drawing); + glBegin(GL_QUADS); + m_drawing = true; +} + +void Graphics::stopDrawing() +{ + if(m_drawing) { + glEnd(); + m_drawing = false; } } + diff --git a/src/framework/graphics/graphics.h b/src/framework/graphics/graphics.h index 3e15788e..c80c2245 100644 --- a/src/framework/graphics/graphics.h +++ b/src/framework/graphics/graphics.h @@ -5,15 +5,6 @@ class Graphics { - enum DrawMode { - 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: /// Initialize default OpenGL states void init(); @@ -35,18 +26,18 @@ public: /// Called after every render void endRender(); - void disableDrawing(); + + void bindColor(const Color& color); + void bindTexture(const TexturePtr& texture); // drawing API void drawTexturedRect(const Rect& screenCoords, const TexturePtr& texture, - const Rect& textureCoords = Rect(), - const Color& color = Color::white); + const Rect& textureCoords = Rect()); void drawRepeatedTexturedRect(const Rect& screenCoords, const TexturePtr& texture, - const Rect& textureCoords, - const Color& color = Color::white); + const Rect& textureCoords); void drawFilledRect(const Rect& screenCoords, const Color& color); @@ -57,14 +48,16 @@ public: const Size& getScreenSize() const { return m_screenSize; } -private: - void bindTexture(const TexturePtr& texture, const Color& color = Color::white); - void bindColor(const Color& color); + void startDrawing(); + void stopDrawing(); + + int getOpacity() const { return m_opacity; } + void setOpacity(int opacity) { m_opacity = opacity; } - TexturePtr m_boundTexture; - Color m_boundColor; +private: + bool m_drawing; + int m_opacity; Size m_screenSize; - DrawMode m_drawMode; }; extern Graphics g_graphics; diff --git a/src/framework/graphics/texture.cpp b/src/framework/graphics/texture.cpp index 7258a877..e6fcb74a 100644 --- a/src/framework/graphics/texture.cpp +++ b/src/framework/graphics/texture.cpp @@ -11,8 +11,6 @@ Texture::Texture(int width, int height, int channels, uchar *pixels) uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int height) { - g_graphics.disableDrawing(); - // get smax texture size supported by the driver static GLint maxTexSize = -1; if(maxTexSize == -1) @@ -95,8 +93,6 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int Texture::~Texture() { - g_graphics.disableDrawing(); - // free texture from gl memory if(m_textureId) glDeleteTextures(1, &m_textureId); @@ -104,8 +100,6 @@ Texture::~Texture() void Texture::enableBilinearFilter() { - g_graphics.disableDrawing(); - // enable smooth texture glBindTexture(GL_TEXTURE_2D, m_textureId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -114,8 +108,6 @@ void Texture::enableBilinearFilter() uchar* Texture::getPixels() { - g_graphics.disableDrawing(); - // copy pixels from opengl memory uchar* pixels = new uchar[m_glSize.area()*4]; glBindTexture(GL_TEXTURE_2D, m_textureId); diff --git a/src/framework/luascript/luafunctions.cpp b/src/framework/luascript/luafunctions.cpp index b150220a..5aa7f00a 100644 --- a/src/framework/luascript/luafunctions.cpp +++ b/src/framework/luascript/luafunctions.cpp @@ -2,6 +2,7 @@ #include #include #include +#include void LuaInterface::registerFunctions() { @@ -21,6 +22,8 @@ void LuaInterface::registerFunctions() g_lua.bindClassMemberField("width", &UIWidget::getWidth, &UIWidget::setWidth); g_lua.bindClassMemberField("height", &UIWidget::getHeight, &UIWidget::setHeight); g_lua.bindClassMemberField("parent", &UIWidget::getParent, &UIWidget::setParent); + g_lua.bindClassMemberField("color", &UIWidget::getColor, &UIWidget::setColor); + g_lua.bindClassMemberField("opacity", &UIWidget::getOpacity, &UIWidget::setOpacity); g_lua.bindClassMemberField("marginTop", &UIWidget::getMarginTop, &UIWidget::setMarginTop); g_lua.bindClassMemberField("marginBottom", &UIWidget::getMarginBottom, &UIWidget::setMarginBottom); g_lua.bindClassMemberField("marginLeft", &UIWidget::getMarginLeft, &UIWidget::setMarginLeft); @@ -57,8 +60,10 @@ void LuaInterface::registerFunctions() // global functions g_lua.bindGlobalFunction("importFont", std::bind(&FontManager::importFont, &g_fonts, _1)); - g_lua.bindGlobalFunction("setDefaultFont", std::bind(&FontManager::setDefaultFont, &g_fonts, _1)); g_lua.bindGlobalFunction("importStyles", std::bind(&UIManager::importStyles, &g_ui, _1)); + g_lua.bindGlobalFunction("setDefaultFont", std::bind(&FontManager::setDefaultFont, &g_fonts, _1)); g_lua.bindGlobalFunction("loadUI", std::bind(&UIManager::loadUI, &g_ui, _1)); g_lua.bindGlobalFunction("getRootWidget", std::bind(&UIManager::getRootWidget, &g_ui)); + g_lua.bindGlobalFunction("addEvent", std::bind(&EventDispatcher::addEvent, &g_dispatcher, _1, false)); + g_lua.bindGlobalFunction("scheduleEvent", std::bind(&EventDispatcher::scheduleEvent, &g_dispatcher, _1, _2)); } diff --git a/src/framework/luascript/luavaluecasts.h b/src/framework/luascript/luavaluecasts.h index 815b5b5c..b94096d8 100644 --- a/src/framework/luascript/luavaluecasts.h +++ b/src/framework/luascript/luavaluecasts.h @@ -192,4 +192,34 @@ luavalue_cast(int index, std::function& o) { return false; } +// additional casts + + +inline void push_luavalue(const Color& v) { + g_lua.newTable(); + g_lua.pushInteger(v.r()); + g_lua.setField("r"); + g_lua.pushInteger(v.g()); + g_lua.setField("g"); + g_lua.pushInteger(v.b()); + g_lua.setField("b"); + g_lua.pushInteger(v.a()); + g_lua.setField("a"); +} + +inline bool luavalue_cast(int index, Color& o) { + if(!g_lua.isTable(index)) + return false; + + g_lua.getField("r", index); + o.setRed(g_lua.popInteger()); + g_lua.getField("g", index); + o.setGreen(g_lua.popInteger()); + g_lua.getField("b", index); + o.setBlue(g_lua.popInteger()); + g_lua.getField("a", index); + o.setAlpha(g_lua.popInteger()); + return true; +} + #endif diff --git a/src/framework/ui/uibutton.cpp b/src/framework/ui/uibutton.cpp index 5d07f311..2b644b8c 100644 --- a/src/framework/ui/uibutton.cpp +++ b/src/framework/ui/uibutton.cpp @@ -24,8 +24,9 @@ void UIButton::loadStyleFromOTML(const OTMLNodePtr& styleNode) UIWidget::loadStyleFromOTML(styleNode); for(int i=0; i<3; ++i) { - m_statesStyle[i].image = getImage(); - m_statesStyle[i].color = getColor(); + m_statesStyle[i].image = m_image; + m_statesStyle[i].color = m_color; + m_statesStyle[i].fontColor = m_fontColor; m_statesStyle[i].textTranslate = Point(0,0); } @@ -51,7 +52,8 @@ void UIButton::loadStateStyle(ButtonStateStyle& stateStyle, const OTMLNodePtr& s if(OTMLNodePtr node = stateStyleNode->get("image")) stateStyle.image = Image::loadFromOTML(node); stateStyle.textTranslate = stateStyleNode->readAt("text-translate", Point()); - stateStyle.color = stateStyleNode->readAt("color", getColor()); + stateStyle.color = stateStyleNode->readAt("font-color", m_fontColor); + stateStyle.color = stateStyleNode->readAt("color", m_color); } void UIButton::render() @@ -63,7 +65,7 @@ void UIButton::render() currentStyle.image->draw(textRect); textRect.translate(currentStyle.textTranslate); - getFont()->renderText(m_text, textRect, AlignCenter, currentStyle.color); + getFont()->renderText(m_text, textRect, AlignCenter, currentStyle.fontColor); } void UIButton::onHoverChange(UIHoverEvent& event) diff --git a/src/framework/ui/uibutton.h b/src/framework/ui/uibutton.h index 7ea93244..66572ed8 100644 --- a/src/framework/ui/uibutton.h +++ b/src/framework/ui/uibutton.h @@ -8,6 +8,7 @@ class UIButton : public UIWidget struct ButtonStateStyle { ImagePtr image; Point textTranslate; + Color fontColor; Color color; }; diff --git a/src/framework/ui/uilabel.cpp b/src/framework/ui/uilabel.cpp index 1561d8c9..a2e08950 100644 --- a/src/framework/ui/uilabel.cpp +++ b/src/framework/ui/uilabel.cpp @@ -30,7 +30,7 @@ void UILabel::loadStyleFromOTML(const OTMLNodePtr& styleNode) void UILabel::render() { - getFont()->renderText(m_text, getGeometry(), m_align, getColor()); + getFont()->renderText(m_text, getGeometry(), m_align, m_fontColor); } void UILabel::resizeToText() diff --git a/src/framework/ui/uilineedit.cpp b/src/framework/ui/uilineedit.cpp index 3804dbb7..fd95cbc3 100644 --- a/src/framework/ui/uilineedit.cpp +++ b/src/framework/ui/uilineedit.cpp @@ -37,7 +37,7 @@ void UILineEdit::render() int textLength = m_text.length(); const TexturePtr& texture = m_font->getTexture(); for(int i=0;i #include #include +#include UIWidget::UIWidget(UIWidgetType type) { @@ -18,8 +19,10 @@ UIWidget::UIWidget(UIWidgetType type) m_focusable = false; m_destroyed = false; m_updateScheduled = false; + m_opacity = 255; m_marginLeft = m_marginRight = m_marginTop = m_marginBottom = 0; m_color = Color::white; + m_fontColor = Color::white; // generate an unique id, this is need because anchored layouts find widgets by id static unsigned long id = 1; @@ -116,10 +119,18 @@ void UIWidget::loadStyleFromOTML(const OTMLNodePtr& styleNode) else if(node->tag() == "font") { setFont(g_fonts.getFont(node->value())); } + // font color + else if(node->tag() == "font-color") { + setFontColor(node->read()); + } // color else if(node->tag() == "color") { setColor(node->read()); } + // opacity + else if(node->tag() == "opacity") { + setOpacity(node->read()); + } // size else if(node->tag() == "size") { resize(node->read()); @@ -199,8 +210,16 @@ void UIWidget::render() m_image->draw(getGeometry()); for(const UIWidgetPtr& child : m_children) { - if(child->isVisible()) + if(child->isVisible()) { + int oldOpacity = g_graphics.getOpacity(); + if(child->getOpacity() < oldOpacity) + g_graphics.setOpacity(child->getOpacity()); + + g_graphics.bindColor(child->getColor()); child->render(); + + g_graphics.setOpacity(oldOpacity); + } } } diff --git a/src/framework/ui/uiwidget.h b/src/framework/ui/uiwidget.h index b8f91931..44ccf3bc 100644 --- a/src/framework/ui/uiwidget.h +++ b/src/framework/ui/uiwidget.h @@ -49,7 +49,9 @@ public: void setImage(const ImagePtr& image) { m_image = image; } virtual void setFont(const FontPtr& font) { m_font = font; } + void setOpacity(int opacity) { m_opacity = opacity; } void setColor(const Color& color) { m_color = color; } + void setFontColor(const Color& color) { m_fontColor = color; } void setMarginLeft(int margin) { m_marginLeft = margin; updateGeometry(); } void setMarginRight(int margin) { m_marginRight = margin; updateGeometry(); } void setMarginTop(int margin) { m_marginTop = margin; updateGeometry(); } @@ -86,7 +88,9 @@ public: ImagePtr getImage() const { return m_image; } FontPtr getFont() const { return m_font; } + Color getFontColor() const { return m_fontColor; } Color getColor() const { return m_color; } + int getOpacity() const { return m_opacity; } int getMarginLeft() const { return m_marginLeft; } int getMarginRight() const { return m_marginRight; } int getMarginTop() const { return m_marginTop; } @@ -164,7 +168,9 @@ protected: // basic style components used by all widgets ImagePtr m_image; FontPtr m_font; + int m_opacity; Color m_color; + Color m_fontColor; int m_marginLeft; int m_marginRight; int m_marginTop; diff --git a/src/framework/ui/uiwindow.cpp b/src/framework/ui/uiwindow.cpp index 5e2af239..b4218228 100644 --- a/src/framework/ui/uiwindow.cpp +++ b/src/framework/ui/uiwindow.cpp @@ -55,7 +55,7 @@ void UIWindow::render() headTextRect.addLeft(-m_headMargin); else if(m_titleAlign & AlignRight) headTextRect.addRight(-m_headMargin); - getFont()->renderText(m_title, headTextRect, m_titleAlign, getColor()); + m_font->renderText(m_title, headTextRect, m_titleAlign, m_fontColor); } // draw window body diff --git a/src/framework/util/color.h b/src/framework/util/color.h index 3e47fc03..adacb81e 100644 --- a/src/framework/util/color.h +++ b/src/framework/util/color.h @@ -46,17 +46,16 @@ private: inline std::ostream& operator<<(std::ostream& out, const Color& color) { - out << "Color(" << (int)color.r() << "," - << (int)color.g() << "," - << (int)color.b() << "," - << (int)color.a() << ")"; + out << (int)color.r() << " "<< (int)color.g() << " "<< (int)color.b() << " " << (int)color.a(); return out; -} +} inline std::istream& operator>>(std::istream& in, Color& color) { - int r, g, b, a; - in >> r >> g >> b >> a; + int r, g, b, a = 255; + in >> r >> g >> b; + if(!in.eof()) + in >> a; color.setRGBA(r, g, b, a); return in; } diff --git a/src/protocolgame.h b/src/protocolgame.h old mode 100755 new mode 100644 diff --git a/src/tibiaspr.h b/src/tibiaspr.h old mode 100755 new mode 100644