mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
major update
This was SVN commit r290.
This commit is contained in:
parent
1343010185
commit
e326ebae46
31 changed files with 2891 additions and 901 deletions
|
|
@ -6,59 +6,61 @@ gee@pyro.nu
|
|||
|
||||
//#include "stdafx."
|
||||
#include "GUI.h"
|
||||
#include "CButton.h"
|
||||
|
||||
// TODO Gee: font.h is temporary.
|
||||
#include "res/font.h"
|
||||
#include "res/res.h"
|
||||
#include "ogl.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Offsets
|
||||
DECLARE_SETTINGS_INFO(SButtonSettings)
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Constructor / Destructor
|
||||
//-------------------------------------------------------------------
|
||||
CButton::CButton()
|
||||
{
|
||||
// Settings defaults !
|
||||
/* m_Settings.m_Disabled = false;
|
||||
m_Settings.m_Font = "null";
|
||||
m_Settings.m_Sprite = "null";
|
||||
m_Settings.m_SpriteDisabled = "null";
|
||||
m_Settings.m_SpriteOver = "null";
|
||||
m_Settings.m_SpritePressed = "null";
|
||||
m_Settings.m_TextAlign = EAlign_Center;
|
||||
// m_Settings.m_TextColor = CColor();
|
||||
// m_Settings.m_TextColorDisabled;
|
||||
// m_Settings.m_TextColorOver;
|
||||
// m_Settings.m_TextColorPressed;
|
||||
m_Settings.m_TextValign = EValign_Center;
|
||||
m_Settings.m_ToolTip = "null";
|
||||
m_Settings.m_ToolTipStyle = "null";
|
||||
*/
|
||||
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_CColor, "textcolor");
|
||||
AddSetting(GUIST_CColor, "textcolor-over");
|
||||
AddSetting(GUIST_CColor, "textcolor-pressed");
|
||||
AddSetting(GUIST_CColor, "textcolor-disabled");
|
||||
|
||||
// Static! Only done once
|
||||
if (m_SettingsInfo.empty())
|
||||
{
|
||||
// Setup the base ones too
|
||||
SetupBaseSettingsInfo(m_SettingsInfo);
|
||||
|
||||
GUI_ADD_OFFSET_EXT(SButtonSettings, m_Sprite, "string", "sprite")
|
||||
GUI_ADD_OFFSET_EXT(SButtonSettings, m_SpriteOver, "string", "sprite-over")
|
||||
GUI_ADD_OFFSET_EXT(SButtonSettings, m_SpritePressed, "string", "sprite-pressed")
|
||||
GUI_ADD_OFFSET_EXT(SButtonSettings, m_SpriteDisabled, "string", "sprite-disabled")
|
||||
}
|
||||
// Add text
|
||||
AddText(new SGUIText());
|
||||
}
|
||||
|
||||
CButton::~CButton()
|
||||
{
|
||||
}
|
||||
|
||||
void CButton::SetupText()
|
||||
{
|
||||
if (!GetGUI())
|
||||
return;
|
||||
|
||||
assert(m_GeneratedTexts.size()>=1);
|
||||
|
||||
CStr font;
|
||||
CGUIString caption;
|
||||
GUI<CGUIString>::GetSetting(this, "caption", caption);
|
||||
|
||||
*m_GeneratedTexts[0] = GetGUI()->GenerateText(caption, CStr("verdana12.fnt"), 0, 0);
|
||||
|
||||
// Set position of text
|
||||
m_TextPos = m_CachedActualSize.CenterPoint() - m_GeneratedTexts[0]->m_Size/2;
|
||||
}
|
||||
|
||||
void CButton::HandleMessage(const SGUIMessage &Message)
|
||||
{
|
||||
// Important
|
||||
IGUIButtonBehavior::HandleMessage(Message);
|
||||
IGUITextOwner::HandleMessage(Message);
|
||||
|
||||
switch (Message.type)
|
||||
{
|
||||
|
|
@ -98,31 +100,24 @@ void CButton::Draw()
|
|||
glDisable(GL_TEXTURE_2D);
|
||||
//////////
|
||||
|
||||
if (GetGUI())
|
||||
{
|
||||
bool useBase = false;
|
||||
float bz = GetBufferedZ();
|
||||
|
||||
if (!GetBaseSettings().m_Enabled)
|
||||
{
|
||||
if (m_Settings.m_SpriteDisabled != CStr("null"))
|
||||
GetGUI()->DrawSprite(m_Settings.m_SpriteDisabled, GetBufferedZ(), m_CachedActualSize);
|
||||
else
|
||||
useBase = true;
|
||||
}
|
||||
else
|
||||
if (m_MouseHovering)
|
||||
{
|
||||
if (m_Pressed && m_Settings.m_SpritePressed != CStr("null"))
|
||||
GetGUI()->DrawSprite(m_Settings.m_SpritePressed, GetBufferedZ(), m_CachedActualSize);
|
||||
else
|
||||
if (!m_Pressed && m_Settings.m_SpriteOver != CStr("null"))
|
||||
GetGUI()->DrawSprite(m_Settings.m_SpriteOver, GetBufferedZ(), m_CachedActualSize);
|
||||
else
|
||||
useBase = true;
|
||||
}
|
||||
else useBase = true;
|
||||
CStr sprite, sprite_over, sprite_pressed, sprite_disabled;
|
||||
|
||||
if (useBase)
|
||||
GetGUI()->DrawSprite(m_Settings.m_Sprite, GetBufferedZ(), m_CachedActualSize);
|
||||
}
|
||||
GUI<CStr>::GetSetting(this, "sprite", sprite);
|
||||
GUI<CStr>::GetSetting(this, "sprite-over", sprite_over);
|
||||
GUI<CStr>::GetSetting(this, "sprite-pressed", sprite_pressed);
|
||||
GUI<CStr>::GetSetting(this, "sprite-disabled", sprite_disabled);
|
||||
|
||||
DrawButton(m_CachedActualSize,
|
||||
bz,
|
||||
sprite,
|
||||
sprite_over,
|
||||
sprite_pressed,
|
||||
sprite_disabled);
|
||||
|
||||
|
||||
CColor color = ChooseColor();
|
||||
|
||||
IGUITextOwner::Draw(0, color, m_TextPos, bz+0.1f);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,28 +33,6 @@ gee@pyro.nu
|
|||
// Declarations
|
||||
//--------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Button Settings
|
||||
*/
|
||||
struct SButtonSettings
|
||||
{
|
||||
CStr m_Font;
|
||||
CStr m_Sprite;
|
||||
CStr m_SpriteDisabled;
|
||||
CStr m_SpriteOver;
|
||||
CStr m_SpritePressed;
|
||||
EAlign m_TextAlign;
|
||||
CColor m_TextColor;
|
||||
CColor m_TextColorDisabled;
|
||||
CColor m_TextColorOver;
|
||||
CColor m_TextColorPressed;
|
||||
EValign m_TextValign;
|
||||
CStr m_ToolTip;
|
||||
CStr m_ToolTipStyle;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @author Gustav Larsson
|
||||
*
|
||||
|
|
@ -63,9 +41,8 @@ struct SButtonSettings
|
|||
* @see IGUIObject
|
||||
* @see IGUISettingsObject
|
||||
* @see IGUIButtonBehavior
|
||||
* @see SButtonSettings
|
||||
*/
|
||||
class CButton : public IGUISettingsObject<SButtonSettings>, public IGUIButtonBehavior
|
||||
class CButton : public IGUIButtonBehavior, public IGUITextOwner
|
||||
{
|
||||
GUI_OBJECT(CButton)
|
||||
|
||||
|
|
@ -73,13 +50,6 @@ public:
|
|||
CButton();
|
||||
virtual ~CButton();
|
||||
|
||||
/**
|
||||
* Since we're doing multiple inheritance, this is to avoid error message
|
||||
*
|
||||
* @return Settings infos
|
||||
*/
|
||||
virtual map_Settings GetSettingsInfo() const { return IGUISettingsObject<SButtonSettings>::m_SettingsInfo; }
|
||||
|
||||
virtual void ResetStates() { IGUIButtonBehavior::ResetStates(); }
|
||||
|
||||
/**
|
||||
|
|
@ -93,6 +63,18 @@ public:
|
|||
* Draws the Button
|
||||
*/
|
||||
virtual void Draw();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Sets up text, should be called every time changes has been
|
||||
* made that can change the visual.
|
||||
*/
|
||||
void SetupText();
|
||||
|
||||
/**
|
||||
* Placement of text.
|
||||
*/
|
||||
CPos m_TextPos;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
153
source/gui/CCheckBox.cpp
Executable file
153
source/gui/CCheckBox.cpp
Executable file
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
CCheckBox
|
||||
by Gustav Larsson
|
||||
gee@pyro.nu
|
||||
*/
|
||||
|
||||
//#include "stdafx."
|
||||
#include "GUI.h"
|
||||
#include "CCheckBox.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Constructor / Destructor
|
||||
//-------------------------------------------------------------------
|
||||
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;
|
||||
*/
|
||||
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_int, "square-side");
|
||||
|
||||
// Add text
|
||||
AddText(new SGUIText());
|
||||
}
|
||||
|
||||
CCheckBox::~CCheckBox()
|
||||
{
|
||||
}
|
||||
|
||||
void CCheckBox::SetupText()
|
||||
{
|
||||
if (!GetGUI())
|
||||
return;
|
||||
|
||||
assert(m_GeneratedTexts.size()>=1);
|
||||
|
||||
CStr font;
|
||||
CGUIString caption;
|
||||
//int square_side;
|
||||
GUI<CGUIString>::GetSetting(this, "caption", caption);
|
||||
//GUI<CGUIString>::GetSetting(this, "square-side", square_side);
|
||||
|
||||
// TODO Gee: Establish buffer zones
|
||||
*m_GeneratedTexts[0] = GetGUI()->GenerateText(caption, CStr("verdana12.fnt"), m_CachedActualSize.GetWidth()-20, 0);
|
||||
|
||||
// Set position of text
|
||||
// TODO Gee: Big TODO
|
||||
// m_TextPos.x = m_CachedActualSize.left + 20;
|
||||
// m_TextPos.y = m_CachedActualSize.top;
|
||||
}
|
||||
|
||||
void CCheckBox::HandleMessage(const SGUIMessage &Message)
|
||||
{
|
||||
// Important
|
||||
IGUIButtonBehavior::HandleMessage(Message);
|
||||
|
||||
switch (Message.type)
|
||||
{
|
||||
case GUIM_PRESSED:
|
||||
{
|
||||
bool checked;
|
||||
|
||||
GUI<bool>::GetSetting(this, "checked", checked);
|
||||
checked = !checked;
|
||||
GUI<bool>::SetSetting(this, "checked", checked);
|
||||
|
||||
//GetGUI()->TEMPmessage = "Check box " + string((const TCHAR*)m_Name) + " was " + (m_Settings.m_Checked?"checked":"unchecked");
|
||||
} break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CCheckBox::Draw()
|
||||
{
|
||||
////////// Gee: janwas, this is just temp to see it
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
//////////
|
||||
|
||||
int square_side;
|
||||
GUI<int>::GetSetting(this, "square-side", square_side);
|
||||
|
||||
float bz = GetBufferedZ();
|
||||
|
||||
// Get square
|
||||
// TODO Gee: edit below when CRect has got "height()"
|
||||
int middle = (m_CachedActualSize.bottom - m_CachedActualSize.top)/2;
|
||||
CRect rect;
|
||||
rect.left = m_CachedActualSize.left + middle - square_side/2;
|
||||
rect.right = rect.left + square_side;
|
||||
rect.top = m_CachedActualSize.top + middle - square_side/2;
|
||||
rect.bottom = rect.top + square_side;
|
||||
|
||||
bool checked;
|
||||
GUI<bool>::GetSetting(this, "checked", checked);
|
||||
|
||||
CStr sprite, sprite_over, sprite_pressed, sprite_disabled;
|
||||
|
||||
if (checked)
|
||||
{
|
||||
GUI<CStr>::GetSetting(this, "sprite2", sprite);
|
||||
GUI<CStr>::GetSetting(this, "sprite2-over", sprite_over);
|
||||
GUI<CStr>::GetSetting(this, "sprite2-pressed", sprite_pressed);
|
||||
GUI<CStr>::GetSetting(this, "sprite2-disabled", sprite_disabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI<CStr>::GetSetting(this, "sprite", sprite);
|
||||
GUI<CStr>::GetSetting(this, "sprite-over", sprite_over);
|
||||
GUI<CStr>::GetSetting(this, "sprite-pressed", sprite_pressed);
|
||||
GUI<CStr>::GetSetting(this, "sprite-disabled", sprite_disabled);
|
||||
}
|
||||
|
||||
DrawButton( rect,
|
||||
bz,
|
||||
sprite,
|
||||
sprite_over,
|
||||
sprite_pressed,
|
||||
sprite_disabled);
|
||||
|
||||
CColor color = ChooseColor();
|
||||
|
||||
// IGUITextOwner::Draw(0, color, m_TextPos, bz+0.1f);
|
||||
}
|
||||
75
source/gui/CCheckBox.h
Executable file
75
source/gui/CCheckBox.h
Executable file
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
GUI Object - Check box
|
||||
by Gustav Larsson
|
||||
gee@pyro.nu
|
||||
|
||||
--Overview--
|
||||
|
||||
GUI Object representing a check box
|
||||
|
||||
--More info--
|
||||
|
||||
Check GUI.h
|
||||
|
||||
*/
|
||||
|
||||
#ifndef CCheckBox_H
|
||||
#define CCheckBox_H
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Includes / Compiler directives
|
||||
//--------------------------------------------------------
|
||||
#include "GUI.h"
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Macros
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Types
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Declarations
|
||||
//--------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @author Gustav Larsson
|
||||
*
|
||||
* CheckBox
|
||||
*
|
||||
* @see IGUIObject
|
||||
* @see IGUISettingsObject
|
||||
* @see IGUIButtonBehavior
|
||||
*/
|
||||
class CCheckBox : public IGUIButtonBehavior, public IGUITextOwner
|
||||
{
|
||||
GUI_OBJECT(CCheckBox)
|
||||
|
||||
public:
|
||||
CCheckBox();
|
||||
virtual ~CCheckBox();
|
||||
|
||||
virtual void ResetStates() { IGUIButtonBehavior::ResetStates(); }
|
||||
|
||||
/**
|
||||
* Handle Messages
|
||||
*
|
||||
* @param Message GUI Message
|
||||
*/
|
||||
virtual void HandleMessage(const SGUIMessage &Message);
|
||||
|
||||
/**
|
||||
* Draws the control
|
||||
*/
|
||||
virtual void Draw();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Sets up text, should be called every time changes has been
|
||||
* made that can change the visual.
|
||||
*/
|
||||
void SetupText();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -6,6 +6,13 @@ gee@pyro.nu
|
|||
|
||||
//#include "stdafx."
|
||||
#include "GUI.h"
|
||||
|
||||
// Types - when including them into the engine.
|
||||
#include "CButton.h"
|
||||
#include "CText.h"
|
||||
#include "CCheckBox.h"
|
||||
#include "CRadioButton.h"
|
||||
|
||||
#include <xercesc/dom/DOM.hpp>
|
||||
#include <xercesc/parsers/XercesDOMParser.hpp>
|
||||
#include <xercesc/framework/LocalFileInputSource.hpp>
|
||||
|
|
@ -15,6 +22,9 @@ gee@pyro.nu
|
|||
#include "XercesErrorHandler.h"
|
||||
#include "Prometheus.h"
|
||||
#include "input.h"
|
||||
#include "OverlayText.h"
|
||||
// TODO Gee: Whatever include CRect/CPos/CSize
|
||||
#include "Overlay.h"
|
||||
|
||||
#include <string>
|
||||
#include <assert.h>
|
||||
|
|
@ -28,6 +38,12 @@ using namespace std;
|
|||
#pragma comment(lib, "xerces-c_2.lib")
|
||||
#endif
|
||||
|
||||
// TODO Gee: how to draw overlays?
|
||||
void render(COverlayText* overlaytext)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// called from main loop when (input) events are received.
|
||||
|
|
@ -43,7 +59,7 @@ bool CGUI::HandleEvent(const SDL_Event& ev)
|
|||
{
|
||||
if(ev.type == SDL_MOUSEMOTION)
|
||||
{
|
||||
m_MouseX = ev.motion.x, m_MouseY = ev.motion.y;
|
||||
m_MousePos = CPos(ev.motion.x, ev.motion.y);
|
||||
|
||||
// pNearest will after this point at the hovered object, possibly NULL
|
||||
GUI<SGUIMessage>::RecurseObject(GUIRR_HIDDEN | GUIRR_GHOST, m_BaseObject,
|
||||
|
|
@ -51,14 +67,15 @@ bool CGUI::HandleEvent(const SDL_Event& ev)
|
|||
SGUIMessage(GUIM_MOUSE_MOTION));
|
||||
}
|
||||
|
||||
char buf[30];
|
||||
sprintf(buf, "type = %d", ev.type);
|
||||
TEMPmessage = buf;
|
||||
// TODO Gee: temp-stuff
|
||||
// char buf[30];
|
||||
// sprintf(buf, "type = %d", ev.type);
|
||||
//TEMPmessage = buf;
|
||||
|
||||
if (ev.type == SDL_MOUSEBUTTONDOWN)
|
||||
{
|
||||
sprintf(buf, "button = %d", ev.button.button);
|
||||
TEMPmessage = buf;
|
||||
// sprintf(buf, "button = %d", ev.button.button);
|
||||
//TEMPmessage = buf;
|
||||
}
|
||||
|
||||
// JW: (pre|post)process omitted; what're they for? why would we need any special button_released handling?
|
||||
|
|
@ -68,6 +85,9 @@ bool CGUI::HandleEvent(const SDL_Event& ev)
|
|||
|
||||
try
|
||||
{
|
||||
// TODO Gee: Optimizations needed!
|
||||
// these two recursive function are quite overhead heavy.
|
||||
|
||||
// pNearest will after this point at the hovered object, possibly NULL
|
||||
GUI<IGUIObject*>::RecurseObject(GUIRR_HIDDEN | GUIRR_GHOST, m_BaseObject,
|
||||
&IGUIObject::ChooseMouseOverAndClosest,
|
||||
|
|
@ -80,70 +100,79 @@ bool CGUI::HandleEvent(const SDL_Event& ev)
|
|||
&IGUIObject::UpdateMouseOver,
|
||||
pNearest);
|
||||
|
||||
//if (ev.type == SDL_MOUSEBUTTONDOWN)
|
||||
if (ev.type == SDL_MOUSEBUTTONDOWN)
|
||||
{
|
||||
if (ev.type == SDL_MOUSEBUTTONDOWN)
|
||||
switch (ev.button.button)
|
||||
{
|
||||
switch (ev.button.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
if (pNearest)
|
||||
{
|
||||
pNearest->HandleMessage(SGUIMessage(GUIM_MOUSE_PRESS_LEFT));
|
||||
|
||||
// some temp
|
||||
CClientArea ca;
|
||||
bool hidden;
|
||||
|
||||
/*GUI<CClientArea>::GetSetting(*this, CStr("backdrop"), CStr("size"), ca);
|
||||
GUI<bool>::GetSetting(*this, CStr("backdrop"), CStr("hidden"), hidden);
|
||||
|
||||
//hidden = !hidden;
|
||||
ca.pixel.right += 3;
|
||||
ca.pixel.bottom += 3;
|
||||
|
||||
GUI<CClientArea>::SetSetting(*this, CStr("backdrop"), CStr("size"), ca);
|
||||
GUI<bool>::SetSetting(*this, CStr("backdrop"), CStr("hidden"), hidden);
|
||||
*/ }
|
||||
break;
|
||||
|
||||
case 3: // wheel down
|
||||
if (pNearest)
|
||||
{
|
||||
pNearest->HandleMessage(SGUIMessage(GUIM_MOUSE_WHEEL_DOWN));
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: // wheel up
|
||||
if (pNearest)
|
||||
{
|
||||
pNearest->HandleMessage(SGUIMessage(GUIM_MOUSE_WHEEL_UP));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
if (ev.type == SDL_MOUSEBUTTONUP)
|
||||
{
|
||||
if (ev.button.button == SDL_BUTTON_LEFT)
|
||||
{
|
||||
if (pNearest)
|
||||
pNearest->HandleMessage(SGUIMessage(GUIM_MOUSE_RELEASE_LEFT));
|
||||
}
|
||||
|
||||
// Reset all states on all visible objects
|
||||
GUI<>::RecurseObject(GUIRR_HIDDEN, m_BaseObject,
|
||||
&IGUIObject::ResetStates);
|
||||
|
||||
// It will have reset the mouse over of the current hovered, so we'll
|
||||
// have to restore that
|
||||
case SDL_BUTTON_LEFT:
|
||||
if (pNearest)
|
||||
pNearest->m_MouseHovering = true;
|
||||
{
|
||||
pNearest->HandleMessage(SGUIMessage(GUIM_MOUSE_PRESS_LEFT));
|
||||
}
|
||||
|
||||
{
|
||||
// some temp
|
||||
/* CClientArea ca;
|
||||
bool hidden;
|
||||
|
||||
GUI<CClientArea>::GetSetting(*this, CStr("backdrop43"), CStr("size"), ca);
|
||||
|
||||
//hidden = !hidden;
|
||||
ca.pixel.right -= 3;
|
||||
|
||||
GUI<CClientArea>::SetSetting(*this, CStr("backdrop43"), CStr("size"), ca);
|
||||
*/ }
|
||||
break;
|
||||
|
||||
case 3: // wheel down
|
||||
if (pNearest)
|
||||
{
|
||||
pNearest->HandleMessage(SGUIMessage(GUIM_MOUSE_WHEEL_DOWN));
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: // wheel up
|
||||
if (pNearest)
|
||||
{
|
||||
pNearest->HandleMessage(SGUIMessage(GUIM_MOUSE_WHEEL_UP));
|
||||
}
|
||||
break;
|
||||
|
||||
// TODO Gee: Just temp
|
||||
case SDL_BUTTON_RIGHT:
|
||||
{
|
||||
CClientArea ca;
|
||||
GUI<CClientArea>::GetSetting(*this, CStr("backdrop43"), CStr("size"), ca);
|
||||
|
||||
//hidden = !hidden;
|
||||
ca.pixel.right -= 3;
|
||||
|
||||
GUI<CClientArea>::SetSetting(*this, CStr("backdrop43"), CStr("size"), ca);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
if (ev.type == SDL_MOUSEBUTTONUP)
|
||||
{
|
||||
if (ev.button.button == SDL_BUTTON_LEFT)
|
||||
{
|
||||
if (pNearest)
|
||||
pNearest->HandleMessage(SGUIMessage(GUIM_MOUSE_RELEASE_LEFT));
|
||||
}
|
||||
|
||||
// Reset all states on all visible objects
|
||||
GUI<>::RecurseObject(GUIRR_HIDDEN, m_BaseObject,
|
||||
&IGUIObject::ResetStates);
|
||||
|
||||
// It will have reset the mouse over of the current hovered, so we'll
|
||||
// have to restore that
|
||||
if (pNearest)
|
||||
pNearest->m_MouseHovering = true;
|
||||
}
|
||||
}
|
||||
catch (PS_RESULT e)
|
||||
|
|
@ -164,7 +193,7 @@ bool CGUI::HandleEvent(const SDL_Event& ev)
|
|||
//-------------------------------------------------------------------
|
||||
// Constructor / Destructor
|
||||
//-------------------------------------------------------------------
|
||||
CGUI::CGUI()
|
||||
CGUI::CGUI() : m_InternalNameNumber(0)
|
||||
{
|
||||
m_BaseObject = new CGUIDummyObject;
|
||||
m_BaseObject->SetGUI(this);
|
||||
|
|
@ -198,8 +227,11 @@ void CGUI::Initialize()
|
|||
// Add base types!
|
||||
// You can also add types outside the GUI to extend the flexibility of the GUI.
|
||||
// Prometheus though will have all the object types inserted from here.
|
||||
AddObjectType("button", &CButton::ConstructObject);
|
||||
AddObjectType("text", &CText::ConstructObject);
|
||||
AddObjectType("empty", &CGUIDummyObject::ConstructObject);
|
||||
AddObjectType("button", &CButton::ConstructObject);
|
||||
AddObjectType("text", &CText::ConstructObject);
|
||||
AddObjectType("checkbox", &CCheckBox::ConstructObject);
|
||||
AddObjectType("radiobutton", &CRadioButton::ConstructObject);
|
||||
}
|
||||
|
||||
void CGUI::Process()
|
||||
|
|
@ -301,10 +333,12 @@ void CGUI::DrawSprite(const CStr &SpriteName,
|
|||
const CRect &Clipping)
|
||||
{
|
||||
// This is not an error, it's just a choice not to draw any sprite.
|
||||
if (SpriteName == CStr("null") || SpriteName == CStr())
|
||||
if (SpriteName == CStr())
|
||||
return;
|
||||
|
||||
bool DoClipping = (Clipping != CRect(0,0,0,0));
|
||||
const char * buf = SpriteName;
|
||||
|
||||
bool DoClipping = (Clipping != CRect());
|
||||
CGUISprite Sprite;
|
||||
|
||||
// Fetch real sprite from name
|
||||
|
|
@ -325,6 +359,9 @@ void CGUI::DrawSprite(const CStr &SpriteName,
|
|||
{
|
||||
CRect real = cit->m_Size.GetClientArea(Rect);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(0.f, 0.f, cit->m_DeltaZ);
|
||||
|
||||
glColor3f(cit->m_BackColor.r , cit->m_BackColor.g, cit->m_BackColor.b);
|
||||
//glColor3f((float)real.right/1000.f, 0.5f, 0.5f);
|
||||
|
||||
|
|
@ -335,6 +372,8 @@ void CGUI::DrawSprite(const CStr &SpriteName,
|
|||
glVertex2i(real.left, real.top);
|
||||
glVertex2i(real.right, real.top);
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
|
|
@ -356,7 +395,6 @@ void CGUI::Destroy()
|
|||
}
|
||||
|
||||
delete it->second;
|
||||
it->second = NULL;
|
||||
}
|
||||
|
||||
// Clear all
|
||||
|
|
@ -383,6 +421,8 @@ void CGUI::AddObject(IGUIObject* pObject)
|
|||
// Cache tree
|
||||
GUI<>::RecurseObject(0, pObject, &IGUIObject::UpdateCachedSize);
|
||||
|
||||
// Loaded
|
||||
GUI<SGUIMessage>::RecurseObject(0, pObject, &IGUIObject::HandleMessage, SGUIMessage(GUIM_LOAD));
|
||||
}
|
||||
catch (PS_RESULT e)
|
||||
{
|
||||
|
|
@ -413,10 +453,316 @@ void CGUI::UpdateObjects()
|
|||
|
||||
bool CGUI::ObjectExists(const CStr &Name) const
|
||||
{
|
||||
if (m_pAllObjects.count(Name))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
return m_pAllObjects.count(Name);
|
||||
}
|
||||
|
||||
// private struct used only in GenerateText(...)
|
||||
static struct SGenerateTextImage
|
||||
{
|
||||
int m_YFrom, // The images starting location in Y
|
||||
m_YTo, // The images end location in Y
|
||||
m_Indentation; // The image width in other words
|
||||
|
||||
// Some help functions
|
||||
// TODO Gee: CRect => CPoint ?
|
||||
void SetupSpriteCall(const bool &Left, SGUIText::SSpriteCall &SpriteCall,
|
||||
const int &width, const int &y,
|
||||
const CSize &Size, const CStr &TextureName,
|
||||
const int &BufferZone)
|
||||
{
|
||||
// TODO Gee: Temp hardcoded values
|
||||
SpriteCall.m_Area.top = y+BufferZone;
|
||||
SpriteCall.m_Area.bottom = y+BufferZone + Size.cy;
|
||||
|
||||
if (Left)
|
||||
{
|
||||
SpriteCall.m_Area.left = BufferZone;
|
||||
SpriteCall.m_Area.right = Size.cx+BufferZone;
|
||||
}
|
||||
else
|
||||
{
|
||||
SpriteCall.m_Area.left = width-BufferZone - Size.cx;
|
||||
SpriteCall.m_Area.right = width-BufferZone;
|
||||
}
|
||||
|
||||
SpriteCall.m_TextureName = TextureName;
|
||||
|
||||
m_YFrom = SpriteCall.m_Area.top-BufferZone;
|
||||
m_YTo = SpriteCall.m_Area.bottom+BufferZone;
|
||||
m_Indentation = Size.cx+BufferZone*2;
|
||||
}
|
||||
};
|
||||
|
||||
SGUIText CGUI::GenerateText(const CGUIString &string, /*const CColor &Color, */
|
||||
const CStr &Font, const int &Width, const int &BufferZone)
|
||||
{
|
||||
SGUIText Text; // object we're generating
|
||||
|
||||
if (string.m_Words.size() == 0)
|
||||
return Text;
|
||||
|
||||
int x=BufferZone, y=BufferZone; // drawing pointer
|
||||
int from=0;
|
||||
bool done=false;
|
||||
|
||||
// Images on the left or the right side.
|
||||
vector<SGenerateTextImage> Images[2];
|
||||
int pos_last_img=-1; // Position in the string where last img (either left or right) were encountered.
|
||||
// in order to avoid duplicate processing.
|
||||
|
||||
// Easier to read.
|
||||
bool WordWrapping = (Width != 0);
|
||||
|
||||
// Go through string word by word
|
||||
for (int i=0; i<string.m_Words.size()-1 && !done; ++i)
|
||||
{
|
||||
// Pre-process each line one time, so we know which floating images
|
||||
// will be added for that line.
|
||||
|
||||
// Generated stuff is stored in Feedback.
|
||||
CGUIString::SFeedback Feedback;
|
||||
|
||||
// Preliminary line_height, used for word-wrapping with floating images.
|
||||
int prelim_line_height=0;
|
||||
|
||||
// Width and height of all text calls generated.
|
||||
string.GenerateTextCall(Feedback, Font, /*CColor(),*/
|
||||
string.m_Words[i], string.m_Words[i+1]);
|
||||
|
||||
// Loop through our images queues, to see if images has been added.
|
||||
|
||||
// Check if this has already been processed.
|
||||
// Also, floating images are only applicable if Word-Wrapping is on
|
||||
if (WordWrapping && i > pos_last_img)
|
||||
{
|
||||
// Loop left/right
|
||||
for (int j=0; j<2; ++j)
|
||||
{
|
||||
for (vector<CStr>::const_iterator it = Feedback.m_Images[j].begin();
|
||||
it != Feedback.m_Images[j].end();
|
||||
++it)
|
||||
{
|
||||
SGUIText::SSpriteCall SpriteCall;
|
||||
SGenerateTextImage Image;
|
||||
|
||||
// Y is if no other floating images is above, y. Else it is placed
|
||||
// after the last image, like a stack downwards.
|
||||
int _y;
|
||||
if (Images[j].size() > 0)
|
||||
_y = max(y, Images[j].back().m_YTo);
|
||||
else
|
||||
_y = y;
|
||||
|
||||
// TODO Gee: CSize temp
|
||||
CSize size; size.cx = 100; size.cy = 100;
|
||||
Image.SetupSpriteCall((j==CGUIString::SFeedback::Left), SpriteCall, Width, _y, size, CStr("white-border"), BufferZone);
|
||||
|
||||
// Check if image is the lowest thing.
|
||||
Text.m_Size.cy = max(Text.m_Size.cy, Image.m_YTo);
|
||||
|
||||
Images[j].push_back(Image);
|
||||
Text.m_SpriteCalls.push_back(SpriteCall);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pos_last_img = max(pos_last_img, i);
|
||||
|
||||
x += Feedback.m_Size.cx;
|
||||
prelim_line_height = max(prelim_line_height, Feedback.m_Size.cy);
|
||||
|
||||
// If Width is 0, then there's no word-wrapping, disable NewLine.
|
||||
if ((WordWrapping && (x > Width-BufferZone || Feedback.m_NewLine)) || i == string.m_Words.size()-2)
|
||||
{
|
||||
// Change from to i, but first keep a copy of its value.
|
||||
int temp_from = from;
|
||||
from = i;
|
||||
|
||||
static const int From=0, To=1;
|
||||
//int width_from=0, width_to=width;
|
||||
int width_range[2];
|
||||
width_range[From] = BufferZone;
|
||||
width_range[To] = Width - BufferZone;
|
||||
|
||||
// Floating images are only appicable if word-wrapping is enabled.
|
||||
if (WordWrapping)
|
||||
{
|
||||
// Decide width of the line. We need to iterate our floating images.
|
||||
// this won't be exact because we're assuming the line_height
|
||||
// will be as our preliminary calculation said. But that may change,
|
||||
// although we'd have to add a couple of more loops to try straightening
|
||||
// this problem out, and it is very unlikely to happen noticably if one
|
||||
// stuctures his text in a stylistically pure fashion. Even if not, it
|
||||
// is still quite unlikely it will happen.
|
||||
// Loop through left and right side, from and to.
|
||||
for (int j=0; j<2; ++j)
|
||||
{
|
||||
for (vector<SGenerateTextImage>::const_iterator it = Images[j].begin();
|
||||
it != Images[j].end();
|
||||
++it)
|
||||
{
|
||||
// We're working with two intervals here, the image's and the line height's.
|
||||
// let's find the union of these two.
|
||||
int union_from, union_to;
|
||||
|
||||
union_from = max(y, it->m_YFrom);
|
||||
union_to = min(y+prelim_line_height, it->m_YTo);
|
||||
|
||||
// The union is not ø
|
||||
if (union_to > union_from)
|
||||
{
|
||||
if (j == From)
|
||||
width_range[From] = max(width_range[From], it->m_Indentation);
|
||||
else
|
||||
width_range[To] = min(width_range[To], Width - it->m_Indentation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reset X for the next loop
|
||||
x = width_range[From];
|
||||
|
||||
// Now we'll do another loop to figure out the height of
|
||||
// the line (the height of the largest character). This
|
||||
// couldn't be determined in the first loop (main loop)
|
||||
// because it didn't regard images, so we don't know
|
||||
// if all characters processed, will actually be involved
|
||||
// in that line.
|
||||
int line_height=0;
|
||||
for (int j=temp_from; j<=i; ++j)
|
||||
{
|
||||
// We don't want to use Feedback now, so we'll have to use
|
||||
// another.
|
||||
CGUIString::SFeedback Feedback2;
|
||||
|
||||
string.GenerateTextCall(Feedback2, Font, /*CColor(),*/
|
||||
string.m_Words[j], string.m_Words[j+1]);
|
||||
|
||||
// Append X value.
|
||||
x += Feedback2.m_Size.cx;
|
||||
|
||||
if (WordWrapping && x > width_range[To] && j!=temp_from && !Feedback2.m_NewLine)
|
||||
break;
|
||||
|
||||
// Let line_height be the maximum m_Height we encounter.
|
||||
line_height = max(line_height, Feedback2.m_Size.cy);
|
||||
|
||||
if (WordWrapping && Feedback2.m_NewLine)
|
||||
break;
|
||||
}
|
||||
|
||||
// Reset x once more
|
||||
x = width_range[From];
|
||||
|
||||
// Do the real processing now
|
||||
for (int j=temp_from; j<=i; ++j)
|
||||
{
|
||||
// We don't want to use Feedback now, so we'll have to use
|
||||
// another.
|
||||
CGUIString::SFeedback Feedback2;
|
||||
|
||||
// Defaults
|
||||
string.GenerateTextCall(Feedback2, Font, /*Color, */
|
||||
string.m_Words[j], string.m_Words[j+1]);
|
||||
|
||||
// Iterate all and set X/Y values
|
||||
// Since X values are not set, we need to make an internal
|
||||
// iteration with an increment that will append the internal
|
||||
// x, that is what x_pointer is for.
|
||||
int x_pointer=0;
|
||||
|
||||
vector<SGUIText::STextCall>::iterator it;
|
||||
for (it = Feedback2.m_TextCalls.begin(); it != Feedback2.m_TextCalls.end(); ++it)
|
||||
{
|
||||
it->m_Pos = CPos(x + x_pointer, y + line_height - it->m_Size.cy);
|
||||
|
||||
x_pointer += it->m_Size.cx;
|
||||
|
||||
if (it->m_pSpriteCall)
|
||||
{
|
||||
it->m_pSpriteCall->m_Area =
|
||||
it->m_pSpriteCall->m_Area + it->m_Pos;
|
||||
}
|
||||
}
|
||||
|
||||
// Append X value.
|
||||
x += Feedback2.m_Size.cx;
|
||||
|
||||
Text.m_Size.cx = max(Text.m_Size.cx, x+BufferZone);
|
||||
|
||||
// The first word overrides the width limit, that we
|
||||
// do in those cases, are just draw that word even
|
||||
// though it'll extend the object.
|
||||
if (WordWrapping) // only if word-wrapping is applicable
|
||||
{
|
||||
if (Feedback2.m_NewLine)
|
||||
{
|
||||
from = j+1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
if (x > width_range[To] && j==temp_from)
|
||||
{
|
||||
from = j+1;
|
||||
// do not break, since we want it to be added to m_TextCalls
|
||||
}
|
||||
else
|
||||
if (x > width_range[To])
|
||||
{
|
||||
from = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the whole Feedback2.m_TextCalls to our m_TextCalls.
|
||||
Text.m_TextCalls.insert(Text.m_TextCalls.end(), Feedback2.m_TextCalls.begin(), Feedback2.m_TextCalls.end());
|
||||
Text.m_SpriteCalls.insert(Text.m_SpriteCalls.end(), Feedback2.m_SpriteCalls.begin(), Feedback2.m_SpriteCalls.end());
|
||||
|
||||
if (j == string.m_Words.size()-2)
|
||||
done = true;
|
||||
}
|
||||
|
||||
// Reset X, and append Y.
|
||||
x = 0;
|
||||
y += line_height;
|
||||
|
||||
// Update height of all
|
||||
Text.m_Size.cy = max(Text.m_Size.cy, y+BufferZone);
|
||||
|
||||
// Now if we entered as from = i, then we want
|
||||
// i being one minus that, so that it will become
|
||||
// the same i in the next loop. The difference is that
|
||||
// we're on a new line now.
|
||||
i = from-1;
|
||||
}
|
||||
}
|
||||
|
||||
return Text;
|
||||
}
|
||||
|
||||
void CGUI::DrawText(const SGUIText &Text, const CColor &DefaultColor,
|
||||
const CPos &pos, const float &z)
|
||||
{
|
||||
for (vector<SGUIText::STextCall>::const_iterator it=Text.m_TextCalls.begin();
|
||||
it!=Text.m_TextCalls.end();
|
||||
++it)
|
||||
{
|
||||
if (it->m_pSpriteCall)
|
||||
continue;
|
||||
|
||||
COverlayText txt(pos.x+it->m_Pos.x, pos.y+it->m_Pos.y,
|
||||
z, it->m_Font, it->m_String,
|
||||
(it->m_UseCustomColor?it->m_Color:DefaultColor));
|
||||
render(&txt);
|
||||
}
|
||||
|
||||
for (vector<SGUIText::SSpriteCall>::const_iterator it=Text.m_SpriteCalls.begin();
|
||||
it!=Text.m_SpriteCalls.end();
|
||||
++it)
|
||||
{
|
||||
DrawSprite(it->m_TextureName, z, it->m_Area + pos);
|
||||
}
|
||||
}
|
||||
|
||||
void CGUI::ReportParseError(const CStr &str, ...)
|
||||
|
|
@ -427,6 +773,8 @@ void CGUI::ReportParseError(const CStr &str, ...)
|
|||
/// g_nemLog("*** GUI Tree Creation Errors");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Important, set ParseError to true
|
||||
++m_Errors;
|
||||
/* TODO Gee: (MEGA)
|
||||
|
|
@ -540,7 +888,7 @@ void CGUI::LoadXMLFile(const string &Filename)
|
|||
// XML Reading Xerces Specific Sub-Routines
|
||||
//===================================================================
|
||||
|
||||
void CGUI::Xerces_ReadRootObjects(XERCES_CPP_NAMESPACE::DOMElement *pElement)
|
||||
void CGUI::Xerces_ReadRootObjects(DOMElement *pElement)
|
||||
{
|
||||
// Iterate main children
|
||||
// they should all be <object> elements
|
||||
|
|
@ -558,7 +906,7 @@ void CGUI::Xerces_ReadRootObjects(XERCES_CPP_NAMESPACE::DOMElement *pElement)
|
|||
}
|
||||
}
|
||||
|
||||
void CGUI::Xerces_ReadRootSprites(XERCES_CPP_NAMESPACE::DOMElement *pElement)
|
||||
void CGUI::Xerces_ReadRootSprites(DOMElement *pElement)
|
||||
{
|
||||
// Iterate main children
|
||||
// they should all be <sprite> elements
|
||||
|
|
@ -576,7 +924,7 @@ void CGUI::Xerces_ReadRootSprites(XERCES_CPP_NAMESPACE::DOMElement *pElement)
|
|||
}
|
||||
}
|
||||
|
||||
void CGUI::Xerces_ReadRootStyles(XERCES_CPP_NAMESPACE::DOMElement *pElement)
|
||||
void CGUI::Xerces_ReadRootStyles(DOMElement *pElement)
|
||||
{
|
||||
// Iterate main children
|
||||
// they should all be <styles> elements
|
||||
|
|
@ -594,7 +942,7 @@ void CGUI::Xerces_ReadRootStyles(XERCES_CPP_NAMESPACE::DOMElement *pElement)
|
|||
}
|
||||
}
|
||||
|
||||
void CGUI::Xerces_ReadRootSetup(XERCES_CPP_NAMESPACE::DOMElement *pElement)
|
||||
void CGUI::Xerces_ReadRootSetup(DOMElement *pElement)
|
||||
{
|
||||
// Iterate main children
|
||||
// they should all be <icon>, <scrollbar> or <tooltip>.
|
||||
|
|
@ -665,7 +1013,6 @@ void CGUI::Xerces_ReadObject(DOMElement *pElement, IGUIObject *pParent)
|
|||
}
|
||||
else object->LoadStyle(*this, argStyle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
|
|
@ -683,6 +1030,10 @@ void CGUI::Xerces_ReadObject(DOMElement *pElement, IGUIObject *pParent)
|
|||
CStr attr_name = XMLString::transcode( attr->getName() );
|
||||
CStr attr_value = XMLString::transcode( attr->getValue() );
|
||||
|
||||
// If value is "null", then it is equivalent as never being entered
|
||||
if (attr_value == CStr("null"))
|
||||
continue;
|
||||
|
||||
// Ignore "type" and "style", we've already checked it
|
||||
if (attr_name == CStr("type") || attr_name == CStr("style") )
|
||||
continue;
|
||||
|
|
@ -711,10 +1062,11 @@ void CGUI::Xerces_ReadObject(DOMElement *pElement, IGUIObject *pParent)
|
|||
}
|
||||
}
|
||||
|
||||
// Check if name isn't set, report error in that case
|
||||
// Check if name isn't set, generate an internal name in that case.
|
||||
if (!NameSet)
|
||||
{
|
||||
// TODO Gee: Generate internal name!
|
||||
object->SetName(CStr("__internal(") + CStr(m_InternalNameNumber) + CStr(")"));
|
||||
++m_InternalNameNumber;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -759,8 +1111,15 @@ void CGUI::Xerces_ReadObject(DOMElement *pElement, IGUIObject *pParent)
|
|||
// Thank you CStr =)
|
||||
caption.Trim(PS_TRIM_BOTH);
|
||||
|
||||
// Set the setting caption to this
|
||||
GUI<CStr>::SetSetting(object, "caption", caption);
|
||||
try
|
||||
{
|
||||
// Set the setting caption to this
|
||||
object->SetSetting("caption", caption);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// There is no harm if the object didn't have a "caption"
|
||||
}
|
||||
}
|
||||
// else
|
||||
// TODO Gee: give warning
|
||||
|
|
@ -779,9 +1138,12 @@ void CGUI::Xerces_ReadObject(DOMElement *pElement, IGUIObject *pParent)
|
|||
}
|
||||
else
|
||||
{
|
||||
bool absolute;
|
||||
GUI<bool>::GetSetting(object, "absolute", absolute);
|
||||
|
||||
// If the object is absolute, we'll have to get the parent's Z buffered,
|
||||
// and add to that!
|
||||
if (object->GetBaseSettings().m_Absolute)
|
||||
if (absolute)
|
||||
{
|
||||
GUI<float>::SetSetting(object, "z", pParent->GetBufferedZ() + 10.f);
|
||||
}
|
||||
|
|
@ -811,7 +1173,7 @@ void CGUI::Xerces_ReadObject(DOMElement *pElement, IGUIObject *pParent)
|
|||
}
|
||||
}
|
||||
|
||||
void CGUI::Xerces_ReadSprite(XERCES_CPP_NAMESPACE::DOMElement *pElement)
|
||||
void CGUI::Xerces_ReadSprite(DOMElement *pElement)
|
||||
{
|
||||
assert(pElement);
|
||||
|
||||
|
|
@ -862,7 +1224,7 @@ void CGUI::Xerces_ReadSprite(XERCES_CPP_NAMESPACE::DOMElement *pElement)
|
|||
m_Sprites[name] = sprite;
|
||||
}
|
||||
|
||||
void CGUI::Xerces_ReadImage(XERCES_CPP_NAMESPACE::DOMElement *pElement, CGUISprite &parent)
|
||||
void CGUI::Xerces_ReadImage(DOMElement *pElement, CGUISprite &parent)
|
||||
{
|
||||
assert(pElement);
|
||||
|
||||
|
|
@ -899,6 +1261,16 @@ void CGUI::Xerces_ReadImage(XERCES_CPP_NAMESPACE::DOMElement *pElement, CGUISpri
|
|||
else image.m_Size = ca;
|
||||
}
|
||||
else
|
||||
if (attr_name == CStr("z-level"))
|
||||
{
|
||||
int z_level;
|
||||
if (!GUI<int>::ParseString(attr_value, z_level))
|
||||
{
|
||||
// TODO Gee: Error
|
||||
}
|
||||
else image.m_DeltaZ = (float)z_level/100.f;
|
||||
}
|
||||
else
|
||||
if (attr_name == CStr("backcolor"))
|
||||
{
|
||||
CColor color;
|
||||
|
|
@ -923,7 +1295,7 @@ void CGUI::Xerces_ReadImage(XERCES_CPP_NAMESPACE::DOMElement *pElement, CGUISpri
|
|||
parent.AddImage(image);
|
||||
}
|
||||
|
||||
void CGUI::Xerces_ReadStyle(XERCES_CPP_NAMESPACE::DOMElement *pElement)
|
||||
void CGUI::Xerces_ReadStyle(DOMElement *pElement)
|
||||
{
|
||||
assert(pElement);
|
||||
|
||||
|
|
@ -958,7 +1330,7 @@ void CGUI::Xerces_ReadStyle(XERCES_CPP_NAMESPACE::DOMElement *pElement)
|
|||
m_Styles[name] = style;
|
||||
}
|
||||
|
||||
void CGUI::Xerces_ReadScrollBarStyle(XERCES_CPP_NAMESPACE::DOMElement *pElement)
|
||||
void CGUI::Xerces_ReadScrollBarStyle(DOMElement *pElement)
|
||||
{
|
||||
assert(pElement);
|
||||
|
||||
|
|
@ -978,6 +1350,9 @@ void CGUI::Xerces_ReadScrollBarStyle(XERCES_CPP_NAMESPACE::DOMElement *pElement)
|
|||
CStr attr_name = XMLString::transcode( attr->getName() );
|
||||
CStr attr_value = XMLString::transcode( attr->getValue() );
|
||||
|
||||
if (attr_value == CStr("null"))
|
||||
continue;
|
||||
|
||||
if (attr_name == CStr("name"))
|
||||
name = attr_value;
|
||||
else
|
||||
|
|
@ -990,6 +1365,79 @@ void CGUI::Xerces_ReadScrollBarStyle(XERCES_CPP_NAMESPACE::DOMElement *pElement)
|
|||
}
|
||||
scrollbar.m_Width = i;
|
||||
}
|
||||
else
|
||||
if (attr_name == CStr("minimum-bar-size"))
|
||||
{
|
||||
int i;
|
||||
if (!GUI<int>::ParseString(attr_value, i))
|
||||
{
|
||||
// TODO Gee: Report in log file
|
||||
}
|
||||
scrollbar.m_MinimumBarSize = i;
|
||||
}
|
||||
else
|
||||
if (attr_name == CStr("sprite-button-top"))
|
||||
scrollbar.m_SpriteButtonTop = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-button-top-pressed"))
|
||||
scrollbar.m_SpriteButtonTopPressed = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-button-top-disabled"))
|
||||
scrollbar.m_SpriteButtonTopDisabled = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-button-top-over"))
|
||||
scrollbar.m_SpriteButtonTopOver = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-button-bottom"))
|
||||
scrollbar.m_SpriteButtonBottom = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-button-bottom-pressed"))
|
||||
scrollbar.m_SpriteButtonBottomPressed = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-button-bottom-disabled"))
|
||||
scrollbar.m_SpriteButtonBottomDisabled = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-button-bottom-over"))
|
||||
scrollbar.m_SpriteButtonBottomOver = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-back-vertical"))
|
||||
scrollbar.m_SpriteBackVertical = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-bar-vertical"))
|
||||
scrollbar.m_SpriteBarVertical = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-bar-vertical-over"))
|
||||
scrollbar.m_SpriteBarVerticalOver = attr_value;
|
||||
else
|
||||
if (attr_name == CStr("sprite-bar-vertical-pressed"))
|
||||
scrollbar.m_SpriteBarVerticalPressed = attr_value;
|
||||
|
||||
/*
|
||||
CStr m_SpriteButtonTop;
|
||||
CStr m_SpriteButtonTopPressed;
|
||||
CStr m_SpriteButtonTopDisabled;
|
||||
|
||||
CStr m_SpriteButtonBottom;
|
||||
CStr m_SpriteButtonBottomPressed;
|
||||
CStr m_SpriteButtonBottomDisabled;
|
||||
|
||||
CStr m_SpriteScrollBackHorizontal;
|
||||
CStr m_SpriteScrollBarHorizontal;
|
||||
|
||||
|
||||
CStr m_SpriteButtonLeft;
|
||||
CStr m_SpriteButtonLeftPressed;
|
||||
CStr m_SpriteButtonLeftDisabled;
|
||||
|
||||
CStr m_SpriteButtonRight;
|
||||
CStr m_SpriteButtonRightPressed;
|
||||
CStr m_SpriteButtonRightDisabled;
|
||||
|
||||
CStr m_SpriteScrollBackVertical;
|
||||
CStr m_SpriteScrollBarVertical;
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -108,7 +108,18 @@ public:
|
|||
* @param Clipping The sprite shouldn't be drawn outside this rectangle
|
||||
*/
|
||||
void DrawSprite(const CStr &SpriteName, const float &Z,
|
||||
const CRect &Rect, const CRect &Clipping=CRect(0,0,0,0));
|
||||
const CRect &Rect, const CRect &Clipping=CRect());
|
||||
|
||||
/**
|
||||
* Draw a SGUIText object
|
||||
*
|
||||
* @param Text Text object.
|
||||
* @param DefaultColor Color used if no tag applied.
|
||||
* @param pos position
|
||||
* @param z z value.
|
||||
*/
|
||||
void DrawText(const SGUIText &Text, const CColor &DefaultColor,
|
||||
const CPos &pos, const float &z);
|
||||
|
||||
/**
|
||||
* Clean up, call this to clean up all memory allocated
|
||||
|
|
@ -169,6 +180,24 @@ public:
|
|||
*/
|
||||
void UpdateResolution();
|
||||
|
||||
/**
|
||||
* Generate a SGUIText object from the inputted string.
|
||||
* The function will break down the string and its
|
||||
* tags to calculate exactly which rendering queries
|
||||
* will be sent to the Renderer.
|
||||
*
|
||||
* Done through the CGUI since it can communicate with
|
||||
*
|
||||
* @param Text Text to generate SGUIText object from
|
||||
* @param Color Default color
|
||||
* @param Font Default font, notice both Default color and defult 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.
|
||||
*/
|
||||
SGUIText GenerateText(const CGUIString &Text, /*const CColor &Color, */
|
||||
const CStr &Font, const int &Width, const int &BufferZone);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Updates the object pointers, needs to be called each
|
||||
|
|
@ -385,9 +414,10 @@ private:
|
|||
* ChooseMouseOverAndClosest broadcast -
|
||||
* we'd need to pack this and pNearest in a struct
|
||||
*/
|
||||
u16 m_MouseX, m_MouseY;
|
||||
CPos m_MousePos;
|
||||
|
||||
/// Used when reading in XML files
|
||||
// TODO Gee: Used?
|
||||
int16 m_Errors;
|
||||
|
||||
//@}
|
||||
|
|
@ -411,6 +441,14 @@ private:
|
|||
*/
|
||||
map_pObjects m_pAllObjects;
|
||||
|
||||
/**
|
||||
* Number of object that has been given name automatically.
|
||||
* the name given will be '__internal(#)', the number (#)
|
||||
* being this variable. When an object's name has been set
|
||||
* as followed, the value will increment.
|
||||
*/
|
||||
int m_InternalNameNumber;
|
||||
|
||||
/**
|
||||
* Function pointers to functions that constructs
|
||||
* IGUIObjects by name... For instance m_ObjectTypes["button"]
|
||||
|
|
|
|||
|
|
@ -9,81 +9,182 @@ gee@pyro.nu
|
|||
|
||||
using namespace std;
|
||||
|
||||
void CGUIScrollBarVertical::SetPosFromMousePos(int _x, int _y)
|
||||
CGUIScrollBarVertical::CGUIScrollBarVertical()
|
||||
{
|
||||
m_Pos = m_PosWhenPressed + ((float)_y-m_BarPressedAtY)/(m_Length-GetStyle().m_Width*2)*2.f;
|
||||
}
|
||||
|
||||
CGUIScrollBarVertical::~CGUIScrollBarVertical()
|
||||
{
|
||||
}
|
||||
|
||||
void CGUIScrollBarVertical::SetPosFromMousePos(const CPos &mouse)
|
||||
{
|
||||
if (!GetStyle())
|
||||
return;
|
||||
|
||||
m_Pos = (m_PosWhenPressed + (float)m_ScrollRange*((float)mouse.y-m_BarPressedAtPos.y)/(m_Length-GetStyle()->m_Width*2));
|
||||
}
|
||||
|
||||
void CGUIScrollBarVertical::Draw()
|
||||
{
|
||||
int StartX = (m_RightAligned)?(m_X-GetStyle().m_Width):(m_X);
|
||||
if (!GetStyle())
|
||||
{
|
||||
// TODO Gee: Report in error log
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw background
|
||||
g_GUI.DrawSprite(GetStyle().m_SpriteScrollBackVertical, m_Z+0.1f,
|
||||
CRect( StartX,
|
||||
m_Y+GetStyle().m_Width,
|
||||
StartX+GetStyle().m_Width,
|
||||
m_Y+m_Length-GetStyle().m_Width)
|
||||
);
|
||||
if (GetGUI())
|
||||
{
|
||||
CRect outline = GetOuterRect();
|
||||
|
||||
// Draw top button
|
||||
g_GUI.DrawSprite(GetStyle().m_SpriteButtonTop, m_Z+0.2f, CRect(StartX, m_Y, StartX+GetStyle().m_Width, m_Y+GetStyle().m_Width));
|
||||
|
||||
// Draw bottom button
|
||||
g_GUI.DrawSprite(GetStyle().m_SpriteButtonBottom, m_Z+0.2f, CRect(StartX, m_Y+m_Length-GetStyle().m_Width, StartX+GetStyle().m_Width, m_Y+m_Length));
|
||||
// Draw background
|
||||
GetGUI()->DrawSprite(GetStyle()->m_SpriteBackVertical, m_Z+0.1f,
|
||||
CRect( outline.left,
|
||||
outline.top+(m_UseEdgeButtons?GetStyle()->m_Width:0),
|
||||
outline.right,
|
||||
outline.bottom-(m_UseEdgeButtons?GetStyle()->m_Width:0))
|
||||
);
|
||||
|
||||
// Draw bar
|
||||
if (m_BarPressed)
|
||||
g_GUI.DrawSprite(GetStyle().m_SpriteScrollBarVertical, m_Z+0.2f, GetBarRect());
|
||||
else
|
||||
g_GUI.DrawSprite(GetStyle().m_SpriteScrollBarVertical, m_Z+0.2f, GetBarRect());
|
||||
}
|
||||
if (m_UseEdgeButtons)
|
||||
{
|
||||
// Get Appropriate sprites
|
||||
CStr button_top, button_bottom;
|
||||
|
||||
bool CGUIScrollBarVertical::HandleMessage(const SGUIMessage &Message)
|
||||
// figure out what sprite to use for top button
|
||||
if (m_ButtonMinusHovered)
|
||||
{
|
||||
if (m_ButtonMinusPressed)
|
||||
button_top = GUI<>::FallBackSprite(GetStyle()->m_SpriteButtonTopPressed, GetStyle()->m_SpriteButtonTop);
|
||||
else
|
||||
button_top = GUI<>::FallBackSprite(GetStyle()->m_SpriteButtonTopOver, GetStyle()->m_SpriteButtonTop);
|
||||
}
|
||||
else button_top = GetStyle()->m_SpriteButtonTop;
|
||||
|
||||
// figure out what sprite to use for top button
|
||||
if (m_ButtonPlusHovered)
|
||||
{
|
||||
if (m_ButtonPlusPressed)
|
||||
button_bottom = GUI<>::FallBackSprite(GetStyle()->m_SpriteButtonBottomPressed, GetStyle()->m_SpriteButtonBottom);
|
||||
else
|
||||
button_bottom = GUI<>::FallBackSprite(GetStyle()->m_SpriteButtonBottomOver, GetStyle()->m_SpriteButtonBottom);
|
||||
}
|
||||
else button_bottom = GetStyle()->m_SpriteButtonBottom;
|
||||
|
||||
// Draw top button
|
||||
GetGUI()->DrawSprite(button_top,
|
||||
m_Z+0.2f,
|
||||
CRect(outline.left,
|
||||
outline.top,
|
||||
outline.right,
|
||||
outline.top+GetStyle()->m_Width)
|
||||
);
|
||||
|
||||
// Draw bottom button
|
||||
GetGUI()->DrawSprite(button_bottom,
|
||||
m_Z+0.2f,
|
||||
CRect(outline.left,
|
||||
outline.bottom-GetStyle()->m_Width,
|
||||
outline.right,
|
||||
outline.bottom)
|
||||
);
|
||||
}
|
||||
|
||||
// Draw bar
|
||||
if (m_BarPressed)
|
||||
GetGUI()->DrawSprite(GUI<>::FallBackSprite(GetStyle()->m_SpriteBarVerticalPressed, GetStyle()->m_SpriteBarVertical),
|
||||
m_Z+0.2f,
|
||||
GetBarRect());
|
||||
else
|
||||
if (m_BarHovered)
|
||||
GetGUI()->DrawSprite(GUI<>::FallBackSprite(GetStyle()->m_SpriteBarVerticalOver, GetStyle()->m_SpriteBarVertical),
|
||||
m_Z+0.2f,
|
||||
GetBarRect());
|
||||
else
|
||||
GetGUI()->DrawSprite(GetStyle()->m_SpriteBarVertical,
|
||||
m_Z+0.2f,
|
||||
GetBarRect());
|
||||
}
|
||||
}
|
||||
|
||||
void CGUIScrollBarVertical::HandleMessage(const SGUIMessage &Message)
|
||||
{
|
||||
IGUIScrollBar::HandleMessage(Message);
|
||||
|
||||
/* switch (Message.type)
|
||||
{
|
||||
|
||||
*/ return true;
|
||||
}
|
||||
|
||||
CRect CGUIScrollBarVertical::GetBarRect() const
|
||||
{
|
||||
CRect ret;
|
||||
if (!GetStyle())
|
||||
return ret;
|
||||
|
||||
int size;
|
||||
float from, to;
|
||||
|
||||
size = (int)((m_Length-GetStyle().m_Width*2)*m_BarSize);
|
||||
from = (float)(m_Y+GetStyle().m_Width);
|
||||
to = (float)(m_Y+m_Length-GetStyle().m_Width-size);
|
||||
// is edge buttons used?
|
||||
if (m_UseEdgeButtons)
|
||||
{
|
||||
size = (int)((m_Length-GetStyle()->m_Width*2)*m_BarSize);
|
||||
if (size < GetStyle()->m_MinimumBarSize)
|
||||
size = GetStyle()->m_MinimumBarSize;
|
||||
|
||||
from = (float)(m_Y+GetStyle()->m_Width);
|
||||
to = (float)(m_Y+m_Length-GetStyle()->m_Width-size);
|
||||
}
|
||||
else
|
||||
{
|
||||
size = (int)(m_Length*m_BarSize);
|
||||
if (size < GetStyle()->m_MinimumBarSize)
|
||||
size = GetStyle()->m_MinimumBarSize;
|
||||
|
||||
from = (float)(m_Y);
|
||||
to = (float)(m_Y+m_Length-size);
|
||||
}
|
||||
|
||||
// Setup rectangle
|
||||
CRect ret;
|
||||
ret.top = (int)(from + (to-from)*m_Pos);
|
||||
ret.top = (int)(from + (to-from)*((float)m_Pos/(float)(max(1,m_ScrollRange - m_ScrollSpace))));
|
||||
ret.bottom = ret.top+size;
|
||||
ret.right = m_X + ((m_RightAligned)?(0):(GetStyle().m_Width));
|
||||
ret.left = ret.right - GetStyle().m_Width;
|
||||
ret.right = m_X + ((m_RightAligned)?(0):(GetStyle()->m_Width));
|
||||
ret.left = ret.right - GetStyle()->m_Width;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CGUIScrollBarVertical::HoveringButtonMinus(int mouse_x, int mouse_y)
|
||||
CRect CGUIScrollBarVertical::GetOuterRect() const
|
||||
{
|
||||
int StartX = (m_RightAligned)?(m_X-GetStyle().m_Width):(m_X);
|
||||
CRect ret;
|
||||
if (!GetStyle())
|
||||
return ret;
|
||||
|
||||
return (mouse_x > StartX &&
|
||||
mouse_x < StartX + GetStyle().m_Width &&
|
||||
mouse_y > m_Y &&
|
||||
mouse_y < m_Y + GetStyle().m_Width);
|
||||
ret.top = m_Y;
|
||||
ret.bottom = m_Y+m_Length;
|
||||
ret.right = m_X + ((m_RightAligned)?(0):(GetStyle()->m_Width));
|
||||
ret.left = ret.right - GetStyle()->m_Width;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CGUIScrollBarVertical::HoveringButtonPlus(int mouse_x, int mouse_y)
|
||||
bool CGUIScrollBarVertical::HoveringButtonMinus(const CPos &mouse)
|
||||
{
|
||||
int StartX = (m_RightAligned)?(m_X-GetStyle().m_Width):(m_X);
|
||||
if (!GetStyle())
|
||||
return false;
|
||||
|
||||
return (mouse_x > StartX &&
|
||||
mouse_x < StartX + GetStyle().m_Width &&
|
||||
mouse_y > m_Y + m_Length - GetStyle().m_Width &&
|
||||
mouse_y < m_Y + m_Length);
|
||||
int StartX = (m_RightAligned)?(m_X-GetStyle()->m_Width):(m_X);
|
||||
|
||||
return (mouse.x >= StartX &&
|
||||
mouse.x <= StartX + GetStyle()->m_Width &&
|
||||
mouse.y >= m_Y &&
|
||||
mouse.y <= m_Y + GetStyle()->m_Width);
|
||||
}
|
||||
|
||||
bool CGUIScrollBarVertical::HoveringButtonPlus(const CPos &mouse)
|
||||
{
|
||||
if (!GetStyle())
|
||||
return false;
|
||||
|
||||
int StartX = (m_RightAligned)?(m_X-GetStyle()->m_Width):(m_X);
|
||||
|
||||
return (mouse.x > StartX &&
|
||||
mouse.x < StartX + GetStyle()->m_Width &&
|
||||
mouse.y > m_Y + m_Length - GetStyle()->m_Width &&
|
||||
mouse.y < m_Y + m_Length);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ gee@pyro.nu
|
|||
class CGUIScrollBarVertical : public IGUIScrollBar
|
||||
{
|
||||
public:
|
||||
CGUIScrollBarVertical() {}
|
||||
virtual ~CGUIScrollBarVertical() {}
|
||||
CGUIScrollBarVertical();
|
||||
virtual ~CGUIScrollBarVertical();
|
||||
|
||||
public:
|
||||
/**
|
||||
|
|
@ -59,22 +59,22 @@ public:
|
|||
* @return true if messages handled the scroll-bar some. False if
|
||||
* the message should be processed by the object.
|
||||
*/
|
||||
virtual bool HandleMessage(const SGUIMessage &Message);
|
||||
virtual void HandleMessage(const SGUIMessage &Message);
|
||||
|
||||
/**
|
||||
* Set m_Pos with mouse_x/y input, i.e. when draggin.
|
||||
*/
|
||||
virtual void SetPosFromMousePos(int _x, int _y);
|
||||
virtual void SetPosFromMousePos(const CPos &mouse);
|
||||
|
||||
/**
|
||||
* @see IGUIScrollBar#HoveringButtonMinus
|
||||
*/
|
||||
virtual bool HoveringButtonMinus(int m_x, int m_y);
|
||||
virtual bool HoveringButtonMinus(const CPos &mouse);
|
||||
|
||||
/**
|
||||
* @see IGUIScrollBar#HoveringButtonPlus
|
||||
*/
|
||||
virtual bool HoveringButtonPlus(int m_x, int m_y);
|
||||
virtual bool HoveringButtonPlus(const CPos &mouse);
|
||||
|
||||
/**
|
||||
* Set Right Aligned
|
||||
|
|
@ -89,6 +89,13 @@ protected:
|
|||
*/
|
||||
virtual CRect GetBarRect() const;
|
||||
|
||||
/**
|
||||
* Get the rectangle of the outline of the scrollbar, every component of the
|
||||
* scroll-bar should be inside this area.
|
||||
* @return Rectangle, CRect
|
||||
*/
|
||||
virtual CRect GetOuterRect() const;
|
||||
|
||||
/**
|
||||
* Should the scroll bar proceed to the left or to the right of the m_X value.
|
||||
* Notice, this has nothing to do with where the owner places it.
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ gee@pyro.nu
|
|||
// Includes / Compiler directives
|
||||
//--------------------------------------------------------
|
||||
#include "GUI.h"
|
||||
#include "Overlay.h"
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Macros
|
||||
|
|
@ -51,6 +52,9 @@ gee@pyro.nu
|
|||
*/
|
||||
struct SGUIImage
|
||||
{
|
||||
SGUIImage() : m_Border(false), m_DeltaZ(0.f) {}
|
||||
~SGUIImage() {}
|
||||
|
||||
CStr m_Texture;
|
||||
|
||||
// Image placement
|
||||
|
|
@ -65,6 +69,13 @@ struct SGUIImage
|
|||
|
||||
// 0 or 1 pixel border is the only option
|
||||
bool m_Border;
|
||||
|
||||
/**
|
||||
* Z value modification of the image.
|
||||
* Inputted in XML as x-level, although it just an easier and safer
|
||||
* way of declaring delta-z.
|
||||
*/
|
||||
float m_DeltaZ;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -87,16 +98,6 @@ public:
|
|||
CGUISprite() {}
|
||||
virtual ~CGUISprite() {}
|
||||
|
||||
/**
|
||||
* Execute a drawing request for this sprite
|
||||
*
|
||||
* @param z Draw in what depth.
|
||||
* @param rect Outer rectangle to draw the collage.
|
||||
* @param clipping The clipping rectangle, things should only
|
||||
* be drawn within these perimeters.
|
||||
*/
|
||||
//void Draw(const float &z, const CRect &rect, const CRect &clipping);
|
||||
|
||||
/**
|
||||
* Adds an image to the sprite collage.
|
||||
*
|
||||
|
|
|
|||
37
source/gui/CRadioButton.cpp
Executable file
37
source/gui/CRadioButton.cpp
Executable file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
CCheckBox
|
||||
by Gustav Larsson
|
||||
gee@pyro.nu
|
||||
*/
|
||||
|
||||
//#include "stdafx."
|
||||
#include "GUI.h"
|
||||
#include "CRadioButton.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void CRadioButton::HandleMessage(const SGUIMessage &Message)
|
||||
{
|
||||
// Important
|
||||
IGUIButtonBehavior::HandleMessage(Message);
|
||||
|
||||
switch (Message.type)
|
||||
{
|
||||
case GUIM_PRESSED:
|
||||
for (vector_pObjects::iterator it = GetParent()->ChildrenItBegin(); it != GetParent()->ChildrenItEnd(); ++it)
|
||||
{
|
||||
// Notice, if you use other objects within the parent object that has got
|
||||
// this the "checked", it too will change. Hence NO OTHER OBJECTS THAN
|
||||
// RADIO BUTTONS SHOULD BE WITHIN IT!
|
||||
GUI<bool>::SetSetting((*it), "checked", false);
|
||||
}
|
||||
|
||||
GUI<bool>::SetSetting(this, "checked", true);
|
||||
|
||||
//GetGUI()->TEMPmessage = "Check box " + string((const TCHAR*)m_Name) + " was " + (m_Settings.m_Checked?"checked":"unchecked");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
49
source/gui/CRadioButton.h
Executable file
49
source/gui/CRadioButton.h
Executable file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
GUI Object - Radio Button
|
||||
by Gustav Larsson
|
||||
gee@pyro.nu
|
||||
|
||||
--Overview--
|
||||
|
||||
GUI Object representing a radio button
|
||||
|
||||
--More info--
|
||||
|
||||
Check GUI.h
|
||||
|
||||
*/
|
||||
|
||||
#ifndef CRadioButton_H
|
||||
#define CRadioButton_H
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Includes / Compiler directives
|
||||
//--------------------------------------------------------
|
||||
#include "GUI.h"
|
||||
#include "CCheckBox.h"
|
||||
|
||||
/**
|
||||
* @author Gustav Larsson
|
||||
*
|
||||
* Just like a check box, but it'll nullify its siblings (of the same kind),
|
||||
* and it won't switch itself.
|
||||
*
|
||||
* @see CCheckBox
|
||||
*/
|
||||
class CRadioButton : public CCheckBox
|
||||
{
|
||||
GUI_OBJECT(CRadioButton)
|
||||
|
||||
// Let the class freely interact with its siblings
|
||||
friend class CRadioButton;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Handle Messages
|
||||
*
|
||||
* @param Message GUI Message
|
||||
*/
|
||||
virtual void HandleMessage(const SGUIMessage &Message);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -6,71 +6,122 @@ gee@pyro.nu
|
|||
|
||||
//#include "stdafx."
|
||||
#include "GUI.h"
|
||||
#include "CText.h"
|
||||
|
||||
// TODO Gee: font.h is temporary.
|
||||
#include "res/font.h"
|
||||
#include "ogl.h"
|
||||
|
||||
using namespace std;
|
||||
// TODO Gee: new
|
||||
#include "OverlayText.h"
|
||||
|
||||
// Offsets
|
||||
DECLARE_SETTINGS_INFO(STextSettings)
|
||||
using namespace std;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Constructor / Destructor
|
||||
//-------------------------------------------------------------------
|
||||
CText::CText()
|
||||
{
|
||||
// Static! Only done once
|
||||
if (m_SettingsInfo.empty())
|
||||
{
|
||||
// Setup the base ones too
|
||||
SetupBaseSettingsInfo(m_SettingsInfo);
|
||||
AddSetting(GUIST_CGUIString, "caption");
|
||||
AddSetting(GUIST_bool, "scrollbar");
|
||||
AddSetting(GUIST_CStr, "scrollbar-style");
|
||||
AddSetting(GUIST_CStr, "sprite");
|
||||
AddSetting(GUIST_CColor, "textcolor");
|
||||
|
||||
GUI_ADD_OFFSET_EXT(STextSettings, m_Sprite, "string", "sprite")
|
||||
GUI_ADD_OFFSET_EXT(STextSettings, m_ScrollBar, "bool", "scrollbar")
|
||||
GUI_ADD_OFFSET_EXT(STextSettings, m_ScrollBarStyle, "string", "scrollbar-style")
|
||||
}
|
||||
//GUI<bool>::SetSetting(this, "ghost", true);
|
||||
GUI<bool>::SetSetting(this, "scrollbar", false);
|
||||
|
||||
// Add scroll-bar
|
||||
CGUIScrollBarVertical * bar = new CGUIScrollBarVertical();
|
||||
bar->SetRightAligned(true);
|
||||
bar->SetUseEdgeButtons(true);
|
||||
AddScrollBar(bar);
|
||||
|
||||
// Add text
|
||||
AddText(new SGUIText());
|
||||
}
|
||||
|
||||
CText::~CText()
|
||||
{
|
||||
}
|
||||
|
||||
void CText::SetupText()
|
||||
{
|
||||
if (!GetGUI())
|
||||
return;
|
||||
|
||||
assert(m_GeneratedTexts.size()>=1);
|
||||
|
||||
CColor color;
|
||||
CStr font;
|
||||
CGUIString caption;
|
||||
bool scrollbar;
|
||||
GUI<CColor>::GetSetting(this, "textcolor", color);
|
||||
GUI<CGUIString>::GetSetting(this, "caption", caption);
|
||||
GUI<bool>::GetSetting(this, "scrollbar", scrollbar);
|
||||
|
||||
int width = m_CachedActualSize.GetWidth();
|
||||
// remove scrollbar if applicable
|
||||
if (scrollbar && GetScrollBar(0).GetStyle())
|
||||
width -= GetScrollBar(0).GetStyle()->m_Width;
|
||||
|
||||
*m_GeneratedTexts[0] = GetGUI()->GenerateText(caption, /*color,*/ CStr("verdana12.fnt"), width, 4);
|
||||
|
||||
// Setup scrollbar
|
||||
if (scrollbar)
|
||||
{
|
||||
GetScrollBar(0).SetScrollRange( m_GeneratedTexts[0]->m_Size.cy );
|
||||
GetScrollBar(0).SetScrollSpace( m_CachedActualSize.GetHeight() );
|
||||
}
|
||||
}
|
||||
|
||||
void CText::HandleMessage(const SGUIMessage &Message)
|
||||
{
|
||||
// TODO Gee:
|
||||
IGUIScrollBarOwner::HandleMessage(Message);
|
||||
IGUITextOwner::HandleMessage(Message);
|
||||
|
||||
switch (Message.type)
|
||||
{
|
||||
case GUIM_SETTINGS_UPDATED:
|
||||
if (Message.value == CStr("size") || Message.value == CStr("z") ||
|
||||
Message.value == CStr("absolute"))
|
||||
bool scrollbar;
|
||||
GUI<bool>::GetSetting(this, "scrollbar", scrollbar);
|
||||
|
||||
// Update scroll-bar
|
||||
if (scrollbar &&
|
||||
(Message.value == CStr("size") || Message.value == CStr("z") ||
|
||||
Message.value == CStr("absolute")))
|
||||
{
|
||||
|
||||
GetScrollBar(0).SetX( m_CachedActualSize.right );
|
||||
GetScrollBar(0).SetY( m_CachedActualSize.top );
|
||||
GetScrollBar(0).SetZ( GetBufferedZ() );
|
||||
GetScrollBar(0).SetLength( m_CachedActualSize.bottom - m_CachedActualSize.top );
|
||||
}
|
||||
|
||||
|
||||
// Update scrollbar
|
||||
if (Message.value == CStr("scrollbar-style"))
|
||||
{
|
||||
GetScrollBar(0).SetScrollBarStyle( GetSettings().m_ScrollBarStyle );
|
||||
CStr scrollbar_style;
|
||||
GUI<CStr>::GetSetting(this, Message.value, scrollbar_style);
|
||||
|
||||
GetScrollBar(0).SetScrollBarStyle( scrollbar_style );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case GUIM_MOUSE_WHEEL_DOWN:
|
||||
GetScrollBar(0).ScrollPlus();
|
||||
// Since the scroll was changed, let's simulate a mouse movement
|
||||
// to check if scrollbar now is hovered
|
||||
HandleMessage(SGUIMessage(GUIM_MOUSE_MOTION));
|
||||
break;
|
||||
|
||||
case GUIM_MOUSE_WHEEL_UP:
|
||||
GetScrollBar(0).ScrollMinus();
|
||||
// Since the scroll was changed, let's simulate a mouse movement
|
||||
// to check if scrollbar now is hovered
|
||||
HandleMessage(SGUIMessage(GUIM_MOUSE_MOTION));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -84,12 +135,35 @@ void CText::Draw()
|
|||
glDisable(GL_TEXTURE_2D);
|
||||
//////////
|
||||
|
||||
float bz = GetBufferedZ();
|
||||
|
||||
// First call draw on ScrollBarOwner
|
||||
IGUIScrollBarOwner::Draw();
|
||||
bool scrollbar;
|
||||
GUI<bool>::GetSetting(this, "scrollbar", scrollbar);
|
||||
|
||||
if (scrollbar)
|
||||
{
|
||||
// Draw scrollbar
|
||||
IGUIScrollBarOwner::Draw();
|
||||
}
|
||||
|
||||
if (GetGUI())
|
||||
{
|
||||
GetGUI()->DrawSprite(m_Settings.m_Sprite, GetBufferedZ(), m_CachedActualSize);
|
||||
}
|
||||
CStr sprite;
|
||||
GUI<CStr>::GetSetting(this, "sprite", sprite);
|
||||
|
||||
GetGUI()->DrawSprite(sprite, bz, m_CachedActualSize);
|
||||
|
||||
int scroll=0;
|
||||
if (scrollbar)
|
||||
{
|
||||
scroll = GetScrollBar(0).GetPos();
|
||||
}
|
||||
|
||||
CColor color;
|
||||
GUI<CColor>::GetSetting(this, "textcolor", color);
|
||||
|
||||
// Draw text
|
||||
IGUITextOwner::Draw(0, color, m_CachedActualSize.TopLeft() - CPos(0,scroll), bz+0.1f);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,24 +36,6 @@ class IGUIScrollBar;
|
|||
// Declarations
|
||||
//--------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Text Settings
|
||||
*/
|
||||
struct STextSettings
|
||||
{
|
||||
CStr m_Font;
|
||||
CStr m_Sprite;
|
||||
EAlign m_TextAlign;
|
||||
CColor m_TextColor;
|
||||
EValign m_TextValign;
|
||||
CStr m_ToolTip;
|
||||
CStr m_ToolTipStyle;
|
||||
bool m_ScrollBar;
|
||||
CStr m_ScrollBarStyle;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @author Gustav Larsson
|
||||
*
|
||||
|
|
@ -61,9 +43,8 @@ struct STextSettings
|
|||
*
|
||||
* @see IGUIObject
|
||||
* @see IGUISettingsObject
|
||||
* @see STextSettings
|
||||
*/
|
||||
class CText : public IGUISettingsObject<STextSettings>, public IGUIScrollBarOwner
|
||||
class CText : public IGUIScrollBarOwner, public IGUITextOwner
|
||||
{
|
||||
GUI_OBJECT(CText)
|
||||
|
||||
|
|
@ -71,15 +52,15 @@ public:
|
|||
CText();
|
||||
virtual ~CText();
|
||||
|
||||
/**
|
||||
* Since we're doing multiple inheritance, this is to avoid error message
|
||||
*
|
||||
* @return Settings infos
|
||||
*/
|
||||
virtual map_Settings GetSettingsInfo() const { return IGUISettingsObject<STextSettings>::m_SettingsInfo; }
|
||||
|
||||
virtual void ResetStates() { IGUIScrollBarOwner::ResetStates(); }
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Sets up text, should be called every time changes has been
|
||||
* made that can change the visual.
|
||||
*/
|
||||
void SetupText();
|
||||
|
||||
/**
|
||||
* Handle Messages
|
||||
*
|
||||
|
|
@ -91,9 +72,6 @@ public:
|
|||
* Draws the Text
|
||||
*/
|
||||
virtual void Draw();
|
||||
|
||||
// TODO Gee: Temp!
|
||||
//CGUIScrollBar m_ScrollBar;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -66,16 +66,14 @@ gee@pyro.nu
|
|||
|
||||
#include "GUIbase.h"
|
||||
#include "GUIutil.h"
|
||||
#include "GUItext.h"
|
||||
#include "IGUIObject.h"
|
||||
#include "IGUISettingsObject.h"
|
||||
#include "IGUIButtonBehavior.h"
|
||||
#include "IGUIScrollBarOwner.h"
|
||||
#include "IGUITextOwner.h"
|
||||
#include "IGUIScrollBar.h"
|
||||
#include "CGUIScrollBarVertical.h"
|
||||
#include "CButton.h"
|
||||
#include "CText.h"
|
||||
#include "CGUISprite.h"
|
||||
#include "CGUI.h"
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -36,20 +36,6 @@ class IGUIObject;
|
|||
#define g_GUI CGUI::GetSingleton()
|
||||
|
||||
// Object settings setups
|
||||
#define GUI_ADD_OFFSET_GENERIC(si, guiss, _struct, var, type, str) \
|
||||
si[CStr(str)].m_Offset = offsetof(_struct, var); \
|
||||
si[CStr(str)].m_SettingsStruct = guiss; \
|
||||
si[CStr(str)].m_Type = CStr(type);
|
||||
|
||||
#define GUI_ADD_OFFSET_BASE(_struct, var, type, str) \
|
||||
GUI_ADD_OFFSET_GENERIC(m_SettingsInfo, GUISS_BASE, _struct, var, type, str)
|
||||
|
||||
#define GUI_ADD_OFFSET_EXT(_struct, var, type, str) \
|
||||
GUI_ADD_OFFSET_GENERIC(m_SettingsInfo, GUISS_EXTENDED, _struct, var, type, str)
|
||||
|
||||
// Declares the static variable in IGUISettingsObject<>
|
||||
#define DECLARE_SETTINGS_INFO(_struct) \
|
||||
map_Settings IGUISettingsObject<_struct>::m_SettingsInfo;
|
||||
|
||||
// Setup an object's ConstructObject function
|
||||
#define GUI_OBJECT(obj) \
|
||||
|
|
@ -83,10 +69,13 @@ enum EGUIMessageType
|
|||
GUIM_MOUSE_WHEEL_DOWN,
|
||||
GUIM_SETTINGS_UPDATED, // SGUIMessage.m_Value = name of setting
|
||||
GUIM_PRESSED,
|
||||
GUIM_MOUSE_MOTION
|
||||
GUIM_MOUSE_MOTION,
|
||||
GUIM_LOAD // Called when an object is added to the GUI.
|
||||
};
|
||||
|
||||
/**
|
||||
* @author Gustav Larsson
|
||||
*
|
||||
* Message send to IGUIObject::HandleMessage() in order
|
||||
* to give life to Objects manually with
|
||||
* a derived HandleMessage().
|
||||
|
|
|
|||
481
source/gui/GUItext.cpp
Executable file
481
source/gui/GUItext.cpp
Executable file
|
|
@ -0,0 +1,481 @@
|
|||
/*
|
||||
GUI text
|
||||
by Gustav Larsson
|
||||
gee@pyro.nu
|
||||
*/
|
||||
|
||||
#include "GUI.h"
|
||||
#include "Parser.h"
|
||||
#include "OverlayText.h"
|
||||
#include <algorithm>
|
||||
|
||||
// TODO Gee: Remove, just for temp-output
|
||||
#include <fstream>
|
||||
|
||||
static const TCHAR TagStart = '[';
|
||||
static const TCHAR TagEnd = ']';
|
||||
|
||||
void CGUIString::SFeedback::Reset()
|
||||
{
|
||||
m_Images[Left].clear();
|
||||
m_Images[Right].clear();
|
||||
m_TextCalls.clear();
|
||||
m_SpriteCalls.clear();
|
||||
m_Size = CSize();
|
||||
m_NewLine=false;
|
||||
}
|
||||
|
||||
void CGUIString::GenerateTextCall(SFeedback &Feedback,
|
||||
const CStr &DefaultFont, /*const CColor &DefaultColor,*/
|
||||
const int &from, const int &to) const
|
||||
{
|
||||
// Reset width and height, because they will be determined with incrementation
|
||||
// or comparisons.
|
||||
Feedback.Reset();
|
||||
|
||||
// Check out which text chunk this is within.
|
||||
//bool match_found = false;
|
||||
vector<TextChunk>::const_iterator itTextChunk;
|
||||
for (itTextChunk=m_TextChunks.begin(); itTextChunk!=m_TextChunks.end(); ++itTextChunk)
|
||||
{
|
||||
// Get the area that is overlapped by both the TextChunk and
|
||||
// by the from/to inputted.
|
||||
int _from, _to;
|
||||
_from = max(from, itTextChunk->m_From);
|
||||
_to = min(to, itTextChunk->m_To);
|
||||
|
||||
// If from is larger than to, than they are not overlapping
|
||||
if (_to == _from && itTextChunk->m_From == itTextChunk->m_To && _from > from)
|
||||
{
|
||||
// These should never be able to have more than one tag.
|
||||
assert(itTextChunk->m_Tags.size()==1);
|
||||
|
||||
// Single tags
|
||||
if (itTextChunk->m_Tags[0].m_TagType == CGUIString::TextChunk::Tag::TAG_IMGLEFT)
|
||||
{
|
||||
//if (_from > from)
|
||||
Feedback.m_Images[SFeedback::Left].push_back(itTextChunk->m_Tags[0].m_TagValue);
|
||||
}
|
||||
else
|
||||
if (itTextChunk->m_Tags[0].m_TagType == CGUIString::TextChunk::Tag::TAG_IMGRIGHT)
|
||||
{
|
||||
//if (_from > from)
|
||||
Feedback.m_Images[SFeedback::Right].push_back(itTextChunk->m_Tags[0].m_TagValue);
|
||||
}
|
||||
else
|
||||
if (itTextChunk->m_Tags[0].m_TagType == CGUIString::TextChunk::Tag::TAG_ICON)
|
||||
{
|
||||
//if (_from <= from)continue;;
|
||||
// We'll need to setup a text-call that will point
|
||||
// to the icon, this is to be able to iterate
|
||||
// through the text-calls without having to
|
||||
// complex the structure ultimately for nothing more.
|
||||
SGUIText::STextCall TextCall;
|
||||
|
||||
// Also add it to the sprites being rendered.
|
||||
SGUIText::SSpriteCall SpriteCall;
|
||||
|
||||
CSize size(20,20);
|
||||
// Query size of icon
|
||||
// TODO Gee: Temp
|
||||
|
||||
// append width, and make maximum height the height.
|
||||
Feedback.m_Size.cx += size.cx;
|
||||
Feedback.m_Size.cy = max(Feedback.m_Size.cy, size.cy);
|
||||
|
||||
// These are also needed later
|
||||
TextCall.m_Size = size;
|
||||
SpriteCall.m_Area = size;
|
||||
|
||||
SpriteCall.m_TextureName = CStr("scroll");
|
||||
|
||||
// Add sprite call
|
||||
Feedback.m_SpriteCalls.push_back(SpriteCall);
|
||||
|
||||
// Finalize text call
|
||||
TextCall.m_pSpriteCall = &Feedback.m_SpriteCalls.back();
|
||||
|
||||
// Add text call
|
||||
Feedback.m_TextCalls.push_back(TextCall);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (_to > _from && !Feedback.m_NewLine)
|
||||
{
|
||||
SGUIText::STextCall TextCall;
|
||||
|
||||
// Set defaults
|
||||
TextCall.m_Font = DefaultFont;
|
||||
TextCall.m_UseCustomColor = false;
|
||||
|
||||
// Extract substring from RawString.
|
||||
TextCall.m_String = GetRawString().GetSubstring(_from, _to-_from);
|
||||
|
||||
// Go through tags and apply changes.
|
||||
vector<CGUIString::TextChunk::Tag>::const_iterator it2;
|
||||
for (it2 = itTextChunk->m_Tags.begin(); it2 != itTextChunk->m_Tags.end(); ++it2)
|
||||
{
|
||||
if (it2->m_TagType == CGUIString::TextChunk::Tag::TAG_COLOR)
|
||||
{
|
||||
// Set custom color
|
||||
TextCall.m_UseCustomColor = true;
|
||||
GUI<CColor>::ParseString(it2->m_TagValue, TextCall.m_Color);
|
||||
}
|
||||
else
|
||||
if (it2->m_TagType == CGUIString::TextChunk::Tag::TAG_FONT)
|
||||
{
|
||||
TextCall.m_Font = it2->m_TagValue;
|
||||
}
|
||||
}
|
||||
|
||||
CSize size;
|
||||
|
||||
COverlayText txt(0, 0, 0, TextCall.m_Font, TextCall.m_String, TextCall.m_Color);
|
||||
// TODO Gee: Ask Rich to change to (size);
|
||||
txt.GetOutputStringSize((int&)size.cx, (int&)size.cy);
|
||||
|
||||
// append width, and make maximum height the height.
|
||||
Feedback.m_Size.cx += size.cx;
|
||||
Feedback.m_Size.cy = max(Feedback.m_Size.cy, size.cy);
|
||||
|
||||
// These are also needed later
|
||||
TextCall.m_Size = size;
|
||||
|
||||
if (TextCall.m_String.Length() >= 1)
|
||||
{
|
||||
if (TextCall.m_String[0] == '\n')
|
||||
{
|
||||
Feedback.m_NewLine = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Add text-chunk
|
||||
Feedback.m_TextCalls.push_back(TextCall);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CGUIString::TextChunk::Tag::SetTagType(const CStr &tagtype)
|
||||
{
|
||||
CStr _tagtype = tagtype.UpperCase();
|
||||
|
||||
if (_tagtype == CStr("B"))
|
||||
{
|
||||
m_TagType = TAG_B;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (_tagtype == CStr("I"))
|
||||
{
|
||||
m_TagType = TAG_I;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (_tagtype == CStr("COLOR"))
|
||||
{
|
||||
m_TagType = TAG_COLOR;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (_tagtype == CStr("FONT"))
|
||||
{
|
||||
m_TagType = TAG_FONT;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (_tagtype == CStr("ICON"))
|
||||
{
|
||||
m_TagType = TAG_ICON;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (_tagtype == CStr("IMGLEFT"))
|
||||
{
|
||||
m_TagType = TAG_IMGLEFT;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (_tagtype == CStr("IMGRIGHT"))
|
||||
{
|
||||
m_TagType = TAG_IMGRIGHT;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CGUIString::SetValue(const CStr &str)
|
||||
{
|
||||
// clear
|
||||
m_TextChunks.clear();
|
||||
m_Words.clear();
|
||||
m_RawString = CStr();
|
||||
|
||||
// Setup parser
|
||||
CParser Parser;
|
||||
Parser.InputTaskType("start", "$ident[_=_$value]");
|
||||
Parser.InputTaskType("end", "/$ident");
|
||||
|
||||
_long position = 0;
|
||||
_long from=0; // the position in the raw string where the last tag ended
|
||||
_long from_nonraw=0; // like from only in position of the REAL string, with tags.
|
||||
_long curpos = 0;
|
||||
|
||||
// Current Text Chunk
|
||||
CGUIString::TextChunk CurrentTextChunk;
|
||||
|
||||
for (;;position = curpos+1)
|
||||
{
|
||||
// Find next TagStart character
|
||||
curpos = str.Find(position, TagStart);
|
||||
|
||||
if (curpos == -1)
|
||||
{
|
||||
m_RawString += str.GetSubstring(position, str.Length()-position);
|
||||
|
||||
if (from != m_RawString.Length())
|
||||
{
|
||||
CurrentTextChunk.m_From = from;
|
||||
CurrentTextChunk.m_To = m_RawString.Length();
|
||||
m_TextChunks.push_back(CurrentTextChunk);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// First check if there is another TagStart before a TagEnd,
|
||||
// in that case it's just a regular TagStart and we can continue.
|
||||
_long pos_left = str.Find(curpos+1, TagStart);
|
||||
_long pos_right = str.Find(curpos+1, TagEnd);
|
||||
|
||||
if (pos_right == -1)
|
||||
{
|
||||
m_RawString += str.GetSubstring(position, curpos-position+1);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
if (pos_left != -1 && pos_left < pos_right)
|
||||
{
|
||||
m_RawString += str.GetSubstring(position, pos_left-position);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RawString += str.GetSubstring(position, curpos-position);
|
||||
|
||||
// Okay we've found a TagStart and TagEnd, positioned
|
||||
// at pos and pos_right. Now let's extract the
|
||||
// interior and try parsing.
|
||||
CStr tagstr = str.GetSubstring(curpos+1, pos_right-curpos-1);
|
||||
|
||||
CParserLine Line;
|
||||
Line.ParseString(Parser, (const char*)tagstr);
|
||||
|
||||
// Set to true if the tag is just text.
|
||||
bool justtext = false;
|
||||
|
||||
if (Line.m_ParseOK)
|
||||
{
|
||||
if (Line.m_TaskTypeName == "start")
|
||||
{
|
||||
// The tag
|
||||
TextChunk::Tag tag;
|
||||
CStr Str_TagType;
|
||||
|
||||
Line.GetArgString(0, (std::string &)Str_TagType);
|
||||
|
||||
if (!tag.SetTagType(Str_TagType))
|
||||
{
|
||||
justtext = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check for possible value-strings
|
||||
if (Line.GetArgCount() == 2)
|
||||
Line.GetArgString(1, (std::string &)tag.m_TagValue);
|
||||
|
||||
// Finalize last
|
||||
if (curpos != from_nonraw)
|
||||
{
|
||||
CurrentTextChunk.m_From = from;
|
||||
CurrentTextChunk.m_To = from + curpos - from_nonraw;
|
||||
m_TextChunks.push_back(CurrentTextChunk);
|
||||
from = CurrentTextChunk.m_To;
|
||||
}
|
||||
from_nonraw = pos_right+1;
|
||||
|
||||
// Some tags does not have a closure, and should be
|
||||
// stored without text. Like a <tag /> in XML.
|
||||
if (tag.m_TagType == TextChunk::Tag::TAG_IMGLEFT ||
|
||||
tag.m_TagType == TextChunk::Tag::TAG_IMGRIGHT ||
|
||||
tag.m_TagType == TextChunk::Tag::TAG_ICON)
|
||||
{
|
||||
// We need to use a fresh text chunk
|
||||
// because 'tag' should be the *only* tag.
|
||||
TextChunk FreshTextChunk;
|
||||
|
||||
// They does not work with the text system.
|
||||
FreshTextChunk.m_From = from + pos_right+1 - from_nonraw;
|
||||
FreshTextChunk.m_To = from + pos_right+1 - from_nonraw;
|
||||
|
||||
FreshTextChunk.m_Tags.push_back(tag);
|
||||
|
||||
m_TextChunks.push_back(FreshTextChunk);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add that tag, but first, erase previous occurences of the
|
||||
// same tag.
|
||||
vector<TextChunk::Tag>::iterator it;
|
||||
for (it = CurrentTextChunk.m_Tags.begin(); it != CurrentTextChunk.m_Tags.end(); ++it)
|
||||
{
|
||||
if (it->m_TagType == tag.m_TagType)
|
||||
{
|
||||
CurrentTextChunk.m_Tags.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add!
|
||||
CurrentTextChunk.m_Tags.push_back(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (Line.m_TaskTypeName == "end")
|
||||
{
|
||||
// The tag
|
||||
TextChunk::Tag tag;
|
||||
CStr Str_TagType;
|
||||
|
||||
Line.GetArgString(0, (std::string &)Str_TagType);
|
||||
|
||||
if (!tag.SetTagType(Str_TagType))
|
||||
{
|
||||
justtext = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Finalize the previous chunk
|
||||
if (curpos != from_nonraw)
|
||||
{
|
||||
CurrentTextChunk.m_From = from;
|
||||
CurrentTextChunk.m_To = from + curpos - from_nonraw;
|
||||
m_TextChunks.push_back(CurrentTextChunk);
|
||||
from = CurrentTextChunk.m_To;
|
||||
}
|
||||
from_nonraw = pos_right+1;
|
||||
|
||||
// Search for the tag, if it's not added, then
|
||||
// pass it as plain text.
|
||||
vector<TextChunk::Tag>::iterator it;
|
||||
for (it = CurrentTextChunk.m_Tags.begin(); it != CurrentTextChunk.m_Tags.end(); ++it)
|
||||
{
|
||||
if (it->m_TagType == tag.m_TagType)
|
||||
{
|
||||
CurrentTextChunk.m_Tags.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else justtext = true;
|
||||
|
||||
if (justtext)
|
||||
{
|
||||
// What was within the tags could not be interpreted
|
||||
// so we'll assume it's just text.
|
||||
m_RawString += str.GetSubstring(curpos, pos_right-curpos+1);
|
||||
}
|
||||
|
||||
curpos = pos_right;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
|
||||
ofstream fout("output1.txt");
|
||||
|
||||
for (int i=0; i<m_TextChunks.size(); ++i)
|
||||
{
|
||||
fout << "{\"";
|
||||
fout << m_TextChunks[i].m_From << " " << m_TextChunks[i].m_To << "\",";
|
||||
for (int j=0; j<m_TextChunks[i].m_Tags.size(); ++j)
|
||||
{
|
||||
fout << "(" << m_TextChunks[i].m_Tags[j].m_TagType << " " << m_TextChunks[i].m_Tags[j].m_TagValue << ")";
|
||||
}
|
||||
fout << "}\n";
|
||||
}
|
||||
|
||||
fout.close();
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// Add a delimiter at start and at end, it helps when
|
||||
// processing later, because we don't have make exceptions for
|
||||
// those cases.
|
||||
// We'll sort later.
|
||||
m_Words.push_back(0);
|
||||
m_Words.push_back(m_RawString.Length());
|
||||
|
||||
// Space: ' '
|
||||
for (position=0, curpos=0;;position = curpos+1)
|
||||
{
|
||||
// Find the next word-delimiter.
|
||||
_long dl = m_RawString.Find(position, ' ');
|
||||
|
||||
if (dl == -1)
|
||||
break;
|
||||
|
||||
curpos = dl;
|
||||
m_Words.push_back((int)dl+1);
|
||||
}
|
||||
|
||||
// Dash: '-'
|
||||
for (position=0, curpos=0;;position = curpos+1)
|
||||
{
|
||||
// Find the next word-delimiter.
|
||||
_long dl = m_RawString.Find(position, '-');
|
||||
|
||||
if (dl == -1)
|
||||
break;
|
||||
|
||||
curpos = dl;
|
||||
m_Words.push_back((int)dl+1);
|
||||
}
|
||||
|
||||
// New Line: '\n'
|
||||
for (position=0, curpos=0;;position = curpos+1)
|
||||
{
|
||||
// Find the next word-delimiter.
|
||||
_long dl = m_RawString.Find(position, '\n');
|
||||
|
||||
if (dl == -1)
|
||||
break;
|
||||
|
||||
curpos = dl;
|
||||
|
||||
// Add before and
|
||||
m_Words.push_back((int)dl);
|
||||
m_Words.push_back((int)dl+1);
|
||||
}
|
||||
|
||||
sort(m_Words.begin(), m_Words.end());
|
||||
|
||||
// Remove duplicates
|
||||
vector<int>::iterator it;
|
||||
int last_word = -1;
|
||||
for (it = m_Words.begin(); it != m_Words.end(); ++it)
|
||||
{
|
||||
if (last_word == *it)
|
||||
m_Words.erase(it);
|
||||
|
||||
last_word = *it;
|
||||
}
|
||||
}
|
||||
300
source/gui/GUItext.h
Executable file
300
source/gui/GUItext.h
Executable file
|
|
@ -0,0 +1,300 @@
|
|||
/*
|
||||
GUI text, handles text stuff
|
||||
by Gustav Larsson
|
||||
gee@pyro.nu
|
||||
|
||||
--Overview--
|
||||
|
||||
Mainly contains struct SGUIText and friends.
|
||||
Actual text processing is made in CGUI::GenerateText()
|
||||
|
||||
--More info--
|
||||
|
||||
Check GUI.h
|
||||
|
||||
*/
|
||||
|
||||
#ifndef GUItext_H
|
||||
#define GUItext_H
|
||||
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Includes / Compiler directives
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Declarations
|
||||
//--------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @author Gustav Larsson
|
||||
*
|
||||
* An SGUIText object is a parsed string, divided into
|
||||
* text-rendering components. Each component, being a
|
||||
* call to the Renderer. For instance, if you by tags
|
||||
* change the color, then the GUI will have to make
|
||||
* individual calls saying it want that color on the
|
||||
* text.
|
||||
*
|
||||
* For instance (this is not the syntax):
|
||||
* "Hello [b]there[/b] bunny!"
|
||||
*
|
||||
* That without word-wrapping would mean 3 components.
|
||||
* i.e. 3 calls to CRenderer. One drawing "Hello",
|
||||
* one drawing "there" in bold, and one drawing "bunny!".
|
||||
*/
|
||||
struct SGUIText
|
||||
{
|
||||
/**
|
||||
* @author Gustav Larsson
|
||||
*
|
||||
* A sprite call to the CRenderer
|
||||
*/
|
||||
struct SSpriteCall
|
||||
{
|
||||
/**
|
||||
* Size and position of sprite
|
||||
*/
|
||||
CRect m_Area;
|
||||
|
||||
/**
|
||||
* Texture name from texture database.
|
||||
*/
|
||||
CStr m_TextureName;
|
||||
};
|
||||
|
||||
/**
|
||||
* @author Gustav Larsson
|
||||
*
|
||||
* A text call to the CRenderer
|
||||
*/
|
||||
struct STextCall
|
||||
{
|
||||
STextCall() :
|
||||
m_Bold(false), m_Italic(false), m_Underlined(false),
|
||||
m_UseCustomColor(false), m_pSpriteCall(NULL) {}
|
||||
|
||||
/**
|
||||
* Position
|
||||
*/
|
||||
CPos m_Pos;
|
||||
|
||||
/**
|
||||
* Size
|
||||
*/
|
||||
CSize m_Size;
|
||||
|
||||
/**
|
||||
* The string that is suppose to be rendered.
|
||||
*/
|
||||
CStr m_String;
|
||||
|
||||
/**
|
||||
* Use custom color? If true then m_Color is used,
|
||||
* else the color inputted will be used.
|
||||
*/
|
||||
bool m_UseCustomColor;
|
||||
|
||||
/**
|
||||
* Color setup
|
||||
*/
|
||||
CColor m_Color;
|
||||
|
||||
/**
|
||||
* Font name
|
||||
*/
|
||||
CStr m_Font;
|
||||
|
||||
/**
|
||||
* Settings
|
||||
*/
|
||||
bool m_Bold, m_Italic, m_Underlined;
|
||||
|
||||
/**
|
||||
* *IF* an icon, than this is not NULL.
|
||||
*/
|
||||
SSpriteCall *m_pSpriteCall;
|
||||
};
|
||||
|
||||
/**
|
||||
* List of TextCalls, for instance "Hello", "there!"
|
||||
*/
|
||||
std::vector<STextCall> m_TextCalls;
|
||||
|
||||
/**
|
||||
* List of sprites, or "icons" that should be rendered
|
||||
* along with the text.
|
||||
*/
|
||||
std::vector<SSpriteCall> m_SpriteCalls;
|
||||
|
||||
/**
|
||||
* Width and height of the whole output, used when setting up
|
||||
* scrollbars and such.
|
||||
*/
|
||||
CSize m_Size;
|
||||
};
|
||||
|
||||
/**
|
||||
* @author Gustav Larsson
|
||||
*
|
||||
* String class, substitue for CStr, but that parses
|
||||
* the tags and builds up a list of all text that will
|
||||
* be different when outputted.
|
||||
*
|
||||
* The difference between CGUIString and SGUIText is that
|
||||
* CGUIString is a string-class that parses the tags
|
||||
* when the value is set. The SGUIText is just a container
|
||||
* which stores the positions and settings of all text-calls
|
||||
* that will have to be made to the Renderer.
|
||||
*/
|
||||
class CGUIString
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @author Gustav Larsson
|
||||
*
|
||||
* A chunk of text that represents one call to the renderer.
|
||||
* In other words, all text in one chunk, will be drawn
|
||||
* exactly with the same settings.
|
||||
*/
|
||||
struct TextChunk
|
||||
{
|
||||
/**
|
||||
* @author Gustav Larsson
|
||||
*
|
||||
* A tag looks like this "Hello [B]there[/B] little"
|
||||
*/
|
||||
struct Tag
|
||||
{
|
||||
/**
|
||||
* Tag Type
|
||||
*/
|
||||
enum TagType
|
||||
{
|
||||
TAG_B,
|
||||
TAG_I,
|
||||
TAG_FONT,
|
||||
TAG_SIZE,
|
||||
TAG_COLOR,
|
||||
TAG_IMGLEFT,
|
||||
TAG_IMGRIGHT,
|
||||
TAG_ICON
|
||||
};
|
||||
|
||||
/**
|
||||
* Set tag from string
|
||||
*
|
||||
* @param tagtype TagType by string, like 'IMG' for [IMG]
|
||||
* @return True if m_TagType was set.
|
||||
*/
|
||||
bool SetTagType(const CStr &tagtype);
|
||||
|
||||
/**
|
||||
* In [B=Hello][/B]
|
||||
* m_TagType is TAG_B
|
||||
*/
|
||||
TagType m_TagType;
|
||||
|
||||
/**
|
||||
* In [B=Hello][/B]
|
||||
* m_TagValue is 'Hello'
|
||||
*/
|
||||
CStr m_TagValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* m_From and m_To is the range of the string
|
||||
*/
|
||||
int m_From, m_To;
|
||||
|
||||
/**
|
||||
* Tags that are present. [A][B]
|
||||
*/
|
||||
std::vector<Tag> m_Tags;
|
||||
};
|
||||
|
||||
/**
|
||||
* @author Gustav Larsson
|
||||
*
|
||||
* All data generated in GenerateTextCall()
|
||||
*/
|
||||
struct SFeedback
|
||||
{
|
||||
// Constants
|
||||
const static int Left=0;
|
||||
const static int Right=1;
|
||||
|
||||
/**
|
||||
* Reset all member data.
|
||||
*/
|
||||
void Reset();
|
||||
|
||||
/**
|
||||
* Image stacks, for left and right floating images.
|
||||
*/
|
||||
std::vector<CStr> m_Images[2]; // left and right
|
||||
|
||||
/**
|
||||
* Text and Sprite Calls.
|
||||
*/
|
||||
std::vector<SGUIText::STextCall> m_TextCalls;
|
||||
std::vector<SGUIText::SSpriteCall> m_SpriteCalls;
|
||||
|
||||
/**
|
||||
* Width and Height *feedback*
|
||||
*/
|
||||
CSize m_Size;
|
||||
|
||||
/**
|
||||
* If the word inputted was a new line.
|
||||
*/
|
||||
bool m_NewLine;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the value, the string will automatically
|
||||
* be parsed when set.
|
||||
*/
|
||||
void SetValue(const CStr &str);
|
||||
|
||||
/**
|
||||
* Get String, without tags
|
||||
*/
|
||||
CStr GetRawString() const { return m_RawString; }
|
||||
|
||||
/**
|
||||
* Generate Text Call from specified range. The range
|
||||
* must span only within ONE TextChunk though. Otherwise
|
||||
* it can't be fit into a single Text Call
|
||||
*
|
||||
* Notice it won't make it complete, you will have to add
|
||||
* X/Y values and such.
|
||||
*
|
||||
* @param Feedback contains all info that is generated.
|
||||
* @param DefaultFont Default Font
|
||||
* @param DefaultColor Default Color
|
||||
* @param from From character n,
|
||||
* @param to to chacter n.
|
||||
*/
|
||||
void GenerateTextCall(SFeedback &Feedback,
|
||||
const CStr &DefaultFont, /*const CColor &DefaultColor,*/
|
||||
const int &from, const int &to) const;
|
||||
|
||||
/**
|
||||
* Words
|
||||
*/
|
||||
std::vector<int> m_Words;
|
||||
|
||||
/**
|
||||
* TextChunks
|
||||
*/
|
||||
std::vector<TextChunk> m_TextChunks;
|
||||
|
||||
private:
|
||||
/**
|
||||
* The full raw string. Stripped of tags.
|
||||
*/
|
||||
CStr m_RawString;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -10,6 +10,122 @@ gee@pyro.nu
|
|||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
bool __ParseString(const CStr &Value, T &tOutput)
|
||||
{
|
||||
// TODO Gee: Unsupported, report error/warning
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool __ParseString<bool>(const CStr &Value, bool &Output)
|
||||
{
|
||||
if (Value == CStr(_T("true")))
|
||||
Output = true;
|
||||
else
|
||||
if (Value == CStr(_T("false")))
|
||||
Output = false;
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool __ParseString<int>(const CStr &Value, int &Output)
|
||||
{
|
||||
Output = Value.ToInt();
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool __ParseString<float>(const CStr &Value, float &Output)
|
||||
{
|
||||
Output = Value.ToFloat();
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool __ParseString<CRect>(const CStr &Value, CRect &Output)
|
||||
{
|
||||
// Use the parser to parse the values
|
||||
CParser parser;
|
||||
parser.InputTaskType("", "_$value_$value_$value_$value_");
|
||||
|
||||
string str = (const TCHAR*)Value;
|
||||
|
||||
CParserLine line;
|
||||
line.ParseString(parser, str);
|
||||
if (!line.m_ParseOK)
|
||||
{
|
||||
// Parsing failed
|
||||
return false;
|
||||
}
|
||||
int values[4];
|
||||
for (int i=0; i<4; ++i)
|
||||
{
|
||||
if (!line.GetArgInt(i, values[i]))
|
||||
{
|
||||
// Parsing failed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally the rectangle values
|
||||
Output = CRect(values[0], values[1], values[2], values[3]);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool __ParseString<CClientArea>(const CStr &Value, CClientArea &Output)
|
||||
{
|
||||
return Output.SetClientArea(Value);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool __ParseString<CColor>(const CStr &Value, CColor &Output)
|
||||
{
|
||||
// Use the parser to parse the values
|
||||
CParser parser;
|
||||
parser.InputTaskType("", "_$value_$value_$value_[$value_]");
|
||||
|
||||
string str = (const TCHAR*)Value;
|
||||
|
||||
CParserLine line;
|
||||
line.ParseString(parser, str);
|
||||
if (!line.m_ParseOK)
|
||||
{
|
||||
// TODO Gee: Parsing failed
|
||||
return false;
|
||||
}
|
||||
float values[4];
|
||||
values[3] = 255.f; // default
|
||||
for (int i=0; i<line.GetArgCount(); ++i)
|
||||
{
|
||||
if (!line.GetArgFloat(i, values[i]))
|
||||
{
|
||||
// TODO Gee: Parsing failed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Output.r = values[0]/255.f;
|
||||
Output.g = values[1]/255.f;
|
||||
Output.b = values[2]/255.f;
|
||||
Output.a = values[3]/255.f;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool __ParseString<CGUIString>(const CStr &Value, CGUIString &Output)
|
||||
{
|
||||
const char * buf = Value;
|
||||
|
||||
Output.SetValue(Value);
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Help Classes/Structs for the GUI implementation
|
||||
//--------------------------------------------------------
|
||||
|
|
@ -177,11 +293,6 @@ void CInternalCGUIAccessorBase::QueryResetting(IGUIObject *pObject)
|
|||
GUI<>::RecurseObject(0, pObject, &IGUIObject::ResetStates);
|
||||
}
|
||||
|
||||
void * CInternalCGUIAccessorBase::GetStructPointer(IGUIObject *pObject, const EGUISettingsStruct &SettingsStruct)
|
||||
{
|
||||
return pObject->GetStructPointer(SettingsStruct);
|
||||
}
|
||||
|
||||
void CInternalCGUIAccessorBase::HandleMessage(IGUIObject *pObject, const SGUIMessage &message)
|
||||
{
|
||||
pObject->HandleMessage(message);
|
||||
|
|
|
|||
|
|
@ -23,40 +23,39 @@ gee@pyro.nu
|
|||
//--------------------------------------------------------
|
||||
#include "GUI.h"
|
||||
#include "Parser.h"
|
||||
// TODO Gee: New
|
||||
#include "Overlay.h"
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Help Classes/Structs for the GUI
|
||||
//--------------------------------------------------------
|
||||
// TEMP
|
||||
struct CRect
|
||||
{
|
||||
CRect() {}
|
||||
CRect(int _l, int _t, int _r, int _b) :
|
||||
left(_l),
|
||||
top(_t),
|
||||
right(_r),
|
||||
bottom(_b) {}
|
||||
int bottom, top, left, right;
|
||||
|
||||
bool operator ==(const CRect &rect) const
|
||||
{
|
||||
return (bottom==rect.bottom) &&
|
||||
(top==rect.top) &&
|
||||
(left==rect.left) &&
|
||||
(right==rect.right);
|
||||
}
|
||||
class CClientArea;
|
||||
class CGUIString;
|
||||
|
||||
bool operator !=(const CRect &rect) const
|
||||
{
|
||||
return !(*this==rect);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
bool __ParseString(const CStr &Value, T &tOutput);
|
||||
|
||||
// TEMP
|
||||
struct CColor
|
||||
{
|
||||
float r, g, b, a;
|
||||
};
|
||||
template <>
|
||||
bool __ParseString<bool>(const CStr &Value, bool &Output);
|
||||
|
||||
template <>
|
||||
bool __ParseString<int>(const CStr &Value, int &Output);
|
||||
|
||||
template <>
|
||||
bool __ParseString<float>(const CStr &Value, float &Output);
|
||||
|
||||
template <>
|
||||
bool __ParseString<CRect>(const CStr &Value, CRect &Output);
|
||||
|
||||
template <>
|
||||
bool __ParseString<CClientArea>(const CStr &Value, CClientArea &Output);
|
||||
|
||||
template <>
|
||||
bool __ParseString<CColor>(const CStr &Value, CColor &Output);
|
||||
|
||||
template <>
|
||||
bool __ParseString<CGUIString>(const CStr &Value, CGUIString &Output);
|
||||
|
||||
/**
|
||||
* @author Gustav Larsson
|
||||
|
|
@ -66,7 +65,7 @@ struct CColor
|
|||
* You can input the whole value of the Client Area by
|
||||
* string. Like used in the GUI.
|
||||
*/
|
||||
struct CClientArea
|
||||
class CClientArea
|
||||
{
|
||||
public:
|
||||
CClientArea();
|
||||
|
|
@ -128,8 +127,6 @@ protected:
|
|||
/// Wrapper for ResetStates
|
||||
static void QueryResetting(IGUIObject *pObject);
|
||||
|
||||
static void * GetStructPointer(IGUIObject *pObject, const EGUISettingsStruct &SettingsStruct);
|
||||
|
||||
static void HandleMessage(IGUIObject *pObject, const SGUIMessage &message);
|
||||
};
|
||||
|
||||
|
|
@ -167,13 +164,12 @@ public:
|
|||
if (!pObject->SettingExists(Setting))
|
||||
return PS_SETTING_FAIL;
|
||||
|
||||
// Set value
|
||||
Value =
|
||||
// *(T*)((size_t)pObject->GetStructPointer(pObject->GetSettingsInfo()[Setting].m_SettingsStruct) +
|
||||
// pObject->GetSettingsInfo()[Setting].m_Offset);
|
||||
*(T*)((size_t)GetStructPointer(pObject, pObject->GetSettingsInfo()[Setting].m_SettingsStruct) +
|
||||
pObject->GetSettingsInfo()[Setting].m_Offset);
|
||||
if (!pObject->m_Settings.find(Setting)->second.m_pSetting)
|
||||
return PS_FAIL;
|
||||
|
||||
// Set value
|
||||
Value = *(T*)pObject->m_Settings.find(Setting)->second.m_pSetting;
|
||||
|
||||
return PS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -196,11 +192,7 @@ public:
|
|||
return PS_SETTING_FAIL;
|
||||
|
||||
// Set value
|
||||
//*(T*)((size_t)pObject->GetStructPointer(pObject->GetSettingsInfo()[Setting].m_SettingsStruct) +
|
||||
// pObject->GetSettingsInfo()[Setting].m_Offset) = Value;
|
||||
*(T*)((size_t)GetStructPointer(pObject, pObject->GetSettingsInfo()[Setting].m_SettingsStruct) +
|
||||
pObject->GetSettingsInfo()[Setting].m_Offset) = Value;
|
||||
|
||||
*(T*)pObject->m_Settings[Setting].m_pSetting = Value;
|
||||
|
||||
//
|
||||
// Some settings needs special attention at change
|
||||
|
|
@ -219,12 +211,24 @@ public:
|
|||
//RecurseObject(0, pObject, IGUIObject::ResetStates);
|
||||
}
|
||||
|
||||
//pObject->HandleMessage(SGUIMessage(GUIM_SETTINGS_UPDATED, Setting));
|
||||
HandleMessage(pObject, SGUIMessage(GUIM_SETTINGS_UPDATED, Setting));
|
||||
|
||||
return PS_OK;
|
||||
}
|
||||
|
||||
#ifdef g_GUI
|
||||
/**
|
||||
* Adapter that uses the singleton g_GUI
|
||||
* Can safely be removed.
|
||||
*/
|
||||
static PS_RESULT GetSetting(
|
||||
const CStr &Object,
|
||||
const CStr &Setting, T &Value)
|
||||
{
|
||||
return GetSetting(g_GUI, Object, Setting, Value);
|
||||
}
|
||||
#endif // g_GUI
|
||||
|
||||
/**
|
||||
* Retrieves a setting by settings name and object name
|
||||
*
|
||||
|
|
@ -246,6 +250,18 @@ public:
|
|||
return GetSetting(pObject, Setting, Value);
|
||||
}
|
||||
|
||||
#ifdef g_GUI
|
||||
/**
|
||||
* Adapter that uses the singleton g_GUI
|
||||
* Can safely be removed.
|
||||
*/
|
||||
static PS_RESULT SetSetting(
|
||||
const CStr &Object, const CStr &Setting, const T &Value)
|
||||
{
|
||||
return SetSetting(g_GUI, Object, Setting, Value);
|
||||
}
|
||||
#endif // g_GUI
|
||||
|
||||
/**
|
||||
* Sets a value by setting and object name using a real
|
||||
* datatype as input
|
||||
|
|
@ -274,8 +290,36 @@ public:
|
|||
|
||||
return SetSetting(pObject, Setting, Value);
|
||||
}
|
||||
|
||||
/**
|
||||
* This will return the value of the first sprite if it's not null,
|
||||
* if it is null, it will return the value of the second sprite, if
|
||||
* that one is null, then null it is.
|
||||
*
|
||||
* @param prim Primary sprite that should be used
|
||||
* @param sec Secondary sprite if Primary should fail
|
||||
* @return Resulting string
|
||||
*/
|
||||
static CStr FallBackSprite(const CStr &prim, const CStr &sec)
|
||||
{
|
||||
// CStr() == empty string, null
|
||||
return ((prim!=CStr())?(prim):(sec));
|
||||
}
|
||||
|
||||
/**
|
||||
* Same principle as FallBackSprite
|
||||
*
|
||||
* @param prim Primary color that should be used
|
||||
* @param sec Secondary color if Primary should fail
|
||||
* @return Resulting color
|
||||
* @see FallBackSprite
|
||||
*/
|
||||
static CColor FallBackColor(const CColor &prim, const CColor &sec)
|
||||
{
|
||||
// CColor() == null.
|
||||
return ((prim!=CColor())?(prim):(sec));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets a value by setting and object name using a real
|
||||
* datatype as input.
|
||||
|
|
@ -283,7 +327,6 @@ public:
|
|||
* This is just a wrapper for _mem_ParseString() which really
|
||||
* works the magic.
|
||||
*
|
||||
* @param Type type in string, like "float" or "client area"
|
||||
* @param Value The value in string form, like "0 0 100% 100%"
|
||||
* @param tOutput Parsed value of type T
|
||||
* @return True at success.
|
||||
|
|
@ -292,164 +335,10 @@ public:
|
|||
*/
|
||||
static bool ParseString(const CStr &Value, T &tOutput)
|
||||
{
|
||||
void *mem = NULL;
|
||||
|
||||
if (!_mem_ParseString(Value, mem))
|
||||
return false;
|
||||
|
||||
// Copy from memory
|
||||
tOutput = *(T*)mem;
|
||||
|
||||
free(mem);
|
||||
|
||||
// TODO Gee: Undefined type - maybe report in log
|
||||
return true;
|
||||
return __ParseString<T>(Value, tOutput);
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Input a value in string form, and it will output the result in
|
||||
* Memory with type T.
|
||||
*
|
||||
* @param Type type in string, like "float" or "client area"
|
||||
* @param Value The value in string form, like "0 0 100% 100%"
|
||||
* @param Memory Should be NULL, will be constructed within the function.
|
||||
* @return True at success.
|
||||
*/
|
||||
static bool _mem_ParseString(const CStr &Value, void *&Memory)
|
||||
{
|
||||
/* if (typeid(T) == typeid(CStr))
|
||||
{
|
||||
tOutput = Value;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
*/ if (typeid(T) == typeid(bool))
|
||||
{
|
||||
bool _Value;
|
||||
|
||||
if (Value == CStr(_T("true")))
|
||||
_Value = true;
|
||||
else
|
||||
if (Value == CStr(_T("false")))
|
||||
_Value = false;
|
||||
else
|
||||
return false;
|
||||
|
||||
Memory = malloc(sizeof(bool));
|
||||
memcpy(Memory, (const void*)&_Value, sizeof(bool));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (typeid(T) == typeid(float))
|
||||
{
|
||||
float _Value = Value.ToFloat();
|
||||
// TODO Gee: Okay float value!?
|
||||
Memory = malloc(sizeof(float));
|
||||
memcpy(Memory, (const void*)&_Value, sizeof(float));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (typeid(T) == typeid(int))
|
||||
{
|
||||
int _Value = Value.ToInt();
|
||||
// TODO Gee: Okay float value!?
|
||||
Memory = malloc(sizeof(int));
|
||||
memcpy(Memory, (const void*)&_Value, sizeof(int));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (typeid(T) == typeid(CRect))
|
||||
{
|
||||
// Use the parser to parse the values
|
||||
CParser parser;
|
||||
parser.InputTaskType("", "_$value_$value_$value_$value_");
|
||||
|
||||
string str = (const TCHAR*)Value;
|
||||
|
||||
CParserLine line;
|
||||
line.ParseString(parser, str);
|
||||
if (!line.m_ParseOK)
|
||||
{
|
||||
// Parsing failed
|
||||
return false;
|
||||
}
|
||||
int values[4];
|
||||
for (int i=0; i<4; ++i)
|
||||
{
|
||||
if (!line.GetArgInt(i, values[i]))
|
||||
{
|
||||
// Parsing failed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally the rectangle values
|
||||
CRect _Value(values[0], values[1], values[2], values[3]);
|
||||
|
||||
Memory = malloc(sizeof(CRect));
|
||||
memcpy(Memory, (const void*)&_Value, sizeof(CRect));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (typeid(T) == typeid(CClientArea))
|
||||
{
|
||||
// Get Client Area
|
||||
CClientArea _Value;
|
||||
|
||||
// Check if valid!
|
||||
if (!_Value.SetClientArea(Value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Memory = malloc(sizeof(CClientArea));
|
||||
memcpy(Memory, (const void*)&_Value, sizeof(CClientArea));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (typeid(T) == typeid(CColor))
|
||||
{
|
||||
// Use the parser to parse the values
|
||||
CParser parser;
|
||||
parser.InputTaskType("", "_$value_$value_$value_[$value_]");
|
||||
|
||||
string str = (const TCHAR*)Value;
|
||||
|
||||
CParserLine line;
|
||||
line.ParseString(parser, str);
|
||||
if (!line.m_ParseOK)
|
||||
{
|
||||
// TODO Gee: Parsing failed
|
||||
return false;
|
||||
}
|
||||
float values[4];
|
||||
values[3] = 255.f; // default
|
||||
for (int i=0; i<line.GetArgCount(); ++i)
|
||||
{
|
||||
if (!line.GetArgFloat(i, values[i]))
|
||||
{
|
||||
// TODO Gee: Parsing failed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally the rectangle values
|
||||
CColor _Value;
|
||||
// TODO Gee: Done better when CColor is sweeter
|
||||
_Value.r = values[0]/255.f;
|
||||
_Value.g = values[1]/255.f;
|
||||
_Value.b = values[2]/255.f;
|
||||
_Value.a = values[3]/255.f;
|
||||
|
||||
Memory = malloc(sizeof(CColor));
|
||||
memcpy(Memory, (const void*)&_Value, sizeof(CColor));
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO Gee: Undefined type - maybe report in log
|
||||
return false;
|
||||
}
|
||||
|
||||
// templated typedef of function pointer
|
||||
typedef void (IGUIObject::*void_Object_pFunction_argT)(const T &arg);
|
||||
|
|
@ -553,17 +442,26 @@ private:
|
|||
{
|
||||
if (RR & GUIRR_HIDDEN)
|
||||
{
|
||||
if (pObject->GetBaseSettings().m_Hidden)
|
||||
bool hidden;
|
||||
GUI<bool>::GetSetting(pObject, "hidden", hidden);
|
||||
|
||||
if (hidden)
|
||||
return true;
|
||||
}
|
||||
if (RR & GUIRR_DISABLED)
|
||||
{
|
||||
if (pObject->GetBaseSettings().m_Enabled)
|
||||
bool enabled;
|
||||
GUI<bool>::GetSetting(pObject, "enabled", enabled);
|
||||
|
||||
if (!enabled)
|
||||
return true;
|
||||
}
|
||||
if (RR & GUIRR_GHOST)
|
||||
{
|
||||
if (pObject->GetBaseSettings().m_Ghost)
|
||||
bool ghost;
|
||||
GUI<bool>::GetSetting(pObject, "ghost", ghost);
|
||||
|
||||
if (ghost)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,38 +22,26 @@ IGUIButtonBehavior::~IGUIButtonBehavior()
|
|||
|
||||
void IGUIButtonBehavior::HandleMessage(const SGUIMessage &Message)
|
||||
{
|
||||
// TODO Gee: easier access functions
|
||||
switch (Message.type)
|
||||
{
|
||||
case GUIM_PREPROCESS:
|
||||
m_Pressed = false;
|
||||
break;
|
||||
|
||||
/* case GUIM_POSTPROCESS:
|
||||
// Check if button has been pressed
|
||||
if (m_Pressed)
|
||||
{
|
||||
// Now check if mouse is released, that means
|
||||
// it's released outside, since GUIM_MOUSE_RELEASE_LEFT
|
||||
// would've handled m_Pressed and reset it already
|
||||
|
||||
// Get input structure
|
||||
/// if (GetGUI()->GetInput()->mRelease(NEMM_BUTTON1))
|
||||
{
|
||||
// Reset
|
||||
m_Pressed = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
*/
|
||||
case GUIM_MOUSE_PRESS_LEFT:
|
||||
if (!GetBaseSettings().m_Enabled)
|
||||
{
|
||||
bool enabled;
|
||||
GUI<bool>::GetSetting(this, "enabled", enabled);
|
||||
|
||||
if (!enabled)
|
||||
break;
|
||||
|
||||
m_Pressed = true;
|
||||
break;
|
||||
} break;
|
||||
|
||||
case GUIM_MOUSE_RELEASE_LEFT:
|
||||
if (!GetBaseSettings().m_Enabled)
|
||||
{
|
||||
bool enabled;
|
||||
GUI<bool>::GetSetting(this, "enabled", enabled);
|
||||
|
||||
if (!enabled)
|
||||
break;
|
||||
|
||||
if (m_Pressed)
|
||||
|
|
@ -62,7 +50,7 @@ void IGUIButtonBehavior::HandleMessage(const SGUIMessage &Message)
|
|||
// BUTTON WAS CLICKED
|
||||
HandleMessage(GUIM_PRESSED);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
case GUIM_SETTINGS_UPDATED:
|
||||
// If it's hidden, then it can't be pressed
|
||||
|
|
@ -74,3 +62,59 @@ void IGUIButtonBehavior::HandleMessage(const SGUIMessage &Message)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CColor IGUIButtonBehavior::ChooseColor()
|
||||
{
|
||||
CColor color, color_over, color_pressed, color_disabled;
|
||||
|
||||
// Yes, the object must possess these settings. They are standard
|
||||
GUI<CColor>::GetSetting(this, "textcolor", color);
|
||||
GUI<CColor>::GetSetting(this, "textcolor-over", color_over);
|
||||
GUI<CColor>::GetSetting(this, "textcolor-pressed", color_pressed);
|
||||
GUI<CColor>::GetSetting(this, "textcolor-disabled", color_disabled);
|
||||
|
||||
bool enabled;
|
||||
GUI<bool>::GetSetting(this, "enabled", enabled);
|
||||
|
||||
if (!enabled)
|
||||
{
|
||||
return GUI<>::FallBackColor(color_disabled, color);
|
||||
}
|
||||
else
|
||||
if (m_MouseHovering)
|
||||
{
|
||||
if (m_Pressed)
|
||||
return GUI<>::FallBackColor(color_pressed, color);
|
||||
else
|
||||
return GUI<>::FallBackColor(color_over, color);
|
||||
}
|
||||
else return color;
|
||||
}
|
||||
|
||||
void IGUIButtonBehavior::DrawButton(const CRect &rect,
|
||||
const float &z,
|
||||
const CStr &sprite,
|
||||
const CStr &sprite_over,
|
||||
const CStr &sprite_pressed,
|
||||
const CStr &sprite_disabled)
|
||||
{
|
||||
if (GetGUI())
|
||||
{
|
||||
bool enabled;
|
||||
GUI<bool>::GetSetting(this, "enabled", enabled);
|
||||
|
||||
if (!enabled)
|
||||
{
|
||||
GetGUI()->DrawSprite(GUI<>::FallBackSprite(sprite_disabled, sprite), z, rect);
|
||||
}
|
||||
else
|
||||
if (m_MouseHovering)
|
||||
{
|
||||
if (m_Pressed)
|
||||
GetGUI()->DrawSprite(GUI<>::FallBackSprite(sprite_pressed, sprite), z, rect);
|
||||
else
|
||||
GetGUI()->DrawSprite(GUI<>::FallBackSprite(sprite_over, sprite), z, rect);
|
||||
}
|
||||
else GetGUI()->DrawSprite(sprite, z, rect);
|
||||
}
|
||||
}
|
||||
|
|
@ -57,6 +57,34 @@ public:
|
|||
*/
|
||||
virtual void HandleMessage(const SGUIMessage &Message);
|
||||
|
||||
/**
|
||||
* This is a function that lets a button being drawn,
|
||||
* it regards if it's over, disabled, pressed and such.
|
||||
* You input sprite names and area and it'll output
|
||||
* it accordingly.
|
||||
*
|
||||
* This class is meant to be used manually in Draw()
|
||||
*
|
||||
* @param rect Rectangle in which the sprite should be drawn
|
||||
* @param z Z-value
|
||||
* @param sprite Sprite drawn when not pressed, hovered or disabled
|
||||
* @param sprite_over Sprite drawn when m_MouseHovering is true
|
||||
* @param sprite_pressed Sprite drawn when m_Pressed is true
|
||||
* @param sprite_disabled Sprite drawn when "enabled" is false
|
||||
*/
|
||||
void DrawButton(const CRect &rect,
|
||||
const float &z,
|
||||
const CStr &sprite,
|
||||
const CStr &sprite_over,
|
||||
const CStr &sprite_pressed,
|
||||
const CStr &sprite_disabled);
|
||||
|
||||
/**
|
||||
* Choosing which color of the following according to
|
||||
*/
|
||||
CColor IGUIButtonBehavior::ChooseColor();
|
||||
|
||||
|
||||
protected:
|
||||
virtual void ResetStates()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,16 +14,10 @@ gee@pyro.nu
|
|||
|
||||
using namespace std;
|
||||
|
||||
// Offsets
|
||||
map_Settings IGUIObject::m_SettingsInfo;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Implementation Macros
|
||||
//-------------------------------------------------------------------
|
||||
/*#define _GUI_ADD_OFFSET(type, str, var) \
|
||||
SettingsInfo[str].m_Offset = offsetof(IGUIObject, m_BaseSettings) + offsetof(SGUIBaseSettings,var); \
|
||||
SettingsInfo[str].m_Type = type;
|
||||
*/
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Constructor / Destructor
|
||||
//-------------------------------------------------------------------
|
||||
|
|
@ -32,21 +26,38 @@ IGUIObject::IGUIObject() :
|
|||
m_pParent(NULL),
|
||||
m_MouseHovering(false)
|
||||
{
|
||||
// TODO Gee: Remove this when base object is excluded from the recursion routines.
|
||||
m_BaseSettings.m_Hidden = false;
|
||||
m_BaseSettings.m_Ghost = false;
|
||||
m_BaseSettings.m_Enabled = true;
|
||||
m_BaseSettings.m_Absolute = true;
|
||||
AddSetting(GUIST_bool, "enabled");
|
||||
AddSetting(GUIST_bool, "hidden");
|
||||
AddSetting(GUIST_CClientArea, "size");
|
||||
AddSetting(GUIST_CStr, "style");
|
||||
AddSetting(GUIST_float, "z");
|
||||
// AddSetting(GUIST_CGUIString, "caption");
|
||||
AddSetting(GUIST_bool, "absolute");
|
||||
AddSetting(GUIST_bool, "ghost");
|
||||
|
||||
// Static! Only done once
|
||||
if (m_SettingsInfo.empty())
|
||||
{
|
||||
SetupBaseSettingsInfo(m_SettingsInfo);
|
||||
}
|
||||
// Setup important defaults
|
||||
GUI<bool>::SetSetting(this, "hidden", false);
|
||||
GUI<bool>::SetSetting(this, "ghost", false);
|
||||
GUI<bool>::SetSetting(this, "enabled", true);
|
||||
GUI<bool>::SetSetting(this, "absolute", true);
|
||||
|
||||
|
||||
|
||||
bool hidden=true;
|
||||
|
||||
GUI<bool>::GetSetting(this, "hidden", hidden);
|
||||
|
||||
int hej=23;
|
||||
}
|
||||
|
||||
IGUIObject::~IGUIObject()
|
||||
{
|
||||
map<CStr, SGUISetting>::iterator it;
|
||||
for (it = m_Settings.begin(); it != m_Settings.end(); ++it)
|
||||
{
|
||||
if (!it->second.m_pSetting)
|
||||
delete it->second.m_pSetting;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
|
@ -116,24 +127,36 @@ void IGUIObject::Destroy()
|
|||
// Is there anything besides the children to destroy?
|
||||
}
|
||||
|
||||
void IGUIObject::SetupBaseSettingsInfo(map_Settings &SettingsInfo)
|
||||
// Notice if using this, the naming convention of GUIST_ should be strict.
|
||||
#define CASE_TYPE(type) \
|
||||
case GUIST_##type: \
|
||||
m_Settings[Name].m_pSetting = new type(); \
|
||||
break;
|
||||
|
||||
void IGUIObject::AddSetting(const EGUISettingType &Type, const CStr &Name)
|
||||
{
|
||||
/* _GUI_ADD_OFFSET("bool", "enabled", m_Enabled)
|
||||
_GUI_ADD_OFFSET("bool", "hidden", m_Hidden)
|
||||
_GUI_ADD_OFFSET("client area", "size", m_Size)
|
||||
_GUI_ADD_OFFSET("string", "style", m_Style)
|
||||
_GUI_ADD_OFFSET("float", "z", m_Z)
|
||||
_GUI_ADD_OFFSET("string", "caption", m_Caption)
|
||||
_GUI_ADD_OFFSET("bool", "absolute", m_Absolute)
|
||||
*/
|
||||
GUI_ADD_OFFSET_GENERIC(SettingsInfo, GUISS_BASE, SGUIBaseSettings, m_Enabled, "bool", "enabled")
|
||||
GUI_ADD_OFFSET_GENERIC(SettingsInfo, GUISS_BASE, SGUIBaseSettings, m_Hidden, "bool", "hidden")
|
||||
GUI_ADD_OFFSET_GENERIC(SettingsInfo, GUISS_BASE, SGUIBaseSettings, m_Size, "client area", "size")
|
||||
GUI_ADD_OFFSET_GENERIC(SettingsInfo, GUISS_BASE, SGUIBaseSettings, m_Style, "string", "style")
|
||||
GUI_ADD_OFFSET_GENERIC(SettingsInfo, GUISS_BASE, SGUIBaseSettings, m_Z, "float", "z")
|
||||
GUI_ADD_OFFSET_GENERIC(SettingsInfo, GUISS_BASE, SGUIBaseSettings, m_Caption, "string", "caption")
|
||||
GUI_ADD_OFFSET_GENERIC(SettingsInfo, GUISS_BASE, SGUIBaseSettings, m_Absolute, "bool", "absolute")
|
||||
GUI_ADD_OFFSET_GENERIC(SettingsInfo, GUISS_BASE, SGUIBaseSettings, m_Ghost, "bool", "ghost")
|
||||
// Is name already taken?
|
||||
if (m_Settings.count(Name) >= 1)
|
||||
return;
|
||||
|
||||
// Construct, and set type
|
||||
m_Settings[Name].m_Type = Type;
|
||||
|
||||
switch (Type)
|
||||
{
|
||||
// Construct the setting.
|
||||
CASE_TYPE(bool)
|
||||
CASE_TYPE(int)
|
||||
CASE_TYPE(float)
|
||||
CASE_TYPE(CClientArea)
|
||||
CASE_TYPE(CStr)
|
||||
CASE_TYPE(CColor)
|
||||
CASE_TYPE(CGUIString)
|
||||
|
||||
default:
|
||||
// TODO Gee: Report in log, type is not recognized.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool IGUIObject::MouseOver()
|
||||
|
|
@ -141,23 +164,12 @@ bool IGUIObject::MouseOver()
|
|||
if(!GetGUI())
|
||||
throw PS_NEEDS_PGUI;
|
||||
|
||||
u16 mouse_x = GetMouseX(),
|
||||
mouse_y = GetMouseY();
|
||||
|
||||
return (mouse_x >= m_CachedActualSize.left &&
|
||||
mouse_x <= m_CachedActualSize.right &&
|
||||
mouse_y >= m_CachedActualSize.top &&
|
||||
mouse_y <= m_CachedActualSize.bottom);
|
||||
return m_CachedActualSize.PointInside(GetMousePos());
|
||||
}
|
||||
|
||||
u16 IGUIObject::GetMouseX() const
|
||||
CPos IGUIObject::GetMousePos() const
|
||||
{
|
||||
return ((GetGUI())?(GetGUI()->m_MouseX):0);
|
||||
}
|
||||
|
||||
u16 IGUIObject::GetMouseY() const
|
||||
{
|
||||
return ((GetGUI())?(GetGUI()->m_MouseY):0);
|
||||
return ((GetGUI())?(GetGUI()->m_MousePos):CPos());
|
||||
}
|
||||
|
||||
void IGUIObject::UpdateMouseOver(IGUIObject * const &pMouseOver)
|
||||
|
|
@ -190,12 +202,24 @@ void IGUIObject::UpdateMouseOver(IGUIObject * const &pMouseOver)
|
|||
bool IGUIObject::SettingExists(const CStr &Setting) const
|
||||
{
|
||||
// Because GetOffsets will direct dynamically defined
|
||||
// classes with polymorifsm to respective m_SettingsInfo
|
||||
// classes with polymorifsm to respective ms_SettingsInfo
|
||||
// we need to make no further updates on this function
|
||||
// in derived classes.
|
||||
return (GetSettingsInfo().count(Setting) == 1)?true:false;
|
||||
//return (GetSettingsInfo().count(Setting) >= 1);
|
||||
return (m_Settings.count(Setting) >= 1);
|
||||
}
|
||||
|
||||
#define ADD_TYPE(type) \
|
||||
else \
|
||||
if (set.m_Type == GUIST_##type) \
|
||||
{ \
|
||||
type _Value; \
|
||||
if (!GUI<type>::ParseString(Value, _Value)) \
|
||||
throw PS_FAIL; \
|
||||
\
|
||||
GUI<type>::SetSetting(this, Setting, _Value); \
|
||||
}
|
||||
|
||||
void IGUIObject::SetSetting(const CStr &Setting, const CStr &Value)
|
||||
{
|
||||
if (!SettingExists(Setting))
|
||||
|
|
@ -204,48 +228,18 @@ void IGUIObject::SetSetting(const CStr &Setting, const CStr &Value)
|
|||
}
|
||||
|
||||
// Get setting
|
||||
SGUISetting set = GetSettingsInfo()[Setting];
|
||||
SGUISetting set = m_Settings[Setting];
|
||||
|
||||
if (set.m_Type == CStr(_T("string")))
|
||||
if (set.m_Type == GUIST_CStr)
|
||||
{
|
||||
GUI<CStr>::SetSetting(this, Setting, Value);
|
||||
}
|
||||
else
|
||||
if (set.m_Type == CStr(_T("bool")))
|
||||
{
|
||||
bool _Value;
|
||||
if (!GUI<bool>::ParseString(Value, _Value))
|
||||
throw PS_FAIL;
|
||||
|
||||
GUI<bool>::SetSetting(this, Setting, _Value);
|
||||
}
|
||||
else
|
||||
if (set.m_Type == CStr(_T("float")))
|
||||
{
|
||||
float _Value;
|
||||
if (!GUI<float>::ParseString(Value, _Value))
|
||||
throw PS_FAIL;
|
||||
|
||||
GUI<float>::SetSetting(this, Setting, _Value);
|
||||
}
|
||||
else
|
||||
if (set.m_Type == CStr(_T("rect")))
|
||||
{
|
||||
CRect _Value;
|
||||
if (!GUI<CRect>::ParseString(Value, _Value))
|
||||
throw PS_FAIL;
|
||||
|
||||
GUI<CRect>::SetSetting(this, Setting, _Value);
|
||||
}
|
||||
else
|
||||
if (set.m_Type == CStr(_T("client area")))
|
||||
{
|
||||
CClientArea _Value;
|
||||
if (!GUI<CClientArea>::ParseString(Value, _Value))
|
||||
throw PS_FAIL;
|
||||
|
||||
GUI<CClientArea>::SetSetting(this, Setting, _Value);
|
||||
}
|
||||
ADD_TYPE(bool, "bool")
|
||||
ADD_TYPE(float, "float")
|
||||
ADD_TYPE(int, "int")
|
||||
ADD_TYPE(CColor, "color")
|
||||
ADD_TYPE(CClientArea, "client area")
|
||||
ADD_TYPE(CGUIString, "text")
|
||||
else
|
||||
{
|
||||
throw PS_FAIL;
|
||||
|
|
@ -285,28 +279,22 @@ IGUIObject *IGUIObject::GetParent() const
|
|||
return m_pParent;
|
||||
}
|
||||
|
||||
void * IGUIObject::GetStructPointer(const EGUISettingsStruct &SettingsStruct) const
|
||||
{
|
||||
switch (SettingsStruct)
|
||||
{
|
||||
case GUISS_BASE:
|
||||
return (void*)&m_BaseSettings;
|
||||
|
||||
default:
|
||||
// TODO Gee: report error
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void IGUIObject::UpdateCachedSize()
|
||||
{
|
||||
bool absolute;
|
||||
GUI<bool>::GetSetting(this, "absolute", absolute);
|
||||
|
||||
CClientArea ca;
|
||||
GUI<CClientArea>::GetSetting(this, "size", ca);
|
||||
|
||||
// If absolute="false" and the object has got a parent,
|
||||
// use its cached size instead of the screen. Notice
|
||||
// it must have just been cached for it to work.
|
||||
if (m_BaseSettings.m_Absolute == false && m_pParent)
|
||||
m_CachedActualSize = m_BaseSettings.m_Size.GetClientArea( m_pParent->m_CachedActualSize );
|
||||
if (absolute == false && m_pParent)
|
||||
m_CachedActualSize = ca.GetClientArea(m_pParent->m_CachedActualSize);
|
||||
else
|
||||
m_CachedActualSize = m_BaseSettings.m_Size.GetClientArea( CRect(0, 0, g_xres, g_yres) );
|
||||
m_CachedActualSize = ca.GetClientArea(CRect(0, 0, g_xres, g_yres));
|
||||
|
||||
}
|
||||
|
||||
void IGUIObject::LoadStyle(CGUI &GUIinstance, const CStr &StyleName)
|
||||
|
|
@ -335,31 +323,39 @@ void IGUIObject::LoadStyle(const SGUIStyle &Style)
|
|||
// since it's generic.
|
||||
catch (PS_RESULT e)
|
||||
{
|
||||
// was ist das?
|
||||
e;
|
||||
// TODO Gee: was ist das?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float IGUIObject::GetBufferedZ() const
|
||||
{
|
||||
if (GetBaseSettings().m_Absolute)
|
||||
return GetBaseSettings().m_Z;
|
||||
bool absolute;
|
||||
GUI<bool>::GetSetting(this, "absolute", absolute);
|
||||
|
||||
float Z;
|
||||
GUI<float>::GetSetting(this, "z", Z);
|
||||
|
||||
if (absolute)
|
||||
return Z;
|
||||
else
|
||||
{
|
||||
if (GetParent())
|
||||
return GetParent()->GetBufferedZ() + GetBaseSettings().m_Z;
|
||||
return GetParent()->GetBufferedZ() + Z;
|
||||
else
|
||||
// TODO Gee: Error, no object should be relative with a parent!
|
||||
return GetBaseSettings().m_Z;
|
||||
// TODO Gee: Error, no object should be relative without a parent!
|
||||
return Z;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Gee: keep this function and all???
|
||||
void IGUIObject::CheckSettingsValidity()
|
||||
{
|
||||
bool hidden;
|
||||
GUI<bool>::GetSetting(this, "hidden", hidden);
|
||||
|
||||
// If we hide an object, reset many of its parts
|
||||
if (GetBaseSettings().m_Hidden)
|
||||
if (hidden)
|
||||
{
|
||||
// Simulate that no object is hovered for this object and all its children
|
||||
// why? because it's
|
||||
|
|
|
|||
|
|
@ -63,17 +63,39 @@ typedef std::map<CStr, SGUISetting> map_Settings;
|
|||
enum EAlign { EAlign_Left, EAlign_Right, EAlign_Center };
|
||||
enum EValign { EValign_Top, EValign_Bottom, EValign_Center };
|
||||
|
||||
/**
|
||||
* Setting Type
|
||||
* @see SGUISetting
|
||||
*
|
||||
* For use of later macros, all names should be GUIST_ followed
|
||||
* by the code name (case sensitive!).
|
||||
*/
|
||||
enum EGUISettingType
|
||||
{
|
||||
GUIST_bool,
|
||||
GUIST_int,
|
||||
GUIST_float,
|
||||
GUIST_CColor,
|
||||
GUIST_CClientArea,
|
||||
GUIST_CGUIString,
|
||||
GUIST_CStr
|
||||
};
|
||||
|
||||
/**
|
||||
* @author Gustav Larsson
|
||||
*
|
||||
* Stores the information where to find a variable
|
||||
* in a GUI-Object object, also what type it is.
|
||||
* A GUI Setting is anything that can be inputted from XML as
|
||||
* <object>-attributes (with exceptions). For instance:
|
||||
* <object style="null">
|
||||
*
|
||||
* "style" will be a SGUISetting.
|
||||
*/
|
||||
struct SGUISetting
|
||||
{
|
||||
size_t m_Offset; // The offset from IGUIObject to the variable (not from SGUIBaseSettings or similar)
|
||||
EGUISettingsStruct m_SettingsStruct;
|
||||
CStr m_Type; // "string" or maybe "int"
|
||||
SGUISetting() : m_pSetting(NULL) {}
|
||||
|
||||
void *m_pSetting;
|
||||
EGUISettingType m_Type;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -83,8 +105,9 @@ struct SGUISetting
|
|||
* in their m_BaseSettings
|
||||
* Instructions can be found in the documentations.
|
||||
*/
|
||||
struct SGUIBaseSettings
|
||||
/*struct SGUIBaseSettings
|
||||
{
|
||||
//int banan;
|
||||
bool m_Absolute;
|
||||
CStr m_Caption; // Is usually set within an XML element and not in the attributes
|
||||
bool m_Enabled;
|
||||
|
|
@ -93,7 +116,7 @@ struct SGUIBaseSettings
|
|||
CClientArea m_Size;
|
||||
CStr m_Style;
|
||||
float m_Z;
|
||||
};
|
||||
};*/
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -108,22 +131,11 @@ class IGUIObject
|
|||
friend class CGUI;
|
||||
friend class CInternalCGUIAccessorBase;
|
||||
friend class IGUIScrollBar;
|
||||
#ifndef _MSC_VER
|
||||
template <class T>
|
||||
#endif
|
||||
friend class GUI;
|
||||
|
||||
public:
|
||||
IGUIObject();
|
||||
virtual ~IGUIObject();
|
||||
|
||||
/**
|
||||
* Get offsets
|
||||
*
|
||||
* @return Retrieves settings info
|
||||
*/
|
||||
virtual map_Settings GetSettingsInfo() const { return m_SettingsInfo; }
|
||||
|
||||
/**
|
||||
* Checks if mouse is hovering this object.
|
||||
* The mouse position is cached in CGUI.
|
||||
|
|
@ -193,8 +205,6 @@ public:
|
|||
//--------------------------------------------------------
|
||||
//@{
|
||||
|
||||
SGUIBaseSettings GetBaseSettings() const { return m_BaseSettings; }
|
||||
|
||||
/**
|
||||
* Checks if settings exists, only available for derived
|
||||
* classes that has this set up, that's why the base
|
||||
|
|
@ -231,7 +241,7 @@ public:
|
|||
*
|
||||
* @param SettingsInfo Pointers that should be filled with base variables
|
||||
*/
|
||||
void SetupBaseSettingsInfo(map_Settings &SettingsInfo);
|
||||
//void SetupBaseSettingsInfo(map_Settings &SettingsInfo);
|
||||
|
||||
/**
|
||||
* Set a setting by string, regardless of what type it is.
|
||||
|
|
@ -259,6 +269,14 @@ protected:
|
|||
//--------------------------------------------------------
|
||||
//@{
|
||||
|
||||
/**
|
||||
* Add a setting to m_Settings
|
||||
*
|
||||
* @param Type Setting type
|
||||
* @param Name Setting reference name
|
||||
*/
|
||||
void AddSetting(const EGUISettingType &Type, const CStr &Name);
|
||||
|
||||
/**
|
||||
* Calls Destroy on all children, and deallocates all memory.
|
||||
* MEGA TODO Should it destroy it's children?
|
||||
|
|
@ -271,7 +289,7 @@ protected:
|
|||
*
|
||||
* @param Message GUI Message
|
||||
*/
|
||||
virtual void HandleMessage(const SGUIMessage &Message)=0;
|
||||
virtual void HandleMessage(const SGUIMessage &Message) {};
|
||||
|
||||
/**
|
||||
* Draws the object.
|
||||
|
|
@ -305,7 +323,7 @@ protected:
|
|||
*
|
||||
* @return Actual Z value on the screen.
|
||||
*/
|
||||
float GetBufferedZ() const;
|
||||
virtual float GetBufferedZ() const;
|
||||
|
||||
// This is done internally
|
||||
CGUI *GetGUI() { return m_pGUI; }
|
||||
|
|
@ -342,11 +360,12 @@ protected:
|
|||
*
|
||||
* @param SettingsStruct tells us which pointer ot return
|
||||
*/
|
||||
virtual void *GetStructPointer(const EGUISettingsStruct &SettingsStruct) const;
|
||||
//virtual void *GetStructPointer(const EGUISettingsStruct &SettingsStruct) const;
|
||||
|
||||
// Get cached mouse x/y from CGUI
|
||||
u16 GetMouseX() const;
|
||||
u16 GetMouseY() const;
|
||||
/**
|
||||
* Get Mouse from CGUI.
|
||||
*/
|
||||
CPos GetMousePos() const;
|
||||
|
||||
/**
|
||||
* Cached size, real size m_Size is actually dependent on resolution
|
||||
|
|
@ -402,7 +421,7 @@ protected:
|
|||
IGUIObject *m_pParent;
|
||||
|
||||
/// Base settings
|
||||
SGUIBaseSettings m_BaseSettings;
|
||||
//SGUIBaseSettings m_BaseSettings;
|
||||
|
||||
/**
|
||||
* This is an array of true or false, each element is associated with
|
||||
|
|
@ -429,7 +448,18 @@ protected:
|
|||
* <b>note!</b> @uNOT from SGUIBaseSettings to
|
||||
* m_Frozen!
|
||||
*/
|
||||
static map_Settings m_SettingsInfo;
|
||||
//static map_Settings ms_SettingsInfo;
|
||||
|
||||
/**
|
||||
* Settings pool, all an object's settings are located here
|
||||
* If a derived object has got more settings that the base
|
||||
* settings, it's becasue they have a new version of the
|
||||
* function SetupSettings().
|
||||
*
|
||||
* @see SetupSettings()
|
||||
*/
|
||||
public:
|
||||
std::map<CStr, SGUISetting> m_Settings;
|
||||
|
||||
private:
|
||||
/// An object can't function stand alone
|
||||
|
|
@ -441,10 +471,13 @@ private:
|
|||
* @author Gustav Larsson
|
||||
*
|
||||
* Dummy object used primarily for the root object
|
||||
* which isn't a *real* object in the GUI.
|
||||
* or objects of type 'empty'
|
||||
*/
|
||||
class CGUIDummyObject : public IGUIObject
|
||||
{
|
||||
GUI_OBJECT(CGUIDummyObject)
|
||||
|
||||
public:
|
||||
virtual void HandleMessage(const SGUIMessage &Message) {}
|
||||
virtual void Draw() {}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -12,7 +12,18 @@ using namespace std;
|
|||
//-------------------------------------------------------------------
|
||||
// IGUIScrollBar
|
||||
//-------------------------------------------------------------------
|
||||
IGUIScrollBar::IGUIScrollBar() : m_pStyle(NULL), m_X(300), m_Y(300), m_Length(200), m_Width(20), m_BarSize(0.5), m_Pos(0.5)
|
||||
IGUIScrollBar::IGUIScrollBar() : m_pStyle(NULL), m_pGUI(NULL),
|
||||
m_X(300), m_Y(300),
|
||||
m_ScrollRange(1), m_ScrollSpace(0), // MaxPos: not 0, due to division.
|
||||
m_Length(200), m_Width(20),
|
||||
m_BarSize(0.5), m_Pos(0),
|
||||
m_UseEdgeButtons(true),
|
||||
m_ButtonPlusPressed(false),
|
||||
m_ButtonMinusPressed(false),
|
||||
m_ButtonPlusHovered(false),
|
||||
m_ButtonMinusHovered(false),
|
||||
m_BarHovered(false),
|
||||
m_BarPressed(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -20,72 +31,122 @@ IGUIScrollBar::~IGUIScrollBar()
|
|||
{
|
||||
}
|
||||
|
||||
const SGUIScrollBarStyle & IGUIScrollBar::GetStyle() const
|
||||
void IGUIScrollBar::SetupBarSize()
|
||||
{
|
||||
m_BarSize = min((float)m_ScrollSpace/(float)m_ScrollRange, 1.f);
|
||||
}
|
||||
|
||||
const SGUIScrollBarStyle *IGUIScrollBar::GetStyle() const
|
||||
{
|
||||
if (!m_pHostObject)
|
||||
return SGUIScrollBarStyle();
|
||||
return NULL;
|
||||
|
||||
return m_pHostObject->GetScrollBarStyle(m_ScrollBarStyle);
|
||||
}
|
||||
|
||||
void IGUIScrollBar::UpdatePosBoundaries()
|
||||
{
|
||||
if (m_Pos > 1.f)
|
||||
m_Pos = 1.f;
|
||||
else
|
||||
if (m_Pos < 0.f)
|
||||
m_Pos = 0.f;
|
||||
CGUI *IGUIScrollBar::GetGUI() const
|
||||
{
|
||||
if (!m_pHostObject)
|
||||
return NULL;
|
||||
|
||||
return m_pHostObject->GetGUI();
|
||||
}
|
||||
|
||||
bool IGUIScrollBar::HandleMessage(const SGUIMessage &Message)
|
||||
void IGUIScrollBar::UpdatePosBoundaries()
|
||||
{
|
||||
if (m_Pos < 0 ||
|
||||
m_ScrollRange < m_ScrollSpace) // <= scrolling not applicable
|
||||
m_Pos = 0;
|
||||
else
|
||||
if (m_Pos > m_ScrollRange - m_ScrollSpace)
|
||||
m_Pos = m_ScrollRange - m_ScrollSpace;
|
||||
}
|
||||
|
||||
void IGUIScrollBar::HandleMessage(const SGUIMessage &Message)
|
||||
{
|
||||
switch (Message.type)
|
||||
{
|
||||
case GUIM_MOUSE_MOTION:
|
||||
if (m_BarPressed)
|
||||
{
|
||||
SetPosFromMousePos(m_pHostObject->GetMouseX(), m_pHostObject->GetMouseY());
|
||||
UpdatePosBoundaries();
|
||||
}
|
||||
break;
|
||||
// TODO Gee: Optimizations needed!
|
||||
|
||||
CPos mouse = m_pHostObject->GetMousePos();
|
||||
|
||||
// If bar is being dragged
|
||||
if (m_BarPressed)
|
||||
{
|
||||
SetPosFromMousePos(mouse);
|
||||
UpdatePosBoundaries();
|
||||
}
|
||||
|
||||
CRect bar_rect = GetBarRect();
|
||||
// check if components are being hovered
|
||||
m_BarHovered = bar_rect.PointInside(mouse);
|
||||
|
||||
m_ButtonMinusHovered = HoveringButtonMinus(m_pHostObject->GetMousePos());
|
||||
m_ButtonPlusHovered = HoveringButtonPlus(m_pHostObject->GetMousePos());
|
||||
|
||||
if (!m_ButtonMinusHovered)
|
||||
m_ButtonMinusPressed = false;
|
||||
|
||||
if (!m_ButtonPlusHovered)
|
||||
m_ButtonPlusPressed = false;
|
||||
} break;
|
||||
|
||||
case GUIM_MOUSE_PRESS_LEFT:
|
||||
{
|
||||
if (!m_pHostObject)
|
||||
break;
|
||||
|
||||
int mouse_x = m_pHostObject->GetMouseX(),
|
||||
mouse_y = m_pHostObject->GetMouseY();
|
||||
CPos mouse = m_pHostObject->GetMousePos();
|
||||
|
||||
// if bar is pressed
|
||||
if (mouse_x >= GetBarRect().left &&
|
||||
mouse_x <= GetBarRect().right &&
|
||||
mouse_y >= GetBarRect().top &&
|
||||
mouse_y <= GetBarRect().bottom)
|
||||
if (GetBarRect().PointInside(mouse))
|
||||
{
|
||||
m_BarPressed = true;
|
||||
m_BarPressedAtX = mouse_x;
|
||||
m_BarPressedAtY = mouse_y;
|
||||
m_BarPressedAtPos = mouse;
|
||||
m_PosWhenPressed = m_Pos;
|
||||
}
|
||||
else
|
||||
// if button-minus is pressed
|
||||
if (HoveringButtonMinus(mouse_x, mouse_y))
|
||||
if (m_ButtonMinusHovered)
|
||||
{
|
||||
m_ButtonMinusPressed = true;
|
||||
ScrollMinus();
|
||||
}
|
||||
else
|
||||
// if button-plus is pressed
|
||||
if (HoveringButtonPlus(mouse_x, mouse_y))
|
||||
if (m_ButtonPlusHovered)
|
||||
{
|
||||
m_ButtonPlusPressed = true;
|
||||
ScrollPlus();
|
||||
}
|
||||
}
|
||||
else
|
||||
// Pressing the background of the bar, to scroll
|
||||
// notice the if-sentence alone does not admit that,
|
||||
// it must be after the above if/elses
|
||||
{
|
||||
if (GetOuterRect().PointInside(mouse))
|
||||
{
|
||||
// Scroll plus or minus a lot, this might change, it doesn't
|
||||
// have to be fancy though.
|
||||
if (mouse.y < GetBarRect().top)
|
||||
ScrollMinusPlenty();
|
||||
else
|
||||
ScrollPlusPlenty();
|
||||
|
||||
// Simulate mouse movement to see if bar now is hovered
|
||||
HandleMessage(SGUIMessage(GUIM_MOUSE_MOTION));
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case GUIM_MOUSE_RELEASE_LEFT:
|
||||
m_ButtonMinusPressed = false;
|
||||
m_ButtonPlusPressed = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,13 +86,18 @@ struct SGUIScrollBarStyle
|
|||
CStr m_SpriteButtonTop;
|
||||
CStr m_SpriteButtonTopPressed;
|
||||
CStr m_SpriteButtonTopDisabled;
|
||||
CStr m_SpriteButtonTopOver;
|
||||
|
||||
CStr m_SpriteButtonBottom;
|
||||
CStr m_SpriteButtonBottomPressed;
|
||||
CStr m_SpriteButtonBottomDisabled;
|
||||
CStr m_SpriteButtonBottomOver;
|
||||
|
||||
CStr m_SpriteScrollBackHorizontal;
|
||||
CStr m_SpriteScrollBarHorizontal;
|
||||
CStr m_SpriteBarVertical;
|
||||
CStr m_SpriteBarVerticalOver;
|
||||
CStr m_SpriteBarVerticalPressed;
|
||||
|
||||
CStr m_SpriteBackVertical;
|
||||
|
||||
//@}
|
||||
//--------------------------------------------------------
|
||||
|
|
@ -108,8 +113,8 @@ struct SGUIScrollBarStyle
|
|||
CStr m_SpriteButtonRightPressed;
|
||||
CStr m_SpriteButtonRightDisabled;
|
||||
|
||||
CStr m_SpriteScrollBackVertical;
|
||||
CStr m_SpriteScrollBarVertical;
|
||||
CStr m_SpriteBackHorizontal;
|
||||
CStr m_SpriteBarHorizontal;
|
||||
|
||||
//@}
|
||||
};
|
||||
|
|
@ -151,12 +156,12 @@ public:
|
|||
* @return true if messages handled the scroll-bar some. False if
|
||||
* the message should be processed by the object.
|
||||
*/
|
||||
virtual bool HandleMessage(const SGUIMessage &Message)=0;
|
||||
virtual void HandleMessage(const SGUIMessage &Message)=0;
|
||||
|
||||
/**
|
||||
* Set m_Pos with mouse_x/y input, i.e. when draggin.
|
||||
*/
|
||||
virtual void SetPosFromMousePos(int _x, int _y)=0;
|
||||
virtual void SetPosFromMousePos(const CPos &mouse)=0;
|
||||
|
||||
/**
|
||||
* Hovering the scroll minus button
|
||||
|
|
@ -165,7 +170,7 @@ public:
|
|||
* @param m_y mouse y
|
||||
* @return True if mouse positions are hovering the button
|
||||
*/
|
||||
virtual bool HoveringButtonMinus(int m_x, int m_y) { return false; }
|
||||
virtual bool HoveringButtonMinus(const CPos &mouse) { return false; }
|
||||
|
||||
/**
|
||||
* Hovering the scroll plus button
|
||||
|
|
@ -174,17 +179,32 @@ public:
|
|||
* @param m_y mouse y
|
||||
* @return True if mouse positions are hovering the button
|
||||
*/
|
||||
virtual bool HoveringButtonPlus(int m_x, int m_y) { return false; }
|
||||
virtual bool HoveringButtonPlus(const CPos &mouse) { return false; }
|
||||
|
||||
/**
|
||||
* Get scroll-position
|
||||
*/
|
||||
int GetPos() const { return m_Pos; }
|
||||
|
||||
/**
|
||||
* Scroll towards 1.0 one step
|
||||
*/
|
||||
virtual void ScrollPlus() { m_Pos += 0.1f; UpdatePosBoundaries(); }
|
||||
virtual void ScrollPlus() { m_Pos += 30; UpdatePosBoundaries(); }
|
||||
|
||||
/**
|
||||
* Scroll towards 0.0 one step
|
||||
*/
|
||||
virtual void ScrollMinus() { m_Pos -= 0.1f; UpdatePosBoundaries(); }
|
||||
virtual void ScrollMinus() { m_Pos -= 30; UpdatePosBoundaries(); }
|
||||
|
||||
/**
|
||||
* Scroll towards 1.0 one step
|
||||
*/
|
||||
virtual void ScrollPlusPlenty() { m_Pos += 90; UpdatePosBoundaries(); }
|
||||
|
||||
/**
|
||||
* Scroll towards 0.0 one step
|
||||
*/
|
||||
virtual void ScrollMinusPlenty() { m_Pos -= 90; UpdatePosBoundaries(); }
|
||||
|
||||
/**
|
||||
* Set host object, must be done almost at creation of scroll bar.
|
||||
|
|
@ -192,6 +212,18 @@ public:
|
|||
*/
|
||||
void SetHostObject(IGUIScrollBarOwner * pOwner) { m_pHostObject = pOwner; }
|
||||
|
||||
/**
|
||||
* Get GUI pointer
|
||||
* @return CGUI pointer
|
||||
*/
|
||||
CGUI *GetGUI() const;
|
||||
|
||||
/**
|
||||
* Set GUI pointer
|
||||
* @param pGUI pointer to CGUI object.
|
||||
*/
|
||||
void SetGUI(CGUI *pGUI) { m_pGUI = pGUI; }
|
||||
|
||||
/**
|
||||
* Set Width
|
||||
* @param width Width
|
||||
|
|
@ -202,25 +234,37 @@ public:
|
|||
* Set X Position
|
||||
* @param x Position in this axis
|
||||
*/
|
||||
void SetX(const int &x) {m_X = x; }
|
||||
void SetX(const int &x) { m_X = x; }
|
||||
|
||||
/**
|
||||
* Set Y Position
|
||||
* @param y Position in this axis
|
||||
*/
|
||||
void SetY(const int &y) {m_Y = y; }
|
||||
void SetY(const int &y) { m_Y = y; }
|
||||
|
||||
/**
|
||||
* Set Z Position
|
||||
* @param z Position in this axis
|
||||
*/
|
||||
void SetZ(const float &z) {m_Z = z; }
|
||||
void SetZ(const float &z) { m_Z = z; }
|
||||
|
||||
/**
|
||||
* Set Length of scroll bar
|
||||
* @param length Length
|
||||
*/
|
||||
void SetLength(const float &length) {m_Length = length; }
|
||||
void SetLength(const int &length) { m_Length = length; }
|
||||
|
||||
/**
|
||||
* Set content length
|
||||
* @param range Maximum scrollable range
|
||||
*/
|
||||
void SetScrollRange(const int &range) { m_ScrollRange = max(range,1); SetupBarSize(); }
|
||||
|
||||
/**
|
||||
* Set space that is visible in the scrollable control.
|
||||
* @param space Visible area in the scrollable control.
|
||||
*/
|
||||
void SetScrollSpace(const int &space) { m_ScrollSpace = space; SetupBarSize(); }
|
||||
|
||||
/**
|
||||
* Set bar pressed
|
||||
|
|
@ -228,23 +272,42 @@ public:
|
|||
*/
|
||||
void SetBarPressed(const bool &b) { m_BarPressed = b; }
|
||||
|
||||
/**
|
||||
* Set use edge buttons
|
||||
* @param b True if edge buttons should be used
|
||||
*/
|
||||
void SetUseEdgeButtons(const bool &b) { m_UseEdgeButtons = b; }
|
||||
|
||||
/**
|
||||
* Set Scroll bar style string
|
||||
* @param style String with scroll bar style reference name
|
||||
*/
|
||||
void SetScrollBarStyle(const CStr &style) { m_ScrollBarStyle = style; }
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Get the rectangle of the actual BAR. not the whole scroll-bar.
|
||||
*/
|
||||
virtual CRect GetBarRect() const = 0;
|
||||
|
||||
/**
|
||||
* Get style used by the scrollbar
|
||||
* @return Scroll bar style struct.
|
||||
*/
|
||||
const SGUIScrollBarStyle & GetStyle() const;
|
||||
const SGUIScrollBarStyle * GetStyle() const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Sets up bar size
|
||||
*/
|
||||
void SetupBarSize();
|
||||
|
||||
/**
|
||||
* Get the rectangle of the actual BAR. not the whole scroll-bar.
|
||||
* @return Rectangle, CRect
|
||||
*/
|
||||
virtual CRect GetBarRect() const = 0;
|
||||
|
||||
/**
|
||||
* Get the rectangle of the outline of the scrollbar, every component of the
|
||||
* scroll-bar should be inside this area.
|
||||
* @return Rectangle, CRect
|
||||
*/
|
||||
virtual CRect GetOuterRect() const = 0;
|
||||
|
||||
/**
|
||||
* Call every time m_Pos has been updated.
|
||||
|
|
@ -258,10 +321,16 @@ protected:
|
|||
//--------------------------------------------------------
|
||||
//@{
|
||||
|
||||
/**
|
||||
* True if you want edge buttons, i.e. buttons that can be pressed in order
|
||||
* to scroll.
|
||||
*/
|
||||
bool m_UseEdgeButtons;
|
||||
|
||||
/**
|
||||
* Width of the scroll bar
|
||||
*/
|
||||
int16 m_Width;
|
||||
int m_Width;
|
||||
|
||||
/**
|
||||
* Absolute X Position
|
||||
|
|
@ -283,6 +352,16 @@ protected:
|
|||
*/
|
||||
int m_Length;
|
||||
|
||||
/**
|
||||
* Content that can be scrolled, in pixels
|
||||
*/
|
||||
int m_ScrollRange;
|
||||
|
||||
/**
|
||||
* Content that can be viewed at a time, in pixels
|
||||
*/
|
||||
int m_ScrollSpace;
|
||||
|
||||
/**
|
||||
* Use input from the scroll-wheel? True or false.
|
||||
*/
|
||||
|
|
@ -303,10 +382,15 @@ protected:
|
|||
*/
|
||||
IGUIScrollBarOwner *m_pHostObject;
|
||||
|
||||
/**
|
||||
* Reference to CGUI object, these cannot work stand-alone
|
||||
*/
|
||||
CGUI *m_pGUI;
|
||||
|
||||
/**
|
||||
* Mouse position when bar was pressed
|
||||
*/
|
||||
int m_BarPressedAtX, m_BarPressedAtY;
|
||||
CPos m_BarPressedAtPos;
|
||||
|
||||
//@}
|
||||
//--------------------------------------------------------
|
||||
|
|
@ -320,10 +404,26 @@ protected:
|
|||
bool m_BarPressed;
|
||||
|
||||
/**
|
||||
* Position of scroll bar, 0 means scrolled all the way to one side... 1 means
|
||||
* scrolled all the way to the other side.
|
||||
* Bar being hovered or not
|
||||
*/
|
||||
float m_Pos;
|
||||
bool m_BarHovered;
|
||||
|
||||
/**
|
||||
* Scroll buttons hovered
|
||||
*/
|
||||
bool m_ButtonMinusHovered, m_ButtonPlusHovered;
|
||||
|
||||
/**
|
||||
* Scroll buttons pressed
|
||||
*/
|
||||
bool m_ButtonMinusPressed, m_ButtonPlusPressed;
|
||||
|
||||
/**
|
||||
* Position of scroll bar, 0 means scrolled all the way to one side.
|
||||
* It is meassured in pixels, it is up to the host to make it actually
|
||||
* apply in pixels.
|
||||
*/
|
||||
int m_Pos;
|
||||
|
||||
/**
|
||||
* Position from 0.f to 1.f it had when the bar was pressed.
|
||||
|
|
|
|||
|
|
@ -40,24 +40,31 @@ void IGUIScrollBarOwner::ResetStates()
|
|||
void IGUIScrollBarOwner::AddScrollBar(IGUIScrollBar * scrollbar)
|
||||
{
|
||||
scrollbar->SetHostObject(this);
|
||||
scrollbar->SetGUI(GetGUI());
|
||||
m_ScrollBars.push_back(scrollbar);
|
||||
}
|
||||
|
||||
const SGUIScrollBarStyle & IGUIScrollBarOwner::GetScrollBarStyle(const CStr &style) const
|
||||
/*
|
||||
void SetGUI(CGUI * const &pGUI)
|
||||
{
|
||||
m_pGUI = pGUI;
|
||||
scrollbar->SetGUI(m_pGUI);
|
||||
}
|
||||
*/
|
||||
const SGUIScrollBarStyle * IGUIScrollBarOwner::GetScrollBarStyle(const CStr &style) const
|
||||
{
|
||||
if (!GetGUI())
|
||||
{
|
||||
// TODO Gee: Output in log
|
||||
return SGUIScrollBarStyle();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (GetGUI()->m_ScrollBarStyles.count(style) == 0)
|
||||
{
|
||||
// TODO Gee: Output in log
|
||||
return SGUIScrollBarStyle();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return GetGUI()->m_ScrollBarStyles.find(style)->second;
|
||||
return &GetGUI()->m_ScrollBarStyles.find(style)->second;
|
||||
}
|
||||
|
||||
void IGUIScrollBarOwner::HandleMessage(const SGUIMessage &Message)
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ struct SGUIScrollBarStyle;
|
|||
*/
|
||||
class IGUIScrollBarOwner : virtual public IGUIObject
|
||||
{
|
||||
friend class IGUIScrollBar;
|
||||
|
||||
public:
|
||||
IGUIScrollBarOwner();
|
||||
virtual ~IGUIScrollBarOwner();
|
||||
|
|
@ -65,7 +67,7 @@ public:
|
|||
/**
|
||||
* Interface for the m_ScrollBar to use.
|
||||
*/
|
||||
virtual const SGUIScrollBarStyle & GetScrollBarStyle(const CStr &style) const;
|
||||
virtual const SGUIScrollBarStyle *GetScrollBarStyle(const CStr &style) const;
|
||||
|
||||
/**
|
||||
* Add a scroll-bar
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
IGUISettingsObject
|
||||
by Gustav Larsson
|
||||
gee@pyro.nu
|
||||
*/
|
||||
|
||||
//#include "stdafx.h"
|
||||
#include "GUI.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
@ -1,146 +0,0 @@
|
|||
/*
|
||||
GUI Object Base - Setting Extension
|
||||
by Gustav Larsson
|
||||
gee@pyro.nu
|
||||
|
||||
--Overview--
|
||||
|
||||
Generic object that stores a struct with settings
|
||||
|
||||
--Usage--
|
||||
|
||||
If an object wants settings with a standard,
|
||||
it will use this as a middle step instead of being
|
||||
directly derived from IGUIObject
|
||||
|
||||
--Examples--
|
||||
|
||||
instead of:
|
||||
|
||||
class CButton : public IGUIObject
|
||||
|
||||
you go:
|
||||
|
||||
class CButton : public IGUISettingsObject<SButtonSettings>
|
||||
|
||||
and SButtonSettings will be included as m_Settings with
|
||||
all gets and sets set up
|
||||
|
||||
--More info--
|
||||
|
||||
Check GUI.h
|
||||
|
||||
*/
|
||||
|
||||
#ifndef IGUISettingsObject_H
|
||||
#define IGUISettingsObject_H
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Includes / Compiler directives
|
||||
//--------------------------------------------------------
|
||||
#include "GUI.h"
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Macros
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Types
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Error declarations
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Declarations
|
||||
//--------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @author Gustav Larsson
|
||||
*
|
||||
* Appends more settings to the IGUIObject.
|
||||
* Can be used with multiple inheritance.
|
||||
*
|
||||
* @see IGUIObject
|
||||
*/
|
||||
template <typename SETTINGS>
|
||||
class IGUISettingsObject : virtual public IGUIObject
|
||||
{
|
||||
public:
|
||||
IGUISettingsObject() {}
|
||||
virtual ~IGUISettingsObject() {}
|
||||
|
||||
/**
|
||||
* Get Offsets, <b>important</b> to include so it returns this
|
||||
* m_Offsets and not IGUIObject::m_SettingsInfo
|
||||
*
|
||||
* @return Settings infos
|
||||
*/
|
||||
virtual map_Settings GetSettingsInfo() const { return m_SettingsInfo; }
|
||||
|
||||
/**
|
||||
* @return Returns a copy of m_Settings
|
||||
*/
|
||||
SETTINGS GetSettings() const { return m_Settings; }
|
||||
|
||||
/// Sets settings
|
||||
void SetSettings(const SETTINGS &Set)
|
||||
{
|
||||
m_Settings = Set;
|
||||
|
||||
//CheckSettingsValidity();
|
||||
// Since that function out-commented above really
|
||||
// does just update the base settings, we'll call
|
||||
// the message immediately instead
|
||||
try
|
||||
{
|
||||
HandleMessage(GUIM_SETTINGS_UPDATED);
|
||||
}
|
||||
catch (...) { }
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* You input the setting struct you want, and it will return a pointer to
|
||||
* the struct.
|
||||
*
|
||||
* @param SettingsStruct tells us which pointer to return
|
||||
*/
|
||||
virtual void *GetStructPointer(const EGUISettingsStruct &SettingsStruct) const
|
||||
{
|
||||
switch (SettingsStruct)
|
||||
{
|
||||
case GUISS_BASE:
|
||||
return (void*)&m_BaseSettings;
|
||||
|
||||
case GUISS_EXTENDED:
|
||||
return (void*)&m_Settings;
|
||||
|
||||
default:
|
||||
// TODO Gee: Report error
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/// Settings struct
|
||||
SETTINGS m_Settings;
|
||||
|
||||
/**
|
||||
* <b>Offset database</b>\n
|
||||
* tells us where a variable by a string name is
|
||||
* located hardcoded, in order to acquire a pointer
|
||||
* for that variable... Say "frozen" gives
|
||||
* the offset from IGUIObject to m_Frozen.
|
||||
*
|
||||
* <b>note!</b> _NOT_ from SGUIBaseSettings to m_Frozen!
|
||||
*
|
||||
* Note that it's imperative that this m_SettingsInfo includes
|
||||
* all offsets of m_BaseSettings too, because when
|
||||
* using this class, this m_SettingsInfo will be the only
|
||||
* one used.
|
||||
*/
|
||||
static map_Settings m_SettingsInfo;
|
||||
};
|
||||
|
||||
#endif
|
||||
73
source/gui/IGUITextOwner.cpp
Executable file
73
source/gui/IGUITextOwner.cpp
Executable file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
IGUITextOwner
|
||||
by Gustav Larsson
|
||||
gee@pyro.nu
|
||||
*/
|
||||
|
||||
//#include "stdafx.h"
|
||||
#include "GUI.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Constructor / Destructor
|
||||
//-------------------------------------------------------------------
|
||||
IGUITextOwner::IGUITextOwner()
|
||||
{
|
||||
}
|
||||
|
||||
IGUITextOwner::~IGUITextOwner()
|
||||
{
|
||||
// Delete scroll-bars
|
||||
vector<SGUIText*>::iterator it;
|
||||
for (it=m_GeneratedTexts.begin(); it!=m_GeneratedTexts.end(); ++it)
|
||||
{
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
|
||||
void IGUITextOwner::AddText(SGUIText * text)
|
||||
{
|
||||
m_GeneratedTexts.push_back(text);
|
||||
}
|
||||
|
||||
void IGUITextOwner::HandleMessage(const SGUIMessage &Message)
|
||||
{
|
||||
switch (Message.type)
|
||||
{
|
||||
case GUIM_SETTINGS_UPDATED:
|
||||
// Everything that can change the visual appearance.
|
||||
// it is assumed that the text of the object will be dependent on
|
||||
// these. But that is not certain, but one will have to manually
|
||||
// change it and disregard this function.
|
||||
if (Message.value == CStr("size") || Message.value == CStr("z") ||
|
||||
Message.value == CStr("absolute") || Message.value == CStr("caption") ||
|
||||
Message.value == CStr("font") || Message.value == CStr("textcolor"))
|
||||
{
|
||||
SetupText();
|
||||
}
|
||||
break;
|
||||
|
||||
case GUIM_LOAD:
|
||||
SetupText();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void IGUITextOwner::Draw(const int &index, const CColor &color, const CPos &pos,
|
||||
const float &z, const CRect &clipping)
|
||||
{
|
||||
if (index < 0 && index >= m_GeneratedTexts.size())
|
||||
{
|
||||
// TODO Gee: Warning
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetGUI())
|
||||
{
|
||||
GetGUI()->DrawText(*m_GeneratedTexts[index], color, pos, z);
|
||||
}
|
||||
}
|
||||
88
source/gui/IGUITextOwner.h
Executable file
88
source/gui/IGUITextOwner.h
Executable file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
GUI Object Base - Text Owner
|
||||
by Gustav Larsson
|
||||
gee@pyro.nu
|
||||
|
||||
--Overview--
|
||||
|
||||
Interface class that enhance the IGUIObject with
|
||||
cached CGUIStrings. This class is not at all needed,
|
||||
and many controls that will use CGUIStrings might
|
||||
not use this, but does help for regular usage such
|
||||
as a text-box, a button, a radio button etc.
|
||||
|
||||
--More info--
|
||||
|
||||
Check GUI.h
|
||||
|
||||
*/
|
||||
|
||||
#ifndef IGUITextOwner_H
|
||||
#define IGUITextOwner_H
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Includes / Compiler directives
|
||||
//--------------------------------------------------------
|
||||
#include "GUI.h"
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Macros
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Types
|
||||
//--------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Declarations
|
||||
//--------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @author Gustav Larsson
|
||||
*
|
||||
* Framework for handling Output text.
|
||||
*
|
||||
* @see IGUIObject
|
||||
*/
|
||||
class IGUITextOwner : virtual public IGUIObject
|
||||
{
|
||||
public:
|
||||
IGUITextOwner();
|
||||
virtual ~IGUITextOwner();
|
||||
|
||||
/**
|
||||
* Adds a text object.
|
||||
*/
|
||||
void AddText(SGUIText * text);
|
||||
|
||||
/**
|
||||
* @see IGUIObject#HandleMessage()
|
||||
*/
|
||||
virtual void HandleMessage(const SGUIMessage &Message);
|
||||
|
||||
/**
|
||||
* Draws the Text.
|
||||
*
|
||||
* @param index Index value of text. Mostly this will be 0
|
||||
* @param pos Position
|
||||
* @param z Z value
|
||||
* @param clipping Clipping rectangle, don't even add a paramter
|
||||
* to get no clipping.
|
||||
*/
|
||||
virtual void Draw(const int &index, const CColor &color, const CPos &pos,
|
||||
const float &z, const CRect &clipping = CRect());
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Setup texts. Functions that sets up all texts when changes have been made.
|
||||
*/
|
||||
virtual void SetupText()=0;
|
||||
|
||||
/**
|
||||
* Texts that are generated and ready to be rendred.
|
||||
*/
|
||||
std::vector<SGUIText*> m_GeneratedTexts;
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Reference in a new issue