53#include <wx/stdpaths.h>
54#include <wx/tokenzr.h>
55#include <wx/display.h>
56#include <wx/jsonreader.h>
58#include "o_sound/o_sound.h"
82#include "model/nav_object_database.h"
94#include "ais_info_gui.h"
95#include "dialog_alert.h"
99#include "ais_info_gui.h"
123#include "load_errors_dlg.h"
126#include "N2KParser.h"
154#include "androidUTIL.h"
162arrayofCanvasPtr g_canvasArray;
168GLenum g_texture_rectangle_format;
171#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
172extern wxLocale *plocale_def_lang;
176extern bool g_b_EnableVBO;
177extern GLenum g_texture_rectangle_format;
181static int g_last_ChartScaleFactor;
182static char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
183static int options_subpage = 0;
184static bool b_reloadForPlugins;
186static wxSize options_lastWindowSize(0, 0);
187static wxPoint options_lastWindowPos(0, 0);
191static double gQueryVar = 361.0;
193static char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
194static o_sound::Sound *_bells_sounds[] = {o_sound::Factory(),
196static std::vector<o_sound::Sound *> bells_sound(_bells_sounds,
199static wxArrayPtrVoid *UserColourHashTableArray;
204typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
205typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
207static SetSysColors_t pSetSysColors;
208static GetSysColor_t pGetSysColor;
210void SaveSystemColors();
211void RestoreSystemColors();
216DWORD color_3ddkshadow;
218DWORD color_activecaption;
219DWORD color_gradientactivecaption;
220DWORD color_captiontext;
221DWORD color_windowframe;
222DWORD color_inactiveborder;
227#include <wx/msw/msvcrt.h>
231static const long long lNaN = 0xfff8000000000000;
232#define NAN (*(double *)&lNaN)
235static wxArrayPtrVoid *UserColorTableArray = 0;
238static double gLat_gt, gLon_gt;
239static double gLat_gt_m1, gLon_gt_m1;
240static uint64_t fix_time_gt;
241static uint64_t fix_time_gt_last;
243static double gSog_gt, gHdt_gt;
244static double gCog_gt_m1, gHdt_gt_m1;
245static uint64_t hdt_time_gt;
246static double cog_rate_gt, hdt_rate_gt;
248void InitializeUserColors();
249void DeInitializeUserColors();
250void SetSystemColors(ColorScheme cs);
252static bool LoadAllPlugIns(
bool load_enabled) {
253 AbstractPlatform::ShowBusySpinner();
254 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
255 AbstractPlatform::HideBusySpinner();
259static void LaunchLocalHelp() {
261 androidLaunchHelpView();
263 wxString def_lang_canonical =
"en_US";
266 if (plocale_def_lang)
267 def_lang_canonical = plocale_def_lang->GetCanonicalName();
270 wxString help_locn = g_Platform->GetSharedDataDir() +
"doc/help_";
272 wxString help_try = help_locn + def_lang_canonical +
".html";
274 if (!::wxFileExists(help_try)) {
275 help_try = help_locn +
"en_US" +
".html";
277 if (!::wxFileExists(help_try)) {
278 help_try = help_locn +
"web" +
".html";
281 if (!::wxFileExists(help_try))
return;
284 wxLaunchDefaultBrowser(wxString(
"file:///") + help_try);
288static void DoHelpDialog() {
300 [] { LaunchLocalHelp(); });
312#if defined(__WXGTK__) || defined(__WXQT__)
313#include "bitmaps/opencpn.xpm"
327void BuildiENCToolbar(
bool bnew) {
328 if (g_bInlandEcdis) {
332 wxPoint tbp_incanvas =
335 g_iENCToolbarPosY = tbp_incanvas.y;
336 g_iENCToolbarPosX = tbp_incanvas.x;
344 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
348 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
351 g_iENCToolbarPosY = -1;
354 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
360 wxPoint(g_maintoolbar_x +
g_MainToolbar->GetToolbarSize().x + 4,
364 double tool_scale_factor =
365 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
368 new iENCToolbar(gFrame, posn, wxTB_HORIZONTAL, tool_scale_factor);
379 if (chart ==
nullptr)
return false;
382 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
384 if (cc && cc->m_singleChart == chart) {
391#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
394static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
395 const char *prop_name) {
399 unsigned long ret_nitems;
400 unsigned long ret_bytes_after;
401 unsigned char *ret_prop;
403 xa_prop_name = XInternAtom(disp, prop_name, False);
411 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
412 &xa_ret_type, &ret_format, &ret_nitems,
413 &ret_bytes_after, &ret_prop) != Success)
416 if (xa_ret_type != xa_prop_type) {
420 return (
char *)ret_prop;
425static bool isTransparentToolbarInOpenGLOK() {
432 if (!g_bdisable_opengl) {
433 Display *disp = XOpenDisplay(NULL);
435 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
437 "_NET_SUPPORTING_WM_CHECK")) ||
438 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
440 "_WIN_SUPPORTING_WM_CHECK"))) {
443 if ((wm_name = get_X11_property(disp, *sup_window,
444 XInternAtom(disp,
"UTF8_STRING", False),
446 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
449 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
470wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
472BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
473EVT_CLOSE(MyFrame::OnCloseWindow)
474EVT_MENU(wxID_EXIT, MyFrame::OnExit)
475EVT_SIZE(MyFrame::OnSize)
476EVT_MOVE(MyFrame::OnMove)
477EVT_ICONIZE(MyFrame::OnIconize)
478EVT_MENU(-1, MyFrame::OnToolLeftClick)
479EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
481EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
482EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
483EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
485EVT_MAXIMIZE(MyFrame::OnMaximize)
486EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
487 MyFrame::RequestNewToolbarArgEvent)
488EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
490EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
491EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
492EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
494#ifdef wxHAS_POWER_EVENTS
495EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
496EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
497EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
498EVT_POWER_RESUME(MyFrame::OnResume)
509static
void onBellsFinishedCB(
void *ptr) {
510 auto framePtr =
static_cast<MyFrame *
>(ptr);
512 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
513 wxPostEvent(framePtr, ev);
518 auto msg = ev.GetString().ToStdString();
519 auto ¬eman = NotificationManager::GetInstance();
520 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
523static NmeaLog *GetDataMonitor() {
524 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
525 return dynamic_cast<NmeaLog *
>(w);
529MyFrame::MyFrame(wxFrame *frame,
const wxString &title,
const wxPoint &pos,
530 const wxSize &size,
long style,
531 wxAuiDefaultDockArt *pauidockart)
532 : wxFrame(frame, -1, title, pos, size, style, kTopLevelWindowName),
533 m_connections_dlg(nullptr),
535 m_pauidockart(pauidockart) {
547 m_ulLastNMEATicktime = 0;
548 m_data_monitor->Hide();
550 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
554 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
557 InitTimer.SetOwner(
this, INIT_TIMER);
559 m_initializing =
false;
562 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
565 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
568 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
571 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
574 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
576 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
585 m_bTimeIsSet =
false;
588 m_bdefer_resize =
false;
591 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
592 COGFilterTable[i] = NAN;
593 SOGFilterTable[i] = NAN;
595 m_last_bGPSValid =
false;
596 m_last_bVelocityValid =
false;
606 for (
int i = 0; i < MAX_COG_AVERAGE_SECONDS; i++) COGTable[i] = NAN;
611 double process_noise_std = 1.0;
612 double measurement_noise_std = 0.5;
614 m_ChartUpdatePeriod = 1;
619 log_callbacks.log_is_active = [&]() {
620 auto log = GetDataMonitor();
621 return log && log->IsVisible();
623 log_callbacks.log_message = [&](
Logline ll) {
624 NmeaLog *monitor = GetDataMonitor();
627 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
630 ais_callbacks.confirm_stop_track = []() {
631 int r = OCPNMessageBox(
633 _(
"This AIS target has Persistent tracking selected by MMSI "
635 "A Persistent track recording will therefore be restarted for this "
637 "Do you instead want to stop Persistent tracking for this target?"),
638 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
639 return r == wxID_YES;
641 ais_callbacks.get_target_mmsi = []() {
642 auto alert_dlg_active =
644 assert(alert_dlg_active);
645 return alert_dlg_active->Get_Dialog_MMSI();
653 wxLogMessage(
" **** Connect stuff");
659 Connect(wxEVT_OCPN_MSG,
660 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
668 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
676#if defined(__WXGTK__) || defined(__WXQT__)
677 wxIcon app_icon(opencpn);
685 wxDynamicLibrary dllUser32(
"user32.dll");
687 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(
"SetSysColors");
688 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(
"GetSysColor");
693 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
698 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
699 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
701 assert(
g_pRouteMan != 0 &&
"g_pRouteMan not available");
703 [&](wxCommandEvent) { Refresh(); });
704 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
706 m_update_statusbar_listener.Init(
707 GuiEvents::GetInstance().gframe_update_status_bar,
709 m_center_aistarget_listener.Init(
710 GuiEvents::GetInstance().on_center_ais_target, [&](
ObservedEvt &ev) {
711 auto ais_target = UnpackEvtPointer<AisTargetData>(ev);
712 CenterAisTarget(ais_target);
717 EnableFullScreenView();
719 int is_day = GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
725 FrameTenHzTimer.Stop();
740 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
746void MyFrame::FreezeCharts() {
749 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
751 if (cc && !cc->IsFrozen()) cc->Freeze();
755void MyFrame::CenterAisTarget(
756 const std::shared_ptr<const AisTargetData> &ais_target) {
764 double factor = cc->GetScaleValue() / 5000.0;
765 JumpToPosition(GetFocusCanvas(), ais_target->Lat, ais_target->Lon,
771void MyFrame::ThawCharts() {
774 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
776 if (cc && cc->IsFrozen()) cc->Thaw();
783 switch (event.type) {
784 case SENC_BUILD_STARTED:
787 case SENC_BUILD_DONE_NOERROR:
789 chart =
event.m_ticket->m_chart;
791 chart->PostInit(FULL_INIT, global_color_scheme);
793 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
795 if (cc) cc->ClearS52PLIBStateHash();
800 delete event.m_ticket;
802 case SENC_BUILD_DONE_ERROR:
810void MyFrame::RebuildChartDatabase() {
811 bool b_SetInitialPoint =
false;
814 ArrayOfCDI ChartDirArray;
815 pConfig->LoadChartDirArray(ChartDirArray);
817 if (ChartDirArray.GetCount()) {
822 _(
"OpenCPN needs to update the chart database from config file "
826 wxICON_INFORMATION | wxOK);
834 _(
"Rebuilding chart database from configuration file entries..."));
838 wxString dummy1 = _(
"Elapsed time : ");
839 wxString dummy2 = _(
"Estimated time : ");
840 wxString dummy3 = _(
"Remaining time : ");
841 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
842 _(
"OpenCPN Chart Update"), line, 100, NULL,
843 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
844 wxPD_REMAINING_TIME);
847 ChartData->SaveBinary(ChartListFileName);
857void MyFrame::OnBellsFinished(wxCommandEvent &event) {
858 int bells = wxMin(m_BellsToPlay, 2);
859 if (bells <= 0)
return;
861 wxString soundfile =
"sounds";
862 appendOSDirSlash(&soundfile);
863 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
864 soundfile.Prepend(g_Platform->GetSharedDataDir());
865 wxLogMessage(
"Using bells sound file: " + soundfile);
867 o_sound::Sound *sound = bells_sound[bells - 1];
868 sound->SetFinishedCallback(onBellsFinishedCB,
this);
869 auto cmd_sound =
dynamic_cast<o_sound::SystemCmdSound *
>(sound);
870 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
871 sound->Load(soundfile);
872 if (!sound->IsOk()) {
873 wxLogMessage(
"Failed to load bells sound file: " + soundfile);
877 m_BellsToPlay -= bells;
880void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
882void MyFrame::OnMaximize(wxMaximizeEvent &event) {
889ColorScheme GetColorScheme() {
return global_color_scheme; }
891ColorScheme MyFrame::GetColorScheme() {
return global_color_scheme; }
893void MyFrame::ReloadAllVP() {
894 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
896 if (cc) cc->ReloadVP();
900void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
901 int is_day = cs == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
904 global_color_scheme = cs;
907 case GLOBAL_COLOR_SCHEME_DAY:
910 case GLOBAL_COLOR_SCHEME_DUSK:
913 case GLOBAL_COLOR_SCHEME_NIGHT:
914 SchemeName =
"NIGHT";
921 m_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
923 m_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
924 m_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
925 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
926 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
927 m_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
929 m_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
958 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
959 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
963 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
966 unsigned Usercolortable_index = 0;
967 for (
unsigned int i = 0; i < UserColorTableArray->GetCount(); i++) {
968 colTable *ct = (colTable *)UserColorTableArray->Item(i);
969 if (SchemeName.IsSameAs(*ct->tableName)) {
970 Usercolortable_index = i;
975 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
979 (wxColorHashMap *)UserColourHashTableArray->Item(Usercolortable_index);
984 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
987 cc->SetColorScheme(cs);
988 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
989 cc->HideChartInfoWindow();
990 cc->SetQuiltChartHiLiteIndex(-1);
996 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1008 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1021 if (g_pais_query_dialog_active) {
1022 bool b_isshown = g_pais_query_dialog_active->IsShown();
1023 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1024 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1026 g_pais_query_dialog_active->Close();
1029 g_pais_query_dialog_active->
Create(
1030 this, -1, _(
"AIS Target Query"),
1031 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1032 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1033 g_pais_query_dialog_active->UpdateText();
1034 if (b_isshown) g_pais_query_dialog_active->Show();
1037 if (pRouteManagerDialog) pRouteManagerDialog->SetColorScheme();
1039 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1043 ApplyGlobalColorSchemetoStatusBar();
1045 UpdateAllToolbars(cs);
1050 bool btoolbarFull = g_bmasterToolbarFull;
1056 if (!btoolbarFull) {
1058 RequestNewMasterToolbar();
1060 CollapseGlobalToolbar();
1063 RequestNewMasterToolbar();
1072void MyFrame::ApplyGlobalColorSchemetoStatusBar() {
1073 if (m_pStatusBar != NULL) {
1074 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1075 m_pStatusBar->ClearBackground();
1080 if (g_canvasArray.GetCount() > 0)
1081 return g_canvasArray.Item(0);
1085void MyFrame::CancelAllMouseRoute() {
1087 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1089 if (cc) cc->CancelMouseRoute();
1093void MyFrame::NotifyChildrenResize() {}
1095void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1103 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1111 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1120 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1123 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1124 config_array.Item(i)->canvas = NULL;
1130 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1131 g_canvasArray.RemoveAt(i);
1135 switch (g_canvasConfig) {
1138 if (!g_canvasArray.GetCount() || !config_array.Item(0)) {
1141 g_canvasArray.Add(cc);
1143 cc = g_canvasArray[0];
1149 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1150 cc->GetglCanvas()->Show();
1153 config_array.Item(0)->canvas = cc;
1157 cc->ApplyCanvasConfig(config_array.Item(0));
1161 cc->ConfigureChartBar();
1162 cc->SetColorScheme(global_color_scheme);
1163 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1164 cc->SetShowGPS(
true);
1167 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1169 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1175 if (!g_canvasArray.GetCount() || !g_canvasArray[0]) {
1177 g_canvasArray.Add(cc);
1179 cc = g_canvasArray[0];
1185 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1188 config_array.Item(0)->canvas = cc;
1190 cc->ApplyCanvasConfig(config_array.Item(0));
1193 cc->ConfigureChartBar();
1194 cc->SetColorScheme(global_color_scheme);
1195 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1196 cc->SetShowGPS(
false);
1199 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1201 .CaptionVisible(
false)
1203 .CloseButton(
false);
1208 g_canvasArray.Add(cc);
1212 if (config_array.GetCount() < 2) {
1214 pcc->configIndex = 1;
1218 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1219 config_array.Add(pcc);
1222 config_array.Item(1)->canvas = cc;
1224 cc->ApplyCanvasConfig(config_array.Item(1));
1227 cc->ConfigureChartBar();
1228 cc->SetColorScheme(global_color_scheme);
1229 cc->SetShowGPS(
true);
1233 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1235 .CaptionVisible(
false)
1237 .CloseButton(
false);
1238 g_pauimgr->GetPane(cc).RightDockable(
true);
1242 config_array.Item(1)->canvasSize =
1243 wxSize(GetClientSize().x / 2, GetClientSize().y);
1244 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1249 if (b_useStoredSize) {
1250 int ccw = config_array.Item(1)->canvasSize.x;
1251 int cch = config_array.Item(1)->canvasSize.y;
1254 if (ccw < GetClientSize().x / 10) {
1255 ccw = GetClientSize().x / 2;
1256 cch = GetClientSize().y;
1259 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1260 cc->SetSize(ccw, cch);
1274 if (g_canvasArray.size() > 1)
1278 console->SetColorScheme(global_color_scheme);
1283 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1289void MyFrame::RequestNewToolbars(
bool bforcenew) {
1290 if (b_inCloseWindow) {
1294 BuildiENCToolbar(bforcenew);
1295 PositionIENCToolbar();
1304void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1310void MyFrame::SetAllToolbarScale() {
1311 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1314void MyFrame::SetGPSCompassScale() {
1315 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1319 wxPoint screenPoint = ::wxGetMousePosition();
1322 switch (g_canvasConfig) {
1324 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1327 if (canvas->GetScreenRect().Contains(
1331 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1334 if (canvas->GetScreenRect().Contains(
1341 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1344 if (canvas->GetScreenRect().Contains(
1345 canvas->ScreenToClient(screenPoint)))
1353int MyFrame::GetCanvasIndexUnderMouse() {
1354 wxPoint screenPoint = ::wxGetMousePosition();
1357 switch (g_canvasConfig) {
1359 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1362 if (canvas->GetScreenRect().Contains(
1366 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1369 if (canvas->GetScreenRect().Contains(
1376 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1379 if (canvas->GetScreenRect().Contains(
1380 canvas->ScreenToClient(screenPoint)))
1388bool MyFrame::DropMarker(
bool atOwnShip) {
1395 if (!canvas)
return false;
1402 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1404 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1406 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1411 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1412 pRouteManagerDialog->UpdateWptListCtrl();
1417 RefreshAllCanvas(
false);
1422void MyFrame::SwitchKBFocus(
ChartCanvas *pCanvas) {
1423 if (g_canvasConfig != 0) {
1426 int nTargetGTK = -1;
1428 wxWindow *source = FindFocus();
1434 switch (g_canvasConfig) {
1436 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1439 if (canvas && (canvas == test)) {
1444 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1447 if (canvas && (canvas == test)) {
1455 int nfinalTarget = nTarget;
1457 nfinalTarget = nTargetGTK;
1459 target = ConfigMgr::Get()
1460 .GetCanvasConfigArray()
1465 target->Refresh(
true);
1476void MyFrame::FastClose() {
1478 FrameTenHzTimer.Stop();
1480 FrameTimer1.Start(1);
1484void MyFrame::OnExit(wxCommandEvent &event) {
1488void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1491 if (b_inCloseWindow) {
1501 if (!g_bDeferredInitDone)
return;
1518 if (bDBUpdateInProgress)
return;
1520 b_inCloseWindow =
true;
1522 ::wxSetCursor(wxCURSOR_WAIT);
1526 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1528 if (cc && cc->IsMeasureActive()) {
1529 cc->CancelMeasureRoute();
1534 SendPreShutdownHookToPlugins();
1538 if (g_pAISTargetList) {
1539 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1540 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1541 g_pauimgr->DetachPane(g_pAISTargetList);
1552 pConfig->SetPath(
"/AUI");
1553 pConfig->Write(
"AUIPerspective",
g_pauimgr->SavePerspective());
1568 SetCursor(wxCURSOR_WAIT);
1570 RefreshAllCanvas(
true);
1576 RestoreScreenBrightness();
1587 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1588 g_iENCToolbarPosY = tbp_incanvas.y;
1589 g_iENCToolbarPosX = tbp_incanvas.x;
1593 g_bframemax = IsMaximized();
1596 FrameTenHzTimer.Stop();
1598 FrameCOGTimer.Stop();
1612 if (g_bAutoAnchorMark) {
1613 bool watching_anchor =
false;
1621 wxDateTime now = wxDateTime::Now();
1622 wxTimeSpan uptime = now.Subtract(g_start_time);
1624 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1625 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1630 if (g_declutter_anchorage) {
1631 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1632 if (pr->GetName().StartsWith(
"Anchorage")) {
1633 double a =
gLat - pr->m_lat;
1634 double b =
gLon - pr->m_lon;
1635 double l = sqrt((a * a) + (b * b));
1638 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1640 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1641 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1649 wxString name = now.Format();
1650 name.Prepend(_(
"Anchorage created "));
1656 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1661 pConfig->UpdateSettings();
1665 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1669 NavObj_dB::GetInstance().Close();
1673 pConfig->DeleteGroup(
"/Routes");
1674 pConfig->DeleteGroup(
"/Marks");
1700 if (g_pAISTargetList) {
1701 g_pAISTargetList->Disconnect_decoder();
1702 g_pAISTargetList->Destroy();
1709 if (RouteManagerDialog::getInstanceFlag()) {
1710 if (pRouteManagerDialog) {
1711 pRouteManagerDialog->Destroy();
1712 pRouteManagerDialog = NULL;
1726 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1728 if (cc) cc->Destroy();
1731 g_canvasArray.Clear();
1752 MyApp &app = wxGetApp();
1753 app.m_comm_bridge.SaveConfig();
1773 auto ®istry = CommDriverRegistry::GetInstance();
1774 registry.CloseAllDrivers();
1777 for (
auto *cp : TheConnectionParams()) {
1782 while (pLayerList->size())
delete *pLayerList->begin();
1786 ReleaseApiListeners();
1789 g_bTempShowMenuBar =
false;
1791#define THREAD_WAIT_SECONDS 5
1801 wxLogMessage(
"Starting compressor pool drain");
1802 wxDateTime now = wxDateTime::Now();
1803 time_t stall = now.GetTicks();
1804 time_t end = stall + THREAD_WAIT_SECONDS;
1807 while (stall < end) {
1808 wxDateTime later = wxDateTime::Now();
1809 stall = later.GetTicks();
1812 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1821 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1827 uninitIXNetSystem();
1831 wxLogMessage(
"gFrame destroyed.");
1834#ifndef USE_ANDROID_GLES2
1835 qDebug() <<
"Calling OnExit()";
1839 wxTheApp->ExitMainLoop();
1842void MyFrame::OnMove(wxMoveEvent &event) {
1843 auto idx = wxDisplay::GetFromWindow(
this);
1856 DEBUG_LOG <<
"Moved to " << idx
1857#if wxCHECK_VERSION(3, 1, 6)
1858 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1859 << wxDisplay(idx).GetPPI().GetY()
1860 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1862 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1863 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1864 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1865 << wxGetDisplaySizeMM().GetY()
1866 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1875 if (g_config_display_size_manual) {
1884 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1887 cc->SetMUIBarPosition();
1896 UpdateGPSCompassStatusBoxes();
1906 PositionIENCToolbar();
1912 g_nframewin_posx = GetPosition().x;
1913 g_nframewin_posy = GetPosition().y;
1916void MyFrame::ProcessCanvasResize() {
1917 UpdateGPSCompassStatusBoxes(
true);
1921 PositionIENCToolbar();
1924 TriggerRecaptureTimer();
1928void MyFrame::TriggerRecaptureTimer() {
1929 m_recaptureTimer.Start(
1930 1000, wxTIMER_ONE_SHOT);
1933void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1935void MyFrame::SetCanvasSizes(wxSize frameSize) {
1936 if (!g_canvasArray.GetCount())
return;
1939 int cccw = frameSize.x;
1940 int ccch = frameSize.y;
1944 switch (g_canvasConfig) {
1948 cc = g_canvasArray.Item(0);
1950 cc->GetSize( &cur_width, &cur_height );
1951 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1953 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1955 cc->SetSize( 0, 0, cccw, ccch );
1963 cc = g_canvasArray.Item(1);
1965 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1966 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1968 ccw = wxMin(ccw, cccw * 8 / 10);
1969 ccw = wxMax(ccw, cccw * 2 / 10);
1973 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1980 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
1997void MyFrame::OnIconize(wxIconizeEvent &event) {
2007 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2009 if (cc && cc->GetMUIBar()) {
2010 if (cc->GetMUIBar()->GetCanvasOptions()) {
2011 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2012 cc->GetMUIBar()->PushCanvasOptions();
2021void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2023void MyFrame::ODoSetSize() {
2025 GetClientSize(&x, &y);
2028 if (m_pStatusBar != NULL) {
2029 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2030 int currentCount = m_pStatusBar->GetFieldsCount();
2031 if (currentCount != m_StatusBarFieldCount) {
2032 if ((currentCount > 0) && (currentCount < 7)) {
2035 int widths[] = {2, 2, 2, 2, 2, 2};
2036 m_pStatusBar->SetStatusWidths(currentCount, widths);
2039 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2042 if (m_StatusBarFieldCount) {
2047 if (m_StatusBarFieldCount > 2) {
2048 int widths[] = {-6, -5, -5, -6, -4};
2049 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2050 }
else if (m_StatusBarFieldCount == 2) {
2051 int cwidth = x * 90 / 100;
2052 int widths[] = {100, 100};
2053 widths[0] = cwidth * 6.4 / 10.0;
2054 widths[1] = cwidth * 3.6 / 10.0;
2055 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2057 int widths[] = {100, 100};
2058 widths[0] = x * 90 / 100;
2059 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2062 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2063 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2064 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2066 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2068 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2076 m_pStatusBar->GetFieldRect(0, stat_box);
2079 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2081 wxFont sys_font = *wxNORMAL_FONT;
2082 int try_font_size = sys_font.GetPointSize();
2085 int min_font_size = 10;
2095 wxFont *statusBarFont =
2096 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2097 int font_size = statusBarFont->GetPointSize();
2099 font_size = wxMin(font_size,
2102 wxMax(font_size, min_font_size);
2105 font_size = statusBarFont->GetPointSize();
2112 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2113 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2115 int min_height = stat_box.height;
2117 m_pStatusBar->SetFont(*pstat_font);
2118 m_pStatusBar->SetForegroundColour(
2119 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2121 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2123 (min_height >> 1) * 2;
2124 m_pStatusBar->SetMinHeight(min_height);
2133 SetCanvasSizes(GetClientSize());
2135 UpdateGPSCompassStatusBoxes(
true);
2137 if (
console) PositionConsole();
2140 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2142 if (cc) cc->FormatPianoKeys();
2148 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2149 GetPrimaryCanvas()->GetCompass()->GetRect());
2175 options_lastWindowSize = wxSize(0, 0);
2176 options_lastWindowPos = wxPoint(0, 0);
2183 if (!b_inCloseWindow) {
2186 resizeAndroidPersistents();
2190 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2191 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2197void MyFrame::PositionConsole() {
2198#if defined(__WXMSW__) || defined(__WXMAC__)
2199 if (NULL == GetPrimaryCanvas())
return;
2201 int ccx, ccy, ccsx, ccsy, consx, consy;
2203 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2206 consoleHost->GetSize(&ccsx, &ccsy);
2207 consoleHost->GetPosition(&ccx, &ccy);
2209 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2210 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2211 consoleHost = GetPrimaryCanvas();
2216 if (consoleHost->GetCompass()) {
2217 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2219 if (compass_rect.y < 100)
2220 yOffset = compass_rect.y + compass_rect.height + 45;
2224 wxSize csz =
console->GetSize();
2228 wxPoint screen_pos =
2229 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2232 if (NULL == GetPrimaryCanvas())
return;
2234 int ccx, ccy, ccsx, ccsy, consx, consy;
2236 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2239 consoleHost->GetSize(&ccsx, &ccsy);
2240 consoleHost->GetPosition(&ccx, &ccy);
2242 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2243 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2244 consoleHost = GetPrimaryCanvas();
2247 int yTopOffset = 60;
2248 int yBottomOffset = 0;
2250 if (consoleHost->GetCompass()) {
2251 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2253 if (compass_rect.y < 100)
2254 yTopOffset = compass_rect.y + compass_rect.height;
2256 if (consoleHost->GetMUIBar()) {
2257 wxRect mui_rect = consoleHost->GetMUIBarRect();
2258 yBottomOffset = ccsy - mui_rect.y;
2262 wxSize csz =
console->GetSize();
2265 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2267 if (consy < yAvail) {
2268 yFinal = (yAvail - consy) / 2;
2269 yFinal += yTopOffset;
2270 }
else if (
console->GetCDI()->IsShown()) {
2271 int cdi_height =
console->GetCDI()->GetSize().y;
2272 int consy_no_cdi = consy - cdi_height;
2273 yFinal = (yAvail - consy_no_cdi) / 2;
2274 yFinal += yTopOffset;
2278 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2283void MyFrame::UpdateAllFonts() {
2292 DestroyPersistentDialogs();
2294 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2299void MyFrame::DestroyPersistentDialogs() {
2300 if (g_pais_query_dialog_active) {
2301 g_pais_query_dialog_active->Hide();
2302 g_pais_query_dialog_active->Destroy();
2303 g_pais_query_dialog_active = NULL;
2331void MyFrame::RefreshGroupIndices() {
2333 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2335 if (cc) cc->canvasRefreshGroupIndex();
2339void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2342 switch (event.GetId()) {
2343 case ID_MENU_SCALE_OUT:
2344 DoStackDelta(GetPrimaryCanvas(), 1);
2348 case ID_MENU_SCALE_IN:
2349 DoStackDelta(GetPrimaryCanvas(), -1);
2353 case ID_MENU_ZOOM_IN: {
2354 if (GetFocusCanvas()) {
2355 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2360 case ID_MENU_ZOOM_OUT: {
2361 if (GetFocusCanvas()) {
2362 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2367 case ID_MENU_ROUTE_NEW: {
2368 if (GetFocusCanvas()) {
2369 if (0 == GetFocusCanvas()->m_routeState) {
2370 GetFocusCanvas()->StartRoute();
2372 GetFocusCanvas()->FinishRoute();
2378 case ID_MENU_TOOL_MEASURE: {
2379 GetPrimaryCanvas()->StartMeasureRoute();
2383 case ID_MENU_TOOL_NMEA_DBG_LOG:
2384 m_data_monitor->Show();
2385 m_data_monitor->Raise();
2388 case ID_MENU_TOOL_IO_MONITOR:
2389 m_data_monitor->Show();
2392 case ID_MENU_MARK_BOAT: {
2397 case ID_MENU_MARK_CURSOR: {
2402 case ID_MENU_NAV_FOLLOW: {
2403 if (
gFrame->GetPrimaryCanvas())
2404 gFrame->GetPrimaryCanvas()->TogglebFollow();
2408 case ID_MENU_CHART_OUTLINES: {
2409 ToggleChartOutlines(GetFocusCanvas());
2413 case ID_MENU_CHART_QUILTING: {
2414 ToggleQuiltMode(GetFocusCanvas());
2418 case ID_MENU_UI_CHARTBAR: {
2419 ToggleChartBar(GetFocusCanvas());
2423 case ID_MENU_ENC_TEXT:
2425 ToggleENCText(GetFocusCanvas());
2428 case ID_MENU_ENC_LIGHTS: {
2429 ToggleLights(GetFocusCanvas());
2432 case ID_MENU_ENC_SOUNDINGS: {
2433 ToggleSoundings(GetFocusCanvas());
2436 case ID_MENU_ENC_ANCHOR: {
2437 ToggleAnchor(GetFocusCanvas());
2440 case ID_MENU_ENC_DATA_QUALITY: {
2441 ToggleDataQuality(GetFocusCanvas());
2444 case ID_MENU_SHOW_NAVOBJECTS: {
2445 ToggleNavobjects(GetFocusCanvas());
2449 case ID_MENU_AIS_TARGETS: {
2450 ToggleAISDisplay(GetFocusCanvas());
2453 case ID_MENU_AIS_MOORED_TARGETS: {
2454 g_bHideMoored = !g_bHideMoored;
2457 case ID_MENU_AIS_SCALED_TARGETS: {
2458 ToggleAISMinimizeTargets(GetFocusCanvas());
2462 case ID_MENU_AIS_TARGETLIST: {
2463 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2467 case ID_MENU_AIS_TRACKS: {
2468 g_bAISShowTracks = !g_bAISShowTracks;
2469 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2473 case ID_MENU_AIS_CPADIALOG: {
2474 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2475 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2476 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2477 if (g_bAIS_CPA_Alert) {
2478 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2483 case ID_MENU_AIS_CPASOUND: {
2484 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2485 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2489 case ID_MENU_AIS_CPAWARNING: {
2490 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2491 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2495 case wxID_PREFERENCES:
2502 case ID_SETTINGS_NEW: {
2507 case ID_SETTINGS_DELETE: {
2510 g_pOptions =
nullptr;
2514 case ID_RELOAD_CHARTS: {
2519 case ID_MENU_SETTINGS_BASIC: {
2522 androidDisableFullScreen();
2524 DoAndroidPreferences();
2531 case ID_MENU_UI_FULLSCREEN: {
2536 case ID_MENU_SHOW_CURRENTS: {
2537 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2538 GetFocusCanvas()->ReloadVP();
2539 GetFocusCanvas()->Refresh(
false);
2543 case ID_MENU_SHOW_TIDES: {
2544 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2545 GetFocusCanvas()->ReloadVP();
2546 GetFocusCanvas()->Refresh(
false);
2566 case ID_MENU_UI_COLSCHEME:
2567 case ID_COLSCHEME: {
2568 ToggleColorScheme();
2577 case ID_MENU_OQUIT: {
2582 case ID_MENU_ROUTE_MANAGER:
2583 case ID_ROUTEMANAGER: {
2584 pRouteManagerDialog = RouteManagerDialog::getInstance(
2587 if (pRouteManagerDialog->IsShown())
2588 pRouteManagerDialog->Hide();
2590 pRouteManagerDialog->UpdateRouteListCtrl();
2591 pRouteManagerDialog->UpdateTrkListCtrl();
2592 pRouteManagerDialog->UpdateWptListCtrl();
2593 pRouteManagerDialog->UpdateLayListCtrl();
2595 pRouteManagerDialog->Show();
2599 pRouteManagerDialog->Centre();
2600 pRouteManagerDialog->Raise();
2606 case ID_MENU_NAV_TRACK:
2608 if (!g_bTrackActive) {
2610 g_bTrackCarryOver =
true;
2613 g_bTrackCarryOver =
false;
2614 RefreshAllCanvas(
true);
2619 case ID_MENU_CHART_NORTHUP: {
2620 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2623 case ID_MENU_CHART_COGUP: {
2624 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2627 case ID_MENU_CHART_HEADUP: {
2628 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2632 case ID_MENU_MARK_MOB:
2638 case ID_MASTERTOGGLE: {
2640 wxString tip = _(
"Show Toolbar");
2641 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2643 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2645 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2648 if (g_bmasterToolbarFull)
2649 m_nMasterToolCountShown =
2653 m_nMasterToolCountShown = 2;
2655 m_nMasterToolCountShown =
2658 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2666 case ID_CMD_SELECT_CHART_TYPE: {
2667 selectChartDisplay(event.GetExtraLong(), -1);
2671 case ID_CMD_SELECT_CHART_FAMILY: {
2672 selectChartDisplay(-1, event.GetExtraLong());
2676 case ID_CMD_APPLY_SETTINGS: {
2677 applySettingsString(event.GetString());
2679 androidRestoreFullScreen();
2685 case ID_CMD_NULL_REFRESH: {
2690 case ID_CMD_SETVP: {
2691 setStringVP(event.GetString());
2695 case ID_CMD_INVALIDATE: {
2701 case ID_CMD_POST_JSON_TO_PLUGINS: {
2707 int numErrors = reader.
Parse(event.GetString(), &root);
2708 if (numErrors == 0) {
2709 if (root[
"MessageID"].IsString()) {
2710 wxString MsgID = root[
"MessageID"].
AsString();
2734 ArrayOfPlugInToolbarTools tool_array =
2736 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2738 if (event.GetId() == pttc->id) {
2739 if (pttc->m_pplugin)
2761bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2762 bool viz_now = g_bmasterToolbarFull;
2765 wxString tip = _(
"Show Toolbar");
2767 tip = _(
"Hide Toolbar");
2769 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2772 bool toggle =
false;
2773 if (viz && !g_bmasterToolbarFull)
2776 else if (!viz && g_bmasterToolbarFull)
2780 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2783 if (g_bmasterToolbarFull)
2784 m_nMasterToolCountShown =
2788 m_nMasterToolCountShown = 2;
2790 m_nMasterToolCountShown =
2793 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2799void MyFrame::ScheduleReloadCharts() {
2800 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2801 evt.SetId(ID_RELOAD_CHARTS);
2802 GetEventHandler()->AddPendingEvent(evt);
2805void MyFrame::ScheduleDeleteSettingsDialog() {
2806 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2807 evt.SetId(ID_SETTINGS_DELETE);
2808 GetEventHandler()->AddPendingEvent(evt);
2811void MyFrame::ScheduleSettingsDialog() {
2812 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2813 evt.SetId(ID_SETTINGS);
2814 GetEventHandler()->AddPendingEvent(evt);
2817void MyFrame::ScheduleSettingsDialogNew() {
2818 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2819 evt.SetId(ID_SETTINGS_NEW);
2820 GetEventHandler()->AddPendingEvent(evt);
2823void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2824 UpdateCanvasConfigDescriptors();
2826 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2827 CreateCanvasLayout(
true);
2829 CreateCanvasLayout();
2833 ConfigureStatusBar();
2834 wxSize lastOptSize = options_lastWindowSize;
2839 options_lastWindowSize = lastOptSize;
2843 ScheduleSettingsDialogNew();
2845 ScheduleSettingsDialog();
2850 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2853 int index_hint = -1;
2854 if (i < pathArray.GetCount())
2855 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2856 cc->canvasChartsRefresh(index_hint);
2857 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2866 return GetPrimaryCanvas();
2869void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2870 if (g_bmasterToolbarFull) {
2871#ifndef OCPN_TOOLBAR_ANIMATE
2872 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2875 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2876 m_nMasterToolCountShown++;
2881 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2889#ifndef OCPN_TOOLBAR_ANIMATE
2890 m_nMasterToolCountShown = 1;
2892 if (m_nMasterToolCountShown > 1) {
2893 m_nMasterToolCountShown--;
2897 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2907void MyFrame::InvalidateAllGL() {
2910 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2920void MyFrame::RefreshAllCanvas(
bool bErase) {
2922 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2925 cc->Refresh(bErase);
2930void MyFrame::setStringVP(wxString VPS) {
2935 wxStringTokenizer tkz(VPS,
";");
2937 wxString token = tkz.GetNextToken();
2939 token.ToDouble(&lat);
2941 token = tkz.GetNextToken();
2943 token.ToDouble(&lon);
2945 token = tkz.GetNextToken();
2947 token.ToDouble(&scale_ppm);
2949 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2952void MyFrame::DoSettingsNew() {
2959void MyFrame::DoSettings() {
2963 ApplyGlobalSettings(
true);
2966 bool b_loadHarmonics =
false;
2967 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2970 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2973 if (b_loadHarmonics) LoadHarmonics();
2981 g_bShowChartBar = !g_bShowChartBar;
2983 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
2988 if (g_bShowChartBar) {
2990 UpdateControlBar(cc);
2993 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
2996void MyFrame::ToggleColorScheme() {
2997 static bool lastIsNight;
2998 ColorScheme s = GetColorScheme();
3001 if (lastIsNight && is == 3)
3004 lastIsNight =
false;
3006 if (lastIsNight) is = 2;
3007 if (is == 3) lastIsNight =
true;
3008 s = (ColorScheme)is;
3009 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3011 SetAndApplyColorScheme(s);
3014void MyFrame::ToggleFullScreen() {
3015 bool to = !IsFullScreen();
3020 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3022 ShowFullScreen(to, style);
3025 UpdateAllToolbars(global_color_scheme);
3027 UpdateControlBar(GetPrimaryCanvas());
3029 TriggerRecaptureTimer();
3032void MyFrame::ActivateMOB() {
3034 wxDateTime mob_time = wxDateTime::Now();
3035 wxString mob_label(_(
"MAN OVERBOARD"));
3036 mob_label += _(
" on ");
3037 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3041 pWP_MOB->SetShared(
true);
3043 pWP_MOB->SetWaypointArrivalRadius(
3045 pWP_MOB->SetUseSca(
false);
3047 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3055 new RoutePoint(zlat, zlon, g_default_wp_icon,
3056 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3057 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3062 temp_route->AddPoint(pWP_src);
3063 temp_route->AddPoint(pWP_MOB);
3065 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3075 temp_route->SetRouteArrivalRadius(-1.0);
3081 v[
"GUID"] = temp_route->
m_GUID;
3082 wxString msg_id(
"OCPN_MAN_OVERBOARD");
3083 SendJSONMessageToAllPlugins(msg_id, v);
3086 if (RouteManagerDialog::getInstanceFlag()) {
3087 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3088 pRouteManagerDialog->UpdateRouteListCtrl();
3089 pRouteManagerDialog->UpdateWptListCtrl();
3094 RefreshAllCanvas(
false);
3096 wxString mob_message(_(
"MAN OVERBOARD"));
3097 mob_message += _(
" Time: ");
3098 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3099 mob_message += _(
" Position: ");
3100 mob_message += toSDMM(1,
gLat);
3102 mob_message += toSDMM(2,
gLon);
3103 wxLogMessage(mob_message);
3105void MyFrame::TrackOn() {
3106 g_bTrackActive =
true;
3114 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3116 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3118 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3121 androidSetTrackTool(
true);
3124 if (RouteManagerDialog::getInstanceFlag()) {
3125 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3126 pRouteManagerDialog->UpdateTrkListCtrl();
3127 pRouteManagerDialog->UpdateRouteListCtrl();
3133 if (name.IsEmpty()) {
3139 name = _(
"(Unnamed Track)");
3143 wxString msg_id(
"OCPN_TRK_ACTIVATED");
3144 SendJSONMessageToAllPlugins(msg_id, v);
3145 g_FlushNavobjChangesTimeout =
3149Track *MyFrame::TrackOff(
bool do_add_point) {
3154 wxString msg_id(
"OCPN_TRK_DEACTIVATED");
3156 SendJSONMessageToAllPlugins(msg_id, v);
3165 if (g_bTrackDaily) {
3170 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3171 return_val = pExtendTrack;
3178 g_bTrackActive =
false;
3180 if (RouteManagerDialog::getInstanceFlag()) {
3181 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3182 pRouteManagerDialog->UpdateTrkListCtrl();
3183 pRouteManagerDialog->UpdateRouteListCtrl();
3187 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3189 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3190 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3193 androidSetTrackTool(
false);
3197 m_target_rotate_time = wxInvalidDateTime;
3202void MyFrame::InitializeTrackRestart() {
3203 if (!g_bTrackDaily)
return;
3204 if (m_target_rotate_time.IsValid())
return;
3207 switch (g_track_rotate_time_type) {
3209 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3211 case TIME_TYPE_COMPUTER:
3212 rotate_at = g_track_rotate_time;
3216 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3217 rotate_at = g_track_rotate_time + utc_offset;
3220 if (rotate_at > 86400)
3222 else if (rotate_at < 0)
3225 wxTimeSpan rotate_seconds = wxTimeSpan(0, 0, rotate_at);
3226 m_target_rotate_time = wxDateTime::Today() + rotate_seconds;
3229 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3230 m_target_rotate_time += wxTimeSpan(24);
3234bool MyFrame::ShouldRestartTrack() {
3236 InitializeTrackRestart();
3238 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3239 m_target_rotate_time += wxTimeSpan(24);
3245void MyFrame::TrackDailyRestart() {
3247 Track *pPreviousTrack = TrackOff(
true);
3254 if (pPreviousTrack) {
3255 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3259 if (RouteManagerDialog::getInstanceFlag()) {
3260 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3261 pRouteManagerDialog->UpdateTrkListCtrl();
3262 pRouteManagerDialog->UpdateRouteListCtrl();
3267void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3269 cc->SetUpMode(mode);
3271 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3272 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3273 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3276 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3281 cc->SetShowENCText(!cc->GetShowENCText());
3283 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3291void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3294 cc->SetENCDisplayCategory(nset);
3296 UpdateGlobalMenuItems();
3307 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3309 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3318 cc->SetShowENCLights(!cc->GetShowENCLights());
3320 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3330void MyFrame::ToggleRocks(
void )
3336 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3337 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3338 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3339 pOLE->nViz = !pOLE->nViz;
3343 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3344 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3345 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3348 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3352 ps52plib->GenerateStateHash();
3359 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3361 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3369 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3371 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3386 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3387 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3392 cc->SetShowAIS(!cc->GetShowAIS());
3393 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3397void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3398 cc->SetAttenAIS(!cc->GetAttenAIS());
3399 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3405 cc->m_bFollow =
true;
3408 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3412 SetChartUpdatePeriod();
3420 cc->m_bFollow =
false;
3422 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3426 SetChartUpdatePeriod();
3429void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3430 cc->SetShowOutlines(!cc->GetShowOutlines());
3432 RefreshAllCanvas(
false);
3436 if (g_bopengl) InvalidateAllGL();
3439 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3442void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3444void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3446 bool enabled = m_pMenuBar->IsEnabled(item_id);
3447 m_pMenuBar->Enable(item_id,
false);
3448 m_pMenuBar->Check(item_id, state);
3449 m_pMenuBar->Enable(item_id, enabled);
3453void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3460void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3461 wxBitmap *bmpRollover) {
3463 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3468void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3469 wxString rolloverSVGfile,
3470 wxString toggledSVGfile) {
3473 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3477void MyFrame::ConfigureStatusBar() {
3479 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3482 UseNativeStatusBar(
false);
3485 if (g_bShowStatusBar) {
3486 if (!m_pStatusBar) {
3488 CreateStatusBar(m_StatusBarFieldCount, 0);
3489 ApplyGlobalColorSchemetoStatusBar();
3494 m_pStatusBar->Destroy();
3495 m_pStatusBar = NULL;
3501void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3502 ConfigureStatusBar();
3504 wxSize lastOptSize = options_lastWindowSize;
3510 options_lastWindowSize = lastOptSize;
3512 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3515wxString _menuText(wxString name, wxString shortcut) {
3519 menutext <<
"\t" << shortcut;
3524void MyFrame::BuildMenuBar() {
3530 bool showMenuBar =
true;
3532 bool showMenuBar = g_bShowMenuBar;
3544 m_pMenuBar =
new wxMenuBar();
3545 RegisterGlobalMenuItems();
3546 SetMenuBar(m_pMenuBar);
3550 UpdateGlobalMenuItems();
3555 m_pMenuBar->Destroy();
3561void MyFrame::RegisterGlobalMenuItems() {
3562 if (!m_pMenuBar)
return;
3564 wxMenu *nav_menu =
new wxMenu();
3565 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3566 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3567 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3568 nav_menu->AppendSeparator();
3569 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3570 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3571 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3572 nav_menu->AppendSeparator();
3574 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3575 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3577 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3578 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3580 nav_menu->AppendSeparator();
3581 nav_menu->Append(ID_MENU_SCALE_IN,
3582 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3583 nav_menu->Append(ID_MENU_SCALE_OUT,
3584 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3586 nav_menu->AppendSeparator();
3587 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3589 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3591 wxMenu *view_menu =
new wxMenu();
3593 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3594 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3595 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3596 _menuText(_(
"Show Chart Outlines"),
"O"));
3598 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3599 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3600 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3601 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3603 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3604 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3606 view_menu->AppendSeparator();
3608 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3609 _menuText(_(
"Show ENC text"),
"T"));
3610 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3611 _menuText(_(
"Show ENC Lights"),
"L"));
3612 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3613 _menuText(_(
"Show ENC Soundings"),
"S"));
3614 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3615 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3616 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3617 _menuText(_(
"Show ENC Data Quality"),
"U"));
3618 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3619 _menuText(_(
"Show Navobjects"),
"V"));
3621 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3622 _menuText(_(
"Show ENC text"),
"Alt-T"));
3623 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3624 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3625 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3626 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3627 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3628 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3629 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3630 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3631 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3632 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3634 view_menu->AppendSeparator();
3635 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3636 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3637 view_menu->AppendSeparator();
3639 view_menu->Append(ID_MENU_UI_COLSCHEME,
3640 _menuText(_(
"Change Color Scheme"),
"C"));
3642 view_menu->Append(ID_MENU_UI_COLSCHEME,
3643 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3646 view_menu->AppendSeparator();
3648 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3649 _menuText(_(
"Toggle Full Screen"),
"F11"));
3651 m_pMenuBar->Append(view_menu, _(
"&View"));
3653 wxMenu *ais_menu =
new wxMenu();
3654 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3655 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3656 _(
"Attenuate less critical AIS targets"));
3657 ais_menu->AppendSeparator();
3658 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3659 _(
"Hide Moored AIS Targets"));
3660 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3661 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3662 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3665 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3666 _menuText(_(
"Show CPA Warnings"),
"W"));
3668 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3669 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3672 ais_menu->AppendSeparator();
3673 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3674 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3676 wxMenu *tools_menu =
new wxMenu();
3677 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3678 _menuText(_(
"Data Monitor"),
"Alt-C"));
3680 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3681 _menuText(_(
"Measure Distance"),
"M"));
3683 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3684 _menuText(_(
"Measure Distance"),
"Alt-M"));
3687 tools_menu->AppendSeparator();
3688 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3689 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3690 tools_menu->AppendSeparator();
3691 tools_menu->Append(ID_MENU_MARK_BOAT,
3692 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3693 tools_menu->Append(ID_MENU_MARK_CURSOR,
3694 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3695 tools_menu->AppendSeparator();
3699 _menuText(_(
"Drop MOB Marker"),
3701 tools_menu->AppendSeparator();
3702 tools_menu->Append(wxID_PREFERENCES,
3703 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3705 tools_menu->Append(ID_MENU_MARK_MOB,
3706 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3707 tools_menu->AppendSeparator();
3708 tools_menu->Append(wxID_PREFERENCES,
3709 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3711 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3714 wxMenu *window_menu =
new wxMenu();
3715 m_pMenuBar->Append(window_menu, _(
"&Window"));
3718 wxMenu *help_menu =
new wxMenu();
3719 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3720 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3721 m_pMenuBar->Append(help_menu, _(
"&Help"));
3724 UpdateGlobalMenuItems();
3727void MyFrame::UpdateGlobalMenuItems() {
3728 if (!m_pMenuBar)
return;
3730 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3731 ->Check(GetPrimaryCanvas()->m_bFollow);
3732 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3733 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3734 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3735 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3736 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3737 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3738 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3739 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3740 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3741 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3742 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3743 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3744 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3745 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3746 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3747 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3748 if (g_bAIS_CPA_Alert) {
3749 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3750 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3752 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3753 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3756 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3757 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3758 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3761 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3762 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3763 ->Check(ps52plib->GetShowSoundings());
3765 bool light_state =
false;
3767 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3769 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3770 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3771 light_state = (pOLE->nViz == 1);
3776 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3777 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3781 DisCat nset = ps52plib->GetDisplayCategory();
3782 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3783 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3784 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3785 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3786 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3787 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3788 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3790 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3791 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3792 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3797void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3798 if (!m_pMenuBar)
return;
3800 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3802 if (cc->GetUpMode() == NORTH_UP_MODE)
3803 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3804 else if (cc->GetUpMode() == COURSE_UP_MODE)
3805 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3807 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3809 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3810 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3811 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3812 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3813 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3814 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3815 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3816 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3817 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3818 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3819 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3820 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3821 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3822 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3823 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3826 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3827 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3830 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3832 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3833 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3838 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3842 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3843 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3844 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3845 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3846 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3847 ->Check(cc->GetShowENCDataQual());
3848 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3850 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3851 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3852 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3857void MyFrame::InvalidateAllCanvasUndo() {
3859 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3861 if (cc) cc->undo->InvalidateUndo();
3865void MyFrame::SubmergeAllCanvasToolbars() {
3867 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3869 if (cc) cc->SubmergeToolbar();
3873void MyFrame::SurfaceAllCanvasToolbars() {
3874 if (g_bshowToolbar) {
3876 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3878 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3885void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3887 if (lon > 180.0) lon -= 360.0;
3892 cc->JumpToPosition(lat, lon,
scale);
3895 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3899void MyFrame::UpdateCanvasConfigDescriptors() {
3901 for (
unsigned int i = 0;
3902 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3903 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3911 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3912 cc->GroupID = chart->m_groupIndex;
3915 cc->
bQuilt = chart->GetQuiltMode();
3922 cc->
bFollow = chart->m_bFollow;
3927 int upmode = chart->GetUpMode();
3928 if (upmode == COURSE_UP_MODE)
3930 else if (upmode == HEAD_UP_MODE)
3937void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3938 if (!RBBox.GetValid())
return;
3940 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3941 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3944 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3945 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3953 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3954 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3956 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3957 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3959 cc->GetSize(&ww, &wh);
3961 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3963 ppm = wxMin(ppm, 1.0);
3969void MyFrame::PrepareOptionsClose(
options *settings,
3970 int settings_return_value) {
3972 options_lastPage = settings->lastPage;
3977 if (options_lastPage == 1) options_lastPage = 0;
3979 options_subpage = settings->lastSubPage;
3980 options_lastWindowPos = settings->lastWindowPos;
3981 options_lastWindowSize = settings->lastWindowSize;
3984 androidEnableBackButton(
true);
3985 androidEnableOptionsMenu(
true);
3986 androidRestoreFullScreen();
3987 androidEnableRotation();
3992void MyFrame::DoOptionsDialog() {
3994 AbstractPlatform::ShowBusySpinner();
3997 pConfig->SetPath(
"/Settings");
3998 pConfig->Read(
"OptionsSizeX", &sx, -1);
3999 pConfig->Read(
"OptionsSizeY", &sy, -1);
4001 wxWindow *optionsParent =
this;
4003 optionsParent = GetPrimaryCanvas();
4008 AbstractPlatform::HideBusySpinner();
4012 g_options->SetInitChartDir(*pInit_Chart_Dir);
4016 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4017 g_options->SetWorkDirListPtr(pWorkDirArray);
4023 prev_locale = g_locale;
4024 g_options->SetInitialPage(options_lastPage, options_subpage);
4027 g_options->lastWindowPos = options_lastWindowPos;
4028 if (options_lastWindowPos != wxPoint(0, 0)) {
4030 g_options->SetSize(options_lastWindowSize);
4034 if (options_lastWindowSize != wxSize(0, 0)) {
4035 g_options->SetSize(options_lastWindowSize);
4040 androidEnableBackButton(
false);
4041 androidEnableOptionsMenu(
false);
4042 androidDisableFullScreen();
4050 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4053 wxString chart_file_name;
4054 if (cc->GetQuiltMode()) {
4055 int dbi = cc->GetQuiltRefChartdbIndex();
4056 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4058 if (cc->m_singleChart)
4059 chart_file_name = cc->m_singleChart->GetFullPath();
4062 pathArray.Add(chart_file_name);
4068 last_canvasConfig = g_canvasConfig;
4071 g_last_ChartScaleFactor = g_ChartScaleFactor;
4077void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4078 bool b_need_refresh =
false;
4080 if ((rr & VISIT_CHARTS) &&
4081 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4083 UpdateChartDatabaseInplace(*pNewDirArray,
4084 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4087 b_need_refresh =
true;
4091 if (rr & STYLE_CHANGED) {
4094 _(
"Please restart OpenCPN to activate language or style changes."),
4095 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4098 bool b_groupchange =
false;
4099 if (((rr & VISIT_CHARTS) &&
4100 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) ||
4101 (rr & GROUPS_CHANGED)) {
4102 b_groupchange = ScrubGroupArray();
4104 RefreshGroupIndices();
4107 if (rr & GROUPS_CHANGED || b_groupchange) {
4108 pConfig->DestroyConfigGroups();
4112 if (rr & TIDES_CHANGED) {
4118 if (rr & S52_CHANGED) {
4119 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4122 pConfig->UpdateSettings();
4130 g_Platform->GetDisplayDPmm());
4133 double stuffcog = NAN;
4134 double stuffsog = NAN;
4135 if (!std::isnan(
gCog)) stuffcog =
gCog;
4136 if (!std::isnan(
gSog)) stuffsog =
gSog;
4138 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
4139 COGFilterTable[i] = stuffcog;
4140 SOGFilterTable[i] = stuffsog;
4143 SetChartUpdatePeriod();
4145 if (rr & GL_CHANGED) {
4149 b_need_refresh =
true;
4152 if (rr & S52_CHANGED) {
4153 b_need_refresh =
true;
4157 if (rr & REBUILD_RASTER_CACHE) {
4159 GetPrimaryCanvas()->Disable();
4161 GetPrimaryCanvas()->Enable();
4166 if (g_config_display_size_manual &&
4174 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4181 int rrt = rr & S52_CHANGED;
4183 (rrt == S52_CHANGED) ||
4184 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4194 ps52plib->SetScaleFactorExp(
4195 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4196 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4200 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4202 if (cc) cc->ApplyGlobalSettings();
4207 bool ztc = g_bEnableZoomToCursor;
4208 g_bEnableZoomToCursor =
4212 if (!GetPrimaryCanvas()->IsFrozen())
4214 g_bEnableZoomToCursor = ztc;
4217 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4226 SetGPSCompassScale();
4228 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4231 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4232 cc->UpdateCanvasControlBar();
4235 UpdateGPSCompassStatusBoxes();
4237 SetAllToolbarScale();
4238 RequestNewToolbars();
4241 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4244 cc->RebuildCursors();
4249 bool b_masterScaleChange =
false;
4250 if (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4251 b_masterScaleChange =
true;
4253 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4254 RequestNewMasterToolbar(
true);
4256 bool bMuiChange =
false;
4262 if (b_masterScaleChange || bMuiChange) {
4264 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4267 cc->ProcessNewGUIScale();
4273 if (rr & LOCALE_CHANGED) {
4274 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4276 rr |= NEED_NEW_OPTIONS;
4285 g_last_ChartScaleFactor = g_ChartScaleFactor;
4287 if (rr & FORCE_RELOAD) ScheduleReloadCharts();
4292bool MyFrame::CheckGroup(
int igroup) {
4293 if (igroup == 0)
return true;
4297 if (!pGroup->m_element_array.size())
4300 for (
const auto &elem : pGroup->m_element_array) {
4301 for (
unsigned int ic = 0;
4302 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4304 wxString chart_full_path(pcte->GetpFullPath(), wxConvUTF8);
4306 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4313bool MyFrame::ScrubGroupArray() {
4318 bool b_change =
false;
4319 unsigned int igroup = 0;
4320 while (igroup < g_pGroupArray->GetCount()) {
4321 bool b_chart_in_element =
false;
4324 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4325 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4327 for (
unsigned int ic = 0;
4328 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4330 wxString chart_full_path = pcte->GetFullSystemPath();
4332 if (chart_full_path.StartsWith(element_root)) {
4333 b_chart_in_element =
true;
4339 if (!b_chart_in_element) {
4340 wxString test_string =
"GSHH";
4341 if (element_root.Upper().Contains(test_string))
4342 b_chart_in_element =
true;
4345 if (!b_chart_in_element)
4347 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4359void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4361 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4363 if (cc && (cc != ccThis)) cc->Refresh();
4368void MyFrame::ChartsRefresh() {
4371 AbstractPlatform::ShowBusySpinner();
4373 bool b_run = FrameTimer1.IsRunning();
4376 FrameTenHzTimer.Stop();
4379 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4382 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4383 if (cc->GetQuiltMode()) {
4384 currentIndex = cc->GetQuiltReferenceChartIndex();
4386 cc->canvasChartsRefresh(currentIndex);
4390 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4391 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4393 AbstractPlatform::HideBusySpinner();
4396void MyFrame::InvalidateAllQuilts() {
4397 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4400 cc->InvalidateQuilt();
4401 cc->SetQuiltRefChart(-1);
4402 cc->m_singleChart = NULL;
4407bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4409 const wxString &ChartListFileName) {
4410 bool b_run = FrameTimer1.IsRunning();
4412 FrameTenHzTimer.Stop();
4414 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4415 FrameCOGTimer.Stop();
4418 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4421 cc->InvalidateQuilt();
4422 cc->SetQuiltRefChart(-1);
4423 cc->m_singleChart = NULL;
4433 AbstractPlatform::ShowBusySpinner();
4435 wxGenericProgressDialog *pprog =
nullptr;
4437 wxString longmsg = _(
"OpenCPN Chart Update");
4439 ".................................................................."
4442 pprog =
new wxGenericProgressDialog();
4445 pprog->SetFont(*qFont);
4447 pprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4448 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4449 wxPD_REMAINING_TIME);
4456 wxLogMessage(
"Starting chart database Update...");
4457 wxString gshhg_chart_loc = gWorldMapLocation;
4458 gWorldMapLocation = wxEmptyString;
4462 ChartData->SaveBinary(ChartListFileName);
4463 wxLogMessage(
"Finished chart database Update");
4465 if (gWorldMapLocation.empty()) {
4469 gWorldMapLocation = gDefaultWorldMapLocation;
4470 gshhg_chart_loc = wxEmptyString;
4473 if (gWorldMapLocation != gshhg_chart_loc) {
4475 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4477 if (cc) cc->ResetWorldBackgroundChart();
4480 gshhsCrossesLandReset();
4485 AbstractPlatform::HideBusySpinner();
4487 pConfig->UpdateChartDirs(DirArray);
4490 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4491 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4493 if (b_runCOGTimer) {
4495 int period_ms = 100;
4497 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
4504 cc->ToggleCanvasQuiltMode();
4506 bool cur_mode = cc->GetQuiltMode();
4508 if( !cc->GetQuiltMode() )
4509 cc->SetQuiltMode(
true );
4511 if( cc->GetQuiltMode() ) {
4512 cc->SetQuiltMode(
false );
4513 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4517 if( cur_mode != cc->GetQuiltMode() ){
4523 g_bQuiltEnable = cc->GetQuiltMode();
4527 ps52plib->GenerateStateHash();
4532void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4534void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4536void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4538 cc->DoCanvasStackDelta(direction);
4542void MyFrame::PositionIENCToolbar() {
4546 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4548 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4556void MyFrame::OnInitTimer(wxTimerEvent &event) {
4559 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4563 wxLog::FlushActive();
4565 switch (m_iInitCount++) {
4570 if (g_bInlandEcdis) {
4571 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4572 double range_set = 500.;
4574 range = wxRound(range * 10) / 10.;
4578 else if (range > 2000.)
4580 else if (range > 1600.)
4582 else if (range > 1200.)
4584 else if (range > 800.)
4589 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4593 g_Platform->SetFullscreen(g_bFullscreen);
4597 RebuildChartDatabase();
4598 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4601 cc->SetGroupIndex(0,
false);
4609 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4610 CHART_FAMILY_RASTER)) {
4615 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4616 CHART_FAMILY_VECTOR)) {
4629 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4632 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4634 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4637 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4641 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4642 NavObj_dB::GetInstance().LoadNavObjects();
4645 if (!g_AW1GUID.IsEmpty()) {
4648 if (!g_AW2GUID.IsEmpty()) {
4654 appendOSDirSlash(&layerdir);
4655 layerdir.Append(
"layers");
4657 if (wxDir::Exists(layerdir)) {
4659 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4660 wxLogMessage(laymsg);
4661 pConfig->LoadLayers(layerdir);
4671 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4685 3 * GetCharHeight());
4687 m_data_monitor->Center();
4695 pConfig->SetPath(
"/Settings");
4696 pConfig->Read(
"OptionsSizeX", &sx, -1);
4697 pConfig->Read(
"OptionsSizeY", &sy, -1);
4699 wxWindow *optionsParent =
this;
4701 optionsParent = GetPrimaryCanvas();
4707 BuildiENCToolbar(
true);
4714 if (!g_params.empty()) {
4715 for (
size_t n = 0; n < g_params.size(); n++) {
4716 wxString path = g_params[n];
4717 if (::wxFileExists(path)) {
4719 pSet->load_file(path.fn_str());
4722 pSet->LoadAllGPXObjects(
4723 !pSet->IsOpenCPN(), wpt_dups,
4725 LLBBox box = pSet->GetBBox();
4726 if (box.GetValid()) {
4727 CenterView(GetPrimaryCanvas(), box);
4736 InitAppMsgBusListener();
4741 auto loader = PluginLoader::GetInstance();
4742 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4743 if (!b_haveWMM)
gVar = g_UserVar;
4751 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4754 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4756 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4759 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4763 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4764 NavObj_dB::GetInstance().LoadNavObjects();
4767 if (!g_AW1GUID.IsEmpty()) {
4770 if (!g_AW2GUID.IsEmpty()) {
4776 appendOSDirSlash(&layerdir);
4777 layerdir.Append(
"layers");
4779 if (wxDir::Exists(layerdir)) {
4781 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4782 wxLogMessage(laymsg);
4783 pConfig->LoadLayers(layerdir);
4790 wxLogMessage(
"OnInitTimer...Last Call");
4794 RequestNewMasterToolbar();
4796 PositionIENCToolbar();
4798 g_bDeferredInitDone =
true;
4808 GetPrimaryCanvas()->SetFocus();
4809 GetPrimaryCanvas()->Enable();
4816 if (b_reloadForPlugins) {
4822 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4824 if (cc) cc->SetFirstAuto(
true);
4832 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4834 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4838 cc->CheckGroupValid();
4843 androidEnableBackButton(
true);
4844 androidEnableRotation();
4845 androidEnableOptionItems(
true);
4851 if (g_start_fullscreen && !IsFullScreen()) ToggleFullScreen();
4857 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4859 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4861 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4867 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4869 wxLog::FlushActive();
4871 RefreshAllCanvas(
true);
4872 wxGetApp().m_usb_watcher.Start();
4878void MyFrame::InitAppMsgBusListener() {
4879 auto &msgbus = AppMsgBus::GetInstance();
4882 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4883 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4887 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4888 HandleBasicNavMsg(basicnav_msg);
4892 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4893 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4897 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4898 HandleGPSWatchdogMsg(msg);
4905void MyFrame::ReleaseApiListeners() {}
4910 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4911 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4912 server.SetGetRestApiEndpointCb(
4913 [&] {
return wxGetApp().m_rest_server.GetEndpoint(); });
4914 server.open_file_cb = [](
const std::string &path) {
4915 return wxGetApp().OpenFile(path);
4922void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4923 if (msg->gps_watchdog <= 0) {
4924 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4928 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4933 if (m_fix_start_time.IsValid()) {
4934 wxDateTime now = wxDateTime::Now();
4935 wxTimeSpan span = now - m_fix_start_time;
4936 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4937 auto ¬eman = NotificationManager::GetInstance();
4938 wxString msg = _(
"GNSS Position fix lost");
4939 noteman.AddNotification(NotificationSeverity::kCritical,
4941 m_fix_start_time = wxInvalidDateTime;
4945 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4946 bool last_bVelocityValid = bVelocityValid;
4947 bVelocityValid =
false;
4954void MyFrame::CalculateCOGAverage() {
4956 if (!std::isnan(
gCog)) {
4959 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4962 double sum = 0., count = 0;
4964 double adder = COGTable[i];
4965 if (std::isnan(adder))
continue;
4967 if (fabs(adder -
g_COGAvg) > 180.) {
4981 else if (sum >= 360.)
4990void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
4991 m_fixtime = msg->time;
4992 double hdt_data_interval = 0;
4993 double fix_time_interval = 0;
4995 double msgtime = msg->set_time.tv_sec;
4996 double m1 = msg->set_time.tv_nsec / 1e9;
4999 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
5000 ((msg->vflag & POS_VALID) == POS_VALID)) {
5002 if (!m_fix_start_time.IsValid()) {
5003 m_fix_start_time = wxDateTime::Now();
5008 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
5011 fix_time_gt_last = fix_time_gt;
5012 uint64_t fix_time_gt_now =
5013 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5014 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5018 double implied_sog = dist / (fix_time_interval / 3600);
5023 gLat_gt_m1 = gLat_gt;
5024 gLon_gt_m1 = gLon_gt;
5028 fix_time_gt = fix_time_gt_now;
5032 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5033 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5034 gCog_gt_m1 = gCog_gt;
5044 if (!std::isnan(gCog_gt_m1)) {
5046 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5053 if ((fix_time_gt - fix_time_gt_last) > .08) {
5058 if (gCog_gt > gCog_gt_m1) {
5059 if ((gCog_gt - gCog_gt_m1) > 180.)
5064 if ((gCog_gt_m1 - gCog_gt) > 180.)
5069 difft = fabs(gCog_gt - gCog_gt_m1);
5070 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5078 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5079 tentative_cog_rate_gt *= 1e9;
5080 cog_rate_gt = tentative_cog_rate_gt;
5088 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5091static double hdt_avg;
5092 double hdt_norm =
gHdt;
5093 if(
gHdt > 180) hdt_norm -= 360;
5096 hdt_avg += hdt_norm * 0.1;
5101 if (!std::isnan(
gHdt)) {
5103 uint64_t hdt_time_gt_last = hdt_time_gt;
5104 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5105 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5108 if (hdt_data_interval > .09) {
5110 gHdt_gt_m1 = gHdt_gt;
5113 if (!std::isnan(gHdt_gt_m1)) {
5115 double tentative_hdt_rate_gt =
5116 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5117 tentative_hdt_rate_gt *= 1e9;
5119 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5120 hdt_rate_gt = tentative_hdt_rate_gt;
5128 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5131 CalculateCOGAverage();
5139 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5140 if ((msg->vflag & POS_VALID) == POS_VALID)
5145 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5147 bVelocityValid =
true;
5151void MyFrame::UpdateStatusBar() {
5154 unsigned long uiCurrentTickCount;
5155 m_MMEAeventTime.SetToCurrent();
5156 uiCurrentTickCount =
5157 m_MMEAeventTime.GetMillisecond() / 100;
5158 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5159 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5160 m_ulLastNMEATicktime = uiCurrentTickCount;
5162 if (m_tick_idx++ > 6) m_tick_idx = 0;
5167 if (NULL != GetStatusBar()) {
5170 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5173 wxString s1(tick_buf, wxConvUTF8);
5175 s1 += toSDMM(1,
gLat);
5177 s1 += toSDMM(2,
gLon);
5179 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5183 if (!std::isnan(
gSog))
5184 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5186 sogcog.Printf(
"SOG --- ");
5190 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5192 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5194 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5195 (
int)toMagnetic(
gCog), 0x00B0);
5197 cogs.Printf((
"COG ---%c"), 0x00B0);
5199 sogcog.Append(cogs);
5200 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5205void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5206 MemFootTimer.Stop();
5208 int memsize = GetApplicationMemoryUse();
5211 printf(
"Memsize: %d \n", memsize);
5214 if (memsize > (g_MemFootMB * 1000)) {
5218 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5219 unsigned int nCache = pCache->GetCount();
5222 for (
unsigned int i = 0; i < nCache; i++) {
5232 for (
unsigned int i = 0; i < nCache - 1; i++) {
5233 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5235 pcea[i] = pcea[i + 1];
5246 unsigned int idelete = 0;
5247 unsigned int idelete_max = pCache->GetCount();
5250 unsigned int minimum_cache = 1;
5251 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5253 while ((memsize > (g_MemFootMB * 1000)) &&
5254 (pCache->GetCount() > minimum_cache) &&
5255 (idelete < idelete_max)) {
5256 int memsizeb = memsize;
5260 memsize = GetApplicationMemoryUse();
5261 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5269 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5274void MyFrame::CheckToolbarPosition() {
5277 static bool bMaximized;
5279 if (IsMaximized() && !bMaximized) {
5286 PositionIENCToolbar();
5287 }
else if (!IsMaximized() && bMaximized) {
5295 PositionIENCToolbar();
5300void MyFrame::ProcessUnitTest() {
5301 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5308 cc->m_bFollow =
false;
5310 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5311 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5314 if (cc->m_groupIndex > 0) {
5315 while (ut_index < ChartData->GetChartTableEntries() &&
5316 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5320 if (ut_index < ChartData->GetChartTableEntries()) {
5324 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5325 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5332 if (cc->GetQuiltMode()) {
5333 if (cc->IsChartQuiltableRef(ut_index))
5334 cc->SelectQuiltRefdbChart(ut_index);
5336 cc->SelectdbChart(ut_index);
5339 if (g_unit_test_1) {
5347 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5348 cte->GetLatMin(), cte->GetLonMax(), NULL,
5352 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5353 cte->GetLatMax(), cte->GetLonMin(), NULL,
5356 cc->GetSize(&ww, &wh);
5357 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5359 ppm = wxMin(ppm, 1.0);
5366 if (ut_index > ut_index_max) exit(0);
5377 bool b_rotate =
false;
5379 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5382 if (!b_rotate && !g_btenhertz)
return;
5384 bool b_update =
false;
5386 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5389 struct timespec now;
5390 clock_gettime(CLOCK_MONOTONIC, &now);
5391 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5392 double diffc = diff / 1e9;
5395 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5396 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5397 if (gCog_tentative < 0.) gCog_tentative += 360.;
5398 gCog = gCog_tentative;
5402 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5403 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5404 double diffc = diff / 1e9;
5405 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5409 if (gSog_gt && !std::isnan(gCog_gt)) {
5410 double delta_t = diffc / 3600;
5411 double distance = gSog_gt * delta_t;
5414 double angr = gCog_gt / 180 * M_PI;
5415 double latr = gLat_gt * M_PI / 180;
5416 double D = distance / 3443;
5417 double sD = sin(D), cD = cos(D);
5418 double sy = sin(latr), cy = cos(latr);
5419 double sa = sin(angr), ca = cos(angr);
5421 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5422 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5432 if (cc) cc->DoCanvasCOGSet();
5443 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5444 cc->DoCanvasUpdate();
5453 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5456bool MyFrame::ProcessQuitFlag() {
5460 FrameTenHzTimer.Stop();
5462 wxWindow *top = wxTheApp ? wxTheApp->GetTopWindow() :
nullptr;
5463 if (top) top->Close(
true);
5470void MyFrame::ProcessDeferredTrackOn() {
5473 if (g_bDeferredStartTrack) {
5474 if (!g_bTrackActive) {
5477 g_bDeferredStartTrack =
false;
5480 g_bDeferredStartTrack =
false;
5485void MyFrame::ProcessAnchorWatch() {
5493 double d = g_nAWMax;
5495 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5496 bool toofar =
false;
5497 bool tooclose =
false;
5498 if (d >= 0.0) toofar = (dist * 1852. > d);
5499 if (d < 0.0) tooclose = (dist * 1852 < -d);
5501 if (tooclose || toofar)
5502 AnchorAlertOn1 =
true;
5504 AnchorAlertOn1 =
false;
5506 AnchorAlertOn1 =
false;
5514 double d = g_nAWMax;
5516 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5517 bool toofar =
false;
5518 bool tooclose =
false;
5519 if (d >= 0) toofar = (dist * 1852. > d);
5520 if (d < 0) tooclose = (dist * 1852 < -d);
5522 if (tooclose || toofar)
5523 AnchorAlertOn2 =
true;
5525 AnchorAlertOn2 =
false;
5527 AnchorAlertOn2 =
false;
5530 AnchorAlertOn1 =
true;
5533void MyFrame::SendFixToPlugins() {
5544 GPSData.
nSats = g_SatsInView;
5546 wxDateTime tCheck((time_t)m_fixtime);
5547 if (tCheck.IsValid()) {
5556 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5559 SendPositionFixToAllPlugIns(&GPSData);
5563void MyFrame::ProcessLogAndBells() {
5566 wxDateTime lognow = wxDateTime::Now();
5567 int hourLOC = lognow.GetHour();
5568 int minuteLOC = lognow.GetMinute();
5570 int minuteUTC = lognow.GetMinute();
5571 int second = lognow.GetSecond();
5573 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5574 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5575 (minuteUTC == 30)) {
5576 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5577 wxString day = lognow.FormatISODate();
5578 wxString utc = lognow.FormatISOTime();
5579 wxString navmsg =
"LOGBOOK: ";
5587 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5591 if (std::isnan(
gCog))
5592 cog.Printf(
"COG ----- ");
5594 cog.Printf(
"COG %10.5f ",
gCog);
5597 if (std::isnan(
gSog))
5598 sog.Printf(
"SOG ----- ");
5600 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5606 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5609 wxLogMessage(navmsg);
5610 g_loglast_time = lognow;
5612 int bells = (hourLOC % 4) * 2;
5613 if (minuteLOC != 0) bells++;
5614 if (!bells) bells = 8;
5616 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5617 m_BellsToPlay = bells;
5618 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5619 wxPostEvent(
this, ev);
5626 CheckToolbarPosition();
5630 if (ProcessQuitFlag())
return;
5632 if (bDBUpdateInProgress)
return;
5635 FrameTenHzTimer.Stop();
5637 ProcessDeferredTrackOn();
5639 ProcessAnchorWatch();
5640 ProcessLogAndBells();
5642 if (ShouldRestartTrack()) TrackDailyRestart();
5645 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5646 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5647 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5653 if (
gSog > 3.0) g_bCruising =
true;
5659 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5661 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5667 bool bnew_view =
false;
5668 if (!g_btenhertz) bnew_view = DoChartUpdate();
5675 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5678 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5681 cc->DrawBlinkObjects();
5684 if (bactiveRouteUpdate) {
5691 cc->SetOwnShipState(SHIP_NORMAL);
5693 if (cc->GetQuiltMode()) {
5694 double erf = cc->GetQuiltMaxErrorFactor();
5695 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5697 if (cc->m_singleChart) {
5698 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5699 cc->SetOwnShipState(SHIP_LOWACCURACY);
5703 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5706 (bVelocityValid != m_last_bVelocityValid) ||
5707 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5708 if (!g_bopengl) cc->UpdateShips();
5716 m_last_bVelocityValid = bVelocityValid;
5721 bool brq_dynamic =
false;
5723 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5724 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5726 if (pic->m_enabled && pic->m_init_state) {
5727 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5734 if (brq_dynamic) bnew_view =
true;
5738 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5741 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5746 if (cc->GetglCanvas()) {
5748 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5751 if (cc->m_bFollow) {
5752 cc->DoCanvasUpdate();
5759 if (std::isnan(
gCog)) cc->Refresh(
false);
5772 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5786 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5787 g_pais_query_dialog_active->UpdateText();
5790 if (g_pAISTargetList && (0 == (g_tick % (5))))
5791 g_pAISTargetList->UpdateAISTargetList();
5794 UpdateGPSCompassStatusBoxes();
5799 console->RefreshConsoleData();
5806 if (m_bdefer_resize) {
5807 if (0 == (g_tick % (5))) {
5808 printf(
"___RESIZE\n");
5809 SetSize(m_defer_size);
5811 m_bdefer_resize =
false;
5818 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5820 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5821 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5825double MyFrame::GetMag(
double a,
double lat,
double lon) {
5826 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5827 auto loader = PluginLoader::GetInstance();
5828 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5835 wxDateTime now = wxDateTime::Now();
5836 SendJSON_WMM_Var_Request(lat, lon, now);
5837 if (fabs(gQueryVar) < 360.0)
5838 Variance = gQueryVar;
5840 return toMagnetic(a, Variance);
5843bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5849 v[
"Year"] = date.GetYear();
5850 v[
"Month"] = date.GetMonth();
5851 v[
"Day"] = date.GetDay();
5853 SendJSONMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5859void MyFrame::TouchAISActive() {
5861 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5863 if (cc) cc->TouchAISToolActive();
5867void MyFrame::UpdateAISTool() {
5871 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5873 if (cc) cc->UpdateAISTBTool();
5878void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5880 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5882 if (cc) cc->SetbTCUpdate(
true);
5885 RefreshAllCanvas(
false);
5890void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5894 bool b_rotate =
false;
5895 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5897 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5901 FrameCOGTimer.Stop();
5908 int period_ms = 100;
5910 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5913void MyFrame::DoCOGSet() {
5915 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5917 if (cc) cc->DoCanvasCOGSet();
5921void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5927 wxFont oldfont = pdc->GetFont();
5929 pdc->SetFont(*pFont);
5930 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5931 pdc->SetBackgroundMode(wxTRANSPARENT);
5933 pdc->DrawText(str, x, y + 1);
5934 pdc->DrawText(str, x, y - 1);
5935 pdc->DrawText(str, x + 1, y);
5936 pdc->DrawText(str, x - 1, y);
5938 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5940 pdc->DrawText(str, x, y);
5942 pdc->SetFont(oldfont);
5946void MyFrame::UpdateRotationState(
double rotation) {
5948 g_bCourseUp =
false;
5950 if (fabs(rotation) > .001) {
5951 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5952 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5954 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5957 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5958 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5960 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5964 UpdateGPSCompassStatusBoxes(
true);
5968void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5970 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5972 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5978int MyFrame::GetApplicationMemoryUse() {
5984 wxWindow *fWin = wxWindow::FindFocus();
5986 wxArrayString outputArray;
5987 wxString cmd(
"ps --no-headers -o vsize ");
5988 unsigned long pid = wxGetProcessId();
5990 cmd1.Printf(
"%ld", pid);
5992 wxExecute(cmd, outputArray);
5994 if (outputArray.GetCount()) {
5995 wxString s = outputArray.Item(0);
5997 if (s.ToLong(&vtmp)) memsize = vtmp;
6000 if (fWin) fWin->SetFocus();
6006 PROCESS_MEMORY_COUNTERS pmc;
6008 unsigned long processID = wxGetProcessId();
6010 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6012 if (NULL == hProcess)
return 0;
6014 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6032 memsize = pmc.WorkingSetSize / 1024;
6035 CloseHandle(hProcess);
6042double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6043 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6046void MyFrame::SetChartUpdatePeriod() {
6049 g_ChartUpdatePeriod = 0;
6054 bool bskewdc =
false;
6055 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6058 if (!g_bopengl && !cc->GetVP().b_quilt) {
6059 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6061 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6065 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6067 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6072 cc->UpdateCanvasControlBar();
6075void MyFrame::selectChartDisplay(
int type,
int family) {
6077 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6079 if (cc) cc->selectCanvasChartDisplay(type, family);
6082 UpdateGlobalMenuItems();
6091bool MyFrame::DoChartUpdate() {
6092 bool return_val =
false;
6095 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6097 if (cc) return_val |= cc->DoCanvasUpdate();
6103void MyFrame::MouseEvent(wxMouseEvent &event) {
6105 event.GetPosition(&x, &y);
6110#include <mach/mach.h>
6111#include <mach/message.h>
6112#include <mach/kern_return.h>
6113#include <mach/task_info.h>
6115#include <malloc/malloc.h>
6122#if defined(__linux__)
6123#include "sys/types.h"
6124#include "sys/sysinfo.h"
6127void MyFrame::DoPrint(
void) {
6129 g_PrintingInProgress =
true;
6132 GetPrimaryCanvas()->GetglCanvas()->Render();
6133 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6143 printer.Initialize(wxLANDSCAPE);
6144 printer.EnablePageNumbers(
false);
6145 printer.Print(
this, &printout);
6163 g_PrintingInProgress =
false;
6166 GetPrimaryCanvas()->SetFocus();
6172 wxString message_ID =
event.GetID();
6173 wxString message_JSONText =
event.GetJSONText();
6181 if (message_ID ==
"WMM_VARIATION_BOAT") {
6189 int numErrors = reader.
Parse(message_JSONText, &root);
6190 if (numErrors > 0) {
6196 wxString decl = root[
"Decl"].
AsString();
6198 decl.ToDouble(&decl_val);
6204 if (message_ID ==
"WMM_VARIATION") {
6212 int numErrors = reader.
Parse(message_JSONText, &root);
6213 if (numErrors > 0) {
6219 wxString decl = root[
"Decl"].
AsString();
6221 decl.ToDouble(&decl_val);
6223 gQueryVar = decl_val;
6226 if (message_ID ==
"GRIB_TIMELINE") {
6229 int numErrors = r.
Parse(message_JSONText, &v);
6231 if (numErrors > 0) {
6232 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6237 wxDateTime oldTimeSource = gTimeSource;
6239 if (v[
"Day"].AsInt() == -1) {
6240 gTimeSource = wxInvalidDateTime;
6241 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6243 gTimeSource.Set(v[
"Day"].AsInt(), (wxDateTime::Month)v[
"Month"].AsInt(),
6244 v[
"Year"].AsInt(), v[
"Hour"].AsInt(), v[
"Minute"].AsInt(),
6245 v[
"Second"].AsInt());
6249 if (oldTimeSource != gTimeSource) {
6251 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6253 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6258 cc->pCwin->Refresh(
false);
6264 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6267 wxString trk_id = wxEmptyString;
6269 int numErrors = reader.
Parse(message_JSONText, &root);
6270 if (numErrors > 0)
return;
6275 v[
"Track_ID"] = trk_id;
6277 wxString name = wxEmptyString;
6278 if (ptrack->m_GUID == trk_id) {
6279 name = ptrack->GetName();
6280 if (name.IsEmpty()) {
6286 name = _(
"(Unnamed Track)");
6293 v[
"TotalNodes"] = ptrack->GetnPoints();
6294 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6296 v[
"lat"] = tp->m_lat;
6297 v[
"lon"] = tp->m_lon;
6300 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6301 SendJSONMessageToAllPlugins(msg_id, v);
6307 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6308 SendJSONMessageToAllPlugins(msg_id, v);
6310 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6313 wxString guid = wxEmptyString;
6315 int numErrors = reader.
Parse(message_JSONText, &root);
6316 if (numErrors > 0) {
6325 wxString name = wxEmptyString;
6327 if ((*it)->m_GUID == guid) {
6328 name = (*it)->m_RouteNameString;
6329 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6335 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6336 itp != (*it)->pRoutePointList->end(); itp++) {
6337 w[i][
"lat"] = (*itp)->m_lat;
6338 w[i][
"lon"] = (*itp)->m_lon;
6339 w[i][
"Name"] = (*itp)->GetName();
6340 w[i][
"Description"] = (*itp)->GetDescription();
6341 w[i][
"GUID"] = (*itp)->m_GUID;
6342 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6344 auto node = (*itp)->m_HyperlinkList->begin();
6345 if (node != (*itp)->m_HyperlinkList->end()) {
6347 while (node != (*itp)->m_HyperlinkList->end()) {
6349 v[i][
"WPLink" + wxString::Format(
"%d", n)] = httpLink->Link;
6350 v[i][
"WPLinkDesciption" + wxString::Format(
"%d", n++)] =
6351 httpLink->DescrText;
6358 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6359 SendJSONMessageToAllPlugins(msg_id, v);
6366 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6367 SendJSONMessageToAllPlugins(msg_id, v);
6368 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6373 int numErrors = reader.
Parse(message_JSONText, &root);
6374 if (numErrors > 0)
return;
6377 wxString str = root[
"mode"].
AsString();
6378 if (str ==
"Track") route =
false;
6383 for (RouteList::iterator it =
pRouteList->begin();
6385 wxString name = (*it)->m_RouteNameString;
6386 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6388 v[i][
"error"] =
false;
6389 v[i][
"name"] = name;
6390 v[i][
"GUID"] = (*it)->m_GUID;
6391 v[i][
"active"] = (*it)->IsActive();
6396 wxString name = ptrack->GetName();
6397 if (name.IsEmpty()) {
6403 name = _(
"(Unnamed Track)");
6405 v[i][
"error"] =
false;
6406 v[i][
"name"] = name;
6407 v[i][
"GUID"] = ptrack->m_GUID;
6412 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6413 SendJSONMessageToAllPlugins(msg_id, v);
6416 v[0][
"error"] =
true;
6417 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6418 SendJSONMessageToAllPlugins(msg_id, v);
6420 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6422 v[0][
"error"] =
true;
6425 v[0][
"error"] =
false;
6426 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6427 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6428 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6429 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6430 v[0][
"active_waypoint_lat"] =
6432 v[0][
"active_waypoint_lon"] =
6436 wxString msg_id(
"OCPN_ACTIVE_ROUTELEG_RESPONSE");
6437 SendJSONMessageToAllPlugins(msg_id, v);
6441void MyFrame::FilterCogSog() {
6442 if (g_bfilter_cogsog && !g_own_ship_sog_cog_calc) {
6444 double cog_last =
gCog;
6447 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6448 COGFilterTable[i] = COGFilterTable[i - 1];
6449 COGFilterTable[0] = cog_last;
6452 if (!std::isnan(cog_last)) {
6454 double sum = 0., count = 0;
6455 for (
int i = 0; i < g_COGFilterSec; i++) {
6456 double adder = COGFilterTable[i];
6457 if (std::isnan(adder))
continue;
6459 if (fabs(adder - cog_last) > 180.) {
6460 if ((adder - cog_last) > 0.)
6473 else if (sum >= 360.)
6480 double sog_last =
gSog;
6483 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6484 SOGFilterTable[i] = SOGFilterTable[i - 1];
6485 SOGFilterTable[0] = sog_last;
6488 if (!std::isnan(
gSog)) {
6489 double sum = 0., count = 0;
6490 for (
int i = 0; i < g_SOGFilterSec; i++) {
6491 if (std::isnan(SOGFilterTable[i]))
continue;
6493 sum += SOGFilterTable[i];
6503void MyFrame::LoadHarmonics() {
6506 ptcmgr->LoadDataSources(TideCurrentDataSet);
6508 bool b_newdataset =
false;
6511 for (
auto a :
ptcmgr->GetDataSet()) {
6512 bool b_foundi =
false;
6513 for (
auto b : TideCurrentDataSet) {
6520 b_newdataset =
true;
6525 for (
auto a : TideCurrentDataSet) {
6526 bool b_foundi =
false;
6527 for (
auto b :
ptcmgr->GetDataSet()) {
6534 b_newdataset =
true;
6539 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6543void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6544 if (!ptarget)
return;
6547 wxDateTime mob_time = wxDateTime::Now();
6548 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6549 mob_label += _(
" on ");
6550 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6553 mob_label, wxEmptyString);
6554 pWP_MOB->SetShared(
true);
6556 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6558 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6560 pWP_MOB->SetUseSca(
false);
6568 wxString(_(
"Own ship")), wxEmptyString);
6570 pWP_MOB->SetUseSca(
false);
6577 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6593 wxString msg_id(
"OCPN_MAN_OVERBOARD");
6594 SendJSONMessageToAllPlugins(msg_id, v);
6597 if (RouteManagerDialog::getInstanceFlag()) {
6598 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
6599 pRouteManagerDialog->UpdateRouteListCtrl();
6600 pRouteManagerDialog->UpdateWptListCtrl();
6604 RefreshAllCanvas(
false);
6606 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6607 mob_message += _(
" Time: ");
6608 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6609 mob_message += _(
" Ownship Position: ");
6610 mob_message += toSDMM(1,
gLat);
6612 mob_message += toSDMM(2,
gLon);
6613 mob_message += _(
" MOB Position: ");
6614 mob_message += toSDMM(1, ptarget->Lat);
6616 mob_message += toSDMM(2, ptarget->Lon);
6617 wxLogMessage(mob_message);
6620void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6624 OwnPoint->m_lat =
gLat;
6625 OwnPoint->m_lon =
gLon;
6627 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6632 MOB_Point->m_lat = ptarget->Lat;
6633 MOB_Point->m_lon = ptarget->Lon;
6635 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6636 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6638 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6639 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6642 RefreshAllCanvas(
false);
6645 wxDateTime mob_time = wxDateTime::Now();
6647 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6648 mob_message += _(
" Time: ");
6649 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6650 mob_message += _(
" Ownship Position: ");
6651 mob_message += toSDMM(1,
gLat);
6653 mob_message += toSDMM(2,
gLon);
6654 mob_message += _(
" MOB Position: ");
6655 mob_message += toSDMM(1, ptarget->Lat);
6657 mob_message += toSDMM(2, ptarget->Lon);
6659 wxLogMessage(mob_message);
6663void MyFrame::applySettingsString(wxString settings) {
6665 int last_UIScaleFactor = g_GUIScaleFactor;
6666 bool previous_expert = g_bUIexpert;
6667 g_last_ChartScaleFactor = g_ChartScaleFactor;
6668 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6671 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6674 pConfig->UpdateSettings();
6677 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6679 if (rr & S52_CHANGED) {
6681 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6683 ->ClearCNSYLUPArray();
6684 ps52plib->GenerateStateHash();
6688 ProcessOptionsDialog(rr, pNewDirArray);
6693 bool b_newToolbar =
false;
6695 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6697 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6699 if (rr & TOOLBAR_CHANGED) {
6700 b_newToolbar =
true;
6705 if (previous_expert && !g_bUIexpert) {
6706 androidForceFullRepaint();
6710 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6714 SetGPSCompassScale();
6716 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6718 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6720 UpdateGPSCompassStatusBoxes(
true);
6723 AbstractPlatform::ShowBusySpinner();
6725 SetAllToolbarScale();
6729 AbstractPlatform::HideBusySpinner();
6731 RequestNewMasterToolbar(
true);
6738 UpdateControlBar(GetPrimaryCanvas());
6744 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6747#ifdef wxHAS_POWER_EVENTS
6748void MyFrame::OnSuspending(wxPowerEvent &event) {
6752 wxLogMessage(
"System suspend starting...");
6755void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6758 wxLogMessage(
"System is going to suspend.");
6761void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6764 wxLogMessage(
"System suspend was cancelled.");
6767int g_last_resume_ticks;
6768void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6769 wxDateTime now = wxDateTime::Now();
6770 wxLogMessage(
"System resumed from suspend.");
6772 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6775 wxLogMessage(
"Restarting streams.");
6776 g_last_resume_ticks = now.GetTicks();
6780 g_pMUX->ClearStreams();
6782 g_pMUX->StartAllStreams();
6791 if (IsMaximized()) {
6796 wxSize sz = GetSize();
6797 SetSize(wxSize(sz.x - 1, sz.y));
6809void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6810 bool btbRebuild =
false;
6812 bool b_reshow =
true;
6815 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6816 if ((ff > 0.01f) || bforcenew) {
6826 long orient = g_Platform->GetDefaultToolbarOrientation();
6827 wxWindow *toolbarParent =
this;
6829 toolbarParent = GetPrimaryCanvas();
6832 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor);
6834 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6841 g_bmasterToolbarFull =
true;
6845 CreateMasterToolbar();
6860bool MyFrame::CollapseGlobalToolbar() {
6862 m_nMasterToolCountShown = 1;
6866 g_bmasterToolbarFull =
false;
6882 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6883 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6884 tic->m_bRequired =
true;
6889 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6890 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6894 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6895 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6896 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6901 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6902 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6906 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6907 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6908 _(
"Enable Tracking"),
"MUI_track");
6912 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6913 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6925 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6926 _(
"Print Chart"),
"MUI_print");
6930 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6931 _(
"About OpenCPN"),
"MUI_help");
6935 AddDefaultPositionPlugInTools();
6939 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6940 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6951 ArrayOfPlugInToolbarTools tool_array =
6953 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6955 if (!pttc->b_viz)
continue;
6957 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6960 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6961 if (g_bTrackActive) {
6962 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6969bool MyFrame::CheckAndAddPlugInTool() {
6977 if (!tb)
return false;
6979 int n_tools = tb->GetToolsCount();
6983 ArrayOfPlugInToolbarTools tool_array =
6986 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6988 if (pttc->position == n_tools) {
6989 wxBitmap *ptool_bmp;
6991 switch (global_color_scheme) {
6992 case GLOBAL_COLOR_SCHEME_DAY:
6993 ptool_bmp = pttc->bitmap_day;
6996 case GLOBAL_COLOR_SCHEME_DUSK:
6997 ptool_bmp = pttc->bitmap_dusk;
6999 case GLOBAL_COLOR_SCHEME_NIGHT:
7000 ptool_bmp = pttc->bitmap_night;
7003 ptool_bmp = pttc->bitmap_day;
7008 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7010 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7011 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7012 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7013 tic->m_bPlugin =
true;
7022 while (CheckAndAddPlugInTool()) {
7028bool MyFrame::AddDefaultPositionPlugInTools() {
7035 ArrayOfPlugInToolbarTools tool_array =
7038 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7042 if (!pttc->b_viz)
continue;
7044 if (pttc->position == -1)
7046 wxBitmap *ptool_bmp;
7048 switch (global_color_scheme) {
7049 case GLOBAL_COLOR_SCHEME_DAY:
7050 ptool_bmp = pttc->bitmap_day;
7052 case GLOBAL_COLOR_SCHEME_DUSK:
7053 ptool_bmp = pttc->bitmap_dusk;
7055 case GLOBAL_COLOR_SCHEME_NIGHT:
7056 ptool_bmp = pttc->bitmap_night;
7059 ptool_bmp = pttc->bitmap_day;
7064 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7066 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7067 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7068 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7069 tic->m_bPlugin =
true;
7084wxColour GetGlobalColor(wxString colorName);
7086static const char *usercolors[] = {
7093 "GREEN1;120;255;120;",
"GREEN2; 45;150; 45;",
"GREEN3;200;220;200;",
7094 "GREEN4; 0;255; 0;",
"GREEN5;170;254; 0;",
"BLUE1; 170;170;255;",
7095 "BLUE2; 45; 45;170;",
"BLUE3; 0; 0;255;",
"GREY1; 200;200;200;",
7096 "GREY2; 230;230;230;",
"RED1; 220;200;200;",
"YELO1; 243;229; 47;",
7097 "YELO2; 128; 80; 0;",
"TEAL1; 0;128;128;",
7101 "UWHIT; 255;255;255;",
7104 "COMPT; 245;247;244",
7108 "DILG0; 255;255;255;",
7110 "DILG0; 238;239;242;",
7112 "DILG1; 212;208;200;",
7113 "DILG2; 255;255;255;",
7125 "CHGRF; 163; 180; 183;",
7127 "CHYLW; 244; 218; 72;",
7128 "CHWHT; 212; 234; 238;",
7131 "UINFM; 197; 69; 195;",
7133 "UINFG; 104; 228; 86;",
7135 "UINFR; 241; 84; 105;",
7136 "UINFF; 125; 137; 140;",
7140 "UDKRD; 124; 16; 0;",
7142 "UARTE; 200; 0; 0;",
7145 "NODTA; 163; 180; 183;",
7147 "SNDG1; 125; 137; 140;",
7149 "SCLBR; 235; 125; 54;",
7152 "UIBDR; 125; 137; 140;",
7153 "UIBCK; 212; 234; 238;",
7154 "UINFB; 58; 120; 240;",
7157 "UINFO; 235; 125; 54;",
7160 "PLRTE; 220; 64; 37;",
7161 "CHMGD; 197; 69; 195;",
7165 "DASHB; 255;255;255;",
7166 "DASHL; 175;175;175;",
7167 "DASHF; 50; 50; 50;",
7168 "DASHR; 200; 0; 0;",
7170 "DASHN; 200;120; 0;",
7171 "DASH1; 204;204;255;",
7172 "DASH2; 122;131;172;",
7173 "COMP1; 211;211;211;",
7176 "GREY3; 40; 40; 40;",
7177 "BLUE4; 100;100;200;",
7178 "VIO01; 171; 33;141;",
7179 "VIO02; 209;115;213;",
7180 "BLUEBACK; 212;234;238;",
7181 "LANDBACK; 201;185;122;",
7187 "Table:DUSK",
"GREEN1; 60;128; 60;",
"GREEN2; 22; 75; 22;",
7188 "GREEN3; 80;100; 80;",
"GREEN4; 0;128; 0;",
"BLUE1; 80; 80;160;",
7189 "BLUE2; 30; 30;120;",
"BLUE3; 0; 0;128;",
"GREY1; 100;100;100;",
7190 "GREY2; 128;128;128;",
"RED1; 150;100;100;",
"UBLCK; 0; 0; 0;",
7191 "UWHIT; 255;255;255;",
"URED; 120; 54; 11;",
"UGREN; 35;110; 20;",
7192 "YELO1; 120;115; 24;",
"YELO2; 64; 40; 0;",
"TEAL1; 0; 64; 64;",
7193 "GREEN5; 85;128; 0;",
"COMPT; 124;126;121",
7195 "CHGRF; 41; 46; 46;",
"UINFM; 58; 20; 57;",
"UINFG; 35; 76; 29;",
7196 "UINFF; 41; 46; 46;",
"UINFR; 80; 28; 35;",
"SHIPS; 71; 78; 79;",
7197 "CHYLW; 81; 73; 24;",
"CHWHT; 71; 78; 79;",
7199 "DILG0; 110;110;110;",
7200 "DILG1; 110;110;110;",
7202 "DILG3; 130;130;130;",
7204 "UITX1; 41; 46; 46;",
7207 "UARTE; 64; 64; 64;",
7209 "NODTA; 41; 46; 46;",
"CHBLK; 54; 60; 61;",
"SNDG1; 41; 46; 46;",
7210 "SNDG2; 71; 78; 79;",
"SCLBR; 75; 38; 19;",
"UIBDR; 54; 60; 61;",
7211 "UINFB; 19; 40; 80;",
"UINFD; 71; 78; 79;",
"UINFO; 75; 38; 19;",
7212 "PLRTE; 73; 21; 12;",
"CHMGD; 74; 58; 81;",
"UIBCK; 7; 7; 7;",
7214 "DASHB; 77; 77; 77;",
7215 "DASHL; 54; 54; 54;",
7217 "DASHR; 58; 21; 21;",
7218 "DASHG; 21; 58; 21;",
7219 "DASHN; 100; 50; 0;",
7220 "DASH1; 76; 76;113;",
7221 "DASH2; 48; 52; 72;",
7222 "COMP1; 107;107;107;",
7224 "GREY3; 20; 20; 20;",
7225 "BLUE4; 80; 80;160;",
7226 "VIO01; 128; 25;108;",
"VIO02; 171; 33;141;",
"BLUEBACK; 186;213;235;",
7227 "LANDBACK; 201;185;122;",
7233 "Table:NIGHT",
"GREEN1; 30; 80; 30;",
"GREEN2; 15; 60; 15;",
7234 "GREEN3; 12; 23; 9;",
"GREEN4; 0; 64; 0;",
"BLUE1; 60; 60;100;",
7235 "BLUE2; 22; 22; 85;",
"BLUE3; 0; 0; 40;",
"GREY1; 48; 48; 48;",
7236 "GREY2; 32; 32; 32;",
"RED1; 100; 50; 50;",
"UWHIT; 255;255;255;",
7237 "UBLCK; 0; 0; 0;",
"URED; 60; 27; 5;",
"UGREN; 17; 55; 10;",
7238 "YELO1; 60; 65; 12;",
"YELO2; 32; 20; 0;",
"TEAL1; 0; 32; 32;",
7239 "GREEN5; 44; 64; 0;",
"COMPT; 48; 49; 51",
7240 "DILG0; 80; 80; 80;",
7241 "DILG1; 80; 80; 80;",
7243 "DILG3; 65; 65; 65;",
7244 "DILG4; 220;220;220;",
7245 "UITX1; 31; 34; 35;",
7248 "UARTE; 64; 64; 64;",
7250 "CHGRF; 16; 18; 18;",
"UINFM; 52; 18; 52;",
"UINFG; 22; 24; 7;",
7251 "UINFF; 31; 34; 35;",
"UINFR; 59; 17; 10;",
"SHIPS; 37; 41; 41;",
7252 "CHYLW; 31; 33; 10;",
"CHWHT; 37; 41; 41;",
7254 "NODTA; 7; 7; 7;",
"CHBLK; 31; 34; 35;",
"SNDG1; 31; 34; 35;",
7255 "SNDG2; 43; 48; 48;",
"SCLBR; 52; 28; 12;",
"UIBDR; 31; 34; 35;",
7256 "UINFB; 21; 29; 69;",
"UINFD; 43; 48; 58;",
"UINFO; 52; 28; 12;",
7257 "PLRTE; 66; 19; 11;",
"CHMGD; 52; 18; 52;",
"UIBCK; 7; 7; 7;",
7260 "DASHL; 20; 20; 20;",
7261 "DASHF; 64; 64; 64;",
7262 "DASHR; 70; 15; 15;",
7263 "DASHG; 15; 70; 15;",
7264 "DASHN; 17; 80; 56;",
7265 "DASH1; 48; 52; 72;",
7266 "DASH2; 36; 36; 53;",
7267 "COMP1; 24; 24; 24;",
7269 "GREY3; 10; 10; 10;",
7270 "BLUE4; 70; 70;140;",
7271 "VIO01; 85; 16; 72;",
"VIO02; 128; 25;108;",
"BLUEBACK; 186;213;235;",
7272 "LANDBACK; 201;185;122;",
7276int get_static_line(
char *d,
const char **p,
int index,
int n) {
7277 if (!strcmp(p[index],
"*****"))
return 0;
7279 strncpy(d, p[index], n);
7283void InitializeUserColors() {
7284 const char **p = usercolors;
7292 UserColorTableArray =
new wxArrayPtrVoid;
7293 UserColourHashTableArray =
new wxArrayPtrVoid;
7297 ct->tableName =
new wxString(
"DAY");
7298 ct->color =
new wxArrayPtrVoid;
7299 UserColorTableArray->Add((
void *)ct);
7302 ct->tableName =
new wxString(
"DUSK");
7303 ct->color =
new wxArrayPtrVoid;
7304 UserColorTableArray->Add((
void *)ct);
7307 ct->tableName =
new wxString(
"NIGHT");
7308 ct->color =
new wxArrayPtrVoid;
7309 UserColorTableArray->Add((
void *)ct);
7311 while ((get_static_line(buf, p, index,
sizeof(buf) - 1))) {
7312 if (!strncmp(buf,
"Table", 5)) {
7313 sscanf(buf,
"Table:%s", TableName);
7315 for (
unsigned int it = 0; it < UserColorTableArray->GetCount(); it++) {
7316 ctp = (colTable *)(UserColorTableArray->Item(it));
7317 if (!strcmp(TableName, ctp->tableName->mb_str())) {
7326 while (buf[j] !=
';' && j < 20) {
7332 S52color *c =
new S52color;
7333 strcpy(c->colName, name);
7335 sscanf(&buf[j],
";%i;%i;%i", &R, &G, &B);
7348 for (
unsigned int its = 0; its < UserColorTableArray->GetCount(); its++) {
7349 wxColorHashMap *phash =
new wxColorHashMap;
7350 UserColourHashTableArray->Add((
void *)phash);
7352 colTable *ctp = (colTable *)(UserColorTableArray->Item(its));
7354 for (
unsigned int ic = 0; ic < ctp->color->GetCount(); ic++) {
7355 S52color *c2 = (S52color *)(ctp->color->Item(ic));
7357 wxColour c(c2->R, c2->G, c2->B);
7358 wxString key(c2->colName, wxConvUTF8);
7366 (wxColorHashMap *)UserColourHashTableArray->Item(0);
7369void DeInitializeUserColors() {
7370 if (!UserColorTableArray)
return;
7371 for (
unsigned i = 0; i < UserColorTableArray->GetCount(); i++) {
7372 colTable *ct = (colTable *)UserColorTableArray->Item(i);
7374 for (
unsigned int j = 0; j < ct->color->GetCount(); j++) {
7375 S52color *c = (S52color *)ct->color->Item(j);
7379 delete ct->tableName;
7385 delete UserColorTableArray;
7387 for (
unsigned i = 0; i < UserColourHashTableArray->GetCount(); i++) {
7388 wxColorHashMap *phash = (wxColorHashMap *)UserColourHashTableArray->Item(i);
7392 delete UserColourHashTableArray;
7399typedef struct _MSW_COLOR_SPEC {
7401 wxString S52_RGB_COLOR;
7405MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7406 {COLOR_MENUTEXT,
"UITX1", 0},
7407 {COLOR_BTNSHADOW,
"UIBCK", 0},
7410void SaveSystemColors() {
7424 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7425 while (pcspec->COLOR_NAME != -1) {
7426 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7431void RestoreSystemColors() {
7432 int element[NCOLORS];
7433 int rgbcolor[NCOLORS];
7436 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7437 while (pcspec->COLOR_NAME != -1) {
7438 element[i] = pcspec->COLOR_NAME;
7439 rgbcolor[i] = pcspec->SysRGB_COLOR;
7444 if (pSetSysColors) {
7445 pSetSysColors(i, (
unsigned long *)&element[0],
7446 (
unsigned long *)&rgbcolor[0]);
7452void SetSystemColors(ColorScheme cs) {
7454 int element[NCOLORS];
7455 int rgbcolor[NCOLORS];
7457 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7458 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7459 while (pcspec->COLOR_NAME != -1) {
7460 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7461 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7462 element[i] = pcspec->COLOR_NAME;
7468 pSetSysColors(i, (
unsigned long *)&element[0],
7469 (
unsigned long *)&rgbcolor[0]);
7473 RestoreSystemColors();
7478wxColor GetDimColor(wxColor c) {
7479 if ((global_color_scheme == GLOBAL_COLOR_SCHEME_DAY) ||
7480 (global_color_scheme == GLOBAL_COLOR_SCHEME_RGB))
7484 if (global_color_scheme == GLOBAL_COLOR_SCHEME_DUSK) factor = 0.5;
7485 if (global_color_scheme == GLOBAL_COLOR_SCHEME_NIGHT) factor = 0.25;
7487 wxImage::RGBValue rgb(c.Red(), c.Green(), c.Blue());
7488 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
7489 hsv.value = hsv.value * factor;
7490 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
7492 return wxColor(nrgb.red, nrgb.green, nrgb.blue);
7498double AnchorDistFix(
double const d,
double const AnchorPointMinDist,
7499 double const AnchorPointMaxDist)
7502 if (d < AnchorPointMinDist)
7503 return AnchorPointMinDist;
7504 else if (d > AnchorPointMaxDist)
7505 return AnchorPointMaxDist;
7511 if (d > -AnchorPointMinDist)
7512 return -AnchorPointMinDist;
7513 else if (d < -AnchorPointMaxDist)
7514 return -AnchorPointMaxDist;
7521static const WORD MAX_CONSOLE_LINES =
7526void RedirectIOToConsole()
7531 wxIntPtr lStdHandle;
7533 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7543 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7544 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7545 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7549 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7550 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7551 fp = _fdopen(hConHandle,
"w");
7553 setvbuf(stdout, NULL, _IONBF, 0);
7557 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7558 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7559 fp = _fdopen(hConHandle,
"r");
7561 setvbuf(stdin, NULL, _IONBF, 0);
7565 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7566 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7567 fp = _fdopen(hConHandle,
"w");
7569 setvbuf(stderr, NULL, _IONBF, 0);
7581bool TestGLCanvas(wxString prog_dir) {
7583 wxString test_app = prog_dir;
7584 test_app +=
"ocpn_gltest1.exe";
7586 if (::wxFileExists(test_app)) {
7587 long proc_return = ::wxExecute(test_app, wxEXEC_SYNC);
7588 printf(
"OpenGL Test Process returned %0X\n", proc_return);
7589 if (proc_return == 0)
7590 printf(
"GLCanvas OK\n");
7592 printf(
"GLCanvas failed to start, disabling OpenGL.\n");
7594 return (proc_return == 0);
7604bool ReloadLocale() {
7609 (!g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang)
7616 FontMgr::Get().SetLocale(g_locale);
7630 if (pRouteManagerDialog) {
7631 pRouteManagerDialog->Hide();
7632 pRouteManagerDialog->Destroy();
7633 pRouteManagerDialog = NULL;
7637 if (g_pais_query_dialog_active) {
7638 g_pais_query_dialog_active->Destroy();
7639 g_pais_query_dialog_active = NULL;
7642 auto alert_dlg_active =
7644 if (alert_dlg_active) {
7645 alert_dlg_active->Destroy();
7646 g_pais_alert_dialog_active =
nullptr;
7649 if (g_pAISTargetList) {
7651 g_pAISTargetList->Disconnect_decoder();
7652 g_pAISTargetList->Destroy();
7653 g_pAISTargetList = NULL;
7657 if (gFrame->m_pMenuBar) {
7658 gFrame->SetMenuBar(NULL);
7659 gFrame->m_pMenuBar->Destroy();
7660 gFrame->m_pMenuBar = NULL;
7662 gFrame->BuildMenuBar();
7665 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
7667 if (cc) cc->CanvasApplyLocale();
7672 wxString perspective;
7673 pConfig->SetPath(
"/AUI");
7674 pConfig->Read(
"AUIPerspective", &perspective);
7688 bool bno_load =
false;
7689 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7691 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7692 wxAuiPaneInfo pane = pane_array_val[i];
7693 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7699 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7704 gFrame->RequestNewToolbars(
true);
7705 gFrame->RequestNewMasterToolbar(
true);
7722 g_csv_locn = g_Platform->GetSharedDataDir();
7723 g_csv_locn.Append(
"s57data");
7727 appendOSDirSlash(&g_csv_locn);
7728 g_csv_locn.Append(
"s57data");
7733 if (g_SENCPrefix.IsEmpty()) {
7735 appendOSDirSlash(&g_SENCPrefix);
7736 g_SENCPrefix.Append(
"SENC");
7740 wxFileName f(g_SENCPrefix);
7742 g_SENCPrefix = f.GetFullPath();
7744 g_SENCPrefix =
"SENC";
7750 bool b_force_legacy =
false;
7752 if (g_UserPresLibData.IsEmpty()) {
7753 plib_data = g_csv_locn;
7754 appendOSDirSlash(&plib_data);
7755 plib_data.Append(
"S52RAZDS.RLE");
7757 plib_data = g_UserPresLibData;
7758 b_force_legacy =
true;
7761 ps52plib =
new s52plib(plib_data, b_force_legacy);
7776 if (!ps52plib->m_bOK) {
7779 wxStandardPaths &std_path = g_Platform->GetStdPaths();
7781 wxString look_data_dir;
7782 look_data_dir.Append(std_path.GetUserDataDir());
7783 appendOSDirSlash(&look_data_dir);
7784 wxString tentative_SData_Locn = look_data_dir;
7785 look_data_dir.Append(
"s57data");
7787 plib_data = look_data_dir;
7788 appendOSDirSlash(&plib_data);
7789 plib_data.Append(
"S52RAZDS.RLE");
7791 wxLogMessage(
"Looking for s57data in " + look_data_dir);
7792 ps52plib =
new s52plib(plib_data);
7794 if (ps52plib->m_bOK) {
7795 g_csv_locn = look_data_dir;
7804 if (!ps52plib->m_bOK) {
7807 wxString look_data_dir;
7808 look_data_dir = g_Platform->GetSharedDataDir();
7809 look_data_dir.Append(
"s57data");
7811 plib_data = look_data_dir;
7812 appendOSDirSlash(&plib_data);
7813 plib_data.Append(
"S52RAZDS.RLE");
7815 wxLogMessage(
"Looking for s57data in " + look_data_dir);
7816 ps52plib =
new s52plib(plib_data);
7818 if (ps52plib->m_bOK) g_csv_locn = look_data_dir;
7821 if (ps52plib->m_bOK) {
7822 wxLogMessage(
"Using s57data in " + g_csv_locn);
7824 new s57RegistrarMgr(g_csv_locn, g_Platform->GetLogFilePtr());
7829 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
7831 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
7832 if (!strncmp(pOLE->OBJLName,
"DEPARE", 6)) pOLE->nViz = 1;
7833 if (!strncmp(pOLE->OBJLName,
"LNDARE", 6)) pOLE->nViz = 1;
7834 if (!strncmp(pOLE->OBJLName,
"COALNE", 6)) pOLE->nViz = 1;
7837 pConfig->LoadS57Config();
7838 ps52plib->SetPLIBColorScheme(global_color_scheme, ChartCtxFactory());
7844 ps52plib->SetDIPFactor(dip_factor);
7849 ps52plib->SetScaleFactorExp(
7850 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
7851 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
7858 wxString renderer = wxString(GL_Caps->Renderer.c_str());
7859 ps52plib->SetGLRendererString(renderer);
7862 ps52plib->SetGLOptions(
7863 glChartCanvas::s_b_useStencil, glChartCanvas::s_b_useStencilAP,
7864 glChartCanvas::s_b_useScissorTest, glChartCanvas::s_b_useFBO,
7865 g_b_EnableVBO, g_texture_rectangle_format, 1, 1);
7870 wxLogMessage(
" S52PLIB Initialization failed, disabling Vector charts.");
7879 : wxThread(wxTHREAD_JOINABLE) {
7880 m_filename = filename;
7891 newChart->SetNativeScale(m_scale);
7892 newChart->SetFullExtent(m_ext);
7894 newChart->FindOrCreateSenc(m_filename);
7899 wxString m_filename;
7905static double chart_dist(
int index) {
7911 if (cte.GetBBox().Contains(
gLat,
gLon))
7916 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7917 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7918 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7921 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7922 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7924 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7930WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7931static int CompareInts(
int n1,
int n2) {
7932 double d1 = chart_dist(n1);
7933 double d2 = chart_dist(n2);
7934 return (
int)(d1 - d2);
7939 wxString chart_path;
7944WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7946#include <wx/arrimpl.cpp>
7949void ParseAllENC(wxWindow *parent) {
7950 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7958 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7961 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7963 idx_sorted_by_distance.Add(i);
7967 if (count == 0)
return;
7969 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7975 ArrayOfCompressTargets ct_array;
7976 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7977 int i = idx_sorted_by_distance[j];
7980 double distance = chart_dist(i);
7982 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7985 pct->distance = distance;
7986 pct->chart_path = filename;
7988 ct_array.push_back(pct);
7991 int thread_count = 0;
7994 if (g_nCPUCount > 0)
7995 thread_count = g_nCPUCount;
7997 thread_count = wxThread::GetCPUCount();
7999 if (thread_count < 1) {
8008 for(
int t = 0; t < thread_count; t++)
8012 wxGenericProgressDialog *prog =
nullptr;
8016 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
8017 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
8019 prog =
new wxGenericProgressDialog();
8021 prog->SetFont(*qFont);
8023 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
8024 count + 1, parent, style);
8033 prog->ShowWindowModal();
8042 for (
unsigned int j = 0; j < ct_array.size(); j++) {
8043 wxString filename = ct_array[j].chart_path;
8044 double distance = ct_array[j].distance;
8045 int index =
ChartData->FinddbIndex(filename);
8046 if (index < 0)
continue;
8049 ext.NLAT = cte.GetLatMax();
8050 ext.SLAT = cte.GetLatMin();
8051 ext.WLON = cte.GetLonMin();
8052 ext.ELON = cte.GetLonMax();
8054 int scale = cte.GetScale();
8057 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
8060 if (wxThread::IsMain()) {
8062 wxSize sz = prog->GetSize();
8067 prog->Update(count, msg, &skip);
8079 newChart->SetNativeScale(
scale);
8080 newChart->SetFullExtent(ext);
8081 newChart->DisableBackgroundSENC();
8083 newChart->FindOrCreateSenc(filename,
8087 if (wxThread::IsMain()) {
8088 msg.Printf(_(
"ENC Completed."));
8090 prog->Update(count, msg, &skip);
8100 for (
int t = 0;; t = (t + 1) % thread_count) {
8107 if (!workers[t]->IsAlive()) {
8120#if defined(__WXMSW__) || defined(__WXOSX__)
8127 for(
int t = 0; t<thread_count; t++) {
AboutFrameImpl * g_pAboutDlg
Global instance.
About * g_pAboutDlgLegacy
Global instance.
AisDecoder * g_pAIS
Global instance.
Class AisDecoder and helpers.
Global state for AIS decoder.
Class AISTargetAlertDialog and helpers.
Class AISTargetListDialog.
Class AISTargetQueryDialog.
bool SendNoRouteRmbRmc(Routeman &routeman)
Send RMC + a faked RMB when there is no active route.
Autopilot output support.
Chart canvas configuration state
Class CanvasOptions and helpers – Canvas options Window/Dialog.
Wrapper for creating a ChartCtx based on global vars.
General chart base definitions.
ChartDB * ChartData
Global instance.
Charts database management
ChartGroupArray * g_pGroupArray
Global instance.
ChartCanvas * g_focusCanvas
Global instance.
Generic Chart canvas base.
Dialog for displaying AIS target alerts.
Dialog for querying detailed information about an AIS target.
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &caption=_("Object Query"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=AIS_TARGET_QUERY_STYLE)
Creation.
Extends AboutFrame, providing implementation for various event handlers and additional methods.
The OpenCPN About dialog displaying information including version, authors, license,...
Represents an active track that is currently being recorded.
Handles the AIS information GUI and sound alerts.
Base class for all chart types.
ChartCanvas - Main chart display and interaction component.
double m_cursor_lat
The latitude in degrees corresponding to the most recently processed cursor position.
double GetCanvasScaleFactor()
Return the number of logical pixels per meter for the screen.
void SetDisplaySizeMM(double size)
Set the width of the screen in millimeters.
float GetVPScale()
Return the ViewPort scale factor, in physical pixels per meter.
void ZoomCanvasSimple(double factor)
Perform an immediate zoom operation without smooth transitions.
bool SetVPScale(double sc, bool b_refresh=true)
Sets the viewport scale while maintaining the center point.
double m_cursor_lon
The longitude in degrees corresponding to the most recently processed cursor position.
void ZoomCanvas(double factor, bool can_zoom_to_cursor=true, bool stoptimer=true)
Perform a smooth zoom operation on the chart canvas by the specified factor.
bool SetViewPoint(double lat, double lon)
Centers the view on a specific lat/lon position.
Manages the chart database and provides access to chart data.
bool Create(ArrayOfCDI &dir_array, wxGenericProgressDialog *pprog)
Creates a new chart database from a list of directories.
bool Update(ArrayOfCDI &dir_array, bool bForce, wxGenericProgressDialog *pprog)
Updates the chart database.
Represents a user-defined collection of logically related charts.
void GenerateGLbmp()
In OpenGL mode, make the bitmap capture of the screen before the print method starts as to be sure th...
Overall logging handler, outputs to screen and log file.
bool IsVisible() const override
Return true if log is visible i.e., if it's any point using Add().
void Notify() override
Notify all listeners, no data supplied.
wxFont * FindOrCreateFont(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline=false, const wxString &facename=wxEmptyString, wxFontEncoding encoding=wxFONTENCODING_DEFAULT)
Creates or finds a matching font in the font cache.
void ScrubList()
Cleans up stale font entries after a locale change.
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Get a font object for a UI element.
EventVar color_scheme_change
Notified when the day/dusk/night color scheme changes.
static void ReleaseInstance()
Release Instance.
static LocalServerApi & GetInstance()
Handle logging and forwarding of incoming n0183/n2k messages.
void OnFrameTimer1(wxTimerEvent &event)
Main application timer handler called approximately once per second.
void InitApiListeners()
Setup handling of events from the local ipc/dbus API.
void OnFrameTenHzTimer(wxTimerEvent &event)
High-frequency timer handler running at 10Hz for smooth navigation updates.
virtual bool IsVisible() const =0
Return true if log is visible i.e., if it's any point using Add().
virtual void Add(const Logline &l)=0
Add a formatted string to log output.
void Init(const KeyProvider &kp, const std::function< void(ObservedEvt &ev)> &action)
Initiate an object yet not listening.
void Listen(const std::string &key, wxEvtHandler *listener, wxEventType evt)
Set object to send wxEventType ev to listener on changes in key.
Custom event class for OpenCPN's notification system.
std::shared_ptr< const void > GetSharedPtr() const
Gets the event's payload data.
Data for a loaded plugin, including dl-loaded library.
int m_cap_flag
PlugIn Capabilities descriptor.
bool LoadAllPlugIns(bool enabled_plugins, bool keep_orphans=false)
Update catalog with imported metadata and load all plugin library files.
bool UnLoadAllPlugIns()
Unload allplugins i.
bool UpdatePlugIns()
Update the GetPlugInArray() list by reloading all plugins from disk.
const ArrayOfPlugIns * GetPlugInArray()
Return list of currently loaded plugins.
bool DeactivateAllPlugIns()
Deactivate all plugins.
static PrintDialog & GetInstance()
Get instance to handle the print process,.
Represents a waypoint or mark within the navigation system.
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
bool m_bShowName
Flag indicating if the waypoint name should be shown.
Represents a navigational route in the navigation system.
wxString m_RouteStartString
Name or description of the route's starting point.
bool m_bDeleteOnArrival
Flag indicating whether the route should be deleted once navigation reaches the end.
wxString m_RouteEndString
Name or description of the route's ending point.
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
wxString m_RouteNameString
User-assigned name for the route.
wxString m_GUID
Globally unique identifier for this route.
EventVar on_routes_update
Notified when list of routes is updated (no data in event)
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
Manager for S57 chart SENC creation threads.
EventVar evt_resume
Notified when resuming from hibernate.
Represents a single point in a track.
wxDateTime GetCreateTime(void)
Retrieves the creation timestamp of a track point as a wxDateTime object.
Represents a track, which is a series of connected track points.
double view_scale_ppm
Requested view scale in physical pixels per meter (ppm), before applying projections.
double rotation
Rotation angle of the viewport in radians.
double skew
Angular distortion (shear transform) applied to the viewport in radians.
double clon
Center longitude of the viewport in degrees.
double clat
Center latitude of the viewport in degrees.
Encapsulates persistent canvas configuration.
double iLat
Latitude of the center of the chart, in degrees.
bool bShowOutlines
Display chart outlines.
wxSize canvasSize
Canvas dimensions.
bool bShowDepthUnits
Display depth unit indicators.
double iLon
Longitude of the center of the chart, in degrees.
double iRotation
Initial rotation angle in radians.
bool bCourseUp
Orient display to course up.
bool bQuilt
Enable chart quilting.
bool bFollow
Enable vessel following mode.
double iScale
Initial chart scale factor.
bool bShowGrid
Display coordinate grid.
ChartCanvas * canvas
Pointer to associated chart canvas.
bool bShowCurrents
Display current information.
bool bShowTides
Display tide information.
bool bLookahead
Enable lookahead mode.
bool bHeadUp
Orient display to heading up.
wxRect GetRect(void) const
Return the coordinates of the compass widget, in physical pixels relative to the canvas window.
virtual void OnToolbarToolCallback(int id)
Handles toolbar tool clicks.
Represents an S57 format electronic navigational chart in OpenCPN.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
bool HasMember(unsigned index) const
Return TRUE if the object contains an element at the specified index.
wxString AsString() const
Return the stored value as a wxWidget's string.
CM93OffsetDialog * g_pCM93OffsetDialog
Global instance.
Class cm93chart and helpers – CM93 chart state.
Global variables reflecting command line options and arguments.
wxColorHashMap * pcurrent_user_color_hash
Global instance.
Global color handling by name.
Communication drivers factory and support.
Driver registration container, a singleton.
NMEA Data Multiplexer Object.
Raw messages layer, supports sending and recieving navmsg messages.
Variables maintained by comm stack, read-only access for others.
APConsole * console
Global instance.
Primary navigation console display for route and vessel tracking.
Config file user configuration interface.
bool g_always_send_rmb_rmc
Always send RMB and RMC n0183 messages even if there is no active route.
double g_COGAvg
Debug only usage.
int g_COGAvgSec
COG average period for Course Up Mode (sec)
std::vector< size_t > g_config_display_size_mm
Size of pysical screen in millimeters.
double g_display_size_mm
Physical display width (mm)
Global variables stored in configuration file.
Options | Connections GUI tab managing connections
Extern C linked utilities.
New NMEA Debugger successor main window.
std::vector< OCPN_MonitorInfo > g_monitor_info
Information about the monitors connected to the system.
OpenGL chart rendering canvas.
glTextureManager * g_glTextureManager
Global instance.
Hooks into gui available in model.
Misc GUI event vars, a singleton.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
General purpose GUI support.
size_t g_current_monitor
Current monitor displaying main application frame.
double vLat
Virtual lat from chcanv popup.
double vLon
Virtual lon from chcanv popup.
bool b_inCompressAllCharts
Flag to control adaptive UI scaling.
int g_NeedDBUpdate
0 - No update needed, 1 - Update needed because there is no chart database, inform user 2 - Start upd...
double g_current_monitor_dip_px_ratio
ratio to convert between DIP and physical pixels.
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
GUI constant definitions.
The local API has a server side handling commands and a client part issuing commands.
Enhanced logging interface on top of wx/log.h.
MarkInfoDlg * g_pMarkInfoDialog
global instance
Waypoint properties maintenance dialog.
MUI (Modern User Interface) Control bar.
Multiplexer class and helpers.
MySQL based storage for routes, tracks, etc.
Navigation Utility Functions without GUI dependencies.
User notifications manager.
s57RegistrarMgr * m_pRegistrarMan
Global instance.
OCPN_AUIManager * g_pauimgr
Global instance.
MyFrame * gFrame
Global instance.
PlugIn Object Definition/API.
wxWindow * GetOCPNCanvasWindow()
Gets OpenCPN's main canvas window.
double OCPN_GetDisplayContentScaleFactor()
Gets content scaling factor for current display.
void JumpToPosition(double lat, double lon, double scale)
Centers chart display on specified position at given scale.
wxWindow * GetCanvasUnderMouse()
Gets canvas window under mouse cursor.
void SendPluginMessage(wxString message_id, wxString message_body)
Sends message to other plugins.
options * g_options
Global instance.
bool bGPSValid
Indicate whether the Global Navigation Satellite System (GNSS) has a valid position.
double gHdm
Magnetic heading in degrees (0-359.99).
double gVar
Magnetic variation in degrees.
double gHdt
True heading in degrees (0-359.99).
double gLat
Vessel's current latitude in decimal degrees.
double gCog
Course over ground in degrees (0-359.99).
double gSog
Speed over ground in knots.
double gLon
Vessel's current longitude in decimal degrees.
Position, course, speed, etc.
Tools to send data to plugins.
Low level code to load plugins from disk, notably the PluginLoader class.
PlugInManager * g_pi_manager
Global instance.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
Generic, styled prit dialog.
Print chart canvas mix-in.
wxRect g_blink_rect
Global instance.
Purpose: Track and Trackpoint drawing stuff.
RoutePropDlgImpl * pRoutePropDialog
Global instance.
RoutePoint * pAnchorWatchPoint2
Global instance.
Routeman * g_pRouteMan
Global instance.
RouteList * pRouteList
Global instance.
RoutePoint * pAnchorWatchPoint1
Global instance.
Route * pAISMOBRoute
Global instance.
S57QueryDialog * g_pObjectQueryDialog
Global instance.
S57 object query result window.
Select * pSelect
Global instance.
Selected route, segment, waypoint, etc.
const wxEventType wxEVT_OCPN_BUILDSENCTHREAD
Global instance.
SENCThreadManager * g_SencThreadManager
Global instance.
Class StdIcon, typically a small monochrome svg icon.
Represents an entry in the chart table, containing information about a single chart.
A generic position and navigation data structure.
double kCog
Course over ground in degrees.
double kHdt
True heading in degrees.
int nSats
Number of satellites used in the fix.
double kHdm
Magnetic heading in degrees.
time_t FixTime
UTC time of fix.
double kLat
Latitude in decimal degrees.
double kSog
Speed over ground in knots.
double kVar
Magnetic variation in degrees.
double kLon
Longitude in decimal degrees.
Suspend/resume and new devices events exchange point.
Tide and currents window.
TCMgr * ptcmgr
Global instance.
Tide and Current Manager @TODO Add original author copyright.
Timer identification constants.
ActiveTrack * g_pActiveTrack
global instance
std::vector< Track * > g_TrackList
Global instance.
Recorded track abstraction.
TrackPropDlg * pTrackPropDialog
Global instance.
void DestroyDeviceNotFoundDialogs()
Destroy all open "Device not found" dialog windows.
Access checks for comm devices and dongle.
WaypointMan drawing stuff.