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 }