diff -r 1fc85118c3ae -r 870918037e16 mapnavproviderrefapp/src/mnrpmapcontrol.cpp --- /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 +#include +#include +#include + +#include +#include + +#include + +#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 latTopStr, latBottomStr, lonLeftStr, lonRightStr; + TBuf 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 ); + } + }