Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

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

Generated on Tue Jun 24 01:27:38 2008 for Advanced Strategic Command by  doxygen 1.4.2