/*
form.cpp
Copyright (C) 2007 Acekard, www.acekard.com
Copyright (C) 2007-2009 somebody
Copyright (C) 2009 yellow wood goblin
This program 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 3 of the License, or
(at your option) any later version.
This program 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 this program. If not, see .
*/
#include "ui.h"
#include "form.h"
#include "timer.h"
//#include "dbgtool.h"
//#include "windowmanager.h"
namespace akui {
cForm::cForm( s32 x, s32 y, u32 w, u32 h, cWindow * parent, const std::string & text )
:cWindow( parent, text )
//_renderDesc(NULL)
{
_size = cSize( w, h );
_position = cPoint( x, y );
_modalRet = -1;
}
cForm::~cForm()
{
//if( _renderDesc )
// delete _renderDesc;
}
cForm& cForm::addChildWindow(cWindow* aWindow)
{
_childWindows.push_back(aWindow);
aWindow->setPosition( _position + aWindow->relativePosition() );
//layouter_->addWindow(aWindow);
return *this;
}
cForm& cForm::removeChildWindow(cWindow* aWindow)
{
_childWindows.remove(aWindow);
//layouter_->removeWindow(aWindow);
return *this;
}
cForm& cForm::arrangeChildren()
{
std::list< cWindow * >::iterator it;
for(it = _childWindows.begin(); it != _childWindows.end(); ++it)
{
(*it)->setPosition( _position + (*it)->relativePosition() );
}
return *this;
}
void cForm::draw()
{
std::list< cWindow * >::iterator it;
for(it = _childWindows.begin(); it != _childWindows.end(); ++it)
{
(*it)->render();
}
}
bool cForm::process( const cMessage & msg )
{
dbg_printf("cForm::process\n" );
bool ret = false;
if(isVisible())
{
if( msg.id() > cMessage::touchMessageStart && msg.id() < cMessage::touchMessageEnd )
{
std::list< cWindow * >::iterator it;
for( it = _childWindows.begin(); it != _childWindows.end(); ++it)
{
cWindow * window = *it;
ret = window->process(msg);
if( ret ) {
dbg_printf("(%s) processed\n", window->text().c_str() );
break;
}
}
}
}
// NOTE: cForm does not translate key messages to children in this case
//if( !ret ) {
// dbg_printf("change child focus\n");
// if( msg.id() > cMessage::keyMessageStart && msg.id() < cMessage::keyMessageEnd ) {
// ret = processKeyMessage( (cKeyMessage &)msg );
// }
//}
if(!ret)
{
ret = cWindow::process(msg);
}
return ret;
}
bool cForm::processKeyMessage( const cKeyMessage & msg )
{
bool ret = false;
if( msg.id() == cMessage::keyDown ) {
if( msg.keyCode() >=5 && msg.keyCode() <= 8 ) {
std::list< cWindow * >::iterator it = _childWindows.begin();
for( it = _childWindows.begin(); it != _childWindows.end(); ++it)
{
cWindow * window = *it;
if( window->isFocused() ) {
if( msg.keyCode() == cKeyMessage::UI_KEY_DOWN || msg.keyCode() == cKeyMessage::UI_KEY_RIGHT ) {
++it;
if( it == _childWindows.end() )
it = _childWindows.begin();
if( (*it)->isVisible() ) {
windowManager().setFocusedWindow( (*it) );
ret = true;
break;
}
} else if( msg.keyCode() == cKeyMessage::UI_KEY_UP || msg.keyCode() == cKeyMessage::UI_KEY_LEFT ) {
if( it == _childWindows.begin() ){
it = _childWindows.end();
}
--it;
if( (*it)->isVisible() ) {
windowManager().setFocusedWindow( (*it) );
ret = true;
break;
}
}
}
}
if( _childWindows.end() == it ) {
if( _childWindows.front()->isVisible() ) {
windowManager().setFocusedWindow( _childWindows.front() );
ret = true;
}
}
}
}
return ret;
}
cWindow* cForm::windowBelow(const cPoint& p)
{
cWindow* ret = cWindow::windowBelow(p); // 先看自己在不在点下面
if(ret != 0)
{
std::list::reverse_iterator it;
for(it = _childWindows.rbegin(); it != _childWindows.rend(); ++it)
{
cWindow* window = *it;
cWindow* cw = window->windowBelow(p);
//dbg_printf( "check child (%s)\n", window->text().c_str() );
if(cw != 0)
{
ret = cw;
break;
}
}
}
return ret;
}
void cForm::onResize()
{
arrangeChildren();
}
void cForm::onMove()
{
arrangeChildren();
}
u32 cForm::modalRet()
{
return _modalRet;
}
u32 cForm::doModal()
{
windowManager().addWindow( this );
show();
do { // manually update system loop
timer().updateFps();
INPUT & inputs = updateInput();
processInput( inputs );
windowManager().update();
gdi().present( GE_MAIN );
//dbg_printf( "modal window looping\n" );
} while( modalRet() == (u32 )-1 );
windowManager().removeWindow( this );
return modalRet();
}
void cForm::onOK()
{
_modalRet = 1;
}
void cForm::onCancel()
{
_modalRet = 0;
}
void cForm::centerScreen()
{
_position.x = (SCREEN_WIDTH - _size.x) / 2;
_position.y = (SCREEN_HEIGHT - _size.y) / 2;
}
bool cForm::isActive(void) const
{
bool result=isFocused();
for(std::list::const_iterator it=_childWindows.begin();!result&&it!=_childWindows.end();++it)
{
result=result||(*it)->isFocused();
}
return result;
}
cWindow& cForm::disableFocus(void)
{
for(std::list::iterator it=_childWindows.begin();it!=_childWindows.end();++it)
{
(*it)->disableFocus();
}
return cWindow::disableFocus();
}
}