dashboard.cpp

Go to the documentation of this file.
00001 
00006 /***************************************************************************
00007                           dashboard.cpp  -  description
00008                              -------------------
00009     begin                : Sat Jan 27 2001
00010     copyright            : (C) 2001 by Martin Bickel
00011     email                : bickel@asc-hq.org
00012  ***************************************************************************/
00013 
00014 /***************************************************************************
00015  *                                                                         *
00016  *   This program is free software; you can redistribute it and/or modify  *
00017  *   it under the terms of the GNU General Public License as published by  *
00018  *   the Free Software Foundation; either version 2 of the License, or     *
00019  *   (at your option) any later version.                                   *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023  #include "sigc++/retype.h"
00024 
00025 #include "dashboard.h"
00026 #include "graphics/blitter.h"
00027 #include "graphics/drawing.h"
00028 #include "gamemap.h"
00029 #include "iconrepository.h"
00030 #include "spfst.h"
00031 #include "pgimage.h"
00032 #include "textfiletags.h"
00033 #include "mapdisplay.h"
00034 #include "dialogs/unitinfodialog.h"
00035 #include "dialogs/vehicletypeselector.h"
00036 #include "gameoptions.h"
00037 #include "graphics/ColorTransform_PlayerColor.h"
00038 #include "dialogs/unitnaming.h"
00039 #include "actions/actioncontainer.h"
00040 #include "widgets/textrenderer.h"
00041 
00042 #include "sg.h"
00043 #include "spfst-legacy.h"
00044 #include "actions/renamecontainercommand.h"
00045 
00046 class WeaponInfoLine;
00047 
00048 class WeaponInfoPanel : public Panel {
00049         int weaponCount;
00050         static ASCString name;
00051 
00052         vector<WeaponInfoLine*> weaponInfoLines;
00053 
00054      protected:
00055         bool onClick ( PG_MessageObject* obj, const SDL_MouseButtonEvent* event );
00056         void painter ( const PG_Rect &src, const ASCString& name, const PG_Rect &dst);
00057 
00058              bool eventMouseMotion(const SDL_MouseMotionEvent* motion);
00059 
00060      public:
00061         WeaponInfoPanel (PG_Widget *parent, const Vehicle* veh, const VehicleType* vt ) ;
00062         void showWeapon( const SingleWeapon* weap = NULL );
00063 
00064         // virtual bool   eventMouseButtonDown (const SDL_MouseButtonEvent *button);
00065         bool   eventMouseButtonUp (const SDL_MouseButtonEvent *button);
00066         
00067         static const ASCString& WIP_Name();
00068         // void eval();
00069 };
00070 
00071 
00072 
00073 class ExperienceOverview : public PG_Widget {
00074       static const int columns = 4;
00075    protected:
00076       bool      eventMouseButtonUp (const SDL_MouseButtonEvent *button)
00077       {
00078          QuitModal();
00079          return true;
00080       };
00081 
00082       static PG_Rect getSize( const PG_Point& pos )
00083       {
00084          const Surface& s = IconRepository::getIcon("experience0.png");
00085          return PG_Rect( pos.x, pos.y, columns * s.w(), (maxunitexperience + columns-1)/columns * s.h() );
00086       }
00087       
00088    public:
00089       ExperienceOverview( const PG_Point& pos, int exp = -1 ) : PG_Widget( NULL, getSize(pos), true )
00090       {
00091          // PG_Application::GetApp()->sigMouseButtonUp.connect( SigC::slot( *this, &ExperienceOverview::QuitModal ));
00092       }
00093 
00094 
00095       int RunModal()
00096       {
00097          SetCapture();
00098          return PG_Widget::RunModal();
00099       }
00100 
00101       void      eventDraw (SDL_Surface *surface, const PG_Rect &rect) 
00102       {
00103          const Surface& s = IconRepository::getIcon("experience0.png");
00104          int width = s.w();
00105          int height = s.h();
00106 
00107          Surface s2 = Surface::Wrap( surface );
00108          for ( int i = 0; i <= maxunitexperience; ++i ) 
00109             s2.Blit( IconRepository::getIcon("experience" + ASCString::toString(i) + ".png"), SPoint( i % columns * width , i/columns*height) );
00110       }
00111 };
00112 
00113 DashboardPanel::DashboardPanel ( PG_Widget *parent, const PG_Rect &r, const ASCString& panelName_, bool loadTheme = true )
00114    :LayoutablePanel ( parent, r, panelName_, loadTheme ), veh(NULL), bld(NULL)
00115 {
00116    updateFieldInfo.connect ( SigC::slot( *this, &DashboardPanel::eval ));
00117    registerSpecialDisplay( "windarrow" );
00118 
00119    registerSpecialDisplay( "unitexp" );
00120    registerSpecialDisplay( "unit_level" );
00121    registerSpecialDisplay( "unit_pic" );
00122    for ( int i = 0; i < 10; ++i)
00123       registerSpecialDisplay( "symbol_weapon" + ASCString::toString(i) );
00124    registerSpecialDisplay( "showplayercolor0" );
00125    registerSpecialDisplay( "showplayercolor1" );
00126    registerSpecialDisplay( "field_weather" );
00127 
00128    ContainerBase::anyContainerDestroyed.connect( SigC::slot( *this, &DashboardPanel::containerDeleted ));
00129    
00130    GameMap::sigMapDeletion.connect( SigC::slot( *this, &DashboardPanel::reset ));
00131 
00132    PG_Widget* w = parent->FindChild( "unitexp", true );
00133    if ( w )
00134       w->sigMouseButtonDown.connect( SigC::slot( *this, &DashboardPanel::viewExperienceOverview ));
00135 };
00136 
00137 bool DashboardPanel::viewExperienceOverview()
00138 {
00139    PG_Widget* w = GetParent()->FindChild( "unitexp", true );
00140    if ( w ) {
00141       ExperienceOverview eo(PG_Point( w->my_xpos, w->my_ypos ));
00142       eo.Show();
00143       eo.RunModal();
00144       return true;
00145    } else
00146       return false;
00147 }
00148 
00149 
00150 void DashboardPanel::containerDeleted( ContainerBase* c )
00151 {
00152    if ( c == veh )
00153       veh = NULL;
00154    
00155    if ( c == bld )
00156       bld = NULL;
00157 }
00158 
00159 
00160 bool DashboardPanel::containerRenamed( PG_LineEdit* lineEdit )
00161 {
00162    if ( veh ) {
00163       if ( veh->getMap()->actplayer == veh->getOwner() )
00164          veh->name = lineEdit->GetText();
00165       else
00166          lineEdit->SetText( veh->name );
00167    }
00168    
00169    if ( bld ) {
00170       if ( bld->getMap()->actplayer == bld->getOwner() )
00171          bld->name = lineEdit->GetText();
00172       else
00173          lineEdit->SetText( bld->name );
00174    }
00175 
00176    return true;
00177 }
00178 
00179 void DashboardPanel::reset(GameMap& map)
00180 {
00181    if ( veh && veh->getMap() == &map )
00182       veh = NULL;
00183    
00184    if ( bld && bld->getMap() == &map )
00185       bld = NULL;
00186 }
00187 
00188 
00189 
00190 void DashboardPanel::registerSpecialDisplay( const ASCString& name )
00191 {
00192    SpecialDisplayWidget* sdw = dynamic_cast<SpecialDisplayWidget*>( FindChild( name, true ) );
00193    if ( sdw )
00194      sdw->display.connect( SigC::slot( *this, &DashboardPanel::painter ));
00195 }
00196 
00197 
00198 void DashboardPanel::painter ( const PG_Rect &src, const ASCString& name, const PG_Rect &dst)
00199 {
00200    if ( !actmap || actmap->actplayer < 0 || actmap->actplayer > 8  )
00201       return;
00202 
00203    Surface screen = Surface::Wrap( PG_Application::GetScreen() );
00204 
00205    if ( name == "windarrow" ) {
00206       if ( actmap && actmap->weather.windSpeed > 0 ) {
00207          MegaBlitter<4,colorDepth,ColorTransform_None, ColorMerger_AlphaOverwrite, SourcePixelSelector_DirectRotation> blitter;
00208          blitter.setAngle( (6 - actmap->weather.windDirection) * (360 /6));
00209          blitter.blit ( IconRepository::getIcon("wind-arrow.png"), screen, SPoint(dst.x, dst.y) );
00210       }
00211       return;
00212    }
00213 
00214    if( name == "showplayercolor0" || name == "showplayercolor1" ) {
00215       MegaBlitter<4,4,ColorTransform_PlayerTrueCol,ColorMerger_PlainOverwrite> blitter;
00216       blitter.setColor( actmap->player[actmap->actplayer].getColor() );
00217       // blitter.setPlayer(actmap->actplayer);
00218       blitter.blit( IconRepository::getIcon("show_playercolor.png"), screen, SPoint(dst.x, dst.y));
00219       return;
00220    }
00221    
00222    
00223    if ( name == "field_weather" ) {
00224       MapCoordinate mc = actmap->getCursor();
00225       if ( actmap && mc.valid() && fieldvisiblenow( actmap->getField(mc), actmap->getPlayerView() ) ) {
00226          MegaBlitter<4,colorDepth,ColorTransform_None, ColorMerger_AlphaOverwrite> blitter;
00227 
00228          static const char* weathernames[] = {"terrain_weather_dry.png",
00229                                               "terrain_weather_lightrain.png",
00230                                               "terrain_weather_heavyrain.png",
00231                                               "terrain_weather_lightsnow.png",
00232                                               "terrain_weather_heavysnow.png",
00233                                               "terrain_weather_ice.png" };
00234 
00235          blitter.blit ( IconRepository::getIcon(weathernames[actmap->getField(mc)->getWeather()]), screen, SPoint(dst.x, dst.y) );
00236       }
00237       return;
00238    }
00239 
00240 
00241 
00242 
00243    
00244    if ( veh && !fieldvisiblenow( veh->getMap()->getField( veh->getPosition() ), veh->getMap()->getPlayerView() ))
00245       return;
00246    
00247 
00248 
00249       if ( name == "unitexp" ) {
00250          int experience = 0;
00251          if ( veh )
00252             experience = veh->experience;
00253 
00254          screen.Blit( IconRepository::getIcon("experience" + ASCString::toString(experience) + ".png"), SPoint(dst.x, dst.y) );
00255       }
00256 
00257       if ( name == "unit_level" ) {
00258          int height1 = 0;
00259          int height2 = 0;
00260          int player = actmap->actplayer;
00261          if ( veh ) {
00262             height1 = veh->height;
00263             height2 = veh->typ->height;
00264             player = veh->getOwner();
00265          }
00266 
00267          for ( int i = 0; i < 8; ++i ) {
00268             if ( height1 & (1 << i )) {
00269                MegaBlitter<4,4,ColorTransform_PlayerTrueCol,ColorMerger_PlainOverwrite> blitter;
00270                blitter.setColor( actmap->player[player].getColor() );
00271                // blitter.setPlayer( player );
00272                blitter.blit( IconRepository::getIcon("height-b" + ASCString::toString(i) + ".png"), screen, SPoint(dst.x, dst.y + (7-i) * 13));
00273             } else
00274                if ( height2 & (1 << i ))
00275                   screen.Blit( IconRepository::getIcon("height-a" + ASCString::toString(i) + ".png"), SPoint(dst.x, dst.y + (7-i) * 13 ) );
00276 
00277          }
00278       }
00279 
00280       if ( name == "unit_pic" ) {
00281          if ( veh )
00282            veh->typ->paint( screen, SPoint( dst.x, dst.y ), veh->getOwningPlayer().getPlayerColor() );
00283       }
00284 
00285       if ( veh ) {
00286          int pos = 0;
00287          for ( int i = 0; i < veh->typ->weapons.count; ++i) {
00288             if ( !veh->typ->weapons.weapon[i].service() && pos < 10 ) {
00289                if ( name == "symbol_weapon" + ASCString::toString(pos) )
00290                   screen.Blit( IconRepository::getIcon(SingleWeapon::getIconFileName( veh->typ->weapons.weapon[i].getScalarWeaponType()) + "-small.png"), SPoint(dst.x, dst.y));
00291 
00292                ++pos;
00293              }
00294           }
00295       }
00296 
00297 }
00298 
00299 
00300 void DashboardPanel::eval()
00301 {
00302    if ( !actmap || actmap->actplayer < 0 )
00303       return;
00304 
00305 
00306    MapCoordinate mc = actmap->player[actmap->actplayer].cursorPos;
00307    MapField* fld = actmap->getField(mc);
00308 
00309    Vehicle* veh = fld? fld->vehicle : NULL;
00310 
00311    BulkGraphicUpdates bgu( this );
00312 
00313    setBargraphValue( "winddisplay", float(actmap->weather.windSpeed ) / 255  );
00314 
00315    setLabelText( "windspeed", actmap->weather.windSpeed );
00316 
00317    if ( fld && mc.valid() && fieldvisiblenow( fld, actmap->getPlayerView() )) {
00318       setLabelText( "terrain_harbour", fld->bdt.test(cbharbour) ? "YES" : "NO" );
00319       setLabelText( "terrain_pipe", fld->bdt.test(cbpipeline) || fld->building ? "YES" : "NO" );
00320 
00321       setLabelText( "terrain_defencebonus", fld->getdefensebonus() );
00322       setLabelText( "terrain_attackbonus", fld->getattackbonus() );
00323       setLabelText( "terrain_jam", fld->getjamming() );
00324       setLabelText( "terrain_name", fld->typ->terraintype->name );
00325 
00326       int unitspeed;
00327       if ( veh )
00328          unitspeed = getmaxwindspeedforunit ( veh );
00329       else
00330          unitspeed = maxint;
00331 
00332        int windspeed = actmap->weather.windSpeed*maxwindspeed ;
00333        if ( unitspeed < 255*256 ) {
00334           if ( windspeed > unitspeed*9/10 )
00335              setBarGraphColor( "winddisplay", 0xff0000  );
00336           else
00337              if ( windspeed > unitspeed*66/100 )
00338                 setBarGraphColor( "winddisplay", 0xffff00  );
00339              else
00340                 setBarGraphColor( "winddisplay", 0x00ff00  );
00341        } else
00342           setBarGraphColor( "winddisplay", 0x00ff00  );
00343 
00344    } else {
00345       setLabelText( "terrain_harbour", "" );
00346       setLabelText( "terrain_pipe", "" );
00347 
00348       setLabelText( "terrain_defencebonus", "" );
00349       setLabelText( "terrain_attackbonus", "" );
00350       setLabelText( "terrain_jam", "" );
00351       setLabelText( "terrain_name", "" );
00352       setBarGraphColor( "winddisplay", 0x00ff00  );
00353    }
00354 
00355    if ( mc.valid() && fld ) {
00356       if ( veh && fieldvisiblenow( fld, actmap->getPlayerView() ) ) {
00357          showUnitData( veh, NULL, fld );
00358       } else {
00359 
00360          Building* bld = fld->building;
00361          if ( bld && fieldvisiblenow( fld, actmap->getPlayerView() ) ) 
00362             showUnitData( NULL, bld, fld );
00363          else
00364             showUnitData( NULL, NULL, fld );
00365       }
00366    }
00367 
00368    // PG_Application::SetBulkMode(false);
00369    // Redraw(true);
00370 }
00371 void DashboardPanel::showUnitData( Vehicle* veh, Building* bld, MapField* fld,  bool redraw )
00372 {
00373    int weaponsDisplayed = 0;
00374    this->veh = veh;
00375    this->bld = bld;
00376    
00377    bool bulk = PG_Application::GetBulkMode();
00378    if ( redraw )
00379       PG_Application::SetBulkMode(true);
00380       
00381 
00382    if ( veh ) {
00383       setLabelText( "unittypename", veh->typ->name );
00384       
00385       if ( !veh->privateName.empty() && veh->getOwner() == veh->getMap()->getPlayerView() ) 
00386          setLabelText( "unitname", ">" + veh->privateName + "<" );
00387       else if ( !veh->name.empty() )
00388          setLabelText( "unitname", veh->name );
00389       else
00390          setLabelText( "unitname", veh->typ->description );
00391       
00392       
00393       setBargraphValue( "unitdamage", float(100-veh->damage) / 100  );
00394       setLabelText( "unitstatus", 100-veh->damage );
00395 
00396       setBargraphValue( "unitfuel", veh->getStorageCapacity().fuel ? float( veh->getTank().fuel) / veh->getStorageCapacity().fuel : 0  );
00397       setLabelText( "unitfuelstatus", veh->getTank().fuel );
00398       setBargraphValue( "unitmaterial", veh->getStorageCapacity().material ? float( veh->getTank().material) / veh->getStorageCapacity().material : 0  );
00399       setLabelText( "unitmaterialstatus", veh->getTank().material );
00400       setBargraphValue( "unitenergy", veh->getStorageCapacity().energy ? float( veh->getTank().energy) / veh->getStorageCapacity().energy : 0  );
00401       setLabelText( "unitenergystatus", veh->getTank().energy );
00402 
00403       int endurance = UnitHooveringLogic::getEndurance( veh );
00404       if ( endurance >= 0 )
00405          setLabelText( "unitEndurance", endurance );
00406       else
00407          setLabelText( "unitEndurance", "-" );
00408 
00409 
00410       ASCString moveString = ASCString::toString( veh->getMovement() / 10 );
00411       if ( veh->getMovement() % 10 )
00412          moveString += "." + ASCString::toString(veh->getMovement()%10);
00413 
00414       setLabelText( "movepoints", moveString );
00415 
00416       if ( veh->typ->fuelConsumption )
00417          setLabelText( "fuelrange", veh->getTank().fuel / veh->typ->fuelConsumption );
00418       else
00419          setLabelText( "fuelrange", "-" );
00420 
00421       setLabelText( "armor", veh->typ->armor );
00422 
00423       int &pos = weaponsDisplayed;
00424       for ( int i = 0; i < veh->typ->weapons.count; ++i) {
00425          if ( !veh->typ->weapons.weapon[i].service() && pos < 10 ) {
00426             ASCString ps = ASCString::toString(pos);
00427             setLabelText( "punch_weapon" + ps, veh->typ->weapons.weapon[i].maxstrength );
00428             if ( veh->typ->hasFunction( ContainerBaseType::NoReactionfire  ) || !veh->typ->weapons.weapon[i].shootable() || veh->typ->weapons.weapon[i].getScalarWeaponType() == cwminen )
00429                setLabelText( "RF_weapon" + ps, "-" );
00430             else
00431                setLabelText( "RF_weapon" + ps, veh->typ->weapons.weapon[i].reactionFireShots );
00432             setLabelText( "status_ammo" + ps, veh->ammo[i] );
00433             setBargraphValue( "bar_ammo" + ps, veh->typ->weapons.weapon[i].count ? float(veh->ammo[i]) / veh->typ->weapons.weapon[i].count : 0 );
00434             ++pos;
00435          }
00436       }
00437       
00438       if ( veh->typ->infoImageSmallFilename.length() > 0 ) {
00439          setImage( "Selected3DImageSmall", veh->typ->infoImageSmallFilename, this );
00440          show( "Selected3DImageSmall" );
00441       } else
00442          hide( "Selected3DImageSmall" );
00443       
00444    } else {
00445       if ( bld ) {
00446          setLabelText( "unittypename", bld->typ->name );
00447          
00448          if ( !bld->privateName.empty() && bld->getOwner() == bld->getMap()->getPlayerView()) 
00449             setLabelText( "unitname", ">" + bld->privateName + "<" );
00450          else 
00451             setLabelText( "unitname", bld->name );
00452          
00453          setBargraphValue( "unitdamage", float(100-bld->damage) / 100  );
00454          setLabelText( "unitstatus", 100-bld->damage );
00455          setLabelText( "armor", bld->getArmor() );
00456 
00457          if ( 0 ) {
00458             setLabelText( "unitfuelstatus", bld->getAvailableResource(maxint,2) );
00459             setLabelText( "unitmaterialstatus", bld->getAvailableResource(maxint,1) );
00460             setLabelText( "unitenergystatus", bld->getAvailableResource(maxint,0) );
00461          } else {
00462             setLabelText( "unitfuelstatus", "" );
00463             setLabelText( "unitmaterialstatus", "" );
00464             setLabelText( "unitenergystatus", "" );
00465          }
00466 
00467 
00468       } else {
00469          setLabelText( "armor", "" );
00470          setLabelText( "unittypename", "" );
00471          setLabelText( "unitname", "" );
00472          bool objectFound = false;
00473          if ( fld && fld->objects.size() && fieldvisiblenow( fld )) {
00474             for ( MapField::ObjectContainer::iterator i = fld->objects.begin(); i != fld->objects.end(); ++i )
00475                if ( i->typ->armor > 0 ) {
00476                   setBargraphValue( "unitdamage", float(100-i->damage) / 100  );
00477                   objectFound = true;
00478                   break;
00479                }
00480          } 
00481          if ( !objectFound ) 
00482             setBargraphValue( "unitdamage", 0  );
00483          setLabelText( "unitstatus", "" );
00484 
00485          setLabelText( "unitfuelstatus", "" );
00486          setLabelText( "unitmaterialstatus", "" );
00487          setLabelText( "unitenergystatus", "" );
00488 
00489       }
00490 
00491       setBargraphValue( "unitfuel", 0  );
00492       setBargraphValue( "unitmaterial",  0  );
00493       setBargraphValue( "unitenergy",  0  );
00494       setLabelText( "unitEndurance", "" );
00495 
00496       setLabelText( "fuelrange", "-" );
00497       setLabelText( "movepoints", "" );
00498       hide( "Selected3DImageSmall" );
00499    }
00500    for ( int i = weaponsDisplayed; i < 10; ++i ) {
00501       ASCString ps = ASCString::toString(i);
00502       setLabelText( "punch_weapon" + ps, "" );
00503       setLabelText( "RF_weapon" + ps, "" );
00504       setLabelText( "status_ammo" + ps, "" );
00505       setBargraphValue( "bar_ammo" + ps, 0 );
00506    }
00507    
00508    if ( redraw ) {
00509       if ( !bulk )
00510          PG_Application::SetBulkMode(false);
00511       Redraw(true);
00512    }
00513 }
00514 
00515 
00516 
00517 WindInfoPanel::WindInfoPanel (PG_Widget *parent, const PG_Rect &r ) : DashboardPanel( parent, r, "WindInfo" )
00518 {
00519 }
00520 
00521 
00522 
00523 
00524 UnitInfoPanel::UnitInfoPanel (PG_Widget *parent, const PG_Rect &r ) : DashboardPanel( parent, r, "UnitInfo" )
00525 {
00526    SpecialInputWidget* siw = dynamic_cast<SpecialInputWidget*>( FindChild( "weapinfo", true ) );
00527    if ( siw ) {
00528       siw->sigMouseButtonDown.connect( SigC::slot( *this, &UnitInfoPanel::onClick ));
00529       siw->sigMouseButtonUp.connect( SigC::slot( *this, &UnitInfoPanel::onClick ));
00530    }
00531 
00532    PG_Label* l = dynamic_cast<PG_Label*>( parent->FindChild( "unitname", true ) );
00533    if ( l ) {
00534       l->sigMouseButtonUp.connect( SigC::slot( *this, &UnitInfoPanel::unitNaming ));
00535    }
00536 
00537    VehicleTypeSelectionItemFactory::showVehicleInfo.connect( SigC::slot( *this, &UnitInfoPanel::showUnitInfo ));
00538 }
00539 
00540 void UnitInfoPanel::showUnitInfo( const VehicleType* vt )
00541 {
00542    // showUnitData( vt, NULL, true );
00543 }
00544 
00545 bool UnitInfoPanel::unitNaming()
00546 {
00547    ContainerBase* container = NULL;
00548    if ( veh )
00549       container = veh;
00550    else
00551       if ( bld )
00552          container = bld;
00553    
00554    if ( container && RenameContainerCommand::avail( container ) && container->getOwner() == container->getMap()->actplayer ) {
00555       UnitNaming un( container );
00556       un.Show();
00557       un.RunModal();
00558       showUnitData( veh, bld, NULL, true );
00559    }
00560    return true;
00561 }
00562 
00563 
00564 bool UnitInfoPanel::onClick ( PG_MessageObject* obj, const SDL_MouseButtonEvent* event )
00565 {
00566 
00567    static const bool modalWeaponInfo = true;
00568    
00569    SpecialInputWidget* siw = dynamic_cast<SpecialInputWidget*>(obj);
00570    if ( siw ) {
00571       if ( event->button == SDL_BUTTON_RIGHT ) {
00572          if ( event->type == SDL_MOUSEBUTTONDOWN  ) {
00573 
00574             MapField* fld = actmap->getField( actmap->player[actmap->actplayer].cursorPos );
00575             const Vehicle* vehicle = veh;
00576             const VehicleType* vt = veh ? veh->typ : NULL;
00577             if ( !veh && fld && fld->vehicle ) {
00578                vt = fld->vehicle->typ;
00579                vehicle = fld->vehicle;
00580             }
00581             if ( vt || veh ) {
00582                // parent? PG_Application::GetWidgetById( ASC_PG_App::mainScreenID )
00583                WeaponInfoPanel* wip = new WeaponInfoPanel( NULL, vehicle, vt );
00584                wip->Show();
00585                wip->BringToFront();
00586                if ( modalWeaponInfo ) {
00587                   wip->SetCapture();
00588                   wip->RunModal();
00589                   delete wip;
00590                } // else
00591               //     PG_Application::
00592             }
00593             return true;
00594          }
00595          if ( event->type == SDL_MOUSEBUTTONUP && !modalWeaponInfo ) {
00596             bool result = false;
00597             PG_Widget* wip;
00598             do  {
00599                wip = PG_Application::GetWidgetByName( WeaponInfoPanel::WIP_Name() );
00600                if ( wip ) {
00601                   delete wip;
00602                   result = true;
00603                }
00604             } while ( wip );
00605             return result;
00606          }
00607       }
00608    }
00609    return false;
00610 }
00611 
00612 class WeaponInfoLine: public PG_Image {
00613       const SingleWeapon* weapon;
00614       const VehicleType* veh;
00615       WeaponInfoPanel* wip;
00616       static WeaponInfoLine* displayed;
00617    public:
00618       WeaponInfoLine( WeaponInfoPanel* parent, const PG_Point& p, SDL_Surface* image, const SingleWeapon* weap, const VehicleType* vehicle )
00619            : PG_Image( parent, p, image, false ), weapon(weap), veh ( vehicle ), wip(parent)
00620       {
00621       };
00622 
00623       void painter ( const PG_Rect &src, const ASCString& name, const PG_Rect &dst)
00624       {
00625          Surface screen = Surface::Wrap( PG_Application::GetScreen() );
00626          if ( name == "weapon_symbol1" )
00627             screen.Blit( IconRepository::getIcon(SingleWeapon::getIconFileName( weapon->getScalarWeaponType()) + "-small.png"), SPoint(dst.x, dst.y));
00628 
00629          if ( name == "weapon_targets" || name == "weapon_shootfrom" ) {
00630             int height;
00631             if (name == "weapon_targets")
00632                height = weapon->targ;
00633             else {
00634                height = weapon->sourceheight;
00635                if ( veh )
00636                   height &= veh->height;
00637             }
00638 
00639             for ( int i = 0; i < 8; ++i )
00640                if ( height & (1 << i )) {
00641                   Surface& tick = IconRepository::getIcon("weapon_ok.png");
00642                   screen.Blit( tick, SPoint(dst.x + i * tick.w(), dst.y  ) );
00643                }
00644          }
00645 
00646       };
00647 
00648       void registerSpecialDisplay( const ASCString& name )
00649       {
00650          SpecialDisplayWidget* sdw = dynamic_cast<SpecialDisplayWidget*>( FindChild( name, true ) );
00651          if ( sdw )
00652             sdw->display.connect( SigC::slot( *this, &WeaponInfoLine::painter ));
00653       };
00654 
00655            void eventMouseEnter()
00656       {
00657          wip->showWeapon( weapon );
00658          displayed = this;
00659       };
00660 
00661       void eventMouseLeave()
00662       {
00663          if ( displayed == this )
00664             wip->showWeapon();
00665       };
00666 
00667       bool activate()
00668       {
00669          if ( displayed != this ) {
00670             wip->showWeapon( weapon);
00671             displayed = this;
00672             return true;
00673          } else
00674             return false;
00675       }
00676 };
00677 
00678 WeaponInfoLine* WeaponInfoLine::displayed = NULL;
00679 
00680 
00681 
00682 WeaponInfoPanel::WeaponInfoPanel (PG_Widget *parent, const Vehicle* veh, const VehicleType* vt ) : Panel( parent, PG_Rect::null, "WeaponInfo" ), weaponCount(0)
00683 {
00684    SetName(name);
00685 
00686    vector<const SingleWeapon*> displayedWeapons;
00687    vector<int> displayedWeaponNum;
00688 
00689    for ( int j = 0; j < vt->weapons.count ; j++)
00690       if ( vt->weapons.weapon[j].getScalarWeaponType() >= 0 ) {
00691          ++weaponCount;
00692          displayedWeapons.push_back( &vt->weapons.weapon[j] );
00693          displayedWeaponNum.push_back(j);
00694       }
00695 
00696 
00697    Surface& head = IconRepository::getIcon("weapon_large_top.png");
00698    Surface& line = IconRepository::getIcon("weapon_large_line.png");
00699    Surface& foot = IconRepository::getIcon("weapon_large_bottom.png");
00700    int height = head.h() + foot.h() + weaponCount * line.h() + GetTitlebarHeight();
00701 
00702    SizeWidget( head.w(), height, false );
00703 
00704    int lineStartY = GetTitlebarHeight() + head.h()  - 1;
00705 
00706    PG_Widget* footWidget = FindChild( "bottom", true );
00707    assert( footWidget != NULL );
00708    footWidget->MoveWidget(0,  lineStartY + line.h() * weaponCount, false );
00709 
00710    for ( int i = 0; i < weaponCount; ++i ) {
00711       WidgetParameters widgetParams = getDefaultWidgetParams();
00712       WeaponInfoLine* lineWidget = new WeaponInfoLine ( this, PG_Point( 0,  lineStartY + i * line.h() ), line.getBaseSurface(), displayedWeapons[i], vt );
00713 
00714       PropertyReadingContainer pc ( "panel", textPropertyGroup );
00715 
00716       pc.openBracket("LineWidget");
00717       parsePanelASCTXT( pc, lineWidget, widgetParams );
00718       pc.closeBracket();
00719 
00720 
00721       assignWeaponInfo( this, lineWidget, *displayedWeapons[i] );
00722       lineWidget->registerSpecialDisplay( "weapon_shootfrom" );
00723       lineWidget->registerSpecialDisplay( "weapon_targets" );
00724       if ( veh )
00725          setLabelText( "weapon_currentammo", veh->ammo[displayedWeaponNum[i]], lineWidget );
00726 
00727       weaponInfoLines.push_back( lineWidget );
00728    }
00729    setLabelText( "weapon_shootaftermove", vt->wait ? "no" : "yes" );
00730    setLabelText( "weapon_moveaftershoot", vt->hasFunction( ContainerBaseType::MoveAfterAttack  ) ? "yes" : "no" );
00731 
00732    /*
00733    for ( int i = 0; i < cmovemalitypenum; ++i ) 
00734       setLabelText( ASCString("weapon_efficiency_") + unitCategoryTags[i], cmovemalitypes[i] );
00735       */
00736 }
00737 
00738 
00739 void WeaponInfoPanel::showWeapon( const SingleWeapon* weap )
00740 {
00741    PG_Application::SetBulkMode(true);
00742    int effic[13];
00743    for ( int k = 0; k < 13; k++ )
00744       if ( weap )
00745          effic[k] = weap->efficiency[k];
00746       else
00747          effic[k] = -1;
00748 
00749    if ( weap ) {
00750       int mindelta = 1000;
00751       int maxdelta = -1000;
00752       for ( int h1 = 0; h1 < 8; h1++ )
00753          for ( int h2 = 0; h2 < 8; h2++ )
00754             if ( weap->sourceheight & ( 1 << h1 ) )
00755                if ( weap->targ & ( 1 << h2 )) {
00756                   int delta = getheightdelta ( h1, h2);
00757                   if ( delta > maxdelta )
00758                      maxdelta = delta;
00759                   if ( delta < mindelta )
00760                      mindelta = delta;
00761                }
00762       for ( int a = -6; a < mindelta; a++ )
00763          effic[6+a] = -1;
00764       for ( int b = maxdelta+1; b < 7; b++ )
00765          effic[6+b] = -1;
00766    }
00767 
00768    for ( int i = -6; i <= 6; ++i ) {
00769       if ( effic[6+i] >= 0 )
00770          setLabelText( "weapon_distance_" + ASCString::toString(i), i );
00771       else
00772          setLabelText( "weapon_distance_" + ASCString::toString(i), "" );
00773 
00774       if ( weap && effic[6+i] >= 0 )
00775          setLabelText( "weapon_efficiency_" + ASCString::toString(i), weap->efficiency[6+i]  );
00776       else
00777          setLabelText( "weapon_efficiency_" + ASCString::toString(i), "" );
00778    }
00779 
00780                                    // grey light grey  yellow,    blue      red        green
00781    static const int colors[6] = { 0x969595, 0xdfdfdf, 0xfac914,  0x5383e6,   0xff5e5e, 0x08ce37 };
00782 
00783    for ( int i = 0; i< cmovemalitypenum; ++i)
00784       if ( weap ) {
00785          int col;
00786          if ( weap->targetingAccuracy[i] < 10 )
00787             col = colors[0] ;
00788          else
00789             if ( weap->targetingAccuracy[i] < 30 )
00790                col = colors[1] ;
00791             else
00792                if ( weap->targetingAccuracy[i] < 80 )
00793                   col = colors[3] ;
00794                else
00795                   if ( weap->targetingAccuracy[i] < 120 )
00796                      col = colors[2];
00797                   else
00798                      col = colors[4];
00799          setLabelColor( ASCString("weapon_efficiency_") + unitCategoryTags[i], col );
00800          setLabelText( ASCString("weapon_efficiency_") + unitCategoryTags[i], weap->targetingAccuracy[i]  );
00801       } else
00802          setLabelText( ASCString("weapon_efficiency_") + unitCategoryTags[i], "" );
00803 
00804    if ( weap )
00805       setLabelText( "weapon_text2",  weap->getName() );
00806    else
00807       setLabelText( "weapon_text2",  "" );
00808 
00809    if ( weap )  {
00810       setImage( "weapon_symbol2", IconRepository::getIcon(SingleWeapon::getIconFileName( weap->getScalarWeaponType()) + "-small.png") );
00811       show( "weapon_symbol2" );
00812    } else
00813       hide( "weapon_symbol2" );
00814 
00815    PG_Application::SetBulkMode(false);
00816    Update();
00817 }
00818 
00819 bool   WeaponInfoPanel::eventMouseButtonUp (const SDL_MouseButtonEvent *button)
00820 {
00821    if ( Panel::eventMouseButtonUp( button ))
00822       return true;
00823    
00824    if ( button->button == SDL_BUTTON_RIGHT ) {
00825       QuitModal();
00826       return true;
00827    } else
00828       return false;
00829 }
00830 
00831 
00832 bool WeaponInfoPanel::eventMouseMotion(const SDL_MouseMotionEvent* motion)
00833 {
00834    for ( int i = 0; i < weaponInfoLines.size();++i )
00835       if ( weaponInfoLines[i]->IsMouseInside() )
00836          return weaponInfoLines[i]->activate();
00837    return false;
00838 };
00839 
00840 
00841 ASCString WeaponInfoPanel::name = "WeaponInfoPanel";
00842 const ASCString& WeaponInfoPanel::WIP_Name()
00843 {
00844    return name;
00845 }
00846 
00847 
00848 MapInfoPanel::MapInfoPanel (PG_Widget *parent, const PG_Rect &r, MapDisplayPG* mapDisplay ) : DashboardPanel( parent, r, "MapInfo" ), zoomSlider(NULL), changeActive(false)
00849 {
00850    assert( mapDisplay );
00851    this->mapDisplay = mapDisplay;
00852    
00853    zoomSlider = dynamic_cast<PG_Slider*>( FindChild( "zoomscroller", true ) );
00854    if ( zoomSlider ) {
00855       zoomSlider->SetRange(0,75); // results in zoomlevels from 100 - 25
00856       zoomSlider->sigSlide.connect( SigC::slot( *this, &MapInfoPanel::scrollTrack ));
00857       mapDisplay->newZoom.connect( SigC::slot( *this, &MapInfoPanel::zoomChanged ));
00858       zoomSlider->SetPosition( 100 - mapDisplay->getZoom() );
00859    }   
00860 
00861    const int labelnum = 5;
00862    const char* label[labelnum] = { "pipes", "container", "resources", "visibilityvalue", "reactionfire" };
00863    for ( int i = 0; i < labelnum; ++i ) {
00864       PG_CheckButton* cb = dynamic_cast<PG_CheckButton*>( FindChild( label[i], true ) );
00865       if ( mapDisplay->layerActive( label[i] )
00866          )
00867          layerChanged( true, label[i]);
00868       if ( cb ) 
00869          cb->sigClick.connect( SigC::bind( SigC::slot( *this, &MapInfoPanel::checkBox ), label[i] ));
00870    }      
00871    
00872    mapDisplay->layerChanged.connect( SigC::slot( *this, &MapInfoPanel::layerChanged ));
00873       
00874    PG_Button* b = dynamic_cast<PG_Button*>( FindChild( "weaprange", true ) );
00875    if ( b )
00876       b->sigClick.connect( SigC::slot( *this, &MapInfoPanel::showWeaponRange ));
00877    
00878    PG_Button* b2 = dynamic_cast<PG_Button*>( FindChild( "moverange", true ) );
00879    if ( b2 )
00880       b2->sigClick.connect( SigC::slot( *this, &MapInfoPanel::showMovementRange ));
00881    
00882 }
00883 
00884 void MapInfoPanel::layerChanged( bool state, const ASCString& label )
00885 {
00886    PG_CheckButton* cb = dynamic_cast<PG_CheckButton*>( FindChild( label, true ) );
00887    if ( cb && ! changeActive ) {
00888       if ( state )
00889          cb->SetPressed();
00890       else
00891          cb->SetUnpressed();
00892    }
00893 }
00894 
00895 bool MapInfoPanel::showWeaponRange()
00896 {
00897    executeUserAction( ua_viewunitweaponrange );
00898    return true;
00899 }
00900 
00901 bool MapInfoPanel::showMovementRange()
00902 {
00903    executeUserAction( ua_viewunitmovementrange );
00904    return true;
00905 }
00906 
00907 
00908 void MapInfoPanel::zoomChanged( int zoom )
00909 {
00910    if ( !changeActive )
00911       if ( zoomSlider )
00912          zoomSlider->SetPosition( 100 - zoom );
00913 }
00914 
00915 bool MapInfoPanel::scrollTrack( long pos )
00916 {
00917    changeActive = true;
00918    mapDisplay->setNewZoom( 100 - pos );
00919    repaintMap();
00920    changeActive = false;
00921    return true;
00922 }
00923 
00924 bool MapInfoPanel::checkBox( bool state, const char* name )
00925 {
00926    changeActive = true;
00927    mapDisplay->activateMapLayer( name, state );
00928    repaintMap();
00929    changeActive = false;
00930    return true;
00931 }
00932 
00933 
00934 ActionInfoPanel::ActionInfoPanel (PG_Widget *parent, const PG_Rect &r ) : DashboardPanel( parent, r, "ActionInfo" )
00935 {
00936    ActionContainer::actionListChanged.connect( SigC::slot( *this, &ActionInfoPanel::update ));
00937 }
00938 
00939 void ActionInfoPanel::update( GameMap* map )
00940 {
00941    TextRenderer* text = dynamic_cast<TextRenderer*>( FindChild( "ActionList", true ));
00942    if ( text && map) {
00943       /*
00944       vector<ASCString> list;
00945       map->actions.getActionDescriptions( list );
00946       
00947       ASCString s;
00948       for ( vector<ASCString>::const_iterator i = list.begin(); i != list.end(); ++i )
00949          s += *i + "\n";
00950       */
00951       text->SetText( "Function removed, please use Action/Manage dialog" );
00952    }
00953 }
00954 

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