made GuiWindowRoot a member of C4Game

Controls
David Dormagen 2013-05-26 18:12:03 +02:00
parent f64c6c8852
commit dd1e2e2709
8 changed files with 70 additions and 39 deletions

View File

@ -436,7 +436,7 @@ void C4ControlMenuCommand::Execute() const
Log("Warning: invalid action type for C4ControlMenuCommand!");
return;
}
C4GuiWindow *menu = ::GuiWindowRoot.GetChildByID(menuID);
C4GuiWindow *menu = ::Game.GuiWindowRoot->GetChildByID(menuID);
// menu was closed?
if (!menu) return;

View File

@ -108,7 +108,8 @@ C4Game::C4Game():
pFileMonitor(NULL),
pSec1Timer(new C4GameSec1Timer()),
fPreinited(false), StartupLogPos(0), QuitLogPos(0),
fQuitWithError(false)
fQuitWithError(false),
GuiWindowRoot(0)
{
Default();
}
@ -920,7 +921,7 @@ void C4Game::ClearPointers(C4Object * pObj)
::MessageInput.ClearPointers(pObj);
::Console.ClearPointers(pObj);
::MouseControl.ClearPointers(pObj);
::GuiWindowRoot.ClearPointers(pObj);
GuiWindowRoot->ClearPointers(pObj);
TransferZones.ClearPointers(pObj);
if (pGlobalEffects)
pGlobalEffects->ClearPointers(pObj);
@ -1496,6 +1497,11 @@ void C4Game::Default()
DebugPassword.Clear();
DebugHost.Clear();
DebugWait = false;
delete GuiWindowRoot;
const float standardVerticalBorder = 100.0f;
const float standardHorizontalBorder = 100.0f;
GuiWindowRoot = new C4GuiWindow(standardVerticalBorder, standardHorizontalBorder);
}
void C4Game::Evaluate()
@ -1631,6 +1637,21 @@ void C4Game::CompileFunc(StdCompiler *pComp, CompileSettings comp, C4ValueNumber
pComp->Value(mkNamingAdapt(Weather, "Weather"));
pComp->Value(mkNamingAdapt(Landscape, "Landscape"));
pComp->Value(mkNamingAdapt(Landscape.Sky, "Sky"));
// save custom GUIs only if a real savegame and not for editor-scenario-saves
if (pComp->isCompiler())
{
C4Value val;
pComp->Value(mkNamingAdapt(mkParAdapt(val, numbers), "CustomGUIs", C4VNull));
assert (GuiWindowRoot->GetID() == 0);
GuiWindowRoot->CreateFromPropList(val.getPropList(), false, false, true);
}
else
{
C4Value val = GuiWindowRoot->ToC4Value();
pComp->Value(mkNamingAdapt(mkParAdapt(val, numbers), "CustomGUIs", C4VNull));
}
}
if (comp.fPlayers)

View File

@ -31,6 +31,8 @@
#include "C4Scoreboard.h"
#include <C4PlayerControl.h>
class C4GuiWindow;
class C4Game
{
private:
@ -226,6 +228,7 @@ public:
bool InitPlayerControlSettings();
bool InitPlayerControlUserSettings(); // merge player control default settings and config overloads into user setting
C4GuiWindow *GuiWindowRoot;
protected:
void Default();
void InitInEarth();

View File

@ -305,7 +305,7 @@ void C4Viewport::Draw(C4TargetFacet &cgo0, bool fDrawOverlay)
// ingame menus
C4ST_STARTNEW(GuiWindowStat, "C4Viewport::DrawOverlay: Menus")
pDraw->SetZoom(0, 0, 1.0);
::GuiWindowRoot.Draw(gui_cgo, Player);
::Game.GuiWindowRoot->Draw(gui_cgo, Player);
C4ST_STOP(GuiWindowStat)
DrawOverlay(gui_cgo, GameZoom);

View File

@ -2134,11 +2134,11 @@ static int FnCustomGuiOpen(C4PropList * _this, C4PropList *menu)
{
C4GuiWindow *window = new C4GuiWindow;
::GuiWindowRoot.AddChild(window);
::Game.GuiWindowRoot->AddChild(window);
if (!window->CreateFromPropList(menu, true))
{
::GuiWindowRoot.RemoveChild(window, false);
::Game.GuiWindowRoot->RemoveChild(window, false);
return 0;
}
@ -2147,7 +2147,7 @@ static int FnCustomGuiOpen(C4PropList * _this, C4PropList *menu)
static bool FnCustomGuiSetTag(C4PropList * _this, C4String *tag, int32_t menuID, int32_t childID, C4Object *target)
{
C4GuiWindow *window = ::GuiWindowRoot.GetChildByID(menuID);
C4GuiWindow *window = ::Game.GuiWindowRoot->GetChildByID(menuID);
if (!window) return false;
if (childID) // note: valid child IDs are always non-zero
{
@ -2162,7 +2162,7 @@ static bool FnCustomGuiSetTag(C4PropList * _this, C4String *tag, int32_t menuID,
static bool FnCustomGuiClose(C4PropList *_this, int32_t menuID, int32_t childID, C4Object *target)
{
C4GuiWindow *window = ::GuiWindowRoot.GetChildByID(menuID);
C4GuiWindow *window = ::Game.GuiWindowRoot->GetChildByID(menuID);
if (!window) return false;
if (childID) // note: valid child IDs are always non-zero
{
@ -2178,7 +2178,7 @@ static bool FnCustomGuiClose(C4PropList *_this, int32_t menuID, int32_t childID,
static bool FxCustomGuiUpdate(C4PropList *_this, C4PropList *update, int32_t menuID, int32_t childID, C4Object *target)
{
if (!update) return false;
C4GuiWindow *window = ::GuiWindowRoot.GetChildByID(menuID);
C4GuiWindow *window = ::Game.GuiWindowRoot->GetChildByID(menuID);
if (!window) return false;
if (childID) // note: valid child IDs are always non-zero
{

View File

@ -31,13 +31,6 @@
#include <C4Player.h>
#include <C4PlayerList.h>
const float standardVerticalBorder = 100.0f;
const float standardHorizontalBorder = 100.0f;
C4GuiWindow GuiWindowRoot = C4GuiWindow(standardVerticalBorder, standardHorizontalBorder);
C4GuiWindowAction::~C4GuiWindowAction()
{
if (text)
@ -76,6 +69,10 @@ const C4Value C4GuiWindowAction::ToC4Value(bool first)
break;
}
assert (array->GetSize() < 6);
array->SetSize(6);
array->SetItem(5, C4Value(id));
if (!first || !nextAction) return C4Value(array);
// this action is the first in a chain of actions
@ -132,6 +129,10 @@ bool C4GuiWindowAction::Init(C4ValueArray *array, int32_t index)
// retrieve type of action
int newAction = array->GetItem(0).getInt();
action = 0; // still invalid!
// when loading, the array has a size of 6 with the 5th element being the ID
if (array->GetSize() == 6)
id = array->GetItem(3).getInt();
switch (newAction)
{
@ -144,8 +145,9 @@ bool C4GuiWindowAction::Init(C4ValueArray *array, int32_t index)
value = C4Value(array->GetItem(3));
text->IncRef();
// important! needed to identify actions later!
id = ::GuiWindowRoot.GenerateActionID();
// important! needed to identify actions later!
if (!id)
id = ::Game.GuiWindowRoot->GenerateActionID();
break;
@ -710,7 +712,9 @@ const C4Value C4GuiWindow::ToC4Value()
P_Priority
};
for (size_t i = 0; i < sizeof(toSave); ++i)
const int32_t entryCount = sizeof(toSave) / sizeof(int32_t);
for (size_t i = 0; i < entryCount; ++i)
{
int32_t prop = toSave[i];
C4Value val;
@ -753,6 +757,7 @@ const C4Value C4GuiWindow::ToC4Value()
case P_OnClose: val = props[C4GuiWindowPropertyName::onCloseAction].ToC4Value(); break;
case P_Style: val = props[C4GuiWindowPropertyName::style].ToC4Value(); break;
case P_Mode: val = C4Value(int32_t(hasMouseFocus)); break;
case P_Priority: val = props[C4GuiWindowPropertyName::priority].ToC4Value(); break;
default:
assert(false);
@ -777,9 +782,11 @@ const C4Value C4GuiWindow::ToC4Value()
return C4Value(proplist);
}
bool C4GuiWindow::CreateFromPropList(C4PropList *proplist, bool resetStdTag, bool isUpdate)
bool C4GuiWindow::CreateFromPropList(C4PropList *proplist, bool resetStdTag, bool isUpdate, bool isLoading)
{
assert(parent && "GuiWindow created from proplist without parent (fails for ID tag)");
if (!proplist) return false;
assert((parent || isLoading) && "GuiWindow created from proplist without parent (fails for ID tag)");
bool layoutUpdateRequired = false; // needed for position changes etc
// get properties from proplist
@ -840,16 +847,19 @@ bool C4GuiWindow::CreateFromPropList(C4PropList *proplist, bool resetStdTag, boo
else if(&Strings.P[P_Mode] == key) // note that "Mode" is abused here for saving whether we have mouse focus
hasMouseFocus = property.getBool();
else if(&Strings.P[P_ID] == key)
{
// setting IDs is only valid for subwindows!
if (!isMainWindow)
{
{
// setting IDs is only valid for subwindows or when loading savegames!
if (parent && !isMainWindow)
{
if (id) // already have an ID? remove from parent
parent->ChildWithIDRemoved(this);
parent->ChildWithIDRemoved(this);
id = property.getInt();
if (id != 0)
parent->ChildGotID(this);
}
}
else
if (!isLoading)
id = property.getInt();
}
else if(&Strings.P[P_OnClick] == key)
props[C4GuiWindowPropertyName::onClickAction].Set(property, stdTag);
@ -868,8 +878,9 @@ bool C4GuiWindow::CreateFromPropList(C4PropList *proplist, bool resetStdTag, boo
{
props[C4GuiWindowPropertyName::priority].Set(property, stdTag);
layoutUpdateRequired = true;
// resort into parent's list
parent->ChildChangedPriority(this);
// resort into parent's list
if (parent)
parent->ChildChangedPriority(this);
}
else
{
@ -880,7 +891,7 @@ bool C4GuiWindow::CreateFromPropList(C4PropList *proplist, bool resetStdTag, boo
C4GuiWindow *child = new C4GuiWindow();
AddChild(child);
if (!child->CreateFromPropList(subwindow, isUpdate == true, false))
if (!child->CreateFromPropList(subwindow, isUpdate == true, false, isLoading))
RemoveChild(child, false);
else
layoutUpdateRequired = true;
@ -888,7 +899,7 @@ bool C4GuiWindow::CreateFromPropList(C4PropList *proplist, bool resetStdTag, boo
}
}
if (layoutUpdateRequired)
if (layoutUpdateRequired && parent)
parent->lastDrawPosition.dirty = 2;
if (resetStdTag)
@ -930,7 +941,6 @@ C4GuiWindow *C4GuiWindow::AddChild(C4GuiWindow *child)
{
child->SetID(GenerateMenuID());
child->isMainWindow = true;
//LogF("adding main window: %d [I am %d, root: %d]", child->GetID(), id, int(this == &::GuiWindowRoot));
}
// child's priority is ususally 0 here, so just insert it in front of other windows with a priority below 0
// when the child's priority updates, the update function will be called and the child will be sorted to the correct position
@ -1109,7 +1119,6 @@ void C4GuiWindow::EnableScrollBar(bool enable, float childrenHeight)
void C4GuiWindow::UpdateLayout()
{
//LogF("Updating Layout %p, root: %d, main: %d, style: %d", this, int(this == &::GuiWindowRoot), int(isMainWindow), props[C4GuiWindowPropertyName::style].GetInt());
const int32_t &style = props[C4GuiWindowPropertyName::style].GetInt();
// update scroll bar according to children
@ -1261,7 +1270,7 @@ bool C4GuiWindow::Draw(C4TargetFacet &cgo, int32_t player)
lastDrawPosition.dirty = 0;
// step one: draw all non-multiple windows
DrawChildren(cgo, player, leftDrawX - standardHorizontalBorder, topDrawY - standardVerticalBorder, rightDrawX + standardHorizontalBorder, bottomDrawY + standardVerticalBorder, 1);
DrawChildren(cgo, player, leftDrawX - left, topDrawY - top, rightDrawX + left, bottomDrawY + top, 1);
// TODO: adjust rectangle for main menu if multiple windows exist
// step two: draw one "main" menu
DrawChildren(cgo, player, leftDrawX, topDrawY, rightDrawX, bottomDrawY, 0);

View File

@ -227,7 +227,7 @@ class C4GuiWindow
// sets property value from possible(!) array
void SetArrayTupleProperty(const C4Value &property, C4GuiWindowPropertyName first, C4GuiWindowPropertyName second, C4String *tag);
// this is only supposed to be called at ::GuiWindowRoot since it uses the "ID" property
// this is only supposed to be called at ::Game.GuiWindowRoot since it uses the "ID" property
// this is done to make saving easier. Since IDs do not need to be sequential, action&menu IDs can both be derived from "id"
int32_t GenerateMenuID() { return ++id; }
int32_t GenerateActionID() { return ++id; }
@ -271,7 +271,7 @@ class C4GuiWindow
// pass a proplist to create a window + subwindows as specified
// you can call this function on a window more than once
// if isUpdate is true, all new children will have resetStdTag set
bool CreateFromPropList(C4PropList *proplist, bool resetStdTag = false, bool isUpdate = false);
bool CreateFromPropList(C4PropList *proplist, bool resetStdTag = false, bool isUpdate = false, bool isLoading = false);
// constructs a C4Value (proplist) that contains everything that is needed for saving this window
const C4Value ToC4Value();
@ -296,6 +296,4 @@ class C4GuiWindow
virtual bool MouseInput(int32_t player, int32_t button, int32_t mouseX, int32_t mouseY, DWORD dwKeyParam);
};
extern C4GuiWindow GuiWindowRoot;
#endif

View File

@ -326,7 +326,7 @@ void C4MouseControl::Move(int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyFl
// are custom menus active?
bool menuProcessed = false;
if (pPlayer)
menuProcessed = ::GuiWindowRoot.MouseInput(Player, iButton, iX, iY, dwKeyFlags);
menuProcessed = ::Game.GuiWindowRoot->MouseInput(Player, iButton, iX, iY, dwKeyFlags);
// if not caught by a menu
if (!menuProcessed)