00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "overviewmappanel.h"
00021 #include "spfst.h"
00022 #include "graphics/blitter.h"
00023 #include "graphics/drawing.h"
00024 #include "mapdisplay.h"
00025 #include "spfst-legacy.h"
00026
00027
00028 OverviewMapPanel::OverviewMapPanel( PG_Widget *parent, const PG_Rect &r, MapDisplayPG* mapDisplay, const ASCString& widgetName )
00029 : LayoutablePanel ( parent, r, widgetName, true ), mapDisplayWidget( mapDisplay), currentZoom( 1 ), locked(false)
00030 {
00031 SpecialDisplayWidget* sdw = dynamic_cast<SpecialDisplayWidget*>( FindChild( "overviewmap", true ) );
00032 if ( sdw ) {
00033 sdw->display.connect( SigC::slot( *this, &OverviewMapPanel::painter ));
00034 sdw->sigMouseMotion.connect( SigC::slot( *this, &OverviewMapPanel::mouseMotion ));
00035 sdw->sigMouseButtonDown.connect( SigC::slot( *this, &OverviewMapPanel::mouseButtonDown ));
00036 }
00037
00038 ovmap = sdw;
00039 assert( ovmap );
00040
00041 OverviewMapHolder::generationComplete.connect ( SigC::slot( *this, &OverviewMapPanel::redraw ));
00042 viewChanged.connect ( SigC::slot( *this, &OverviewMapPanel::redraw ));
00043
00044 lockMapdisplay.connect( SigC::slot( *this, &OverviewMapPanel::lockPanel ));
00045 unlockMapdisplay.connect( SigC::slot( *this, &OverviewMapPanel::unlockPanel ));
00046
00047
00048 }
00049
00050
00051 template<int pixelsize>
00052 class ColorMerger_Invert
00053 {
00054 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00055 SDLmm::Color col;
00056 public:
00057
00058 void assign ( PixelType src, PixelType* dest ) const
00059 {
00060 *dest = (col & 0xff000000) + (0xffffff - (*dest & 0xffffff));
00061
00062 };
00063
00064
00065 ColorMerger_Invert( SDLmm::Color color )
00066 {
00067 col = color;
00068 };
00069 };
00070
00071
00072 void OverviewMapPanel::painter ( const PG_Rect &src, const ASCString& name, const PG_Rect &dst)
00073 {
00074 Surface screen = Surface::Wrap( PG_Application::GetScreen() );
00075 if ( name == "overviewmap" && actmap && !locked ) {
00076 Surface s = actmap->overviewMapHolder.getOverviewMap( false );
00077
00078 MegaBlitter< gamemapPixelSize, gamemapPixelSize,ColorTransform_None,ColorMerger_AlphaOverwrite,SourcePixelSelector_DirectZoom,TargetPixelSelector_Rect> blitter;
00079 blitter.setSize( s.w(), s.h(), dst.w, dst.h );
00080
00081 PG_Rect clip= dst.IntersectRect( PG_Application::GetScreen()->clip_rect );
00082 blitter.setTargetRect( clip );
00083
00084
00085 currentZoom = blitter.getZoomX();
00086 blitter.blit( s, screen, SPoint(dst.x, dst.y) );
00087
00088 SPoint ul = OverviewMapImage::map2surface( mapDisplayWidget->upperLeftCorner());
00089 SPoint lr = OverviewMapImage::map2surface( mapDisplayWidget->lowerRightCorner());
00090 ul.x = int( float( ul.x) * currentZoom );
00091 ul.y = int( float( ul.y) * currentZoom );
00092 lr.x = int( float( lr.x) * currentZoom );
00093 lr.y = int( float( lr.y) * currentZoom );
00094
00095 if ( ul.x < 0 )
00096 ul.x = 0;
00097 if ( ul.y < 0 )
00098 ul.y = 0;
00099 if ( lr.x >= src.Width() )
00100 lr.x = src.Width() -1;
00101 if ( lr.y >= src.Height() )
00102 lr.y = src.Height() -1;
00103
00104 rectangle<4>(screen, SPoint(dst.x + ul.x, dst.y + ul.y), lr.x-ul.x, lr.y-ul.y, ColorMerger_Invert<4>(0xff), ColorMerger_Invert<4>(0xff) );
00105 }
00106 }
00107
00108
00109 void OverviewMapPanel::lockPanel()
00110 {
00111 locked = true;
00112 Update();
00113 }
00114
00115 void OverviewMapPanel::unlockPanel()
00116 {
00117 locked = false;
00118 Redraw();
00119 }
00120
00121 bool OverviewMapPanel::mouseClick ( SPoint pos )
00122 {
00123 SPoint unscaledPos = SPoint(int( float(pos.x) / currentZoom), int(float(pos.y) / currentZoom ));
00124 MapCoordinate mc = OverviewMapImage::surface2map( unscaledPos );
00125
00126 if ( !(mc.valid() && mc.x < actmap->xsize && mc.y < actmap->ysize ))
00127 return false;
00128
00129 mapDisplayWidget->centerOnField( mc );
00130 return true;
00131 }
00132
00133
00134 bool OverviewMapPanel::mouseButtonDown ( const SDL_MouseButtonEvent *button)
00135 {
00136 if ( ovmap->IsMouseInside() )
00137 if ( button->type == SDL_MOUSEBUTTONDOWN && button->button == 1 ) {
00138 PG_Point p = ovmap->ScreenToClient( button->x, button->y );
00139 return mouseClick( SPoint( p.x, p.y ));
00140 }
00141
00142 return false;
00143 }
00144
00145 bool OverviewMapPanel::mouseMotion ( const SDL_MouseMotionEvent *motion)
00146 {
00147 if ( ovmap->IsMouseInside() )
00148 if ( motion->type == SDL_MOUSEMOTION && (motion->state & 1 ) ) {
00149 PG_Point p = ovmap->ScreenToClient( motion->x, motion->y );
00150 return mouseClick( SPoint( p.x, p.y ));
00151 }
00152
00153 return false;
00154 }
00155