Files
2025-07-19 23:30:20 +02:00

241 lines
6.8 KiB
C++

/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "ui_local.h"
#include "../script/scriptexception.h"
Event EV_Layout_Menu
(
"menu",
EV_DEFAULT,
"sffsF",
"name width height direction motion_time",
"Sets up the layout of the menu."
);
CLASS_DECLARATION(Listener, UILayout, NULL) {
{&EV_Layout_Menu, &UILayout::CreateWidgetContainer},
{NULL, NULL }
};
UILayout::UILayout()
{
BogusFunction();
m_script = NULL;
m_filename = NULL;
}
UILayout::UILayout(const char *filename)
{
BogusFunction();
m_script = NULL;
m_filename = filename;
if (filename) {
Load(filename, true);
}
}
void UILayout::BogusFunction(void) {}
void UILayout::CreateWidgetContainer(Event *ev)
{
str name;
str direction;
float w, h;
name = ev->GetString(1);
if (!name.length()) {
return;
}
w = ev->GetFloat(2);
h = ev->GetFloat(3);
direction = ev->GetString(4);
m_currentcontainer = new UIWidgetContainer;
m_currentcontainer->setName(name);
if (!stricmp(direction, "from_bottom")) {
m_currentcontainer->setDirection(D_FROM_BOTTOM);
} else if (!stricmp(direction, "from_top")) {
m_currentcontainer->setDirection(D_FROM_TOP);
} else if (!stricmp(direction, "from_left")) {
m_currentcontainer->setDirection(D_FROM_LEFT);
} else if (!stricmp(direction, "from_right")) {
m_currentcontainer->setDirection(D_FROM_RIGHT);
} else {
m_currentcontainer->setDirection(D_NONE);
}
if (ev->NumArgs() > 4) {
m_currentcontainer->setMotionTime(ev->GetFloat(5));
}
m_currentcontainer->setAlwaysOnBottom(true);
m_currentcontainer->InitFrame(NULL, 0, 0, w, h);
m_currentcontainer->m_layout = this;
m_currentwidget = m_currentcontainer;
}
void UILayout::ProcessCommands(bool bFullLoad)
{
const char *token;
Event *ev;
UIWidget *widget;
str postinclude;
try {
while (m_script->TokenAvailable(true)) {
token = m_script->GetToken(true);
if (!strcmp(token, "end.")) {
break;
} else if (!strcmp(token, "include")) {
if (m_script->TokenAvailable(false)) {
m_scriptstack.Push(m_script);
Load(m_script->GetToken(false), bFullLoad);
m_script = m_scriptstack.Pop();
}
} else if (!strcmp(token, "postinclude")) {
if (m_script->TokenAvailable(false)) {
token = m_script->GetToken(false);
postinclude = token;
}
} else if (!strcmp(token, "resource")) {
ClassDef *cls;
str cl;
const char *newname;
token = m_script->GetToken(true);
// find the class resource
newname = uii.Client_TranslateWidgetName(token);
if (!newname) {
newname = token;
}
cl = "UI";
cl += newname;
cls = getClass(cl);
if (!cls) {
Com_Printf("Failed to find resource type '%s'\n", token);
break;
}
widget = (UIWidget *)cls->newInstance();
token = m_script->GetToken(true);
if (*token == '{') {
widget->InitFrame(m_currentcontainer, 0, 0, 128, 64, -1, "verdana-12");
if (m_currentcontainer->m_bVirtual) {
ev = new Event(EV_Layout_VirtualRes);
ev->AddInteger(1);
widget->ProcessEvent(ev);
}
token = m_script->GetToken(true);
while (1) {
if (!strcmp(token, "}")) {
break;
}
if (widget->ValidEvent(token)) {
ev = new Event(token);
while (m_script->TokenAvailable(false)) {
token = m_script->GetToken(false);
ev->AddToken(token);
}
widget->ProcessEvent(ev);
}
if (!m_script->TokenAvailable(true)) {
break;
}
token = m_script->GetToken(true);
}
}
} else {
if (ValidEvent(token)) {
ev = new Event(token);
while (m_script->TokenAvailable(false)) {
token = m_script->GetToken(false);
ev->AddToken(token);
}
ProcessEvent(ev);
} else if (m_currentwidget && m_currentwidget->ValidEvent(token)) {
ev = new Event(token);
while (m_script->TokenAvailable(false)) {
token = m_script->GetToken(false);
ev->AddToken(token);
}
m_currentwidget->ProcessEvent(ev);
}
}
}
} catch (ScriptException& exc) {
uii.Sys_Printf("UI EXCEPTION : %s\n", exc.string.c_str());
}
// process post-includes
if (postinclude.length()) {
m_scriptstack.Push(m_script);
Load(postinclude, bFullLoad);
m_script = m_scriptstack.Pop();
}
}
void UILayout::Load(const char *filename, bool bFullLoad)
{
m_bLoaded = true;
m_script = new Script;
m_script->LoadFile(filename);
ProcessCommands(bFullLoad);
m_bLoaded = bFullLoad;
delete m_script;
m_script = NULL;
}
int UILayout::ForceLoad(void)
{
if (m_bLoaded) {
return 0;
}
Load(m_filename, true);
return true;
}