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