⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mapper.c

📁 CD_高级PALM编程
💻 C
📖 第 1 页 / 共 2 页
字号:
/********************************************************************* FILE:				Mapper.c** DESCRIPTION:	The Mapper user interface** VERSION:		1.0**********************************************************************/#include <PalmOS.h>#include <PalmCompatibility.h>#include "Map.h"#include "Utils.h"#include "UtilsRsc.h"#include "MapperRsc.h"#include "Mapper.h"// These are used by MainFormDraw. We don't get them from the gadget// because the draw routine needs to be fast.#define mapGadgetHeight ( 145 )#define mapGadgetWidth ( 145 )#define mapMinPenMoveForScroll ( 2 )#define mapHitRadius ( 6 )#define mapLabelHeight (12 )#define mapLabelWidth ( 120 )const RectangleType mapGadgetRect = { 0, 15, 145, 160 };// fast absolute value for integers.#define ABS( x ) ( ( x < 0 ? 0 - x : x ) )typedef enum _EMapZoomLevel{	mapZoomNone = 0,	mapZoomLow = 1,	mapZoomHigh = 2} EMapZoomLevel;typedef struct _TPanllInfo{	TMapInfoTypePtr	mapP;	PointType mapOrigin;	EMapZoomLevel zoom;	TMapLayerPtr layerP;	TMapLabel layerLabelP;	PointType layerPOICoord;} TPanllInfoType, *TPanllInfoTypePtr;// prototypesvoid MainFormZoom(	PointType *mapPointP,	TPanllInfoTypePtr panInfoP );static void MainFormStopPan( 	FormType *frmP	// (in) Active Form);static void MainFormDoScroll( 	FormType *frmP,		// Current form	Coord dx, Coord dy	// delta to scroll);static void MainFormDoMapTap( 	FormType *frmP,	Coord x, Coord y // (in) point on which tap occurred);// utility function/*********************************************************************** * FUNCTION:    	RestrictToDisplay * * DESCRIPTION: 	This routine initializes the MainForm form. * * RETURNED:    	nothing ***********************************************************************/ static void RestrictToDisplay(	TPanllInfoTypePtr panInfoP,	// (in) current map scroll info	Coord *xP, Coord *yP			// (in) where we'd like to be									// (out) where we should draw to keep the map on the screen){	PointType *fixPointP, *newPointP, point;// If the new point is outside the map bounds when drawn, clip appropriately.	point.x = *xP; 	point.y = *yP;	newPointP = MapCoordToScreenCoord( &point, &mapGadgetRect );	point.x = 0; 	point.y = 0;	fixPointP = ScreenCoordToMapCoord( &point, &mapGadgetRect );// Clip x on the left	if ( newPointP->x > mapGadgetRect.topLeft.x )	{		*xP = fixPointP->x;	}// Clip y on the top	if ( newPointP->y > mapGadgetRect.topLeft.y )	{		*yP =  fixPointP->x;	}	point.x = panInfoP->mapP->mapBounds.extent.x + mapGadgetRect.topLeft.x; 	point.y = panInfoP->mapP->mapBounds.extent.y + mapGadgetRect.topLeft.y;	fixPointP = ScreenCoordToMapCoord( &point, &mapGadgetRect );// Clip x on the right	if ( newPointP->x + panInfoP->mapP->mapBounds.extent.x < mapGadgetRect.extent.x )	{		*xP = ABS(fixPointP->x);	}// Clip y on the bottom	if ( newPointP->y + panInfoP->mapP->mapBounds.extent.y < mapGadgetRect.extent.y )	{		*yP = ABS(fixPointP->y);	}}/*********************************************************************** * FUNCTION:    	MainFormInit * * DESCRIPTION: 	This routine initializes the MainForm form. * * RETURNED:    	nothing ***********************************************************************/ static void MainFormInit(	FormPtr	frmP		// Pointer to the MainForm form.){	TPanllInfoTypePtr panInfoP;	Err	anErr;	UInt32 depth = 8;	Boolean color = true;		// Set up the map scrolling object.		panInfoP = MemPtrNew( sizeof( TPanllInfoType ) ); 			panInfoP->mapP = MapFetchMap( mapBoulderCreek24, &anErr );	if ( anErr == noErr )	{// Begin by centering the map in the scrolling display.		panInfoP->mapOrigin.x = panInfoP->mapP->mapBounds.extent.x / 2;		panInfoP->mapOrigin.y = panInfoP->mapP->mapBounds.extent.y / 2;		panInfoP->layerP = MapFetchLayer( mapBoulderCreek24, mapLayerPOI, &anErr );		panInfoP->zoom = mapZoomLow;		MemSet( panInfoP->layerLabelP, sizeof( TMapLabel ), 0 );		panInfoP->layerPOICoord.x = panInfoP->layerPOICoord.y = 0;		FrmSetGadgetData ( frmP, FrmGetObjectIndex ( frmP, MainMapGadget ), panInfoP );	}	else	{		MemPtrFree( panInfoP );		FrmAlert( CantGetMapAlert );	}}/*********************************************************************** * FUNCTION:    	MainFormDrawMap * * DESCRIPTION: 	This routine draws the map * * RETURNED:    	nothing ***********************************************************************/inline static void MainFormDrawMap(	TPanllInfoTypePtr panInfoP,	PointType *screenPointP){	WinPaintBitmap( panInfoP->mapP->mapBitmapP, screenPointP->x, screenPointP->y );}/*********************************************************************** * FUNCTION:    	MainFormDrawMapLayer * * DESCRIPTION: 	This routine draws the map layer if necessary * * RETURNED:    	nothing ***********************************************************************/inline static void MainFormDrawMapLayer(	TPanllInfoTypePtr panInfoP,	PointType *screenPointP){	int i;	TMapPOILayerItemPtr poiP;	Handle layerBitmapH;	BitmapType *layerBitmapP;	int dx, dy;// If the layer's being displayed, draw stuff from the layer as well.	if ( panInfoP->layerP )	{		layerBitmapH = DmGetResource( bitmapRsc, 9900 );		if ( layerBitmapH )		{			layerBitmapP = (BitmapType *)MemHandleLock( layerBitmapH );				// Get an offset -- we want to draw the icon centered over the POI.			dx = layerBitmapP->width / 2;			dy = layerBitmapP->height / 2;			// For each POI, if it's on the current display, draw it.			for ( i = 0; i < panInfoP->layerP->count; i++ )			{				poiP = (TMapPOILayerItemPtr)&panInfoP->layerP->layerDataPtr[i];				screenPointP = MapCoordToTapCoord( &poiP->pos, &panInfoP->mapOrigin, &mapGadgetRect );				if ( RctPtInRectangle ( screenPointP->x, screenPointP->y, &mapGadgetRect) )				{					WinPaintBitmap( layerBitmapP, screenPointP->x-dx, screenPointP->y-dy );				}			}			MemHandleUnlock( layerBitmapH );			DmReleaseResource( layerBitmapH );		}	}}/*********************************************************************** * FUNCTION:    	MainFormDrawLabelLayer * * DESCRIPTION: 	This routine draws the map label layer if necessary * * RETURNED:    	nothing ***********************************************************************/static void MainFormDrawLabelLayer(	TPanllInfoTypePtr panInfoP,	PointType *screenPointP){	RectangleType rect;	int width;	int x, y;// If the layer's being displayed, draw stuff from the layer as well.	if ( StrLen( panInfoP->layerLabelP ) > 0 )	{		screenPointP = MapCoordToTapCoord( &panInfoP->layerPOICoord, &panInfoP->mapOrigin, &mapGadgetRect );		if ( RctPtInRectangle( screenPointP->x, screenPointP->y, &mapGadgetRect ) )		{			width = min( FntCharsWidth( panInfoP->layerLabelP, StrLen( panInfoP->layerLabelP ) ),  mapLabelWidth );		// Make sure the rectangle is on the screen.			x = screenPointP->x - mapLabelWidth / 2 > mapGadgetRect.topLeft.x ? 				screenPointP->x - mapLabelWidth / 2 : mapGadgetRect.topLeft.x;			x = ( x + width > mapGadgetRect.extent.x - 4 ) ? mapGadgetRect.extent.x - width - 4: x;						y = screenPointP->y - 4 - mapLabelHeight > mapGadgetRect.topLeft.y ? 				screenPointP->y - 4 - mapLabelHeight : mapGadgetRect.topLeft.y;			y = ( y + mapLabelHeight > mapGadgetRect.extent.y - 4 ) ? mapGadgetRect.extent.y - mapLabelHeight - 4 : y;						RctSetRectangle ( &rect, x, y, width, mapLabelHeight );			screenPointP->x = rect.topLeft.x + 1;			screenPointP->y = rect.topLeft.y + 1;			WinEraseRectangle( &rect, 0 );			WinPaintRectangleFrame( popupFrame, &rect );			WinDrawTruncChars( panInfoP->layerLabelP, StrLen( panInfoP->layerLabelP ),				screenPointP->x, screenPointP->y, mapLabelWidth - 2 );		}	}}/*********************************************************************** * FUNCTION:    	MainFormDraw * * DESCRIPTION: 	This routine draws the non-form contents of the MainForm form. * * RETURNED:    	nothing ***********************************************************************/static void MainFormDraw(	FormPtr	frmP		// Pointer to the MainForm form.){	if ( frmP != NULL ) 	{		TPanllInfoTypePtr panInfoP;		PointType mapPoint, *screenPointP;		panInfoP = FrmGetGadgetData ( frmP, 			FrmGetObjectIndex ( frmP, MainMapGadget ) );				if ( !panInfoP ) return;				mapPoint.x = panInfoP->mapOrigin.x;		mapPoint.y = panInfoP->mapOrigin.y;				screenPointP = MapCoordToScreenCoord( &mapPoint, &mapGadgetRect );					WinScreenLock( winLockCopy );		WinSetClip ( &mapGadgetRect );		WinPushDrawState( );				MainFormDrawMap ( panInfoP, screenPointP );		MainFormDrawMapLayer ( panInfoP, screenPointP );		MainFormDrawLabelLayer ( panInfoP, screenPointP );				WinPopDrawState ( );		WinResetClip ();		WinScreenUnlock ( );	}}/*********************************************************************** * FUNCTION:    	MainFormDone * * DESCRIPTION: 	This routine cleans up after the Main form. * * RETURNED:    	nothing ***********************************************************************/static void MainFormDone(	FormPtr	frmP		// Pointer to the MainForm form){	if ( frmP != NULL )	{		TPanllInfoTypePtr panInfoP;		panInfoP = FrmGetGadgetData ( frmP, FrmGetObjectIndex ( frmP, MainMapGadget ) );		// Deallocate the map window's bitmap and window		if ( panInfoP && panInfoP->mapP )		{			MapReleaseMap( panInfoP->mapP->mapID, panInfoP->mapP );			MapReleaseLayer( panInfoP->mapP->mapID, panInfoP->layerP );// Free the gadget's memory			MemPtrFree( panInfoP );		}	// Then do this as the very last thing		FrmEraseForm	( frmP );		FrmDeleteForm	( frmP );	}}/*********************************************************************** * FUNCTION:    	MainFormStartPan * * DESCRIPTION: 	Call before scrolling the map. * * RETURNED:    	nothing ***********************************************************************/static void MainFormStartPan( 	FormType *frmP	// (in) Active Form){	#pragma unused( frmP )	Boolean penDown;	Coord x, y;	Coord firstX, firstY;    Coord currX, currY;    Coord dx, dy;	// initialize	EvtGetPen (&currX, &currY, &penDown);	firstX = currX;	firstY = currY;	// loop while the pen is down and scroll		while( penDown == true )	{		EvtGetPen (&x, &y, &penDown);		dx = x - currX;		dy = y - currY;		MainFormDoScroll( frmP, dx, dy );		currX = x;		currY = y;	}	// handle pen up	if ( ABS( firstX - currX ) < mapMinPenMoveForScroll && 		 ABS( firstX - currY ) < mapMinPenMoveForScroll )	{		MainFormDoMapTap( frmP, firstX, firstY );	}	MainFormStopPan( frmP );	}/*********************************************************************** * FUNCTION:    	MainFormStopPan * * DESCRIPTION: 	Call after scrolling the map. * * RETURNED:    	nothing ***********************************************************************/static void MainFormStopPan( 	FormType *frmP	// (in) Active Form){	#pragma unused( frmP )}/*********************************************************************** * FUNCTION:    	MainFormDoScroll * * DESCRIPTION: 	This routine scrolls the map the specified amount * * RETURNED:    	nothing ***********************************************************************/static void MainFormDoScroll( 	FormType *frmP,		// Current form	Coord dx, Coord dy	// delta to scroll){	TPanllInfoTypePtr panInfoP;	Coord newX, newY;	panInfoP = FrmGetGadgetData ( frmP, FrmGetObjectIndex ( frmP, MainMapGadget ) );	if ( !panInfoP ) return;	// Secret sauce: scroll the map 2x as fast as pen moves.// Makes scrolling large maps easier, and gives a "psychic feel" to the// gadget.	dx *= 2;	dy *= 2;	newX = panInfoP->mapOrigin.x - dx;	newY = panInfoP->mapOrigin.y - dy;		RestrictToDisplay( panInfoP, &newX, &newY );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -