예제 #1
0
void MapWindow::Initialize() {
#ifndef ENABLE_OPENGL
    ScopeLock Lock(Surface_Mutex);
#endif
    // Reset common topology and waypoint label declutter, first init. Done also in other places.
    ResetLabelDeclutter();

    // Default draw area is full screen, no opacity
    MapRect = MainWindow.GetClientRect();
    DrawRect = MapRect;
    UpdateActiveScreenZone(MapRect);

    UpdateTimeStats(true);

#ifndef ENABLE_OPENGL
    // paint draw window black to start
    DrawSurface.SetBackgroundTransparent();
	DrawSurface.Blackness(MapRect.left, MapRect.top,MapRect.right-MapRect.left, MapRect.bottom-MapRect.top);

    hdcMask.SetBackgroundOpaque();
    BackBufferSurface.Blackness(MapRect.left, MapRect.top,MapRect.right-MapRect.left, MapRect.bottom-MapRect.top);
#endif

    // This is just here to give fully rendered start screen
    UpdateInfo(&GPS_INFO, &CALCULATED_INFO);
    MapDirty = true;

    FillScaleListForEngineeringUnits();
    zoom.RequestedScale(zoom.Scale());
    zoom.ModifyMapScale();

    LKUnloadFixedBitmaps();
    LKUnloadProfileBitmaps();

	LKLoadFixedBitmaps();
	LKLoadProfileBitmaps();

	// This will reset the function for the new ScreenScale
	PolygonRotateShift((POINT*)NULL,0,0,0,DisplayAngle+1);

	// Restart from moving map
	if (MapSpaceMode!=MSM_WELCOME) SetModeType(LKMODE_MAP, MP_MOVING);

	// These should be better checked. first_run is forcing also cache update for topo.
	ForceRenderMap=true;
	first_run=true;
    // Signal that draw thread can run now
    Initialised = TRUE;
#ifndef ENABLE_OPENGL
    drawTriggerEvent.set();
#endif
}
예제 #2
0
static void OnSelectClicked(WindowControl * Sender) {
  (void)Sender;

  if (s_selected<0 || s_selected>=MAXTHISTORY) {
	StartupStore(_T("... Invalid thermal selected to multitarget, out of range:%d %s"),s_selected,NEWLINE);
	DoStatusMessage(_T("ERR-126 invalid thermal"));
	return;
  }

  if (!ThermalHistory[s_selected].Valid) {
	DoStatusMessage(gettext(TEXT("ERR-127 invalid thermal selection")));
	return;
  }

  #if TESTBENCH
  StartupStore(_T("... Selected thermal n.%d <%s>\n"),s_selected,ThermalHistory[s_selected].Name);
  #endif

  SetThermalMultitarget(s_selected); // update selected multitarget

  LockTaskData();
  // now select the new one

  WayPointList[RESWP_LASTTHERMAL].Latitude  = ThermalHistory[s_selected].Latitude;
  WayPointList[RESWP_LASTTHERMAL].Longitude = ThermalHistory[s_selected].Longitude;
  WayPointList[RESWP_LASTTHERMAL].Altitude  = ThermalHistory[s_selected].HBase;
  
  wcscpy(WayPointList[RESWP_LASTTHERMAL].Name, ThermalHistory[s_selected].Name);

  UnlockTaskData();

  // switch to L> multitarget, and force moving map mode
  OvertargetMode=OVT_THER;
  SetModeType(LKMODE_MAP,MP_MOVING);

  wf->SetModalResult(mrOK);

}
예제 #3
0
// handle custom keys. Input: key pressed (center, left etc.)
// Returns true if handled successfully, false if not
//
// Passthrough mode for keys>=1000 (custom menu keys)
//
bool CustomKeyHandler(const int key) {

  int ckeymode;
  static bool doinit=true;
  static int oldModeIndex;

  if (doinit) {
	oldModeIndex=LKMODE_INFOMODE;;
	doinit=false;
  }

  if (key>=1000) {
	ckeymode=key-1000;
	LKASSERT((ckeymode>=0 && ckeymode<ckTOP));
	goto passthrough;
  }

  switch(key) {
	case CKI_BOTTOMCENTER:
		ckeymode=CustomKeyModeCenter;
		break;
	case CKI_BOTTOMLEFT:	
		ckeymode=CustomKeyModeLeft;
		break;
	case CKI_BOTTOMRIGHT:	
		ckeymode=CustomKeyModeRight;
		break;
	case CKI_BOTTOMICON:	
		ckeymode=CustomKeyModeAircraftIcon;
		break;
	case CKI_TOPLEFT:
		ckeymode=CustomKeyModeLeftUpCorner;
		break;
	case CKI_TOPRIGHT:
		ckeymode=CustomKeyModeRightUpCorner;
		break;
	case CKI_CENTERSCREEN:
		ckeymode=CustomKeyModeCenterScreen;
		break;
	default:
		DoStatusMessage(_T("ERR-725 UNKNOWN CUSTOMKEY"));
		return false;
		break;
  }

passthrough:

  switch(ckeymode) {
	case ckDisabled:
		break;
	case ckZoomIn:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		MapWindow::zoom.EventScaleZoom(1);
		return true;
		break;
	case ckZoomInMore:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		MapWindow::zoom.EventScaleZoom(2);
		return true;
		break;
	case ckZoomOut:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		MapWindow::zoom.EventScaleZoom(-1);
		return true;
		break;
	case ckZoomOutMore:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		MapWindow::zoom.EventScaleZoom(-2);
		return true;
		break;
	case ckMenu:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		ShowMenu();
		return true;
	case ckBackMode:
		PreviousModeIndex();
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckToggleMap: //TODO
		if (ModeIndex==LKMODE_MAP)
			SetModeIndex(oldModeIndex);
		else {
			oldModeIndex=ModeIndex;
			SetModeIndex(LKMODE_MAP);
		}
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;

	case ckTrueWind:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::setMode(_T("TrueWind"));
		return true;

	case ckTeamCode:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::eventSetup(_T("Teamcode"));
		return true;

	case ckToggleOverlays:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		ToggleMultimapOverlays();
		return true;

	case ckToggleMapLandable:
		if (ModeIndex==LKMODE_MAP)
			SetModeIndex(LKMODE_WP);
		else
			SetModeIndex(LKMODE_MAP);
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckLandables:
		SetModeIndex(LKMODE_WP);
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckToggleMapCommons:
		if (ModeIndex==LKMODE_MAP)
			SetModeIndex(LKMODE_NAV);
		else
			SetModeIndex(LKMODE_MAP);
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckCommons:
		SetModeIndex(LKMODE_NAV);
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckToggleMapTraffic:
		if (ModeIndex==LKMODE_MAP)
			SetModeIndex(LKMODE_TRF);
		else
			SetModeIndex(LKMODE_MAP);
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckTraffic:
		SetModeIndex(LKMODE_TRF);
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckInvertColors:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::eventInvertColor(NULL);
		return true;
	case ckTimeGates:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::eventTimeGates(NULL);
		return true;
	case ckMarkLocation:
		InputEvents::eventMarkLocation(_T(""));
		return true;
	case ckAutoZoom:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::eventZoom(_T("auto toggle"));
		InputEvents::eventZoom(_T("auto show"));
		return true;
	case ckActiveMap:
		// NO MORE USED BUT KEPT FOR OPTIMIZING COMPILER
		return true;
	case ckBooster:
		DoStatusMessage(_T("FEEL THE THERMAL"));
		if (EnableSoundModes) LKSound(_T("LK_BOOSTER.WAV"));
		return true;
	case ckGoHome:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		if (ValidWayPoint(HomeWaypoint)) {
			if ( (ValidTaskPoint(ActiveWayPoint)) && (Task[ActiveWayPoint].Index == HomeWaypoint )) {
	// LKTOKEN  _@M82_ = "Already going home" 
				DoStatusMessage(gettext(TEXT("_@M82_")));
			} else {
				GotoWaypoint(HomeWaypoint);
			}
		} else
	// LKTOKEN  _@M465_ = "No Home to go!" 
			DoStatusMessage(gettext(TEXT("_@M465_")));
		return true;
	case ckPanorama:
		if (PGZoomTrigger==false)
			PGZoomTrigger=true;
		else
			LastZoomTrigger=0;
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		return true;

	case ckMultitargetRotate:
		RotateOvertarget();
		return true;

	case ckMultitargetMenu:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::setMode(_T("MTarget"));
		return true;
	case ckBaroToggle:
		ToggleBaroAltitude();
		return true;
	case ckBasicSetup:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::eventSetup(_T("Basic"));
		return true;
	case ckSimMenu:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::setMode(_T("SIMMENU"));
		return true;
	case ckToggleMapAirspace:
		if (ModeIndex==LKMODE_MAP)
			SetModeType(LKMODE_WP,WP_AIRSPACES);
		else
			SetModeIndex(LKMODE_MAP);
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckAirspaceAnalysis:
		SetModeType(LKMODE_MAP,MP_MAPASP);
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckOptimizeRoute:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		PGOptimizeRoute=!PGOptimizeRoute;
		if (ISPARAGLIDER && PGOptimizeRoute) {
			AATEnabled = true;
            ClearOptimizedTargetPos();
		}
		return true;
	case ckLockScreen:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::eventService(_T("LOCKMODE"));
		return true;
	case ckWhereAmI:
		// no sound here, chime is played by service event
		InputEvents::eventService(_T("ORACLE"));
		return true;
	case ckUseTotalEnergy:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::eventService(_T("TOTALEN"));
		return true;
	case ckNotepad:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::eventChecklist(_T(""));
		return true;
	case ckTerrainColors:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::eventService(_T("TERRCOL"));
		return true;
	case ckNearestAirspace:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::eventNearestAirspaceDetails(NULL);
		return true;
	case ckOlcAnalysis:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::eventSetup(_T("OlcAnalysis"));
		return true;
	case ckTerrainColorsBack:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::eventService(_T("TERRCOLBACK"));
		return true;
	case ckForceFreeFlightRestart:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		if (!CALCULATED_INFO.Flying) {
			DoStatusMessage(MsgToken(922)); // NOT FLYING
		} else {
			if (MessageBoxX(hWndMapWindow, MsgToken(1754), _T(""), MB_YESNO|MB_ICONQUESTION) == IDYES) {
				LKSW_ForceFreeFlightRestart=true;
			}
		}
		return true;
	case ckCustomMenu1:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		extern void dlgCustomMenuShowModal(void);
		InputEvents::eventMode(_T("MYMODE"));
		return true;
	case ckTaskCalc:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::eventCalculator(NULL);
		return true;
	case ckTaskTarget:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::eventSetup(_T("Target"));
		return true;
	case ckArmAdvance:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::eventArmAdvance(_T("toggle"));
		InputEvents::eventArmAdvance(_T("show"));
		return true;

	case ckMessageRepeat:
		InputEvents::eventRepeatStatusMessage(NULL);
                return true;
		
	case ckWaypointLookup:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::eventWaypointDetails(_T("select"));
		return true;

	case ckPan:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		InputEvents::eventPan(_T("toggle"));
		return true;

	case ckWindRose:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		UseWindRose=!UseWindRose;
		return true;

	case ckFlarmRadar:
		SetModeType(LKMODE_MAP,MP_RADAR);
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckDeviceA:
		if(devA() && devA()->Config) {
			devA()->Config(devA());
		}
		return true;
	case ckDeviceB:
		if(devB() && devB()->Config) {
			devB()->Config(devB());
		}
		return true;
	case ckResetOdometer:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		if (MessageBoxX(hWndMapWindow, MsgToken(2229), _T(""), MB_YESNO|MB_ICONQUESTION) == IDYES) {
			LKSW_ResetOdometer=true;
		}
		return true;
	case ckForceLanding:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		if ( !CALCULATED_INFO.Flying ) {
			DoStatusMessage(MsgToken(922)); // NOT FLYING
		} else {
			if ( (GPS_INFO.Speed > TakeOffSpeedThreshold) && (!GPS_INFO.NAVWarning) ) {
				DoStatusMessage(MsgToken(1799)); // STOP MOVING!
			} else {
				if (MessageBoxX(hWndMapWindow, MsgToken(2230), _T(""), MB_YESNO|MB_ICONQUESTION) == IDYES) {
					LKSW_ForceLanding=true;
				}
			}
		}
		return true;
	case ckResetTripComputer:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
		if (MessageBoxX(hWndMapWindow, MsgToken(2236), _T(""), MB_YESNO|MB_ICONQUESTION) == IDYES) {
			LKSW_ResetTripComputer=true;
		}
		return true;
	case ckSonarToggle:
		SonarWarning = !SonarWarning;
		TCHAR sonarmsg[60];
		_stprintf(sonarmsg,_T("%s "),MsgToken(1293)); // SONAR
		if (SonarWarning)
			_tcscat(sonarmsg,MsgToken(1643)); // ENABLED
		else
			_tcscat(sonarmsg,MsgToken(1600)); // DISABLED
		DoStatusMessage(sonarmsg,NULL,false);
		if (EnableSoundModes) {
			if (SonarWarning)
				LKSound(TEXT("LK_TONEUP.WAV"));
			else
				LKSound(TEXT("LK_TONEDOWN.WAV"));
		}
		return true;
	case ckResetView:
		ModeType[LKMODE_MAP]    =       MP_MOVING;
		ModeType[LKMODE_INFOMODE]=      IM_CRUISE;
		ModeType[LKMODE_WP]     =       WP_AIRPORTS;
		ModeType[LKMODE_NAV]    =       NV_COMMONS;
		ModeType[LKMODE_TRF]    =       TF_LIST;

		SetModeType(LKMODE_MAP,MP_MOVING);
		MapWindow::RefreshMap();
		SoundModeIndex();

		return true;

	case  ckMapOrient:
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif

		TCHAR MapOrientMsg[60];

	    if  (MapSpaceMode==MSM_MAP)
	    {
	      DisplayOrientation++;
	      if(DisplayOrientation > NORTHSMART)
	    	DisplayOrientation = 0;
	      MapWindow::SetAutoOrientation(true); // 101008 reset it
	      switch(DisplayOrientation)
	      {
            case TRACKUP     : _stprintf(MapOrientMsg,_T("%s"),gettext(TEXT("_@M737_"))) ; break;  // _@M737_ "Track up"
            case NORTHUP     : _stprintf(MapOrientMsg,_T("%s"),gettext(TEXT("_@M483_"))) ; break;  // _@M483_ "North up"
            case NORTHCIRCLE : _stprintf(MapOrientMsg,_T("%s"),gettext(TEXT("_@M482_"))) ; break;  // _@M482_ "North circling"
            case TRACKCIRCLE : _stprintf(MapOrientMsg,_T("%s"),gettext(TEXT("_@M682_"))) ; break;  // _@M682_ "Target circling"  _@M485_ "NorthUp above "
            case NORTHTRACK  : _stprintf(MapOrientMsg,_T("%s"),gettext(TEXT("_@M484_"))) ; break;  // _@M484_ "North/track"
            case NORTHSMART  : _stprintf(MapOrientMsg,_T("%s"),gettext(TEXT("_@M481_"))) ; break;  // _@M481_ "North Smart"
	      }
	      DoStatusMessage(MapOrientMsg,NULL,false);
	    }
	    else
	    {
		  SetMMNorthUp(GetSideviewPage(), (GetMMNorthUp(GetSideviewPage())+1)%2);
	    }

		return true;
    case ckResetComm:
        #ifndef DISABLEAUDIO
		if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK"));
		#endif
        InputEvents::eventRestartCommPorts(NULL);
        return true;
	default:
		DoStatusMessage(_T("ERR-726 INVALID CUSTOMKEY"));
		StartupStore(_T("... ERR-726 INVALID CUSTOMKEY=%d\n"),ckeymode);
		break;
  }

  return false;

}
예제 #4
0
static void OnTargetClicked(WindowControl * Sender) {
  (void)Sender;

  if (SelectedTraffic<0 || SelectedTraffic>MAXTRAFFIC) {
	StartupStore(_T("--- Invalid traffic selected to Target, out of range%s"),NEWLINE);
	DoStatusMessage(_T("ERR-126 invalid TARGET traffic"));
	return;
  }
  if ( GPS_INFO.FLARM_Traffic[SelectedTraffic].ID <1 ) {
	DoStatusMessage(gettext(TEXT("_@M879_"))); // SORRY TARGET JUST DISAPPEARED
	return;
  }

  if ( LKTraffic[SelectedTraffic].Locked ) {
#if 0
	if (MessageBoxX(hWndMapWindow,
		gettext(TEXT("_@M880_")), // UNLOCK current target?
		gettext(TEXT("_@M881_")), // Target selection
	MB_YESNO|MB_ICONQUESTION) == IDYES) {

#endif
	LockFlightData();
	GPS_INFO.FLARM_Traffic[SelectedTraffic].Locked=false;
	UnlockFlightData();
	LKTargetIndex=-1;
	LKTargetType=LKT_TYPE_NONE;
	WayPointList[RESWP_FLARMTARGET].Latitude   = RESWP_INVALIDNUMBER;
	WayPointList[RESWP_FLARMTARGET].Longitude  = RESWP_INVALIDNUMBER;
	WayPointList[RESWP_FLARMTARGET].Altitude   = RESWP_INVALIDNUMBER;
	_tcscpy(WayPointList[RESWP_FLARMTARGET].Name,_T(RESWP_FLARMTARGET_NAME) );
	DoStatusMessage(gettext(TEXT("_@M882_"))); // TARGET RELEASED
	wf->SetModalResult(mrOK);
	return;
  }
#if 0
  if (MessageBoxX(hWndMapWindow, 
	gettext(TEXT("_@M884_")), // LOCK this target?
	gettext(TEXT("_@M881_")), // Target selection
  MB_YESNO|MB_ICONQUESTION) == IDYES) {
#endif
	// one more check for existance
	if ( GPS_INFO.FLARM_Traffic[SelectedTraffic].ID <1 ) {
		DoStatusMessage(gettext(TEXT("_@M883_"))); // TARGET DISAPPEARED!
		return;
	}

	LockFlightData();
	// unlock previous target, if any
	if (LKTargetIndex>=0 && LKTargetIndex<MAXTRAFFIC) {
		GPS_INFO.FLARM_Traffic[LKTargetIndex].Locked=false;
	}
	GPS_INFO.FLARM_Traffic[SelectedTraffic].Locked=true;
	UnlockFlightData();
	// LKTOKEN  _@M675_ = "TARGET LOCKED" 
	DoStatusMessage(gettext(TEXT("_@M675_")));
	LKTargetIndex=SelectedTraffic;
	LKTargetType=LKT_TYPE_MASTER;

	// Remember that we need to update the virtual waypoint constantly when we receive FLARM data of target
	// Probably name is not updated if changed from Flarm menu...
	OvertargetMode=OVT_FLARM;
	WayPointList[RESWP_FLARMTARGET].Latitude   = GPS_INFO.FLARM_Traffic[LKTargetIndex].Latitude;
	WayPointList[RESWP_FLARMTARGET].Longitude  = GPS_INFO.FLARM_Traffic[LKTargetIndex].Longitude;
	WayPointList[RESWP_FLARMTARGET].Altitude   = GPS_INFO.FLARM_Traffic[LKTargetIndex].Altitude;
	if (_tcslen(GPS_INFO.FLARM_Traffic[LKTargetIndex].Name) == 1) {
		_stprintf(WayPointList[RESWP_FLARMTARGET].Name,_T("%0x"),GPS_INFO.FLARM_Traffic[LKTargetIndex].ID);
	} else {
		_stprintf(WayPointList[RESWP_FLARMTARGET].Name,_T("%s"),GPS_INFO.FLARM_Traffic[LKTargetIndex].Name);
	}
	SetModeType(LKMODE_TRF, IM_TARGET);
  wf->SetModalResult(mrOK);

}

static void OnRenameClicked(WindowControl * Sender){
  (void)Sender;

  if (SelectedTraffic<0 || SelectedTraffic>MAXTRAFFIC) {
	StartupStore(_T("--- Invalid traffic selected to rename, out of range%s"),NEWLINE);
	DoStatusMessage(_T("ERR-126 invalid traffic"));
	return;
  }
  if ( LKTraffic[SelectedTraffic].ID <1 ) {
	StartupStore(_T("--- Invalid traffic selected to rename, invalid ID%s"),NEWLINE);
	DoStatusMessage(_T("ERR-127 invalid traffic"));
	return;
  }

  TCHAR newName[MAXFLARMNAME+1];
  newName[0] = 0;
  dlgTextEntryShowModal(newName, 7); // 100322 raised from 3 to 6 (+1)
  newName[MAXFLARMNAME] = 0;

  #ifdef DEBUG_LKT
  StartupStore(_T("************  dlgLK RenameClicked for slot=%d id=%lx status=%d oldname=<%s> newName=<%s>\n"),
	SelectedTraffic, 
	GPS_INFO.FLARM_Traffic[SelectedTraffic].ID,
	GPS_INFO.FLARM_Traffic[SelectedTraffic].Status,
	GPS_INFO.FLARM_Traffic[SelectedTraffic].Name,
	newName);
  #endif

  int newnamelen=_tcslen(newName);

  if (newnamelen>0) {

	LockFlightData();

	// Since we don-t know if a new PFLAA with this ID will arrive, and the UpdateNameFlag will be used,
	// we must change the name here now.
	_tcscpy(GPS_INFO.FLARM_Traffic[SelectedTraffic].Name,newName);
	// ... and here also, because SetValues is using this copy 
	_tcscpy(LKTraffic[SelectedTraffic].Name,newName);

	// we assume that no Cn is available, or in any case cannot be kept
	// If newName is smaller or equal to possible Cn, we use it entirely
	if (newnamelen<=MAXFLARMCN) {
		_tcscpy( GPS_INFO.FLARM_Traffic[SelectedTraffic].Cn, newName);
	} else {
		// else we create a fake Cn
		GPS_INFO.FLARM_Traffic[SelectedTraffic].Cn[0]=newName[0];
		GPS_INFO.FLARM_Traffic[SelectedTraffic].Cn[1]=newName[newnamelen-2];
		GPS_INFO.FLARM_Traffic[SelectedTraffic].Cn[2]=newName[newnamelen-1];
		GPS_INFO.FLARM_Traffic[SelectedTraffic].Cn[3]=_T('\0');
	}
	// update it temporarily so that it appears updated leaving the edit page
	_tcscpy(LKTraffic[SelectedTraffic].Cn,GPS_INFO.FLARM_Traffic[SelectedTraffic].Cn);

	// It will be useless, because we already updated the name.. but never mind.
	GPS_INFO.FLARM_Traffic[SelectedTraffic].UpdateNameFlag=true;
	// This will create the local flarmid entry, but won't update the structure in GPS_INFO
	// until a new PFLAA arrives from this ID. 
	AddFlarmLookupItem(GPS_INFO.FLARM_Traffic[SelectedTraffic].ID, newName, true);
	UnlockFlightData();

	#ifdef DEBUG_LKT
	StartupStore(_T("...... dlgLK RENAMED slot=%d id=%lx status=%d name=<%s>\n"),
	SelectedTraffic, 
	GPS_INFO.FLARM_Traffic[SelectedTraffic].ID,
	GPS_INFO.FLARM_Traffic[SelectedTraffic].Status,
	GPS_INFO.FLARM_Traffic[SelectedTraffic].Name);
	#endif
	// reload the name...
	SetValues(SelectedTraffic);

  }

}


static void OnCloseClicked(WindowControl * Sender){
	(void)Sender;
  wf->SetModalResult(mrOK);
}
예제 #5
0
//
// Called by LKDrawLook8000, this is what happens when we change mapspace mode, advancing through types.
// We paint infopages, nearest, tri, etc.etc.
// Normally there is plenty of cpu available because the map is not even calculated.
// This is why we bring to the Draw thread, in the nearest pages case, also calculations.
//
void MapWindow::DrawMapSpace(HDC hdc,  RECT rc ) {

  HFONT oldfont;
  HBRUSH hB;

  TextInBoxMode_t TextDisplayMode = {0};
  TCHAR Buffer[LKSIZEBUFFERLARGE*2];
#ifdef DRAWLKSTATUS
  bool dodrawlkstatus=false;
#endif

  static POINT p[10];

  if (MapSpaceMode==MSM_WELCOME) {
	if (INVERTCOLORS)
		hB=LKBrush_Petrol;
	  else
		hB=LKBrush_Mlight;
  } else {
	if (INVERTCOLORS)
	  hB=LKBrush_Mdark;
	else
	  hB=LKBrush_Mlight;

  }
  oldfont = (HFONT)SelectObject(hdc, LKINFOFONT); // save font

  if (MapSpaceMode!=MSM_WELCOME) FillRect(hdc,&rc, hB); 

  if (DoInit[MDI_DRAWMAPSPACE]) {
	p[0].x=0; p[0].y=rc.bottom-BottomSize-NIBLSCALE(2); p[1].x=rc.right-1; p[1].y=p[0].y;
	p[2].x=0; p[2].y=0; p[3].x=rc.right-1; p[3].y=0; // 091230 right-1
	p[4].x=0; p[4].y=0; p[5].x=0; p[5].y=rc.bottom-BottomSize-NIBLSCALE(2);
	p[6].x=rc.right-1; p[6].y=0; p[7].x=rc.right-1; p[7].y=rc.bottom-BottomSize-NIBLSCALE(2); // 091230 right-1

//	p[8].x=0; p[8].y=rc.bottom-BottomSize-NIBLSCALE(2); p[9].x=rc.right; p[9].y=p[8].y;

/*
StartupStore(_T("DOINIT DRAWMAPSPACE 21=%d=%d 22=%d=%d 23=%d=%d 24=%d=%d 31=%d=%d 32=%d=%d\n"),
ConfIP[LKMODE_WP][0],ConfIP21,
ConfIP[LKMODE_WP][1],ConfIP22,
ConfIP[LKMODE_WP][2],ConfIP23,
ConfIP[LKMODE_WP][3],ConfIP24,
ConfIP[LKMODE_NAV][0],ConfIP31,
ConfIP[LKMODE_NAV][1],ConfIP32);
*/

	if (MapSpaceMode==MSM_WELCOME) LoadSplash(hdc,_T("LKPROFILE"));
	DoInit[MDI_DRAWMAPSPACE]=false; 
  }

  // Paint borders in green, but only in nearest pages and welcome
  if (MapSpaceMode==MSM_WELCOME || (!IsMultiMap() && MapSpaceMode!=MSM_MAP) )
  {
	  if (INVERTCOLORS) {
		_DrawLine(hdc, PS_SOLID, NIBLSCALE(1), p[2], p[3], RGB_GREEN, rc);
		_DrawLine(hdc, PS_SOLID, NIBLSCALE(1), p[4], p[5], RGB_GREEN, rc);
		_DrawLine(hdc, PS_SOLID, NIBLSCALE(1), p[6], p[7], RGB_GREEN, rc);
		_DrawLine(hdc, PS_SOLID, NIBLSCALE(1), p[0], p[1], RGB_GREEN, rc);
	  } else {
		_DrawLine(hdc, PS_SOLID, NIBLSCALE(1), p[2], p[3], RGB_DARKGREEN, rc);
		_DrawLine(hdc, PS_SOLID, NIBLSCALE(1), p[4], p[5], RGB_DARKGREEN, rc);
		_DrawLine(hdc, PS_SOLID, NIBLSCALE(1), p[6], p[7], RGB_DARKGREEN, rc);
		_DrawLine(hdc, PS_SOLID, NIBLSCALE(1), p[0], p[1], RGB_DARKGREEN, rc);
	  }
  }


#ifdef DRAWLKSTATUS 
  if (LKevent==LKEVENT_NEWRUN) dodrawlkstatus=true;
#endif

  // We are entering mapspacemodes with no initial check on configured subpages.
  // Thus we need to ensure that the page is really available, or find the first valid.
  // However, this will prevent direct customkey access to pages!
  // Instead, we do it when we call next page from InfoPageChange
  // if (!ConfIP[ModeIndex][CURTYPE]) NextModeType();
  switch (MapSpaceMode) {
	case MSM_WELCOME:
#if (1)
		if (!DrawInfo.NAVWarning) { 
		static double firsttime=DrawInfo.Time;
		// delayed automatic exit from welcome mode
		if ( DrawInfo.Time > (firsttime+1.0) ) {
			SetModeType(LKMODE_MAP,MP_MOVING);
			LKevent=LKEVENT_NONE;
			if (EnableSoundModes) LKSound(_T("LK_BEEP1.WAV"));
			RefreshMap();
			break;
		}
		}
#endif
		if(GlobalModelType==MODELTYPE_PNA_MINIMAP)
		{
			SetModeType(LKMODE_MAP,MP_MOVING);
			LKevent=LKEVENT_NONE;
			break;
		}

		DrawWelcome8000(hdc, rc);
		break;
	case MSM_MAPTRK:
		SetSideviewPage(IM_HEADING);
		LKDrawMultimap_Asp(hdc,rc);
		break;
	case MSM_MAPWPT:
		#if 0
		// If there is no destination, force jump to the map
		if (GetOvertargetIndex()<0) {
			SetModeType(LKMODE_MAP,MP_MOVING);
			LKevent=LKEVENT_NONE;
			break;
		}
		#endif
		SetSideviewPage(IM_NEXT_WP);
		LKDrawMultimap_Asp(hdc,rc);
		break;
	case MSM_MAPASP:
		SetSideviewPage(IM_NEAR_AS);
		LKDrawMultimap_Asp(hdc,rc);
		break;
	case MSM_MAPRADAR:
		LKDrawMultimap_Radar(hdc,rc);
		break;
	case MSM_VISUALGLIDE:
		SetSideviewPage(IM_VISUALGLIDE);
		LKDrawMultimap_Asp(hdc,rc);
		break;
	case MSM_MAPTEST:
		LKDrawMultimap_Test(hdc,rc);
		break;
	case MSM_LANDABLE:
	case MSM_NEARTPS:
	case MSM_AIRPORTS:
		DrawNearest(hdc, rc);
		break;
	case MSM_AIRSPACES:
		DrawAspNearest(hdc, rc);
		break;
	case MSM_COMMON:
	case MSM_RECENT:
		DrawCommon(hdc, rc);
		break;
	case MSM_MAP:
		break;
	case MSM_INFO_THERMAL:
	case MSM_INFO_CRUISE:
	case MSM_INFO_TASK:
	case MSM_INFO_AUX:
	case MSM_INFO_TRI:
	case MSM_INFO_HSI:
	case MSM_INFO_TRF:
	case MSM_INFO_TARGET:
	case MSM_INFO_CONTEST:
		DrawInfoPage(hdc,rc, false);
		break;
	case MSM_TRAFFIC:
		DrawTraffic(hdc,rc);
		break;
	case MSM_THERMALS:
		DrawThermalHistory(hdc,rc);
		break;

  default:
    memset((void*)&TextDisplayMode, 0, sizeof(TextDisplayMode));
    TextDisplayMode.Color = RGB_WHITE;
    TextDisplayMode.NoSetFont = 1; 
    TextDisplayMode.AlligneCenter = 1;
    SelectObject(hdc, LK8TargetFont);
    _stprintf(Buffer,TEXT("MapSpaceMode=%d"),MapSpaceMode);
    TextInBox(hdc, &rc, Buffer, (rc.right-rc.left)/2, NIBLSCALE(50) , 0, &TextDisplayMode, false);
    break;
  }
#ifdef DRAWLKSTATUS
  // no need to clear dodrawlkstatus, it is already reset at each run
  if (dodrawlkstatus) DrawLKStatus(hdc, rc);
#endif
  SelectObject(hdc, oldfont); 
}
예제 #6
0
DWORD MapWindow::DrawThread (LPVOID lpvoid)
{

  FILETIME CreationTime, ExitTime, StartKernelTime, EndKernelTime, StartUserTime, EndUserTime ;


  while ((!ProgramStarted) || (!Initialised)) {
	Sleep(100);
  }

  #if TRACETHREAD
  StartupStore(_T("##############  DRAW threadid=%d\n"),GetCurrentThreadId());
  #endif


  // THREADRUNNING = FALSE;
  THREADEXIT = FALSE;

  // Reset common topology and waypoint label declutter, first init. Done also in other places.
  ResetLabelDeclutter();

  GetClientRect(hWndMapWindow, &MapRect);
  // Default draw area is full screen, no opacity
  DrawRect=MapRect;

  UpdateTimeStats(true);

  
  SetBkMode(hdcDrawWindow,TRANSPARENT);
  SetBkMode(hDCTemp,OPAQUE);
  SetBkMode(hDCMask,OPAQUE);

  // paint draw window black to start
  SelectObject(hdcDrawWindow, GetStockObject(BLACK_PEN));
  Rectangle(hdcDrawWindow,MapRect.left,MapRect.top,
            MapRect.right,MapRect.bottom);

  BitBlt(hdcScreen, 0, 0, MapRect.right-MapRect.left,
         MapRect.bottom-MapRect.top, 
         hdcDrawWindow, 0, 0, SRCCOPY);

  // This is just here to give fully rendered start screen
  UpdateInfo(&GPS_INFO, &CALCULATED_INFO);
  MapDirty = true;
  UpdateTimeStats(true);

  zoom.RequestedScale(zoom.Scale());
  zoom.ModifyMapScale();
  FillScaleListForEngineeringUnits();
  
  bool lastdrawwasbitblitted=false;
  bool first_run=true;

  // 
  // Big LOOP
  //

  while (!CLOSETHREAD) 
  {
	WaitForSingleObject(drawTriggerEvent, 5000);
	ResetEvent(drawTriggerEvent);
	if (CLOSETHREAD) break; // drop out without drawing

	if ((!THREADRUNNING) || (!GlobalRunning)) {
		Sleep(100);
		continue;
	}

	// This is also occuring on resolution change
	if (LKSW_ReloadProfileBitmaps) {
		#if TESTBENCH
		StartupStore(_T(".... SWITCH: ReloadProfileBitmaps detected\n"));
		#endif
		// This is needed to update resolution change
		GetClientRect(hWndMapWindow, &MapRect);
		DrawRect=MapRect;
		FillScaleListForEngineeringUnits();
		LKUnloadProfileBitmaps();
		LKLoadProfileBitmaps();
		LKUnloadFixedBitmaps();
		LKLoadFixedBitmaps();
		MapWindow::zoom.Reset();

		// This will reset the function for the new ScreenScale
		PolygonRotateShift((POINT*)NULL,0,0,0,DisplayAngle+1);

		// Restart from moving map
		if (MapSpaceMode!=MSM_WELCOME) SetModeType(LKMODE_MAP, MP_MOVING);

		LKSW_ReloadProfileBitmaps=false;
		// These should be better checked. first_run is forcing also cache update for topo.
		ForceRenderMap=true;
		first_run=true;
	}



	GetThreadTimes( hDrawThread, &CreationTime, &ExitTime,&StartKernelTime,&StartUserTime);

	// Until MapDirty is set true again, we shall only repaint the screen. No Render, no calculations, no updates.
	// This is intended for very fast immediate screen refresh.
	//
	// MapDirty is set true by:
	//   - TriggerRedraws()  in calculations thread
	//   - RefreshMap()      in drawthread generally
	//


	extern int XstartScreen, YstartScreen, XtargetScreen, YtargetScreen;
	extern bool OnFastPanning;
	// While we are moving in bitblt mode, ignore RefreshMap requests from LK
	// unless a timeout was triggered by MapWndProc itself.
	if (OnFastPanning) {
		MapDirty=false;
	} 

	// We must check if we are on FastPanning, because we may be in pan mode even while
	// the menu buttons are active and we are using them, accessing other functions.
	// In that case, without checking OnFastPanning, we would fall back here and repaint
	// with bitblt everytime, while instead we were asked a simple fastrefresh!
	//
	// Notice: we could be !MapDirty without OnFastPanning, of course!
	//
	if (!MapDirty && !ForceRenderMap && OnFastPanning && !first_run) {
		
		if (!mode.Is(Mode::MODE_TARGET_PAN) && mode.Is(Mode::MODE_PAN)) {

			int fromX=0, fromY=0;

			fromX=XstartScreen-XtargetScreen;
			fromY=YstartScreen-YtargetScreen;

			BitBlt(hdcScreen, 0, 0, 
				MapRect.right-MapRect.left, 
				MapRect.bottom-MapRect.top, 
				hdcDrawWindow, 0, 0, WHITENESS);


			BitBlt(hdcScreen, 0, 0,
				MapRect.right-MapRect.left,
				MapRect.bottom-MapRect.top, 
				hdcDrawWindow, 
				fromX,fromY, 				// source
				SRCCOPY);

			POINT centerscreen;
			centerscreen.x=ScreenSizeX/2; centerscreen.y=ScreenSizeY/2;
			DrawMapScale(hdcScreen,MapRect,false);
			DrawCrossHairs(hdcScreen, centerscreen, MapRect);
			lastdrawwasbitblitted=true;
		} else {
			// THIS IS NOT GOING TO HAPPEN!
			//
			// The map was not dirty, and we are not in fastpanning mode.
			// FastRefresh!  We simply redraw old bitmap. 
			//
			BitBlt(hdcScreen, 0, 0, MapRect.right-MapRect.left,
				MapRect.bottom-MapRect.top, 
				hdcDrawWindow, 0, 0, SRCCOPY);

			lastdrawwasbitblitted=true;
		}

		// Now we can clear the flag. If it was off already, no problems.
		OnFastPanning=false;
		continue;

	} else {
		//
		// Else the map wasy dirty, and we must render it..
		// Notice: if we were fastpanning, than the map could not be dirty.
		//

		#if 1 // --------------------- EXPERIMENTAL, CHECK ZOOM IS WORKING IN PNA
		static double lasthere=0;
		// Only for special case: PAN mode, map not dirty (including requests for zooms!)
		// not in the ForceRenderMap run and last time was a real rendering. THEN, at these conditions,
		// we simply redraw old bitmap, for the scope of accelerating touch response.
		// In fact, if we are panning the map while rendering, there would be an annoying delay.
		// This is using lastdrawwasbitblitted
		if (INPAN && !MapDirty && !lastdrawwasbitblitted && !ForceRenderMap && !first_run) {
			// In any case, after 5 seconds redraw all
			if ( (LKHearthBeats-8) >lasthere ) {
				lasthere=LKHearthBeats;
				goto _dontbitblt;
			}
			BitBlt(hdcScreen, 0, 0, MapRect.right-MapRect.left,
				MapRect.bottom-MapRect.top, 
				hdcDrawWindow, 0, 0, SRCCOPY);

			POINT centerscreen;
			centerscreen.x=ScreenSizeX/2; centerscreen.y=ScreenSizeY/2;
			DrawMapScale(hdcScreen,MapRect,false);
			DrawCrossHairs(hdcScreen, centerscreen, MapRect);
			continue;
		} 
		#endif // --------------------------
_dontbitblt:
		MapDirty = false;
		PanRefreshed=true;
	} // MapDirty

	lastdrawwasbitblitted=false;
	MapWindow::UpdateInfo(&GPS_INFO, &CALCULATED_INFO);

	RenderMapWindow(MapRect);
    
	if (!ForceRenderMap && !first_run) {
		BitBlt(hdcScreen, 0, 0, 
			MapRect.right-MapRect.left,
			MapRect.bottom-MapRect.top, 
			hdcDrawWindow, 0, 0, SRCCOPY);
		InvalidateRect(hWndMapWindow, &MapRect, false);
	}

	// Draw cross sight for pan mode, in the screen center, 
	// after a full repaint while not fastpanning
	if (mode.AnyPan() && !mode.Is(Mode::MODE_TARGET_PAN) && !OnFastPanning) {
		POINT centerscreen;
		centerscreen.x=ScreenSizeX/2; centerscreen.y=ScreenSizeY/2;
		DrawMapScale(hdcScreen,MapRect,false);
		DrawCompass(hdcScreen, MapRect, DisplayAngle);
		DrawCrossHairs(hdcScreen, centerscreen, MapRect);
	}

	UpdateTimeStats(false);

	// we do caching after screen update, to minimise perceived delay
	// UpdateCaches is updating topology bounds when either forced (only here)
	// or because MapWindow::ForceVisibilityScan  is set true.
	UpdateCaches(first_run);
	first_run=false;

	ForceRenderMap = false;

	if (ProgramStarted==psInitDone) {
		ProgramStarted = psFirstDrawDone;
	}

	if ( (GetThreadTimes( hDrawThread, &CreationTime, &ExitTime,&EndKernelTime,&EndUserTime)) == 0) {
		Cpu_Draw=9999;
	} else {
		Cpustats(&Cpu_Draw,&StartKernelTime, &EndKernelTime, &StartUserTime, &EndUserTime);
	}
    
  } // Big LOOP

  #if TESTBENCH
  StartupStore(_T("... Thread_Draw terminated\n"));
  #endif
  THREADEXIT = TRUE;
  return 0;
}
예제 #7
0
// vkmode 0=normal 1=gesture up 2=gesture down
// however we consider a down as up, and viceversa
int ProcessVirtualKey(int X, int Y, long keytime, short vkmode) {

#define VKTIMELONG 1500
	short yup, ydown;
	short i, j;
	short numpages=0;

	static short s_xright=0, s_xleft=0;

	short shortpress_yup, shortpress_ydown;
	short longpress_yup, longpress_ydown;

	static short s_bottomY=0;
	#if 0 // 121123 CHECK AND REMOVE
	static short oldMapSpaceMode=0;
	#endif

	bool dontdrawthemap=(DONTDRAWTHEMAP);
	VKtime=keytime;

	#ifdef DEBUG_PROCVK
	TCHAR buf[100];
	_stprintf(buf,_T("R=%d,%d,%d,%d, X=%d Y=%d kt=%ld"),0, 0, 
	ScreenSizeX, ScreenSizeY,X,Y,keytime);
	DoStatusMessage(buf);
	#endif


	if (DoInit[MDI_PROCESSVIRTUALKEY]) {

		// calculate left and right starting from center
		s_xleft=(MapWindow::MapRect.right+MapWindow::MapRect.left)/2 -(MapWindow::MapRect.right-MapWindow::MapRect.left)/6;
		s_xright=(MapWindow::MapRect.right+MapWindow::MapRect.left)/2 + (MapWindow::MapRect.right-MapWindow::MapRect.left)/6;

		// same for bottom navboxes: they do not exist in infobox mode
		s_bottomY=MapWindow::Y_BottomBar-NIBLSCALE(2);

		DoInit[MDI_PROCESSVIRTUALKEY]=false;
	}


        // LK v6: check we are not out of MapRect bounds.
        if (X<MapWindow::MapRect.left||X>MapWindow::MapRect.right||Y<MapWindow::MapRect.top||Y>MapWindow::MapRect.bottom)
            return ProcessSubScreenVirtualKey(X,Y,keytime,vkmode);

        if (MapSpaceMode==MSM_WELCOME) {
            SetModeType(LKMODE_MAP, MP_MOVING);
            LKevent=LKEVENT_NONE;
            NextModeIndex();
            PreviousModeIndex();
            MapWindow::RefreshMap();
            LKSound(_T("LK_BEEP0.WAV"));
            return 0;
        }


	// 120602 fix
	// TopSize is dynamically assigned by DrawNearest,Drawcommon, DrawXX etc. so we cannot make static yups
	//
	longpress_yup=(short)((MapWindow::Y_BottomBar-TopSize)/3.7)+TopSize;
	longpress_ydown=(short)(MapWindow::Y_BottomBar-(MapWindow::Y_BottomBar/3.7));
	shortpress_yup=(short)((MapWindow::Y_BottomBar-TopSize)/2.7)+TopSize;
	shortpress_ydown=(short)(MapWindow::Y_BottomBar-(MapWindow::Y_BottomBar/2.7));
	
	// do not consider navboxes, they are processed separately
	// These are coordinates for up down center VKs
	// yup and ydown are used normally on nearest page item selection, but also for real VK
	// that currently are almost unused. 

	if (DrawBottom) {
		// Native LK mode: always fullscreen mode
		// If long click, we are processing an Enter, and we want a wider valid center area
		if ( keytime>=(VKSHORTCLICK*2)) { 
			yup=longpress_yup;
			ydown=longpress_ydown;
		} else {
			yup=shortpress_yup;
			ydown=shortpress_ydown;
		}
	} else {
		// This could happen only in Ibox mode. We should never fall here.
		yup=(short)(ScreenSizeY/2.7);
		ydown=(short)(ScreenSizeY-(ScreenSizeY/2.7));
		#if TESTBENCH
		StartupStore(_T("...... DrawBottom FALSE in virtual key processing!\n"));
		#endif
	}

	#ifdef DEBUG_PROCVK
	TCHAR buf[100];
	#endif

	// Handle fullscreen 8000 mode 
	// sound clicks require some attention here
	if (DrawBottom && !MapWindow::mode.AnyPan() && vkmode==LKGESTURE_NONE) { 
		//
		// CLICKS on NAVBOXES, any MapSpaceMode ok
		//
		if (Y>= s_bottomY ) { // TESTFIX 090930

			if ( X>s_xright ) {
				// standard configurable mode
				if (keytime >=CustomKeyTime) {
					// 2 is right key
					if (CustomKeyHandler(CKI_BOTTOMRIGHT)) return 0;
				}
				#ifdef DEBUG_PROCVK
				_stprintf(buf,_T("RIGHT in limit=%d"),MapWindow::Y_BottomBar-NIBLSCALE(20));
				DoStatusMessage(buf);
				#endif
				BottomBarChange(true); // advance
				BottomSounds();
				MapWindow::RefreshMap();
				return 0;
			}
			if ( X<s_xleft ) { // following is ugly
				if (keytime >=CustomKeyTime) {
					// 1 is left key
					if (CustomKeyHandler(CKI_BOTTOMLEFT)) return 0;
				}

				#ifdef DEBUG_PROCVK
				_stprintf(buf,_T("LEFT in limit=%d"),MapWindow::Y_BottomBar-NIBLSCALE(20));
				DoStatusMessage(buf);
				#endif
				BottomBarChange(false); // backwards
				BottomSounds();
				MapWindow::RefreshMap();
				return 0;
			}
			#ifdef DEBUG_PROCVK
			_stprintf(buf,_T("CENTER in limit=%d"),MapWindow::Y_BottomBar-NIBLSCALE(20));
			DoStatusMessage(buf);
			#endif

			//
			// VIRTUAL CENTER KEY HANDLING
			//
			// long press on center navbox 
			// Activate following choices for testing and experimenting. Always disable for real usage.
#if (0)
			// Output NMEA to device
			if (keytime>1000) {
				PlayResource(TEXT("IDR_WAV_HIGHCLICK"));

				devWriteNMEAString(devA(),_T("$PGRMCE"));
				Message::AddMessage(1000, 3, _T("NMEA out $PGRMCE"));
				return 0;
			}
#endif
#if (0)
			// Simulate incoming NMEA string
			if (keytime>1000) {
				static TCHAR mbuf[200];
				_stprintf(mbuf,_T("$VARIO,1010.18,0.0,0.00,2.34,2,000.0,000.0*51\n"));
				NMEAParser::ParseNMEAString(0, (TCHAR *) mbuf, &GPS_INFO);
				return 0;
			}
#endif
#if (0)	// TESTKEY
			// Print a message on the screen for debugging purposes
			TCHAR mbuf[100];
			if (keytime>1000) {
				// _stprintf(mbuf,_T("Cache MCA %d/%d F=%d"), Cache_Hits_MCA, Cache_Calls_MCA, Cache_False_MCA );
				char *point;
				point=(char*)&mbuf;
				*point++='A';
				*point++='\0';
				*point++='B';
				*point++='\0';
				*point++=0x06;
				*point++=0x01;
				*point++='C';
				*point++='\0';
				*point++='\0';
				*point++='\0';
				//mbuf[1]=0xc4;
				//mbuf[1]=0x86;
				Message::AddMessage(20000, 3, mbuf);
				return 0;
			}
#endif

#if (0)
			if (keytime>=CustomKeyTime) {
				if (OvertargetMode==OVT_MAXMODE) OvertargetMode=0;
				else OvertargetMode++;
				PlayResource(TEXT("IDR_WAV_HIGHCLICK"));
				return 0;
			}
#endif

#if (0)
			if (keytime>=CustomKeyTime) {
				PlayResource(TEXT("IDR_WAV_HIGHCLICK"));
				extern bool RunSignature(void);
				RunSignature();

				return 0;
			}
#endif

#if (0)
			// Long press in center screen bottom bar
			if (keytime>=CustomKeyTime) {
				PlayResource(TEXT("IDR_WAV_HIGHCLICK"));
				extern void ReinitScreen(void);
				ReinitScreen();
				return 0;
			}
#endif

			// REAL USAGE, ALWAYS ACTIVATE 
			#if (1)
			// standard configurable mode
			if (keytime >=CustomKeyTime) {
				// 0 is center key
				if (CustomKeyHandler(CKI_BOTTOMCENTER)) return 0;
			}
			#endif

			// normally, we fall down here.
			// If CustomKeyHandler returned false, back as well here (nothing configured in custom).
			//
			///// If we are clicking on center bottom bar while still in welcome page, set map before nextmode.
			NextModeIndex();
			MapWindow::RefreshMap();
			SoundModeIndex();

			return 0;
		// End click on navboxes 
		} else 
		// CLICK ON SORTBOX line at the top, only with no map and only for enabled pages
		if ( (Y<=SortBoxY[MapSpaceMode]) &&
			( MapSpaceMode == MSM_LANDABLE || MapSpaceMode==MSM_AIRPORTS || 
			MapSpaceMode==MSM_NEARTPS || MapSpaceMode==MSM_TRAFFIC ||
			MapSpaceMode==MSM_AIRSPACES || MapSpaceMode==MSM_THERMALS ||
			MapSpaceMode==MSM_COMMON || MapSpaceMode==MSM_RECENT) ) {

			// only search for 1-3, otherwise it's the fourth (fifth really)
			// we don't use 0 now
			for (i=0, j=4; i<4; i++) { // i=1 original 090925 FIX
				if (X <SortBoxX[MapSpaceMode][i]) {
					j=i;
					break;
				}
			}

			#if 0 // 121123 CHECK AND REMOVE
			// 120504 if we are clicking on the already selected sort button, within the same mapspacemode,
			// then simulate a gesture down to advance to next page, if available.
			if ( (MapSpaceMode==oldMapSpaceMode && SortedMode[MapSpaceMode]==j)  ||
			     (MapSpaceMode==MSM_COMMON) || (MapSpaceMode==MSM_RECENT) ) {
				vkmode=LKGESTURE_DOWN;
				goto shortcut_gesture;
			} else {
				oldMapSpaceMode=MapSpaceMode; // becomes current
			}
			#else
			if ( (SortedMode[MapSpaceMode]==j)  ||
			     (MapSpaceMode==MSM_COMMON) || (MapSpaceMode==MSM_RECENT) ) {
				vkmode=LKGESTURE_DOWN;
				goto shortcut_gesture;
			}
			#endif

			switch(MapSpaceMode) {
				case MSM_LANDABLE:
				case MSM_AIRPORTS:
				case MSM_NEARTPS:
							SortedMode[MapSpaceMode]=j;
							LKForceDoNearest=true;
							PlayResource(TEXT("IDR_WAV_CLICK"));
							break;
				case MSM_TRAFFIC:
							SortedMode[MapSpaceMode]=j;
							// force immediate resorting
							LastDoTraffic=0;
							PlayResource(TEXT("IDR_WAV_CLICK"));
							break;
				case MSM_AIRSPACES:
							SortedMode[MapSpaceMode]=j;
							PlayResource(TEXT("IDR_WAV_CLICK"));
							break;

				case MSM_THERMALS:
							SortedMode[MapSpaceMode]=j;
							// force immediate resorting
							LastDoThermalH=0;
							PlayResource(TEXT("IDR_WAV_CLICK"));
							break;
				default:
							DoStatusMessage(_T("ERR-022 UNKNOWN MSM in VK"));
							break;
			}
			SelectedPage[MapSpaceMode]=0;
			SelectedRaw[MapSpaceMode]=0;
			MapWindow::RefreshMap();

			return 0;
		// end sortbox
		}  
	// end newmap  with no gestures
	}

	// REAL virtual keys
	// Emulate real keypresses with wParam

shortcut_gesture:
	// UP gesture
	if (vkmode>LKGESTURE_NONE) {
		// WE MANAGE GESTURES IN ALL MAPSPACES
		switch(MapSpaceMode) {
			case MSM_LANDABLE:
			case MSM_AIRPORTS:
			case MSM_NEARTPS:
						LKForceDoNearest=true;
						numpages=Numpages;
						break;
			case MSM_COMMON:
						LKForceDoCommon=true;
						numpages=Numpages;
						break;
			case MSM_RECENT:
						LKForceDoRecent=true;
						numpages=Numpages;
						break;
			case MSM_AIRSPACES:
						numpages=Numpages;
						break;
			case MSM_TRAFFIC:
						numpages=Numpages;
						break;
			case MSM_THERMALS:
						numpages=Numpages;
						break;
			default:
						break;
		}
		SelectedRaw[MapSpaceMode]=0;

		switch(vkmode) {
			// SCROLL DOWN
			case LKGESTURE_DOWN:
				// no pagedown for main map.. where do you want to go??
				if (NOTANYPAN && IsMultiMapNoMain()) {
					LKevent=LKEVENT_PAGEDOWN;
					MapWindow::RefreshMap();
					return 0;
				}
				// careful, selectedpage starts from 0
				if (++SelectedPage[MapSpaceMode] >=numpages) {
					PlayResource(TEXT("IDR_WAV_HIGHCLICK"));
					SelectedPage[MapSpaceMode]=0;
				} else {
					PlayResource(TEXT("IDR_WAV_CLICK"));
				}
				LKevent=LKEVENT_NEWPAGE;
				MapWindow::RefreshMap();
				return 0;
			// SCROLL UP
			case LKGESTURE_UP:
				// no pagedown for main map.. where do you want to go??
				if (NOTANYPAN && IsMultiMapNoMain()) {
					LKevent=LKEVENT_PAGEUP;
					MapWindow::RefreshMap();
					return 0;
				}
				if (--SelectedPage[MapSpaceMode] <0) {
					PlayResource(TEXT("IDR_WAV_CLICK"));
					SelectedPage[MapSpaceMode]=(numpages-1);
				} else {
					if (SelectedPage[MapSpaceMode]==0) {
						PlayResource(TEXT("IDR_WAV_HIGHCLICK"));
					} else {
						PlayResource(TEXT("IDR_WAV_CLICK"));
					}
				}
				LKevent=LKEVENT_NEWPAGE;
				MapWindow::RefreshMap();
				return 0;
			case LKGESTURE_RIGHT:
gesture_right:
				NextModeType();
				MapWindow::RefreshMap();

                    // Notice: MultiMap has its own sounds. We come here when switching pages, but with
					// an exception: from moving map we generate currently a direct NextModeType from
					// MapWndProc, and thus we dont get ProcessVirtualKeys for that single case.	
					// We should not be playing a CLICK sound while we are playing the MM tone, or
					// it wont come up !
					if (ModeIndex!=LKMODE_MAP) {
						if (CURTYPE == 0)
							PlayResource(TEXT("IDR_WAV_HIGHCLICK"));
						else
							PlayResource(TEXT("IDR_WAV_CLICK"));
					}
				return 0;

				break;

			case LKGESTURE_LEFT:
gesture_left:
				PreviousModeType();
				MapWindow::RefreshMap();
                if (ModeIndex!=LKMODE_MAP) {
                    if (CURTYPE == 0)
                        PlayResource(TEXT("IDR_WAV_HIGHCLICK"));
                    else
                        PlayResource(TEXT("IDR_WAV_CLICK"));
                }
				return 0;

				break;
			default:
				return 0;
		}

		return 0;
	}

	if (!MapWindow::mode.AnyPan() && (IsMultiMap()||MapSpaceMode==MSM_MAPTRK)) {
		if (keytime>=(VKSHORTCLICK*4)) {
			LKevent=LKEVENT_LONGCLICK;
			MapWindow::RefreshMap();
			return 0;
		}
	}

	// UNGESTURES: 
	// No need to use gestures if clicking on right or left center border screen
	// This will dramatically speed up the user interface in turbulence
	if (dontdrawthemap) {
		if (Y>longpress_yup && Y<longpress_ydown) {
			if (UseUngestures || !ISPARAGLIDER) {
				if (X<=MapWindow::X_Left)  goto gesture_left;
				if (X>=MapWindow::X_Right) goto gesture_right;
			}
		}
	}

	///
	/// REMOVE. ActiveMap always false
	///
	///if (!MapWindow::mode.AnyPan() && IsMultiMapNoMain() && ActiveMap) {
	///	LKevent=LKEVENT_SHORTCLICK;
	///	MapWindow::RefreshMap();
	///	return 0;
	///}

	if (Y<yup) {
		// we are processing up/down in mapspacemode i.e. browsing waypoints on the page
		if (dontdrawthemap) {
			if (MapSpaceMode<=MSM_MAP) {
				// DoStatusMessage(_T("DBG-032-A event up not used here"));
				return 0;
			}
        	PlayResource(TEXT("IDR_WAV_CLICK"));
			LKevent=LKEVENT_UP;
			MapWindow::RefreshMap();
			// DoStatusMessage(_T("DBG-032-B event up used here"));
			return 0;
		}
        PlayResource(TEXT("IDR_WAV_CLICK"));
		if (keytime>=VKTIMELONG)
			return 0xc1;
		else
			return 38;
	}
	if (Y>ydown) {
		if (dontdrawthemap) {
			if (MapSpaceMode<=MSM_MAP) return 0;
        	PlayResource(TEXT("IDR_WAV_CLICK"));
			LKevent=LKEVENT_DOWN;
			MapWindow::RefreshMap();
			return 0;
		}
        PlayResource(TEXT("IDR_WAV_CLICK"));
		if (keytime>=VKTIMELONG)
			return 0xc2;
		else
			return 40;
	}

	// This will not be detected in case of UP and DOWN was detected, of course.
	// We must handle this separately, before checking for UP DOWN, above.
	if (!MapWindow::mode.AnyPan() && IsMultiMap()) {
		LKevent=LKEVENT_SHORTCLICK;
		MapWindow::RefreshMap();
		return 0;
	}

	// no click for already clicked events


		// If in mapspacemode process ENTER 
		if ( (keytime>=(VKSHORTCLICK*2)) && dontdrawthemap && !IsMultiMap()) {
			LKSound(_T("LK_BEEP1.WAV"));
			LKevent=LKEVENT_ENTER;
			MapWindow::RefreshMap();
			return 0;
		}
/*
		// do not process enter in panmode, unused
		if ( !MapWindow::mode.AnyPan() ) {
	             DoStatusMessage(_T("Virtual ENTER")); 
		     return 13;
		}
*/

		//
		// Here we are when short clicking in the center area, not an up and not a down.. a center.
		// We do nothing.
		//


		if (SIMMODE) {
			if ( MapWindow::mode.AnyPan() && ISPARAGLIDER) return 99; // 091221 return impossible value
			else return 0;
		} else {
			return 0;
		}
	DoStatusMessage(_T("VirtualKey Error")); 
	return 0;
}
예제 #8
0
//
// Called by LKDrawLook8000, this is what happens when we change mapspace mode, advancing through types.
// We paint infopages, nearest, tri, etc.etc.
// Normally there is plenty of cpu available because the map is not even calculated.
// This is why we bring to the Draw thread, in the nearest pages case, also calculations.
//
void MapWindow::DrawMapSpace(LKSurface& Surface,  const RECT& rc) {

  BrushReference hB;

  TextInBoxMode_t TextDisplayMode = {0};
  TCHAR Buffer[LKSIZEBUFFERLARGE*2];
#ifdef DRAWLKSTATUS
  bool dodrawlkstatus=false;
#endif


#ifndef DITHER
  if (MapSpaceMode==MSM_WELCOME) {
	if (INVERTCOLORS)
		hB=LKBrush_Petrol;
	  else
		hB=LKBrush_Mlight;
  } else {
	if (INVERTCOLORS)
	  hB=LKBrush_Mdark;
	else
	  hB=LKBrush_Mlight;

  }
#else
  if (INVERTCOLORS)
      hB=LKBrush_Black;
  else
      hB=LKBrush_White;
#endif

  const auto oldfont = Surface.SelectObject(LKINFOFONT); // save font
  if (MapSpaceMode==MSM_WELCOME) {
      LKBitmap WelcomeBitmap = LoadSplash(_T("LKPROFILE"));
      if(WelcomeBitmap) {
          DrawSplash(Surface, WelcomeBitmap);
      }
  } else {
      Surface.FillRect(&rc, hB);
  }

  // Paint borders in green, but only in nearest pages and welcome, and not in DITHER mode
  // In case we want it in dithered mode, some changes are ready to be used.
  #ifndef DITHER
  if (MapSpaceMode==MSM_WELCOME || (!IsMultiMap() && MapSpaceMode!=MSM_MAP) )
  {
     #ifdef DITHER
     LKPen BorderPen(PEN_SOLID, ScreenThinSize, INVERTCOLORS?RGB_WHITE:RGB_BLACK);
     #else
     LKPen BorderPen(PEN_SOLID, ScreenThinSize, INVERTCOLORS?RGB_GREEN:RGB_DARKGREEN);
     #endif
     auto OldPen = Surface.SelectObject(BorderPen);
     auto OldBrush = Surface.SelectObject(LK_HOLLOW_BRUSH);

     Surface.Rectangle(rc.left, rc.top, rc.right, rc.bottom - BottomSize);

     Surface.SelectObject(OldPen);
     Surface.SelectObject(OldBrush);
  }
  #endif


#ifdef DRAWLKSTATUS
  if (LKevent==LKEVENT_NEWRUN) dodrawlkstatus=true;
#endif

  // We are entering mapspacemodes with no initial check on configured subpages.
  // Thus we need to ensure that the page is really available, or find the first valid.
  // However, this will prevent direct customkey access to pages!
  // Instead, we do it when we call next page from InfoPageChange
  // if (!ConfIP[ModeIndex][CURTYPE]) NextModeType();
  switch (MapSpaceMode) {
	case MSM_WELCOME:
#if 0
		SetModeType(LKMODE_MAP,MP_MOVING);
		RefreshMap();
		break;
#endif
#if (1)
		if (!DrawInfo.NAVWarning) {
		static double firsttime=DrawInfo.Time;
		// delayed automatic exit from welcome mode
		if ( DrawInfo.Time > (firsttime+3.0) ) {
			SetModeType(LKMODE_MAP,MP_MOVING);
			LKevent=LKEVENT_NONE;
			LKSound(_T("LK_BEEP1.WAV"));
			RefreshMap();
			break;
		}
		}
#endif
		if(GlobalModelType==MODELTYPE_PNA_MINIMAP)
		{
			SetModeType(LKMODE_MAP,MP_MOVING);
			LKevent=LKEVENT_NONE;
			break;
		}

		DrawWelcome8000(Surface, rc);
		break;
	case MSM_MAPTRK:
		SetSideviewPage(IM_HEADING);
		LKDrawMultimap_Asp(Surface,rc);
		break;
	case MSM_MAPWPT:
		#if 0
		// If there is no destination, force jump to the map
		if (GetOvertargetIndex()<0) {
			SetModeType(LKMODE_MAP,MP_MOVING);
			LKevent=LKEVENT_NONE;
			break;
		}
		#endif
		SetSideviewPage(IM_NEXT_WP);
		LKDrawMultimap_Asp(Surface,rc);
		break;
	case MSM_MAPASP:
		SetSideviewPage(IM_NEAR_AS);
		LKDrawMultimap_Asp(Surface,rc);
		break;
	case MSM_MAPRADAR:
		LKDrawMultimap_Radar(Surface,rc);
		break;
	case MSM_VISUALGLIDE:
		SetSideviewPage(IM_VISUALGLIDE);
		LKDrawMultimap_Asp(Surface,rc);
		break;
	case MSM_MAPTEST:
		LKDrawMultimap_Test(Surface,rc);
		break;
	case MSM_LANDABLE:
	case MSM_NEARTPS:
	case MSM_AIRPORTS:
	case MSM_COMMON:
	case MSM_RECENT:
	case MSM_AIRSPACES:
	case MSM_THERMALS:
	case MSM_TRAFFIC:
		DrawNearest(Surface, rc);
		break;
	case MSM_MAP:
		break;
	case MSM_INFO_THERMAL:
	case MSM_INFO_CRUISE:
	case MSM_INFO_TASK:
	case MSM_INFO_AUX:
	case MSM_INFO_TRI:
	case MSM_INFO_HSI:
	case MSM_INFO_TRF:
	case MSM_INFO_TARGET:
	case MSM_INFO_CONTEST:
		DrawInfoPage(Surface,rc, false);
		break;

  default:
    memset((void*)&TextDisplayMode, 0, sizeof(TextDisplayMode));
    TextDisplayMode.Color = RGB_WHITE;
    TextDisplayMode.NoSetFont = 1;
    TextDisplayMode.AlligneCenter = 1;
    Surface.SelectObject(LK8TargetFont);
    _stprintf(Buffer,TEXT("MapSpaceMode=%d"),MapSpaceMode);
    TextInBox(Surface, &rc, Buffer, (rc.right+rc.left)/2, NIBLSCALE(50) , &TextDisplayMode, false);
    break;
  }
#ifdef DRAWLKSTATUS
  // no need to clear dodrawlkstatus, it is already reset at each run
  if (dodrawlkstatus) DrawLKStatus(hdc, rc);
#endif
  Surface.SelectObject(oldfont);
}