1
0
forked from 0ad/0ad

no message

This was SVN commit r77.
This commit is contained in:
Gee 2003-11-24 17:13:37 +00:00
parent eb2ddf4c50
commit 90bbd48a14
18 changed files with 326 additions and 78 deletions

View File

@ -1,13 +1,10 @@
<?xml version="1.0" encoding="iso-8859-1" standalone="no" ?>
<!DOCTYPE objects SYSTEM "file:///C:/objects.dtd">
<!DOCTYPE objects SYSTEM "objects.dtd">
<objects>
<object name="Button2" type="button" size1024="10 10 100 100" style="hello" z="10" />
<object name="Button3" type="button" size1024="120 120 220 220" style="hello" z="20">
<object name="Child" type="button" size1024="140 140 300 200" z="22">
<object name="ChildsChilds" type="button" size1024="200 150 400 190" z="24"> </object>
</object>
<object name="Child" type="button" size="100%-50 100%-50 100%-5 100%-5" z="22">
</object>
</objects>

View File

@ -18,7 +18,7 @@
<!ATTLIST object disabled (true|false) #IMPLIED>
<!ATTLIST object ghost (true|false) #IMPLIED>
<!ATTLIST object hidden (true|false) #IMPLIED>
<!ATTLIST object size1024 CDATA #IMPLIED>
<!ATTLIST object size CDATA #IMPLIED>
<!ATTLIST object style CDATA #IMPLIED>
<!ATTLIST object z CDATA #IMPLIED>

View File

@ -117,10 +117,10 @@ void CButton::Draw()
if (m_Pressed)
glColor3f(0.7f, 0.f, 0.f);
else
glColor3f(0,1,(float)m_BaseSettings.m_Size.right/300.f);
glColor3f(0,1,(float)m_BaseSettings.m_Size.pixel.right/300.f);
}
else
glColor3f((float)m_BaseSettings.m_Size.right/300.f,0,1);
glColor3f((float)m_BaseSettings.m_Size.pixel.right/300.f,0,1);
////////// Gee: janwas, this is just temp to see it
glDisable(GL_TEXTURE_2D);
@ -133,11 +133,19 @@ void CButton::Draw()
// Do this
glBegin(GL_QUADS);
//glBegin(GL_TRIANGLES);
glVertex2i(GetBaseSettings().m_Size.right, GetBaseSettings().m_Size.bottom);
//CRect ca = GetBaseSettings().m_Size.GetClientArea(CRect(0, 0, g_xres, g_yres));
CRect ca = m_CachedActualSize;
glVertex2i(ca.right, ca.bottom);
glVertex2i(ca.left, ca.bottom);
glVertex2i(ca.left, ca.top);
glVertex2i(ca.right, ca.top);
/* glVertex2i(GetBaseSettings().m_Size.right, GetBaseSettings().m_Size.bottom);
glVertex2i(GetBaseSettings().m_Size.left, GetBaseSettings().m_Size.bottom);
glVertex2i(GetBaseSettings().m_Size.left, GetBaseSettings().m_Size.top);
glVertex2i(GetBaseSettings().m_Size.right, GetBaseSettings().m_Size.top);
/*
*//*
glVertex2i(GetBaseSettings().m_Size.right, GetBaseSettings().m_Size.bottom);
glVertex2i(GetBaseSettings().m_Size.left, GetBaseSettings().m_Size.bottom);
glVertex2i(GetBaseSettings().m_Size.left, GetBaseSettings().m_Size.top);

View File

@ -239,6 +239,11 @@ void CGUI::Destroy()
m_Sprites.clear();
}
void CGUI::UpdateResolution()
{
GUI<>::RecurseObject(0, m_BaseObject, &IGUIObject::UpdateCachedSize );
}
void CGUI::AddObject(IGUIObject* pObject)
{
/* try

View File

@ -128,6 +128,17 @@ public:
*/
void AddObjectType(const CStr &str, ConstructObjectFunction pFunc) { m_ObjectTypes[str] = pFunc; }
/**
* Update Resolution, should be called every time the resolution
* of the opengl screen has been changed, this is becuase it needs
* to re-cache all its actual sizes
*
* Needs no input since screen resolution is global.
*
* @see IGUIObject#UpdateCachedSize()
*/
void UpdateResolution();
private:
/**
* Updates the object pointers, needs to be called each

View File

@ -56,6 +56,7 @@ gee@pyro.nu
//--------------------------------------------------------
#include <map>
#include <string>
#include <vector>
#include <stddef.h>
//// janwas: these are very sloppy added, I don't know the etiquette

View File

@ -97,7 +97,7 @@ enum
// Typedefs
typedef std::map<CStr, IGUIObject*> map_pObjects;
typedef std::vector<IGUIObject*> vector_pObjects;
//--------------------------------------------------------
// Error declarations

View File

@ -6,9 +6,149 @@ gee@pyro.nu
//#include "stdafx.h"
#include "GUI.h"
#include "../ps/Parser.h"
using namespace std;
//--------------------------------------------------------
// Help Classes/Structs for the GUI implementation
//--------------------------------------------------------
CClientArea::CClientArea() : pixel(0,0,0,0), percent(0,0,0,0)
{
}
CClientArea::CClientArea(const CStr &Value)
{
SetClientArea(Value);
}
CRect CClientArea::GetClientArea(const CRect &parent)
{
CRect client;
// This should probably be cached and not calculated all the time for every object.
client.left = int(float(parent.left) + float(parent.right-parent.left)*float(percent.left))/100.f + pixel.left;
client.top = int(float(parent.top) + float(parent.bottom-parent.top)*float(percent.top))/100.f + pixel.top;
client.right = int(float(parent.left) + float(parent.right-parent.left)*float(percent.right))/100.f + pixel.right;
client.bottom = int(float(parent.top) + float(parent.bottom-parent.top)*float(percent.bottom))/100.f + pixel.bottom;
return client;
}
bool CClientArea::SetClientArea(const CStr &Value)
{
// Get value in STL string format
string _Value = (const TCHAR*)Value;
// This might lack incredible speed, but since all XML files
// are read at startup, reading 100 client areas will be
// negligible in the loading time.
// Setup parser to parse the value
CParser parser;
// One of the for values:
// will give outputs like (in argument):
// (200) <== no percent, just the first $value
// (200) (percent) <== just the percent
// (200) (percent) (100) <== percent PLUS pixel
// (200) (percent) (-100) <== percent MINUS pixel
// (200) (percent) (100) (-100) <== Both PLUS and MINUS are used, INVALID
string one_value = "_$value[$arg(percent)%_[+_$value]_[-_$arg(_minus)$value]_]";
string four_values = one_value + "$arg(delim)" +
one_value + "$arg(delim)" +
one_value + "$arg(delim)" +
one_value + "$arg(delim)_"; // it's easier to just end with another delimiter
parser.InputTaskType("ClientArea", four_values);
CParserLine line;
line.ParseString(parser, _Value);
if (!line.m_ParseOK)
return false;
int arg_count[4]; // argument counts for the four values
int arg_start[4] = {0,0,0,0}; // location of first argument, [0] is alwasy 0
// Divide into the four piles (delimiter is an argument named "delim")
for (int i=0, valuenr=0; i<line.GetArgCount(); ++i)
{
string str;
line.GetArgString(i, str);
if (str == "delim")
{
if (valuenr==0)
{
arg_count[0] = i;
arg_start[1] = i+1;
}
else
{
if (valuenr!=3)
{
arg_start[valuenr+1] = i+1;
arg_count[valuenr] = arg_start[valuenr+1] - arg_start[valuenr] - 1;
}
else
arg_count[3] = line.GetArgCount() - arg_start[valuenr] - 1;
}
++valuenr;
}
}
// Iterate argument
// This is the scheme:
// 1 argument = Just pixel value
// 2 arguments = Just percent value
// 3 arguments = percent and pixel
// 4 arguments = INVALID
// Default to 0
int values[4][2] = {{0,0},{0,0},{0,0},{0,0}};
for (int v=0; v<4; ++v)
{
if (arg_count[v] == 1)
{
string str;
line.GetArgString(arg_start[v], str);
if (!line.GetArgInt(arg_start[v], values[v][1]))
return false;
}
else
if (arg_count[v] == 2)
{
if (!line.GetArgInt(arg_start[v], values[v][0]))
return false;
}
else
if (arg_count[v] == 3)
{
if (!line.GetArgInt(arg_start[v], values[v][0]) ||
!line.GetArgInt(arg_start[v]+2, values[v][1]))
return false;
}
else return false;
}
// Now store the values[][] in the right place
pixel.left = values[0][1];
pixel.top = values[1][1];
pixel.right = values[2][1];
pixel.bottom = values[3][1];
percent.left = values[0][0];
percent.top = values[1][0];
percent.right = values[2][0];
percent.bottom = values[3][0];
return true;
}
//--------------------------------------------------------
// Utilities implementation
//--------------------------------------------------------

View File

@ -23,6 +23,84 @@ gee@pyro.nu
//--------------------------------------------------------
#include "GUI.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);
}
bool operator !=(const CRect &rect) const
{
return !(*this==rect);
}
};
/**
* @author Gustav Larsson
*
* Client Area is a rectangle relative to a parent rectangle
*
* You can input the whole value of the Client Area by
* string. Like used in the GUI.
*/
struct CClientArea
{
public:
CClientArea();
CClientArea(const CStr &Value);
/// Pixel modifiers
CRect pixel;
/// Percent modifiers (I'll let this be integers, I don't think a greater precision is needed)
CRect percent;
/**
* Get client area rectangle when the parent is given
*/
CRect GetClientArea(const CRect &parent);
/**
* The ClientArea can be set from a string looking like:
*
* @code
* "0 0 100% 100%"
* "50%-10 50%-10 50%+10 50%+10" @endcode
*
* i.e. First percent modifier, then + or - and the pixel modifier.
* Although you can use just the percent or the pixel modifier. Notice
* though that the percent modifier must always be the first when
* both modifiers are inputted.
*
* @return true if success, false if failure. If false then the client area
* will be unchanged.
*/
bool SetClientArea(const CStr &Value);
};
// TEMP
struct CColor
{
float r, g, b, a;
};
//--------------------------------------------------------
// Forward declarations
//--------------------------------------------------------
@ -154,6 +232,8 @@ public:
// one with the friend relationship
IGUIObject *pObject = GetObjectPointer(GUIinstance, Object);
pObject->CheckSettingsValidity();
return SetSetting(pObject, Setting, Value);
}

View File

@ -124,12 +124,9 @@ void IGUIObject::Destroy()
void IGUIObject::SetupBaseSettingsInfo(map_Settings &SettingsInfo)
{
SettingsInfo["hejsan"].m_Offset = 0;
_GUI_ADD_OFFSET("bool", "enabled", m_Enabled)
_GUI_ADD_OFFSET("bool", "hidden", m_Hidden)
_GUI_ADD_OFFSET("rect", "size1024", m_Size)
_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)
@ -143,10 +140,14 @@ bool IGUIObject::MouseOver()
u16 mouse_x = GetMouseX(),
mouse_y = GetMouseY();
return (mouse_x >= m_BaseSettings.m_Size.left &&
mouse_x <= m_BaseSettings.m_Size.right &&
mouse_y >= m_BaseSettings.m_Size.bottom &&
mouse_y <= m_BaseSettings.m_Size.top);
//CRect ca = m_BaseSettings.m_Size.GetClientArea(CRect(0,0,g_xres,g_yres));
CRect ca = m_CachedActualSize;
return (mouse_x >= ca.left &&
mouse_x <= ca.right &&
mouse_y >= ca.top &&
mouse_y <= ca.bottom);
}
u16 IGUIObject::GetMouseX() const
@ -217,9 +218,6 @@ void IGUIObject::SetSetting(const CStr &Setting, const CStr &Value)
else
if (set.m_Type == CStr(_T("rect")))
{
// TEMP
//GUI<CRect>::SetSetting(this, Setting, CRect(100,100,200,200));
// Use the parser to parse the values
CParser parser;
parser.InputTaskType("", "_$value_$value_$value_$value_");
@ -249,6 +247,21 @@ void IGUIObject::SetSetting(const CStr &Setting, const CStr &Value)
GUI<CRect>::SetSetting(this, Setting, rect);
}
else
if (set.m_Type == CStr(_T("client area")))
{
// Get Client Area
CClientArea ca;
if (!ca.SetClientArea(Value))
{
// GeeTODO REPORT
}
// Check if valid!
GUI<CClientArea>::SetSetting(this, Setting, ca);
}
else
{
throw PS_FAIL;
}
@ -287,9 +300,17 @@ IGUIObject *IGUIObject::GetParent()
return m_pParent;
}
void IGUIObject::UpdateCachedSize()
{
m_CachedActualSize = m_BaseSettings.m_Size.GetClientArea( CRect(0, 0, g_xres, g_yres) );
}
// GeeTODO keep this function and all???
void IGUIObject::CheckSettingsValidity()
{
// Size might have been change, update cached size
UpdateCachedSize();
// If we hide an object, reset many of its parts
if (GetBaseSettings().m_Hidden)
{

View File

@ -48,7 +48,6 @@ class CGUI;
// Map with pointers
typedef std::map<CStr, SGUISetting> map_Settings;
typedef std::vector<IGUIObject*> vector_pObjects;
//--------------------------------------------------------
// Error declarations
@ -58,36 +57,6 @@ typedef std::vector<IGUIObject*> vector_pObjects;
// Declarations
//--------------------------------------------------------
// TEMP
struct CRect
{
CRect() {}
CRect(int _l, int _b, int _r, int _t) :
top(_t),
bottom(_b),
right(_r),
left(_l) {}
int bottom, top, left, right;
bool operator ==(const CRect &rect) const
{
return (bottom==rect.bottom) &&
(top==rect.top) &&
(left==rect.left) &&
(right==rect.right);
}
bool operator !=(const CRect &rect) const
{
return !(*this==rect);
}
};
// TEMP
struct CColor
{
float r, g, b, a;
};
// Text alignments
enum EAlign { EAlign_Left, EAlign_Right, EAlign_Center };
@ -117,7 +86,8 @@ struct SGUIBaseSettings
bool m_Hidden;
bool m_Enabled;
bool m_Absolute;
CRect m_Size;
// CRect m_Size2;
CClientArea m_Size;
CStr m_Style;
float m_Z;
CStr m_Caption; // Is usually set within an XML element and not in the attributes
@ -134,7 +104,7 @@ struct SGUIBaseSettings
class IGUIObject
{
friend class CGUI;
friend class GUI;
template <class T> friend class GUI;
public:
IGUIObject();
@ -229,6 +199,13 @@ public:
*/
bool SettingExists(const CStr &Setting) const;
/**
* All sizes are relative to resolution, and the calculation
* is not wanted in real time, therefore it is cached, update
* the cached size with this function.
*/
void UpdateCachedSize();
/**
* Should be called every time the settings has been updated
* will also send a message GUIM_SETTINGS_UPDATED, so that
@ -321,6 +298,14 @@ protected:
u16 GetMouseX() const;
u16 GetMouseY() const;
/**
* Cached size, real size m_Size is actually dependent on resolution
* and can have different *real* outcomes, this is the real outcome
* cached to avoid slow calculations in real time.
*/
CRect m_CachedActualSize;
//@}
private:
//--------------------------------------------------------
@ -379,7 +364,7 @@ protected:
* located hardcoded, in order to acquire a pointer
* for that variable... Say "frozen" gives
* the offset from IGUIObject to m_Frozen.
* <b>note!</b> <u>NOT</u> from SGUIBaseSettings to
* <b>note!</b> @uNOT from SGUIBaseSettings to
* m_Frozen!
*/
static map_Settings m_SettingsInfo;