00001 /***************************************************************************** 00002 * 00003 * $RCSfile: SkyviewForm_8c-source.html,v $ 00004 * 00005 * GPS4Palm Sky View Form 00006 * 00007 * This program is Copyright (C) 03/2003 Matthias Prinke 00008 * <matthias.prinke@surfeu.de> and covered by GNU's GPL. 00009 * In particular, this program is free software and comes WITHOUT 00010 * ANY WARRANTY. 00011 * 00012 * $Author: mp $ 00013 * 00014 * $Date: 2007-10-08 20:40:34 $ 00015 * 00016 * $Revision: 1.7.2.1 $ 00017 * 00018 * $Log: SkyviewForm_8c-source.html,v $ 00018 * Revision 1.7.2.1 2007-10-08 20:40:34 mp 00018 * updated for gps4palm V0.9.5 beta 00018 * 00019 * Revision 1.19 2005-05-06 13:37:47 mp 00020 * added High-Density Display support 00021 * 00022 * Revision 1.18 2005/04/02 10:09:43 mp 00023 * modified Position2Clipboard() and Position2Geodb() to return 'handled' 00024 * 00025 * Revision 1.17 2005/04/02 07:26:59 mp 00026 * added PosgeodbMenu event handling 00027 * 00028 * Revision 1.16 2005/03/25 13:45:11 mp 00029 * added PosclipMenu event handling 00030 * 00031 * Revision 1.15 2005/01/23 18:40:29 mp 00032 * added PortsMenu event handling 00033 * 00034 * Revision 1.14 2004/12/08 20:48:23 mp 00035 * added track logging 00036 * 00037 * Revision 1.13 2004/11/30 20:44:19 mp 00038 * added TrackMenu event handling 00039 * 00040 * Revision 1.12 2004/11/27 10:20:31 mp 00041 * replaced error handling code by calling Die() 00042 * 00043 * Revision 1.11 2004/11/26 20:08:36 mp 00044 * added error handling for WinCreateOffscreenWindow() 00045 * 00046 * Revision 1.10 2004/11/25 20:08:42 mp 00047 * added NotifyApproach() 00048 * 00049 * Revision 1.9 2004/11/25 16:57:46 mp 00050 * added function call UpdateActWpt() 00051 * 00052 * Revision 1.8 2004/11/24 21:27:49 mp 00053 * moved static function declarations from header to implementation file, 00054 * added AboutForm menu event handling 00055 * 00056 * Revision 1.7 2004/11/23 17:47:31 mp 00057 * removed unused variable 00058 * 00059 * Revision 1.6 2004/04/29 18:18:15 mp 00060 * added RouteForm, modified for doxygen 00061 * 00062 * Revision 1.5 2004/02/28 17:21:43 mp 00063 * added menuEvent WaypointMenu 00064 * 00065 * Revision 1.4 2003/11/20 20:46:31 mp 00066 * added status redraw on frmOpenEvent, added Menu Event MapOptsMenu 00067 * 00068 * Revision 1.3 2003/11/18 20:54:49 mp 00069 * Added MiscOptsMenu, added current Form to Application Preferences. 00070 * 00071 * Revision 1.2 2003/10/20 17:24:48 mp 00072 * added field deallocation and gSkyViewH window handle deletion on frmCloseEvent 00073 * 00074 * Revision 1.1.1.1 2003/07/14 18:59:29 mp 00075 * Imported GPS4Palm to CVS revision control. 00076 * 00077 * 00078 ****************************************************************************/ 00079 #include <PalmOS.h> 00080 #include "ResourceDefines.h" 00081 #include "Serial.h" 00082 #include "Sinetab.h" 00083 #include "SkyviewForm.h" 00084 #include "GPS.h" 00085 #include "HandleMessage.h" 00086 #include "Utils.h" 00087 #include "Data.h" /* UpdateActWpt() */ 00088 #include "Clip.h" 00089 #include "common.h" 00090 00091 /** SkyView window handle for save-behind (Sky View Plot). */ 00092 WinHandle gSkyViewH; 00093 00094 /* Preferences data structure */ 00095 extern PrefsType gPrefs; 00096 00097 /* GPS Data */ 00098 extern GPSType gGPSData; 00099 00100 /* High-Density Display */ 00101 extern Boolean gHdFtrSet; 00102 00103 #ifndef WinDrawPixel 00104 #define WinDrawPixel(x,y) WinDrawLine((x),(y),(x),(y)) 00105 #endif 00106 00107 00108 /* Static Functions */ 00109 static void SkyviewFormInit(void) SKYVIEW_SECTION; 00110 static void DrawSkyView(void) SKYVIEW_SECTION; 00111 00112 00113 static 00114 void SkyviewFormInit(void) 00115 { 00116 gFormOpened = true; 00117 } 00118 00119 static 00120 void DrawSkyView(void) 00121 { 00122 Coord maxx; /* screen width */ 00123 Coord maxy; /* screen height */ 00124 UInt16 x; /* x-coordinate */ 00125 UInt16 y; /* y-coordinate */ 00126 PointType p1; /* a point */ 00127 PointType p2; /* another point */ 00128 UInt16 r; /* radius */ 00129 UInt16 phi; /* angle */ 00130 UInt16 err; /* error code */ 00131 RectangleType rect; /* rectangle structure */ 00132 00133 if (gHdFtrSet) { 00134 WinPushDrawState(); 00135 WinSetCoordinateSystem(kCoordinatesNative); 00136 } 00137 00138 /* get screen dimensions */ 00139 WinGetDisplayExtent(&maxx, &maxy); 00140 00141 /* Base line for S/N bar graph */ 00142 y = (gHdFtrSet) ? WinScaleCoord(SKY_L2, false) : SKY_L2; 00143 WinDrawLine(0, y, maxx-1, y); 00144 y = (gHdFtrSet) ? WinScaleCoord(SKY_L1, false) : SKY_L1; 00145 WinDrawLine(0, y, maxx-1, y); 00146 00147 /* Tick marks for S/N bar graph */ 00148 for (y=SKY_L1+5; y<SKY_L2; y += 5) { 00149 /* left */ 00150 p1.x = 0; 00151 p1.y = y; 00152 p2.x = 2; 00153 p2.y = y; 00154 00155 if (gHdFtrSet) { 00156 WinScalePoint(&p1, false); 00157 WinScalePoint(&p2, false); 00158 } 00159 00160 WinDrawLine(p1.x, p1.y, p2.x, p2.y); 00161 00162 /* right */ 00163 p1.x = 157; 00164 p1.y = y; 00165 p2.x = 159; 00166 p2.y = y; 00167 00168 if (gHdFtrSet) { 00169 WinScalePoint(&p1, false); 00170 WinScalePoint(&p2, false); 00171 } 00172 00173 WinDrawLine(p1.x, p1.y, maxx-1, p2.y); 00174 00175 } /* for (y=SKY_L1+5; y<SKY_L2; y += 5) */ 00176 00177 /* Outer circle */ 00178 r = (gHdFtrSet) ? WinScaleCoord(SKY_R2, false) : SKY_R2; 00179 p1.x = (gHdFtrSet) ? WinScaleCoord(SKY_X, false) : SKY_X; 00180 p1.y = (gHdFtrSet) ? WinScaleCoord(SKY_Y, false) : SKY_Y; 00181 for (phi=0; phi<360; phi++) { 00182 /* Sinus/Cosinus functions using table lookup */ 00183 x = p1.x + r * icos(phi) / 32768; 00184 y = p1.y - r * isin(phi) / 32768; 00185 00186 /* 00187 * Note: 00188 * For High-Density, a step size of one degree does not provide 00189 * enough points for a continuous circle. Connecting the points 00190 * with a line seems to work good enough. (and is still fast) 00191 */ 00192 if (phi == 0) { 00193 WinDrawPixel(x, y); 00194 } else { 00195 WinDrawLine(x, y, p2.x, p2.y); 00196 } 00197 p2.x = x; 00198 p2.y = y; 00199 } /* for (phi=0; phi<360; phi++) */ 00200 00201 /* Inner circle */ 00202 r = (gHdFtrSet) ? WinScaleCoord(SKY_R1, false) : SKY_R1; 00203 for (phi=0; phi<360; phi++) { 00204 /* Sinus/Cosinus functions using table lookup */ 00205 x = p1.x + r * icos(phi) / 32768; 00206 y = p1.y - r * isin(phi) / 32768; 00207 00208 WinDrawPixel(x, y); 00209 } /* for (phi=0; phi<360; phi++) */ 00210 00211 /* Center */ 00212 p1.x = SKY_X-2; 00213 p1.y = SKY_Y; 00214 p2.x = SKY_X+2; 00215 p2.y = SKY_Y; 00216 if (gHdFtrSet) { 00217 WinScalePoint(&p1, false); 00218 WinScalePoint(&p2, false); 00219 } 00220 WinDrawLine(p1.x, p1.y, p2.x, p2.y); 00221 00222 p1.x = SKY_X; 00223 p1.y = SKY_Y-2; 00224 p2.x = SKY_X; 00225 p2.y = SKY_Y+2; 00226 if (gHdFtrSet) { 00227 WinScalePoint(&p1, false); 00228 WinScalePoint(&p2, false); 00229 } 00230 WinDrawLine(p1.x, p1.y, p2.x, p2.y); 00231 00232 p1.x = 2 * SKY_R2; 00233 p1.y = 2 * SKY_R2; 00234 if (gHdFtrSet) WinScalePoint(&p1, false); 00235 gSkyViewH = WinCreateOffscreenWindow(p1.x, p1.y, nativeFormat, &err); 00236 00237 if (!gSkyViewH) { 00238 /* error handling */ 00239 Die("Cannot create OffscreenWindow in SkyviewForm!"); 00240 return; 00241 } 00242 00243 p1.x = SKY_X-SKY_R2; 00244 p1.y = SKY_Y-SKY_R2; 00245 if (gHdFtrSet) WinScalePoint(&p1, false); 00246 x = y = (gHdFtrSet) ? WinScaleCoord(2 * SKY_R2, false) : 2 * SKY_R2; 00247 RctSetRectangle(&rect, p1.x, p1.y, x /* w */, y /* h */); 00248 00249 WinCopyRectangle( NULL, /* WinHandle srcWin, draw window */ 00250 gSkyViewH, /* WinHandle dstWin, draw window */ 00251 &rect, /* RectangleType *srcRect */ 00252 0, /* Coord destX */ 00253 0, /* Coord destY */ 00254 winPaint /* WinDrawOperation mode */); 00255 00256 if (gHdFtrSet) { 00257 WinPopDrawState(); 00258 } 00259 } 00260 00261 00262 /****************************************************************************/ 00263 /** 00264 * \brief Sky View Form event handler 00265 * 00266 * \param event pointer to event structure 00267 * 00268 * \return event handled flag 00269 ****************************************************************************/ 00270 Boolean SkyviewFormHandleEvent(EventPtr event) 00271 { 00272 Boolean handled; 00273 Boolean updatedDisplay; 00274 00275 handled = false; 00276 switch (event->eType) 00277 { 00278 case menuEvent: 00279 switch (event->data.menu.itemID) { 00280 00281 case PositionMenu: 00282 FrmGotoForm(GPSMainForm); 00283 handled = true; 00284 break; 00285 00286 case NavigationMenu: 00287 FrmGotoForm(NavigationForm); 00288 handled = true; 00289 break; 00290 00291 case MapMenu: 00292 FrmGotoForm(MapForm); 00293 handled = true; 00294 break; 00295 00296 case MiscOptsMenu: 00297 FrmGotoForm(MiscOptsForm); 00298 handled = true; 00299 break; 00300 00301 case MapOptsMenu: 00302 FrmGotoForm(MapOptsForm); 00303 handled = true; 00304 break; 00305 00306 case PortsMenu: 00307 if (gNewSerialManager) { 00308 FrmGotoForm(GPSPortForm); 00309 } 00310 handled = true; 00311 break; 00312 00313 case WaypointMenu: 00314 FrmGotoForm(WaypointForm); 00315 handled = true; 00316 break; 00317 00318 case RouteMenu: 00319 FrmGotoForm(RouteForm); 00320 handled = true; 00321 break; 00322 00323 case TrackMenu: 00324 FrmGotoForm(TrackForm); 00325 handled = true; 00326 break; 00327 00328 case PosclipMenu: 00329 handled = Position2Clipboard(gGPSData, gPrefs.units); 00330 break; 00331 00332 case PosgeodbMenu: 00333 handled = Position2Geodb(gGPSData); 00334 break; 00335 00336 case AboutMenu: 00337 FrmGotoForm(AboutForm); 00338 handled = true; 00339 break; 00340 00341 #ifdef DEBUG_FORM 00342 case DebugMenu: 00343 FrmGotoForm(DebugForm); 00344 handled = true; 00345 break; 00346 #endif 00347 } 00348 break; 00349 00350 case nilEvent: 00351 handled = true; 00352 /* throw away anything in the buffer-- we want fresh data */ 00353 DoReceiveFlush(gPortID, 1); 00354 00355 /* read data from GPS */ 00356 updatedDisplay = ReadFromGPS(); 00357 00358 if (gGPSData.valid && gPrefs.act_rte.valid && gPrefs.auto_wpt) { 00359 /* update active waypoint */ 00360 UpdateActWpt(gGPSData.lat, gGPSData.lon, false /* init */); 00361 } 00362 00363 /* Active Waypoint approach detection and display */ 00364 NotifyApproach(); 00365 00366 /* Track Logging */ 00367 if (gPrefs.act_trk.log_state) { 00368 Boolean new_trk; 00369 00370 if (TrackIntervalCheck(false /* init */, &new_trk)) { 00371 TrackWriteLog(new_trk); 00372 } 00373 } 00374 00375 break; 00376 00377 case frmOpenEvent: 00378 gPrefs.form = SkyviewForm; 00379 00380 SkyviewFormInit(); 00381 FrmDrawForm(FrmGetActiveForm()); 00382 DrawSkyView(); 00383 UpdateStatus(STAT_REDRAW); 00384 00385 handled = true; 00386 break; 00387 00388 case frmCloseEvent: 00389 /* Deallocate Fields' Text Memory */ 00390 SetFieldText(SkyViewStatusField, NULL, false, true); 00391 SetFieldText(TimeField, NULL, false, true); 00392 SetFieldText(PDOPField, NULL, false, true); 00393 SetFieldText(HDOPField, NULL, false, true); 00394 SetFieldText(VDOPField, NULL, false, true); 00395 SetFieldText(FixField, NULL, false, true); 00396 SetFieldText(SatsField, NULL, false, true); 00397 SetFieldText(BatField, NULL, false, true); 00398 if (gSkyViewH) 00399 WinDeleteWindow(gSkyViewH, true /* eraseIt */); 00400 handled = false; 00401 break; 00402 } 00403 return(handled); 00404 } /* SkyviewFormHandleEvent() */