--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mapnavproviderrefapp/src/mnrpmapcontrol.cpp Tue Feb 02 00:16:03 2010 +0200
@@ -0,0 +1,644 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: CMnrpMapControl class implementation
+*
+*/
+
+
+#include <coemain.h>
+#include <aknlists.h>
+#include <barsread.h>
+#include <aknnotewrappers.h>
+
+#include <bitstd.h>
+#include <bitdev.h>
+
+#include <lbsposition.h>
+
+#include "debug.h"
+
+#include "mnrputils.h"
+#include "mnrpmapview.h"
+#include "mnrpmapcontrol.h"
+
+const TInt KCodeKeyLeft = 0x34;
+const TInt KCodeKeyRight = 0x36;
+const TInt KCodeKeyUp = 0x32;
+const TInt KCodeKeyDown = 0x38;
+const TInt KCodeKeyCenter = 0x35;
+
+const TInt KCodeKeySelect = EKeyDevice3;
+const TInt KCodeKeySelect2 = 0x13;
+
+const TInt KCodeKeyZoomIn = 42;
+const TInt KCodeKeyZoomOut = 35;
+const TInt KCodeKeyZoomIn2 = 0x33;
+const TInt KCodeKeyZoomOut2 = 0x39;
+
+const TRgb KCursorColor( 255, 255, 255 );
+const TRgb KGridTextColor( 0, 0, 0 );
+const TRgb KOriginMarkColor( 0, 0, 255 );
+
+const TInt KTextFontHeightInTwips = 100;
+const TInt KItemFontHeightInTwips = 120;
+const TReal KBorderSizeFactor = 2;
+
+const TInt KCursorMarginSize = 20; // pixels
+const TInt KCursorArrowSize = 4; // pixels
+const TInt KCursorCircleRadius = 4; // pixels
+
+const TInt KCursorMove = 10; // pixels
+const TInt KWindowMove = 20; // pixels
+const TReal KJumpFactor = 5;
+const TReal KCrawlFactor = 2.0 / KCursorMove;
+
+const TReal KZoomOutRate = 1.5;
+const TReal KZoomInRate = 1 / KZoomOutRate;
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+CMnrpMapControl::CMnrpMapControl( CMnrpMapView& aView )
+ : iView( aView )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+CMnrpMapControl::~CMnrpMapControl()
+ {
+ delete iModel;
+ delete iOffScreenBitmap;
+ DestroyFonts();
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+CMnrpMapControl* CMnrpMapControl::NewL(
+ CMnrpMapView& aView,
+ const TRect& aRect,
+ CMnrpEngine& aEngine )
+ {
+ CMnrpMapControl* self = new ( ELeave ) CMnrpMapControl( aView );
+ CleanupStack::PushL( self );
+ self->ConstructL( aRect, aEngine );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CMnrpMapControl::UpdateModelL( CMnrpMapViewService& aService )
+ {
+ iModel->UpdateModelL( aService );
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CMnrpMapControl::SetSelectionModeL( TBool aSelectionMode )
+ {
+ iSelectionMode = aSelectionMode;
+ iAbsoluteCursor = iModel->Center();
+ iCursor = iModel->AbsoluteToScreen( iAbsoluteCursor );
+ DrawDeferred();
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TCoordinate CMnrpMapControl::CurrentLocation()
+ {
+ return iAbsoluteCursor;
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CMnrpMapControl::ConstructL(
+ const TRect& aRect,
+ CMnrpEngine& aEngine )
+ {
+ // Create a window for this application view
+ CreateWindowL();
+
+ iModel = CMnrpMapModel::NewL( *this, aEngine );
+
+ // Set the windows size
+ SetRect( aRect );
+
+ iAbsoluteCursor = TCoordinate( 0, 0 );
+ iCursor = iModel->AbsoluteToScreen( iAbsoluteCursor );
+
+ CreateFonts();
+ CreateScreenBufferL( aRect.Size() );
+
+ // Activate the window, which makes it ready to be drawn
+ ActivateL();
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TKeyResponse CMnrpMapControl::OfferKeyEventL(
+ const TKeyEvent& aKeyEvent,
+ TEventCode /*aType*/ )
+ {
+ TKeyResponse response = EKeyWasConsumed;
+
+ TInt step = iSelectionMode ? KCursorMove : KWindowMove;
+ TBool isShift = aKeyEvent.iModifiers & EModifierShift;
+ TReal crawlFactor = isShift ? KCrawlFactor : 1;
+
+ TInt xmove = 0;
+ TInt ymove = 0;
+
+ TBool redraw = ETrue;
+
+ switch ( aKeyEvent.iCode )
+ {
+ case EKeyLeftArrow:
+ xmove = -step * crawlFactor;
+ break;
+
+ case KCodeKeyLeft:
+ xmove = -step * KJumpFactor;
+ break;
+
+ case EKeyRightArrow:
+ xmove = step * crawlFactor;
+ break;
+
+ case KCodeKeyRight:
+ xmove = step * KJumpFactor;
+ break;
+
+ case EKeyUpArrow:
+ ymove = -step * crawlFactor;
+ break;
+
+ case KCodeKeyUp:
+ case EKeyPageUp:
+ ymove = -step * KJumpFactor;
+ break;
+
+ case EKeyDownArrow:
+ ymove = step * crawlFactor;
+ break;
+
+ case KCodeKeyDown:
+ case EKeyPageDown:
+ ymove = step * KJumpFactor;
+ break;
+
+ case KCodeKeyZoomIn:
+ case KCodeKeyZoomIn2:
+ Zoom( KZoomInRate );
+ break;
+
+ case KCodeKeyZoomOut:
+ case KCodeKeyZoomOut2:
+ Zoom( KZoomOutRate );
+ break;
+
+ case KCodeKeyCenter:
+ iModel->GoCenter();
+ iCursor = iModel->AbsoluteToScreen( TCoordinate( 0, 0 ) );
+ break;
+
+ case KCodeKeySelect:
+ case KCodeKeySelect2:
+ if ( iSelectionMode )
+ {
+ iView.HandleUserSelectionL( KErrNone );
+ redraw = EFalse;
+ }
+ break;
+
+ default:
+ response = EKeyWasNotConsumed;
+ redraw = EFalse;
+ break;
+ }
+
+ if ( xmove || ymove )
+ {
+ if ( iSelectionMode )
+ {
+ MoveCursor( xmove, ymove );
+ }
+ else
+ {
+ TCoordinate center = iModel->Center();
+ TCoordinate moveTo(
+ center.Latitude() - iModel->ScreenToAbsolute( ymove ),
+ center.Longitude() + iModel->ScreenToAbsolute( xmove ) );
+ iModel->MoveTo( moveTo );
+ }
+ }
+
+ if ( redraw )
+ {
+ RenderL();
+ DrawDeferred();
+ }
+
+ return response;
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CMnrpMapControl::HandleModelUpdateL()
+ {
+ RenderL();
+ DrawDeferred();
+
+ TInt ignored = iModel->NumIgnoredLandmarks();
+ if ( ignored )
+ {
+ CAknInformationNote* note = new (ELeave) CAknInformationNote( ETrue );
+ _LIT( KMessageIgnoredLm, "One landmark\nhas no coordinates\nand can't be shown." );
+ _LIT( KMessageIgnoredLms, "%d landmarks\nhave no coordinates\nand can't be shown." );
+ if ( ignored == 1 )
+ {
+ note->ExecuteLD( KMessageIgnoredLm() );
+ }
+ else
+ {
+ TBuf<64> message;
+ message.Format( KMessageIgnoredLms, ignored );
+ note->ExecuteLD( message );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CMnrpMapControl::CreateScreenBufferL( const TSize& aSize )
+ {
+ CGraphicsDevice* screenDevice = iEikonEnv->ScreenDevice();
+
+ // create a bitmap to be used off-screen
+ CFbsBitmap* offScreenBitmap = new (ELeave) CFbsBitmap();
+ User::LeaveIfError( offScreenBitmap->Create( aSize, screenDevice->DisplayMode() ) );
+ CleanupStack::PushL( offScreenBitmap );
+
+ if ( iOffScreenBitmap )
+ {
+ delete iOffScreenBitmap;
+ }
+ iOffScreenBitmap = offScreenBitmap;
+
+ CleanupStack::Pop( offScreenBitmap );
+ }
+
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CMnrpMapControl::CreateFonts()
+ {
+ CGraphicsDevice* screenDevice = iEikonEnv->ScreenDevice();
+
+ const CFont* denseFont = iEikonEnv->DenseFont();
+ TFontSpec fs = denseFont->FontSpecInTwips();
+
+ fs.iHeight = KTextFontHeightInTwips;
+ screenDevice->GetNearestFontInTwips( iTextFont, fs );
+
+ fs.iHeight = KItemFontHeightInTwips;
+ screenDevice->GetNearestFontInTwips( iItemFont, fs );
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CMnrpMapControl::DestroyFonts()
+ {
+ CGraphicsDevice* screenDevice = iEikonEnv->ScreenDevice();
+
+ screenDevice->ReleaseFont( iItemFont );
+ iItemFont = NULL;
+ screenDevice->ReleaseFont( iTextFont );
+ iTextFont = NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CMnrpMapControl::Draw( const TRect& /*aRect*/ ) const
+ {
+ // Get the standard graphics context
+ CWindowGc& gc = SystemGc();
+
+ TRect rect = Rect();
+ TRect border( rect );
+ border.Shrink( BorderSize() );
+
+ gc.Clear( TRect( rect.iTl.iX, rect.iTl.iY, rect.iBr.iX, border.iBr.iY ) );
+ gc.Clear( TRect( rect.iTl.iX, border.iBr.iY, rect.iBr.iX, rect.iBr.iY ) );
+ gc.Clear( TRect( rect.iTl.iX, border.iTl.iY, border.iTl.iX, border.iBr.iY ) );
+ gc.Clear( TRect( border.iBr.iX, border.iTl.iY, rect.iBr.iX, border.iBr.iY ) );
+
+ CMnrpMapModel::TGrid grid;
+ iModel->GetGrid( grid );
+ DrawGridText( gc, border, rect, iTextFont, grid );
+
+ if ( iOffScreenBitmap )
+ {
+ gc.BitBlt( border.iTl, iOffScreenBitmap );
+ }
+ else
+ {
+ gc.Clear();
+ }
+
+ if ( iSelectionMode )
+ {
+ gc.SetOrigin( border.iTl );
+ DrawCursor( gc );
+ }
+
+ // draw border
+ gc.SetPenColor( KRgbGray );
+ gc.SetPenSize( TSize( 1, 1 ) );
+ gc.SetOrigin( rect.iTl );
+ gc.DrawRect( border );
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CMnrpMapControl::DrawGridText(
+ CWindowGc& aGc,
+ const TRect& aInnerBox,
+ const TRect& aOuterBox,
+ const CFont* aFont,
+ CMnrpMapModel::TGrid& aGrid ) const
+ {
+ aGc.UseFont( aFont );
+
+ TBuf<KMaxCoordStrSize> latTopStr, latBottomStr, lonLeftStr, lonRightStr;
+ TBuf<KMaxCoordStrSize> gridMajorStr, latStr, lonStr;
+
+ MnrpUtils::CoordinateToString( iModel->Left(), lonLeftStr, ETrue );
+ MnrpUtils::CoordinateToString( iModel->Top(), latTopStr, ETrue );
+ MnrpUtils::CoordinateToString( iModel->Right(), lonRightStr, ETrue );
+ MnrpUtils::CoordinateToString( iModel->Bottom(), latBottomStr, ETrue );
+
+ if ( !iSelectionMode )
+ {
+ MnrpUtils::CoordinateToString( ( iModel->Right() + iModel->Left() ) / 2, lonStr, ETrue );
+ MnrpUtils::CoordinateToString( ( iModel->Top() + iModel->Bottom() ) / 2, latStr, ETrue );
+ }
+ else
+ {
+ MnrpUtils::CoordinateToString( iAbsoluteCursor.Longitude(), lonStr, ETrue );
+ MnrpUtils::CoordinateToString( iAbsoluteCursor.Latitude(), latStr, ETrue );
+ }
+
+ MnrpUtils::CoordinateToString( aGrid.iAbsoluteGridStep, gridMajorStr );
+
+ TRect lonBox( aInnerBox.iTl.iX, 0, aInnerBox.iBr.iX, aInnerBox.iBr.iY );
+ TRect latBox( 0, aInnerBox.iTl.iY, aInnerBox.iTl.iX, aInnerBox.iBr.iY );
+ TRect centerBox( aInnerBox.iTl.iX, aInnerBox.iBr.iY, aInnerBox.iBr.iX, aOuterBox.iBr.iY );
+
+ TInt textBaseLine = aFont->AscentInPixels() + KBorderSizeFactor / 2;
+ TInt vertTextBaseLine = aFont->AscentInPixels() + KBorderSizeFactor / 2;
+
+ aGc.SetPenColor( KGridTextColor );
+
+ aGc.DrawText( lonLeftStr, lonBox, textBaseLine, CGraphicsContext::ELeft );
+ aGc.DrawText( lonRightStr, lonBox, textBaseLine, CGraphicsContext::ERight );
+ aGc.DrawTextVertical( latTopStr, latBox, vertTextBaseLine, EFalse, CGraphicsContext::ELeft );
+ aGc.DrawTextVertical( latBottomStr, latBox, vertTextBaseLine, EFalse, CGraphicsContext::ERight );
+
+ aGc.DrawText( gridMajorStr, lonBox, textBaseLine, CGraphicsContext::ECenter );
+
+ aGc.SetPenColor( KOriginMarkColor );
+ aGc.DrawText( latStr, centerBox, textBaseLine, CGraphicsContext::ELeft );
+ aGc.DrawText( lonStr, centerBox, textBaseLine, CGraphicsContext::ERight );
+
+ aGc.DiscardFont();
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CMnrpMapControl::DrawCursor( CWindowGc& aGc ) const
+ {
+ aGc.SetPenColor( KCursorColor );
+ aGc.SetPenSize( TSize( 1, 1 ) );
+ aGc.SetDrawMode( CGraphicsContext::EDrawModeNOTSCREEN );
+
+ TRect cursorCircleRect( iCursor, TSize( 0, 0 ) );
+ cursorCircleRect.Grow( KCursorCircleRadius, KCursorCircleRadius );
+ aGc.DrawEllipse( cursorCircleRect );
+
+ // upper vertical line
+ aGc.DrawLine( TPoint( iCursor.iX, cursorCircleRect.iTl.iY ),
+ TPoint( iCursor.iX, cursorCircleRect.iTl.iY - KCursorArrowSize ) );
+ // lower vertical line
+ aGc.DrawLine( TPoint( iCursor.iX, cursorCircleRect.iBr.iY ),
+ TPoint( iCursor.iX, cursorCircleRect.iBr.iY + KCursorArrowSize ) );
+
+ // left horiz line
+ aGc.DrawLine( TPoint( cursorCircleRect.iTl.iX, iCursor.iY ),
+ TPoint( cursorCircleRect.iTl.iX - KCursorArrowSize, iCursor.iY ) );
+ // right horiz line
+ aGc.DrawLine( TPoint( cursorCircleRect.iBr.iX, iCursor.iY ),
+ TPoint( cursorCircleRect.iBr.iX + KCursorArrowSize, iCursor.iY ) );
+
+ aGc.SetDrawMode( CGraphicsContext::EDrawModePEN );
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CMnrpMapControl::SizeChanged()
+ {
+ TRect rect( Rect() );
+
+ DestroyFonts();
+ CreateFonts();
+
+ rect.Shrink( BorderSize() );
+ iViewSize = rect.Size();
+ iModel->SetScreenSize( iViewSize );
+ TRAP_IGNORE( CreateScreenBufferL( rect.Size() ) );
+ TRAP_IGNORE( RenderL() );
+ DrawDeferred();
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CMnrpMapControl::HandleResourceChange( TInt aType )
+ {
+ CCoeControl::HandleResourceChange( aType );
+ if ( aType == KEikDynamicLayoutVariantSwitch )
+ {
+ SetFullScreen( iIsFullScreen );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CMnrpMapControl::ToggleFullScreen()
+ {
+ SetFullScreen( !iIsFullScreen );
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CMnrpMapControl::SetFullScreen( TBool aFullScreen )
+ {
+ iIsFullScreen = aFullScreen;
+ if ( iIsFullScreen)
+ {
+ SetExtentToWholeScreen();
+ }
+ else
+ {
+ SetRect( iView.ClientRect() );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CMnrpMapControl::MoveCursor( TInt aXmove, TInt aYmove )
+ {
+ iCursor += TPoint( aXmove, aYmove );
+
+ iCursor.iX = Max( 0, iCursor.iX );
+ iCursor.iX = Min( iViewSize.iWidth, iCursor.iX );
+
+ iCursor.iY = Max( 0, iCursor.iY );
+ iCursor.iY = Min( iViewSize.iHeight, iCursor.iY );
+
+ // verify cursor margin
+ TRect cursorMargin = CursorMargin();
+
+ iAbsoluteCursor = iModel->ScreenToAbsolute( iCursor );
+
+ TReal xcorrection = 0;
+ TReal ycorrection = 0;
+
+ if ( aXmove > 0 ) // moving right
+ {
+ TInt toMargin = iCursor.iX - cursorMargin.iBr.iX;
+ if ( toMargin > 0 ) // cursor went beyond cursor margin, move view
+ {
+ xcorrection = iModel->ScreenToAbsolute( toMargin );
+ }
+ }
+ else if ( aXmove < 0 ) // moving left
+ {
+ TInt toMargin = iCursor.iX - cursorMargin.iTl.iX;
+ if ( toMargin < 0 )
+ {
+ xcorrection = iModel->ScreenToAbsolute( toMargin );
+ }
+ }
+
+ if ( aYmove > 0 ) // moving down
+ {
+ TInt toMargin = iCursor.iY - cursorMargin.iBr.iY;
+ if ( toMargin > 0 )
+ {
+ ycorrection = -iModel->ScreenToAbsolute( toMargin );
+ }
+ }
+ else if ( aYmove < 0 ) // moving up
+ {
+ TInt toMargin = iCursor.iY - cursorMargin.iTl.iY;
+ if ( toMargin < 0 )
+ {
+ ycorrection = -iModel->ScreenToAbsolute( toMargin );
+ }
+ }
+
+ TCoordinate center = iModel->Center();
+ TCoordinate moveTo(
+ center.Latitude() + ycorrection,
+ center.Longitude() + xcorrection );
+ iModel->MoveTo( moveTo );
+
+ iCursor = iModel->AbsoluteToScreen( iAbsoluteCursor );
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TRect CMnrpMapControl::CursorMargin()
+ {
+ TRect rect( iViewSize );
+ rect.Shrink( KCursorMarginSize, KCursorMarginSize );
+ return rect;
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CMnrpMapControl::Zoom( TReal aRate )
+ {
+ if ( iSelectionMode )
+ {
+ iModel->MoveTo( iAbsoluteCursor );
+ iModel->Zoom( aRate );
+ iCursor = iModel->AbsoluteToScreen( iAbsoluteCursor );
+ }
+ else
+ {
+ iModel->Zoom( aRate );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TSize CMnrpMapControl::BorderSize() const
+ {
+ TSize size( 0, 0 );
+ if ( iTextFont )
+ {
+ TInt fontHeight = iTextFont->HeightInPixels();
+
+ size.iWidth = size.iHeight = TInt( fontHeight + KBorderSizeFactor );
+ }
+ return size;
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+void CMnrpMapControl::RenderL()
+ {
+ TRect rect = Rect();
+ TRect border( rect );
+ border.Shrink( BorderSize() );
+
+ if ( iOffScreenBitmap && iTextFont && iItemFont )
+ {
+ iModel->RenderL( *iOffScreenBitmap, TRect( border.Size() ), iTextFont, iItemFont );
+ }
+ }