eventeditor.cpp

Go to the documentation of this file.
00001 /*
00002      This file is part of Advanced Strategic Command; http://www.asc-hq.de
00003      Copyright (C) 1994-2010  Martin Bickel  and  Marc Schellenberger
00004  
00005      This program is free software; you can redistribute it and/or modify
00006      it under the terms of the GNU General Public License as published by
00007      the Free Software Foundation; either version 2 of the License, or
00008      (at your option) any later version.
00009  
00010      This program is distributed in the hope that it will be useful,
00011      but WITHOUT ANY WARRANTY; without even the implied warranty of
00012      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013      GNU General Public License for more details.
00014  
00015      You should have received a copy of the GNU General Public License
00016      along with this program; see the file COPYING. If not, write to the 
00017      Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
00018      Boston, MA  02111-1307  USA
00019 */
00020 
00021 
00022 #include <sstream>
00023 #include <pgimage.h>
00024 
00025 #include <pgpropertyeditor.h>
00026 #include <pgpropertyfield_integer.h>
00027 
00028 #include "eventeditor.h"
00029 #include "../paradialog.h"
00030 #include "../gamemap.h"
00031 #include "../spfst.h"
00032 #include "../gameeventsystem.h"
00033 #include "../gameevents.h"
00034 
00035 #include "../widgets/dropdownselector.h"
00036 #include "../widgets/multilistbox.h"
00037 
00038 class EventEditor : public ASC_PG_Dialog {
00039    private:
00040       vector<ASCString> triggerNames;
00041       vector<ASCString> actionNames;
00042 
00043       DropDownSelector* eventType;
00044       DropDownSelector* triggerConnection;
00045       PG_LineEdit* description;
00046       Event* event;
00047       bool result;
00048       PG_ListBox* playerlistbox;
00049       PG_PropertyEditor* properties;
00050 
00051       GameMap* gamemap;
00052       
00053       bool setupEvent()
00054       {
00055          if ( event->action )
00056             event->action->setup();
00057          return true;
00058       }
00059 
00060       void actionSelected( int i )
00061       {
00062          if ( i < 0 )
00063             return;
00064 
00065          EventActionID eai = eventActionFactory::Instance().getID( actionNames.at(i) );
00066 
00067          if ( !event->action )
00068             event->spawnAction( eai );
00069          else
00070             if ( event->action->getActionID() != eai ) {
00071                delete event->action;
00072                event->action = NULL;
00073                event->spawnAction( eai );
00074             }
00075 
00076          event->action->setup();
00077       }
00078 
00079       bool setupTrigger( int num )
00080       {
00081          if ( event->trigger.size() > num )
00082             if ( event->trigger[num] )
00083                event->trigger[num]->setup();
00084          
00085          return true;
00086       }
00087 
00088       void triggerSelected( int type, int num )
00089       {
00090          if ( type>= 0 ) {
00091             EventTriggerID triggerID = eventTriggerFactory::Instance().getID(  triggerNames.at(type) );
00092 
00093             if ( event->trigger.size() <= num ) {
00094                int oldSize = event->trigger.size();
00095                event->trigger.resize(num+1);
00096                for ( int i = oldSize; i < event->trigger.size(); ++i )
00097                   if ( i != num )
00098                      event->trigger[i] = event->spawnTrigger( Trigger_NothingFalse );
00099 
00100                event->trigger[num] = event->spawnTrigger( triggerID );
00101                event->trigger[num]->setup();
00102             } else {
00103                if ( event->trigger[num]->getTriggerID() == triggerID )
00104                   event->trigger[num]->setup();
00105                else {
00106                   delete event->trigger[num];
00107                   event->trigger[num] = event->spawnTrigger( triggerID );
00108                   event->trigger[num]->setup();
00109                }
00110             }
00111          }
00112       }
00113       
00114       bool invertTrigger( bool invert, int e )
00115       {
00116          if ( event->trigger.size() > e ) {
00117             event->trigger[e]->invert = invert;
00118             return true;
00119          } else
00120             return false;
00121       }
00122       
00123 
00124       bool ok()
00125       {
00126          if ( !properties->Apply() )
00127             return false;
00128 
00129          if ( event->trigger.size() < 1 ) {
00130             warningMessage( "no trigger defined !" );
00131             return false;
00132          }
00133          
00134          if ( !event->action ) {
00135             warningMessage ( "no action defined !" );
00136             return false;
00137          }
00138          if ( event->reArmNum && event->delayedexecution.turn < 1 ) {
00139             warningMessage ( "without delayed execution, reArming the event makes no sense !" );
00140             return false;
00141          }
00142 
00143          event->description = description->GetText();
00144 
00145          if ( triggerConnection->GetSelectedItemIndex() == 0 )
00146             event->triggerConnection = Event::AND;
00147          else
00148             event->triggerConnection = Event::OR;
00149 
00150          event->playerBitmap = 0;
00151          for ( int i = 0; i < playerlistbox->GetWidgetCount(); ++i ) {
00152             PG_ListBoxBaseItem* bi = dynamic_cast<PG_ListBoxBaseItem*>(playerlistbox->FindWidget(i));
00153             if ( bi && bi->IsSelected() )
00154                event->playerBitmap |= 1 << i;
00155          }
00156 
00157          result = true;
00158          QuitModal();
00159          
00160          return true;
00161       }
00162       
00163    public:
00164       EventEditor( GameMap* actmap, Event* event ) : ASC_PG_Dialog( NULL, PG_Rect( -1, -1, 700, 500 ), "Edit Event" ), result(false), gamemap(actmap)
00165       {
00166          this->event = event;
00167 
00168          int labelWidth = 80;
00169          int ypos = 30;
00170          
00171          new PG_Label( this, PG_Rect( 10, ypos, labelWidth, 25 ), "Action:" );
00172 
00173          triggerNames = eventTriggerFactory::Instance().getNames();
00174          actionNames = eventActionFactory::Instance().getNames();
00175 
00176          eventType = new DropDownSelector( this, PG_Rect( labelWidth+30, ypos, 300, 25 ), actionNames );
00177          if ( event->action ) 
00178             for ( int i = 0; i < actionNames.size(); ++i )
00179                if ( event->action->getName() == actionNames[i] )
00180                   eventType->SelectItem ( i );
00181 
00182          eventType->selectionSignal.connect( SigC::slot( *this, &EventEditor::actionSelected ));
00183          (new PG_Button( this, PG_Rect( labelWidth + 50 + 300, ypos, 100, 25 ), "setup"))->sigClick.connect( SigC::slot( *this, &EventEditor::setupEvent ));
00184          ypos += 40;
00185 
00186          new PG_Label( this, PG_Rect( 10, ypos, labelWidth, 25 ), "Description:" );
00187          description = new PG_LineEdit( this, PG_Rect( labelWidth+30, ypos, 420, 25 ) );
00188          description->SetText( event->description );
00189          ypos += 40;
00190 
00191          for ( int e = 0; e < 4; ++e ) {
00192             new PG_Label( this, PG_Rect( 10, ypos, labelWidth, 25), "Trigger " + ASCString::toString(e));
00193             
00194             DropDownSelector* trigger = new DropDownSelector( this, PG_Rect( labelWidth+30, ypos, 200,25 ), triggerNames );
00195                  
00196             (new PG_Button( this, PG_Rect( labelWidth+50+200, ypos, 100, 25 ), "setup"))->sigClick.connect( SigC::bind( SigC::slot( *this, &EventEditor::setupTrigger ), e));
00197             
00198             PG_CheckButton* inv = new PG_CheckButton( this, PG_Rect( labelWidth+70+300, ypos, 100, 25 ), "invert");
00199             inv->sigClick.connect( SigC::bind( SigC::slot( *this, &EventEditor::invertTrigger ), e));
00200             if ( event->trigger.size() > e ) {
00201                if ( event->trigger[e]->invert )
00202                   inv->SetPressed();
00203 
00204                for ( int i = 0; i < triggerNames.size(); ++i )
00205                   if ( event->trigger[e]->getTypeName() == triggerNames[i] )
00206                      trigger->SelectItem ( i );
00207             } else
00208                for ( int i = 0; i < triggerNames.size(); ++i )
00209                   if ( triggerNames[i] == "Nothing (always false)"  )
00210                      trigger->SelectItem ( i );
00211                
00212             trigger->selectionSignal.connect( SigC::bind( SigC::slot( *this, &EventEditor::triggerSelected), e ));
00213             ypos += 40;
00214          }
00215 
00216          new PG_Label( this, PG_Rect( 10, ypos, labelWidth, 25 ), "Players:" );
00217          playerlistbox = (new MultiListBox( this, PG_Rect( labelWidth+30, ypos, 150, 160 )))->getListBox();
00218          for ( int i = 0; i < event->getMap()->getPlayerCount(); ++i ) {
00219             PG_ListBoxItem* item;
00220             if ( gamemap->player[i].exist() )
00221                item = new PG_ListBoxItem( playerlistbox, 20, event->getMap()->player[i].getName() );
00222             else
00223                item = new PG_ListBoxItem( playerlistbox, 20, "inactive player " + ASCString::toString(i) );
00224             
00225             if ( event->playerBitmap & (1 << i))
00226                item->Select();
00227          }
00228 
00229          properties = new PG_PropertyEditor( this, PG_Rect( labelWidth + 80 + 160, ypos, 150, 160 ));
00230          new PG_PropertyField_Integer<int>( properties, "Rearm Num", &event->reArmNum );
00231          new PG_PropertyField_Integer<int>( properties, "Offset Turn", &event->delayedexecution.turn );
00232          new PG_PropertyField_Integer<int>( properties, "Offset Move", &event->delayedexecution.move );
00233          ypos += 200;
00234          
00235 
00236          new PG_Label( this, PG_Rect( 10, ypos, labelWidth, 25 ), "Logic:" );
00237          static const char* connectionNames[2] = {"all trigger must be triggered", "only one trigger must be triggered" };
00238          triggerConnection = new DropDownSelector( this, PG_Rect( labelWidth+30, ypos, 300, 25 ), 2, connectionNames );
00239          if ( event->triggerConnection == Event::AND )
00240             triggerConnection->SelectItem( 0 );
00241          else
00242             triggerConnection->SelectItem( 1 );
00243          ypos += 40;
00244 
00245          
00246          AddStandardButton ( "Cancel" )->sigClick.connect( SigC::slot( *this, &EventEditor::QuitModal ));
00247          AddStandardButton ( "OK" )->sigClick.connect( SigC::slot( *this, &EventEditor::ok ));
00248          
00249       };
00250 
00251       bool GetResult()
00252       {
00253          return result;
00254       }
00255 };
00256 
00257 
00258 
00259 
00260 
00261 bool   createevent( GameMap* gamemap, Event* event ) 
00262 {
00263    EventEditor ee ( gamemap, event );
00264    ee.Show();
00265    ee.RunModal();
00266    return ee.GetResult();
00267 }
00268 
00269 // �S EventSel
00270 
00271 
00272 class EventList : public ASC_PG_Dialog {
00273    private:
00274       GameMap* gamemap;
00275       
00276       bool ButtonNew()
00277       {
00278          Event* ev = new Event(*gamemap);
00279          if ( !createevent( gamemap, ev ) ) {
00280             delete ev;
00281             return true;
00282          }
00283 
00284          gamemap->events.push_back( ev );
00285 
00286          updateListbox();
00287          return true;
00288       }
00289 
00290       bool ButtonDelete()
00291       {
00292          int marked = listbox->GetSelectedIndex();
00293          if ( marked < 0 )
00294             return false;
00295          
00296          GameMap::Events::iterator e = gamemap->events.begin();
00297          for ( int t = 0; t < marked && e != gamemap->events.end(); t++ )
00298             ++e;
00299 
00300          if ( e != gamemap->events.end() ) {
00301             delete *e;
00302             gamemap->events.erase ( e );
00303             updateListbox();
00304          }
00305          
00306          return true;
00307       }
00308 
00309       bool ButtonEdit()
00310       {
00311          if ( gamemap->events.size() ) {
00312             MemoryStreamStorage buf;
00313             
00314 
00315             int marked = listbox->GetSelectedIndex();
00316             if ( marked < 0 )
00317                return false;
00318             
00319             GameMap::Events::iterator e = gamemap->events.begin();
00320             for ( int t = 0; t < marked && e != gamemap->events.end(); t++ )
00321                ++e;
00322 
00323             {
00324                MemoryStream stream ( &buf, tnstream::writing );
00325                (*e)->write ( stream );
00326             }
00327 
00328             if ( ! createevent( gamemap, *e ) ) {
00329                      // cancel pressed, we are restoring the original event
00330                MemoryStream stream ( &buf, tnstream::reading );
00331                (*e)->read ( stream );
00332             }
00333 
00334             updateListbox();
00335             return true;
00336          } else
00337             return false;
00338          
00339       }
00340       
00341       bool ButtonOK()
00342       {
00343          QuitModal();
00344          return true;
00345       }
00346       
00347       PG_ListBox* listbox;
00348 
00349 
00350       void updateListbox()
00351       {
00352          listbox->DeleteAll();
00353          for ( GameMap::Events::iterator i = gamemap->events.begin(); i != gamemap->events.end(); ++i ) {
00354             ASCString text = (*i)->action->getName();
00355             text += " - " + (*i)->description;
00356             
00357             new PG_ListBoxItem( listbox, 20, text );
00358          }
00359          listbox->Update();
00360       }
00361 
00362       
00363       
00364    public:
00365       EventList( GameMap* gameMap) : ASC_PG_Dialog( NULL, PG_Rect( -1, -1, 600, 400 ), "Edit Events" ) , gamemap ( gameMap )
00366       {
00367          int w = 500;
00368          PG_Button* b = new PG_Button( this, PG_Rect ( w, 40, 90, 25 ), "~N~ew" );
00369          b->sigClick.connect( SigC::slot( *this, &EventList::ButtonNew ));
00370 
00371          b = new PG_Button( this, PG_Rect ( w, 80, 90, 25 ), "~E~dit" );
00372          b->sigClick.connect( SigC::slot( *this, &EventList::ButtonEdit ));
00373          
00374          b = new PG_Button( this, PG_Rect ( w, 120, 90, 25 ), "~D~elete" );
00375          b->sigClick.connect( SigC::slot( *this, &EventList::ButtonDelete ));
00376          
00377          b = new PG_Button( this, PG_Rect ( w, 160, 90, 25 ), "~O~K" );
00378          b->sigClick.connect( SigC::slot( *this, &EventList::ButtonOK ));
00379          
00380 
00381          listbox = new PG_ListBox( this, PG_Rect( 20, 40, w - 30, Height()-50 ));
00382          listbox->SetTransparency(255);
00383          updateListbox();
00384       };
00385 
00386 };
00387 
00388 
00389 void    eventEditor( GameMap* gamemap )
00390 {
00391    EventList    te ( gamemap );
00392    te.Show();
00393    te.RunModal();
00394 }
00395 
00396 

Generated on Mon May 21 01:26:32 2012 for Advanced Strategic Command by  doxygen 1.5.1