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:
941 case GLOBAL_COLOR_SCHEME_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();
1088 if (g_hicon_colors) {
1090 if (cs == GLOBAL_COLOR_SCHEME_DAY_HICON)
1091 s = GLOBAL_COLOR_SCHEME_DAY;
1092 else if (cs == GLOBAL_COLOR_SCHEME_NIGHT_HICON)
1093 s = GLOBAL_COLOR_SCHEME_DUSK;
1098void MyFrame::ApplyGlobalColorSchemetoStatusBar() {
1099 if (m_pStatusBar != NULL) {
1100 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1101 m_pStatusBar->ClearBackground();
1112void MyFrame::CancelAllMouseRoute() {
1114 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1116 if (cc) cc->CancelMouseRoute();
1120void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1128 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1136 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1145 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1148 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1149 config_array.Item(i)->canvas = NULL;
1155 for (
unsigned int i = 1; i <
g_canvasArray.GetCount(); i++) {
1160 switch (g_canvasConfig) {
1174 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1175 cc->GetglCanvas()->Show();
1178 config_array.Item(0)->canvas = cc;
1182 cc->ApplyCanvasConfig(config_array.Item(0));
1186 cc->ConfigureChartBar();
1187 cc->SetColorScheme(global_color_scheme);
1188 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1189 cc->SetShowGPS(
true);
1192 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1194 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1210 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1213 config_array.Item(0)->canvas = cc;
1215 cc->ApplyCanvasConfig(config_array.Item(0));
1218 cc->ConfigureChartBar();
1219 cc->SetColorScheme(global_color_scheme);
1220 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1221 cc->SetShowGPS(
false);
1224 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1226 .CaptionVisible(
false)
1228 .CloseButton(
false);
1237 if (config_array.GetCount() < 2) {
1239 pcc->configIndex = 1;
1243 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1244 config_array.Add(pcc);
1247 config_array.Item(1)->canvas = cc;
1249 cc->ApplyCanvasConfig(config_array.Item(1));
1252 cc->ConfigureChartBar();
1253 cc->SetColorScheme(global_color_scheme);
1254 cc->SetShowGPS(
true);
1256 cc->SetShowGPSCompassWindow(
true);
1259 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1261 .CaptionVisible(
false)
1263 .CloseButton(
false);
1264 g_pauimgr->GetPane(cc).RightDockable(
true);
1268 config_array.Item(1)->canvasSize =
1269 wxSize(GetClientSize().x / 2, GetClientSize().y);
1270 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1275 if (b_useStoredSize) {
1276 int ccw = config_array.Item(1)->canvasSize.x;
1277 int cch = config_array.Item(1)->canvasSize.y;
1280 if (ccw < GetClientSize().x / 10) {
1281 ccw = GetClientSize().x / 2;
1282 cch = GetClientSize().y;
1285 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1286 cc->SetSize(ccw, cch);
1304 console->SetColorScheme(global_color_scheme);
1309 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1315void MyFrame::RequestNewToolbars(
bool bforcenew) {
1316 if (b_inCloseWindow) {
1320 BuildiENCToolbar(bforcenew, m_toolbar_callbacks);
1321 PositionIENCToolbar();
1330void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1336void MyFrame::SetAllToolbarScale() {
1337 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1340void MyFrame::SetGPSCompassScale() {
1341 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1345 wxPoint screenPoint = ::wxGetMousePosition();
1348 switch (g_canvasConfig) {
1350 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1353 if (canvas->GetScreenRect().Contains(
1357 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1360 if (canvas->GetScreenRect().Contains(
1367 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1370 if (canvas->GetScreenRect().Contains(
1371 canvas->ScreenToClient(screenPoint)))
1379int MyFrame::GetCanvasIndexUnderMouse() {
1380 wxPoint screenPoint = ::wxGetMousePosition();
1383 switch (g_canvasConfig) {
1385 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1388 if (canvas->GetScreenRect().Contains(
1392 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1395 if (canvas->GetScreenRect().Contains(
1402 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1405 if (canvas->GetScreenRect().Contains(
1406 canvas->ScreenToClient(screenPoint)))
1414bool MyFrame::DropMarker(
bool atOwnShip) {
1421 if (!canvas)
return false;
1428 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1430 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1432 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1443 RefreshAllCanvas(
false);
1448void MyFrame::SwitchKBFocusCanvas(
ChartCanvas *pCanvas) {
1449 if (g_canvasConfig != 0) {
1452 int nTargetGTK = -1;
1454 wxWindow *source = FindFocus();
1460 switch (g_canvasConfig) {
1462 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1465 if (canvas && (canvas == test)) {
1470 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1473 if (canvas && (canvas == test)) {
1481 int nfinalTarget = nTarget;
1483 nfinalTarget = nTargetGTK;
1485 target = ConfigMgr::Get()
1486 .GetCanvasConfigArray()
1491 target->Refresh(
true);
1502void MyFrame::FastClose() {
1504 FrameTenHzTimer.Stop();
1506 FrameTimer1.Start(1);
1510void MyFrame::OnExit(wxCommandEvent &event) {
1514void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1517 if (b_inCloseWindow) {
1527 if (!g_bDeferredInitDone)
return;
1544 if (bDBUpdateInProgress)
return;
1546 b_inCloseWindow =
true;
1548 ::wxSetCursor(wxCURSOR_WAIT);
1552 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1554 if (cc && cc->IsMeasureActive()) {
1555 cc->CancelMeasureRoute();
1560 SendPreShutdownHookToPlugins();
1564 if (g_pAISTargetList) {
1565 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1566 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1567 g_pauimgr->DetachPane(g_pAISTargetList);
1594 SetCursor(wxCURSOR_WAIT);
1596 RefreshAllCanvas(
true);
1602 RestoreScreenBrightness();
1613 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1614 g_iENCToolbarPosY = tbp_incanvas.y;
1615 g_iENCToolbarPosX = tbp_incanvas.x;
1619 g_bframemax = IsMaximized();
1622 FrameTenHzTimer.Stop();
1624 FrameCOGTimer.Stop();
1638 if (g_bAutoAnchorMark) {
1639 bool watching_anchor =
false;
1647 wxDateTime now = wxDateTime::Now();
1648 wxTimeSpan uptime = now.Subtract(g_start_time);
1650 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1651 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1656 if (g_declutter_anchorage) {
1657 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1658 if (pr->GetName().StartsWith(
"Anchorage")) {
1659 double a =
gLat - pr->m_lat;
1660 double b =
gLon - pr->m_lon;
1661 double l = sqrt((a * a) + (b * b));
1664 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1666 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1667 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1675 wxString name = now.Format();
1676 name.Prepend(_(
"Anchorage created "));
1682 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1691 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1695 NavObj_dB::GetInstance().Close();
1699 pConfig->DeleteGroup(
"/Routes");
1700 pConfig->DeleteGroup(
"/Marks");
1721 if (g_pAISTargetList) {
1722 g_pAISTargetList->Disconnect_decoder();
1723 g_pAISTargetList->Destroy();
1726 if (RouteManagerDialog::getInstanceFlag()) {
1743 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1745 if (cc) cc->Destroy();
1769 CommBridge::GetInstance().SaveConfig();
1789 auto ®istry = CommDriverRegistry::GetInstance();
1790 registry.CloseAllDrivers();
1798 while (pLayerList->size())
delete *pLayerList->begin();
1802 ReleaseApiListeners();
1805 g_bTempShowMenuBar =
false;
1807#define THREAD_WAIT_SECONDS 5
1817 wxLogMessage(
"Starting compressor pool drain");
1818 wxDateTime now = wxDateTime::Now();
1819 time_t stall = now.GetTicks();
1820 time_t end = stall + THREAD_WAIT_SECONDS;
1823 while (stall < end) {
1824 wxDateTime later = wxDateTime::Now();
1825 stall = later.GetTicks();
1828 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1837 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1843 uninitIXNetSystem();
1850 wxLogMessage(
"gFrame destroyed.");
1853#ifndef USE_ANDROID_GLES2
1854 qDebug() <<
"Calling OnExit()";
1858 wxTheApp->ExitMainLoop();
1861void MyFrame::OnMove(wxMoveEvent &event) {
1862 auto idx = wxDisplay::GetFromWindow(
this);
1875 DEBUG_LOG <<
"Moved to " << idx
1876#if wxCHECK_VERSION(3, 1, 6)
1877 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1878 << wxDisplay(idx).GetPPI().GetY()
1879 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1881 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1882 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1883 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1884 << wxGetDisplaySizeMM().GetY()
1885 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1894 if (g_config_display_size_manual) {
1903 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
1906 cc->SetMUIBarPosition();
1915 UpdateGPSCompassStatusBoxes();
1925 PositionIENCToolbar();
1931 g_nframewin_posx = GetPosition().x;
1932 g_nframewin_posy = GetPosition().y;
1935void MyFrame::ProcessCanvasResize() {
1936 UpdateGPSCompassStatusBoxes(
true);
1940 PositionIENCToolbar();
1943 TriggerRecaptureTimer();
1947void MyFrame::TriggerRecaptureTimer() {
1948 m_recaptureTimer.Start(
1949 1000, wxTIMER_ONE_SHOT);
1952void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1954void MyFrame::SetCanvasSizes(wxSize frameSize) {
1958 int cccw = frameSize.x;
1959 int ccch = frameSize.y;
1963 switch (g_canvasConfig) {
1969 cc->GetSize( &cur_width, &cur_height );
1970 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1972 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1974 cc->SetSize( 0, 0, cccw, ccch );
1984 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1985 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1987 ccw = wxMin(ccw, cccw * 8 / 10);
1988 ccw = wxMax(ccw, cccw * 2 / 10);
1992 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1999 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
2016void MyFrame::OnIconize(wxIconizeEvent &event) {
2026 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2028 if (cc && cc->GetMUIBar()) {
2029 if (cc->GetMUIBar()->GetCanvasOptions()) {
2030 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2031 cc->GetMUIBar()->PushCanvasOptions();
2040void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2042void MyFrame::ODoSetSize() {
2044 GetClientSize(&x, &y);
2047 if (m_pStatusBar != NULL) {
2048 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2049 int currentCount = m_pStatusBar->GetFieldsCount();
2050 if (currentCount != m_StatusBarFieldCount) {
2051 if ((currentCount > 0) && (currentCount < 7)) {
2054 int widths[] = {2, 2, 2, 2, 2, 2};
2055 m_pStatusBar->SetStatusWidths(currentCount, widths);
2058 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2061 if (m_StatusBarFieldCount) {
2066 if (m_StatusBarFieldCount > 2) {
2067 int widths[] = {-6, -5, -5, -6, -4};
2068 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2069 }
else if (m_StatusBarFieldCount == 2) {
2070 int cwidth = x * 90 / 100;
2071 int widths[] = {100, 100};
2072 widths[0] = cwidth * 6.4 / 10.0;
2073 widths[1] = cwidth * 3.6 / 10.0;
2074 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2076 int widths[] = {100, 100};
2077 widths[0] = x * 90 / 100;
2078 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2081 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2082 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2083 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2085 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2087 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2095 m_pStatusBar->GetFieldRect(0, stat_box);
2098 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2100 wxFont sys_font = *wxNORMAL_FONT;
2101 int try_font_size = sys_font.GetPointSize();
2104 int min_font_size = 10;
2114 wxFont *statusBarFont =
2115 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2116 int font_size = statusBarFont->GetPointSize();
2118 font_size = wxMin(font_size,
2121 wxMax(font_size, min_font_size);
2124 font_size = statusBarFont->GetPointSize();
2131 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2132 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2134 int min_height = stat_box.height;
2136 m_pStatusBar->SetFont(*pstat_font);
2137 m_pStatusBar->SetForegroundColour(
2138 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2140 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2142 (min_height >> 1) * 2;
2143 m_pStatusBar->SetMinHeight(min_height);
2152 SetCanvasSizes(GetClientSize());
2154 UpdateGPSCompassStatusBoxes(
true);
2156 if (
console) PositionConsole();
2159 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2161 if (cc) cc->FormatPianoKeys();
2167 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2168 GetPrimaryCanvas()->GetCompass()->GetRect());
2194 options_lastWindowSize = wxSize(0, 0);
2195 options_lastWindowPos = wxPoint(0, 0);
2202 if (!b_inCloseWindow) {
2205 resizeAndroidPersistents();
2209 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2210 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2216void MyFrame::PositionConsole() {
2217#if defined(__WXMSW__) || defined(__WXMAC__)
2218 if (NULL == GetPrimaryCanvas())
return;
2220 int ccx, ccy, ccsx, ccsy, consx, consy;
2225 consoleHost->GetSize(&ccsx, &ccsy);
2226 consoleHost->GetPosition(&ccx, &ccy);
2228 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2229 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2230 consoleHost = GetPrimaryCanvas();
2235 if (consoleHost->GetCompass()) {
2236 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2238 if (compass_rect.y < 100)
2239 yOffset = compass_rect.y + compass_rect.height + 45;
2243 wxSize csz =
console->GetSize();
2247 wxPoint screen_pos =
2248 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2251 if (NULL == GetPrimaryCanvas())
return;
2253 int ccx, ccy, ccsx, ccsy, consx, consy;
2258 consoleHost->GetSize(&ccsx, &ccsy);
2259 consoleHost->GetPosition(&ccx, &ccy);
2261 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2262 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2263 consoleHost = GetPrimaryCanvas();
2266 int yTopOffset = 60;
2267 int yBottomOffset = 0;
2269 if (consoleHost->GetCompass()) {
2270 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2272 if (compass_rect.y < 100)
2273 yTopOffset = compass_rect.y + compass_rect.height;
2275 if (consoleHost->GetMUIBar()) {
2276 wxRect mui_rect = consoleHost->GetMUIBarRect();
2277 yBottomOffset = ccsy - mui_rect.y;
2281 wxSize csz =
console->GetSize();
2284 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2286 if (consy < yAvail) {
2287 yFinal = (yAvail - consy) / 2;
2288 yFinal += yTopOffset;
2289 }
else if (
console->GetCDI()->IsShown()) {
2290 int cdi_height =
console->GetCDI()->GetSize().y;
2291 int consy_no_cdi = consy - cdi_height;
2292 yFinal = (yAvail - consy_no_cdi) / 2;
2293 yFinal += yTopOffset;
2297 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2302void MyFrame::UpdateAllFonts() {
2311 DestroyPersistentDialogs();
2313 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2318void MyFrame::DestroyPersistentDialogs() {
2319 if (g_pais_query_dialog_active) {
2320 g_pais_query_dialog_active->Hide();
2321 g_pais_query_dialog_active->Destroy();
2322 g_pais_query_dialog_active = NULL;
2350void MyFrame::RefreshGroupIndices() {
2352 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2354 if (cc) cc->canvasRefreshGroupIndex();
2358bool MyFrame::DisableTbarTooltips() {
2363 wxLogWarning(
"Global g_MainToolbar has not been created.");
2367void MyFrame::EnableTbarTooltips() {
2373void MyFrame::HideTbarTooltip() {
2379void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2381 switch (event.GetId()) {
2382 case ID_MENU_SCALE_OUT:
2383 DoStackDelta(GetPrimaryCanvas(), 1);
2387 case ID_MENU_SCALE_IN:
2388 DoStackDelta(GetPrimaryCanvas(), -1);
2392 case ID_MENU_ZOOM_IN: {
2393 if (GetFocusCanvas()) {
2394 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2399 case ID_MENU_ZOOM_OUT: {
2400 if (GetFocusCanvas()) {
2401 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2406 case ID_MENU_ROUTE_NEW: {
2407 if (GetFocusCanvas()) {
2408 if (0 == GetFocusCanvas()->m_routeState) {
2409 GetFocusCanvas()->StartRoute();
2411 GetFocusCanvas()->FinishRoute();
2417 case ID_MENU_TOOL_MEASURE: {
2418 GetPrimaryCanvas()->StartMeasureRoute();
2422 case ID_MENU_TOOL_NMEA_DBG_LOG:
2423 m_data_monitor->Show();
2424 m_data_monitor->Raise();
2427 case ID_MENU_TOOL_IO_MONITOR:
2428 m_data_monitor->Show();
2431 case ID_MENU_MARK_BOAT: {
2436 case ID_MENU_MARK_CURSOR: {
2441 case ID_MENU_NAV_FOLLOW: {
2442 if (
gFrame->GetPrimaryCanvas())
2443 gFrame->GetPrimaryCanvas()->TogglebFollow();
2447 case ID_MENU_CHART_OUTLINES: {
2448 ToggleChartOutlines(GetFocusCanvas());
2452 case ID_MENU_CHART_QUILTING: {
2453 ToggleQuiltMode(GetFocusCanvas());
2457 case ID_MENU_UI_CHARTBAR: {
2458 ToggleChartBar(GetFocusCanvas());
2462 case ID_MENU_ENC_TEXT:
2464 ToggleENCText(GetFocusCanvas());
2467 case ID_MENU_ENC_LIGHTS: {
2468 ToggleLights(GetFocusCanvas());
2471 case ID_MENU_ENC_SOUNDINGS: {
2472 ToggleSoundings(GetFocusCanvas());
2475 case ID_MENU_ENC_ANCHOR: {
2476 ToggleAnchor(GetFocusCanvas());
2479 case ID_MENU_ENC_DATA_QUALITY: {
2480 ToggleDataQuality(GetFocusCanvas());
2483 case ID_MENU_SHOW_NAVOBJECTS: {
2484 ToggleNavobjects(GetFocusCanvas());
2488 case ID_MENU_AIS_TARGETS: {
2489 ToggleAISDisplay(GetFocusCanvas());
2492 case ID_MENU_AIS_MOORED_TARGETS: {
2493 g_bHideMoored = !g_bHideMoored;
2496 case ID_MENU_AIS_SCALED_TARGETS: {
2497 ToggleAISMinimizeTargets(GetFocusCanvas());
2501 case ID_MENU_AIS_TARGETLIST: {
2502 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2506 case ID_MENU_AIS_TRACKS: {
2507 g_bAISShowTracks = !g_bAISShowTracks;
2508 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2512 case ID_MENU_AIS_CPADIALOG: {
2513 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2514 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2515 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2516 if (g_bAIS_CPA_Alert) {
2517 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2522 case ID_MENU_AIS_CPASOUND: {
2523 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2524 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2528 case ID_MENU_AIS_CPAWARNING: {
2529 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2530 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2534 case wxID_PREFERENCES:
2541 case ID_SETTINGS_NEW: {
2546 case ID_SETTINGS_DELETE: {
2549 g_pOptions =
nullptr;
2553 case ID_RELOAD_CHARTS: {
2558 case ID_MENU_SETTINGS_BASIC: {
2560 androidDisableFullScreen();
2562 DoAndroidPreferences();
2569 case ID_MENU_UI_FULLSCREEN: {
2574 case ID_MENU_SHOW_CURRENTS: {
2575 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2576 GetFocusCanvas()->ReloadVP();
2577 GetFocusCanvas()->Refresh(
false);
2581 case ID_MENU_SHOW_TIDES: {
2582 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2583 GetFocusCanvas()->ReloadVP();
2584 GetFocusCanvas()->Refresh(
false);
2604 case ID_MENU_UI_COLSCHEME:
2605 case ID_COLSCHEME: {
2606 ToggleColorScheme();
2615 case ID_MENU_OQUIT: {
2620 case ID_MENU_ROUTE_MANAGER:
2621 case ID_ROUTEMANAGER: {
2644 case ID_MENU_NAV_TRACK:
2646 if (!g_bTrackActive) {
2648 g_bTrackCarryOver =
true;
2651 g_bTrackCarryOver =
false;
2652 RefreshAllCanvas(
true);
2657 case ID_MENU_CHART_NORTHUP: {
2658 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2661 case ID_MENU_CHART_COGUP: {
2662 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2665 case ID_MENU_CHART_HEADUP: {
2666 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2670 case ID_MENU_MARK_MOB:
2676 case ID_MASTERTOGGLE: {
2678 wxString tip = _(
"Show Toolbar");
2679 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2681 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2683 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2686 if (g_bmasterToolbarFull)
2687 m_nMasterToolCountShown =
2691 m_nMasterToolCountShown = 2;
2693 m_nMasterToolCountShown =
2696 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2704 case ID_CMD_SELECT_CHART_TYPE: {
2705 selectChartDisplay(event.GetExtraLong(), -1);
2709 case ID_CMD_SELECT_CHART_FAMILY: {
2710 selectChartDisplay(-1, event.GetExtraLong());
2714 case ID_CMD_APPLY_SETTINGS: {
2715 applySettingsString(event.GetString());
2717 androidRestoreFullScreen();
2723 case ID_CMD_NULL_REFRESH: {
2728 case ID_CMD_SETVP: {
2729 setStringVP(event.GetString());
2733 case ID_CMD_INVALIDATE: {
2739 case ID_CMD_POST_JSON_TO_PLUGINS: {
2742 nlohmann::json root;
2744 root = nlohmann::json::parse(event.GetString().ToStdString());
2745 if (root[
"MessageID"].is_string()) {
2746 std::string msg_id = root[
"MessageID"].get<std::string>();
2749 }
catch (nlohmann::json::exception &) {
2771 ArrayOfPlugInToolbarTools tool_array =
2773 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2775 if (event.GetId() == pttc->id) {
2776 if (pttc->m_pplugin)
2798bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2799 bool viz_now = g_bmasterToolbarFull;
2802 wxString tip = _(
"Show Toolbar");
2804 tip = _(
"Hide Toolbar");
2806 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2809 bool toggle =
false;
2810 if (viz && !g_bmasterToolbarFull)
2813 else if (!viz && g_bmasterToolbarFull)
2817 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2820 if (g_bmasterToolbarFull)
2821 m_nMasterToolCountShown =
2825 m_nMasterToolCountShown = 2;
2827 m_nMasterToolCountShown =
2830 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2836void MyFrame::ScheduleReloadCharts() {
2837 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2838 evt.SetId(ID_RELOAD_CHARTS);
2839 GetEventHandler()->AddPendingEvent(evt);
2842void MyFrame::ScheduleDeleteSettingsDialog() {
2843 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2844 evt.SetId(ID_SETTINGS_DELETE);
2845 GetEventHandler()->AddPendingEvent(evt);
2848void MyFrame::ScheduleSettingsDialog() {
2849 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2850 evt.SetId(ID_SETTINGS);
2851 GetEventHandler()->AddPendingEvent(evt);
2854void MyFrame::ScheduleSettingsDialogNew() {
2855 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2856 evt.SetId(ID_SETTINGS_NEW);
2857 GetEventHandler()->AddPendingEvent(evt);
2860void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2861 UpdateCanvasConfigDescriptors();
2863 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2864 CreateCanvasLayout(
true);
2866 CreateCanvasLayout();
2870 ConfigureStatusBar();
2871 wxSize lastOptSize = options_lastWindowSize;
2876 options_lastWindowSize = lastOptSize;
2880 ScheduleSettingsDialogNew();
2882 ScheduleSettingsDialog();
2887 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2890 int index_hint = -1;
2891 if (i < pathArray.GetCount())
2892 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2893 cc->canvasChartsRefresh(index_hint);
2894 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2903 return GetPrimaryCanvas();
2906void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2908 if (g_bmasterToolbarFull) {
2909#ifndef OCPN_TOOLBAR_ANIMATE
2910 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2913 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2914 m_nMasterToolCountShown++;
2919 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2927#ifndef OCPN_TOOLBAR_ANIMATE
2928 m_nMasterToolCountShown = 1;
2930 if (m_nMasterToolCountShown > 1) {
2931 m_nMasterToolCountShown--;
2935 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2945void MyFrame::InvalidateAllGL() {
2948 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2958void MyFrame::RefreshAllCanvas(
bool bErase) {
2960 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
2963 cc->Refresh(bErase);
2968void MyFrame::setStringVP(wxString VPS) {
2973 wxStringTokenizer tkz(VPS,
";");
2975 wxString token = tkz.GetNextToken();
2977 token.ToDouble(&lat);
2979 token = tkz.GetNextToken();
2981 token.ToDouble(&lon);
2983 token = tkz.GetNextToken();
2985 token.ToDouble(&scale_ppm);
2987 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2990void MyFrame::DoSettingsNew() {
2997void MyFrame::DoSettings() {
2998 if (!g_bDeferredInitDone) {
2999 wxLogWarning(
"Ignoring settings request while OpenCPN is initializing.");
3007 ApplyGlobalSettings(
true);
3010 bool b_loadHarmonics =
false;
3011 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3014 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
3017 if (b_loadHarmonics) LoadHarmonics();
3025 g_bShowChartBar = !g_bShowChartBar;
3027 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
3032 if (g_bShowChartBar) {
3034 UpdateControlBar(cc);
3037 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
3040void MyFrame::ToggleColorScheme() {
3041 static bool lastIsNight;
3042 ColorScheme s = user_colors::GetColorScheme();
3043 if (!g_hicon_colors) {
3046 if (lastIsNight && is == 3)
3049 lastIsNight =
false;
3051 if (lastIsNight) is = 2;
3052 if (is == 3) lastIsNight =
true;
3053 s = (ColorScheme)(is);
3054 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3056 if (s == GLOBAL_COLOR_SCHEME_DAY_HICON)
3057 s = GLOBAL_COLOR_SCHEME_NIGHT_HICON;
3058 else if (s == GLOBAL_COLOR_SCHEME_NIGHT_HICON)
3059 s = GLOBAL_COLOR_SCHEME_DAY_HICON;
3061 s = GLOBAL_COLOR_SCHEME_DAY_HICON;
3064 SetAndApplyColorScheme(s);
3067void MyFrame::ToggleFullScreen() {
3068 bool to = !IsFullScreen();
3073 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3075 ShowFullScreen(to, style);
3078 UpdateAllToolbars(global_color_scheme);
3080 UpdateControlBar(GetPrimaryCanvas());
3082 TriggerRecaptureTimer();
3085void MyFrame::ActivateMOB() {
3087 wxDateTime mob_time = wxDateTime::Now();
3088 wxString mob_label(_(
"MAN OVERBOARD"));
3089 mob_label += _(
" on ");
3090 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3094 pWP_MOB->SetShared(
true);
3096 pWP_MOB->SetWaypointArrivalRadius(
3098 pWP_MOB->SetUseSca(
false);
3100 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3108 new RoutePoint(zlat, zlon, g_default_wp_icon,
3109 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3110 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3115 temp_route->AddPoint(pWP_src);
3116 temp_route->AddPoint(pWP_MOB);
3118 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3128 temp_route->SetRouteArrivalRadius(-1.0);
3134 v[
"GUID"] = temp_route->
m_GUID;
3135 SendJsonMessageToAllPlugins(
"OCPN_MAN_OVERBOARD", v);
3138 if (RouteManagerDialog::getInstanceFlag()) {
3146 RefreshAllCanvas(
false);
3148 wxString mob_message(_(
"MAN OVERBOARD"));
3149 mob_message += _(
" Time: ");
3150 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3151 mob_message += _(
" Position: ");
3152 mob_message += toSDMM(1,
gLat);
3154 mob_message += toSDMM(2,
gLon);
3155 wxLogMessage(mob_message);
3157void MyFrame::TrackOn() {
3158 g_bTrackActive =
true;
3166 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3168 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3170 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3173 androidSetTrackTool(
true);
3176 if (RouteManagerDialog::getInstanceFlag()) {
3185 if (name.IsEmpty()) {
3191 name = _(
"(Unnamed Track)");
3195 SendJsonMessageToAllPlugins(
"OCPN_TRK_ACTIVATED", v);
3197 g_FlushNavobjChangesTimeout = 30;
3200Track *MyFrame::TrackOff(
bool do_add_point) {
3206 SendJsonMessageToAllPlugins(
"OCPN_TRK_DEACTIVATED", v);
3215 if (g_bTrackDaily) {
3220 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3221 return_val = pExtendTrack;
3228 g_bTrackActive =
false;
3230 if (RouteManagerDialog::getInstanceFlag()) {
3237 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3239 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3240 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3243 androidSetTrackTool(
false);
3247 m_target_rotate_time = wxInvalidDateTime;
3252void MyFrame::InitializeTrackRestart() {
3253 if (!g_bTrackDaily)
return;
3254 if (m_target_rotate_time.IsValid())
return;
3257 switch (g_track_rotate_time_type) {
3259 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3261 case TIME_TYPE_COMPUTER:
3262 rotate_at = g_track_rotate_time;
3266 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3267 rotate_at = g_track_rotate_time + utc_offset;
3270 if (rotate_at > 86400)
3272 else if (rotate_at < 0)
3275 wxTimeSpan rotate_seconds = wxTimeSpan(0, 0, rotate_at);
3276 m_target_rotate_time = wxDateTime::Today() + rotate_seconds;
3279 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3280 m_target_rotate_time += wxTimeSpan(24);
3284bool MyFrame::ShouldRestartTrack() {
3286 InitializeTrackRestart();
3288 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3289 m_target_rotate_time += wxTimeSpan(24);
3295void MyFrame::TrackDailyRestart() {
3297 Track *pPreviousTrack = TrackOff(
true);
3304 if (pPreviousTrack) {
3305 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3309 if (RouteManagerDialog::getInstanceFlag()) {
3317void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3319 cc->SetUpMode(mode);
3321 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3322 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3323 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3326 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3331 cc->SetShowENCText(!cc->GetShowENCText());
3333 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3341void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3344 cc->SetENCDisplayCategory(nset);
3346 UpdateGlobalMenuItems();
3357 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3359 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3368 cc->SetShowENCLights(!cc->GetShowENCLights());
3370 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3380void MyFrame::ToggleRocks(
void )
3386 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3387 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3388 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3389 pOLE->nViz = !pOLE->nViz;
3393 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3394 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3395 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3398 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3402 ps52plib->GenerateStateHash();
3409 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3411 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3419 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3421 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3436 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3437 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3442 cc->SetShowAIS(!cc->GetShowAIS());
3443 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3447void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3448 cc->SetAttenAIS(!cc->GetAttenAIS());
3449 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3455 cc->m_bFollow =
true;
3458 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3462 SetChartUpdatePeriod();
3470 cc->m_bFollow =
false;
3472 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3476 SetChartUpdatePeriod();
3479void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3480 cc->SetShowOutlines(!cc->GetShowOutlines());
3482 RefreshAllCanvas(
false);
3486 if (g_bopengl) InvalidateAllGL();
3489 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3492void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3494void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3496 bool enabled = m_pMenuBar->IsEnabled(item_id);
3497 m_pMenuBar->Enable(item_id,
false);
3498 m_pMenuBar->Check(item_id, state);
3499 m_pMenuBar->Enable(item_id, enabled);
3503void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3510void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3511 wxBitmap *bmpRollover) {
3513 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3518void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3519 wxString rolloverSVGfile,
3520 wxString toggledSVGfile) {
3523 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3527void MyFrame::ConfigureStatusBar() {
3529 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3532 UseNativeStatusBar(
false);
3535 if (g_bShowStatusBar) {
3536 if (!m_pStatusBar) {
3538 CreateStatusBar(m_StatusBarFieldCount, 0);
3539 ApplyGlobalColorSchemetoStatusBar();
3544 m_pStatusBar->Destroy();
3545 m_pStatusBar = NULL;
3551void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3552 ConfigureStatusBar();
3554 wxSize lastOptSize = options_lastWindowSize;
3560 options_lastWindowSize = lastOptSize;
3562 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3565void MyFrame::BuildMenuBar() {
3571 bool showMenuBar =
true;
3573 bool showMenuBar = g_bShowMenuBar;
3585 m_pMenuBar =
new wxMenuBar();
3586 RegisterGlobalMenuItems();
3587 SetMenuBar(m_pMenuBar);
3591 UpdateGlobalMenuItems();
3596 m_pMenuBar->Destroy();
3602void MyFrame::RegisterGlobalMenuItems() {
3603 if (!m_pMenuBar)
return;
3605 wxMenu *nav_menu =
new wxMenu();
3606 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3607 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3608 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3609 nav_menu->AppendSeparator();
3610 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3611 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3612 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3613 nav_menu->AppendSeparator();
3615 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3616 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3618 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3619 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3621 nav_menu->AppendSeparator();
3622 nav_menu->Append(ID_MENU_SCALE_IN,
3623 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3624 nav_menu->Append(ID_MENU_SCALE_OUT,
3625 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3627 nav_menu->AppendSeparator();
3628 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3630 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3632 wxMenu *view_menu =
new wxMenu();
3634 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3635 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3636 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3637 _menuText(_(
"Show Chart Outlines"),
"O"));
3639 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3640 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3641 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3642 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3644 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3645 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3647 view_menu->AppendSeparator();
3649 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3650 _menuText(_(
"Show ENC text"),
"T"));
3651 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3652 _menuText(_(
"Show ENC Lights"),
"L"));
3653 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3654 _menuText(_(
"Show ENC Soundings"),
"S"));
3655 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3656 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3657 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3658 _menuText(_(
"Show ENC Data Quality"),
"U"));
3659 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3660 _menuText(_(
"Show Navobjects"),
"V"));
3662 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3663 _menuText(_(
"Show ENC text"),
"Alt-T"));
3664 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3665 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3666 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3667 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3668 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3669 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3670 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3671 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3672 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3673 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3675 view_menu->AppendSeparator();
3676 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3677 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3678 view_menu->AppendSeparator();
3680 view_menu->Append(ID_MENU_UI_COLSCHEME,
3681 _menuText(_(
"Change Color Scheme"),
"C"));
3683 view_menu->Append(ID_MENU_UI_COLSCHEME,
3684 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3687 view_menu->AppendSeparator();
3689 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3690 _menuText(_(
"Toggle Full Screen"),
"F11"));
3692 m_pMenuBar->Append(view_menu, _(
"&View"));
3694 wxMenu *ais_menu =
new wxMenu();
3695 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3696 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3697 _(
"Attenuate less critical AIS targets"));
3698 ais_menu->AppendSeparator();
3699 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3700 _(
"Hide Moored AIS Targets"));
3701 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3702 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3703 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3706 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3707 _menuText(_(
"Show CPA Warnings"),
"W"));
3709 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3710 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3713 ais_menu->AppendSeparator();
3714 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3715 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3717 wxMenu *tools_menu =
new wxMenu();
3719 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3720 _menuText(_(
"Data Monitor"),
"E"));
3721 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3722 _menuText(_(
"Measure Distance"),
"M"));
3724 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3725 _menuText(_(
"Data Monitor"),
"Alt-E"));
3726 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3727 _menuText(_(
"Measure Distance"),
"Alt-M"));
3730 tools_menu->AppendSeparator();
3731 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3732 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3733 tools_menu->AppendSeparator();
3734 tools_menu->Append(ID_MENU_MARK_BOAT,
3735 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3736 tools_menu->Append(ID_MENU_MARK_CURSOR,
3737 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3738 tools_menu->AppendSeparator();
3742 _menuText(_(
"Drop MOB Marker"),
3744 tools_menu->AppendSeparator();
3745 tools_menu->Append(wxID_PREFERENCES,
3746 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3748 tools_menu->Append(ID_MENU_MARK_MOB,
3749 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3750 tools_menu->AppendSeparator();
3751 tools_menu->Append(wxID_PREFERENCES,
3752 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3754 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3757 wxMenu *window_menu =
new wxMenu();
3758 m_pMenuBar->Append(window_menu, _(
"&Window"));
3761 wxMenu *help_menu =
new wxMenu();
3762 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3763 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3764 m_pMenuBar->Append(help_menu, _(
"&Help"));
3767 UpdateGlobalMenuItems();
3768 EnableSettingsTool(g_bDeferredInitDone);
3771void MyFrame::UpdateGlobalMenuItems() {
3772 if (!m_pMenuBar)
return;
3774 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3775 ->Check(GetPrimaryCanvas()->m_bFollow);
3776 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3777 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3778 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3779 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3780 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3781 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3782 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3783 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3784 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3785 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3786 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3787 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3788 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3789 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3790 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3791 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3792 if (g_bAIS_CPA_Alert) {
3793 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3794 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3796 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3797 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3800 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3801 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3802 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3805 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3806 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3807 ->Check(ps52plib->GetShowSoundings());
3809 bool light_state =
false;
3811 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3813 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3814 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3815 light_state = (pOLE->nViz == 1);
3820 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3821 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3825 DisCat nset = ps52plib->GetDisplayCategory();
3826 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3827 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3828 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3829 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3830 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3831 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3832 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3834 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3835 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3836 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3841void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3842 if (!m_pMenuBar)
return;
3844 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3846 if (cc->GetUpMode() == NORTH_UP_MODE)
3847 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3848 else if (cc->GetUpMode() == COURSE_UP_MODE)
3849 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3851 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3853 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3854 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3855 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3856 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3857 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3858 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3859 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3860 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3861 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3862 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3863 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3864 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3865 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3866 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3867 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3870 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3871 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3874 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3876 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3877 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3882 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3886 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3887 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3888 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3889 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3890 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3891 ->Check(cc->GetShowENCDataQual());
3892 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3894 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3895 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3896 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3901void MyFrame::InvalidateAllCanvasUndo() {
3903 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3905 if (cc) cc->undo->InvalidateUndo();
3909void MyFrame::SubmergeAllCanvasToolbars() {
3911 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3913 if (cc) cc->SubmergeToolbar();
3917void MyFrame::SurfaceAllCanvasToolbars() {
3918 if (g_bshowToolbar) {
3920 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
3922 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3929void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3931 if (lon > 180.0) lon -= 360.0;
3936 cc->JumpToPosition(lat, lon,
scale);
3939 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3943void MyFrame::UpdateCanvasConfigDescriptors() {
3945 for (
unsigned int i = 0;
3946 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3947 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3955 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3956 cc->GroupID = chart->m_groupIndex;
3959 cc->
bQuilt = chart->GetQuiltMode();
3965 cc->bEnableBasemapTile = chart->GetbEnableBasemapTile();
3967 cc->
bFollow = chart->m_bFollow;
3972 int upmode = chart->GetUpMode();
3973 if (upmode == COURSE_UP_MODE)
3975 else if (upmode == HEAD_UP_MODE)
3982void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3983 if (!RBBox.GetValid())
return;
3985 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3986 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3989 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3990 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3998 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3999 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
4001 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
4002 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
4004 cc->GetSize(&ww, &wh);
4006 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
4008 ppm = wxMin(ppm, 1.0);
4014void MyFrame::PrepareOptionsClose(
options *settings,
4015 int settings_return_value) {
4017 options_lastPage = settings->lastPage;
4022 if (options_lastPage == 1) options_lastPage = 0;
4024 options_subpage = settings->lastSubPage;
4025 options_lastWindowPos = settings->lastWindowPos;
4026 options_lastWindowSize = settings->lastWindowSize;
4029 androidEnableBackButton(
true);
4030 androidEnableOptionsMenu(
true);
4031 androidRestoreFullScreen();
4032 androidEnableRotation();
4035 EnableSettingsTool(
true);
4038void MyFrame::DoOptionsDialog() {
4039 EnableSettingsTool(
false);
4042 AbstractPlatform::ShowBusySpinner();
4045 pConfig->SetPath(
"/Settings");
4046 pConfig->Read(
"OptionsSizeX", &sx, -1);
4047 pConfig->Read(
"OptionsSizeY", &sy, -1);
4049 wxWindow *optionsParent =
this;
4051 optionsParent = GetPrimaryCanvas();
4054 callbacks.prepare_close = [&](
options *me,
int changes) {
4055 PrepareOptionsClose(me, changes);
4057 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4058 ProcessOptionsDialog(changes, workdir_list);
4061 wxPoint(-1, -1), wxSize(sx, sy));
4063 AbstractPlatform::HideBusySpinner();
4067 g_options->SetInitChartDir(*pInit_Chart_Dir);
4071 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4072 g_options->SetWorkDirListPtr(pWorkDirArray);
4078 prev_locale = g_locale;
4079 g_options->SetInitialPage(options_lastPage, options_subpage);
4082 g_options->lastWindowPos = options_lastWindowPos;
4083 if (options_lastWindowPos != wxPoint(0, 0)) {
4085 g_options->SetSize(options_lastWindowSize);
4089 if (options_lastWindowSize != wxSize(0, 0)) {
4090 g_options->SetSize(options_lastWindowSize);
4095 androidEnableBackButton(
false);
4096 androidEnableOptionsMenu(
false);
4097 androidDisableFullScreen();
4105 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4108 wxString chart_file_name;
4109 if (cc->GetQuiltMode()) {
4110 int dbi = cc->GetQuiltRefChartdbIndex();
4111 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4113 if (cc->m_singleChart)
4114 chart_file_name = cc->m_singleChart->GetFullPath();
4117 pathArray.Add(chart_file_name);
4123 last_canvasConfig = g_canvasConfig;
4126 g_last_ChartScaleFactor = g_ChartScaleFactor;
4132void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4133 bool b_need_refresh =
false;
4136 if ((rr & VISIT_CHARTS) &&
4137 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4139 UpdateChartDatabaseInplace(*pNewDirArray,
4140 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4143 b_need_refresh =
true;
4148 if (rr & STYLE_CHANGED) {
4151 _(
"Please restart OpenCPN to activate language or style changes."),
4152 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4155 bool charts_updating =
4156 (rr & VISIT_CHARTS) && ((rr & CHANGE_CHARTS) || (rr & SCAN_UPDATE));
4157 if (!charts_updating) RefreshGroupIndices();
4159 if (rr & TIDES_CHANGED) {
4165 if (rr & S52_CHANGED) {
4166 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4177 g_Platform->GetDisplayDPmm());
4180 double stuffcog = NAN;
4181 double stuffsog = NAN;
4182 if (!std::isnan(
gCog)) stuffcog =
gCog;
4183 if (!std::isnan(
gSog)) stuffsog =
gSog;
4185 for (
int i = 0; i < kMaxCogsogFilterSeconds; i++) {
4186 COGFilterTable[i] = stuffcog;
4187 SOGFilterTable[i] = stuffsog;
4190 SetChartUpdatePeriod();
4192 if (rr & GL_CHANGED) {
4196 b_need_refresh =
true;
4199 if (rr & S52_CHANGED) {
4200 b_need_refresh =
true;
4204 if (rr & REBUILD_RASTER_CACHE) {
4206 GetPrimaryCanvas()->Disable();
4208 GetPrimaryCanvas()->Enable();
4213 if (g_config_display_size_manual &&
4221 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4228 int rrt = rr & S52_CHANGED;
4230 (rrt == S52_CHANGED) ||
4231 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4241 ps52plib->SetScaleFactorExp(
4242 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4243 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4247 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4249 if (cc) cc->ApplyGlobalSettings();
4257 if (!charts_updating) {
4258 bool ztc = g_bEnableZoomToCursor;
4259 g_bEnableZoomToCursor =
false;
4261 if (!GetPrimaryCanvas()->IsFrozen())
4263 g_bEnableZoomToCursor = ztc;
4268 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4277 SetGPSCompassScale();
4279 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4282 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4283 if (!charts_updating) cc->UpdateCanvasControlBar();
4286 UpdateGPSCompassStatusBoxes();
4288 SetAllToolbarScale();
4289 RequestNewToolbars();
4291 if ((rr & MENU_CHANGED) == MENU_CHANGED) BuildMenuBar();
4294 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4297 cc->RebuildCursors();
4302 bool b_masterScaleChange =
false;
4304 (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f))
4305 b_masterScaleChange =
true;
4307 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4308 RequestNewMasterToolbar(
true);
4310 bool bMuiChange =
false;
4316 if (b_masterScaleChange || bMuiChange) {
4318 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4321 cc->ProcessNewGUIScale();
4327 if (rr & LOCALE_CHANGED) {
4328 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4330 rr |= NEED_NEW_OPTIONS;
4339 g_last_ChartScaleFactor = g_ChartScaleFactor;
4342 ValidateColorScheme();
4343 SetAndApplyColorScheme(global_color_scheme);
4348void MyFrame::ValidateColorScheme() {
4350 if (g_hicon_colors) {
4351 if ((global_color_scheme != GLOBAL_COLOR_SCHEME_DAY_HICON) &&
4352 (global_color_scheme != GLOBAL_COLOR_SCHEME_NIGHT_HICON))
4353 global_color_scheme = GLOBAL_COLOR_SCHEME_DAY_HICON;
4355 if ((global_color_scheme != GLOBAL_COLOR_SCHEME_DAY) &&
4356 (global_color_scheme != GLOBAL_COLOR_SCHEME_NIGHT) &&
4357 (global_color_scheme != GLOBAL_COLOR_SCHEME_DUSK))
4358 global_color_scheme = GLOBAL_COLOR_SCHEME_DAY;
4362bool MyFrame::CheckGroup(
int igroup) {
4363 if (igroup == 0)
return true;
4367 if (!pGroup->m_element_array.size())
4370 for (
const auto &elem : pGroup->m_element_array) {
4371 for (
unsigned int ic = 0;
4372 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4373 auto &cte =
ChartData->GetChartTableEntry(ic);
4374 wxString chart_full_path(cte.GetpFullPath(), wxConvUTF8);
4376 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4383bool MyFrame::ScrubGroupArray() {
4388 bool b_change =
false;
4389 unsigned int igroup = 0;
4390 while (igroup < g_pGroupArray->GetCount()) {
4391 bool b_chart_in_element =
false;
4394 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4395 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4397 for (
unsigned int ic = 0;
4398 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4399 auto &cte =
ChartData->GetChartTableEntry(ic);
4400 wxString chart_full_path = cte.GetFullSystemPath();
4402 if (chart_full_path.StartsWith(element_root)) {
4403 b_chart_in_element =
true;
4409 if (!b_chart_in_element) {
4410 wxString test_string =
"GSHH";
4411 if (element_root.Upper().Contains(test_string))
4412 b_chart_in_element =
true;
4415 if (!b_chart_in_element)
4417 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4429void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4431 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4433 if (cc && (cc != ccThis)) cc->Refresh();
4438void MyFrame::ChartsRefresh() {
4441 AbstractPlatform::ShowBusySpinner();
4443 bool b_run = FrameTimer1.IsRunning();
4446 FrameTenHzTimer.Stop();
4449 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4452 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4453 if (cc->GetQuiltMode()) {
4454 currentIndex = cc->GetQuiltReferenceChartIndex();
4456 cc->canvasChartsRefresh(currentIndex);
4460 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4461 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4463 AbstractPlatform::HideBusySpinner();
4466void MyFrame::InvalidateAllQuilts() {
4467 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4470 cc->InvalidateQuilt();
4471 cc->SetQuiltRefChart(-1);
4472 cc->m_singleChart = NULL;
4477bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4479 const wxString &ChartListFileName) {
4480 bool b_run = FrameTimer1.IsRunning();
4482 FrameTenHzTimer.Stop();
4484 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4485 FrameCOGTimer.Stop();
4488 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4491 cc->InvalidateQuilt();
4492 cc->SetQuiltRefChart(-1);
4493 cc->m_singleChart = NULL;
4503 AbstractPlatform::ShowBusySpinner();
4506 wxString longmsg = _(
"OpenCPN Chart Update");
4508 ".................................................................."
4511 Updateprog =
new wxGenericProgressDialog();
4514 Updateprog->SetFont(*qFont);
4516 Updateprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4517 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4518 wxPD_REMAINING_TIME);
4520 DimeControl(Updateprog);
4525 wxLogMessage(
"Starting chart database Update...");
4529 m_gshhg_chart_loc = gWorldMapLocation;
4530 gWorldMapLocation = wxEmptyString;
4534 AbstractPlatform::HideBusySpinner();
4538void MyFrame::FinalizeChartDBUpdate() {
4540 if (!g_bDeferredInitDone) {
4542 InitTimer.Start(100, wxTIMER_ONE_SHOT);
4545 bool b_groupchange = ScrubGroupArray();
4547 RefreshGroupIndices();
4549 if (b_groupchange) {
4550 pConfig->DestroyConfigGroups();
4555 if (g_bDeferredInitDone) ScheduleReloadCharts();
4560 cc->ToggleCanvasQuiltMode();
4562 bool cur_mode = cc->GetQuiltMode();
4564 if( !cc->GetQuiltMode() )
4565 cc->SetQuiltMode(
true );
4567 if( cc->GetQuiltMode() ) {
4568 cc->SetQuiltMode(
false );
4569 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4573 if( cur_mode != cc->GetQuiltMode() ){
4579 g_bQuiltEnable = cc->GetQuiltMode();
4583 ps52plib->GenerateStateHash();
4591 DoStackDelta(cc, -1);
4597 DoStackDelta(cc, 1);
4600void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4602void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4604void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4606 cc->DoCanvasStackDelta(direction);
4610void MyFrame::PositionIENCToolbar() {
4614 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4616 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4624void MyFrame::OnInitTimer(wxTimerEvent &event) {
4627 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4631 wxLog::FlushActive();
4633 switch (m_iInitCount++) {
4635 EnableSettingsTool(
false);
4640 if (g_bInlandEcdis) {
4641 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4642 double range_set = 500.;
4644 range = wxRound(range * 10) / 10.;
4648 else if (range > 2000.)
4650 else if (range > 1600.)
4652 else if (range > 1200.)
4654 else if (range > 800.)
4659 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4663 g_Platform->SetFullscreen(g_bFullscreen);
4667 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4670 cc->SetGroupIndex(0,
false);
4676 const bool update_started = StartRebuildChartDatabase();
4678 if (update_started) {
4690 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4704 3 * GetCharHeight());
4706 m_data_monitor->Center();
4714 pConfig->SetPath(
"/Settings");
4715 pConfig->Read(
"OptionsSizeX", &sx, -1);
4716 pConfig->Read(
"OptionsSizeY", &sy, -1);
4718 wxWindow *optionsParent =
this;
4720 optionsParent = GetPrimaryCanvas();
4722 BuildiENCToolbar(
true, m_toolbar_callbacks);
4729 if (!g_params.empty()) {
4730 for (
size_t n = 0; n < g_params.size(); n++) {
4731 wxString path = g_params[n];
4732 if (::wxFileExists(path)) {
4734 pSet->load_file(path.fn_str());
4737 pSet->LoadAllGPXObjects(
4738 !pSet->IsOpenCPN(), wpt_dups,
4740 LLBBox box = pSet->GetBBox();
4741 if (box.GetValid()) {
4742 CenterView(GetPrimaryCanvas(), box);
4751 InitAppMsgBusListener();
4756 auto loader = PluginLoader::GetInstance();
4757 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4758 if (!b_haveWMM)
gVar = g_UserVar;
4766 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4769 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4771 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4774 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4778 NavObj_dB::GetInstance().FullSchemaMigrate(
this);
4779 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4780 NavObj_dB::GetInstance().LoadNavObjects();
4783 if (!g_AW1GUID.IsEmpty()) {
4786 if (!g_AW2GUID.IsEmpty()) {
4792 appendOSDirSlash(&layerdir);
4793 layerdir.Append(
"layers");
4795 if (wxDir::Exists(layerdir)) {
4797 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4798 wxLogMessage(laymsg);
4799 pConfig->LoadLayers(layerdir);
4804 if (!g_kiosk_startup) {
4805 AbstractPlatform::ShowBusySpinner();
4808 pConfig->SetPath(
"/Settings");
4809 pConfig->Read(
"OptionsSizeX", &sx, -1);
4810 pConfig->Read(
"OptionsSizeY", &sy, -1);
4812 wxWindow *optionsParent =
this;
4814 optionsParent = GetPrimaryCanvas();
4817 callbacks.prepare_close = [&](
options *me,
int changes) {
4818 PrepareOptionsClose(me, changes);
4820 callbacks.process_dialog = [&](
int changes, ArrayOfCDI *workdir_list) {
4821 ProcessOptionsDialog(changes, workdir_list);
4824 wxPoint(-1, -1), wxSize(sx, sy));
4825 AbstractPlatform::HideBusySpinner();
4832 wxLogMessage(
"OnInitTimer...Last Call");
4836 RequestNewMasterToolbar();
4838 PositionIENCToolbar();
4840 g_bDeferredInitDone =
true;
4850 GetPrimaryCanvas()->SetFocus();
4851 GetPrimaryCanvas()->Enable();
4854 if (b_reloadForPlugins) {
4860 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4862 if (cc) cc->SetFirstAuto(
true);
4870 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4872 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
4876 cc->CheckGroupValid();
4877 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4878 cc->SetShowGPSCompassWindow(
true);
4883 androidEnableBackButton(
true);
4884 androidEnableRotation();
4885 androidEnableOptionItems(
true);
4889 if (g_start_fullscreen && !IsFullScreen()) ToggleFullScreen();
4895 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4897 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4899 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4905 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4907 wxLog::FlushActive();
4909 RefreshAllCanvas(
true);
4910 UsbWatchDaemon::GetInstance().Start();
4911 EnableSettingsTool(g_bDeferredInitDone);
4917void MyFrame::InitAppMsgBusListener() {
4918 auto &msgbus = AppMsgBus::GetInstance();
4921 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4922 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4926 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4927 HandleBasicNavMsg(basicnav_msg);
4931 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4932 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4936 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4937 HandleGPSWatchdogMsg(msg);
4944void MyFrame::ReleaseApiListeners() {}
4949 m_on_raise_listener.Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4950 m_on_quit_listener.Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4951 server.SetGetRestApiEndpointCb([&] {
return m_rest_server.
GetEndpoint(); });
4952 server.open_file_cb = [&](
const std::string &path) {
4953 return m_open_gpx_file(path);
4960void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4961 if (msg->gps_watchdog <= 0) {
4962 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4966 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4971 if (m_fix_start_time.IsValid()) {
4972 wxDateTime now = wxDateTime::Now();
4973 wxTimeSpan span = now - m_fix_start_time;
4974 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4975 auto ¬eman = NotificationManager::GetInstance();
4976 wxString msg = _(
"GNSS Position fix lost");
4977 noteman.AddNotification(NotificationSeverity::kCritical,
4979 m_fix_start_time = wxInvalidDateTime;
4983 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4984 bool last_bVelocityValid = bVelocityValid;
4985 bVelocityValid =
false;
4992void MyFrame::CalculateCOGAverage() {
4994 if (!std::isnan(
gCog)) {
4997 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
5000 double sum = 0., count = 0;
5002 double adder = COGTable[i];
5003 if (std::isnan(adder))
continue;
5005 if (fabs(adder -
g_COGAvg) > 180.) {
5019 else if (sum >= 360.)
5028void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
5029 m_fixtime = msg->time;
5030 double hdt_data_interval = 0;
5031 double fix_time_interval = 0;
5033 double msgtime = msg->set_time.tv_sec;
5034 double m1 = msg->set_time.tv_nsec / 1e9;
5037 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
5038 ((msg->vflag & POS_VALID) == POS_VALID)) {
5040 if (!m_fix_start_time.IsValid()) {
5041 m_fix_start_time = wxDateTime::Now();
5046 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
5049 fix_time_gt_last = fix_time_gt;
5050 uint64_t fix_time_gt_now =
5051 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5052 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5056 double implied_sog = dist / (fix_time_interval / 3600);
5061 gLat_gt_m1 = gLat_gt;
5062 gLon_gt_m1 = gLon_gt;
5066 fix_time_gt = fix_time_gt_now;
5070 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5071 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5072 gCog_gt_m1 = gCog_gt;
5082 if (!std::isnan(gCog_gt_m1)) {
5084 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5091 if ((fix_time_gt - fix_time_gt_last) > .08) {
5096 if (gCog_gt > gCog_gt_m1) {
5097 if ((gCog_gt - gCog_gt_m1) > 180.)
5102 if ((gCog_gt_m1 - gCog_gt) > 180.)
5107 difft = fabs(gCog_gt - gCog_gt_m1);
5108 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5116 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5117 tentative_cog_rate_gt *= 1e9;
5118 cog_rate_gt = tentative_cog_rate_gt;
5126 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5129static double hdt_avg;
5130 double hdt_norm =
gHdt;
5131 if(
gHdt > 180) hdt_norm -= 360;
5134 hdt_avg += hdt_norm * 0.1;
5139 if (!std::isnan(
gHdt)) {
5141 uint64_t hdt_time_gt_last = hdt_time_gt;
5142 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5143 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5146 if (hdt_data_interval > .09) {
5148 gHdt_gt_m1 = gHdt_gt;
5151 if (!std::isnan(gHdt_gt_m1)) {
5153 double tentative_hdt_rate_gt =
5154 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5155 tentative_hdt_rate_gt *= 1e9;
5157 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5158 hdt_rate_gt = tentative_hdt_rate_gt;
5166 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5169 CalculateCOGAverage();
5177 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5178 if ((msg->vflag & POS_VALID) == POS_VALID)
5183 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5185 bVelocityValid =
true;
5189void MyFrame::UpdateStatusBar() {
5192 unsigned long uiCurrentTickCount;
5193 m_MMEAeventTime.SetToCurrent();
5194 uiCurrentTickCount =
5195 m_MMEAeventTime.GetMillisecond() / 100;
5196 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5197 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5198 m_ulLastNMEATicktime = uiCurrentTickCount;
5200 if (m_tick_idx++ > 6) m_tick_idx = 0;
5205 if (NULL != GetStatusBar()) {
5208 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5211 wxString s1(tick_buf, wxConvUTF8);
5213 s1 += toSDMM(1,
gLat);
5215 s1 += toSDMM(2,
gLon);
5217 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5221 if (!std::isnan(
gSog))
5222 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5224 sogcog.Printf(
"SOG --- ");
5228 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5230 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5232 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5233 (
int)toMagnetic(
gCog), 0x00B0);
5235 cogs.Printf((
"COG ---%c"), 0x00B0);
5237 sogcog.Append(cogs);
5238 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5243void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5244 MemFootTimer.Stop();
5246 int memsize = GetApplicationMemoryUse();
5249 printf(
"Memsize: %d \n", memsize);
5252 if (memsize > (g_MemFootMB * 1000)) {
5256 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5257 unsigned int nCache = pCache->GetCount();
5260 for (
unsigned int i = 0; i < nCache; i++) {
5270 for (
unsigned int i = 0; i < nCache - 1; i++) {
5271 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5273 pcea[i] = pcea[i + 1];
5284 unsigned int idelete = 0;
5285 unsigned int idelete_max = pCache->GetCount();
5288 unsigned int minimum_cache = 1;
5289 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5291 while ((memsize > (g_MemFootMB * 1000)) &&
5292 (pCache->GetCount() > minimum_cache) &&
5293 (idelete < idelete_max)) {
5294 int memsizeb = memsize;
5298 memsize = GetApplicationMemoryUse();
5299 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5307 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5312void MyFrame::ProcessUnitTest() {
5313 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5320 cc->m_bFollow =
false;
5322 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5323 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5326 if (cc->m_groupIndex > 0) {
5327 while (ut_index < ChartData->GetChartTableEntries() &&
5328 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5332 if (ut_index < ChartData->GetChartTableEntries()) {
5336 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5337 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5344 if (cc->GetQuiltMode()) {
5345 if (cc->IsChartQuiltableRef(ut_index))
5346 cc->SelectQuiltRefdbChart(ut_index);
5348 cc->SelectdbChart(ut_index);
5351 if (g_unit_test_1) {
5359 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5360 cte->GetLatMin(), cte->GetLonMax(), NULL,
5364 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5365 cte->GetLatMax(), cte->GetLonMin(), NULL,
5368 cc->GetSize(&ww, &wh);
5369 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5371 ppm = wxMin(ppm, 1.0);
5378 if (ut_index > ut_index_max) exit(0);
5389 bool b_rotate =
false;
5391 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5394 if (!b_rotate && !g_btenhertz)
return;
5396 bool b_update =
false;
5398 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5401 struct timespec now;
5402 clock_gettime(CLOCK_MONOTONIC, &now);
5403 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5404 double diffc = diff / 1e9;
5407 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5408 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5409 if (gCog_tentative < 0.) gCog_tentative += 360.;
5410 gCog = gCog_tentative;
5414 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5415 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5416 double diffc = diff / 1e9;
5417 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5421 if (gSog_gt && !std::isnan(gCog_gt)) {
5422 double delta_t = diffc / 3600;
5423 double distance = gSog_gt * delta_t;
5426 double angr = gCog_gt / 180 * M_PI;
5427 double latr = gLat_gt * M_PI / 180;
5428 double D = distance / 3443;
5429 double sD = sin(D), cD = cos(D);
5430 double sy = sin(latr), cy = cos(latr);
5431 double sa = sin(angr), ca = cos(angr);
5433 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5434 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5444 if (cc) cc->DoCanvasCOGSet();
5453 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5454 bool bnew = cc->DoCanvasUpdate();
5455 if (!bnew) cc->UpdateShips();
5464 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5467bool MyFrame::ProcessQuitFlag() {
5471 FrameTenHzTimer.Stop();
5473 wxWindow *top = wxTheApp ? wxTheApp->GetTopWindow() :
nullptr;
5474 if (top) top->Close(
true);
5481void MyFrame::ProcessDeferredTrackOn() {
5484 if (g_bDeferredStartTrack) {
5485 if (!g_bTrackActive) {
5488 g_bDeferredStartTrack =
false;
5491 g_bDeferredStartTrack =
false;
5496void MyFrame::ProcessAnchorWatch() {
5504 double d = g_nAWMax;
5507 bool toofar =
false;
5508 bool tooclose =
false;
5509 if (d >= 0.0) toofar = (dist * 1852. > d);
5510 if (d < 0.0) tooclose = (dist * 1852 < -d);
5512 if (tooclose || toofar)
5513 AnchorAlertOn1 =
true;
5515 AnchorAlertOn1 =
false;
5517 AnchorAlertOn1 =
false;
5525 double d = g_nAWMax;
5528 bool toofar =
false;
5529 bool tooclose =
false;
5530 if (d >= 0) toofar = (dist * 1852. > d);
5531 if (d < 0) tooclose = (dist * 1852 < -d);
5533 if (tooclose || toofar)
5534 AnchorAlertOn2 =
true;
5536 AnchorAlertOn2 =
false;
5538 AnchorAlertOn2 =
false;
5541 AnchorAlertOn1 =
true;
5544void MyFrame::SendFixToPlugins() {
5555 GPSData.
nSats = g_SatsInView;
5557 wxDateTime tCheck((time_t)m_fixtime);
5558 if (tCheck.IsValid()) {
5567 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5570 SendPositionFixToAllPlugIns(&GPSData);
5574void MyFrame::ProcessLogAndBells() {
5577 wxDateTime lognow = wxDateTime::Now();
5578 int hourLOC = lognow.GetHour();
5579 int minuteLOC = lognow.GetMinute();
5581 int minuteUTC = lognow.GetMinute();
5582 int second = lognow.GetSecond();
5584 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5585 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5586 (minuteUTC == 30)) {
5587 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5588 wxString day = lognow.FormatISODate();
5589 wxString utc = lognow.FormatISOTime();
5590 wxString navmsg =
"LOGBOOK: ";
5598 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5602 if (std::isnan(
gCog))
5603 cog.Printf(
"COG ----- ");
5605 cog.Printf(
"COG %10.5f ",
gCog);
5608 if (std::isnan(
gSog))
5609 sog.Printf(
"SOG ----- ");
5611 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5617 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5620 wxLogMessage(navmsg);
5621 g_loglast_time = lognow;
5623 int bells = (hourLOC % 4) * 2;
5624 if (minuteLOC != 0) bells++;
5625 if (!bells) bells = 8;
5627 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5628 m_BellsToPlay = bells;
5629 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5630 wxPostEvent(
this, ev);
5639 if (ProcessQuitFlag())
return;
5641 if (bDBUpdateInProgress)
return;
5644 FrameTenHzTimer.Stop();
5646 ProcessDeferredTrackOn();
5648 ProcessAnchorWatch();
5649 ProcessLogAndBells();
5651 if (ShouldRestartTrack()) TrackDailyRestart();
5654 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5655 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5656 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5662 if (
gSog > 3.0) g_bCruising =
true;
5668 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5670 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5676 bool bnew_view =
false;
5677 if (!g_btenhertz) bnew_view = DoChartUpdate();
5684 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5687 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5690 cc->DrawBlinkObjects();
5693 if (bactiveRouteUpdate) {
5700 cc->SetOwnShipState(SHIP_NORMAL);
5702 if (cc->GetQuiltMode()) {
5703 double erf = cc->GetQuiltMaxErrorFactor();
5704 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5706 if (cc->m_singleChart) {
5707 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5708 cc->SetOwnShipState(SHIP_LOWACCURACY);
5712 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5715 (bVelocityValid != m_last_bVelocityValid) ||
5716 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5717 if (!g_bopengl) cc->UpdateShips();
5725 m_last_bVelocityValid = bVelocityValid;
5730 bool brq_dynamic =
false;
5732 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5733 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5735 if (pic->m_enabled && pic->m_init_state) {
5736 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5743 if (brq_dynamic) bnew_view =
true;
5747 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5750 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5755 if (cc->GetglCanvas()) {
5757 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5759 if ((!g_btenhertz)) {
5760 if (cc->m_bFollow) {
5761 cc->DoCanvasUpdate();
5778 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5792 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5793 g_pais_query_dialog_active->UpdateText();
5796 if (g_pAISTargetList && (0 == (g_tick % (5))))
5797 g_pAISTargetList->UpdateAISTargetList();
5800 UpdateGPSCompassStatusBoxes();
5805 console->RefreshConsoleData();
5812 if (m_bdefer_resize) {
5813 if (0 == (g_tick % (5))) {
5814 printf(
"___RESIZE\n");
5815 SetSize(m_defer_size);
5817 m_bdefer_resize =
false;
5824 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5826 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5827 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5831double MyFrame::GetMag(
double a,
double lat,
double lon) {
5832 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5833 auto loader = PluginLoader::GetInstance();
5834 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5841 wxDateTime now = wxDateTime::Now();
5842 SendJSON_WMM_Var_Request(lat, lon, now);
5843 if (fabs(gQueryVar) < 360.0)
5844 Variance = gQueryVar;
5846 return toMagnetic(a, Variance);
5849bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5855 v[
"Year"] = date.GetYear();
5856 v[
"Month"] = date.GetMonth();
5857 v[
"Day"] = date.GetDay();
5859 SendJsonMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5865void MyFrame::TouchAISActive() {
5867 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5869 if (cc) cc->TouchAISToolActive();
5873void MyFrame::UpdateAISTool() {
5877 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5879 if (cc) cc->UpdateAISTBTool();
5884void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5886 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5888 if (cc) cc->SetbTCUpdate(
true);
5891 RefreshAllCanvas(
false);
5896void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5900 bool b_rotate =
false;
5901 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5903 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5907 FrameCOGTimer.Stop();
5914 int period_ms = 100;
5916 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5919void MyFrame::DoCOGSet() {
5921 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5923 if (cc) cc->DoCanvasCOGSet();
5927void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5933 wxFont oldfont = pdc->GetFont();
5935 pdc->SetFont(*pFont);
5936 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5937 pdc->SetBackgroundMode(wxTRANSPARENT);
5939 pdc->DrawText(str, x, y + 1);
5940 pdc->DrawText(str, x, y - 1);
5941 pdc->DrawText(str, x + 1, y);
5942 pdc->DrawText(str, x - 1, y);
5944 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5946 pdc->DrawText(str, x, y);
5948 pdc->SetFont(oldfont);
5952void MyFrame::UpdateRotationState(
double rotation) {
5954 g_bCourseUp =
false;
5956 if (fabs(rotation) > .001) {
5957 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5958 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5960 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5963 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5964 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5966 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5970 UpdateGPSCompassStatusBoxes(
true);
5974void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5976 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
5978 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5984int MyFrame::GetApplicationMemoryUse() {
5990 wxWindow *fWin = wxWindow::FindFocus();
5992 wxArrayString outputArray;
5993 wxString cmd(
"ps --no-headers -o vsize ");
5994 unsigned long pid = wxGetProcessId();
5996 cmd1.Printf(
"%ld", pid);
5998 wxExecute(cmd, outputArray);
6000 if (outputArray.GetCount()) {
6001 wxString s = outputArray.Item(0);
6003 if (s.ToLong(&vtmp)) memsize = vtmp;
6006 if (fWin) fWin->SetFocus();
6012 PROCESS_MEMORY_COUNTERS pmc;
6014 unsigned long processID = wxGetProcessId();
6016 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6018 if (NULL == hProcess)
return 0;
6020 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6038 memsize = pmc.WorkingSetSize / 1024;
6041 CloseHandle(hProcess);
6048double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6049 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6052void MyFrame::SetChartUpdatePeriod() {
6055 g_ChartUpdatePeriod = 0;
6060 bool bskewdc =
false;
6061 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6064 if (!g_bopengl && !cc->GetVP().b_quilt) {
6065 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6067 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6071 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6073 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6078 cc->UpdateCanvasControlBar();
6081void MyFrame::selectChartDisplay(
int type,
int family) {
6083 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6085 if (cc) cc->selectCanvasChartDisplay(type, family);
6088 UpdateGlobalMenuItems();
6097bool MyFrame::DoChartUpdate() {
6098 bool return_val =
false;
6101 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6103 if (cc) return_val |= cc->DoCanvasUpdate();
6109void MyFrame::MouseEvent(wxMouseEvent &event) {
6111 event.GetPosition(&x, &y);
6116#include <mach/mach.h>
6117#include <mach/message.h>
6118#include <mach/kern_return.h>
6119#include <mach/task_info.h>
6121#include <malloc/malloc.h>
6128#if defined(__linux__)
6129#include "sys/types.h"
6130#include "sys/sysinfo.h"
6133void MyFrame::DoPrint(
void) {
6135 g_PrintingInProgress =
true;
6138 GetPrimaryCanvas()->GetglCanvas()->Render();
6139 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6149 printer.Initialize(wxLANDSCAPE);
6150 printer.EnablePageNumbers(
false);
6153 bool tooltips_were_enabled = DisableTbarTooltips();
6154 printer.Print(
this, &printout);
6155 if (tooltips_were_enabled) {
6156 EnableTbarTooltips();
6175 g_PrintingInProgress =
false;
6178 GetPrimaryCanvas()->SetFocus();
6184 wxString message_ID =
event.GetID();
6185 wxString message_JSONText =
event.GetJSONText();
6193 if (message_ID ==
"WMM_VARIATION_BOAT") {
6194 nlohmann::json root;
6196 root = nlohmann::json::parse(message_JSONText);
6197 }
catch (nlohmann::json::exception &) {
6202 gVar = root[
"Decl"].get<
double>();
6203 }
catch (nlohmann::json::exception &) {
6209 if (message_ID ==
"WMM_VARIATION") {
6210 nlohmann::json root;
6212 root = nlohmann::json::parse(message_JSONText);
6213 }
catch (nlohmann::json::exception &) {
6217 double decl_val = 0.0;
6218 if (root[
"Decl"].is_number()) {
6219 decl_val = root[
"Decl"].get<
double>();
6220 }
else if (root[
"Decl"].is_string()) {
6221 decl_val = std::stod(root[
"Decl"].get<std::string>());
6224 gQueryVar = decl_val;
6227 if (message_ID ==
"GRIB_TIMELINE") {
6230 v = nlohmann::json::parse(message_JSONText);
6231 }
catch (nlohmann::json::exception &) {
6232 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6235 wxDateTime oldTimeSource = gTimeSource;
6237 if (v[
"Day"].get<int>() == -1) {
6238 gTimeSource = wxInvalidDateTime;
6239 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6241 gTimeSource.Set(v[
"Day"].get<int>(),
6242 (wxDateTime::Month)v[
"Month"].get<int>(),
6243 v[
"Year"].get<int>(), v[
"Hour"].get<int>(),
6244 v[
"Minute"].get<int>(), v[
"Second"].get<int>());
6248 if (oldTimeSource != gTimeSource) {
6250 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6252 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6257 cc->pCwin->Refresh(
false);
6263 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6264 nlohmann::json root;
6265 wxString trk_id =
"";
6268 root = nlohmann::json::parse(message_JSONText);
6269 }
catch (nlohmann::json::exception &) {
6272 if (root.contains(
"Track_ID")) trk_id = root[
"Track_ID"].get<std::string>();
6275 v[
"Track_ID"] = trk_id;
6277 wxString name = wxEmptyString;
6278 if (ptrack->m_GUID == trk_id) {
6279 name = ptrack->GetName();
6280 if (name.IsEmpty()) {
6286 name = _(
"(Unnamed Track)");
6293 v[
"TotalNodes"] = ptrack->GetnPoints();
6294 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6296 v[
"lat"] = tp->m_lat;
6297 v[
"lon"] = tp->m_lon;
6300 SendJsonMessageToAllPlugins(
"OCPN_TRACKPOINTS_COORDS", v);
6305 SendJsonMessageToAllPlugins(
"OCPN_TRACKPOINTS_COORDS", v);
6307 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6308 nlohmann::json root;
6311 root = nlohmann::json::parse(message_JSONText);
6312 }
catch (nlohmann::json::exception &) {
6316 if (root.contains(
"GUID")) guid = root[
"GUID"].get<std::string>();
6321 wxString name = wxEmptyString;
6323 if ((*it)->m_GUID == guid) {
6324 name = (*it)->m_RouteNameString;
6325 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6331 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6332 itp != (*it)->pRoutePointList->end(); itp++) {
6333 w[i][
"lat"] = (*itp)->m_lat;
6334 w[i][
"lon"] = (*itp)->m_lon;
6335 w[i][
"Name"] = (*itp)->GetName();
6336 w[i][
"Description"] = (*itp)->GetDescription();
6337 w[i][
"GUID"] = (*itp)->m_GUID;
6338 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6340 auto node = (*itp)->m_HyperlinkList->begin();
6341 if (node != (*itp)->m_HyperlinkList->end()) {
6343 while (node != (*itp)->m_HyperlinkList->end()) {
6345 v[i][
"WPLink" + std::to_string(n)] = httpLink->Link;
6346 v[i][
"WPLinkDesciption" + std::to_string(n++)] =
6347 httpLink->DescrText;
6354 SendJsonMessageToAllPlugins(
"OCPN_ROUTE_RESPONSE", v);
6360 SendJsonMessageToAllPlugins(
"OCPN_ROUTE_RESPONSE", v);
6361 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6362 nlohmann::json root;
6365 root = nlohmann::json::parse(message_JSONText);
6366 }
catch (nlohmann::json::exception &) {
6369 if (root.contains(
"mode")) {
6370 if (root[
"mode"].get<std::string>() ==
"Track") route =
false;
6375 for (RouteList::iterator it =
pRouteList->begin();
6377 wxString name = (*it)->m_RouteNameString;
6378 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6380 v[i][
"error"] =
false;
6381 v[i][
"name"] = name;
6382 v[i][
"GUID"] = (*it)->m_GUID;
6383 v[i][
"active"] = (*it)->IsActive();
6388 wxString name = ptrack->GetName();
6389 if (name.IsEmpty()) {
6395 name = _(
"(Unnamed Track)");
6397 v[i][
"error"] =
false;
6398 v[i][
"name"] = name;
6399 v[i][
"GUID"] = ptrack->m_GUID;
6404 SendJsonMessageToAllPlugins(
"OCPN_ROUTELIST_RESPONSE", v);
6407 v[0][
"error"] =
true;
6408 SendJsonMessageToAllPlugins(
"OCPN_ROUTELIST_RESPONSE", v);
6410 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6412 v[0][
"error"] =
true;
6415 v[0][
"error"] =
false;
6416 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6417 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6418 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6419 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6420 v[0][
"active_waypoint_lat"] =
6422 v[0][
"active_waypoint_lon"] =
6426 SendJsonMessageToAllPlugins(
"OCPN_ACTIVE_ROUTELEG_RESPONSE", v);
6430void MyFrame::FilterCogSog() {
6431 if (g_bfilter_cogsog) {
6433 double cog_last =
gCog;
6436 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6437 COGFilterTable[i] = COGFilterTable[i - 1];
6438 COGFilterTable[0] = cog_last;
6441 if (!std::isnan(cog_last)) {
6443 double sum = 0., count = 0;
6444 for (
int i = 0; i < g_COGFilterSec; i++) {
6445 double adder = COGFilterTable[i];
6446 if (std::isnan(adder))
continue;
6448 if (fabs(adder - cog_last) > 180.) {
6449 if ((adder - cog_last) > 0.)
6462 else if (sum >= 360.)
6469 double sog_last =
gSog;
6472 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6473 SOGFilterTable[i] = SOGFilterTable[i - 1];
6474 SOGFilterTable[0] = sog_last;
6477 if (!std::isnan(
gSog)) {
6478 double sum = 0., count = 0;
6479 for (
int i = 0; i < g_SOGFilterSec; i++) {
6480 if (std::isnan(SOGFilterTable[i]))
continue;
6482 sum += SOGFilterTable[i];
6492void MyFrame::LoadHarmonics() {
6495 ptcmgr->LoadDataSources(TideCurrentDataSet);
6497 bool b_newdataset =
false;
6500 for (
auto a :
ptcmgr->GetDataSet()) {
6501 bool b_foundi =
false;
6502 for (
auto b : TideCurrentDataSet) {
6509 b_newdataset =
true;
6514 for (
auto a : TideCurrentDataSet) {
6515 bool b_foundi =
false;
6516 for (
auto b :
ptcmgr->GetDataSet()) {
6523 b_newdataset =
true;
6528 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6532void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6533 if (!ptarget)
return;
6536 wxDateTime mob_time = wxDateTime::Now();
6537 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6538 mob_label += _(
" on ");
6539 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6542 mob_label, wxEmptyString);
6543 pWP_MOB->SetShared(
true);
6545 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6547 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6549 pWP_MOB->SetUseSca(
false);
6557 wxString(_(
"Own ship")), wxEmptyString);
6559 pWP_MOB->SetUseSca(
false);
6566 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6582 SendJsonMessageToAllPlugins(
"OCPN_MAN_OVERBOARD", v);
6585 if (RouteManagerDialog::getInstanceFlag()) {
6592 RefreshAllCanvas(
false);
6594 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6595 mob_message += _(
" Time: ");
6596 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6597 mob_message += _(
" Ownship Position: ");
6598 mob_message += toSDMM(1,
gLat);
6600 mob_message += toSDMM(2,
gLon);
6601 mob_message += _(
" MOB Position: ");
6602 mob_message += toSDMM(1, ptarget->Lat);
6604 mob_message += toSDMM(2, ptarget->Lon);
6605 wxLogMessage(mob_message);
6608void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6612 OwnPoint->m_lat =
gLat;
6613 OwnPoint->m_lon =
gLon;
6615 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6620 MOB_Point->m_lat = ptarget->Lat;
6621 MOB_Point->m_lon = ptarget->Lon;
6623 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6624 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6626 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6627 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6630 RefreshAllCanvas(
false);
6633 wxDateTime mob_time = wxDateTime::Now();
6635 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6636 mob_message += _(
" Time: ");
6637 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6638 mob_message += _(
" Ownship Position: ");
6639 mob_message += toSDMM(1,
gLat);
6641 mob_message += toSDMM(2,
gLon);
6642 mob_message += _(
" MOB Position: ");
6643 mob_message += toSDMM(1, ptarget->Lat);
6645 mob_message += toSDMM(2, ptarget->Lon);
6647 wxLogMessage(mob_message);
6651void MyFrame::applySettingsString(wxString settings) {
6653 int last_UIScaleFactor = g_GUIScaleFactor;
6654 bool previous_expert = g_bUIexpert;
6655 g_last_ChartScaleFactor = g_ChartScaleFactor;
6656 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6659 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6665 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6667 if (rr & S52_CHANGED) {
6669 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6671 ->ClearCNSYLUPArray();
6672 ps52plib->GenerateStateHash();
6676 ProcessOptionsDialog(rr, pNewDirArray);
6681 bool b_newToolbar =
false;
6683 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6685 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6687 if (rr & TOOLBAR_CHANGED) {
6688 b_newToolbar =
true;
6693 if (previous_expert && !g_bUIexpert) {
6694 androidForceFullRepaint();
6698 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6702 SetGPSCompassScale();
6704 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
6706 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6708 UpdateGPSCompassStatusBoxes(
true);
6711 AbstractPlatform::ShowBusySpinner();
6713 SetAllToolbarScale();
6717 AbstractPlatform::HideBusySpinner();
6719 RequestNewMasterToolbar(
true);
6726 UpdateControlBar(GetPrimaryCanvas());
6732 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6735#ifdef wxHAS_POWER_EVENTS
6736void MyFrame::OnSuspending(wxPowerEvent &event) {
6740 wxLogMessage(
"System suspend starting...");
6743void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6746 wxLogMessage(
"System is going to suspend.");
6749void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6752 wxLogMessage(
"System suspend was cancelled.");
6755int g_last_resume_ticks;
6756void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6757 wxDateTime now = wxDateTime::Now();
6758 wxLogMessage(
"System resumed from suspend.");
6760 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6763 wxLogMessage(
"Restarting streams.");
6764 g_last_resume_ticks = now.GetTicks();
6768 g_pMUX->ClearStreams();
6770 g_pMUX->StartAllStreams();
6779 if (IsMaximized()) {
6784 wxSize sz = GetSize();
6785 SetSize(wxSize(sz.x - 1, sz.y));
6797void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6798 bool btbRebuild =
false;
6800 bool b_reshow =
true;
6803 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6804 if ((ff > 0.01f) || bforcenew) {
6814 long orient = g_Platform->GetDefaultToolbarOrientation();
6815 wxWindow *toolbarParent =
this;
6817 toolbarParent = GetPrimaryCanvas();
6819 if (!g_bInlandEcdis)
6820 g_maintoolbar_y = 4;
6822 g_maintoolbar_y = 8 +
g_iENCToolbar->GetToolbarRect().height;
6825 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor,
6826 m_toolbar_callbacks);
6828 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6835 g_bmasterToolbarFull =
true;
6839 CreateMasterToolbar();
6849bool MyFrame::CollapseGlobalToolbar() {
6851 m_nMasterToolCountShown = 1;
6855 g_bmasterToolbarFull =
false;
6871 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6872 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6873 tic->m_bRequired =
true;
6878 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6879 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6883 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6884 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6885 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6890 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6891 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6895 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6896 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6897 _(
"Enable Tracking"),
"MUI_track");
6901 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6902 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6914 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6915 _(
"Print Chart"),
"MUI_print");
6919 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6920 _(
"About OpenCPN"),
"MUI_help");
6924 AddDefaultPositionPlugInTools();
6928 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6929 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6940 ArrayOfPlugInToolbarTools tool_array =
6942 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6944 if (!pttc->b_viz)
continue;
6946 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6949 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6950 if (g_bTrackActive) {
6951 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6958bool MyFrame::CheckAndAddPlugInTool() {
6966 if (!tb)
return false;
6968 int n_tools = tb->GetToolsCount();
6972 ArrayOfPlugInToolbarTools tool_array =
6975 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6977 if (pttc->position == n_tools) {
6978 wxBitmap *ptool_bmp;
6980 switch (global_color_scheme) {
6981 case GLOBAL_COLOR_SCHEME_DAY:
6982 case GLOBAL_COLOR_SCHEME_DAY_HICON:
6983 ptool_bmp = pttc->bitmap_day;
6986 case GLOBAL_COLOR_SCHEME_DUSK:
6987 case GLOBAL_COLOR_SCHEME_NIGHT_HICON:
6988 ptool_bmp = pttc->bitmap_dusk;
6990 case GLOBAL_COLOR_SCHEME_NIGHT:
6991 ptool_bmp = pttc->bitmap_night;
6994 ptool_bmp = pttc->bitmap_day;
6999 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7001 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7002 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7003 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7004 tic->m_bPlugin =
true;
7013 while (CheckAndAddPlugInTool()) {
7019bool MyFrame::AddDefaultPositionPlugInTools() {
7026 ArrayOfPlugInToolbarTools tool_array =
7029 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7033 if (!pttc->b_viz)
continue;
7035 if (pttc->position == -1)
7037 wxBitmap *ptool_bmp;
7039 switch (global_color_scheme) {
7040 case GLOBAL_COLOR_SCHEME_DAY:
7041 case GLOBAL_COLOR_SCHEME_DAY_HICON:
7042 ptool_bmp = pttc->bitmap_day;
7044 case GLOBAL_COLOR_SCHEME_DUSK:
7045 case GLOBAL_COLOR_SCHEME_NIGHT_HICON:
7046 ptool_bmp = pttc->bitmap_dusk;
7048 case GLOBAL_COLOR_SCHEME_NIGHT:
7049 ptool_bmp = pttc->bitmap_night;
7052 ptool_bmp = pttc->bitmap_day;
7057 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7059 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7060 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7061 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7062 tic->m_bPlugin =
true;
7081typedef struct _MSW_COLOR_SPEC {
7083 wxString S52_RGB_COLOR;
7087MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7088 {COLOR_MENUTEXT,
"UITX1", 0},
7089 {COLOR_BTNSHADOW,
"UIBCK", 0},
7092void SaveSystemColors() {
7106 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7107 while (pcspec->COLOR_NAME != -1) {
7108 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7113void RestoreSystemColors() {
7114 int element[NCOLORS];
7115 int rgbcolor[NCOLORS];
7118 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7119 while (pcspec->COLOR_NAME != -1) {
7120 element[i] = pcspec->COLOR_NAME;
7121 rgbcolor[i] = pcspec->SysRGB_COLOR;
7126 if (pSetSysColors) {
7127 pSetSysColors(i, (
unsigned long *)&element[0],
7128 (
unsigned long *)&rgbcolor[0]);
7134void SetSystemColors(ColorScheme cs) {
7136 int element[NCOLORS];
7137 int rgbcolor[NCOLORS];
7139 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs) ||
7140 (GLOBAL_COLOR_SCHEME_NIGHT_HICON == cs)) {
7141 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7142 while (pcspec->COLOR_NAME != -1) {
7143 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7144 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7145 element[i] = pcspec->COLOR_NAME;
7151 pSetSysColors(i, (
unsigned long *)&element[0],
7152 (
unsigned long *)&rgbcolor[0]);
7156 RestoreSystemColors();
7163static const WORD MAX_CONSOLE_LINES =
7168void RedirectIOToConsole()
7173 wxIntPtr lStdHandle;
7175 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7185 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7186 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7187 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7191 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7192 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7193 fp = _fdopen(hConHandle,
"w");
7195 setvbuf(stdout, NULL, _IONBF, 0);
7199 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7200 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7201 fp = _fdopen(hConHandle,
"r");
7203 setvbuf(stdin, NULL, _IONBF, 0);
7207 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7208 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7209 fp = _fdopen(hConHandle,
"w");
7211 setvbuf(stderr, NULL, _IONBF, 0);
7222 FontMgr::Get().SetLocale(g_locale);
7243 if (g_pais_query_dialog_active) {
7244 g_pais_query_dialog_active->Destroy();
7245 g_pais_query_dialog_active = NULL;
7248 auto alert_dlg_active =
7250 if (alert_dlg_active) {
7251 alert_dlg_active->Destroy();
7252 g_pais_alert_dialog_active =
nullptr;
7255 if (g_pAISTargetList) {
7257 g_pAISTargetList->Disconnect_decoder();
7258 g_pAISTargetList->Destroy();
7259 g_pAISTargetList = NULL;
7263 if (gFrame->m_pMenuBar) {
7264 gFrame->SetMenuBar(NULL);
7265 gFrame->m_pMenuBar->Destroy();
7266 gFrame->m_pMenuBar = NULL;
7268 gFrame->BuildMenuBar();
7271 for (
unsigned int i = 0; i <
g_canvasArray.GetCount(); i++) {
7273 if (cc) cc->CanvasApplyLocale();
7278 wxString perspective;
7280 pConfig->Read(
"AUIPerspective", &perspective);
7294 bool bno_load =
false;
7295 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7297 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7298 wxAuiPaneInfo pane = pane_array_val[i];
7299 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7305 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7310 gFrame->RequestNewToolbars(
true);
7311 gFrame->RequestNewMasterToolbar(
true);
7318 : wxThread(wxTHREAD_JOINABLE) {
7319 m_filename = filename;
7330 newChart->SetNativeScale(m_scale);
7331 newChart->SetFullExtent(m_ext);
7333 newChart->FindOrCreateSenc(m_filename);
7338 wxString m_filename;
7344static double chart_dist(
int index) {
7350 if (cte.GetBBox().Contains(
gLat,
gLon))
7355 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7356 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7357 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7360 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7361 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7363 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7369WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7370static int CompareInts(
int n1,
int n2) {
7371 double d1 = chart_dist(n1);
7372 double d2 = chart_dist(n2);
7373 return (
int)(d1 - d2);
7378 wxString chart_path;
7383WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7385#include <wx/arrimpl.cpp>
7388void ParseAllENC(wxWindow *parent) {
7389 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7397 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7400 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7402 idx_sorted_by_distance.Add(i);
7406 if (count == 0)
return;
7408 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7414 ArrayOfCompressTargets ct_array;
7415 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7416 int i = idx_sorted_by_distance[j];
7419 double distance = chart_dist(i);
7421 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7424 pct->distance = distance;
7425 pct->chart_path = filename;
7427 ct_array.push_back(pct);
7430 int thread_count = 0;
7433 if (g_nCPUCount > 0)
7434 thread_count = g_nCPUCount;
7436 thread_count = wxThread::GetCPUCount();
7438 if (thread_count < 1) {
7447 for(
int t = 0; t < thread_count; t++)
7451 wxGenericProgressDialog *prog =
nullptr;
7455 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
7456 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
7458 prog =
new wxGenericProgressDialog();
7460 prog->SetFont(*qFont);
7462 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
7463 count + 1, parent, style);
7472 prog->ShowWindowModal();
7481 for (
unsigned int j = 0; j < ct_array.size(); j++) {
7482 wxString filename = ct_array[j].chart_path;
7483 double distance = ct_array[j].distance;
7484 int index =
ChartData->FinddbIndex(filename);
7485 if (index < 0)
continue;
7488 ext.NLAT = cte.GetLatMax();
7489 ext.SLAT = cte.GetLatMin();
7490 ext.WLON = cte.GetLonMin();
7491 ext.ELON = cte.GetLonMax();
7493 int scale = cte.GetScale();
7496 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
7499 if (wxThread::IsMain()) {
7501 wxSize sz = prog->GetSize();
7506 prog->Update(count, msg, &skip);
7518 newChart->SetNativeScale(
scale);
7519 newChart->SetFullExtent(ext);
7520 newChart->DisableBackgroundSENC();
7522 newChart->FindOrCreateSenc(filename,
7526 if (wxThread::IsMain()) {
7527 msg.Printf(_(
"ENC Completed."));
7529 prog->Update(count, msg, &skip);
7539 for (
int t = 0;; t = (t + 1) % thread_count) {
7546 if (!workers[t]->IsAlive()) {
7559#if defined(__WXMSW__) || defined(__WXOSX__)
7566 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.