1
0
forked from 0ad/0ad

Major fixes and updates. Let me know if I screwed up resolving conflicts.

This was SVN commit r1085.
This commit is contained in:
Gee 2004-08-31 02:09:58 +00:00
parent 3b91514dbe
commit 924b0bf1b4
16 changed files with 402 additions and 237 deletions

View File

@ -46,12 +46,13 @@ void CButton::SetupText()
CStr font;
if (GUI<CStr>::GetSetting(this, "font", font) != PS_OK || font.Length()==0)
// Use the default if none is specified
// TODO Gee: (2004-08-14) Default should not be hard-coded, but be in styles!
font = "default";
CGUIString caption;
GUI<CGUIString>::GetSetting(this, "caption", caption);
*m_GeneratedTexts[0] = GetGUI()->GenerateText(caption, font, m_CachedActualSize.GetWidth(), 0);
*m_GeneratedTexts[0] = GetGUI()->GenerateText(caption, font, m_CachedActualSize.GetWidth(), 0, this);
// Set position of text
//m_TextPos = m_CachedActualSize.CenterPoint() - m_GeneratedTexts[0]->m_Size/2;

View File

@ -69,6 +69,7 @@ void CCheckBox::SetupText()
//GUI<CGUIString>::GetSetting(this, "square-side", square_side);
// TODO Gee: Establish buffer zones
// TODO Gee: research if even "default" should be hardcoded.
*m_GeneratedTexts[0] = GetGUI()->GenerateText(caption, CStr("default"), m_CachedActualSize.GetWidth()-20, 0);
// Set position of text

View File

@ -383,8 +383,8 @@ void CGUI::DrawSprite(const CStr& SpriteName,
// Fetch real sprite from name
if (m_Sprites.count(SpriteName) == 0)
{
debug_warn("CGUI::DrawSprite error");
// TODO Gee: Report error
LOG(ERROR, LOG_CATEGORY, "Trying to use a sprite that doesn't exist (\"%s\").", SpriteName.c_str());
// TODO Gee: (2004-08-31) This will be called continuously when it happens.
return;
}
else Sprite = m_Sprites[SpriteName];
@ -483,6 +483,7 @@ void CGUI::Destroy()
// Clear all
m_pAllObjects.clear();
m_Sprites.clear();
m_Icons.clear();
}
void CGUI::UpdateResolution()
@ -587,8 +588,9 @@ struct SGenerateTextImage
}
};
SGUIText CGUI::GenerateText(const CGUIString &string, /*const CColor &Color, */
const CStr& Font, const int &Width, const int &BufferZone)
SGUIText CGUI::GenerateText(const CGUIString &string,
const CStr& Font, const int &Width, const int &BufferZone,
const IGUIObject *pObject)
{
SGUIText Text; // object we're generating
@ -607,6 +609,8 @@ SGUIText CGUI::GenerateText(const CGUIString &string, /*const CColor &Color, */
// Easier to read.
bool WordWrapping = (Width != 0);
size_t TEMP = string.m_Words.size();
// Go through string word by word
for (int i=0; i<(int)string.m_Words.size()-1 && !done; ++i)
{
@ -620,7 +624,7 @@ SGUIText CGUI::GenerateText(const CGUIString &string, /*const CColor &Color, */
int prelim_line_height=0;
// Width and height of all text calls generated.
string.GenerateTextCall(Feedback, Font, /*CColor(),*/
string.GenerateTextCall(Feedback, Font,
string.m_Words[i], string.m_Words[i+1]);
// Loop through our images queues, to see if images has been added.
@ -632,8 +636,11 @@ SGUIText CGUI::GenerateText(const CGUIString &string, /*const CColor &Color, */
// Loop left/right
for (int j=0; j<2; ++j)
{
// TEMP
int TEMPsize = Feedback.m_Images[j].size();
for (vector<CStr>::const_iterator it = Feedback.m_Images[j].begin();
it != Feedback.m_Images[j].end();
it != Feedback.m_Images[j].end();
++it)
{
SGUIText::SSpriteCall SpriteCall;
@ -647,9 +654,11 @@ SGUIText CGUI::GenerateText(const CGUIString &string, /*const CColor &Color, */
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);
// Get Size from Icon database
SGUIIcon icon = GetIcon(*it);
CSize size = icon.m_Size;
Image.SetupSpriteCall((j==CGUIString::SFeedback::Left), SpriteCall, Width, _y, size, icon.m_TextureName, BufferZone);
// Check if image is the lowest thing.
Text.m_Size.cy = max(Text.m_Size.cy, Image.m_YTo);
@ -668,7 +677,7 @@ SGUIText CGUI::GenerateText(const CGUIString &string, /*const CColor &Color, */
// If Width is 0, then there's no word-wrapping, disable NewLine.
if ((WordWrapping && (x > Width-BufferZone || Feedback.m_NewLine)) || i == (int)string.m_Words.size()-2)
{
// Change from to i, but first keep a copy of its value.
// Change 'from' to 'i', but first keep a copy of its value.
int temp_from = from;
from = i;
@ -678,7 +687,7 @@ SGUIText CGUI::GenerateText(const CGUIString &string, /*const CColor &Color, */
width_range[From] = BufferZone;
width_range[To] = Width - BufferZone;
// Floating images are only appicable if word-wrapping is enabled.
// Floating images are only applicable if word-wrapping is enabled.
if (WordWrapping)
{
// Decide width of the line. We need to iterate our floating images.
@ -730,7 +739,10 @@ SGUIText CGUI::GenerateText(const CGUIString &string, /*const CColor &Color, */
// another.
CGUIString::SFeedback Feedback2;
string.GenerateTextCall(Feedback2, Font, /*CColor(),*/
// Don't attach object, it'll suppress the errors
// we want them to be reported in the final GenerateTextCall()
// so that we don't get duplicates.
string.GenerateTextCall(Feedback2, Font,
string.m_Words[j], string.m_Words[j+1]);
// Append X value.
@ -755,12 +767,13 @@ SGUIText CGUI::GenerateText(const CGUIString &string, /*const CColor &Color, */
for (int j=temp_from; j<=i; ++j)
{
// We don't want to use Feedback now, so we'll have to use
// another.
// another one.
CGUIString::SFeedback Feedback2;
// Defaults
string.GenerateTextCall(Feedback2, Font, /*Color, */
string.m_Words[j], string.m_Words[j+1]);
string.GenerateTextCall(Feedback2, Font,
string.m_Words[j], string.m_Words[j+1],
pObject);
// Iterate all and set X/Y values
// Since X values are not set, we need to make an internal
@ -777,8 +790,7 @@ SGUIText CGUI::GenerateText(const CGUIString &string, /*const CColor &Color, */
if (it->m_pSpriteCall)
{
it->m_pSpriteCall->m_Area =
it->m_pSpriteCall->m_Area + it->m_Pos;
it->m_pSpriteCall->m_Area += it->m_Pos - CSize(0,it->m_pSpriteCall->m_Area.GetHeight());
}
}
@ -787,14 +799,18 @@ SGUIText CGUI::GenerateText(const CGUIString &string, /*const CColor &Color, */
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
// The first word overrides the width limit, what we
// do, in those cases, are just drawing that word even
// though it'll extend the object.
if (WordWrapping) // only if word-wrapping is applicable
{
if (Feedback2.m_NewLine)
{
from = j+1;
// Sprite call can exist within only a newline segment,
// therefore we need this.
Text.m_SpriteCalls.insert(Text.m_SpriteCalls.end(), Feedback2.m_SpriteCalls.begin(), Feedback2.m_SpriteCalls.end());
break;
}
else
@ -818,7 +834,7 @@ SGUIText CGUI::GenerateText(const CGUIString &string, /*const CColor &Color, */
if (j == (int)string.m_Words.size()-2)
done = true;
}
// Reset X
x = 0;
@ -855,6 +871,7 @@ void CGUI::DrawText(const SGUIText &Text, const CColor &DefaultColor,
it != Text.m_TextCalls.end();
++it)
{
// If this is just a placeholder for a sprite call, continue
if (it->m_pSpriteCall)
continue;
@ -881,7 +898,7 @@ void CGUI::DrawText(const SGUIText &Text, const CColor &DefaultColor,
delete font;
for (vector<SGUIText::SSpriteCall>::const_iterator it=Text.m_SpriteCalls.begin();
for (list<SGUIText::SSpriteCall>::const_iterator it=Text.m_SpriteCalls.begin();
it!=Text.m_SpriteCalls.end();
++it)
{
@ -889,8 +906,16 @@ void CGUI::DrawText(const SGUIText &Text, const CColor &DefaultColor,
}
}
void CGUI::ReportParseError(const CStr& str)
void CGUI::ReportParseError(const char *str, ...)
{
va_list argp;
char buffer[512];
memset(buffer,0,sizeof(buffer));
va_start(argp, str);
vsnprintf2(buffer, sizeof(buffer), str, argp);
va_end(argp);
// Print header
if (m_Errors==0)
{
@ -900,7 +925,7 @@ void CGUI::ReportParseError(const CStr& str)
// Important, set ParseError to true
++m_Errors;
LOG(ERROR, LOG_CATEGORY, str);
LOG(ERROR, LOG_CATEGORY, buffer);
}
/**
@ -1038,6 +1063,11 @@ void CGUI::Xeromyces_ReadRootSetup(XMBElement Element, CXeromyces* pFile)
{
Xeromyces_ReadScrollBarStyle(child, pFile);
}
else
if (name == "icon")
{
Xeromyces_ReadIcon(child, pFile);
}
// No need for else, we're using DTD.
}
}
@ -1064,8 +1094,6 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec
{
// Report error that object was unsuccessfully loaded
ReportParseError(CStr("Unrecognized type: ") + CStr(type));
delete object;
return;
}
@ -1101,8 +1129,7 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec
// additional check
if (m_Styles.count(argStyle) == 0)
{
debug_warn("CGUI::Xeromyces_ReadObject error");
// TODO Gee: Error
ReportParseError("Trying to use style '%s' that doesn't exist.", argStyle.c_str());
}
else object->LoadStyle(*this, argStyle);
}
@ -1411,6 +1438,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite
// Image object we're adding
SGUIImage image;
// TODO Gee: (2004-08-30) This is not how to set defaults.
CStr DefaultTextureSize = "0 0 100% 100%";
image.m_TextureSize = CClientArea(DefaultTextureSize);
@ -1438,6 +1466,8 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite
Handle tex = tex_load(TexFilename.c_str());
if (tex <= 0)
{
// Don't use ReportParseError, because this is not a *parsing* error
// and has ultimately nothing to do with the actual sprite we're reading.
LOG(ERROR, LOG_CATEGORY, "Error opening texture '%s': %lld", TexFilename.c_str(), tex);
}
else
@ -1453,8 +1483,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite
CClientArea ca;
if (!GUI<CClientArea>::ParseString(attr_value, ca))
{
debug_warn("CGUI::Xeromyces_ReadImage error");
// TODO Gee: Error
ReportParseError("Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str());
}
else image.m_Size = ca;
}
@ -1464,8 +1493,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite
CClientArea ca;
if (!GUI<CClientArea>::ParseString(attr_value, ca))
{
debug_warn("CGUI::Xeromyces_ReadImage error");
// TODO Gee: Error
ReportParseError("Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str());
}
else image.m_TextureSize = ca;
}
@ -1475,8 +1503,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite
int z_level;
if (!GUI<int>::ParseString(attr_value, z_level))
{
debug_warn("CGUI::Xeromyces_ReadImage error");
// TODO Gee: Error
ReportParseError("Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str());
}
else image.m_DeltaZ = (float)z_level/100.f;
}
@ -1486,18 +1513,11 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite
CColor color;
if (!GUI<CColor>::ParseString(attr_value, color))
{
debug_warn("CGUI::Xeromyces_ReadImage error");
// TODO Gee: Error
ReportParseError("Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str());
}
else image.m_BackColor = color;
}
else
{
debug_warn("CGUI::Xeromyces_ReadImage error");
// TODO Gee: Log
//g_console.submit("echo Error attribute " + attr_name + " is not expected in <image>");
return;
}
// We don't need no else when we're using DTDs.
}
//
@ -1569,7 +1589,7 @@ void CGUI::Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile)
int i;
if (!GUI<int>::ParseString(attr_value, i))
{
// TODO Gee: Report in log file
ReportParseError("Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str());
}
scrollbar.m_Width = i;
}
@ -1579,7 +1599,7 @@ void CGUI::Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile)
int i;
if (!GUI<int>::ParseString(attr_value, i))
{
// TODO Gee: Report in log file
ReportParseError("Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str());
}
scrollbar.m_MinimumBarSize = i;
}
@ -1619,33 +1639,6 @@ void CGUI::Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile)
else
if (attr_name == "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;
*/
}
//
@ -1654,3 +1647,39 @@ void CGUI::Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile)
m_ScrollBarStyles[name] = scrollbar;
}
void CGUI::Xeromyces_ReadIcon(XMBElement Element, CXeromyces* pFile)
{
// Icon we're adding
SGUIIcon icon;
CStr name;
XMBAttributeList attributes = Element.getAttributes();
for (int i=0; i<attributes.Count; ++i)
{
XMBAttribute attr = attributes.item(i);
std::string attr_name = pFile->getAttributeString(attr.Name);
CStr attr_value (attr.Value);
if (attr_value == CStr("null"))
continue;
if (attr_name == "name")
name = attr_value;
else
if (attr_name == "texture")
icon.m_TextureName = attr_value;
else
if (attr_name == "size")
{
CSize size;
if (!GUI<CSize>::ParseString(attr_value, size))
{
ReportParseError("Error parsing '%s' (\"%s\") when reading and <icon>.", attr_name.c_str(), attr_value.c_str());
}
icon.m_Size = size;
}
}
m_Icons[name] = icon;
}

View File

@ -204,14 +204,18 @@ public:
* 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.
*
* pObject is *only* if error parsing fails, and we need to be able to output
* which object the error occured in to aid the user. The parameter is completely
* optional.
*/
SGUIText GenerateText(const CGUIString &Text, /*const CColor &Color, */
const CStr& Font, const int &Width, const int &BufferZone);
SGUIText GenerateText(const CGUIString &Text,
const CStr& Font, const int &Width, const int &BufferZone,
const IGUIObject *pObject=NULL);
/**
* Returns the JSObject* associated with the GUI
@ -220,6 +224,16 @@ public:
*/
void* GetScriptObject() { return m_ScriptObject; }
/**
* Check if an icon exists
*/
bool IconExists(const CStr &str) const { return (m_Icons.count(str) != 0); }
/**
* Get Icon (a copy, can never be changed)
*/
SGUIIcon GetIcon(const CStr &str) const { return m_Icons.find(str)->second; }
private:
/**
* Updates the object pointers, needs to be called each
@ -249,7 +263,7 @@ private:
*
* @param str Error message
*/
void ReportParseError(const CStr& str);
void ReportParseError(const char *str, ...);
/**
* You input the name of the object type, and let's
@ -274,41 +288,38 @@ private:
/**
Xeromyces_* functions tree
<code>
\<objects\> (ReadRootObjects)
<objects> (ReadRootObjects)
|
+-\<script\> (ReadScript)
+-<script> (ReadScript)
|
+-\<object\> (ReadObject)
+-<object> (ReadObject)
|
+-\<action\>
+-<action>
|
+-Optional Type Extensions (IGUIObject::ReadExtendedElement) TODO
|
+-«object» *recursive*
\<styles\> (ReadRootStyles)
<styles> (ReadRootStyles)
|
+-\<style\> (ReadStyle)
+-<style> (ReadStyle)
\<sprites\> (ReadRootSprites)
<sprites> (ReadRootSprites)
|
+-\<sprite\> (ReadSprite)
+-<sprite> (ReadSprite)
|
+-\<image\> (ReadImage)
+-<image> (ReadImage)
\<setup>\ (ReadRootSetup)
<setup> (ReadRootSetup)
|
+-\<tooltip>\ (ReadToolTip)
+-<tooltip> (ReadToolTip)
|
+-\<scrollbar>\ (ReadScrollBar)
+-<scrollbar> (ReadScrollBar)
|
+-\<icon>\ (ReadIcon)
</code>
+-<icon> (ReadIcon)
*/
//@{
@ -337,7 +348,7 @@ private:
void Xeromyces_ReadRootSprites(XMBElement Element, CXeromyces* pFile);
/**
* Reads in the root element \<styles\> (the DOMElement).
* Reads in the root element <styles> (the DOMElement).
*
* @param Element The Xeromyces object that represents
* the styles-tag.
@ -363,15 +374,15 @@ private:
/**
* Notice! Recursive function!
*
* Read in an \<object\> (the DOMElement) and stores it
* Read in an <object> (the XMBElement) and stores it
* as a child in the pParent.
*
* It will also check the object's children and call this function
* on them too. Also it will call all other functions that reads
* in other stuff that can be found within an object. Such as a
* \<action\> will call Xerces_ReadAction (TODO, real funcion?).
* in other stuff that can be found within an object. Check the
* tree in the beginning of this class' Xeromyces_* section.
*
* Reads in the root element \<sprites\> (the DOMElement).
* Reads in the root element <sprites> (the DOMElement).
*
* @param Element The Xeromyces object that represents
* the object-tag.
@ -383,7 +394,7 @@ private:
void Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObject *pParent);
/**
* Reads in the element \<script\> (the DOMElement) and executes
* Reads in the element <script> (the XMBElement) and executes
* the script's code.
*
* @param Element The Xeromyces object that represents
@ -395,7 +406,7 @@ private:
void Xeromyces_ReadScript(XMBElement Element, CXeromyces* pFile);
/**
* Reads in the element \<sprite\> (the DOMElement) and stores the
* Reads in the element <sprite> (the XMBElement) and stores the
* result in a new CGUISprite.
*
* @param Element The Xeromyces object that represents
@ -407,7 +418,7 @@ private:
void Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile);
/**
* Reads in the element \<image\> (the DOMElement) and stores the
* Reads in the element <image> (the XMBElement) and stores the
* result within the CGUISprite.
*
* @param Element The Xeromyces object that represents
@ -420,7 +431,7 @@ private:
void Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite &parent);
/**
* Reads in the element \<style\> (the DOMElement) and stores the
* Reads in the element <style> (the XMBElement) and stores the
* result in m_Styles.
*
* @param Element The Xeromyces object that represents
@ -432,7 +443,7 @@ private:
void Xeromyces_ReadStyle(XMBElement Element, CXeromyces* pFile);
/**
* Reads in the element \<scrollbar\> (the DOMElement) and stores the
* Reads in the element <scrollbar> (the XMBElement) and stores the
* result in m_ScrollBarStyles.
*
* @param Element The Xeromyces object that represents
@ -443,6 +454,18 @@ private:
*/
void Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile);
/**
* Reads in the element <icon> (the XMBElement) and stores the
* result in m_Icons.
*
* @param Element The Xeromyces object that represents
* the scrollbar-tag.
* @param pFile The Xeromyces object for the file being read
*
* @see LoadXMLFile()
*/
void Xeromyces_ReadIcon(XMBElement Element, CXeromyces* pFile);
//@}
private:
@ -515,22 +538,21 @@ private:
*/
std::map<CStr, ConstructObjectFunction> m_ObjectTypes;
//@}
//--------------------------------------------------------
/** @name Databases */
// Databases
//--------------------------------------------------------
//@{
/// Sprites
// Sprites
std::map<CStr, CGUISprite> m_Sprites;
/// Styles
// Styles
std::map<CStr, SGUIStyle> m_Styles;
/// Scroll-bar styles
// Scroll-bar styles
std::map<CStr, SGUIScrollBarStyle> m_ScrollBarStyles;
//@}
// Icons
std::map<CStr, SGUIIcon> m_Icons;
};
#endif

View File

@ -18,20 +18,18 @@ void CRadioButton::HandleMessage(const SGUIMessage &Message)
switch (Message.type)
{
case GUIM_PRESSED:
{ // janwas added scoping to squelch ICC var decl warning
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);
}
for (vector_pObjects::iterator it = GetParent()->ChildrenItBegin(); it != GetParent()->ChildrenItEnd(); ++it)
{
// Notice, if you use other objects within the parent object that has got
// the setting "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;
}
GUI<bool>::SetSetting(this, "checked", true);
break;
}
default:
break;

View File

@ -26,6 +26,9 @@ CText::CText()
AddSetting(GUIST_CStr, "scrollbar-style");
AddSetting(GUIST_CStr, "sprite");
AddSetting(GUIST_CColor, "textcolor");
// TODO Gee: (2004-08-14)
// Add a setting for buffer zone
//AddSetting(GUIST_int, "
//GUI<bool>::SetSetting(this, "ghost", true);
GUI<bool>::SetSetting(this, "scrollbar", false);
@ -56,6 +59,7 @@ void CText::SetupText()
CStr font;
if (GUI<CStr>::GetSetting(this, "font", font) != PS_OK || font.Length()==0)
// Use the default if none is specified
// TODO Gee: (2004-08-14) Don't define standard like this. Do it with the default style.
font = "default";
CGUIString caption;
@ -69,7 +73,7 @@ void CText::SetupText()
if (scrollbar && GetScrollBar(0).GetStyle())
width -= GetScrollBar(0).GetStyle()->m_Width;
*m_GeneratedTexts[0] = GetGUI()->GenerateText(caption, /*color,*/ font, width, 4);
*m_GeneratedTexts[0] = GetGUI()->GenerateText(caption, font, width, 4, this);
// Setup scrollbar
if (scrollbar)
@ -115,14 +119,14 @@ void CText::HandleMessage(const SGUIMessage &Message)
break;
case GUIM_MOUSE_WHEEL_DOWN:
GetScrollBar(0).ScrollPlus();
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;
case GUIM_MOUSE_WHEEL_UP:
GetScrollBar(0).ScrollMinus();
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));

View File

@ -5,40 +5,14 @@ gee@pyro.nu
--Overview--
Include this file and it will include the whole GUI
Include this file and it will include the whole GUI.
--More info--
http://gee.pyro.nu/GUI/
Check TDD for GUI Engine Documentation
*/
// Main page for GUI documentation
/**
* @mainpage
* Welcome to the Wildfire Games Graphical User Interface Documentation.
*
* Additional Downloads can be made from the link below.\n
* <a href="http://gee.pyro.nu/GUIfiles/">Technical Design Document</a>
*
* The GUI uses <a href="http://xml.apache.org/xerces-c/">Xerces C++ Parser</a>,
* Current official version (ensured to work): 2.3.0
*
* @dot
* digraph
* {
* node [shape=record, fontname=Helvetica, fontsize=10];
* q [ label="Questions?"];
* c [ label="Comments?"];
* s [ label="Suggestions?"];
* email [label="E-mail Me" URL="mailto:gee@pyro.nu"];
* q -> email;
* c -> email;
* s -> email;
* }
* @enddot
*/
#ifndef GUI_H
#define GUI_H

View File

@ -22,12 +22,15 @@ gee@pyro.nu
// Includes / Compiler directives
//--------------------------------------------------------
// I would like to just forward declare CSize, but it doesn't
// seem to be defined anywhere in the predefined header.
#include "Overlay.h"
//--------------------------------------------------------
// Forward declarations
//--------------------------------------------------------
class IGUIObject;
//--------------------------------------------------------
// Macros
//--------------------------------------------------------
@ -129,6 +132,19 @@ enum EGUISettingsStruct
typedef std::map<CStr, IGUIObject*> map_pObjects;
typedef std::vector<IGUIObject*> vector_pObjects;
// Smaller structs that don't deserve their own files :)
// Icon, you create them in the XML file with root element <setup>
// you use them in text owned by different objects... Such as CText.
struct SGUIIcon
{
// Texture name of icon
CStr m_TextureName;
// Size
CSize m_Size;
};
//--------------------------------------------------------
// Error declarations
//--------------------------------------------------------

View File

@ -7,14 +7,14 @@ gee@pyro.nu
#include "precompiled.h"
#include "GUI.h"
#include "CLogger.h"
#include "Parser.h"
#include "OverlayText.h"
#include <algorithm>
#include "ps/Font.h"
#define LOG_CATEGORY "gui"
// TODO Gee: Remove, just for temp-output
#include <fstream>
#include "ps/Font.h"
using namespace std;
@ -32,8 +32,9 @@ void CGUIString::SFeedback::Reset()
}
void CGUIString::GenerateTextCall(SFeedback &Feedback,
const CStr& DefaultFont, /*const CColor &DefaultColor,*/
const int &from, const int &to) const
const CStr& DefaultFont,
const int &from, const int &to,
const IGUIObject *pObject) const
{
// Reset width and height, because they will be determined with incrementation
// or comparisons.
@ -44,6 +45,10 @@ void CGUIString::GenerateTextCall(SFeedback &Feedback,
vector<TextChunk>::const_iterator itTextChunk;
for (itTextChunk=m_TextChunks.begin(); itTextChunk!=m_TextChunks.end(); ++itTextChunk)
{
// - GL - Temp
TextChunk tc = *itTextChunk;
// -- GL
// Get the area that is overlapped by both the TextChunk and
// by the from/to inputted.
int _from, _to;
@ -51,58 +56,106 @@ void CGUIString::GenerateTextCall(SFeedback &Feedback,
_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)
if (_to == _from && itTextChunk->m_From == itTextChunk->m_To)
{
// These should never be able to have more than one tag.
assert(itTextChunk->m_Tags.size()==1);
// Now do second check
// because icons and images are placed on exactly one position
// in the words-list, it can be counted twice if placed on an
// edge. But there is always only one logical preference that
// we want. This check filters the unwanted.
// it's in the end of one word, and the icon
// should really belong to the beginning of the next one
if (_to == to)
{
if (GetRawString()[to-1] == ' ' ||
GetRawString()[to-1] == '-' ||
GetRawString()[to-1] == '\n')
continue;
}
// This string is just a break
if (_from == from && from >= 1)
{
if (GetRawString()[from] == '\n' &&
GetRawString()[from-1] != '\n' &&
GetRawString()[from-1] != ' ' &&
GetRawString()[from-1] != '-')
continue;
}
// Single tags
if (itTextChunk->m_Tags[0].m_TagType == CGUIString::TextChunk::Tag::TAG_IMGLEFT)
{
//if (_from > from)
// Only add the image if the icon exists.
if (g_GUI.IconExists(itTextChunk->m_Tags[0].m_TagValue))
{
Feedback.m_Images[SFeedback::Left].push_back(itTextChunk->m_Tags[0].m_TagValue);
}
else if (pObject)
{
LOG(ERROR, LOG_CATEGORY, "Trying to use an [imgleft]-tag with an undefined icon (\"%s\").", itTextChunk->m_Tags[0].m_TagValue.c_str());
}
}
else
if (itTextChunk->m_Tags[0].m_TagType == CGUIString::TextChunk::Tag::TAG_IMGRIGHT)
{
//if (_from > from)
// Only add the image if the icon exists.
if (g_GUI.IconExists(itTextChunk->m_Tags[0].m_TagValue))
{
Feedback.m_Images[SFeedback::Right].push_back(itTextChunk->m_Tags[0].m_TagValue);
}
else if (pObject)
{
LOG(ERROR, LOG_CATEGORY, "Trying to use an [imgright]-tag with an undefined icon (\"%s\").", itTextChunk->m_Tags[0].m_TagValue.c_str());
}
}
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;
// Only add the image if the icon exists.
if (g_GUI.IconExists(itTextChunk->m_Tags[0].m_TagValue))
{
// 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 virtually for nothing more.
SGUIText::STextCall TextCall;
// Also add it to the sprites being rendered.
SGUIText::SSpriteCall SpriteCall;
// Also add it to the sprites being rendered.
SGUIText::SSpriteCall SpriteCall;
CSize size(20,20);
// Query size of icon
// TODO Gee: Temp
// Get Icon from icon database in g_GUI
SGUIIcon icon = g_GUI.GetIcon(itTextChunk->m_Tags[0].m_TagValue);
// 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);
CSize size = icon.m_Size;
// These are also needed later
TextCall.m_Size = size;
SpriteCall.m_Area = size;
// 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);
SpriteCall.m_TextureName = CStr("scroll");
// These are also needed later
TextCall.m_Size = size;
SpriteCall.m_Area = size;
// Add sprite call
Feedback.m_SpriteCalls.push_back(SpriteCall);
// TODO Gee: (2004-08-16) Eventually shouldn't be hardcoded
SpriteCall.m_TextureName = icon.m_TextureName;
// Finalize text call
TextCall.m_pSpriteCall = &Feedback.m_SpriteCalls.back();
// Add sprite call
Feedback.m_SpriteCalls.push_back(SpriteCall);
// Add text call
Feedback.m_TextCalls.push_back(TextCall);
// Finalize text call
TextCall.m_pSpriteCall = &Feedback.m_SpriteCalls.back();
// Add text call
Feedback.m_TextCalls.push_back(TextCall);
}
else if (pObject)
{
LOG(ERROR, LOG_CATEGORY, "Trying to use an [icon]-tag with an undefined icon (\"%s\").", itTextChunk->m_Tags[0].m_TagValue.c_str());
}
}
}
else
@ -125,11 +178,18 @@ void CGUIString::GenerateTextCall(SFeedback &Feedback,
{
// Set custom color
TextCall.m_UseCustomColor = true;
GUI<CColor>::ParseString(it2->m_TagValue, TextCall.m_Color);
// Try parsing the color string
if (!GUI<CColor>::ParseString(it2->m_TagValue, TextCall.m_Color))
{
if (pObject)
LOG(ERROR, LOG_CATEGORY, "Error parsing the value of a [color]-tag in GUI text when reading object \"%s\".", pObject->GetPresentableName().c_str());
}
}
else
if (it2->m_TagType == CGUIString::TextChunk::Tag::TAG_FONT)
{
// TODO Gee: (2004-08-15) Check if Font exists?
TextCall.m_Font = it2->m_TagValue;
}
}
@ -217,12 +277,13 @@ void CGUIString::SetValue(const CStr& str)
m_RawString = CStr();
// Setup parser
// TODO Gee: (2004-08-16) Create and store this parser object somewhere to save loading time.
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=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;
@ -402,26 +463,6 @@ void CGUIString::SetValue(const CStr& str)
}
}
#if 1
ofstream fout("output1.txt");
for (int i=0; i<(int)m_TextChunks.size(); ++i)
{
fout << "{\"";
fout << m_TextChunks[i].m_From << " " << m_TextChunks[i].m_To << "\",";
for (int j=0; j<(int)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.
@ -473,19 +514,38 @@ void CGUIString::SetValue(const CStr& str)
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(); )
// Remove duplicates (only if larger than 2)
if (m_Words.size() > 2)
{
if (last_word == *it)
vector<int>::iterator it;
int last_word = -1;
for (it = m_Words.begin(); it != m_Words.end(); )
{
it = m_Words.erase(it);
}
else
{
last_word = *it;
++it;
if (last_word == *it)
{
it = m_Words.erase(it);
}
else
{
last_word = *it;
++it;
}
}
}
#if 1
for (int i=0; i<(int)m_Words.size(); ++i)
{
LOG(NORMAL, LOG_CATEGORY, "m_Words[%d] = %d", i, m_Words[i]);
}
for (int i=0; i<(int)m_TextChunks.size(); ++i)
{
LOG(NORMAL, LOG_CATEGORY, "m_TextChunk[%d] = [%d,%d]", i, m_TextChunks[i].m_From, m_TextChunks[i].m_To);
for (int j=0; j<(int)m_TextChunks[i].m_Tags.size(); ++j)
{
LOG(NORMAL, LOG_CATEGORY, "--Tag: %d \"%s\"", (int)m_TextChunks[i].m_Tags[j].m_TagType, m_TextChunks[i].m_Tags[j].m_TagValue.c_str());
}
}
#endif
}

View File

@ -36,7 +36,7 @@ gee@pyro.nu
* individual calls saying it want that color on the
* text.
*
* For instance (this is not the syntax):
* For instance:
* "Hello [b]there[/b] bunny!"
*
* That without word-wrapping would mean 3 components.
@ -113,7 +113,7 @@ struct SGUIText
/**
* *IF* an icon, than this is not NULL.
*/
SSpriteCall *m_pSpriteCall;
std::list<SSpriteCall>::pointer m_pSpriteCall;
};
/**
@ -125,7 +125,8 @@ struct SGUIText
* List of sprites, or "icons" that should be rendered
* along with the text.
*/
std::vector<SSpriteCall> m_SpriteCalls;
std::list<SSpriteCall> m_SpriteCalls; // list for consistant mem addresses
// so that we can point to elements.
/**
* Width and height of the whole output, used when setting up
@ -238,7 +239,8 @@ public:
* Text and Sprite Calls.
*/
std::vector<SGUIText::STextCall> m_TextCalls;
std::vector<SGUIText::SSpriteCall> m_SpriteCalls;
std::list<SGUIText::SSpriteCall> m_SpriteCalls; // list for consistent mem addresses
// so that we can point to elements.
/**
* Width and Height *feedback*
@ -272,13 +274,18 @@ public:
*
* @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.
*
* pObject Only for Error outputting, optional! If NULL
* then no Errors will be reported! Useful when you need
* to make several GenerateTextCall in different phases,
* it avoids duplicates.
*/
void GenerateTextCall(SFeedback &Feedback,
const CStr& DefaultFont, /*const CColor &DefaultColor,*/
const int &from, const int &to) const;
const CStr& DefaultFont,
const int &from, const int &to,
const IGUIObject *pObject=NULL) const;
/**
* Words

View File

@ -104,7 +104,7 @@ bool __ParseString<CColor>(const CStr& Value, CColor &Output)
{
if (!line.GetArgFloat(i, values[i]))
{
// TODO Gee: Parsing failed
// Parsing failed
return false;
}
}
@ -117,6 +117,45 @@ bool __ParseString<CColor>(const CStr& Value, CColor &Output)
return true;
}
template <>
bool __ParseString<CSize>(const CStr& Value, CSize &Output)
{
// Use the parser to parse the values
CParser parser;
parser.InputTaskType("", "_$value_$value_");
string str = (const TCHAR*)Value;
CParserLine line;
line.ParseString(parser, str);
if (!line.m_ParseOK)
{
// Parsing failed
return false;
}
int x, y;
// x
if (!line.GetArgInt(0, x))
{
// TODO Gee: Parsing failed
return false;
}
// y
if (!line.GetArgInt(1, y))
{
// TODO Gee: Parsing failed
return false;
}
Output.cx = x;
Output.cy = y;
return true;
}
template <>
bool __ParseString<CGUIString>(const CStr& Value, CGUIString &Output)
{

View File

@ -54,6 +54,9 @@ bool __ParseString<CClientArea>(const CStr& Value, CClientArea &Output);
template <>
bool __ParseString<CColor>(const CStr& Value, CColor &Output);
template <>
bool __ParseString<CSize>(const CStr& Value, CSize &Output);
template <>
bool __ParseString<CGUIString>(const CStr& Value, CGUIString &Output);

View File

@ -172,7 +172,8 @@ void IGUIObject::AddSetting(const EGUISettingType &Type, const CStr& Name)
default:
debug_warn("IGUIObject::AddSetting failed");
// TODO Gee: Report in log, type is not recognized.
// TODO Gee: Report in log, type is not recognized. This should be an assert, not in log
// because it's strictly hardcoded error
break;
}
}
@ -478,3 +479,16 @@ void IGUIObject::ScriptEvent(const CStr& Action)
JS_RemoveRoot(g_ScriptingHost.getContext(), &mouseObj);
JS_RemoveRoot(g_ScriptingHost.getContext(), &jsGuiObject);
}
CStr IGUIObject::GetPresentableName() const
{
// __internal(), must be at least 13 letters to be able to be
// an internal name
if (m_Name.Length() <= 12)
return m_Name;
if (m_Name.GetSubstring(0, 10) == CStr("__internal"))
return CStr("[unnamed object]");
else
return m_Name;
}

View File

@ -166,6 +166,10 @@ public:
/// Get object name
void SetName(const CStr& Name) { m_Name = Name; }
// Get Presentable name.
// Will change all internally set names to something like "<unnamed object>"
CStr GetPresentableName() const;
/**
* Adds object and its children to the map, it's name being the
* first part, and the second being itself.

View File

@ -43,13 +43,7 @@ void IGUIScrollBarOwner::AddScrollBar(IGUIScrollBar * scrollbar)
scrollbar->SetGUI(GetGUI());
m_ScrollBars.push_back(scrollbar);
}
/*
void SetGUI(CGUI * const &pGUI)
{
m_pGUI = pGUI;
scrollbar->SetGUI(m_pGUI);
}
*/
const SGUIScrollBarStyle * IGUIScrollBarOwner::GetScrollBarStyle(const CStr& style) const
{
if (!GetGUI())

View File

@ -38,7 +38,7 @@ void IGUITextOwner::HandleMessage(const SGUIMessage &Message)
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
// these. Although 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") ||
@ -61,9 +61,8 @@ void IGUITextOwner::Draw(const int &index, const CColor &color, const CPos &pos,
const float &z, const CRect &UNUSEDPARAM(clipping))
{
if (index < 0 || index >= (int)m_GeneratedTexts.size())
// janwas fixed bug here; was i < 0 && i >= size - impossible.
{
// TODO Gee: Warning
debug_warn("Trying to draw a Text Index within a IGUITextOwner that doesn't exist");
return;
}