Skip to content

Commit 8403eb7

Browse files
committed
#158 implement load gui design CGUIImporter
1 parent 1224b38 commit 8403eb7

File tree

8 files changed

+247
-3
lines changed

8 files changed

+247
-3
lines changed

Projects/Editor/Source/Editor/Space/GUIDesign/CSpaceGUIDesign.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ This file is part of the "Skylicht Engine".
3131

3232
#include "Handles/CGUIHandles.h"
3333

34+
#include "Graphics2D/CGUIImporter.h"
35+
3436
using namespace std::placeholders;
3537

3638
namespace Skylicht
@@ -152,10 +154,27 @@ namespace Skylicht
152154

153155
void CSpaceGUIDesign::openGUI(const char* path)
154156
{
157+
// fix for open new space and open path
158+
if (!m_scene)
159+
m_scene = CSceneController::getInstance()->getScene();
160+
155161
if (m_scene)
156162
{
157163
CGameObject* canvasObj = m_scene->searchObjectInChild(L"GUICanvas");
164+
CCanvas* canvas = canvasObj->getComponent<CCanvas>();
165+
canvas->removeAllElement();
158166
m_gizmos->onRemove();
167+
168+
if (CGUIImporter::beginImport(path, canvas) == true)
169+
{
170+
bool loadFinish = false;
171+
do
172+
{
173+
loadFinish = CGUIImporter::updateLoadGUI();
174+
} while (!loadFinish);
175+
176+
CGUIDesignController::getInstance()->rebuildGUIHierachy();
177+
}
159178
}
160179
}
161180

Projects/Skylicht/Engine/Source/Graphics2D/CCanvas.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,11 @@ namespace Skylicht
331331
return result;
332332
}
333333

334+
void CCanvas::removeAllElement()
335+
{
336+
m_root->removeAllChilds();
337+
}
338+
334339
/*
335340
* Element constructor
336341
*/

Projects/Skylicht/Engine/Source/Graphics2D/CCanvas.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ namespace Skylicht
122122
return m_enable3DBillboard;
123123
}
124124

125+
void removeAllElement();
126+
125127
CGUIElement* createElement();
126128

127129
CGUIElement* createElement(const core::rectf& r);

Projects/Skylicht/Engine/Source/Graphics2D/CGUIImporter.cpp

Lines changed: 186 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,196 @@ This file is part of the "Skylicht Engine".
2424

2525
#include "pch.h"
2626
#include "CGUIImporter.h"
27+
#include "Utils/CStringImp.h"
2728

2829
namespace Skylicht
2930
{
30-
bool CGUIImporter::load(const char* file, CCanvas* canvas)
31+
io::IXMLReader* CGUIImporter::s_reader = NULL;
32+
std::string CGUIImporter::s_guiPath;
33+
CCanvas* CGUIImporter::s_canvas = NULL;
34+
35+
int CGUIImporter::s_loadStep = 10;
36+
int CGUIImporter::s_loading = 0;
37+
38+
std::list<CGUIElement*> CGUIImporter::s_listObject;
39+
std::list<CGUIElement*>::iterator CGUIImporter::s_current;
40+
41+
void CGUIImporter::buildCanvas(CCanvas* canvas, io::IXMLReader* reader)
3142
{
43+
std::wstring nodeName = L"node";
44+
std::wstring attributeName;
45+
46+
std::stack<CGUIElement*> parents;
47+
48+
s_listObject.clear();
49+
50+
CGUIElement* currentObject = NULL;
51+
52+
core::rectf nullRect;
53+
SColor nullColor;
54+
55+
while (reader->read())
56+
{
57+
switch (reader->getNodeType())
58+
{
59+
case io::EXN_ELEMENT:
60+
if (nodeName == reader->getNodeName())
61+
{
62+
if (reader->getAttributeValue(L"type") != NULL)
63+
{
64+
attributeName = reader->getAttributeValue(L"type");
65+
66+
CGUIElement* parent = NULL;
67+
if (parents.size() > 0)
68+
parent = parents.top();
69+
70+
CGUIElement* element = NULL;
71+
72+
// No need create root
73+
if (parent)
74+
{
75+
// create null object, that will load data in later
76+
if (attributeName == L"CGUIElement")
77+
element = canvas->createElement(parent, nullRect);
78+
else if (attributeName == L"CGUIImage")
79+
element = canvas->createImage(parent, nullRect);
80+
else if (attributeName == L"CGUIMask")
81+
element = canvas->createMask(parent, nullRect);
82+
else if (attributeName == L"CGUIRect")
83+
element = canvas->createRect(parent, nullRect, nullColor);
84+
else if (attributeName == L"CGUIRoundedRect")
85+
element = canvas->createRoundedRect(parent, nullRect, 10.0f, nullColor);
86+
else if (attributeName == L"CGUISprite")
87+
element = canvas->createSprite(parent, nullRect, NULL);
88+
else if (attributeName == L"CGUIText")
89+
element = canvas->createText(parent, nullRect, NULL);
90+
}
91+
else
92+
{
93+
if (attributeName == L"CGUIElement")
94+
element = canvas->getRootElement();
95+
}
96+
97+
if (element)
98+
{
99+
s_listObject.push_back(element);
100+
currentObject = element;
101+
}
102+
103+
if (currentObject && attributeName == L"Childs")
104+
{
105+
parents.push(currentObject);
106+
}
107+
}
108+
}
109+
break;
110+
case io::EXN_ELEMENT_END:
111+
if (nodeName == reader->getNodeName())
112+
{
113+
if (attributeName == L"Childs")
114+
{
115+
parents.pop();
116+
}
117+
}
118+
break;
119+
default:
120+
break;
121+
}
122+
}
123+
124+
s_current = s_listObject.begin();
125+
}
126+
127+
bool CGUIImporter::beginImport(const char* file, CCanvas* canvas)
128+
{
129+
// step 1
130+
// build scene object
131+
s_reader = getIrrlichtDevice()->getFileSystem()->createXMLReader(file);
132+
if (s_reader == NULL)
133+
return false;
134+
135+
buildCanvas(canvas, s_reader);
136+
137+
// close
138+
s_reader->drop();
139+
140+
// re-open the scene file
141+
s_reader = getIrrlichtDevice()->getFileSystem()->createXMLReader(file);
142+
s_guiPath = file;
143+
s_canvas = canvas;
144+
s_loading = 0;
145+
146+
return true;
147+
}
148+
149+
bool CGUIImporter::loadStep(CCanvas* canvas, io::IXMLReader* reader)
150+
{
151+
std::wstring nodeName = L"node";
152+
std::wstring attributeName;
153+
154+
int step = 0;
155+
156+
while (step < s_loadStep && reader->read())
157+
{
158+
switch (reader->getNodeType())
159+
{
160+
case io::EXN_ELEMENT:
161+
if (nodeName == reader->getNodeName())
162+
{
163+
if (reader->getAttributeValue(L"type") != NULL)
164+
{
165+
attributeName = reader->getAttributeValue(L"type");
166+
167+
if (attributeName == L"CGUIElement" ||
168+
attributeName == L"CGUIImage" ||
169+
attributeName == L"CGUIMask" ||
170+
attributeName == L"CGUIRect" ||
171+
attributeName == L"CGUIRoundedRect" ||
172+
attributeName == L"CGUISprite" ||
173+
attributeName == L"CGUIText")
174+
{
175+
CGUIElement* guiObject = dynamic_cast<CGUIElement*>(*s_current);
176+
++s_current;
177+
++s_loading;
178+
++step;
179+
180+
CObjectSerializable* data = guiObject->createSerializable();
181+
data->parseSerializable(reader);
182+
guiObject->loadSerializable(data);
183+
delete data;
184+
}
185+
}
186+
}
187+
break;
188+
default:
189+
break;
190+
}
191+
}
192+
193+
return s_current == s_listObject.end();
194+
}
195+
196+
bool CGUIImporter::updateLoadGUI()
197+
{
198+
if (CGUIImporter::loadStep(s_canvas, s_reader))
199+
{
200+
// drop
201+
if (s_reader)
202+
{
203+
s_reader->drop();
204+
s_reader = NULL;
205+
}
206+
207+
s_canvas = NULL;
208+
return true;
209+
}
210+
32211
return false;
33212
}
213+
214+
float CGUIImporter::getLoadingPercent()
215+
{
216+
int size = (int)s_listObject.size();
217+
return s_loading / (float)size;
218+
}
34219
}

Projects/Skylicht/Engine/Source/Graphics2D/CGUIImporter.h

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,31 @@ namespace Skylicht
3030
{
3131
class CGUIImporter
3232
{
33+
static io::IXMLReader* s_reader;
34+
35+
static std::string s_guiPath;
36+
37+
static CCanvas* s_canvas;
38+
39+
static int s_loadStep;
40+
41+
static int s_loading;
42+
43+
static std::list<CGUIElement*> s_listObject;
44+
45+
static std::list<CGUIElement*>::iterator s_current;
46+
3347
public:
34-
static bool load(const char* file, CCanvas* canvas);
48+
static bool beginImport(const char* file, CCanvas* canvas);
49+
50+
static bool updateLoadGUI();
51+
52+
static float getLoadingPercent();
53+
54+
protected:
55+
56+
static bool loadStep(CCanvas* canvas, io::IXMLReader* reader);
57+
58+
static void buildCanvas(CCanvas* canvas, io::IXMLReader* reader);
3559
};
3660
}

Projects/Skylicht/Engine/Source/Graphics2D/GUI/CGUISprite.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ namespace Skylicht
153153
// load by id first
154154
CSpriteFrame* sprite = spriteMgr->getSpriteById(m_spriteId.c_str());
155155
if (!sprite)
156-
sprite = spriteMgr->loadSprite(m_spriteId.c_str());
156+
sprite = spriteMgr->loadSprite(m_sprite.c_str());
157157

158158
if (sprite && sprite->getId() == m_spriteId)
159159
{

Projects/Skylicht/Engine/Source/Graphics2D/SpriteFrame/CSpriteFont.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ namespace Skylicht
5454
if (xmlReader == NULL)
5555
return false;
5656

57+
// see the font format here
58+
// https://www.angelcode.com/products/bmfont/doc/file_format.html
59+
5760
char text[512];
5861

5962
int readState = -1;

Projects/Skylicht/Engine/Source/Graphics2D/SpriteFrame/CSpriteFont.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ This file is part of the "Skylicht Engine".
2929

3030
namespace Skylicht
3131
{
32+
/// <summary>
33+
/// CSpriteFont
34+
/// Use the software BMFont
35+
/// https://www.angelcode.com/products/bmfont/
36+
/// To generate the font sprite
37+
/// </summary>
3238
class CSpriteFont :
3339
public CSpriteFrame,
3440
public IFont

0 commit comments

Comments
 (0)