mapnavproviderrefapp/src/mnrpmapcontrol.cpp
branchRCL_3
changeset 18 870918037e16
parent 0 522cd55cc3d7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mapnavproviderrefapp/src/mnrpmapcontrol.cpp	Wed Sep 01 12:31:27 2010 +0100
@@ -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 );
+        }
+    }