From c19f3608a575136010b201ace0ee3ea89a0779ff Mon Sep 17 00:00:00 2001 From: Ykkrosh Date: Wed, 15 Dec 2004 21:24:46 +0000 Subject: [PATCH] Initial changes to GUI sprite code. (There shouldn't be any visible effects - if there are, they're bugs) This was SVN commit r1507. --- source/gui/CButton.cpp | 28 +-- source/gui/CCheckBox.cpp | 74 ++++---- source/gui/CGUI.cpp | 153 ++------------- source/gui/CGUI.h | 15 +- source/gui/CGUIScrollBarStyle.h | 34 ++-- source/gui/CGUIScrollBarVertical.cpp | 2 +- source/gui/CGUISprite.cpp | 45 +++-- source/gui/CGUISprite.h | 70 +++---- source/gui/CImage.cpp | 6 +- source/gui/CInput.cpp | 18 +- source/gui/CProgressBar.cpp | 12 +- source/gui/CText.cpp | 18 +- source/gui/GUIRenderer.cpp | 175 ++++++++++++++++++ source/gui/GUIRenderer.h | 37 ++++ source/gui/GUItext.cpp | 2 +- source/gui/GUItext.h | 6 +- source/gui/GUIutil.cpp | 12 +- source/gui/GUIutil.h | 44 +---- source/gui/IGUIButtonBehavior.cpp | 8 +- source/gui/IGUIButtonBehavior.h | 10 +- source/gui/IGUIObject.cpp | 11 +- source/gui/IGUIObject.h | 5 +- source/gui/IGUIScrollBar.cpp | 2 +- source/gui/IGUIScrollBar.h | 44 ++--- source/gui/IGUIScrollBarOwner.cpp | 4 +- source/gui/IGUIScrollBarOwner.h | 2 +- .../gui/scripting/JSInterface_IGUIObject.cpp | 38 ++-- 27 files changed, 499 insertions(+), 376 deletions(-) create mode 100644 source/gui/GUIRenderer.cpp create mode 100644 source/gui/GUIRenderer.h diff --git a/source/gui/CButton.cpp b/source/gui/CButton.cpp index 21c04381e1..19117e3c7f 100755 --- a/source/gui/CButton.cpp +++ b/source/gui/CButton.cpp @@ -20,10 +20,10 @@ CButton::CButton() AddSetting(GUIST_float, "buffer-zone"); AddSetting(GUIST_CGUIString, "caption"); AddSetting(GUIST_CStr, "font"); - AddSetting(GUIST_CStr, "sprite"); - AddSetting(GUIST_CStr, "sprite-over"); - AddSetting(GUIST_CStr, "sprite-pressed"); - AddSetting(GUIST_CStr, "sprite-disabled"); + AddSetting(GUIST_CGUISpriteInstance, "sprite"); + AddSetting(GUIST_CGUISpriteInstance, "sprite-over"); + AddSetting(GUIST_CGUISpriteInstance, "sprite-pressed"); + AddSetting(GUIST_CGUISpriteInstance, "sprite-disabled"); AddSetting(GUIST_EAlign, "text-align"); AddSetting(GUIST_EVAlign, "text-valign"); AddSetting(GUIST_CColor, "textcolor"); @@ -124,18 +124,18 @@ void CButton::Draw() { float bz = GetBufferedZ(); - CStr sprite, sprite_over, sprite_pressed, sprite_disabled; + CGUISpriteInstance sprite, sprite_over, sprite_pressed, sprite_disabled; - GUI::GetSetting(this, "sprite", sprite); - GUI::GetSetting(this, "sprite-over", sprite_over); - GUI::GetSetting(this, "sprite-pressed", sprite_pressed); - GUI::GetSetting(this, "sprite-disabled", sprite_disabled); - - DrawButton(m_CachedActualSize, - bz, + GUI::GetSetting(this, "sprite", sprite); + GUI::GetSetting(this, "sprite-over", sprite_over); + GUI::GetSetting(this, "sprite-pressed", sprite_pressed); + GUI::GetSetting(this, "sprite-disabled", sprite_disabled); + + DrawButton(m_CachedActualSize, + bz, sprite, - sprite_over, - sprite_pressed, + sprite_over, + sprite_pressed, sprite_disabled); CColor color = ChooseColor(); diff --git a/source/gui/CCheckBox.cpp b/source/gui/CCheckBox.cpp index d6903d52af..4f5ca29b94 100755 --- a/source/gui/CCheckBox.cpp +++ b/source/gui/CCheckBox.cpp @@ -15,36 +15,36 @@ using namespace std; //------------------------------------------------------------------- CCheckBox::CCheckBox() { -/* bool m_Checked; - CStr m_Font; - CStr m_Sprite; - CStr m_SpriteDisabled; - CStr m_SpriteOver; - CStr m_SpritePressed; - CStr m_Sprite2; - CStr m_Sprite2Disabled; - CStr m_Sprite2Over; - CStr m_Sprite2Pressed; - int m_SquareSide; - EAlign m_TextAlign; - CColor m_TextColor; - CColor m_TextColorDisabled; - CColor m_TextColorOver; - CColor m_TextColorPressed; - EVAlign m_TextValign; - CStr m_ToolTip; - CStr m_ToolTipStyle; +/* bool m_Checked; + CStr m_Font; + CGUISpriteInstance m_Sprite; + CGUISpriteInstance m_SpriteDisabled; + CGUISpriteInstance m_SpriteOver; + CGUISpriteInstance m_SpritePressed; + CGUISpriteInstance m_Sprite2; + CGUISpriteInstance m_Sprite2Disabled; + CGUISpriteInstance m_Sprite2Over; + CGUISpriteInstance m_Sprite2Pressed; + int m_SquareSide; + EAlign m_TextAlign; + CColor m_TextColor; + CColor m_TextColorDisabled; + CColor m_TextColorOver; + CColor m_TextColorPressed; + EVAlign m_TextValign; + CStr m_ToolTip; + CStr m_ToolTipStyle; */ AddSetting(GUIST_CGUIString, "caption"); AddSetting(GUIST_bool, "checked"); - AddSetting(GUIST_CStr, "sprite"); - AddSetting(GUIST_CStr, "sprite-over"); - AddSetting(GUIST_CStr, "sprite-pressed"); - AddSetting(GUIST_CStr, "sprite-disabled"); - AddSetting(GUIST_CStr, "sprite2"); - AddSetting(GUIST_CStr, "sprite2-over"); - AddSetting(GUIST_CStr, "sprite2-pressed"); - AddSetting(GUIST_CStr, "sprite2-disabled"); + AddSetting(GUIST_CGUISpriteInstance,"sprite"); + AddSetting(GUIST_CGUISpriteInstance,"sprite-over"); + AddSetting(GUIST_CGUISpriteInstance,"sprite-pressed"); + AddSetting(GUIST_CGUISpriteInstance,"sprite-disabled"); + AddSetting(GUIST_CGUISpriteInstance,"sprite2"); + AddSetting(GUIST_CGUISpriteInstance,"sprite2-over"); + AddSetting(GUIST_CGUISpriteInstance,"sprite2-pressed"); + AddSetting(GUIST_CGUISpriteInstance,"sprite2-disabled"); AddSetting(GUIST_int, "square-side"); // Add text @@ -123,21 +123,21 @@ void CCheckBox::Draw() bool checked; GUI::GetSetting(this, "checked", checked); - CStr sprite, sprite_over, sprite_pressed, sprite_disabled; + CGUISpriteInstance sprite, sprite_over, sprite_pressed, sprite_disabled; if (checked) { - GUI::GetSetting(this, "sprite2", sprite); - GUI::GetSetting(this, "sprite2-over", sprite_over); - GUI::GetSetting(this, "sprite2-pressed", sprite_pressed); - GUI::GetSetting(this, "sprite2-disabled", sprite_disabled); - } + GUI::GetSetting(this, "sprite2", sprite); + GUI::GetSetting(this, "sprite2-over", sprite_over); + GUI::GetSetting(this, "sprite2-pressed", sprite_pressed); + GUI::GetSetting(this, "sprite2-disabled", sprite_disabled); + } else { - GUI::GetSetting(this, "sprite", sprite); - GUI::GetSetting(this, "sprite-over", sprite_over); - GUI::GetSetting(this, "sprite-pressed", sprite_pressed); - GUI::GetSetting(this, "sprite-disabled", sprite_disabled); + GUI::GetSetting(this, "sprite", sprite); + GUI::GetSetting(this, "sprite-over", sprite_over); + GUI::GetSetting(this, "sprite-pressed", sprite_pressed); + GUI::GetSetting(this, "sprite-disabled", sprite_disabled); } DrawButton( rect, diff --git a/source/gui/CGUI.cpp b/source/gui/CGUI.cpp index 5f8d1e365a..705e1dcefe 100755 --- a/source/gui/CGUI.cpp +++ b/source/gui/CGUI.cpp @@ -407,134 +407,24 @@ void CGUI::Draw() glPopMatrix(); } -void CGUI::DrawSprite(const CStr& SpriteName, - const float &Z, - const CRect &Rect, +void CGUI::DrawSprite(CGUISpriteInstance& Sprite, + const float &Z, + const CRect &Rect, const CRect &Clipping) { - // This is not an error, it's just a choice not to draw any sprite. - if (SpriteName == CStr()) + // If the sprite doesn't exist (name == ""), don't bother drawing anything + if (Sprite.IsEmpty()) return; // TODO: Clipping? - bool DoClipping = (Clipping != CRect()); - - CGUISprite Sprite; - - // Fetch real sprite from name - if (m_Sprites.count(SpriteName) == 0) - { - LOG_ONCE(ERROR, LOG_CATEGORY, "Trying to use a sprite that doesn't exist (\"%s\").", SpriteName.c_str()); - return; - } - else Sprite = m_Sprites[SpriteName]; glPushMatrix(); glTranslatef(0.0f, 0.0f, Z); - // Iterate all images and request them being drawn be the - // CRenderer - std::vector::const_iterator cit; - for (cit=Sprite.m_Images.begin(); cit!=Sprite.m_Images.end(); ++cit) - { - if (cit->m_Texture) - { - // TODO: Handle the GL state in a nicer way + Sprite.Draw(Rect, m_Sprites); - glEnable(GL_TEXTURE_2D); - glColor3f(1.0f, 1.0f, 1.0f); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - int fmt; - tex_info(cit->m_Texture, NULL, NULL, &fmt, NULL, NULL); - if (fmt == GL_RGBA || fmt == GL_BGRA) - { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - } - else - { - glDisable(GL_BLEND); - } - - tex_bind(cit->m_Texture); - - CRect real = cit->m_Size.GetClientArea(Rect); - - // Get the screen position/size of a single tiling of the texture - CRect TexSize = cit->m_TextureSize.GetClientArea(real); - - // Actual texture coordinates we'll send to OGL. - CRect TexCoords; - - TexCoords.left = (TexSize.left - real.left) / TexSize.GetWidth(); - TexCoords.right = TexCoords.left + real.GetWidth() / TexSize.GetWidth(); - - // 'Bottom' is actually the top in screen-space (I think), - // because the GUI puts (0,0) at the top-left - TexCoords.bottom = (TexSize.bottom - real.bottom) / TexSize.GetHeight(); - TexCoords.top = TexCoords.bottom + real.GetHeight() / TexSize.GetHeight(); - - if (cit->m_TexturePlacementInFile != CRect()) - { - // Save the width/height, because we'll change the values one at a time and need - // to be able to use the unchanged width/height - float width = TexCoords.GetWidth(), - height = TexCoords.GetHeight(); - - // Get texture width/height - int t_w, t_h; - tex_info(cit->m_Texture, &t_w, &t_h, NULL, NULL, NULL); - - float fTW=(float)t_w, fTH=(float)t_h; - - // notice left done after right, so that left is still unchanged, that is important. - TexCoords.right = TexCoords.left + width * cit->m_TexturePlacementInFile.right/fTW; - TexCoords.left += width * cit->m_TexturePlacementInFile.left/fTW; - - TexCoords.bottom = TexCoords.top + height * cit->m_TexturePlacementInFile.bottom/fTH; - TexCoords.top += height * cit->m_TexturePlacementInFile.top/fTH; - } - - glBegin(GL_QUADS); - glTexCoord2f(TexCoords.right, TexCoords.bottom); glVertex3f(real.right, real.bottom, cit->m_DeltaZ); - glTexCoord2f(TexCoords.left, TexCoords.bottom); glVertex3f(real.left, real.bottom, cit->m_DeltaZ); - glTexCoord2f(TexCoords.left, TexCoords.top); glVertex3f(real.left, real.top, cit->m_DeltaZ); - glTexCoord2f(TexCoords.right, TexCoords.top); glVertex3f(real.right, real.top, cit->m_DeltaZ); - glEnd(); - - glDisable(GL_TEXTURE_2D); - - } - else - { - //glDisable(GL_TEXTURE_2D); - - // TODO Gee: (2004-09-04) Shouldn't untextured sprites be able to be transparent too? - glColor4f(cit->m_BackColor.r, cit->m_BackColor.g, cit->m_BackColor.b, cit->m_BackColor.a); - - CRect real = cit->m_Size.GetClientArea(Rect); - - glBegin(GL_QUADS); - glVertex3f(real.right, real.bottom, cit->m_DeltaZ); - glVertex3f(real.left, real.bottom, cit->m_DeltaZ); - glVertex3f(real.left, real.top, cit->m_DeltaZ); - glVertex3f(real.right, real.top, cit->m_DeltaZ); - glEnd(); - - if (cit->m_Border) - { - glColor3f(cit->m_BorderColor.r, cit->m_BorderColor.g, cit->m_BorderColor.b); - glBegin(GL_LINE_LOOP); - glVertex3f(real.left, real.top+1.f, cit->m_DeltaZ); - glVertex3f(real.right-1.f, real.top+1.f, cit->m_DeltaZ); - glVertex3f(real.right-1.f, real.bottom, cit->m_DeltaZ); - glVertex3f(real.left, real.bottom, cit->m_DeltaZ); - glEnd(); - } - } - } glPopMatrix(); + } void CGUI::Destroy() @@ -658,7 +548,7 @@ struct SGenerateTextImage SpriteCall.m_Area.right = width-BufferZone; } - SpriteCall.m_TextureName = TextureName; + SpriteCall.m_Sprite = TextureName; m_YFrom = SpriteCall.m_Area.top-BufferZone; m_YTo = SpriteCall.m_Area.bottom+BufferZone; @@ -932,7 +822,7 @@ SGUIText CGUI::GenerateText(const CGUIString &string, return Text; } -void CGUI::DrawText(const SGUIText &Text, const CColor &DefaultColor, +void CGUI::DrawText(SGUIText &Text, const CColor &DefaultColor, const CPos &pos, const float &z) { // TODO Gee: All these really necessary? Some @@ -984,11 +874,11 @@ void CGUI::DrawText(const SGUIText &Text, const CColor &DefaultColor, if (font) delete font; - for (list::const_iterator it=Text.m_SpriteCalls.begin(); + for (list::iterator it=Text.m_SpriteCalls.begin(); it!=Text.m_SpriteCalls.end(); ++it) { - DrawSprite(it->m_TextureName, z, it->m_Area + pos); + DrawSprite(it->m_Sprite, z, it->m_Area + pos); } // TODO To whom it may concern: Thing were not reset, so @@ -1213,7 +1103,7 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec if (m_Styles.count(CStr("default")) == 1) object->LoadStyle(*this, CStr("default")); - if (argStyle != CStr()) + if (argStyle.Length()) { // additional check if (m_Styles.count(argStyle) == 0) @@ -1262,6 +1152,8 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec ManuallySetZ = true; +/* TODO: Reimplement this inside GUIRenderer.cpp + // Generate "stretched:filename" sprites. // // Check whether it's actually one of the many sprite... parameters. @@ -1299,7 +1191,7 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec } } } - +*/ // Try setting the value if (object->SetSetting(pFile->getAttributeString(attr.Name), (CStr)attr.Value) != PS_OK) { @@ -1531,23 +1423,10 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite // This is the only attribute we want if (attr_name == "texture") { - // Load the texture from disk now, because now's as good a time as any CStr TexFilename ("art/textures/ui/"); TexFilename += attr_value; - Handle tex = tex_load(TexFilename.c_str()); - if (tex <= 0) - { - // Don't use ReportParseError, because this is not a *parsing* error - // and has ultimately nothing to do with the actual sprite we're reading. - LOG(ERROR, LOG_CATEGORY, "Error opening texture '%s': %lld", TexFilename.c_str(), tex); - } - else - { - image.m_TextureName = TexFilename; - image.m_Texture = tex; - tex_upload(tex); - } + image.m_TextureName = TexFilename; } else if (attr_name == "size") diff --git a/source/gui/CGUI.h b/source/gui/CGUI.h index b28a4b37a5..02935ba15a 100755 --- a/source/gui/CGUI.h +++ b/source/gui/CGUI.h @@ -104,14 +104,15 @@ public: void Draw(); /** - * Draw GUI Sprite, cooperates with CRenderer. + * Draw GUI Sprite * - * @param SpriteName By name! The GUI will fetch the real object itself. + * @param Sprite Object refering to the sprite (which also caches + * calculations for faster rendering) * @param Z Drawing order, depth value * @param Rect Position and Size * @param Clipping The sprite shouldn't be drawn outside this rectangle */ - void DrawSprite(const CStr& SpriteName, const float &Z, + void DrawSprite(CGUISpriteInstance& Sprite, const float &Z, const CRect &Rect, const CRect &Clipping=CRect()); /** @@ -122,7 +123,7 @@ public: * @param pos position * @param z z value. */ - void DrawText(const SGUIText &Text, const CColor &DefaultColor, + void DrawText(SGUIText &Text, const CColor &DefaultColor, const CPos &pos, const float &z); /** @@ -185,7 +186,7 @@ public: /** * Update Resolution, should be called every time the resolution - * of the opengl screen has been changed, this is becuase it needs + * of the OpenGL screen has been changed, this is because it needs * to re-cache all its actual sizes * * Needs no input since screen resolution is global. @@ -203,7 +204,7 @@ public: * Done through the CGUI since it can communicate with * * @param Text Text to generate SGUIText object from - * @param Font Default font, notice both Default color and defult font + * @param Font Default font, notice both Default color and default font * can be changed by tags. * @param Width Width, 0 if no word-wrapping. * @param BufferZone space between text and edge, and space between text and images. @@ -248,7 +249,7 @@ private: /** * Adds an object to the GUI's object database * Private, since you can only add objects through - * XML files. Why? Becasue it enables the GUI to + * XML files. Why? Because it enables the GUI to * be much more encapsulated and safe. * * @throws Rethrows PS_RESULT from IGUIObject::SetGUI() and diff --git a/source/gui/CGUIScrollBarStyle.h b/source/gui/CGUIScrollBarStyle.h index a381f7e196..52d987018d 100755 --- a/source/gui/CGUIScrollBarStyle.h +++ b/source/gui/CGUIScrollBarStyle.h @@ -82,33 +82,33 @@ struct CGUIScrollBarStyle //-------------------------------------------------------- //@{ - CStr m_SpriteButtonTop; - CStr m_SpriteButtonTopPressed; - CStr m_SpriteButtonTopDisabled; + CGUISpriteInstance m_SpriteButtonTop; + CGUISpriteInstance m_SpriteButtonTopPressed; + CGUISpriteInstance m_SpriteButtonTopDisabled; - CStr m_SpriteButtonBottom; - CStr m_SpriteButtonBottomPressed; - CStr m_SpriteButtonBottomDisabled; + CGUISpriteInstance m_SpriteButtonBottom; + CGUISpriteInstance m_SpriteButtonBottomPressed; + CGUISpriteInstance m_SpriteButtonBottomDisabled; - CStr m_SpriteScrollBackHorizontal; - CStr m_SpriteScrollBarHorizontal; + CGUISpriteInstance m_SpriteScrollBackHorizontal; + CGUISpriteInstance m_SpriteScrollBarHorizontal; //@} //-------------------------------------------------------- - /** @name Verical Sprites */ + /** @name Vertical Sprites */ //-------------------------------------------------------- //@{ - CStr m_SpriteButtonLeft; - CStr m_SpriteButtonLeftPressed; - CStr m_SpriteButtonLeftDisabled; + CGUISpriteInstance m_SpriteButtonLeft; + CGUISpriteInstance m_SpriteButtonLeftPressed; + CGUISpriteInstance m_SpriteButtonLeftDisabled; - CStr m_SpriteButtonRight; - CStr m_SpriteButtonRightPressed; - CStr m_SpriteButtonRightDisabled; + CGUISpriteInstance m_SpriteButtonRight; + CGUISpriteInstance m_SpriteButtonRightPressed; + CGUISpriteInstance m_SpriteButtonRightDisabled; - CStr m_SpriteScrollBackVertical; - CStr m_SpriteScrollBarVertical; + CGUISpriteInstance m_SpriteScrollBackVertical; + CGUISpriteInstance m_SpriteScrollBarVertical; //@} }; diff --git a/source/gui/CGUIScrollBarVertical.cpp b/source/gui/CGUIScrollBarVertical.cpp index 3c1d2586d6..94b101bc48 100755 --- a/source/gui/CGUIScrollBarVertical.cpp +++ b/source/gui/CGUIScrollBarVertical.cpp @@ -48,7 +48,7 @@ void CGUIScrollBarVertical::Draw() if (m_UseEdgeButtons) { // Get Appropriate sprites - CStr button_top, button_bottom; + CGUISpriteInstance button_top, button_bottom; // figure out what sprite to use for top button if (m_ButtonMinusHovered) diff --git a/source/gui/CGUISprite.cpp b/source/gui/CGUISprite.cpp index 0c9449c84c..c7876e6bc5 100755 --- a/source/gui/CGUISprite.cpp +++ b/source/gui/CGUISprite.cpp @@ -1,15 +1,38 @@ -/* -CGUISprite -by Gustav Larsson -gee@pyro.nu -*/ - #include "precompiled.h" -#include "GUI.h" +#include "CGUISprite.h" -using namespace std; -/* -void CGUISprite::Draw(const float &z, const CRect &rect, const CRect &clipping=CRect(0,0,0,0)) +CGUISpriteInstance::CGUISpriteInstance() { } -*/ + +CGUISpriteInstance::CGUISpriteInstance(CStr SpriteName) + : m_SpriteName(SpriteName) +{ +} + +CGUISpriteInstance &CGUISpriteInstance::operator=(CStr SpriteName) +{ + m_SpriteName = SpriteName; + Invalidate(); + return *this; +} + +void CGUISpriteInstance::Draw(CRect Size, std::map &Sprites) +{ + if (m_CachedSize != Size) + { + GUIRenderer::UpdateDrawCallCache(m_DrawCallCache, m_SpriteName, Size, Sprites); + m_CachedSize = Size; + } + GUIRenderer::Draw(m_DrawCallCache); +} + +void CGUISpriteInstance::Invalidate() +{ + m_CachedSize = CRect(); +} + +bool CGUISpriteInstance::IsEmpty() const +{ + return m_SpriteName==""; +} \ No newline at end of file diff --git a/source/gui/CGUISprite.h b/source/gui/CGUISprite.h index 462eec8018..9eeddc07ff 100755 --- a/source/gui/CGUISprite.h +++ b/source/gui/CGUISprite.h @@ -25,7 +25,8 @@ gee@pyro.nu //-------------------------------------------------------- // Includes / Compiler directives //-------------------------------------------------------- -#include "GUI.h" +#include "GUIutil.h" + #include "Overlay.h" #include "lib/res/ogl_tex.h" @@ -53,43 +54,28 @@ gee@pyro.nu */ struct SGUIImage { - SGUIImage() : m_Texture(0), m_Border(false), m_DeltaZ(0.f), m_TexturePlacementInFile() {} - ~SGUIImage() { - if (m_Texture) - tex_free(m_Texture); - } - - // Copy constructor, which increments the refcount of the texture. - // Slightly inefficient, but makes sure things get destructed - // at the right times. - SGUIImage(const SGUIImage& s) - { - #define C(x) m_##x = s.m_##x - C(TextureName); C(Texture); - C(Size); C(TextureSize); - C(BackColor); C(BorderColor); - C(Border); C(DeltaZ); - C(TexturePlacementInFile); - #undef C - // 'Load' the texture (but don't do any work because it's cached) - if (m_Texture) - tex_load(m_TextureName); - } + SGUIImage() : m_Border(false), m_DeltaZ(0.f) {} + // Filename of the texture CStr m_TextureName; - Handle m_Texture; - // Image placement + // Image placement (relative to object) CClientArea m_Size; - // Texture placement + // Texture placement (relative to image placement) CClientArea m_TextureSize; // Because OpenGL wants textures in squares with a power of 2 (64x64, 256x256) - // it's sometimes tediuos to adjust this. So this value simulates which area + // it's sometimes tedious to adjust this. So this value simulates which area // is the real texture CRect m_TexturePlacementInFile; + // For textures that contain a collection of icons (e.g. unit portraits), this + // will be set to the size of one icon. An object's icon-id will determine + // which part of the texture is used. + // Equal to CPos(0,0) for non-icon textures. + CSize m_IconSize; + // Color CColor m_BackColor; CColor m_BorderColor; @@ -118,9 +104,6 @@ struct SGUIImage */ class CGUISprite { - // For CGUI::DrawSprite() - friend class CGUI; - public: CGUISprite() {} virtual ~CGUISprite() {} @@ -132,9 +115,34 @@ public: */ void AddImage(const SGUIImage &image) { m_Images.push_back(image); } -private: /// List of images std::vector m_Images; }; +#include "GUIRenderer.h" + +// An instance of a sprite, usually stored in IGUIObjects - basically a string +// giving the sprite's name, but with some extra data to cache rendering +// calculations between draw calls. +class CGUISpriteInstance +{ +public: + CGUISpriteInstance(); + CGUISpriteInstance(CStr SpriteName); + CGUISpriteInstance &operator=(CStr SpriteName); + void Draw(CRect Size, std::map &Sprites); + void Invalidate(); + bool IsEmpty() const; + CStr GetName() { return m_SpriteName; } + +private: + CStr m_SpriteName; + + // Stored drawing calls, for more efficient rendering + GUIRenderer::DrawCalls m_DrawCallCache; + // Size of previously rendered sprite; the cache is invalidated + // whenever this changes. + CRect m_CachedSize; +}; + #endif diff --git a/source/gui/CImage.cpp b/source/gui/CImage.cpp index 3252ca6d2c..3bd3ed2776 100755 --- a/source/gui/CImage.cpp +++ b/source/gui/CImage.cpp @@ -17,7 +17,7 @@ using namespace std; //------------------------------------------------------------------- CImage::CImage() { - AddSetting(GUIST_CStr, "sprite"); + AddSetting(GUIST_CGUISpriteInstance, "sprite"); } CImage::~CImage() @@ -30,8 +30,8 @@ void CImage::Draw() { float bz = GetBufferedZ(); - CStr sprite; - GUI::GetSetting(this, "sprite", sprite); + CGUISpriteInstance sprite; + GUI::GetSetting(this, "sprite", sprite); GetGUI()->DrawSprite(sprite, bz, m_CachedActualSize); } diff --git a/source/gui/CInput.cpp b/source/gui/CInput.cpp index c366096c4b..bf67a8cd63 100755 --- a/source/gui/CInput.cpp +++ b/source/gui/CInput.cpp @@ -25,13 +25,13 @@ using namespace std; //------------------------------------------------------------------- CInput::CInput() : m_iBufferPos(0) { - AddSetting(GUIST_float, "buffer-zone"); - AddSetting(GUIST_CStrW, "caption"); - AddSetting(GUIST_CStr, "font"); - AddSetting(GUIST_bool, "scrollbar"); - AddSetting(GUIST_CStr, "scrollbar-style"); - AddSetting(GUIST_CStr, "sprite"); - AddSetting(GUIST_CColor, "textcolor"); + AddSetting(GUIST_float, "buffer-zone"); + AddSetting(GUIST_CStrW, "caption"); + AddSetting(GUIST_CStr, "font"); + AddSetting(GUIST_bool, "scrollbar"); + AddSetting(GUIST_CStr, "scrollbar-style"); + AddSetting(GUIST_CGUISpriteInstance, "sprite"); + AddSetting(GUIST_CColor, "textcolor"); // TODO Gee: (2004-08-14) // Add a setting for buffer zone //AddSetting(GUIST_int, " @@ -344,8 +344,8 @@ void CInput::Draw() if (GetGUI()) { - CStr sprite; - GUI::GetSetting(this, "sprite", sprite); + CGUISpriteInstance sprite; + GUI::GetSetting(this, "sprite", sprite); GetGUI()->DrawSprite(sprite, bz, m_CachedActualSize); diff --git a/source/gui/CProgressBar.cpp b/source/gui/CProgressBar.cpp index 4f67e75846..d71af724da 100755 --- a/source/gui/CProgressBar.cpp +++ b/source/gui/CProgressBar.cpp @@ -17,9 +17,9 @@ using namespace std; //------------------------------------------------------------------- CProgressBar::CProgressBar() { - AddSetting(GUIST_CStr, "sprite-background"); - AddSetting(GUIST_CStr, "sprite-bar"); - AddSetting(GUIST_float, "caption"); // aka value from 0 to 100 + AddSetting(GUIST_CGUISpriteInstance, "sprite-background"); + AddSetting(GUIST_CGUISpriteInstance, "sprite-bar"); + AddSetting(GUIST_float, "caption"); // aka value from 0 to 100 } CProgressBar::~CProgressBar() @@ -58,10 +58,10 @@ void CProgressBar::Draw() { float bz = GetBufferedZ(); - CStr sprite_background, sprite_bar; + CGUISpriteInstance sprite_background, sprite_bar; float value; - GUI::GetSetting(this, "sprite-background", sprite_background); - GUI::GetSetting(this, "sprite-bar", sprite_bar); + GUI::GetSetting(this, "sprite-background", sprite_background); + GUI::GetSetting(this, "sprite-bar", sprite_bar); GUI::GetSetting(this, "caption", value); GetGUI()->DrawSprite(sprite_background, bz, m_CachedActualSize); diff --git a/source/gui/CText.cpp b/source/gui/CText.cpp index 36db86c7c6..21a2c75bbe 100755 --- a/source/gui/CText.cpp +++ b/source/gui/CText.cpp @@ -20,13 +20,13 @@ using namespace std; //------------------------------------------------------------------- CText::CText() { - AddSetting(GUIST_float, "buffer-zone"); - AddSetting(GUIST_CGUIString, "caption"); - AddSetting(GUIST_CStr, "font"); - AddSetting(GUIST_bool, "scrollbar"); - AddSetting(GUIST_CStr, "scrollbar-style"); - AddSetting(GUIST_CStr, "sprite"); - AddSetting(GUIST_CColor, "textcolor"); + AddSetting(GUIST_float, "buffer-zone"); + AddSetting(GUIST_CGUIString, "caption"); + AddSetting(GUIST_CStr, "font"); + AddSetting(GUIST_bool, "scrollbar"); + AddSetting(GUIST_CStr, "scrollbar-style"); + AddSetting(GUIST_CGUISpriteInstance, "sprite"); + AddSetting(GUIST_CColor, "textcolor"); // TODO Gee: (2004-08-14) // Add a setting for buffer zone //AddSetting(GUIST_int, " @@ -161,8 +161,8 @@ void CText::Draw() if (GetGUI()) { - CStr sprite; - GUI::GetSetting(this, "sprite", sprite); + CGUISpriteInstance sprite; + GUI::GetSetting(this, "sprite", sprite); GetGUI()->DrawSprite(sprite, bz, m_CachedActualSize); diff --git a/source/gui/GUIRenderer.cpp b/source/gui/GUIRenderer.cpp new file mode 100644 index 0000000000..6bd3c70848 --- /dev/null +++ b/source/gui/GUIRenderer.cpp @@ -0,0 +1,175 @@ +#include "precompiled.h" + +#include "GUIRenderer.h" + +#include "lib/ogl.h" + +#include "ps/CLogger.h" +#define LOG_CATEGORY "gui" + +void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, CStr &SpriteName, CRect &Size, std::map &Sprites) +{ + Calls.clear(); + + std::map::iterator it (Sprites.find(SpriteName)); + if (it == Sprites.end()) + { + // Sprite not found. Check whether this a special sprite: + // stretched:filename.ext + // filename.ext + // and if so, try to create it as a new sprite. + + // TODO: Implement this. + + // Otherwise, just complain and give up: + LOG(ERROR, LOG_CATEGORY, "Trying to use a sprite that doesn't exist (\"%s\").", (const char*)SpriteName); + return; + } + + Calls.reserve(it->second.m_Images.size()); + + // Iterate through all the sprite's images + std::vector::const_iterator cit; + for (cit = it->second.m_Images.begin(); cit != it->second.m_Images.end(); ++cit) + { + SDrawCall Call; + if (cit->m_TextureName.Length()) + { + Handle h = tex_load(cit->m_TextureName); + if (h <= 0) + { + LOG(ERROR, LOG_CATEGORY, "Error reading texture '%s': %lld", (const char*)cit->m_TextureName, h); + return; + } + + Call.m_TexHandle = h; + + int err = tex_upload(Call.m_TexHandle); + if (err < 0) + { + LOG(ERROR, LOG_CATEGORY, "Error uploading texture '%s': %d", (const char*)cit->m_TextureName, err); + return; + } + + int fmt, t_w, t_h; + tex_info(Call.m_TexHandle, &t_w, &t_h, &fmt, NULL, NULL); + Call.m_EnableBlending = (fmt == GL_RGBA || fmt == GL_BGRA); + + CRect real = cit->m_Size.GetClientArea(Size); + + // Get the screen position/size of a single tiling of the texture + CRect TexSize = cit->m_TextureSize.GetClientArea(real); + + CRect TexCoords; + + TexCoords.left = (TexSize.left - real.left) / TexSize.GetWidth(); + TexCoords.right = TexCoords.left + real.GetWidth() / TexSize.GetWidth(); + + // 'Bottom' is actually the top in screen-space (I think), + // because the GUI puts (0,0) at the top-left + TexCoords.bottom = (TexSize.bottom - real.bottom) / TexSize.GetHeight(); + TexCoords.top = TexCoords.bottom + real.GetHeight() / TexSize.GetHeight(); + + if (cit->m_TexturePlacementInFile != CRect()) + { + // Save the width/height, because we'll change the values one at a time and need + // to be able to use the unchanged width/height + float width = TexCoords.GetWidth(), + height = TexCoords.GetHeight(); + + float fTW=(float)t_w, fTH=(float)t_h; + + // notice left done after right, so that left is still unchanged, that is important. + TexCoords.right = TexCoords.left + width * cit->m_TexturePlacementInFile.right/fTW; + TexCoords.left += width * cit->m_TexturePlacementInFile.left/fTW; + + TexCoords.bottom = TexCoords.top + height * cit->m_TexturePlacementInFile.bottom/fTH; + TexCoords.top += height * cit->m_TexturePlacementInFile.top/fTH; + } + + Call.m_TexCoords = TexCoords; + Call.m_Vertices = real; + } + else + { + Call.m_TexHandle = 0; + } + + Call.m_BackColor = cit->m_BackColor; + Call.m_BorderColor = cit->m_Border ? cit->m_BorderColor : CColor(); + Call.m_DeltaZ = cit->m_DeltaZ; + + Calls.push_back(Call); + } +} + +void GUIRenderer::Draw(DrawCalls &Calls) +{ + + // Iterate through each DrawCall, and execute whatever drawing code is being called + for (DrawCalls::const_iterator cit = Calls.begin(); cit != Calls.end(); ++cit) + { + glColor4f(cit->m_BackColor.r, cit->m_BackColor.g, cit->m_BackColor.b, cit->m_BackColor.a); + + if (cit->m_EnableBlending) + { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + } + else + { + glDisable(GL_BLEND); + } + + if (cit->m_TexHandle) + { + // TODO: Handle the GL state in a nicer way + + glEnable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + tex_bind(cit->m_TexHandle); + + glBegin(GL_QUADS); + + glTexCoord2f(cit->m_TexCoords.right,cit->m_TexCoords.bottom); + glVertex3f(cit->m_Vertices.right, cit->m_Vertices.bottom, cit->m_DeltaZ); + + glTexCoord2f(cit->m_TexCoords.left, cit->m_TexCoords.bottom); + glVertex3f(cit->m_Vertices.left, cit->m_Vertices.bottom, cit->m_DeltaZ); + + glTexCoord2f(cit->m_TexCoords.left, cit->m_TexCoords.top); + glVertex3f(cit->m_Vertices.left, cit->m_Vertices.top, cit->m_DeltaZ); + + glTexCoord2f(cit->m_TexCoords.right,cit->m_TexCoords.top); + glVertex3f(cit->m_Vertices.right, cit->m_Vertices.top, cit->m_DeltaZ); + + glEnd(); + + glDisable(GL_TEXTURE_2D); + + } + else + { + + glBegin(GL_QUADS); + glVertex3f(cit->m_Vertices.right, cit->m_Vertices.bottom, cit->m_DeltaZ); + glVertex3f(cit->m_Vertices.left, cit->m_Vertices.bottom, cit->m_DeltaZ); + glVertex3f(cit->m_Vertices.left, cit->m_Vertices.top, cit->m_DeltaZ); + glVertex3f(cit->m_Vertices.right, cit->m_Vertices.top, cit->m_DeltaZ); + glEnd(); + + + if (cit->m_BorderColor != CColor()) + { + glColor4f(cit->m_BorderColor.r, cit->m_BorderColor.g, cit->m_BorderColor.b, cit->m_BorderColor.a); + glBegin(GL_LINE_LOOP); + glVertex3f(cit->m_Vertices.left, cit->m_Vertices.top+1.f, cit->m_DeltaZ); + glVertex3f(cit->m_Vertices.right-1.f, cit->m_Vertices.top+1.f, cit->m_DeltaZ); + glVertex3f(cit->m_Vertices.right-1.f, cit->m_Vertices.bottom, cit->m_DeltaZ); + glVertex3f(cit->m_Vertices.left, cit->m_Vertices.bottom, cit->m_DeltaZ); + glEnd(); + } + } + } +} diff --git a/source/gui/GUIRenderer.h b/source/gui/GUIRenderer.h new file mode 100644 index 0000000000..1c190e9240 --- /dev/null +++ b/source/gui/GUIRenderer.h @@ -0,0 +1,37 @@ +#ifndef GUIRenderer_h +#define GUIRenderer_h + +#include "lib/res/handle.h" +#include "ps/Overlay.h" +#include "ps/CStr.h" +#include + +namespace GUIRenderer +{ + struct SDrawCall + { + Handle m_TexHandle; + + bool m_EnableBlending; + + CRect m_Vertices; + CRect m_TexCoords; + float m_DeltaZ; + + CColor m_BorderColor; // == CColor() for no border + CColor m_BackColor; + }; + + typedef std::vector DrawCalls; +} + +#include "gui/CGUISprite.h" + +namespace GUIRenderer +{ + void UpdateDrawCallCache(DrawCalls &Calls, CStr &SpriteName, CRect& Size, std::map &Sprites); + + void Draw(DrawCalls &Calls); +} + +#endif // GUIRenderer_h diff --git a/source/gui/GUItext.cpp b/source/gui/GUItext.cpp index 19aab70df4..a3e8709bba 100755 --- a/source/gui/GUItext.cpp +++ b/source/gui/GUItext.cpp @@ -153,7 +153,7 @@ void CGUIString::GenerateTextCall(SFeedback &Feedback, SpriteCall.m_Area += displacement; } - SpriteCall.m_TextureName = icon.m_TextureName; + SpriteCall.m_Sprite = icon.m_TextureName; // Add sprite call Feedback.m_SpriteCalls.push_back(SpriteCall); diff --git a/source/gui/GUItext.h b/source/gui/GUItext.h index 234cf361cd..f0b05f8b3e 100755 --- a/source/gui/GUItext.h +++ b/source/gui/GUItext.h @@ -23,6 +23,8 @@ gee@pyro.nu //-------------------------------------------------------- #include +#include "CGUISprite.h" + //-------------------------------------------------------- // Declarations //-------------------------------------------------------- @@ -59,9 +61,9 @@ struct SGUIText CRect m_Area; /** - * Texture name from texture database. + * Sprite from global GUI sprite database. */ - CStr m_TextureName; + CGUISpriteInstance m_Sprite; }; /** diff --git a/source/gui/GUIutil.cpp b/source/gui/GUIutil.cpp index bc5ff65f29..fd2f47f010 100755 --- a/source/gui/GUIutil.cpp +++ b/source/gui/GUIutil.cpp @@ -184,7 +184,7 @@ bool __ParseString(const CStr &Value, EVAlign &Output) template <> bool __ParseString(const CStr& Value, CGUIString &Output) { - // Translate the Value and retrieve the locilised string in + // Translate the Value and retrieve the localised string in // Unicode. Output.SetValue(translate((CStrW)Value)); @@ -194,13 +194,20 @@ bool __ParseString(const CStr& Value, CGUIString &Output) template <> bool __ParseString(const CStr& Value, CStrW &Output) { - // Translate the Value and retrieve the locilised string in + // Translate the Value and retrieve the localised string in // Unicode. Output = translate((CStrW)Value); return true; } +template <> +bool __ParseString(const CStr& Value, CGUISpriteInstance &Output) +{ + Output = Value; + return true; +} + //-------------------------------------------------------- // Help Classes/Structs for the GUI implementation //-------------------------------------------------------- @@ -397,6 +404,7 @@ void CInternalCGUIAccessorBase::HandleMessage(IGUIObject *pObject, const SGUIMes TYPE(CStrW) TYPE(CColor) TYPE(CGUIString) + TYPE(CGUISpriteInstance) TYPE(EAlign) TYPE(EVAlign) #undef TYPE diff --git a/source/gui/GUIutil.h b/source/gui/GUIutil.h index 083cdbaf0c..9dc7188fc4 100755 --- a/source/gui/GUIutil.h +++ b/source/gui/GUIutil.h @@ -21,7 +21,6 @@ gee@pyro.nu //-------------------------------------------------------- // Includes / Compiler directives //-------------------------------------------------------- -#include "GUI.h" #include "Parser.h" // TODO Gee: New #include "Overlay.h" @@ -36,39 +35,6 @@ class CGUIString; template bool __ParseString(const CStr& Value, T &tOutput); -template <> -bool __ParseString(const CStr& Value, bool &Output); - -template <> -bool __ParseString(const CStr& Value, int &Output); - -template <> -bool __ParseString(const CStr& Value, float &Output); - -template <> -bool __ParseString(const CStr& Value, CRect &Output); - -template <> -bool __ParseString(const CStr& Value, CClientArea &Output); - -template <> -bool __ParseString(const CStr& Value, CColor &Output); - -template <> -bool __ParseString(const CStr& Value, CSize &Output); - -template <> -bool __ParseString(const CStr& Value, EAlign &Output); - -template <> -bool __ParseString(const CStr& Value, EVAlign &Output); - -template <> -bool __ParseString(const CStr& Value, CGUIString &Output); - -template <> -bool __ParseString(const CStr& Value, CStrW &Output); - // Icon, you create them in the XML file with root element // you use them in text owned by different objects... Such as CText. @@ -129,6 +95,8 @@ public: //-------------------------------------------------------- class CGUI; class IGUIObject; +struct SGUIMessage; +class CGUISpriteInstance; /** * @author Gustav Larsson @@ -211,7 +179,7 @@ public: * Sets a value by name using a real datatype as input. * * This is the official way of setting a setting, no other - * way should only causiously be used! + * way should only cautiously be used! * * @param pObject Object pointer * @param Setting Setting by name @@ -338,10 +306,12 @@ public: * @param sec Secondary sprite if Primary should fail * @return Resulting string */ - static CStr FallBackSprite(const CStr& prim, const CStr& sec) + static CGUISpriteInstance& FallBackSprite( + CGUISpriteInstance& prim, + CGUISpriteInstance& sec) { // CStr() == empty string, null - return ((prim!=CStr())?(prim):(sec)); + return (prim.IsEmpty() ? sec : prim); } /** diff --git a/source/gui/IGUIButtonBehavior.cpp b/source/gui/IGUIButtonBehavior.cpp index 40ce762973..6345f33211 100755 --- a/source/gui/IGUIButtonBehavior.cpp +++ b/source/gui/IGUIButtonBehavior.cpp @@ -88,10 +88,10 @@ CColor IGUIButtonBehavior::ChooseColor() void IGUIButtonBehavior::DrawButton(const CRect &rect, const float &z, - const CStr& sprite, - const CStr& sprite_over, - const CStr& sprite_pressed, - const CStr& sprite_disabled) + CGUISpriteInstance& sprite, + CGUISpriteInstance& sprite_over, + CGUISpriteInstance& sprite_pressed, + CGUISpriteInstance& sprite_disabled) { if (GetGUI()) { diff --git a/source/gui/IGUIButtonBehavior.h b/source/gui/IGUIButtonBehavior.h index fc222b0c92..f15f544010 100755 --- a/source/gui/IGUIButtonBehavior.h +++ b/source/gui/IGUIButtonBehavior.h @@ -25,6 +25,8 @@ gee@pyro.nu //-------------------------------------------------------- #include "GUI.h" +class CGUISpriteInstance; + //-------------------------------------------------------- // Macros //-------------------------------------------------------- @@ -74,10 +76,10 @@ public: */ void DrawButton(const CRect &rect, const float &z, - const CStr& sprite, - const CStr& sprite_over, - const CStr& sprite_pressed, - const CStr& sprite_disabled); + CGUISpriteInstance& sprite, + CGUISpriteInstance& sprite_over, + CGUISpriteInstance& sprite_pressed, + CGUISpriteInstance& sprite_disabled); /** * Choosing which color of the following according to diff --git a/source/gui/IGUIObject.cpp b/source/gui/IGUIObject.cpp index b0996154af..0f76f77541 100755 --- a/source/gui/IGUIObject.cpp +++ b/source/gui/IGUIObject.cpp @@ -67,12 +67,13 @@ IGUIObject::~IGUIObject() TYPE(CColor); TYPE(CClientArea); TYPE(CGUIString); + TYPE(CGUISpriteInstance); TYPE(CStr); TYPE(CStrW); TYPE(EAlign); TYPE(EVAlign); default: - assert(!"Invalid setting type"); + debug_warn("Invalid setting type"); } #undef TYPE } @@ -170,6 +171,7 @@ void IGUIObject::AddSetting(const EGUISettingType &Type, const CStr& Name) CASE_TYPE(CStrW) CASE_TYPE(CColor) CASE_TYPE(CGUIString) + CASE_TYPE(CGUISpriteInstance) CASE_TYPE(EAlign) CASE_TYPE(EVAlign) @@ -225,7 +227,7 @@ void IGUIObject::UpdateMouseOver(IGUIObject * const &pMouseOver) bool IGUIObject::SettingExists(const CStr& Setting) const { // Because GetOffsets will direct dynamically defined - // classes with polymorifsm to respective ms_SettingsInfo + // classes with polymorphism to respective ms_SettingsInfo // we need to make no further updates on this function // in derived classes. //return (GetSettingsInfo().count(Setting) >= 1); @@ -264,6 +266,7 @@ PS_RESULT IGUIObject::SetSetting(const CStr& Setting, const CStr& Value) ADD_TYPE(CColor) ADD_TYPE(CClientArea) ADD_TYPE(CGUIString) + ADD_TYPE(CGUISpriteInstance) ADD_TYPE(EAlign) ADD_TYPE(EVAlign) else @@ -438,7 +441,7 @@ void IGUIObject::RegisterScriptHandler(const CStr& Action, const CStr& Code, CGU void IGUIObject::ScriptEvent(const CStr& Action) { - map::iterator it = m_ScriptHandlers.find(Action); + map::iterator it = m_ScriptHandlers.find(Action); if (it == m_ScriptHandlers.end()) return; @@ -474,7 +477,7 @@ void IGUIObject::ScriptEvent(const CStr& Action) paramData[0] = OBJECT_TO_JSVAL(mouseObj); jsval result; - JSBool ok = JS_CallFunction(g_ScriptingHost.getContext(), jsGuiObject, (JSFunction*)((*it).second), 1, paramData, &result); + JSBool ok = JS_CallFunction(g_ScriptingHost.getContext(), jsGuiObject, it->second, 1, paramData, &result); if (!ok) { JS_ReportError(g_ScriptingHost.getContext(), "Errors executing script action \"%s\"", Action.c_str()); diff --git a/source/gui/IGUIObject.h b/source/gui/IGUIObject.h index d02dd6b305..39ecf19384 100755 --- a/source/gui/IGUIObject.h +++ b/source/gui/IGUIObject.h @@ -53,6 +53,8 @@ class CGUI; // Map with pointers typedef std::map map_Settings; +struct JSObject; + //-------------------------------------------------------- // Error declarations //-------------------------------------------------------- @@ -78,6 +80,7 @@ enum EGUISettingType GUIST_CGUIString, GUIST_CStr, GUIST_CStrW, + GUIST_CGUISpriteInstance, GUIST_EAlign, GUIST_EVAlign }; @@ -433,7 +436,7 @@ protected: /** * Internal storage for registered script handlers. */ - std::map m_ScriptHandlers; + std::map m_ScriptHandlers; //@} private: diff --git a/source/gui/IGUIScrollBar.cpp b/source/gui/IGUIScrollBar.cpp index 33def1523a..9b8e966842 100755 --- a/source/gui/IGUIScrollBar.cpp +++ b/source/gui/IGUIScrollBar.cpp @@ -36,7 +36,7 @@ void IGUIScrollBar::SetupBarSize() m_BarSize = min((float)m_ScrollSpace/(float)m_ScrollRange, 1.f); } -const SGUIScrollBarStyle *IGUIScrollBar::GetStyle() const +SGUIScrollBarStyle *IGUIScrollBar::GetStyle() const { if (!m_pHostObject) return NULL; diff --git a/source/gui/IGUIScrollBar.h b/source/gui/IGUIScrollBar.h index a7ebfbf531..cb01458dd4 100755 --- a/source/gui/IGUIScrollBar.h +++ b/source/gui/IGUIScrollBar.h @@ -83,38 +83,38 @@ struct SGUIScrollBarStyle //-------------------------------------------------------- //@{ - CStr m_SpriteButtonTop; - CStr m_SpriteButtonTopPressed; - CStr m_SpriteButtonTopDisabled; - CStr m_SpriteButtonTopOver; + CGUISpriteInstance m_SpriteButtonTop; + CGUISpriteInstance m_SpriteButtonTopPressed; + CGUISpriteInstance m_SpriteButtonTopDisabled; + CGUISpriteInstance m_SpriteButtonTopOver; - CStr m_SpriteButtonBottom; - CStr m_SpriteButtonBottomPressed; - CStr m_SpriteButtonBottomDisabled; - CStr m_SpriteButtonBottomOver; + CGUISpriteInstance m_SpriteButtonBottom; + CGUISpriteInstance m_SpriteButtonBottomPressed; + CGUISpriteInstance m_SpriteButtonBottomDisabled; + CGUISpriteInstance m_SpriteButtonBottomOver; - CStr m_SpriteBarVertical; - CStr m_SpriteBarVerticalOver; - CStr m_SpriteBarVerticalPressed; + CGUISpriteInstance m_SpriteBarVertical; + CGUISpriteInstance m_SpriteBarVerticalOver; + CGUISpriteInstance m_SpriteBarVerticalPressed; - CStr m_SpriteBackVertical; + CGUISpriteInstance m_SpriteBackVertical; //@} //-------------------------------------------------------- - /** @name Verical Sprites */ + /** @name Vertical Sprites */ //-------------------------------------------------------- //@{ - CStr m_SpriteButtonLeft; - CStr m_SpriteButtonLeftPressed; - CStr m_SpriteButtonLeftDisabled; + CGUISpriteInstance m_SpriteButtonLeft; + CGUISpriteInstance m_SpriteButtonLeftPressed; + CGUISpriteInstance m_SpriteButtonLeftDisabled; - CStr m_SpriteButtonRight; - CStr m_SpriteButtonRightPressed; - CStr m_SpriteButtonRightDisabled; + CGUISpriteInstance m_SpriteButtonRight; + CGUISpriteInstance m_SpriteButtonRightPressed; + CGUISpriteInstance m_SpriteButtonRightDisabled; - CStr m_SpriteBackHorizontal; - CStr m_SpriteBarHorizontal; + CGUISpriteInstance m_SpriteBackHorizontal; + CGUISpriteInstance m_SpriteBarHorizontal; //@} }; @@ -288,7 +288,7 @@ public: * Get style used by the scrollbar * @return Scroll bar style struct. */ - const SGUIScrollBarStyle * GetStyle() const; + SGUIScrollBarStyle * GetStyle() const; protected: /** diff --git a/source/gui/IGUIScrollBarOwner.cpp b/source/gui/IGUIScrollBarOwner.cpp index 6f09dee24a..8cef34c42c 100755 --- a/source/gui/IGUIScrollBarOwner.cpp +++ b/source/gui/IGUIScrollBarOwner.cpp @@ -44,7 +44,7 @@ void IGUIScrollBarOwner::AddScrollBar(IGUIScrollBar * scrollbar) m_ScrollBars.push_back(scrollbar); } -const SGUIScrollBarStyle * IGUIScrollBarOwner::GetScrollBarStyle(const CStr& style) const +SGUIScrollBarStyle * IGUIScrollBarOwner::GetScrollBarStyle(const CStr& style) const { if (!GetGUI()) { @@ -58,7 +58,7 @@ const SGUIScrollBarStyle * IGUIScrollBarOwner::GetScrollBarStyle(const CStr& sty return NULL; } - return &GetGUI()->m_ScrollBarStyles.find(style)->second; + return &((CGUI*)GetGUI())->m_ScrollBarStyles.find(style)->second; } void IGUIScrollBarOwner::HandleMessage(const SGUIMessage &Message) diff --git a/source/gui/IGUIScrollBarOwner.h b/source/gui/IGUIScrollBarOwner.h index 87b53bfb5d..ac4cd83c22 100755 --- a/source/gui/IGUIScrollBarOwner.h +++ b/source/gui/IGUIScrollBarOwner.h @@ -67,7 +67,7 @@ public: /** * Interface for the m_ScrollBar to use. */ - virtual const SGUIScrollBarStyle *GetScrollBarStyle(const CStr& style) const; + virtual SGUIScrollBarStyle *GetScrollBarStyle(const CStr& style) const; /** * Add a scroll-bar diff --git a/source/gui/scripting/JSInterface_IGUIObject.cpp b/source/gui/scripting/JSInterface_IGUIObject.cpp index d5134e76bc..e39af58e30 100755 --- a/source/gui/scripting/JSInterface_IGUIObject.cpp +++ b/source/gui/scripting/JSInterface_IGUIObject.cpp @@ -37,17 +37,17 @@ JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsval id, jsval // the private IGUIObject* has been set (and thus crash). The others are // just for efficiency, and to allow correct reporting of attempts to access // nonexistent properties.) - if (propName == (CStr)"constructor" || - propName == (CStr)"prototype" || - propName == (CStr)"toString" || - propName == (CStr)"getByName" + if (propName == "constructor" || + propName == "prototype" || + propName == "toString" || + propName == "getByName" ) return JS_TRUE; IGUIObject* e = (IGUIObject*)JS_GetPrivate(cx, obj); // Handle the "parent" property specially - if (propName == (CStr)"parent") + if (propName == "parent") { IGUIObject* parent = e->GetParent(); if (parent) @@ -65,7 +65,7 @@ JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsval id, jsval return JS_TRUE; } // Also handle "name" specially - else if (propName == (CStr)"name") + else if (propName == "name") { *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, e->GetName())); return JS_TRUE; @@ -163,7 +163,6 @@ JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsval id, jsval { CGUIString value; GUI::GetSetting(e, propName, value); - // Create a garbage-collectable copy of the string JSString* s = StringConvert::wchars_to_jsstring(cx, value.GetRawString().c_str()); *vp = STRING_TO_JSVAL(s); break; @@ -173,8 +172,7 @@ JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsval id, jsval { CStr value; GUI::GetSetting(e, propName, value); - // Create a garbage-collectible copy of the string - *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, value.c_str() )); + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, value)); break; } @@ -182,8 +180,15 @@ JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsval id, jsval { CStrW value; GUI::GetSetting(e, propName, value); - // Create a garbage-collectible copy of the string - *vp = STRING_TO_JSVAL(JS_NewUCStringCopyZ(cx, value.utf16().c_str() )); + *vp = STRING_TO_JSVAL(JS_NewUCStringCopyZ(cx, value.utf16().c_str())); + break; + } + + case GUIST_CGUISpriteInstance: + { + CGUISpriteInstance value; + GUI::GetSetting(e, propName, value); + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, value.GetName())); break; } @@ -203,7 +208,7 @@ JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsval id, jsval { IGUIObject* e = (IGUIObject*)JS_GetPrivate(cx, obj); CStr propName = g_ScriptingHost.ValueToString(id); - if (propName == (CStr)"name") + if (propName == "name") { CStr propValue = JS_GetStringBytes(JS_ValueToString(cx, *vp)); e->SetName(propValue); @@ -223,7 +228,7 @@ JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsval id, jsval case GUIST_CStr: { - CStr value = JS_GetStringBytes(JS_ValueToString(cx, *vp)); + CStr value (JS_GetStringBytes(JS_ValueToString(cx, *vp))); GUI::SetSetting(e, propName, value); break; } @@ -235,6 +240,13 @@ JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsval id, jsval break; } + case GUIST_CGUISpriteInstance: + { + CStr value (JS_GetStringBytes(JS_ValueToString(cx, *vp))); + GUI::SetSetting(e, propName, value); + break; + } + case GUIST_CGUIString: { std::wstring value;