openmohaa/code/uilib/uilayout.cpp

297 lines
5.6 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 "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 );
}
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 );
assert( cls );
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( widget->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;
}