56#include <wx/stdpaths.h>
57#include <wx/tokenzr.h>
58#include <wx/display.h>
59#include <wx/jsonreader.h>
61#include "o_sound/o_sound.h"
86#include "model/nav_object_database.h"
100#include "ais_info_gui.h"
104#include "ais_info_gui.h"
128#include "load_errors_dlg.h"
131#include "N2KParser.h"
154#include "user_colors.h"
160#include "androidUTIL.h"
164static constexpr long kFrameStyle = wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS;
175GLenum g_texture_rectangle_format;
178#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
179extern wxLocale *plocale_def_lang;
183extern bool g_b_EnableVBO;
184extern GLenum g_texture_rectangle_format;
188static int g_last_ChartScaleFactor;
189static char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
190static int options_subpage = 0;
191static bool b_reloadForPlugins;
193static wxSize options_lastWindowSize(0, 0);
194static wxPoint options_lastWindowPos(0, 0);
198static double gQueryVar = 361.0;
200static char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
201static o_sound::Sound *_bells_sounds[] = {o_sound::Factory(),
203static std::vector<o_sound::Sound *> bells_sound(_bells_sounds,
209typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
210typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
212static SetSysColors_t pSetSysColors;
213static GetSysColor_t pGetSysColor;
215void SaveSystemColors();
216void RestoreSystemColors();
221DWORD color_3ddkshadow;
223DWORD color_activecaption;
224DWORD color_gradientactivecaption;
225DWORD color_captiontext;
226DWORD color_windowframe;
227DWORD color_inactiveborder;
232#include <wx/msw/msvcrt.h>
236static const long long lNaN = 0xfff8000000000000;
237#define NAN (*(double *)&lNaN)
241static double gLat_gt, gLon_gt;
242static double gLat_gt_m1, gLon_gt_m1;
243static uint64_t fix_time_gt;
244static uint64_t fix_time_gt_last;
246static double gSog_gt, gHdt_gt;
247static double gCog_gt_m1, gHdt_gt_m1;
248static uint64_t hdt_time_gt;
249static double cog_rate_gt, hdt_rate_gt;
251void InitializeUserColors();
252void DeInitializeUserColors();
253void SetSystemColors(ColorScheme cs);
255static bool LoadAllPlugIns(
bool load_enabled) {
256 AbstractPlatform::ShowBusySpinner();
257 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
258 AbstractPlatform::HideBusySpinner();
262static void LaunchLocalHelp() {
264 androidLaunchHelpView();
266 wxString def_lang_canonical =
"en_US";
269 if (plocale_def_lang)
270 def_lang_canonical = plocale_def_lang->GetCanonicalName();
273 wxString help_locn = g_Platform->GetSharedDataDir() +
"doc/help_";
275 wxString help_try = help_locn + def_lang_canonical +
".html";
277 if (!::wxFileExists(help_try)) {
278 help_try = help_locn +
"en_US" +
".html";
280 if (!::wxFileExists(help_try)) {
281 help_try = help_locn +
"web" +
".html";
284 if (!::wxFileExists(help_try))
return;
287 wxLaunchDefaultBrowser(wxString(
"file:///") + help_try);
292static wxString _menuText(wxString name, wxString shortcut) {
296 menutext <<
"\t" << shortcut;
301static void DoHelpDialog() {
313 [] { LaunchLocalHelp(); });
325#if defined(__WXGTK__) || defined(__WXQT__)
326#include "bitmaps/opencpn.xpm"
341 if (g_bInlandEcdis) {
345 wxPoint tbp_incanvas =
348 g_iENCToolbarPosY = tbp_incanvas.y;
349 g_iENCToolbarPosX = tbp_incanvas.x;
357 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
361 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
364 g_iENCToolbarPosY = -1;
367 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
372 double tool_scale_factor =
373 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
375 tool_scale_factor, callbacks);
387#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
390static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
391 const char *prop_name) {
395 unsigned long ret_nitems;
396 unsigned long ret_bytes_after;
397 unsigned char *ret_prop;
399 xa_prop_name = XInternAtom(disp, prop_name, False);
407 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
408 &xa_ret_type, &ret_format, &ret_nitems,
409 &ret_bytes_after, &ret_prop) != Success)
412 if (xa_ret_type != xa_prop_type) {
416 return (
char *)ret_prop;
421static bool isTransparentToolbarInOpenGLOK() {
428 if (!g_bdisable_opengl) {
429 Display *disp = XOpenDisplay(NULL);
431 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
433 "_NET_SUPPORTING_WM_CHECK")) ||
434 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
436 "_WIN_SUPPORTING_WM_CHECK"))) {
439 if ((wm_name = get_X11_property(disp, *sup_window,
440 XInternAtom(disp,
"UTF8_STRING", False),
442 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
445 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
460wxFont *MyFrame::GetFont(wxFont *font,
double scale) {
462 font->GetFamily(), font->GetStyle(),
463 font->GetWeight(),
false, font->GetFaceName());
465wxFont *MyFrame::GetScaledFont(
int pointSize, wxFontFamily family,
466 wxFontStyle style, wxFontWeight weight,
467 const wxString faceName,
double scale) {
471wxFont *MyFrame::GetDefaultFont(wxString label,
int Ptsize) {
472 return GetOCPNScaledFont_PlugIn(label, Ptsize);
481wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
483BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
484EVT_CLOSE(MyFrame::OnCloseWindow)
485EVT_MENU(wxID_EXIT, MyFrame::OnExit)
486EVT_SIZE(MyFrame::OnSize)
487EVT_MOVE(MyFrame::OnMove)
488EVT_ICONIZE(MyFrame::OnIconize)
489EVT_MENU(-1, MyFrame::OnToolLeftClick)
490EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
492EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
493EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
494EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
496EVT_MAXIMIZE(MyFrame::OnMaximize)
497EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
498 MyFrame::RequestNewToolbarArgEvent)
499EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
501EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
502EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
503EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
505#ifdef wxHAS_POWER_EVENTS
506EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
507EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
508EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
509EVT_POWER_RESUME(MyFrame::OnResume)
520static
void onBellsFinishedCB(
void *ptr) {
521 auto framePtr =
static_cast<MyFrame *
>(ptr);
523 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
524 wxPostEvent(framePtr, ev);
529 auto msg = ev.GetString().ToStdString();
530 auto ¬eman = NotificationManager::GetInstance();
531 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
534static NmeaLog *GetDataMonitor() {
535 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
536 return dynamic_cast<NmeaLog *
>(w);
539MyFrame::MyFrame(
const wxString &title,
const wxPoint &pos,
const wxSize &size,
540 RestServer &rest_server, wxAuiDefaultDockArt *pauidockart,
541 OpenFileFunc open_gpx_file)
543 m_connections_dlg(nullptr),
545 m_pauidockart(pauidockart),
546 m_rest_server(rest_server),
547 m_open_gpx_file(open_gpx_file) {
559 m_ulLastNMEATicktime = 0;
560 m_data_monitor->Hide();
562 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
566 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
569 InitTimer.SetOwner(
this, INIT_TIMER);
571 m_initializing =
false;
572 m_toolbar_callbacks.render_gl_textures =
574 [&](
ocpnDC &dc,
float *coords,
float *uv) {
575 GetPrimaryCanvas()->GetglCanvas()->RenderTextures(
576 dc, coords, uv, 4, &GetPrimaryCanvas()->GetVP());
579 [&](
ocpnDC &dc,
float *coords,
float *uv) {};
583 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
586 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
589 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
592 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
595 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
597 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
606 m_bTimeIsSet =
false;
607 m_bdefer_resize =
false;
610 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
611 COGFilterTable[i] = NAN;
612 SOGFilterTable[i] = NAN;
614 m_last_bGPSValid =
false;
615 m_last_bVelocityValid =
false;
625 for (
int i = 0; i < kMaxCogAverageSeconds; i++) COGTable[i] = NAN;
630 double process_noise_std = 1.0;
631 double measurement_noise_std = 0.5;
635 m_ChartUpdatePeriod = 1;
640 log_callbacks.log_is_active = [&]() {
641 auto log = GetDataMonitor();
642 return log && log->IsVisible();
644 log_callbacks.log_message = [&](
Logline ll) {
645 NmeaLog *monitor = GetDataMonitor();
648 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
651 ais_callbacks.confirm_stop_track = []() {
652 int r = OCPNMessageBox(
654 _(
"This AIS target has Persistent tracking selected by MMSI "
656 "A Persistent track recording will therefore be restarted for this "
658 "Do you instead want to stop Persistent tracking for this target?"),
659 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
660 return r == wxID_YES;
662 ais_callbacks.get_target_mmsi = []() {
663 auto alert_dlg_active =
665 assert(alert_dlg_active);
666 return alert_dlg_active->Get_Dialog_MMSI();
674 wxLogMessage(
" **** Connect stuff");
680 Connect(wxEVT_OCPN_MSG,
681 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
689 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
697#if defined(__WXGTK__) || defined(__WXQT__)
698 wxIcon app_icon(opencpn);
706 wxDynamicLibrary dllUser32(
"user32.dll");
708 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(
"SetSysColors");
709 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(
"GetSysColor");
714 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
719 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
720 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
722 assert(
g_pRouteMan != 0 &&
"g_pRouteMan not available");
723 m_routes_update_listener.Init(GuiEvents::GetInstance().on_routes_update,
724 [&](wxCommandEvent) { Refresh(); });
725 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
727 m_update_statusbar_listener.Init(
728 GuiEvents::GetInstance().gframe_update_status_bar,
730 m_center_aistarget_listener.Init(
731 GuiEvents::GetInstance().on_center_ais_target, [&](
ObservedEvt &ev) {
732 auto ais_target = obs::UnpackEvtPointer<AisTargetData>(ev);
733 CenterAisTarget(ais_target);
735 m_reload_charts_listener.Init(
736 GuiEvents::GetInstance().on_finalize_chartdbs,
737 [&](
ObservedEvt &ev) { FinalizeChartDBUpdate(); });
741 EnableFullScreenView();
743 int is_day = user_colors::GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
749 FrameTenHzTimer.Stop();
764 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
770void MyFrame::FreezeCharts() {
773 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
775 if (cc && !cc->IsFrozen()) cc->Freeze();
779void MyFrame::CenterAisTarget(
780 const std::shared_ptr<const AisTargetData> &ais_target) {
788 double factor = cc->GetScaleValue() / 5000.0;
789 JumpToPosition(GetFocusCanvas(), ais_target->Lat, ais_target->Lon,
795void MyFrame::ThawCharts() {
798 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
800 if (cc && cc->IsFrozen()) cc->Thaw();
807 switch (event.type) {
808 case SENC_BUILD_STARTED:
811 case SENC_BUILD_DONE_NOERROR:
813 chart =
event.m_ticket->m_chart;
815 chart->PostInit(FULL_INIT, global_color_scheme);
817 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
819 if (cc) cc->ClearS52PLIBStateHash();
826 delete event.m_ticket;
828 case SENC_BUILD_DONE_ERROR:
829 wxLogDebug(
"SENC build done: SENC_BUILD_DONE_ERROR");
832 delete event.m_ticket;
839bool MyFrame::StartRebuildChartDatabase() {
840 bool b_SetInitialPoint =
false;
843 ArrayOfCDI ChartDirArray;
844 pConfig->LoadChartDirArray(ChartDirArray);
846 if (ChartDirArray.GetCount()) {
851 _(
"OpenCPN needs to update the chart database from config file "
855 wxICON_INFORMATION | wxOK);
863 _(
"Rebuilding chart database from configuration file entries..."));
867 wxString dummy1 = _(
"Elapsed time : ");
868 wxString dummy2 = _(
"Estimated time : ");
869 wxString dummy3 = _(
"Remaining time : ");
870 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
871 _(
"OpenCPN Chart Update"), line, 100, NULL, wxPD_SMOOTH);
881void MyFrame::OnBellsFinished(wxCommandEvent &event) {
882 int bells = wxMin(m_BellsToPlay, 2);
883 if (bells <= 0)
return;
885 wxString soundfile =
"sounds";
886 appendOSDirSlash(&soundfile);
887 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
888 soundfile.Prepend(g_Platform->GetSharedDataDir());
889 wxLogMessage(
"Using bells sound file: " + soundfile);
891 o_sound::Sound *sound = bells_sound[bells - 1];
892 sound->SetFinishedCallback(onBellsFinishedCB,
this);
893 auto cmd_sound =
dynamic_cast<o_sound::SystemCmdSound *
>(sound);
894 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
895 sound->Load(soundfile);
896 if (!sound->IsOk()) {
897 wxLogMessage(
"Failed to load bells sound file: " + soundfile);
901 m_BellsToPlay -= bells;
904void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
906void MyFrame::OnMaximize(wxMaximizeEvent &event) {
913void MyFrame::ReloadAllVP() {
914 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
916 if (cc) cc->ReloadVP();
920void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
922 (cs == GLOBAL_COLOR_SCHEME_DAY) | (cs == GLOBAL_COLOR_SCHEME_DAY_HICON);
923 int is_day = scheme_day ? 1 : 0;
926 global_color_scheme = cs;
929 case GLOBAL_COLOR_SCHEME_DAY:
932 case GLOBAL_COLOR_SCHEME_DUSK:
935 case GLOBAL_COLOR_SCHEME_NIGHT:
936 SchemeName =
"NIGHT";
938 case GLOBAL_COLOR_SCHEME_DAY_HICON:
939 SchemeName =
"DAY_HICON";
941 case GLOBAL_COLOR_SCHEME_NIGHT_HICON:
942 SchemeName =
"NIGHT_HICON";
949 m_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
951 m_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
952 m_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
953 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
954 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
955 m_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
957 m_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
986 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
987 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
991 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
993 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
997 user_colors::GetMapByScheme(SchemeName.ToStdString());
1002 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1005 cc->SetColorScheme(cs);
1006 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
1007 cc->HideChartInfoWindow();
1008 cc->SetQuiltChartHiLiteIndex(-1);
1014 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1026 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1039 if (g_pais_query_dialog_active) {
1040 bool b_isshown = g_pais_query_dialog_active->IsShown();
1041 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1042 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1044 g_pais_query_dialog_active->Close();
1047 g_pais_query_dialog_active->
Create(
1048 this, -1, _(
"AIS Target Query"),
1049 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1050 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1051 g_pais_query_dialog_active->UpdateText();
1052 if (b_isshown) g_pais_query_dialog_active->Show();
1057 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1061 ApplyGlobalColorSchemetoStatusBar();
1063 UpdateAllToolbars(cs);
1068 bool btoolbarFull = g_bmasterToolbarFull;
1074 if (!btoolbarFull) {
1076 RequestNewMasterToolbar();
1078 CollapseGlobalToolbar();
1081 RequestNewMasterToolbar();
1090void MyFrame::ApplyGlobalColorSchemetoStatusBar() {
1091 if (m_pStatusBar != NULL) {
1092 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1093 m_pStatusBar->ClearBackground();
1104void MyFrame::CancelAllMouseRoute() {
1106 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1108 if (cc) cc->CancelMouseRoute();
1112void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1120 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1128 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1137 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1140 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1141 config_array.Item(i)->canvas = NULL;
1147 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1152 switch (g_canvasConfig) {
1166 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1167 cc->GetglCanvas()->Show();
1170 config_array.Item(0)->canvas = cc;
1174 cc->ApplyCanvasConfig(config_array.Item(0));
1178 cc->ConfigureChartBar();
1179 cc->SetColorScheme(global_color_scheme);
1180 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1181 cc->SetShowGPS(
true);
1184 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1186 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1202 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1205 config_array.Item(0)->canvas = cc;
1207 cc->ApplyCanvasConfig(config_array.Item(0));
1210 cc->ConfigureChartBar();
1211 cc->SetColorScheme(global_color_scheme);
1212 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1213 cc->SetShowGPS(
false);
1216 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1218 .CaptionVisible(
false)
1220 .CloseButton(
false);
1229 if (config_array.GetCount() < 2) {
1231 pcc->configIndex = 1;
1235 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1236 config_array.Add(pcc);
1239 config_array.Item(1)->canvas = cc;
1241 cc->ApplyCanvasConfig(config_array.Item(1));
1244 cc->ConfigureChartBar();
1245 cc->SetColorScheme(global_color_scheme);
1246 cc->SetShowGPS(
true);
1248 cc->SetShowGPSCompassWindow(
true);
1251 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1253 .CaptionVisible(
false)
1255 .CloseButton(
false);
1256 g_pauimgr->GetPane(cc).RightDockable(
true);
1260 config_array.Item(1)->canvasSize =
1261 wxSize(GetClientSize().x / 2, GetClientSize().y);
1262 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1267 if (b_useStoredSize) {
1268 int ccw = config_array.Item(1)->canvasSize.x;
1269 int cch = config_array.Item(1)->canvasSize.y;
1272 if (ccw < GetClientSize().x / 10) {
1273 ccw = GetClientSize().x / 2;
1274 cch = GetClientSize().y;
1277 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1278 cc->SetSize(ccw, cch);
1296 console->SetColorScheme(global_color_scheme);
1301 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1307void MyFrame::RequestNewToolbars(
bool bforcenew) {
1308 if (b_inCloseWindow) {
1312 BuildiENCToolbar(bforcenew, m_toolbar_callbacks);
1313 PositionIENCToolbar();
1322void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1328void MyFrame::SetAllToolbarScale() {
1329 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1332void MyFrame::SetGPSCompassScale() {
1333 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1337 wxPoint screenPoint = ::wxGetMousePosition();
1340 switch (g_canvasConfig) {
1342 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1345 if (canvas->GetScreenRect().Contains(
1349 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1352 if (canvas->GetScreenRect().Contains(
1359 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1362 if (canvas->GetScreenRect().Contains(
1363 canvas->ScreenToClient(screenPoint)))
1371int MyFrame::GetCanvasIndexUnderMouse() {
1372 wxPoint screenPoint = ::wxGetMousePosition();
1375 switch (g_canvasConfig) {
1377 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1380 if (canvas->GetScreenRect().Contains(
1384 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1387 if (canvas->GetScreenRect().Contains(
1394 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1397 if (canvas->GetScreenRect().Contains(
1398 canvas->ScreenToClient(screenPoint)))
1406bool MyFrame::DropMarker(
bool atOwnShip) {
1413 if (!canvas)
return false;
1420 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1422 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1424 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1435 RefreshAllCanvas(
false);
1440void MyFrame::SwitchKBFocusCanvas(
ChartCanvas *pCanvas) {
1441 if (g_canvasConfig != 0) {
1444 int nTargetGTK = -1;
1446 wxWindow *source = FindFocus();
1452 switch (g_canvasConfig) {
1454 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1457 if (canvas && (canvas == test)) {
1462 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1465 if (canvas && (canvas == test)) {
1473 int nfinalTarget = nTarget;
1475 nfinalTarget = nTargetGTK;
1477 target = ConfigMgr::Get()
1478 .GetCanvasConfigArray()
1483 target->Refresh(
true);
1494void MyFrame::FastClose() {
1496 FrameTenHzTimer.Stop();
1498 FrameTimer1.Start(1);
1502void MyFrame::OnExit(wxCommandEvent &event) {
1506void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1509 if (b_inCloseWindow) {
1519 if (!g_bDeferredInitDone)
return;
1536 if (bDBUpdateInProgress)
return;
1538 b_inCloseWindow =
true;
1540 ::wxSetCursor(wxCURSOR_WAIT);
1544 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1546 if (cc && cc->IsMeasureActive()) {
1547 cc->CancelMeasureRoute();
1552 SendPreShutdownHookToPlugins();
1556 if (g_pAISTargetList) {
1557 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1558 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1559 g_pauimgr->DetachPane(g_pAISTargetList);
1586 SetCursor(wxCURSOR_WAIT);
1588 RefreshAllCanvas(
true);
1594 RestoreScreenBrightness();
1605 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1606 g_iENCToolbarPosY = tbp_incanvas.y;
1607 g_iENCToolbarPosX = tbp_incanvas.x;
1611 g_bframemax = IsMaximized();
1614 FrameTenHzTimer.Stop();
1616 FrameCOGTimer.Stop();
1630 if (g_bAutoAnchorMark) {
1631 bool watching_anchor =
false;
1639 wxDateTime now = wxDateTime::Now();
1640 wxTimeSpan uptime = now.Subtract(g_start_time);
1642 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1643 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1648 if (g_declutter_anchorage) {
1649 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1650 if (pr->GetName().StartsWith(
"Anchorage")) {
1651 double a =
gLat - pr->m_lat;
1652 double b =
gLon - pr->m_lon;
1653 double l = sqrt((a * a) + (b * b));
1656 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1658 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1659 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1667 wxString name = now.Format();
1668 name.Prepend(_(
"Anchorage created "));
1674 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1683 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1687 NavObj_dB::GetInstance().Close();
1691 pConfig->DeleteGroup(
"/Routes");
1692 pConfig->DeleteGroup(
"/Marks");
1713 if (g_pAISTargetList) {
1714 g_pAISTargetList->Disconnect_decoder();
1715 g_pAISTargetList->Destroy();
1718 if (RouteManagerDialog::getInstanceFlag()) {
1735 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1737 if (cc) cc->Destroy();
1761 CommBridge::GetInstance().SaveConfig();
1781 auto ®istry = CommDriverRegistry::GetInstance();
1782 registry.CloseAllDrivers();
1790 while (pLayerList->size())
delete *pLayerList->begin();
1794 ReleaseApiListeners();
1797 g_bTempShowMenuBar =
false;
1799#define THREAD_WAIT_SECONDS 5
1809 wxLogMessage(
"Starting compressor pool drain");
1810 wxDateTime now = wxDateTime::Now();
1811 time_t stall = now.GetTicks();
1812 time_t end = stall + THREAD_WAIT_SECONDS;
1815 while (stall < end) {
1816 wxDateTime later = wxDateTime::Now();
1817 stall = later.GetTicks();
1820 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1829 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1835 uninitIXNetSystem();
1842 wxLogMessage(
"gFrame destroyed.");
1845#ifndef USE_ANDROID_GLES2
1846 qDebug() <<
"Calling OnExit()";
1850 wxTheApp->ExitMainLoop();
1853void MyFrame::OnMove(wxMoveEvent &event) {
1854 auto idx = wxDisplay::GetFromWindow(
this);
1867 DEBUG_LOG <<
"Moved to " << idx
1868#if wxCHECK_VERSION(3, 1, 6)
1869 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1870 << wxDisplay(idx).GetPPI().GetY()
1871 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1873 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1874 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1875 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1876 << wxGetDisplaySizeMM().GetY()
1877 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1886 if (g_config_display_size_manual) {
1895 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1898 cc->SetMUIBarPosition();
1907 UpdateGPSCompassStatusBoxes();
1917 PositionIENCToolbar();
1923 g_nframewin_posx = GetPosition().x;
1924 g_nframewin_posy = GetPosition().y;
1927void MyFrame::ProcessCanvasResize() {
1928 UpdateGPSCompassStatusBoxes(
true);
1932 PositionIENCToolbar();
1935 TriggerRecaptureTimer();
1939void MyFrame::TriggerRecaptureTimer() {
1940 m_recaptureTimer.Start(
1941 1000, wxTIMER_ONE_SHOT);
1944void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1946void MyFrame::SetCanvasSizes(wxSize frameSize) {
1950 int cccw = frameSize.x;
1951 int ccch = frameSize.y;
1955 switch (g_canvasConfig) {
1961 cc->GetSize( &cur_width, &cur_height );
1962 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1964 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1966 cc->SetSize( 0, 0, cccw, ccch );
1976 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1977 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1979 ccw = wxMin(ccw, cccw * 8 / 10);
1980 ccw = wxMax(ccw, cccw * 2 / 10);
1984 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1991 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
2008void MyFrame::OnIconize(wxIconizeEvent &event) {
2018 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2020 if (cc && cc->GetMUIBar()) {
2021 if (cc->GetMUIBar()->GetCanvasOptions()) {
2022 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2023 cc->GetMUIBar()->PushCanvasOptions();
2032void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2034void MyFrame::ODoSetSize() {
2036 GetClientSize(&x, &y);
2039 if (m_pStatusBar != NULL) {
2040 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2041 int currentCount = m_pStatusBar->GetFieldsCount();
2042 if (currentCount != m_StatusBarFieldCount) {
2043 if ((currentCount > 0) && (currentCount < 7)) {
2046 int widths[] = {2, 2, 2, 2, 2, 2};
2047 m_pStatusBar->SetStatusWidths(currentCount, widths);
2050 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2053 if (m_StatusBarFieldCount) {
2058 if (m_StatusBarFieldCount > 2) {
2059 int widths[] = {-6, -5, -5, -6, -4};
2060 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2061 }
else if (m_StatusBarFieldCount == 2) {
2062 int cwidth = x * 90 / 100;
2063 int widths[] = {100, 100};
2064 widths[0] = cwidth * 6.4 / 10.0;
2065 widths[1] = cwidth * 3.6 / 10.0;
2066 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2068 int widths[] = {100, 100};
2069 widths[0] = x * 90 / 100;
2070 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2073 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2074 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2075 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2077 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2079 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2087 m_pStatusBar->GetFieldRect(0, stat_box);
2090 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2092 wxFont sys_font = *wxNORMAL_FONT;
2093 int try_font_size = sys_font.GetPointSize();
2096 int min_font_size = 10;
2106 wxFont *statusBarFont =
2107 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2108 int font_size = statusBarFont->GetPointSize();
2110 font_size = wxMin(font_size,
2113 wxMax(font_size, min_font_size);
2116 font_size = statusBarFont->GetPointSize();
2123 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2124 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2126 int min_height = stat_box.height;
2128 m_pStatusBar->SetFont(*pstat_font);
2129 m_pStatusBar->SetForegroundColour(
2130 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2132 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2134 (min_height >> 1) * 2;
2135 m_pStatusBar->SetMinHeight(min_height);
2144 SetCanvasSizes(GetClientSize());
2146 UpdateGPSCompassStatusBoxes(
true);
2148 if (
console) PositionConsole();
2151 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2153 if (cc) cc->FormatPianoKeys();
2159 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2160 GetPrimaryCanvas()->GetCompass()->GetRect());
2186 options_lastWindowSize = wxSize(0, 0);
2187 options_lastWindowPos = wxPoint(0, 0);
2194 if (!b_inCloseWindow) {
2197 resizeAndroidPersistents();
2201 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2202 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2208void MyFrame::PositionConsole() {
2209#if defined(__WXMSW__) || defined(__WXMAC__)
2210 if (NULL == GetPrimaryCanvas())
return;
2212 int ccx, ccy, ccsx, ccsy, consx, consy;
2217 consoleHost->GetSize(&ccsx, &ccsy);
2218 consoleHost->GetPosition(&ccx, &ccy);
2220 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2221 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2222 consoleHost = GetPrimaryCanvas();
2227 if (consoleHost->GetCompass()) {
2228 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2230 if (compass_rect.y < 100)
2231 yOffset = compass_rect.y + compass_rect.height + 45;
2235 wxSize csz =
console->GetSize();
2239 wxPoint screen_pos =
2240 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2243 if (NULL == GetPrimaryCanvas())
return;
2245 int ccx, ccy, ccsx, ccsy, consx, consy;
2250 consoleHost->GetSize(&ccsx, &ccsy);
2251 consoleHost->GetPosition(&ccx, &ccy);
2253 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2254 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2255 consoleHost = GetPrimaryCanvas();
2258 int yTopOffset = 60;
2259 int yBottomOffset = 0;
2261 if (consoleHost->GetCompass()) {
2262 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2264 if (compass_rect.y < 100)
2265 yTopOffset = compass_rect.y + compass_rect.height;
2267 if (consoleHost->GetMUIBar()) {
2268 wxRect mui_rect = consoleHost->GetMUIBarRect();
2269 yBottomOffset = ccsy - mui_rect.y;
2273 wxSize csz =
console->GetSize();
2276 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2278 if (consy < yAvail) {
2279 yFinal = (yAvail - consy) / 2;
2280 yFinal += yTopOffset;
2281 }
else if (
console->GetCDI()->IsShown()) {
2282 int cdi_height =
console->GetCDI()->GetSize().y;
2283 int consy_no_cdi = consy - cdi_height;
2284 yFinal = (yAvail - consy_no_cdi) / 2;
2285 yFinal += yTopOffset;
2289 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2294void MyFrame::UpdateAllFonts() {
2303 DestroyPersistentDialogs();
2305 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2310void MyFrame::DestroyPersistentDialogs() {
2311 if (g_pais_query_dialog_active) {
2312 g_pais_query_dialog_active->Hide();
2313 g_pais_query_dialog_active->Destroy();
2314 g_pais_query_dialog_active = NULL;
2342void MyFrame::RefreshGroupIndices() {
2344 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2346 if (cc) cc->canvasRefreshGroupIndex();
2350bool MyFrame::DisableTbarTooltips() {
2355 wxLogWarning(
"Global g_MainToolbar has not been created.");
2359void MyFrame::EnableTbarTooltips() {
2365void MyFrame::HideTbarTooltip() {
2371void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2373 switch (event.GetId()) {
2374 case ID_MENU_SCALE_OUT:
2375 DoStackDelta(GetPrimaryCanvas(), 1);
2379 case ID_MENU_SCALE_IN:
2380 DoStackDelta(GetPrimaryCanvas(), -1);
2384 case ID_MENU_ZOOM_IN: {
2385 if (GetFocusCanvas()) {
2386 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2391 case ID_MENU_ZOOM_OUT: {
2392 if (GetFocusCanvas()) {
2393 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2398 case ID_MENU_ROUTE_NEW: {
2399 if (GetFocusCanvas()) {
2400 if (0 == GetFocusCanvas()->m_routeState) {
2401 GetFocusCanvas()->StartRoute();
2403 GetFocusCanvas()->FinishRoute();
2409 case ID_MENU_TOOL_MEASURE: {
2410 GetPrimaryCanvas()->StartMeasureRoute();
2414 case ID_MENU_TOOL_NMEA_DBG_LOG:
2415 m_data_monitor->Show();
2416 m_data_monitor->Raise();
2419 case ID_MENU_TOOL_IO_MONITOR:
2420 m_data_monitor->Show();
2423 case ID_MENU_MARK_BOAT: {
2428 case ID_MENU_MARK_CURSOR: {
2433 case ID_MENU_NAV_FOLLOW: {
2434 if (
gFrame->GetPrimaryCanvas())
2435 gFrame->GetPrimaryCanvas()->TogglebFollow();
2439 case ID_MENU_CHART_OUTLINES: {
2440 ToggleChartOutlines(GetFocusCanvas());
2444 case ID_MENU_CHART_QUILTING: {
2445 ToggleQuiltMode(GetFocusCanvas());
2449 case ID_MENU_UI_CHARTBAR: {
2450 ToggleChartBar(GetFocusCanvas());
2454 case ID_MENU_ENC_TEXT:
2456 ToggleENCText(GetFocusCanvas());
2459 case ID_MENU_ENC_LIGHTS: {
2460 ToggleLights(GetFocusCanvas());
2463 case ID_MENU_ENC_SOUNDINGS: {
2464 ToggleSoundings(GetFocusCanvas());
2467 case ID_MENU_ENC_ANCHOR: {
2468 ToggleAnchor(GetFocusCanvas());
2471 case ID_MENU_ENC_DATA_QUALITY: {
2472 ToggleDataQuality(GetFocusCanvas());
2475 case ID_MENU_SHOW_NAVOBJECTS: {
2476 ToggleNavobjects(GetFocusCanvas());
2480 case ID_MENU_AIS_TARGETS: {
2481 ToggleAISDisplay(GetFocusCanvas());
2484 case ID_MENU_AIS_MOORED_TARGETS: {
2485 g_bHideMoored = !g_bHideMoored;
2488 case ID_MENU_AIS_SCALED_TARGETS: {
2489 ToggleAISMinimizeTargets(GetFocusCanvas());
2493 case ID_MENU_AIS_TARGETLIST: {
2494 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2498 case ID_MENU_AIS_TRACKS: {
2499 g_bAISShowTracks = !g_bAISShowTracks;
2500 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2504 case ID_MENU_AIS_CPADIALOG: {
2505 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2506 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2507 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2508 if (g_bAIS_CPA_Alert) {
2509 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2514 case ID_MENU_AIS_CPASOUND: {
2515 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2516 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2520 case ID_MENU_AIS_CPAWARNING: {
2521 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2522 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2526 case wxID_PREFERENCES:
2533 case ID_SETTINGS_NEW: {
2538 case ID_SETTINGS_DELETE: {
2541 g_pOptions =
nullptr;
2545 case ID_RELOAD_CHARTS: {
2550 case ID_MENU_SETTINGS_BASIC: {
2552 androidDisableFullScreen();
2554 DoAndroidPreferences();
2561 case ID_MENU_UI_FULLSCREEN: {
2566 case ID_MENU_SHOW_CURRENTS: {
2567 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2568 GetFocusCanvas()->ReloadVP();
2569 GetFocusCanvas()->Refresh(
false);
2573 case ID_MENU_SHOW_TIDES: {
2574 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2575 GetFocusCanvas()->ReloadVP();
2576 GetFocusCanvas()->Refresh(
false);
2596 case ID_MENU_UI_COLSCHEME:
2597 case ID_COLSCHEME: {
2598 ToggleColorScheme();
2607 case ID_MENU_OQUIT: {
2612 case ID_MENU_ROUTE_MANAGER:
2613 case ID_ROUTEMANAGER: {
2636 case ID_MENU_NAV_TRACK:
2638 if (!g_bTrackActive) {
2640 g_bTrackCarryOver =
true;
2643 g_bTrackCarryOver =
false;
2644 RefreshAllCanvas(
true);
2649 case ID_MENU_CHART_NORTHUP: {
2650 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2653 case ID_MENU_CHART_COGUP: {
2654 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2657 case ID_MENU_CHART_HEADUP: {
2658 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2662 case ID_MENU_MARK_MOB:
2668 case ID_MASTERTOGGLE: {
2670 wxString tip = _(
"Show Toolbar");
2671 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2673 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2675 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2678 if (g_bmasterToolbarFull)
2679 m_nMasterToolCountShown =
2683 m_nMasterToolCountShown = 2;
2685 m_nMasterToolCountShown =
2688 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2696 case ID_CMD_SELECT_CHART_TYPE: {
2697 selectChartDisplay(event.GetExtraLong(), -1);
2701 case ID_CMD_SELECT_CHART_FAMILY: {
2702 selectChartDisplay(-1, event.GetExtraLong());
2706 case ID_CMD_APPLY_SETTINGS: {
2707 applySettingsString(event.GetString());
2709 androidRestoreFullScreen();
2715 case ID_CMD_NULL_REFRESH: {
2720 case ID_CMD_SETVP: {
2721 setStringVP(event.GetString());
2725 case ID_CMD_INVALIDATE: {
2731 case ID_CMD_POST_JSON_TO_PLUGINS: {
2734 nlohmann::json root;
2736 root = nlohmann::json::parse(event.GetString().ToStdString());
2737 if (root[
"MessageID"].is_string()) {
2738 std::string msg_id = root[
"MessageID"].get<std::string>();
2741 }
catch (nlohmann::json::exception &) {
2763 ArrayOfPlugInToolbarTools tool_array =
2765 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2767 if (event.GetId() == pttc->id) {
2768 if (pttc->m_pplugin)
2790bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2791 bool viz_now = g_bmasterToolbarFull;
2794 wxString tip = _(
"Show Toolbar");
2796 tip = _(
"Hide Toolbar");
2798 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2801 bool toggle =
false;
2802 if (viz && !g_bmasterToolbarFull)
2805 else if (!viz && g_bmasterToolbarFull)
2809 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2812 if (g_bmasterToolbarFull)
2813 m_nMasterToolCountShown =
2817 m_nMasterToolCountShown = 2;
2819 m_nMasterToolCountShown =
2822 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2828void MyFrame::ScheduleReloadCharts() {
2829 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2830 evt.SetId(ID_RELOAD_CHARTS);
2831 GetEventHandler()->AddPendingEvent(evt);
2834void MyFrame::ScheduleDeleteSettingsDialog() {
2835 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2836 evt.SetId(ID_SETTINGS_DELETE);
2837 GetEventHandler()->AddPendingEvent(evt);
2840void MyFrame::ScheduleSettingsDialog() {
2841 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2842 evt.SetId(ID_SETTINGS);
2843 GetEventHandler()->AddPendingEvent(evt);
2846void MyFrame::ScheduleSettingsDialogNew() {
2847 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2848 evt.SetId(ID_SETTINGS_NEW);
2849 GetEventHandler()->AddPendingEvent(evt);
2852void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2853 UpdateCanvasConfigDescriptors();
2855 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2856 CreateCanvasLayout(
true);
2858 CreateCanvasLayout();
2862 ConfigureStatusBar();
2863 wxSize lastOptSize = options_lastWindowSize;
2868 options_lastWindowSize = lastOptSize;
2872 ScheduleSettingsDialogNew();
2874 ScheduleSettingsDialog();
2879 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2882 int index_hint = -1;
2883 if (i < pathArray.GetCount())
2884 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2885 cc->canvasChartsRefresh(index_hint);
2886 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2895 return GetPrimaryCanvas();
2898void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2900 if (g_bmasterToolbarFull) {
2901#ifndef OCPN_TOOLBAR_ANIMATE
2902 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2905 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2906 m_nMasterToolCountShown++;
2911 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2919#ifndef OCPN_TOOLBAR_ANIMATE
2920 m_nMasterToolCountShown = 1;
2922 if (m_nMasterToolCountShown > 1) {
2923 m_nMasterToolCountShown--;
2927 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2937void MyFrame::InvalidateAllGL() {
2940 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2950void MyFrame::RefreshAllCanvas(
bool bErase) {
2952 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2955 cc->Refresh(bErase);
2960void MyFrame::setStringVP(wxString VPS) {
2965 wxStringTokenizer tkz(VPS,
";");
2967 wxString token = tkz.GetNextToken();
2969 token.ToDouble(&lat);
2971 token = tkz.GetNextToken();
2973 token.ToDouble(&lon);
2975 token = tkz.GetNextToken();
2977 token.ToDouble(&scale_ppm);
2979 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2982void MyFrame::DoSettingsNew() {
2989void MyFrame::DoSettings() {
2990 if (!g_bDeferredInitDone) {
2991 wxLogWarning(
"Ignoring settings request while OpenCPN is initializing.");
2999 ApplyGlobalSettings(
true);
3002 bool b_loadHarmonics =
false;
3003 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3006 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
3009 if (b_loadHarmonics) LoadHarmonics();
3017 g_bShowChartBar = !g_bShowChartBar;
3019 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
3024 if (g_bShowChartBar) {
3026 UpdateControlBar(cc);
3029 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
3032void MyFrame::ToggleColorScheme() {
3033 static bool lastIsNight;
3034 ColorScheme s = user_colors::GetColorScheme();
3035 if (!g_hicon_colors) {
3038 if (lastIsNight && is == 3)
3041 lastIsNight =
false;
3043 if (lastIsNight) is = 2;
3044 if (is == 3) lastIsNight =
true;
3045 s = (ColorScheme)(is);
3046 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3048 if (s == GLOBAL_COLOR_SCHEME_DAY_HICON)
3049 s = GLOBAL_COLOR_SCHEME_NIGHT_HICON;
3050 else if (s == GLOBAL_COLOR_SCHEME_NIGHT_HICON)
3051 s = GLOBAL_COLOR_SCHEME_DAY_HICON;
3053 s = GLOBAL_COLOR_SCHEME_DAY_HICON;
3056 SetAndApplyColorScheme(s);
3059void MyFrame::ToggleFullScreen() {
3060 bool to = !IsFullScreen();
3065 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3067 ShowFullScreen(to, style);
3070 UpdateAllToolbars(global_color_scheme);
3072 UpdateControlBar(GetPrimaryCanvas());
3074 TriggerRecaptureTimer();
3077void MyFrame::ActivateMOB() {
3079 wxDateTime mob_time = wxDateTime::Now();
3080 wxString mob_label(_(
"MAN OVERBOARD"));
3081 mob_label += _(
" on ");
3082 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3086 pWP_MOB->SetShared(
true);
3088 pWP_MOB->SetWaypointArrivalRadius(
3090 pWP_MOB->SetUseSca(
false);
3092 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3100 new RoutePoint(zlat, zlon, g_default_wp_icon,
3101 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3102 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3107 temp_route->AddPoint(pWP_src);
3108 temp_route->AddPoint(pWP_MOB);
3110 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3120 temp_route->SetRouteArrivalRadius(-1.0);
3126 v[
"GUID"] = temp_route->
m_GUID;
3127 SendJsonMessageToAllPlugins(
"OCPN_MAN_OVERBOARD", v);
3130 if (RouteManagerDialog::getInstanceFlag()) {
3138 RefreshAllCanvas(
false);
3140 wxString mob_message(_(
"MAN OVERBOARD"));
3141 mob_message += _(
" Time: ");
3142 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3143 mob_message += _(
" Position: ");
3144 mob_message += toSDMM(1,
gLat);
3146 mob_message += toSDMM(2,
gLon);
3147 wxLogMessage(mob_message);
3149void MyFrame::TrackOn() {
3150 g_bTrackActive =
true;
3158 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3160 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3162 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3165 androidSetTrackTool(
true);
3168 if (RouteManagerDialog::getInstanceFlag()) {
3177 if (name.IsEmpty()) {
3183 name = _(
"(Unnamed Track)");
3187 SendJsonMessageToAllPlugins(
"OCPN_TRK_ACTIVATED", v);
3189 g_FlushNavobjChangesTimeout = 30;
3192Track *MyFrame::TrackOff(
bool do_add_point) {
3198 SendJsonMessageToAllPlugins(
"OCPN_TRK_DEACTIVATED", v);
3207 if (g_bTrackDaily) {
3212 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3213 return_val = pExtendTrack;
3220 g_bTrackActive =
false;
3222 if (RouteManagerDialog::getInstanceFlag()) {
3229 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3231 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3232 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3235 androidSetTrackTool(
false);
3239 m_target_rotate_time = wxInvalidDateTime;
3244void MyFrame::InitializeTrackRestart() {
3245 if (!g_bTrackDaily)
return;
3246 if (m_target_rotate_time.IsValid())
return;
3249 switch (g_track_rotate_time_type) {
3251 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3253 case TIME_TYPE_COMPUTER:
3254 rotate_at = g_track_rotate_time;
3258 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3259 rotate_at = g_track_rotate_time + utc_offset;
3262 if (rotate_at > 86400)
3264 else if (rotate_at < 0)
3267 wxTimeSpan rotate_seconds = wxTimeSpan(0, 0, rotate_at);
3268 m_target_rotate_time = wxDateTime::Today() + rotate_seconds;
3271 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3272 m_target_rotate_time += wxTimeSpan(24);
3276bool MyFrame::ShouldRestartTrack() {
3278 InitializeTrackRestart();
3280 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3281 m_target_rotate_time += wxTimeSpan(24);
3287void MyFrame::TrackDailyRestart() {
3289 Track *pPreviousTrack = TrackOff(
true);
3296 if (pPreviousTrack) {
3297 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3301 if (RouteManagerDialog::getInstanceFlag()) {
3309void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3311 cc->SetUpMode(mode);
3313 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3314 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3315 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3318 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3323 cc->SetShowENCText(!cc->GetShowENCText());
3325 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3333void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3336 cc->SetENCDisplayCategory(nset);
3338 UpdateGlobalMenuItems();
3349 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3351 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3360 cc->SetShowENCLights(!cc->GetShowENCLights());
3362 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3372void MyFrame::ToggleRocks(
void )
3378 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3379 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3380 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3381 pOLE->nViz = !pOLE->nViz;
3385 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3386 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3387 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3390 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3394 ps52plib->GenerateStateHash();
3401 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3403 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3411 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3413 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3428 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3429 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3434 cc->SetShowAIS(!cc->GetShowAIS());
3435 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3439void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3440 cc->SetAttenAIS(!cc->GetAttenAIS());
3441 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3447 cc->m_bFollow =
true;
3450 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3454 SetChartUpdatePeriod();
3462 cc->m_bFollow =
false;
3464 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3468 SetChartUpdatePeriod();
3471void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3472 cc->SetShowOutlines(!cc->GetShowOutlines());
3474 RefreshAllCanvas(
false);
3478 if (g_bopengl) InvalidateAllGL();
3481 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3484void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3486void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3488 bool enabled = m_pMenuBar->IsEnabled(item_id);
3489 m_pMenuBar->Enable(item_id,
false);
3490 m_pMenuBar->Check(item_id, state);
3491 m_pMenuBar->Enable(item_id, enabled);
3495void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3502void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3503 wxBitmap *bmpRollover) {
3505 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3510void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3511 wxString rolloverSVGfile,
3512 wxString toggledSVGfile) {
3515 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3519void MyFrame::ConfigureStatusBar() {
3521 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3524 UseNativeStatusBar(
false);
3527 if (g_bShowStatusBar) {
3528 if (!m_pStatusBar) {
3530 CreateStatusBar(m_StatusBarFieldCount, 0);
3531 ApplyGlobalColorSchemetoStatusBar();
3536 m_pStatusBar->Destroy();
3537 m_pStatusBar = NULL;
3543void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3544 ConfigureStatusBar();
3546 wxSize lastOptSize = options_lastWindowSize;
3552 options_lastWindowSize = lastOptSize;
3554 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3557void MyFrame::BuildMenuBar() {
3563 bool showMenuBar =
true;
3565 bool showMenuBar = g_bShowMenuBar;
3577 m_pMenuBar =
new wxMenuBar();
3578 RegisterGlobalMenuItems();
3579 SetMenuBar(m_pMenuBar);
3583 UpdateGlobalMenuItems();
3588 m_pMenuBar->Destroy();
3594void MyFrame::RegisterGlobalMenuItems() {
3595 if (!m_pMenuBar)
return;
3597 wxMenu *nav_menu =
new wxMenu();
3598 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3599 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3600 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3601 nav_menu->AppendSeparator();
3602 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3603 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3604 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3605 nav_menu->AppendSeparator();
3607 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3608 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3610 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3611 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3613 nav_menu->AppendSeparator();
3614 nav_menu->Append(ID_MENU_SCALE_IN,
3615 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3616 nav_menu->Append(ID_MENU_SCALE_OUT,
3617 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3619 nav_menu->AppendSeparator();
3620 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3622 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3624 wxMenu *view_menu =
new wxMenu();
3626 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3627 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3628 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3629 _menuText(_(
"Show Chart Outlines"),
"O"));
3631 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3632 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3633 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3634 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3636 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3637 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3639 view_menu->AppendSeparator();
3641 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3642 _menuText(_(
"Show ENC text"),
"T"));
3643 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3644 _menuText(_(
"Show ENC Lights"),
"L"));
3645 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3646 _menuText(_(
"Show ENC Soundings"),
"S"));
3647 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3648 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3649 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3650 _menuText(_(
"Show ENC Data Quality"),
"U"));
3651 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3652 _menuText(_(
"Show Navobjects"),
"V"));
3654 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3655 _menuText(_(
"Show ENC text"),
"Alt-T"));
3656 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3657 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3658 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3659 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3660 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3661 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3662 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3663 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3664 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3665 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3667 view_menu->AppendSeparator();
3668 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3669 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3670 view_menu->AppendSeparator();
3672 view_menu->Append(ID_MENU_UI_COLSCHEME,
3673 _menuText(_(
"Change Color Scheme"),
"C"));
3675 view_menu->Append(ID_MENU_UI_COLSCHEME,
3676 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3679 view_menu->AppendSeparator();
3681 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3682 _menuText(_(
"Toggle Full Screen"),
"F11"));
3684 m_pMenuBar->Append(view_menu, _(
"&View"));
3686 wxMenu *ais_menu =
new wxMenu();
3687 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3688 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3689 _(
"Attenuate less critical AIS targets"));
3690 ais_menu->AppendSeparator();
3691 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3692 _(
"Hide Moored AIS Targets"));
3693 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3694 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3695 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3698 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3699 _menuText(_(
"Show CPA Warnings"),
"W"));
3701 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3702 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3705 ais_menu->AppendSeparator();
3706 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3707 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3709 wxMenu *tools_menu =
new wxMenu();
3711 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3712 _menuText(_(
"Data Monitor"),
"E"));
3713 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3714 _menuText(_(
"Measure Distance"),
"M"));
3716 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3717 _menuText(_(
"Data Monitor"),
"Alt-E"));
3718 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3719 _menuText(_(
"Measure Distance"),
"Alt-M"));
3722 tools_menu->AppendSeparator();
3723 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3724 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3725 tools_menu->AppendSeparator();
3726 tools_menu->Append(ID_MENU_MARK_BOAT,
3727 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3728 tools_menu->Append(ID_MENU_MARK_CURSOR,
3729 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3730 tools_menu->AppendSeparator();
3734 _menuText(_(
"Drop MOB Marker"),
3736 tools_menu->AppendSeparator();
3737 tools_menu->Append(wxID_PREFERENCES,
3738 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3740 tools_menu->Append(ID_MENU_MARK_MOB,
3741 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3742 tools_menu->AppendSeparator();
3743 tools_menu->Append(wxID_PREFERENCES,
3744 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3746 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3749 wxMenu *window_menu =
new wxMenu();
3750 m_pMenuBar->Append(window_menu, _(
"&Window"));
3753 wxMenu *help_menu =
new wxMenu();
3754 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3755 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3756 m_pMenuBar->Append(help_menu, _(
"&Help"));
3759 UpdateGlobalMenuItems();
3760 EnableSettingsTool(g_bDeferredInitDone);
3763void MyFrame::UpdateGlobalMenuItems() {
3764 if (!m_pMenuBar)
return;
3766 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3767 ->Check(GetPrimaryCanvas()->m_bFollow);
3768 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3769 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3770 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3771 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3772 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3773 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3774 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3775 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3776 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3777 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3778 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3779 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3780 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3781 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3782 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3783 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3784 if (g_bAIS_CPA_Alert) {
3785 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3786 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3788 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3789 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3792 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3793 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3794 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3797 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3798 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3799 ->Check(ps52plib->GetShowSoundings());
3801 bool light_state =
false;
3803 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3805 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3806 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3807 light_state = (pOLE->nViz == 1);
3812 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3813 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3817 DisCat nset = ps52plib->GetDisplayCategory();
3818 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3819 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3820 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3821 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3822 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3823 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3824 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3826 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3827 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3828 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3833void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3834 if (!m_pMenuBar)
return;
3836 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3838 if (cc->GetUpMode() == NORTH_UP_MODE)
3839 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3840 else if (cc->GetUpMode() == COURSE_UP_MODE)
3841 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3843 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3845 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3846 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3847 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3848 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3849 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3850 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3851 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3852 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3853 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3854 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3855 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3856 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3857 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3858 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3859 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3862 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3863 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3866 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3868 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3869 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3874 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3878 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3879 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3880 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3881 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3882 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3883 ->Check(cc->GetShowENCDataQual());
3884 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3886 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3887 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3888 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3893void MyFrame::InvalidateAllCanvasUndo() {
3895 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3897 if (cc) cc->undo->InvalidateUndo();
3901void MyFrame::SubmergeAllCanvasToolbars() {
3903 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3905 if (cc) cc->SubmergeToolbar();
3909void MyFrame::SurfaceAllCanvasToolbars() {
3910 if (g_bshowToolbar) {
3912 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3914 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3921void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3923 if (lon > 180.0) lon -= 360.0;
3928 cc->JumpToPosition(lat, lon,
scale);
3931 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3935void MyFrame::UpdateCanvasConfigDescriptors() {
3937 for (
unsigned int i = 0;
3938 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3939 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3947 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3948 cc->GroupID = chart->m_groupIndex;
3951 cc->
bQuilt = chart->GetQuiltMode();
3957 cc->bEnableBasemapTile = chart->GetbEnableBasemapTile();
3959 cc->
bFollow = chart->m_bFollow;
3964 int upmode = chart->GetUpMode();
3965 if (upmode == COURSE_UP_MODE)
3967 else if (upmode == HEAD_UP_MODE)
3974void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3975 if (!RBBox.GetValid())
return;
3977 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3978 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3981 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3982 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3990 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3991 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3993 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3994 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3996 cc->GetSize(&ww, &wh);
3998 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
4000 ppm = wxMin(ppm, 1.0);
4006void MyFrame::PrepareOptionsClose(
options *settings,
4007 int settings_return_value) {
4009 options_lastPage = settings->lastPage;
4014 if (options_lastPage == 1) options_lastPage = 0;
4016 options_subpage = settings->lastSubPage;
4017 options_lastWindowPos = settings->lastWindowPos;
4018 options_lastWindowSize = settings->lastWindowSize;
4021 androidEnableBackButton(
true);
4022 androidEnableOptionsMenu(
true);
4023 androidRestoreFullScreen();
4024 androidEnableRotation();
4027 EnableSettingsTool(
true);
4030void MyFrame::DoOptionsDialog() {
4031 EnableSettingsTool(
false);
4034 AbstractPlatform::ShowBusySpinner();
4037 pConfig->SetPath(
"/Settings");
4038 pConfig->Read(
"OptionsSizeX", &sx, -1);
4039 pConfig->Read(
"OptionsSizeY", &sy, -1);
4041 wxWindow *optionsParent =
this;
4043 optionsParent = GetPrimaryCanvas();
4046 callbacks.prepare_close = [&](
options *me,
int changes) {
4047 PrepareOptionsClose(me, changes);
4049 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4050 ProcessOptionsDialog(changes, workdir_list);
4053 wxPoint(-1, -1), wxSize(sx, sy));
4055 AbstractPlatform::HideBusySpinner();
4059 g_options->SetInitChartDir(*pInit_Chart_Dir);
4063 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4064 g_options->SetWorkDirListPtr(pWorkDirArray);
4070 prev_locale = g_locale;
4071 g_options->SetInitialPage(options_lastPage, options_subpage);
4074 g_options->lastWindowPos = options_lastWindowPos;
4075 if (options_lastWindowPos != wxPoint(0, 0)) {
4077 g_options->SetSize(options_lastWindowSize);
4081 if (options_lastWindowSize != wxSize(0, 0)) {
4082 g_options->SetSize(options_lastWindowSize);
4087 androidEnableBackButton(
false);
4088 androidEnableOptionsMenu(
false);
4089 androidDisableFullScreen();
4097 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4100 wxString chart_file_name;
4101 if (cc->GetQuiltMode()) {
4102 int dbi = cc->GetQuiltRefChartdbIndex();
4103 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4105 if (cc->m_singleChart)
4106 chart_file_name = cc->m_singleChart->GetFullPath();
4109 pathArray.Add(chart_file_name);
4115 last_canvasConfig = g_canvasConfig;
4118 g_last_ChartScaleFactor = g_ChartScaleFactor;
4124void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4125 bool b_need_refresh =
false;
4128 if ((rr & VISIT_CHARTS) &&
4129 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4131 UpdateChartDatabaseInplace(*pNewDirArray,
4132 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4135 b_need_refresh =
true;
4140 if (rr & STYLE_CHANGED) {
4143 _(
"Please restart OpenCPN to activate language or style changes."),
4144 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4147 bool charts_updating =
4148 (rr & VISIT_CHARTS) && ((rr & CHANGE_CHARTS) || (rr & SCAN_UPDATE));
4149 if (!charts_updating) RefreshGroupIndices();
4151 if (rr & TIDES_CHANGED) {
4157 if (rr & S52_CHANGED) {
4158 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4169 g_Platform->GetDisplayDPmm());
4172 double stuffcog = NAN;
4173 double stuffsog = NAN;
4174 if (!std::isnan(
gCog)) stuffcog =
gCog;
4175 if (!std::isnan(
gSog)) stuffsog =
gSog;
4177 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
4178 COGFilterTable[i] = stuffcog;
4179 SOGFilterTable[i] = stuffsog;
4182 SetChartUpdatePeriod();
4184 if (rr & GL_CHANGED) {
4188 b_need_refresh =
true;
4191 if (rr & S52_CHANGED) {
4192 b_need_refresh =
true;
4196 if (rr & REBUILD_RASTER_CACHE) {
4198 GetPrimaryCanvas()->Disable();
4200 GetPrimaryCanvas()->Enable();
4205 if (g_config_display_size_manual &&
4213 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4220 int rrt = rr & S52_CHANGED;
4222 (rrt == S52_CHANGED) ||
4223 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4233 ps52plib->SetScaleFactorExp(
4234 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4235 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4239 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4241 if (cc) cc->ApplyGlobalSettings();
4249 if (!charts_updating) {
4250 bool ztc = g_bEnableZoomToCursor;
4251 g_bEnableZoomToCursor =
false;
4253 if (!GetPrimaryCanvas()->IsFrozen())
4255 g_bEnableZoomToCursor = ztc;
4260 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4269 SetGPSCompassScale();
4271 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4274 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4275 if (!charts_updating) cc->UpdateCanvasControlBar();
4278 UpdateGPSCompassStatusBoxes();
4280 SetAllToolbarScale();
4281 RequestNewToolbars();
4283 if ((rr & MENU_CHANGED) == MENU_CHANGED) BuildMenuBar();
4286 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4289 cc->RebuildCursors();
4294 bool b_masterScaleChange =
false;
4296 (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f))
4297 b_masterScaleChange =
true;
4299 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4300 RequestNewMasterToolbar(
true);
4302 bool bMuiChange =
false;
4308 if (b_masterScaleChange || bMuiChange) {
4310 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4313 cc->ProcessNewGUIScale();
4319 if (rr & LOCALE_CHANGED) {
4320 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4322 rr |= NEED_NEW_OPTIONS;
4331 g_last_ChartScaleFactor = g_ChartScaleFactor;
4334 ValidateColorScheme();
4335 SetAndApplyColorScheme(global_color_scheme);
4340void MyFrame::ValidateColorScheme() {
4342 if (g_hicon_colors) {
4343 if ((global_color_scheme != GLOBAL_COLOR_SCHEME_DAY_HICON) &&
4344 (global_color_scheme != GLOBAL_COLOR_SCHEME_NIGHT_HICON))
4345 global_color_scheme = GLOBAL_COLOR_SCHEME_DAY_HICON;
4347 if ((global_color_scheme != GLOBAL_COLOR_SCHEME_DAY) &&
4348 (global_color_scheme != GLOBAL_COLOR_SCHEME_NIGHT) &&
4349 (global_color_scheme != GLOBAL_COLOR_SCHEME_DUSK))
4350 global_color_scheme = GLOBAL_COLOR_SCHEME_DAY;
4354bool MyFrame::CheckGroup(
int igroup) {
4355 if (igroup == 0)
return true;
4359 if (!pGroup->m_element_array.size())
4362 for (
const auto &elem : pGroup->m_element_array) {
4363 for (
unsigned int ic = 0;
4364 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4365 auto &cte =
ChartData->GetChartTableEntry(ic);
4366 wxString chart_full_path(cte.GetpFullPath(), wxConvUTF8);
4368 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4375bool MyFrame::ScrubGroupArray() {
4380 bool b_change =
false;
4381 unsigned int igroup = 0;
4382 while (igroup < g_pGroupArray->GetCount()) {
4383 bool b_chart_in_element =
false;
4386 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4387 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4389 for (
unsigned int ic = 0;
4390 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4391 auto &cte =
ChartData->GetChartTableEntry(ic);
4392 wxString chart_full_path = cte.GetFullSystemPath();
4394 if (chart_full_path.StartsWith(element_root)) {
4395 b_chart_in_element =
true;
4401 if (!b_chart_in_element) {
4402 wxString test_string =
"GSHH";
4403 if (element_root.Upper().Contains(test_string))
4404 b_chart_in_element =
true;
4407 if (!b_chart_in_element)
4409 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4421void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4423 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4425 if (cc && (cc != ccThis)) cc->Refresh();
4430void MyFrame::ChartsRefresh() {
4433 AbstractPlatform::ShowBusySpinner();
4435 bool b_run = FrameTimer1.IsRunning();
4438 FrameTenHzTimer.Stop();
4441 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4444 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4445 if (cc->GetQuiltMode()) {
4446 currentIndex = cc->GetQuiltReferenceChartIndex();
4448 cc->canvasChartsRefresh(currentIndex);
4452 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4453 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4455 AbstractPlatform::HideBusySpinner();
4458void MyFrame::InvalidateAllQuilts() {
4459 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4462 cc->InvalidateQuilt();
4463 cc->SetQuiltRefChart(-1);
4464 cc->m_singleChart = NULL;
4469bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4471 const wxString &ChartListFileName) {
4472 bool b_run = FrameTimer1.IsRunning();
4474 FrameTenHzTimer.Stop();
4476 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4477 FrameCOGTimer.Stop();
4480 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4483 cc->InvalidateQuilt();
4484 cc->SetQuiltRefChart(-1);
4485 cc->m_singleChart = NULL;
4495 AbstractPlatform::ShowBusySpinner();
4498 wxString longmsg = _(
"OpenCPN Chart Update");
4500 ".................................................................."
4503 Updateprog =
new wxGenericProgressDialog();
4506 Updateprog->SetFont(*qFont);
4508 Updateprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4509 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4510 wxPD_REMAINING_TIME);
4512 DimeControl(Updateprog);
4517 wxLogMessage(
"Starting chart database Update...");
4521 m_gshhg_chart_loc = gWorldMapLocation;
4522 gWorldMapLocation = wxEmptyString;
4526 AbstractPlatform::HideBusySpinner();
4530void MyFrame::FinalizeChartDBUpdate() {
4532 if (!g_bDeferredInitDone) {
4534 InitTimer.Start(100, wxTIMER_ONE_SHOT);
4537 bool b_groupchange = ScrubGroupArray();
4539 RefreshGroupIndices();
4541 if (b_groupchange) {
4542 pConfig->DestroyConfigGroups();
4547 if (g_bDeferredInitDone) ScheduleReloadCharts();
4552 cc->ToggleCanvasQuiltMode();
4554 bool cur_mode = cc->GetQuiltMode();
4556 if( !cc->GetQuiltMode() )
4557 cc->SetQuiltMode(
true );
4559 if( cc->GetQuiltMode() ) {
4560 cc->SetQuiltMode(
false );
4561 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4565 if( cur_mode != cc->GetQuiltMode() ){
4571 g_bQuiltEnable = cc->GetQuiltMode();
4575 ps52plib->GenerateStateHash();
4583 DoStackDelta(cc, -1);
4589 DoStackDelta(cc, 1);
4592void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4594void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4596void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4598 cc->DoCanvasStackDelta(direction);
4602void MyFrame::PositionIENCToolbar() {
4606 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4608 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4616void MyFrame::OnInitTimer(wxTimerEvent &event) {
4619 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4623 wxLog::FlushActive();
4625 switch (m_iInitCount++) {
4627 EnableSettingsTool(
false);
4632 if (g_bInlandEcdis) {
4633 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4634 double range_set = 500.;
4636 range = wxRound(range * 10) / 10.;
4640 else if (range > 2000.)
4642 else if (range > 1600.)
4644 else if (range > 1200.)
4646 else if (range > 800.)
4651 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4655 g_Platform->SetFullscreen(g_bFullscreen);
4659 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4662 cc->SetGroupIndex(0,
false);
4668 const bool update_started = StartRebuildChartDatabase();
4670 if (update_started) {
4682 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4696 3 * GetCharHeight());
4698 m_data_monitor->Center();
4706 pConfig->SetPath(
"/Settings");
4707 pConfig->Read(
"OptionsSizeX", &sx, -1);
4708 pConfig->Read(
"OptionsSizeY", &sy, -1);
4710 wxWindow *optionsParent =
this;
4712 optionsParent = GetPrimaryCanvas();
4714 BuildiENCToolbar(
true, m_toolbar_callbacks);
4721 if (!g_params.empty()) {
4722 for (
size_t n = 0; n < g_params.size(); n++) {
4723 wxString path = g_params[n];
4724 if (::wxFileExists(path)) {
4726 pSet->load_file(path.fn_str());
4729 pSet->LoadAllGPXObjects(
4730 !pSet->IsOpenCPN(), wpt_dups,
4732 LLBBox box = pSet->GetBBox();
4733 if (box.GetValid()) {
4734 CenterView(GetPrimaryCanvas(), box);
4743 InitAppMsgBusListener();
4748 auto loader = PluginLoader::GetInstance();
4749 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4750 if (!b_haveWMM)
gVar = g_UserVar;
4758 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4761 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4763 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4766 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4770 NavObj_dB::GetInstance().FullSchemaMigrate(
this);
4771 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4772 NavObj_dB::GetInstance().LoadNavObjects();
4775 if (!g_AW1GUID.IsEmpty()) {
4778 if (!g_AW2GUID.IsEmpty()) {
4784 appendOSDirSlash(&layerdir);
4785 layerdir.Append(
"layers");
4787 if (wxDir::Exists(layerdir)) {
4789 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4790 wxLogMessage(laymsg);
4791 pConfig->LoadLayers(layerdir);
4796 if (!g_kiosk_startup) {
4797 AbstractPlatform::ShowBusySpinner();
4800 pConfig->SetPath(
"/Settings");
4801 pConfig->Read(
"OptionsSizeX", &sx, -1);
4802 pConfig->Read(
"OptionsSizeY", &sy, -1);
4804 wxWindow *optionsParent =
this;
4806 optionsParent = GetPrimaryCanvas();
4809 callbacks.prepare_close = [&](
options *me,
int changes) {
4810 PrepareOptionsClose(me, changes);
4812 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4813 ProcessOptionsDialog(changes, workdir_list);
4816 wxPoint(-1, -1), wxSize(sx, sy));
4817 AbstractPlatform::HideBusySpinner();
4824 wxLogMessage(
"OnInitTimer...Last Call");
4828 RequestNewMasterToolbar();
4830 PositionIENCToolbar();
4832 g_bDeferredInitDone =
true;
4842 GetPrimaryCanvas()->SetFocus();
4843 GetPrimaryCanvas()->Enable();
4846 if (b_reloadForPlugins) {
4852 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4854 if (cc) cc->SetFirstAuto(
true);
4862 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4864 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4868 cc->CheckGroupValid();
4869 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4870 cc->SetShowGPSCompassWindow(
true);
4875 androidEnableBackButton(
true);
4876 androidEnableRotation();
4877 androidEnableOptionItems(
true);
4881 if (g_start_fullscreen && !IsFullScreen()) ToggleFullScreen();
4887 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4889 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4891 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4897 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4899 wxLog::FlushActive();
4901 RefreshAllCanvas(
true);
4902 UsbWatchDaemon::GetInstance().Start();
4903 EnableSettingsTool(g_bDeferredInitDone);
4909void MyFrame::InitAppMsgBusListener() {
4910 auto &msgbus = AppMsgBus::GetInstance();
4913 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4914 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4918 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4919 HandleBasicNavMsg(basicnav_msg);
4923 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4924 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4928 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4929 HandleGPSWatchdogMsg(msg);
4936void MyFrame::ReleaseApiListeners() {}
4941 m_on_raise_listener.Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4942 m_on_quit_listener.Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4943 server.SetGetRestApiEndpointCb([&] {
return m_rest_server.
GetEndpoint(); });
4944 server.open_file_cb = [&](
const std::string &path) {
4945 return m_open_gpx_file(path);
4952void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4953 if (msg->gps_watchdog <= 0) {
4954 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4958 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4963 if (m_fix_start_time.IsValid()) {
4964 wxDateTime now = wxDateTime::Now();
4965 wxTimeSpan span = now - m_fix_start_time;
4966 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4967 auto ¬eman = NotificationManager::GetInstance();
4968 wxString msg = _(
"GNSS Position fix lost");
4969 noteman.AddNotification(NotificationSeverity::kCritical,
4971 m_fix_start_time = wxInvalidDateTime;
4975 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4976 bool last_bVelocityValid = bVelocityValid;
4977 bVelocityValid =
false;
4984void MyFrame::CalculateCOGAverage() {
4986 if (!std::isnan(
gCog)) {
4989 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4992 double sum = 0., count = 0;
4994 double adder = COGTable[i];
4995 if (std::isnan(adder))
continue;
4997 if (fabs(adder -
g_COGAvg) > 180.) {
5011 else if (sum >= 360.)
5020void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
5021 m_fixtime = msg->time;
5022 double hdt_data_interval = 0;
5023 double fix_time_interval = 0;
5025 double msgtime = msg->set_time.tv_sec;
5026 double m1 = msg->set_time.tv_nsec / 1e9;
5029 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
5030 ((msg->vflag & POS_VALID) == POS_VALID)) {
5032 if (!m_fix_start_time.IsValid()) {
5033 m_fix_start_time = wxDateTime::Now();
5038 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
5041 fix_time_gt_last = fix_time_gt;
5042 uint64_t fix_time_gt_now =
5043 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5044 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5048 double implied_sog = dist / (fix_time_interval / 3600);
5053 gLat_gt_m1 = gLat_gt;
5054 gLon_gt_m1 = gLon_gt;
5058 fix_time_gt = fix_time_gt_now;
5062 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5063 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5064 gCog_gt_m1 = gCog_gt;
5074 if (!std::isnan(gCog_gt_m1)) {
5076 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5083 if ((fix_time_gt - fix_time_gt_last) > .08) {
5088 if (gCog_gt > gCog_gt_m1) {
5089 if ((gCog_gt - gCog_gt_m1) > 180.)
5094 if ((gCog_gt_m1 - gCog_gt) > 180.)
5099 difft = fabs(gCog_gt - gCog_gt_m1);
5100 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5108 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5109 tentative_cog_rate_gt *= 1e9;
5110 cog_rate_gt = tentative_cog_rate_gt;
5118 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5121static double hdt_avg;
5122 double hdt_norm =
gHdt;
5123 if(
gHdt > 180) hdt_norm -= 360;
5126 hdt_avg += hdt_norm * 0.1;
5131 if (!std::isnan(
gHdt)) {
5133 uint64_t hdt_time_gt_last = hdt_time_gt;
5134 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5135 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5138 if (hdt_data_interval > .09) {
5140 gHdt_gt_m1 = gHdt_gt;
5143 if (!std::isnan(gHdt_gt_m1)) {
5145 double tentative_hdt_rate_gt =
5146 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5147 tentative_hdt_rate_gt *= 1e9;
5149 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5150 hdt_rate_gt = tentative_hdt_rate_gt;
5158 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5161 CalculateCOGAverage();
5169 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5170 if ((msg->vflag & POS_VALID) == POS_VALID)
5175 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5177 bVelocityValid =
true;
5181void MyFrame::UpdateStatusBar() {
5184 unsigned long uiCurrentTickCount;
5185 m_MMEAeventTime.SetToCurrent();
5186 uiCurrentTickCount =
5187 m_MMEAeventTime.GetMillisecond() / 100;
5188 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5189 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5190 m_ulLastNMEATicktime = uiCurrentTickCount;
5192 if (m_tick_idx++ > 6) m_tick_idx = 0;
5197 if (NULL != GetStatusBar()) {
5200 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5203 wxString s1(tick_buf, wxConvUTF8);
5205 s1 += toSDMM(1,
gLat);
5207 s1 += toSDMM(2,
gLon);
5209 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5213 if (!std::isnan(
gSog))
5214 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5216 sogcog.Printf(
"SOG --- ");
5220 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5222 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5224 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5225 (
int)toMagnetic(
gCog), 0x00B0);
5227 cogs.Printf((
"COG ---%c"), 0x00B0);
5229 sogcog.Append(cogs);
5230 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5235void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5236 MemFootTimer.Stop();
5238 int memsize = GetApplicationMemoryUse();
5241 printf(
"Memsize: %d \n", memsize);
5244 if (memsize > (g_MemFootMB * 1000)) {
5248 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5249 unsigned int nCache = pCache->GetCount();
5252 for (
unsigned int i = 0; i < nCache; i++) {
5262 for (
unsigned int i = 0; i < nCache - 1; i++) {
5263 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5265 pcea[i] = pcea[i + 1];
5276 unsigned int idelete = 0;
5277 unsigned int idelete_max = pCache->GetCount();
5280 unsigned int minimum_cache = 1;
5281 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5283 while ((memsize > (g_MemFootMB * 1000)) &&
5284 (pCache->GetCount() > minimum_cache) &&
5285 (idelete < idelete_max)) {
5286 int memsizeb = memsize;
5290 memsize = GetApplicationMemoryUse();
5291 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5299 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5304void MyFrame::ProcessUnitTest() {
5305 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5312 cc->m_bFollow =
false;
5314 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5315 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5318 if (cc->m_groupIndex > 0) {
5319 while (ut_index < ChartData->GetChartTableEntries() &&
5320 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5324 if (ut_index < ChartData->GetChartTableEntries()) {
5328 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5329 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5336 if (cc->GetQuiltMode()) {
5337 if (cc->IsChartQuiltableRef(ut_index))
5338 cc->SelectQuiltRefdbChart(ut_index);
5340 cc->SelectdbChart(ut_index);
5343 if (g_unit_test_1) {
5351 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5352 cte->GetLatMin(), cte->GetLonMax(), NULL,
5356 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5357 cte->GetLatMax(), cte->GetLonMin(), NULL,
5360 cc->GetSize(&ww, &wh);
5361 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5363 ppm = wxMin(ppm, 1.0);
5370 if (ut_index > ut_index_max) exit(0);
5381 bool b_rotate =
false;
5383 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5386 if (!b_rotate && !g_btenhertz)
return;
5388 bool b_update =
false;
5390 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5393 struct timespec now;
5394 clock_gettime(CLOCK_MONOTONIC, &now);
5395 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5396 double diffc = diff / 1e9;
5399 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5400 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5401 if (gCog_tentative < 0.) gCog_tentative += 360.;
5402 gCog = gCog_tentative;
5406 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5407 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5408 double diffc = diff / 1e9;
5409 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5413 if (gSog_gt && !std::isnan(gCog_gt)) {
5414 double delta_t = diffc / 3600;
5415 double distance = gSog_gt * delta_t;
5418 double angr = gCog_gt / 180 * M_PI;
5419 double latr = gLat_gt * M_PI / 180;
5420 double D = distance / 3443;
5421 double sD = sin(D), cD = cos(D);
5422 double sy = sin(latr), cy = cos(latr);
5423 double sa = sin(angr), ca = cos(angr);
5425 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5426 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5436 if (cc) cc->DoCanvasCOGSet();
5445 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5446 bool bnew = cc->DoCanvasUpdate();
5447 if (!bnew) cc->UpdateShips();
5456 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5459bool MyFrame::ProcessQuitFlag() {
5463 FrameTenHzTimer.Stop();
5465 wxWindow *top = wxTheApp ? wxTheApp->GetTopWindow() :
nullptr;
5466 if (top) top->Close(
true);
5473void MyFrame::ProcessDeferredTrackOn() {
5476 if (g_bDeferredStartTrack) {
5477 if (!g_bTrackActive) {
5480 g_bDeferredStartTrack =
false;
5483 g_bDeferredStartTrack =
false;
5488void MyFrame::ProcessAnchorWatch() {
5496 double d = g_nAWMax;
5499 bool toofar =
false;
5500 bool tooclose =
false;
5501 if (d >= 0.0) toofar = (dist * 1852. > d);
5502 if (d < 0.0) tooclose = (dist * 1852 < -d);
5504 if (tooclose || toofar)
5505 AnchorAlertOn1 =
true;
5507 AnchorAlertOn1 =
false;
5509 AnchorAlertOn1 =
false;
5517 double d = g_nAWMax;
5520 bool toofar =
false;
5521 bool tooclose =
false;
5522 if (d >= 0) toofar = (dist * 1852. > d);
5523 if (d < 0) tooclose = (dist * 1852 < -d);
5525 if (tooclose || toofar)
5526 AnchorAlertOn2 =
true;
5528 AnchorAlertOn2 =
false;
5530 AnchorAlertOn2 =
false;
5533 AnchorAlertOn1 =
true;
5536void MyFrame::SendFixToPlugins() {
5547 GPSData.
nSats = g_SatsInView;
5549 wxDateTime tCheck((time_t)m_fixtime);
5550 if (tCheck.IsValid()) {
5559 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5562 SendPositionFixToAllPlugIns(&GPSData);
5566void MyFrame::ProcessLogAndBells() {
5569 wxDateTime lognow = wxDateTime::Now();
5570 int hourLOC = lognow.GetHour();
5571 int minuteLOC = lognow.GetMinute();
5573 int minuteUTC = lognow.GetMinute();
5574 int second = lognow.GetSecond();
5576 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5577 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5578 (minuteUTC == 30)) {
5579 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5580 wxString day = lognow.FormatISODate();
5581 wxString utc = lognow.FormatISOTime();
5582 wxString navmsg =
"LOGBOOK: ";
5590 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5594 if (std::isnan(
gCog))
5595 cog.Printf(
"COG ----- ");
5597 cog.Printf(
"COG %10.5f ",
gCog);
5600 if (std::isnan(
gSog))
5601 sog.Printf(
"SOG ----- ");
5603 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5609 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5612 wxLogMessage(navmsg);
5613 g_loglast_time = lognow;
5615 int bells = (hourLOC % 4) * 2;
5616 if (minuteLOC != 0) bells++;
5617 if (!bells) bells = 8;
5619 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5620 m_BellsToPlay = bells;
5621 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5622 wxPostEvent(
this, ev);
5631 if (ProcessQuitFlag())
return;
5633 if (bDBUpdateInProgress)
return;
5636 FrameTenHzTimer.Stop();
5638 ProcessDeferredTrackOn();
5640 ProcessAnchorWatch();
5641 ProcessLogAndBells();
5643 if (ShouldRestartTrack()) TrackDailyRestart();
5646 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5647 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5648 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5654 if (
gSog > 3.0) g_bCruising =
true;
5660 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5662 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5668 bool bnew_view =
false;
5669 if (!g_btenhertz) bnew_view = DoChartUpdate();
5676 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5679 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5682 cc->DrawBlinkObjects();
5685 if (bactiveRouteUpdate) {
5692 cc->SetOwnShipState(SHIP_NORMAL);
5694 if (cc->GetQuiltMode()) {
5695 double erf = cc->GetQuiltMaxErrorFactor();
5696 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5698 if (cc->m_singleChart) {
5699 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5700 cc->SetOwnShipState(SHIP_LOWACCURACY);
5704 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5707 (bVelocityValid != m_last_bVelocityValid) ||
5708 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5709 if (!g_bopengl) cc->UpdateShips();
5717 m_last_bVelocityValid = bVelocityValid;
5722 bool brq_dynamic =
false;
5724 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5725 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5727 if (pic->m_enabled && pic->m_init_state) {
5728 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5735 if (brq_dynamic) bnew_view =
true;
5739 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5742 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5747 if (cc->GetglCanvas()) {
5749 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5751 if ((!g_btenhertz)) {
5752 if (cc->m_bFollow) {
5753 cc->DoCanvasUpdate();
5770 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5784 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5785 g_pais_query_dialog_active->UpdateText();
5788 if (g_pAISTargetList && (0 == (g_tick % (5))))
5789 g_pAISTargetList->UpdateAISTargetList();
5792 UpdateGPSCompassStatusBoxes();
5797 console->RefreshConsoleData();
5804 if (m_bdefer_resize) {
5805 if (0 == (g_tick % (5))) {
5806 printf(
"___RESIZE\n");
5807 SetSize(m_defer_size);
5809 m_bdefer_resize =
false;
5816 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5818 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5819 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5823double MyFrame::GetMag(
double a,
double lat,
double lon) {
5824 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5825 auto loader = PluginLoader::GetInstance();
5826 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5833 wxDateTime now = wxDateTime::Now();
5834 SendJSON_WMM_Var_Request(lat, lon, now);
5835 if (fabs(gQueryVar) < 360.0)
5836 Variance = gQueryVar;
5838 return toMagnetic(a, Variance);
5841bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5847 v[
"Year"] = date.GetYear();
5848 v[
"Month"] = date.GetMonth();
5849 v[
"Day"] = date.GetDay();
5851 SendJsonMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5857void MyFrame::TouchAISActive() {
5859 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5861 if (cc) cc->TouchAISToolActive();
5865void MyFrame::UpdateAISTool() {
5869 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5871 if (cc) cc->UpdateAISTBTool();
5876void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5878 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5880 if (cc) cc->SetbTCUpdate(
true);
5883 RefreshAllCanvas(
false);
5888void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5892 bool b_rotate =
false;
5893 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5895 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5899 FrameCOGTimer.Stop();
5906 int period_ms = 100;
5908 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5911void MyFrame::DoCOGSet() {
5913 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5915 if (cc) cc->DoCanvasCOGSet();
5919void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5925 wxFont oldfont = pdc->GetFont();
5927 pdc->SetFont(*pFont);
5928 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5929 pdc->SetBackgroundMode(wxTRANSPARENT);
5931 pdc->DrawText(str, x, y + 1);
5932 pdc->DrawText(str, x, y - 1);
5933 pdc->DrawText(str, x + 1, y);
5934 pdc->DrawText(str, x - 1, y);
5936 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5938 pdc->DrawText(str, x, y);
5940 pdc->SetFont(oldfont);
5944void MyFrame::UpdateRotationState(
double rotation) {
5946 g_bCourseUp =
false;
5948 if (fabs(rotation) > .001) {
5949 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5950 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5952 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5955 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5956 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5958 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5962 UpdateGPSCompassStatusBoxes(
true);
5966void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5968 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5970 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5976int MyFrame::GetApplicationMemoryUse() {
5982 wxWindow *fWin = wxWindow::FindFocus();
5984 wxArrayString outputArray;
5985 wxString cmd(
"ps --no-headers -o vsize ");
5986 unsigned long pid = wxGetProcessId();
5988 cmd1.Printf(
"%ld", pid);
5990 wxExecute(cmd, outputArray);
5992 if (outputArray.GetCount()) {
5993 wxString s = outputArray.Item(0);
5995 if (s.ToLong(&vtmp)) memsize = vtmp;
5998 if (fWin) fWin->SetFocus();
6004 PROCESS_MEMORY_COUNTERS pmc;
6006 unsigned long processID = wxGetProcessId();
6008 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6010 if (NULL == hProcess)
return 0;
6012 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6030 memsize = pmc.WorkingSetSize / 1024;
6033 CloseHandle(hProcess);
6040double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6041 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6044void MyFrame::SetChartUpdatePeriod() {
6047 g_ChartUpdatePeriod = 0;
6052 bool bskewdc =
false;
6053 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6056 if (!g_bopengl && !cc->GetVP().b_quilt) {
6057 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6059 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6063 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6065 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6070 cc->UpdateCanvasControlBar();
6073void MyFrame::selectChartDisplay(
int type,
int family) {
6075 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6077 if (cc) cc->selectCanvasChartDisplay(type, family);
6080 UpdateGlobalMenuItems();
6089bool MyFrame::DoChartUpdate() {
6090 bool return_val =
false;
6093 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6095 if (cc) return_val |= cc->DoCanvasUpdate();
6101void MyFrame::MouseEvent(wxMouseEvent &event) {
6103 event.GetPosition(&x, &y);
6108#include <mach/mach.h>
6109#include <mach/message.h>
6110#include <mach/kern_return.h>
6111#include <mach/task_info.h>
6113#include <malloc/malloc.h>
6120#if defined(__linux__)
6121#include "sys/types.h"
6122#include "sys/sysinfo.h"
6125void MyFrame::DoPrint(
void) {
6127 g_PrintingInProgress =
true;
6130 GetPrimaryCanvas()->GetglCanvas()->Render();
6131 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6141 printer.Initialize(wxLANDSCAPE);
6142 printer.EnablePageNumbers(
false);
6145 bool tooltips_were_enabled = DisableTbarTooltips();
6146 printer.Print(
this, &printout);
6147 if (tooltips_were_enabled) {
6148 EnableTbarTooltips();
6167 g_PrintingInProgress =
false;
6170 GetPrimaryCanvas()->SetFocus();
6176 wxString message_ID =
event.GetID();
6177 wxString message_JSONText =
event.GetJSONText();
6185 if (message_ID ==
"WMM_VARIATION_BOAT") {
6186 nlohmann::json root;
6188 root = nlohmann::json::parse(message_JSONText);
6189 }
catch (nlohmann::json::exception &) {
6194 gVar = root[
"Decl"].get<
double>();
6195 }
catch (nlohmann::json::exception &) {
6201 if (message_ID ==
"WMM_VARIATION") {
6202 nlohmann::json root;
6204 root = nlohmann::json::parse(message_JSONText);
6205 }
catch (nlohmann::json::exception &) {
6209 double decl_val = 0.0;
6210 if (root[
"Decl"].is_number()) {
6211 decl_val = root[
"Decl"].get<
double>();
6212 }
else if (root[
"Decl"].is_string()) {
6213 decl_val = std::stod(root[
"Decl"].get<std::string>());
6216 gQueryVar = decl_val;
6219 if (message_ID ==
"GRIB_TIMELINE") {
6222 v = nlohmann::json::parse(message_JSONText);
6223 }
catch (nlohmann::json::exception &) {
6224 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6227 wxDateTime oldTimeSource = gTimeSource;
6229 if (v[
"Day"].get<int>() == -1) {
6230 gTimeSource = wxInvalidDateTime;
6231 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6233 gTimeSource.Set(v[
"Day"].get<int>(),
6234 (wxDateTime::Month)v[
"Month"].get<int>(),
6235 v[
"Year"].get<int>(), v[
"Hour"].get<int>(),
6236 v[
"Minute"].get<int>(), v[
"Second"].get<int>());
6240 if (oldTimeSource != gTimeSource) {
6242 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6244 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6249 cc->pCwin->Refresh(
false);
6255 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6256 nlohmann::json root;
6257 wxString trk_id =
"";
6260 root = nlohmann::json::parse(message_JSONText);
6261 }
catch (nlohmann::json::exception &) {
6264 if (root.contains(
"Track_ID")) trk_id = root[
"Track_ID"].get<std::string>();
6267 v[
"Track_ID"] = trk_id;
6269 wxString name = wxEmptyString;
6270 if (ptrack->m_GUID == trk_id) {
6271 name = ptrack->GetName();
6272 if (name.IsEmpty()) {
6278 name = _(
"(Unnamed Track)");
6285 v[
"TotalNodes"] = ptrack->GetnPoints();
6286 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6288 v[
"lat"] = tp->m_lat;
6289 v[
"lon"] = tp->m_lon;
6292 SendJsonMessageToAllPlugins(
"OCPN_TRACKPOINTS_COORDS", v);
6297 SendJsonMessageToAllPlugins(
"OCPN_TRACKPOINTS_COORDS", v);
6299 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6300 nlohmann::json root;
6303 root = nlohmann::json::parse(message_JSONText);
6304 }
catch (nlohmann::json::exception &) {
6308 if (root.contains(
"GUID")) guid = root[
"GUID"].get<std::string>();
6313 wxString name = wxEmptyString;
6315 if ((*it)->m_GUID == guid) {
6316 name = (*it)->m_RouteNameString;
6317 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6323 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6324 itp != (*it)->pRoutePointList->end(); itp++) {
6325 w[i][
"lat"] = (*itp)->m_lat;
6326 w[i][
"lon"] = (*itp)->m_lon;
6327 w[i][
"Name"] = (*itp)->GetName();
6328 w[i][
"Description"] = (*itp)->GetDescription();
6329 w[i][
"GUID"] = (*itp)->m_GUID;
6330 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6332 auto node = (*itp)->m_HyperlinkList->begin();
6333 if (node != (*itp)->m_HyperlinkList->end()) {
6335 while (node != (*itp)->m_HyperlinkList->end()) {
6337 v[i][
"WPLink" + std::to_string(n)] = httpLink->Link;
6338 v[i][
"WPLinkDesciption" + std::to_string(n++)] =
6339 httpLink->DescrText;
6346 SendJsonMessageToAllPlugins(
"OCPN_ROUTE_RESPONSE", v);
6352 SendJsonMessageToAllPlugins(
"OCPN_ROUTE_RESPONSE", v);
6353 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6354 nlohmann::json root;
6357 root = nlohmann::json::parse(message_JSONText);
6358 }
catch (nlohmann::json::exception &) {
6361 if (root.contains(
"mode")) {
6362 if (root[
"mode"].get<std::string>() ==
"Track") route =
false;
6367 for (RouteList::iterator it =
pRouteList->begin();
6369 wxString name = (*it)->m_RouteNameString;
6370 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6372 v[i][
"error"] =
false;
6373 v[i][
"name"] = name;
6374 v[i][
"GUID"] = (*it)->m_GUID;
6375 v[i][
"active"] = (*it)->IsActive();
6380 wxString name = ptrack->GetName();
6381 if (name.IsEmpty()) {
6387 name = _(
"(Unnamed Track)");
6389 v[i][
"error"] =
false;
6390 v[i][
"name"] = name;
6391 v[i][
"GUID"] = ptrack->m_GUID;
6396 SendJsonMessageToAllPlugins(
"OCPN_ROUTELIST_RESPONSE", v);
6399 v[0][
"error"] =
true;
6400 SendJsonMessageToAllPlugins(
"OCPN_ROUTELIST_RESPONSE", v);
6402 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6404 v[0][
"error"] =
true;
6407 v[0][
"error"] =
false;
6408 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6409 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6410 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6411 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6412 v[0][
"active_waypoint_lat"] =
6414 v[0][
"active_waypoint_lon"] =
6418 SendJsonMessageToAllPlugins(
"OCPN_ACTIVE_ROUTELEG_RESPONSE", v);
6422void MyFrame::FilterCogSog() {
6423 if (g_bfilter_cogsog) {
6425 double cog_last =
gCog;
6428 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6429 COGFilterTable[i] = COGFilterTable[i - 1];
6430 COGFilterTable[0] = cog_last;
6433 if (!std::isnan(cog_last)) {
6435 double sum = 0., count = 0;
6436 for (
int i = 0; i < g_COGFilterSec; i++) {
6437 double adder = COGFilterTable[i];
6438 if (std::isnan(adder))
continue;
6440 if (fabs(adder - cog_last) > 180.) {
6441 if ((adder - cog_last) > 0.)
6454 else if (sum >= 360.)
6461 double sog_last =
gSog;
6464 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6465 SOGFilterTable[i] = SOGFilterTable[i - 1];
6466 SOGFilterTable[0] = sog_last;
6469 if (!std::isnan(
gSog)) {
6470 double sum = 0., count = 0;
6471 for (
int i = 0; i < g_SOGFilterSec; i++) {
6472 if (std::isnan(SOGFilterTable[i]))
continue;
6474 sum += SOGFilterTable[i];
6484void MyFrame::LoadHarmonics() {
6487 ptcmgr->LoadDataSources(TideCurrentDataSet);
6489 bool b_newdataset =
false;
6492 for (
auto a :
ptcmgr->GetDataSet()) {
6493 bool b_foundi =
false;
6494 for (
auto b : TideCurrentDataSet) {
6501 b_newdataset =
true;
6506 for (
auto a : TideCurrentDataSet) {
6507 bool b_foundi =
false;
6508 for (
auto b :
ptcmgr->GetDataSet()) {
6515 b_newdataset =
true;
6520 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6524void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6525 if (!ptarget)
return;
6528 wxDateTime mob_time = wxDateTime::Now();
6529 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6530 mob_label += _(
" on ");
6531 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6534 mob_label, wxEmptyString);
6535 pWP_MOB->SetShared(
true);
6537 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6539 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6541 pWP_MOB->SetUseSca(
false);
6549 wxString(_(
"Own ship")), wxEmptyString);
6551 pWP_MOB->SetUseSca(
false);
6558 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6574 SendJsonMessageToAllPlugins(
"OCPN_MAN_OVERBOARD", v);
6577 if (RouteManagerDialog::getInstanceFlag()) {
6584 RefreshAllCanvas(
false);
6586 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6587 mob_message += _(
" Time: ");
6588 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6589 mob_message += _(
" Ownship Position: ");
6590 mob_message += toSDMM(1,
gLat);
6592 mob_message += toSDMM(2,
gLon);
6593 mob_message += _(
" MOB Position: ");
6594 mob_message += toSDMM(1, ptarget->Lat);
6596 mob_message += toSDMM(2, ptarget->Lon);
6597 wxLogMessage(mob_message);
6600void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6604 OwnPoint->m_lat =
gLat;
6605 OwnPoint->m_lon =
gLon;
6607 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6612 MOB_Point->m_lat = ptarget->Lat;
6613 MOB_Point->m_lon = ptarget->Lon;
6615 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6616 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6618 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6619 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6622 RefreshAllCanvas(
false);
6625 wxDateTime mob_time = wxDateTime::Now();
6627 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6628 mob_message += _(
" Time: ");
6629 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6630 mob_message += _(
" Ownship Position: ");
6631 mob_message += toSDMM(1,
gLat);
6633 mob_message += toSDMM(2,
gLon);
6634 mob_message += _(
" MOB Position: ");
6635 mob_message += toSDMM(1, ptarget->Lat);
6637 mob_message += toSDMM(2, ptarget->Lon);
6639 wxLogMessage(mob_message);
6643void MyFrame::applySettingsString(wxString settings) {
6645 int last_UIScaleFactor = g_GUIScaleFactor;
6646 bool previous_expert = g_bUIexpert;
6647 g_last_ChartScaleFactor = g_ChartScaleFactor;
6648 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6651 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6657 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6659 if (rr & S52_CHANGED) {
6661 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6663 ->ClearCNSYLUPArray();
6664 ps52plib->GenerateStateHash();
6668 ProcessOptionsDialog(rr, pNewDirArray);
6673 bool b_newToolbar =
false;
6675 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6677 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6679 if (rr & TOOLBAR_CHANGED) {
6680 b_newToolbar =
true;
6685 if (previous_expert && !g_bUIexpert) {
6686 androidForceFullRepaint();
6690 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6694 SetGPSCompassScale();
6696 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6698 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6700 UpdateGPSCompassStatusBoxes(
true);
6703 AbstractPlatform::ShowBusySpinner();
6705 SetAllToolbarScale();
6709 AbstractPlatform::HideBusySpinner();
6711 RequestNewMasterToolbar(
true);
6718 UpdateControlBar(GetPrimaryCanvas());
6724 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6727#ifdef wxHAS_POWER_EVENTS
6728void MyFrame::OnSuspending(wxPowerEvent &event) {
6732 wxLogMessage(
"System suspend starting...");
6735void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6738 wxLogMessage(
"System is going to suspend.");
6741void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6744 wxLogMessage(
"System suspend was cancelled.");
6747int g_last_resume_ticks;
6748void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6749 wxDateTime now = wxDateTime::Now();
6750 wxLogMessage(
"System resumed from suspend.");
6752 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6755 wxLogMessage(
"Restarting streams.");
6756 g_last_resume_ticks = now.GetTicks();
6760 g_pMUX->ClearStreams();
6762 g_pMUX->StartAllStreams();
6771 if (IsMaximized()) {
6776 wxSize sz = GetSize();
6777 SetSize(wxSize(sz.x - 1, sz.y));
6789void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6790 bool btbRebuild =
false;
6792 bool b_reshow =
true;
6795 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6796 if ((ff > 0.01f) || bforcenew) {
6806 long orient = g_Platform->GetDefaultToolbarOrientation();
6807 wxWindow *toolbarParent =
this;
6809 toolbarParent = GetPrimaryCanvas();
6811 if (!g_bInlandEcdis)
6812 g_maintoolbar_y = 4;
6814 g_maintoolbar_y = 8 +
g_iENCToolbar->GetToolbarRect().height;
6817 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor,
6818 m_toolbar_callbacks);
6820 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6827 g_bmasterToolbarFull =
true;
6831 CreateMasterToolbar();
6841bool MyFrame::CollapseGlobalToolbar() {
6843 m_nMasterToolCountShown = 1;
6847 g_bmasterToolbarFull =
false;
6863 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6864 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6865 tic->m_bRequired =
true;
6870 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6871 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6875 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6876 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6877 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6882 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6883 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6887 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6888 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6889 _(
"Enable Tracking"),
"MUI_track");
6893 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6894 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6906 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6907 _(
"Print Chart"),
"MUI_print");
6911 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6912 _(
"About OpenCPN"),
"MUI_help");
6916 AddDefaultPositionPlugInTools();
6920 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6921 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6932 ArrayOfPlugInToolbarTools tool_array =
6934 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6936 if (!pttc->b_viz)
continue;
6938 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6941 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6942 if (g_bTrackActive) {
6943 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6950bool MyFrame::CheckAndAddPlugInTool() {
6958 if (!tb)
return false;
6960 int n_tools = tb->GetToolsCount();
6964 ArrayOfPlugInToolbarTools tool_array =
6967 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6969 if (pttc->position == n_tools) {
6970 wxBitmap *ptool_bmp;
6972 switch (global_color_scheme) {
6973 case GLOBAL_COLOR_SCHEME_DAY:
6974 ptool_bmp = pttc->bitmap_day;
6977 case GLOBAL_COLOR_SCHEME_DUSK:
6978 ptool_bmp = pttc->bitmap_dusk;
6980 case GLOBAL_COLOR_SCHEME_NIGHT:
6981 ptool_bmp = pttc->bitmap_night;
6984 ptool_bmp = pttc->bitmap_day;
6989 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
6991 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
6992 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
6993 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
6994 tic->m_bPlugin =
true;
7003 while (CheckAndAddPlugInTool()) {
7009bool MyFrame::AddDefaultPositionPlugInTools() {
7016 ArrayOfPlugInToolbarTools tool_array =
7019 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7023 if (!pttc->b_viz)
continue;
7025 if (pttc->position == -1)
7027 wxBitmap *ptool_bmp;
7029 switch (global_color_scheme) {
7030 case GLOBAL_COLOR_SCHEME_DAY:
7031 ptool_bmp = pttc->bitmap_day;
7033 case GLOBAL_COLOR_SCHEME_DUSK:
7034 ptool_bmp = pttc->bitmap_dusk;
7036 case GLOBAL_COLOR_SCHEME_NIGHT:
7037 ptool_bmp = pttc->bitmap_night;
7040 ptool_bmp = pttc->bitmap_day;
7045 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7047 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7048 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7049 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7050 tic->m_bPlugin =
true;
7069typedef struct _MSW_COLOR_SPEC {
7071 wxString S52_RGB_COLOR;
7075MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7076 {COLOR_MENUTEXT,
"UITX1", 0},
7077 {COLOR_BTNSHADOW,
"UIBCK", 0},
7080void SaveSystemColors() {
7094 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7095 while (pcspec->COLOR_NAME != -1) {
7096 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7101void RestoreSystemColors() {
7102 int element[NCOLORS];
7103 int rgbcolor[NCOLORS];
7106 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7107 while (pcspec->COLOR_NAME != -1) {
7108 element[i] = pcspec->COLOR_NAME;
7109 rgbcolor[i] = pcspec->SysRGB_COLOR;
7114 if (pSetSysColors) {
7115 pSetSysColors(i, (
unsigned long *)&element[0],
7116 (
unsigned long *)&rgbcolor[0]);
7122void SetSystemColors(ColorScheme cs) {
7124 int element[NCOLORS];
7125 int rgbcolor[NCOLORS];
7127 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7128 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7129 while (pcspec->COLOR_NAME != -1) {
7130 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7131 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7132 element[i] = pcspec->COLOR_NAME;
7138 pSetSysColors(i, (
unsigned long *)&element[0],
7139 (
unsigned long *)&rgbcolor[0]);
7143 RestoreSystemColors();
7150static const WORD MAX_CONSOLE_LINES =
7155void RedirectIOToConsole()
7160 wxIntPtr lStdHandle;
7162 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7172 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7173 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7174 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7178 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7179 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7180 fp = _fdopen(hConHandle,
"w");
7182 setvbuf(stdout, NULL, _IONBF, 0);
7186 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7187 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7188 fp = _fdopen(hConHandle,
"r");
7190 setvbuf(stdin, NULL, _IONBF, 0);
7194 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7195 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7196 fp = _fdopen(hConHandle,
"w");
7198 setvbuf(stderr, NULL, _IONBF, 0);
7209 FontMgr::Get().SetLocale(g_locale);
7230 if (g_pais_query_dialog_active) {
7231 g_pais_query_dialog_active->Destroy();
7232 g_pais_query_dialog_active = NULL;
7235 auto alert_dlg_active =
7237 if (alert_dlg_active) {
7238 alert_dlg_active->Destroy();
7239 g_pais_alert_dialog_active =
nullptr;
7242 if (g_pAISTargetList) {
7244 g_pAISTargetList->Disconnect_decoder();
7245 g_pAISTargetList->Destroy();
7246 g_pAISTargetList = NULL;
7250 if (gFrame->m_pMenuBar) {
7251 gFrame->SetMenuBar(NULL);
7252 gFrame->m_pMenuBar->Destroy();
7253 gFrame->m_pMenuBar = NULL;
7255 gFrame->BuildMenuBar();
7258 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
7260 if (cc) cc->CanvasApplyLocale();
7265 wxString perspective;
7267 pConfig->Read(
"AUIPerspective", &perspective);
7281 bool bno_load =
false;
7282 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7284 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7285 wxAuiPaneInfo pane = pane_array_val[i];
7286 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7292 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7297 gFrame->RequestNewToolbars(
true);
7298 gFrame->RequestNewMasterToolbar(
true);
7305 : wxThread(wxTHREAD_JOINABLE) {
7306 m_filename = filename;
7317 newChart->SetNativeScale(m_scale);
7318 newChart->SetFullExtent(m_ext);
7320 newChart->FindOrCreateSenc(m_filename);
7325 wxString m_filename;
7331static double chart_dist(
int index) {
7337 if (cte.GetBBox().Contains(
gLat,
gLon))
7342 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7343 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7344 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7347 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7348 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7350 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7356WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7357static int CompareInts(
int n1,
int n2) {
7358 double d1 = chart_dist(n1);
7359 double d2 = chart_dist(n2);
7360 return (
int)(d1 - d2);
7365 wxString chart_path;
7370WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7372#include <wx/arrimpl.cpp>
7375void ParseAllENC(wxWindow *parent) {
7376 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7384 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7387 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7389 idx_sorted_by_distance.Add(i);
7393 if (count == 0)
return;
7395 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7401 ArrayOfCompressTargets ct_array;
7402 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7403 int i = idx_sorted_by_distance[j];
7406 double distance = chart_dist(i);
7408 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7411 pct->distance = distance;
7412 pct->chart_path = filename;
7414 ct_array.push_back(pct);
7417 int thread_count = 0;
7420 if (g_nCPUCount > 0)
7421 thread_count = g_nCPUCount;
7423 thread_count = wxThread::GetCPUCount();
7425 if (thread_count < 1) {
7434 for(
int t = 0; t < thread_count; t++)
7438 wxGenericProgressDialog *prog =
nullptr;
7442 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
7443 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
7445 prog =
new wxGenericProgressDialog();
7447 prog->SetFont(*qFont);
7449 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
7450 count + 1, parent, style);
7459 prog->ShowWindowModal();
7468 for (
unsigned int j = 0; j < ct_array.size(); j++) {
7469 wxString filename = ct_array[j].chart_path;
7470 double distance = ct_array[j].distance;
7471 int index =
ChartData->FinddbIndex(filename);
7472 if (index < 0)
continue;
7475 ext.NLAT = cte.GetLatMax();
7476 ext.SLAT = cte.GetLatMin();
7477 ext.WLON = cte.GetLonMin();
7478 ext.ELON = cte.GetLonMax();
7480 int scale = cte.GetScale();
7483 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
7486 if (wxThread::IsMain()) {
7488 wxSize sz = prog->GetSize();
7493 prog->Update(count, msg, &skip);
7505 newChart->SetNativeScale(
scale);
7506 newChart->SetFullExtent(ext);
7507 newChart->DisableBackgroundSENC();
7509 newChart->FindOrCreateSenc(filename,
7513 if (wxThread::IsMain()) {
7514 msg.Printf(_(
"ENC Completed."));
7516 prog->Update(count, msg, &skip);
7526 for (
int t = 0;; t = (t + 1) % thread_count) {
7533 if (!workers[t]->IsAlive()) {
7546#if defined(__WXMSW__) || defined(__WXOSX__)
7553 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.
AisInfoGui * g_pAISGUI
Global instance.
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.
arrayofCanvasPtr g_canvasArray
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,...
Minimal ChartCAnvas interface with very little dependencies.
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.
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.
float GetVPScale() override
Return ViewPort scale factor, in physical pixels per meter.
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().
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.
obs::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 Listen(const std::string &key, wxEvtHandler *listener, wxEventType evt)
Set object to send wxEventType ev to listeners 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,.
AbstractRestServer implementation and interface to underlying IO thread.
std::string GetEndpoint() override
Return HTTPS url to local rest server.
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.
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
obs::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.
void Notify() override
Notify all listeners, no data supplied.
wxRect GetRect(void) const
Return the coordinates of the compass widget, in physical pixels relative to the canvas window.
Device context class that can use either wxDC or OpenGL for drawing.
virtual void OnToolbarToolCallback(int id)
Handles toolbar tool clicks.
Represents an S57 format electronic navigational chart in OpenCPN.
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.
CommBridge class and helpers.
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.
std::vector< ConnectionParams * > & TheConnectionParams()
Return global list of connections.
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.
double AnchorDistFix(double const d, double const AnchorPointMinDist, double const AnchorPointMaxDist)
Return constrained value of d so that AnchorPointMinDist < abs(d) < AnchorPointMaxDist.
MySQL based storage for routes, tracks, etc.
MyConfig * pConfig
Global instance.
Navigation Utility Functions without GUI dependencies.
User notifications manager.
OCPN_AUIManager * g_pauimgr
Global instance.
MyFrame * gFrame
Global instance.
PlugIn Object Definition/API.
wxWindow * GetOCPNCanvasWindow()
Gets OpenCPN's main canvas window.
wxFont * FindOrCreateFont_PlugIn(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline, const wxString &facename, wxFontEncoding encoding)
Creates or finds a font in the font cache.
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.
Miscellaneous utilities, many of which string related.
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.
RouteManagerDialog * pRouteManagerDialog
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.
Generic hardware events interface.
WaypointMan drawing stuff.