00001 #include "../borqueror.h"
00002
00003 SDL_Surface *GalaxyScreen::img = 0 , *GalaxyScreen::bkgnd;
00004
00005 GalaxyScreen::GalaxyScreen( void )
00006 : curSS( 0 ) , zoom( 1 )
00007 {
00008 timer = new Timer( this );
00009 tooltip = new XLabel();
00010 }
00011
00012
00013 GalaxyScreen::~GalaxyScreen( void )
00014 {
00015 if( timer )
00016 delete timer;
00017 timer = 0;
00018 if( tooltip )
00019 delete tooltip;
00020 tooltip = 0;
00021 }
00022
00023 const bool GalaxyScreen::SetupWindow( const Message &msg )
00024 {
00025 XBox::SetupWindow( msg );
00026 icstring str( "0 0 0 0 (fonth 12) (fg 0xff104c18) (bg 0xffacca70) (states S_RAISED|S_ALIGN_LEFT|S_ALIGN_TOP)" );
00027 tooltip->Init( str );
00028 tooltip->SetParent( this );
00029 tooltip->HideWindow();
00030
00031 string name = Cfg::GetCfg().GetCfgString( "DefaultParameters" , "ShapeName" , "" );
00032 if( !name.empty() )
00033 ChangeImage( "" , name , "@images" );
00034 else if( id == -1 )
00035 if( key.empty() )
00036 id = Graf::LoadImg( fname.empty() ? sct : fname );
00037 else
00038 id = Graf::LoadImg( sct , key , fname );
00039
00040
00041 {
00042 Cfg::Handler &h = Cfg::GetCfg( "@Generator" );
00043 galaxyRect.x = galaxyRect.y = 0;
00044 galaxyRect.w = h.GetCfgInt( "Galaxy-coord" , "playW" );
00045 galaxyRect.h = h.GetCfgInt( "Galaxy-coord" , "playH" );
00046 }
00047 SDL_Surface *sfc = Graf::Img( id );
00048 Graf::SDL_StretchBlt( sfc , 0 , bkgnd , &galaxyRect , true );
00049
00050 MessageServer::Instance().RegisterMessageClient( this , Message::MOUSE_BUTTONDOWN );
00051 MessageServer::Instance().RegisterMessageClient( this , Message::MOUSE_BUTTONUP );
00052 MessageServer::Instance().RegisterMessageClient( this , Message::MOUSE_MOVE );
00053 MessageServer::Instance().RegisterMessageClient( this , Message::CTRL_LCLICK );
00054 MessageServer::Instance().RegisterMessageClient( this , Message::KEYBOARD_KEYUP );
00055 MessageServer::Instance().RegisterMessageClient( this , Message::CTRL_TIMER);
00056
00057 curSS = 0;
00058 zoom = 1;
00059
00060 ResetGalaxyDisplay();
00061
00062 sbh = dynamic_cast<XScrollBar *>( Rsrc::GetAddr( ePlayGame )->GetArsObject( 43 ) );
00063 sbh->SetLimits( 0 , 0 );
00064 sbh->SetPosition( 0 );
00065 sbv = dynamic_cast<XScrollBar *>( Rsrc::GetAddr( ePlayGame )->GetArsObject( 42 ) );
00066 sbv->SetLimits( 0 , 0 );
00067 sbv->SetPosition( 0 );
00068
00069 int zw = galaxyRect.Width() / zoom , zh = galaxyRect.Height() / zoom;
00070 zr = XRect( 0 , 0 , zw , zh );
00071
00072 return true;
00073 }
00074
00075 void GalaxyScreen::ResetGalaxyDisplay( void )
00076 {
00077 if( bkgnd )
00078 {
00079 SDL_SetAlpha( bkgnd , SDL_SRCALPHA , fade );
00080 SDL_BlitSurface( bkgnd , 0 , img , &galaxyRect );
00081 }
00082 else
00083 SDL_FillRect( img , &galaxyRect , 0xff000000 );
00084
00085 for_each( GetGalaxy().begin() , GetGalaxy().end() , bind2nd( mem_fun( &StarSystem::DrawInGalaxy ) , img ) );
00086 for_each( GetGalaxy().begin() , GetGalaxy().end() , bind2nd( mem_fun( &StarSystem::DrawInfluenceZones ) , img ) );
00087 }
00088
00089 void GalaxyScreen::Draw( void )
00090 {
00091 XBox::Draw();
00092
00093 zr.x = sbh->GetPosition();
00094 zr.y = sbv->GetPosition();
00095
00096 XRect dst( GetWindowRect() );
00097 Graf::SDL_StretchBlt( img , &zr , GetGDI() , &dst );
00098 }
00099
00100 XPoint GalaxyScreen::ToGalaxy( const XPoint &mp )
00101 {
00102 XRect dst( GetWindowRect() );
00103 int zoomfactor = (int)pow( 2.0 , zoom - 1.0 );
00104 int zw = galaxyRect.Width() / zoomfactor , zh = galaxyRect.Height() / zoomfactor;
00105
00106 double rw = (double)dst.Width() / zw;
00107 double rh = (double)dst.Height() / zh;
00108
00109 XPoint ans = mp - XPoint( x , y );
00110
00111 ans.x = (int)(ans.x / rw);
00112 ans.y = (int)(ans.y / rh);
00113 return ans + zr.TopLeft();
00114 }
00115
00116
00117 const bool GalaxyScreen::evMouseMove( const MouseMessage &msg )
00118 {
00119 bool ans = XBox::evMouseMove( msg );
00120
00121 if( HitTest( msg.Point ) == RELPOS_INSIDE )
00122 {
00123 XPoint ans = ToGalaxy( msg.Point );
00124 vector<StarSystem *>::iterator pos = find_if( GetGalaxy().begin() , GetGalaxy().end() , bind2nd( mem_fun( &StarSystem::InVicinity ) , &ans ) );
00125 if(curSS == 0 )
00126 {
00127 if( pos != GetGalaxy().end() )
00128 ArsSendMessage( CtrlMessage( Message::CTRL_VALUECHANGE , GetParent() , this , (long int)*pos ) );
00129 else
00130 ArsSendMessage( CtrlMessage( Message::CTRL_VALUECHANGE , GetParent() , this , 0 ) );
00131 ans = true;
00132 }
00133
00134 lastMousePosition = msg.Point;
00135 timer->StopTimer();
00136 if( tooltip->IsVisible() )
00137 HideTip();
00138 if( pos != GetGalaxy().end() )
00139 timer->StartTimer( 2000 );
00140 }
00141 return ans;
00142 }
00143
00144 const bool GalaxyScreen::evMouseButtonUp( const MouseMessage &msg )
00145 {
00146 mp = msg.Point;
00147 timer->StopTimer();
00148 return XBox::evMouseButtonUp( msg );
00149 }
00150
00151 const bool GalaxyScreen::evMouseLClick( const CtrlMessage &msg )
00152 {
00153 XBox::evMouseLClick( msg );
00154
00155 const bool changed = (curSS != 0);
00156
00157 XPoint ans = ToGalaxy( mp );
00158 vector<StarSystem *>::iterator pos = find_if( GetGalaxy().begin() , GetGalaxy().end() , bind2nd( mem_fun( &StarSystem::InVicinity ) , &ans ) );
00159 if( pos != GetGalaxy().end() )
00160 curSS = *pos;
00161 else
00162 curSS = 0;
00163
00164 timer->StopTimer();
00165 if( changed )
00166 ArsSendMessage( CtrlMessage( Message::CTRL_VALUECHANGE , GetParent() , this , (long int)curSS ) );
00167
00168 return true;
00169 }
00170
00171 const bool GalaxyScreen::evKeyUp( const KeyboardMessage &msg )
00172 {
00173 bool ans = XImage::evKeyUp( msg );
00174
00175 switch( msg.Key )
00176 {
00177 case SDLK_o :
00178 if( zoom > 1 )
00179 {
00180 zoom -= 1;
00181 ans = true;
00182 timer->StopTimer();
00183 SetDirty();
00184 }
00185 break;
00186
00187 case SDLK_i :
00188 if( zoom < 6 )
00189 {
00190 zoom += 1;
00191 timer->StopTimer();
00192 ans = true;
00193 SetDirty();
00194 }
00195 break;
00196 }
00197
00198 if( ans )
00199 {
00200 int zoomfactor = (int)pow( 2.0 , zoom - 1.0 );
00201 int zw = galaxyRect.Width() / zoomfactor , zh = galaxyRect.Height() / zoomfactor;
00202
00203 zr = XRect( 0 , 0 , zw , zh );
00204 if( curSS )
00205 {
00206 zr.x = max( 0 , min( curSS->x - zw / 2 , galaxyRect.Right() - zw ) );
00207 zr.y = max( 0 , min( curSS->y - zh / 2 , galaxyRect.Bottom() - zh ) );
00208 }
00209 else
00210 {
00211 zr.x = galaxyRect.Center().x - zw / 2;
00212 zr.y = galaxyRect.Center().y - zh / 2;
00213 }
00214 sbh->SetLimits( 0 , galaxyRect.Width() - zw );
00215 sbh->SetPosition( zr.x );
00216 sbv->SetLimits( 0 , galaxyRect.Height() - zh );
00217 sbv->SetPosition( zr.y );
00218 }
00219 return ans;
00220 }
00221
00222 void GalaxyScreen::ShowTip( const XPoint &p )
00223 {
00224 if( !tooltip->IsVisible() )
00225 {
00226 XPoint ans = ToGalaxy( lastMousePosition );
00227 vector<StarSystem *>::iterator pos = find_if( GetGalaxy().begin() , GetGalaxy().end() , bind2nd( mem_fun( &StarSystem::InVicinity ) , &ans ) );
00228 if( pos != GetGalaxy().end() )
00229 {
00230 tooltip->SetWndText( (*pos)->GetStarInfo() );
00231 tooltip->x = max( (int)x , p.x );
00232 tooltip->y = max( (int)y , p.y );
00233 XPoint p = tooltip->GetTextSize( tooltip->GetWindowText() );
00234 tooltip->w = p.x + 10;
00235 tooltip->h = p.y + 10;
00236 if( tooltip->Right() > Right() )
00237 tooltip->x = Right() - tooltip->Width();
00238 if( tooltip->Bottom() > Bottom() )
00239 tooltip->y = Bottom() - tooltip->Height();
00240
00241 tooltip->ShowWindow();
00242 tooltip->UpdateWindow( true );
00243 }
00244 }
00245 }
00246
00247
00248 void GalaxyScreen::HideTip(void)
00249 {
00250 tooltip->HideWindow();
00251 tooltip->UpdateWindow( true );
00252 }
00253
00254 const bool GalaxyScreen::evTimer( const CtrlMessage &msg )
00255 {
00256 bool ans = XImage::evTimer( msg );
00257
00258 if( msg.Destination() == this )
00259 {
00260 ShowTip( lastMousePosition + XPoint( -6 , 18 ) );
00261 ans = true;
00262 }
00263 return ans;
00264 }