53#include <wx/stdpaths.h>
54#include <wx/tokenzr.h>
55#include <wx/display.h>
56#include <wx/jsonreader.h>
58#include "o_sound/o_sound.h"
83#include "model/nav_object_database.h"
96#include "ais_info_gui.h"
97#include "dialog_alert.h"
101#include "ais_info_gui.h"
125#include "load_errors_dlg.h"
128#include "N2KParser.h"
155#include "androidUTIL.h"
159static constexpr long kFrameStyle = wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS;
166arrayofCanvasPtr g_canvasArray;
172GLenum g_texture_rectangle_format;
175#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
176extern wxLocale *plocale_def_lang;
180extern bool g_b_EnableVBO;
181extern GLenum g_texture_rectangle_format;
185static int g_last_ChartScaleFactor;
186static char nmea_tick_chars[] = {
'|',
'/',
'-',
'\\',
'|',
'/',
'-',
'\\'};
187static int options_subpage = 0;
188static bool b_reloadForPlugins;
190static wxSize options_lastWindowSize(0, 0);
191static wxPoint options_lastWindowPos(0, 0);
195static double gQueryVar = 361.0;
197static char bells_sound_file_name[2][12] = {
"1bells.wav",
"2bells.wav"};
198static o_sound::Sound *_bells_sounds[] = {o_sound::Factory(),
200static std::vector<o_sound::Sound *> bells_sound(_bells_sounds,
203static wxArrayPtrVoid *UserColourHashTableArray;
208typedef DWORD(WINAPI *SetSysColors_t)(DWORD, DWORD *, DWORD *);
209typedef DWORD(WINAPI *GetSysColor_t)(DWORD);
211static SetSysColors_t pSetSysColors;
212static GetSysColor_t pGetSysColor;
214void SaveSystemColors();
215void RestoreSystemColors();
220DWORD color_3ddkshadow;
222DWORD color_activecaption;
223DWORD color_gradientactivecaption;
224DWORD color_captiontext;
225DWORD color_windowframe;
226DWORD color_inactiveborder;
231#include <wx/msw/msvcrt.h>
235static const long long lNaN = 0xfff8000000000000;
236#define NAN (*(double *)&lNaN)
239static wxArrayPtrVoid *UserColorTableArray = 0;
242static double gLat_gt, gLon_gt;
243static double gLat_gt_m1, gLon_gt_m1;
244static uint64_t fix_time_gt;
245static uint64_t fix_time_gt_last;
247static double gSog_gt, gHdt_gt;
248static double gCog_gt_m1, gHdt_gt_m1;
249static uint64_t hdt_time_gt;
250static double cog_rate_gt, hdt_rate_gt;
252void InitializeUserColors();
253void DeInitializeUserColors();
254void SetSystemColors(ColorScheme cs);
256static bool LoadAllPlugIns(
bool load_enabled) {
257 AbstractPlatform::ShowBusySpinner();
258 bool b = PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled);
259 AbstractPlatform::HideBusySpinner();
263static void LaunchLocalHelp() {
265 androidLaunchHelpView();
267 wxString def_lang_canonical =
"en_US";
270 if (plocale_def_lang)
271 def_lang_canonical = plocale_def_lang->GetCanonicalName();
274 wxString help_locn = g_Platform->GetSharedDataDir() +
"doc/help_";
276 wxString help_try = help_locn + def_lang_canonical +
".html";
278 if (!::wxFileExists(help_try)) {
279 help_try = help_locn +
"en_US" +
".html";
281 if (!::wxFileExists(help_try)) {
282 help_try = help_locn +
"web" +
".html";
285 if (!::wxFileExists(help_try))
return;
288 wxLaunchDefaultBrowser(wxString(
"file:///") + help_try);
292static void DoHelpDialog() {
304 [] { LaunchLocalHelp(); });
316#if defined(__WXGTK__) || defined(__WXQT__)
317#include "bitmaps/opencpn.xpm"
331void BuildiENCToolbar(
bool bnew) {
332 if (g_bInlandEcdis) {
336 wxPoint tbp_incanvas =
339 g_iENCToolbarPosY = tbp_incanvas.y;
340 g_iENCToolbarPosX = tbp_incanvas.x;
348 wxPoint posn(g_iENCToolbarPosX, g_iENCToolbarPosY);
352 if ((g_iENCToolbarPosY > g_maintoolbar_y) &&
355 g_iENCToolbarPosY = -1;
358 if ((g_iENCToolbarPosX < 0) || (g_iENCToolbarPosY < 0)) {
364 wxPoint(g_maintoolbar_x +
g_MainToolbar->GetToolbarSize().x + 4,
368 double tool_scale_factor =
369 g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
372 new iENCToolbar(gFrame, posn, wxTB_HORIZONTAL, tool_scale_factor);
383 if (chart ==
nullptr)
return false;
386 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
388 if (cc && cc->m_singleChart == chart) {
395#if defined(__WXGTK__) && defined(OCPN_HAVE_X11)
398static char *get_X11_property(Display *disp, Window win, Atom xa_prop_type,
399 const char *prop_name) {
403 unsigned long ret_nitems;
404 unsigned long ret_bytes_after;
405 unsigned char *ret_prop;
407 xa_prop_name = XInternAtom(disp, prop_name, False);
415 if (XGetWindowProperty(disp, win, xa_prop_name, 0, 1024, False, xa_prop_type,
416 &xa_ret_type, &ret_format, &ret_nitems,
417 &ret_bytes_after, &ret_prop) != Success)
420 if (xa_ret_type != xa_prop_type) {
424 return (
char *)ret_prop;
429static bool isTransparentToolbarInOpenGLOK() {
436 if (!g_bdisable_opengl) {
437 Display *disp = XOpenDisplay(NULL);
439 if ((sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
441 "_NET_SUPPORTING_WM_CHECK")) ||
442 (sup_window = (Window *)get_X11_property(disp, DefaultRootWindow(disp),
444 "_WIN_SUPPORTING_WM_CHECK"))) {
447 if ((wm_name = get_X11_property(disp, *sup_window,
448 XInternAtom(disp,
"UTF8_STRING", False),
450 (wm_name = get_X11_property(disp, *sup_window, XA_STRING,
453 if (strstr(wm_name,
"Xfwm4") || strstr(wm_name,
"Compiz"))
474wxDEFINE_EVENT(BELLS_PLAYED_EVTYPE, wxCommandEvent);
476BEGIN_EVENT_TABLE(
MyFrame, wxFrame)
477EVT_CLOSE(MyFrame::OnCloseWindow)
478EVT_MENU(wxID_EXIT, MyFrame::OnExit)
479EVT_SIZE(MyFrame::OnSize)
480EVT_MOVE(MyFrame::OnMove)
481EVT_ICONIZE(MyFrame::OnIconize)
482EVT_MENU(-1, MyFrame::OnToolLeftClick)
483EVT_TIMER(INIT_TIMER, MyFrame::OnInitTimer)
485EVT_TIMER(FRAME_TC_TIMER, MyFrame::OnFrameTCTimer)
486EVT_TIMER(FRAME_COG_TIMER, MyFrame::OnFrameCOGTimer)
487EVT_TIMER(MEMORY_FOOTPRINT_TIMER, MyFrame::OnMemFootTimer)
489EVT_MAXIMIZE(MyFrame::OnMaximize)
490EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_TOOL_RCLICKED,
491 MyFrame::RequestNewToolbarArgEvent)
492EVT_ERASE_BACKGROUND(MyFrame::OnEraseBackground)
494EVT_TIMER(RECAPTURE_TIMER, MyFrame::OnRecaptureTimer)
495EVT_TIMER(TOOLBAR_ANIMATE_TIMER, MyFrame::OnToolbarAnimateTimer)
496EVT_COMMAND(wxID_ANY, BELLS_PLAYED_EVTYPE, MyFrame::OnBellsFinished)
498#ifdef wxHAS_POWER_EVENTS
499EVT_POWER_SUSPENDING(MyFrame::OnSuspending)
500EVT_POWER_SUSPENDED(MyFrame::OnSuspended)
501EVT_POWER_SUSPEND_CANCEL(MyFrame::OnSuspendCancel)
502EVT_POWER_RESUME(MyFrame::OnResume)
513static
void onBellsFinishedCB(
void *ptr) {
514 auto framePtr =
static_cast<MyFrame *
>(ptr);
516 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
517 wxPostEvent(framePtr, ev);
522 auto msg = ev.GetString().ToStdString();
523 auto ¬eman = NotificationManager::GetInstance();
524 noteman.AddNotification(NotificationSeverity::kInformational, msg, 60);
527static NmeaLog *GetDataMonitor() {
528 auto w = wxWindow::FindWindowByName(kDataMonitorWindowName);
529 return dynamic_cast<NmeaLog *
>(w);
532MyFrame::MyFrame(
const wxString &title,
const wxPoint &pos,
const wxSize &size,
533 RestServer &rest_server, wxAuiDefaultDockArt *pauidockart,
534 OpenFileFunc open_gpx_file)
535 : wxFrame(nullptr, -1, title, pos, size, kFrameStyle, kTopLevelWindowName),
536 m_connections_dlg(nullptr),
538 m_pauidockart(pauidockart),
539 m_rest_server(rest_server),
540 m_open_gpx_file(open_gpx_file) {
552 m_ulLastNMEATicktime = 0;
553 m_data_monitor->Hide();
555 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
559 m_load_errors_dlg_ctrl = std::make_unique<LoadErrorsDlgCtrl>(
this);
562 InitTimer.SetOwner(
this, INIT_TIMER);
564 m_initializing =
false;
567 FrameTimer1.SetOwner(
this, FRAME_TIMER_1);
570 FrameTCTimer.SetOwner(
this, FRAME_TC_TIMER);
573 FrameCOGTimer.SetOwner(
this, FRAME_COG_TIMER);
576 MemFootTimer.SetOwner(
this, MEMORY_FOOTPRINT_TIMER);
579 ToolbarAnimateTimer.SetOwner(
this, TOOLBAR_ANIMATE_TIMER);
581 FrameTenHzTimer.SetOwner(
this, FRANE_TENHZ_TIMER);
590 m_bTimeIsSet =
false;
593 m_bdefer_resize =
false;
596 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
597 COGFilterTable[i] = NAN;
598 SOGFilterTable[i] = NAN;
600 m_last_bGPSValid =
false;
601 m_last_bVelocityValid =
false;
611 for (
int i = 0; i < MAX_COG_AVERAGE_SECONDS; i++) COGTable[i] = NAN;
616 double process_noise_std = 1.0;
617 double measurement_noise_std = 0.5;
619 m_ChartUpdatePeriod = 1;
624 log_callbacks.log_is_active = [&]() {
625 auto log = GetDataMonitor();
626 return log && log->IsVisible();
628 log_callbacks.log_message = [&](
Logline ll) {
629 NmeaLog *monitor = GetDataMonitor();
632 g_pMUX =
new Multiplexer(log_callbacks, g_b_legacy_input_filter_behaviour);
635 ais_callbacks.confirm_stop_track = []() {
636 int r = OCPNMessageBox(
638 _(
"This AIS target has Persistent tracking selected by MMSI "
640 "A Persistent track recording will therefore be restarted for this "
642 "Do you instead want to stop Persistent tracking for this target?"),
643 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60);
644 return r == wxID_YES;
646 ais_callbacks.get_target_mmsi = []() {
647 auto alert_dlg_active =
649 assert(alert_dlg_active);
650 return alert_dlg_active->Get_Dialog_MMSI();
658 wxLogMessage(
" **** Connect stuff");
664 Connect(wxEVT_OCPN_MSG,
665 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
673 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnSENCEvtThread);
681#if defined(__WXGTK__) || defined(__WXQT__)
682 wxIcon app_icon(opencpn);
690 wxDynamicLibrary dllUser32(
"user32.dll");
692 pSetSysColors = (SetSysColors_t)dllUser32.GetSymbol(
"SetSysColors");
693 pGetSysColor = (GetSysColor_t)dllUser32.GetSymbol(
"GetSysColor");
698 m_next_available_plugin_tool_id = ID_PLUGIN_BASE;
703 m_resizeTimer.SetOwner(
this, RESIZE_TIMER);
704 m_recaptureTimer.SetOwner(
this, RECAPTURE_TIMER);
706 assert(
g_pRouteMan != 0 &&
"g_pRouteMan not available");
708 [&](wxCommandEvent) { Refresh(); });
709 m_evt_drv_msg_listener.Init(CommDriverRegistry::GetInstance().evt_driver_msg,
711 m_update_statusbar_listener.Init(
712 GuiEvents::GetInstance().gframe_update_status_bar,
714 m_center_aistarget_listener.Init(
715 GuiEvents::GetInstance().on_center_ais_target, [&](
ObservedEvt &ev) {
716 auto ais_target = UnpackEvtPointer<AisTargetData>(ev);
717 CenterAisTarget(ais_target);
722 EnableFullScreenView();
724 int is_day = GetColorScheme() == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
730 FrameTenHzTimer.Stop();
745 (wxObjectEventFunction)(wxEventFunction)&MyFrame::OnEvtPlugInMessage);
751void MyFrame::FreezeCharts() {
754 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
756 if (cc && !cc->IsFrozen()) cc->Freeze();
760void MyFrame::CenterAisTarget(
761 const std::shared_ptr<const AisTargetData> &ais_target) {
769 double factor = cc->GetScaleValue() / 5000.0;
770 JumpToPosition(GetFocusCanvas(), ais_target->Lat, ais_target->Lon,
776void MyFrame::ThawCharts() {
779 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
781 if (cc && cc->IsFrozen()) cc->Thaw();
788 switch (event.type) {
789 case SENC_BUILD_STARTED:
792 case SENC_BUILD_DONE_NOERROR:
794 chart =
event.m_ticket->m_chart;
796 chart->PostInit(FULL_INIT, global_color_scheme);
798 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
800 if (cc) cc->ClearS52PLIBStateHash();
805 delete event.m_ticket;
807 case SENC_BUILD_DONE_ERROR:
815void MyFrame::RebuildChartDatabase() {
816 bool b_SetInitialPoint =
false;
819 ArrayOfCDI ChartDirArray;
820 pConfig->LoadChartDirArray(ChartDirArray);
822 if (ChartDirArray.GetCount()) {
827 _(
"OpenCPN needs to update the chart database from config file "
831 wxICON_INFORMATION | wxOK);
839 _(
"Rebuilding chart database from configuration file entries..."));
843 wxString dummy1 = _(
"Elapsed time : ");
844 wxString dummy2 = _(
"Estimated time : ");
845 wxString dummy3 = _(
"Remaining time : ");
846 wxGenericProgressDialog *pprog =
new wxGenericProgressDialog(
847 _(
"OpenCPN Chart Update"), line, 100, NULL,
848 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
849 wxPD_REMAINING_TIME);
852 ChartData->SaveBinary(ChartListFileName);
862void MyFrame::OnBellsFinished(wxCommandEvent &event) {
863 int bells = wxMin(m_BellsToPlay, 2);
864 if (bells <= 0)
return;
866 wxString soundfile =
"sounds";
867 appendOSDirSlash(&soundfile);
868 soundfile += wxString(bells_sound_file_name[bells - 1], wxConvUTF8);
869 soundfile.Prepend(g_Platform->GetSharedDataDir());
870 wxLogMessage(
"Using bells sound file: " + soundfile);
872 o_sound::Sound *sound = bells_sound[bells - 1];
873 sound->SetFinishedCallback(onBellsFinishedCB,
this);
874 auto cmd_sound =
dynamic_cast<o_sound::SystemCmdSound *
>(sound);
875 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
876 sound->Load(soundfile);
877 if (!sound->IsOk()) {
878 wxLogMessage(
"Failed to load bells sound file: " + soundfile);
882 m_BellsToPlay -= bells;
885void MyFrame::OnEraseBackground(wxEraseEvent &event) {}
887void MyFrame::OnMaximize(wxMaximizeEvent &event) {
894ColorScheme GetColorScheme() {
return global_color_scheme; }
896ColorScheme MyFrame::GetColorScheme() {
return global_color_scheme; }
898void MyFrame::ReloadAllVP() {
899 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
901 if (cc) cc->ReloadVP();
905void MyFrame::SetAndApplyColorScheme(ColorScheme cs) {
906 int is_day = cs == GLOBAL_COLOR_SCHEME_DAY ? 1 : 0;
909 global_color_scheme = cs;
912 case GLOBAL_COLOR_SCHEME_DAY:
915 case GLOBAL_COLOR_SCHEME_DUSK:
918 case GLOBAL_COLOR_SCHEME_NIGHT:
919 SchemeName =
"NIGHT";
926 m_pauidockart->SetMetric(wxAUI_DOCKART_GRADIENT_TYPE, wxAUI_GRADIENT_NONE);
928 m_pauidockart->SetColour(wxAUI_DOCKART_BORDER_COLOUR, wxColour(0, 0, 0));
929 m_pauidockart->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1);
930 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
931 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 0);
932 m_pauidockart->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR,
934 m_pauidockart->SetColour(wxAUI_DOCKART_BACKGROUND_COLOUR, wxColour(0, 0, 0));
963 m_pauidockart->SetColour(wxAUI_DOCKART_SASH_COLOUR, wxColour(0, 0, 0));
964 m_pauidockart->SetMetric(wxAUI_DOCKART_SASH_SIZE, 6);
968 g_StyleManager->GetCurrentStyle()->SetColorScheme(cs);
971 unsigned Usercolortable_index = 0;
972 for (
unsigned int i = 0; i < UserColorTableArray->GetCount(); i++) {
973 colTable *ct = (colTable *)UserColorTableArray->Item(i);
974 if (SchemeName.IsSameAs(*ct->tableName)) {
975 Usercolortable_index = i;
980 if (ps52plib) ps52plib->SetPLIBColorScheme(SchemeName, ChartCtxFactory());
984 (wxColorHashMap *)UserColourHashTableArray->Item(Usercolortable_index);
989 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
992 cc->SetColorScheme(cs);
993 cc->GetWorldBackgroundChart()->SetColorScheme(cs);
994 cc->HideChartInfoWindow();
995 cc->SetQuiltChartHiLiteIndex(-1);
1001 .SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1013 g_pRouteMan->SetColorScheme(cs, g_Platform->GetDisplayDPmm());
1026 if (g_pais_query_dialog_active) {
1027 bool b_isshown = g_pais_query_dialog_active->IsShown();
1028 int n_mmsi = g_pais_query_dialog_active->GetMMSI();
1029 if (b_isshown) g_pais_query_dialog_active->Show(
false);
1031 g_pais_query_dialog_active->Close();
1034 g_pais_query_dialog_active->
Create(
1035 this, -1, _(
"AIS Target Query"),
1036 wxPoint(g_ais_query_dialog_x, g_ais_query_dialog_y));
1037 g_pais_query_dialog_active->SetMMSI(n_mmsi);
1038 g_pais_query_dialog_active->UpdateText();
1039 if (b_isshown) g_pais_query_dialog_active->Show();
1042 if (pRouteManagerDialog) pRouteManagerDialog->SetColorScheme();
1044 if (g_pAISTargetList) g_pAISTargetList->SetColorScheme();
1048 ApplyGlobalColorSchemetoStatusBar();
1050 UpdateAllToolbars(cs);
1055 bool btoolbarFull = g_bmasterToolbarFull;
1061 if (!btoolbarFull) {
1063 RequestNewMasterToolbar();
1065 CollapseGlobalToolbar();
1068 RequestNewMasterToolbar();
1077void MyFrame::ApplyGlobalColorSchemetoStatusBar() {
1078 if (m_pStatusBar != NULL) {
1079 m_pStatusBar->SetBackgroundColour(GetGlobalColor(
"UIBDR"));
1080 m_pStatusBar->ClearBackground();
1085 if (g_canvasArray.GetCount() > 0)
1086 return g_canvasArray.Item(0);
1090void MyFrame::CancelAllMouseRoute() {
1092 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1094 if (cc) cc->CancelMouseRoute();
1098void MyFrame::NotifyChildrenResize() {}
1100void MyFrame::CreateCanvasLayout(
bool b_useStoredSize) {
1108 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1116 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1125 auto &config_array = ConfigMgr::Get().GetCanvasConfigArray();
1128 for (
unsigned int i = 1; i < config_array.GetCount(); i++) {
1129 config_array.Item(i)->canvas = NULL;
1135 for (
unsigned int i = 1; i < g_canvasArray.GetCount(); i++) {
1136 g_canvasArray.RemoveAt(i);
1140 switch (g_canvasConfig) {
1143 if (!g_canvasArray.GetCount() || !config_array.Item(0)) {
1146 g_canvasArray.Add(cc);
1148 cc = g_canvasArray[0];
1154 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1155 cc->GetglCanvas()->Show();
1158 config_array.Item(0)->canvas = cc;
1162 cc->ApplyCanvasConfig(config_array.Item(0));
1166 cc->ConfigureChartBar();
1167 cc->SetColorScheme(global_color_scheme);
1168 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1169 cc->SetShowGPS(
true);
1172 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1174 g_pauimgr->GetPane(cc).CaptionVisible(
false);
1180 if (!g_canvasArray.GetCount() || !g_canvasArray[0]) {
1182 g_canvasArray.Add(cc);
1184 cc = g_canvasArray[0];
1190 if (!cc->GetglCanvas()) cc->SetupGlCanvas();
1193 config_array.Item(0)->canvas = cc;
1195 cc->ApplyCanvasConfig(config_array.Item(0));
1198 cc->ConfigureChartBar();
1199 cc->SetColorScheme(global_color_scheme);
1200 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
1201 cc->SetShowGPS(
false);
1204 g_pauimgr->GetPane(cc).Name(
"ChartCanvas");
1206 .CaptionVisible(
false)
1208 .CloseButton(
false);
1213 g_canvasArray.Add(cc);
1217 if (config_array.GetCount() < 2) {
1219 pcc->configIndex = 1;
1223 pcc->
canvasSize = wxSize(GetClientSize().x / 2, GetClientSize().y);
1224 config_array.Add(pcc);
1227 config_array.Item(1)->canvas = cc;
1229 cc->ApplyCanvasConfig(config_array.Item(1));
1232 cc->ConfigureChartBar();
1233 cc->SetColorScheme(global_color_scheme);
1234 cc->SetShowGPS(
true);
1238 g_pauimgr->GetPane(cc).Name(
"ChartCanvas2");
1240 .CaptionVisible(
false)
1242 .CloseButton(
false);
1243 g_pauimgr->GetPane(cc).RightDockable(
true);
1247 config_array.Item(1)->canvasSize =
1248 wxSize(GetClientSize().x / 2, GetClientSize().y);
1249 g_pauimgr->GetPane(cc).BestSize(GetClientSize().x / 2, GetClientSize().y);
1254 if (b_useStoredSize) {
1255 int ccw = config_array.Item(1)->canvasSize.x;
1256 int cch = config_array.Item(1)->canvasSize.y;
1259 if (ccw < GetClientSize().x / 10) {
1260 ccw = GetClientSize().x / 2;
1261 cch = GetClientSize().y;
1264 g_pauimgr->GetPane(cc).BestSize(ccw, cch);
1265 cc->SetSize(ccw, cch);
1279 if (g_canvasArray.size() > 1)
1283 console->SetColorScheme(global_color_scheme);
1288 g_pRouteMan->GetDlgContext().show_with_fresh_fonts();
1294void MyFrame::RequestNewToolbars(
bool bforcenew) {
1295 if (b_inCloseWindow) {
1299 BuildiENCToolbar(bforcenew);
1300 PositionIENCToolbar();
1309void MyFrame::UpdateAllToolbars(ColorScheme cs) {
1315void MyFrame::SetAllToolbarScale() {
1316 g_toolbar_scalefactor = g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
1319void MyFrame::SetGPSCompassScale() {
1320 g_compass_scalefactor = g_Platform->GetCompassScaleFactor(g_GUIScaleFactor);
1324 wxPoint screenPoint = ::wxGetMousePosition();
1327 switch (g_canvasConfig) {
1329 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1332 if (canvas->GetScreenRect().Contains(
1336 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1339 if (canvas->GetScreenRect().Contains(
1346 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1349 if (canvas->GetScreenRect().Contains(
1350 canvas->ScreenToClient(screenPoint)))
1358int MyFrame::GetCanvasIndexUnderMouse() {
1359 wxPoint screenPoint = ::wxGetMousePosition();
1362 switch (g_canvasConfig) {
1364 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1367 if (canvas->GetScreenRect().Contains(
1371 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1374 if (canvas->GetScreenRect().Contains(
1381 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1384 if (canvas->GetScreenRect().Contains(
1385 canvas->ScreenToClient(screenPoint)))
1393bool MyFrame::DropMarker(
bool atOwnShip) {
1400 if (!canvas)
return false;
1407 new RoutePoint(lat, lon, g_default_wp_icon, wxEmptyString, wxEmptyString);
1409 pSelect->AddSelectableRoutePoint(lat, lon, pWP);
1411 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1416 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1417 pRouteManagerDialog->UpdateWptListCtrl();
1422 RefreshAllCanvas(
false);
1427void MyFrame::SwitchKBFocus(
ChartCanvas *pCanvas) {
1428 if (g_canvasConfig != 0) {
1431 int nTargetGTK = -1;
1433 wxWindow *source = FindFocus();
1439 switch (g_canvasConfig) {
1441 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(0);
1444 if (canvas && (canvas == test)) {
1449 cc = ConfigMgr::Get().GetCanvasConfigArray().Item(1);
1452 if (canvas && (canvas == test)) {
1460 int nfinalTarget = nTarget;
1462 nfinalTarget = nTargetGTK;
1464 target = ConfigMgr::Get()
1465 .GetCanvasConfigArray()
1470 target->Refresh(
true);
1481void MyFrame::FastClose() {
1483 FrameTenHzTimer.Stop();
1485 FrameTimer1.Start(1);
1489void MyFrame::OnExit(wxCommandEvent &event) {
1493void MyFrame::OnCloseWindow(wxCloseEvent &event) {
1496 if (b_inCloseWindow) {
1506 if (!g_bDeferredInitDone)
return;
1523 if (bDBUpdateInProgress)
return;
1525 b_inCloseWindow =
true;
1527 ::wxSetCursor(wxCURSOR_WAIT);
1531 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1533 if (cc && cc->IsMeasureActive()) {
1534 cc->CancelMeasureRoute();
1539 SendPreShutdownHookToPlugins();
1543 if (g_pAISTargetList) {
1544 wxAuiPaneInfo &pane =
g_pauimgr->GetPane(g_pAISTargetList);
1545 g_AisTargetList_perspective =
g_pauimgr->SavePaneInfo(pane);
1546 g_pauimgr->DetachPane(g_pAISTargetList);
1557 pConfig->SetPath(
"/AUI");
1558 pConfig->Write(
"AUIPerspective",
g_pauimgr->SavePerspective());
1573 SetCursor(wxCURSOR_WAIT);
1575 RefreshAllCanvas(
true);
1581 RestoreScreenBrightness();
1592 wxPoint tbp_incanvas = GetPrimaryCanvas()->ScreenToClient(locn);
1593 g_iENCToolbarPosY = tbp_incanvas.y;
1594 g_iENCToolbarPosX = tbp_incanvas.x;
1598 g_bframemax = IsMaximized();
1601 FrameTenHzTimer.Stop();
1603 FrameCOGTimer.Stop();
1617 if (g_bAutoAnchorMark) {
1618 bool watching_anchor =
false;
1626 wxDateTime now = wxDateTime::Now();
1627 wxTimeSpan uptime = now.Subtract(g_start_time);
1629 if (!watching_anchor && (g_bCruising) && (
gSog < 0.5) &&
1630 (uptime.IsLongerThan(wxTimeSpan(0, 30, 0, 0))))
1635 if (g_declutter_anchorage) {
1636 for (
RoutePoint *pr : *pWayPointMan->GetWaypointList()) {
1637 if (pr->GetName().StartsWith(
"Anchorage")) {
1638 double a =
gLat - pr->m_lat;
1639 double b =
gLon - pr->m_lon;
1640 double l = sqrt((a * a) + (b * b));
1643 if ((l * 60. * 1852.) < (.25 * 1852.)) {
1645 NavObj_dB::GetInstance().DeleteRoutePoint(pr);
1646 pSelect->DeleteSelectablePoint(pr, SELTYPE_ROUTEPOINT);
1654 wxString name = now.Format();
1655 name.Prepend(_(
"Anchorage created "));
1661 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1666 pConfig->UpdateSettings();
1670 wxLogMessage(
"opencpn::MyFrame exiting cleanly.");
1674 NavObj_dB::GetInstance().Close();
1678 pConfig->DeleteGroup(
"/Routes");
1679 pConfig->DeleteGroup(
"/Marks");
1705 if (g_pAISTargetList) {
1706 g_pAISTargetList->Disconnect_decoder();
1707 g_pAISTargetList->Destroy();
1714 if (RouteManagerDialog::getInstanceFlag()) {
1715 if (pRouteManagerDialog) {
1716 pRouteManagerDialog->Destroy();
1717 pRouteManagerDialog = NULL;
1731 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1733 if (cc) cc->Destroy();
1736 g_canvasArray.Clear();
1757 CommBridge::GetInstance().SaveConfig();
1777 auto ®istry = CommDriverRegistry::GetInstance();
1778 registry.CloseAllDrivers();
1781 for (
auto *cp : TheConnectionParams()) {
1786 while (pLayerList->size())
delete *pLayerList->begin();
1790 ReleaseApiListeners();
1793 g_bTempShowMenuBar =
false;
1795#define THREAD_WAIT_SECONDS 5
1805 wxLogMessage(
"Starting compressor pool drain");
1806 wxDateTime now = wxDateTime::Now();
1807 time_t stall = now.GetTicks();
1808 time_t end = stall + THREAD_WAIT_SECONDS;
1811 while (stall < end) {
1812 wxDateTime later = wxDateTime::Now();
1813 stall = later.GetTicks();
1816 msg.Printf(
"Time: %d Job Count: %d", n_comploop,
1825 fmsg.Printf(
"Finished compressor pool drain..Time: %d Job Count: %d",
1831 uninitIXNetSystem();
1835 wxLogMessage(
"gFrame destroyed.");
1838#ifndef USE_ANDROID_GLES2
1839 qDebug() <<
"Calling OnExit()";
1843 wxTheApp->ExitMainLoop();
1846void MyFrame::OnMove(wxMoveEvent &event) {
1847 auto idx = wxDisplay::GetFromWindow(
this);
1860 DEBUG_LOG <<
"Moved to " << idx
1861#if wxCHECK_VERSION(3, 1, 6)
1862 <<
" PPI: " << wxDisplay(idx).GetPPI().GetX() <<
"x"
1863 << wxDisplay(idx).GetPPI().GetY()
1864 <<
" SF wxDisplay: " << wxDisplay(idx).GetScaleFactor()
1866 <<
" Size wxDisplay: " << wxDisplay(idx).GetGeometry().GetWidth()
1867 <<
"x" << wxDisplay(idx).GetGeometry().GetHeight()
1868 <<
" MM wxDisplay: " << wxGetDisplaySizeMM().GetX() <<
"x"
1869 << wxGetDisplaySizeMM().GetY()
1870 <<
" Name wxDisplay: " << wxDisplay(idx).GetName().c_str()
1879 if (g_config_display_size_manual) {
1888 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
1891 cc->SetMUIBarPosition();
1900 UpdateGPSCompassStatusBoxes();
1910 PositionIENCToolbar();
1916 g_nframewin_posx = GetPosition().x;
1917 g_nframewin_posy = GetPosition().y;
1920void MyFrame::ProcessCanvasResize() {
1921 UpdateGPSCompassStatusBoxes(
true);
1925 PositionIENCToolbar();
1928 TriggerRecaptureTimer();
1932void MyFrame::TriggerRecaptureTimer() {
1933 m_recaptureTimer.Start(
1934 1000, wxTIMER_ONE_SHOT);
1937void MyFrame::OnRecaptureTimer(wxTimerEvent &event) { }
1939void MyFrame::SetCanvasSizes(wxSize frameSize) {
1940 if (!g_canvasArray.GetCount())
return;
1943 int cccw = frameSize.x;
1944 int ccch = frameSize.y;
1948 switch (g_canvasConfig) {
1952 cc = g_canvasArray.Item(0);
1954 cc->GetSize( &cur_width, &cur_height );
1955 if( ( cur_width != cccw ) || ( cur_height != ccch ) ) {
1957 g_pauimgr->GetPane( cc ).BestSize( cccw, ccch );
1959 cc->SetSize( 0, 0, cccw, ccch );
1967 cc = g_canvasArray.Item(1);
1969 int ccw = g_canvasConfigArray.Item(1)->canvasSize.x;
1970 int cch = g_canvasConfigArray.Item(1)->canvasSize.y;
1972 ccw = wxMin(ccw, cccw * 8 / 10);
1973 ccw = wxMax(ccw, cccw * 2 / 10);
1977 g_canvasConfigArray.Item(1)->canvasSize = wxSize(ccw, cch);
1984 g_pauimgr->GetPane(cc).MinSize(ccw, cch);
2001void MyFrame::OnIconize(wxIconizeEvent &event) {
2011 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2013 if (cc && cc->GetMUIBar()) {
2014 if (cc->GetMUIBar()->GetCanvasOptions()) {
2015 if (cc->GetMUIBar()->GetCanvasOptions()->IsShown()) {
2016 cc->GetMUIBar()->PushCanvasOptions();
2025void MyFrame::OnSize(wxSizeEvent &event) { ODoSetSize(); }
2027void MyFrame::ODoSetSize() {
2029 GetClientSize(&x, &y);
2032 if (m_pStatusBar != NULL) {
2033 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
2034 int currentCount = m_pStatusBar->GetFieldsCount();
2035 if (currentCount != m_StatusBarFieldCount) {
2036 if ((currentCount > 0) && (currentCount < 7)) {
2039 int widths[] = {2, 2, 2, 2, 2, 2};
2040 m_pStatusBar->SetStatusWidths(currentCount, widths);
2043 m_pStatusBar->SetFieldsCount(m_StatusBarFieldCount);
2046 if (m_StatusBarFieldCount) {
2051 if (m_StatusBarFieldCount > 2) {
2052 int widths[] = {-6, -5, -5, -6, -4};
2053 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2054 }
else if (m_StatusBarFieldCount == 2) {
2055 int cwidth = x * 90 / 100;
2056 int widths[] = {100, 100};
2057 widths[0] = cwidth * 6.4 / 10.0;
2058 widths[1] = cwidth * 3.6 / 10.0;
2059 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2061 int widths[] = {100, 100};
2062 widths[0] = x * 90 / 100;
2063 m_pStatusBar->SetStatusWidths(m_StatusBarFieldCount, widths);
2066 int styles[] = {wxSB_FLAT, wxSB_FLAT, wxSB_FLAT,
2067 wxSB_FLAT, wxSB_FLAT, wxSB_FLAT};
2068 m_pStatusBar->SetStatusStyles(m_StatusBarFieldCount, styles);
2070 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
2072 m_pStatusBar->SetStatusText(sogcog, STAT_FIELD_SOGCOG);
2080 m_pStatusBar->GetFieldRect(0, stat_box);
2083 int max_font_size = wxMin((stat_box.width / 28), (stat_box.height));
2085 wxFont sys_font = *wxNORMAL_FONT;
2086 int try_font_size = sys_font.GetPointSize();
2089 int min_font_size = 10;
2099 wxFont *statusBarFont =
2100 FontMgr::Get().
GetFont(_(
"StatusBar"), try_font_size);
2101 int font_size = statusBarFont->GetPointSize();
2103 font_size = wxMin(font_size,
2106 wxMax(font_size, min_font_size);
2109 font_size = statusBarFont->GetPointSize();
2116 font_size, statusBarFont->GetFamily(), statusBarFont->GetStyle(),
2117 statusBarFont->GetWeight(),
false, statusBarFont->GetFaceName());
2119 int min_height = stat_box.height;
2121 m_pStatusBar->SetFont(*pstat_font);
2122 m_pStatusBar->SetForegroundColour(
2123 FontMgr::Get().GetFontColor(_(
"StatusBar")));
2125 min_height = (pstat_font->GetPointSize() * getAndroidDisplayDensity()) + 10;
2127 (min_height >> 1) * 2;
2128 m_pStatusBar->SetMinHeight(min_height);
2137 SetCanvasSizes(GetClientSize());
2139 UpdateGPSCompassStatusBoxes(
true);
2141 if (
console) PositionConsole();
2144 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2146 if (cc) cc->FormatPianoKeys();
2152 g_MainToolbar->SetGeometry(GetPrimaryCanvas()->GetCompass()->IsShown(),
2153 GetPrimaryCanvas()->GetCompass()->GetRect());
2179 options_lastWindowSize = wxSize(0, 0);
2180 options_lastWindowPos = wxPoint(0, 0);
2187 if (!b_inCloseWindow) {
2190 resizeAndroidPersistents();
2194 if (GetPrimaryCanvas() && GetPrimaryCanvas()->GetNotificationsList()) {
2195 GetPrimaryCanvas()->GetNotificationsList()->RecalculateSize();
2201void MyFrame::PositionConsole() {
2202#if defined(__WXMSW__) || defined(__WXMAC__)
2203 if (NULL == GetPrimaryCanvas())
return;
2205 int ccx, ccy, ccsx, ccsy, consx, consy;
2207 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2210 consoleHost->GetSize(&ccsx, &ccsy);
2211 consoleHost->GetPosition(&ccx, &ccy);
2213 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2214 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2215 consoleHost = GetPrimaryCanvas();
2220 if (consoleHost->GetCompass()) {
2221 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2223 if (compass_rect.y < 100)
2224 yOffset = compass_rect.y + compass_rect.height + 45;
2228 wxSize csz =
console->GetSize();
2232 wxPoint screen_pos =
2233 ClientToScreen(wxPoint(ccx + ccsx - consx - 2, ccy + yOffset));
2236 if (NULL == GetPrimaryCanvas())
return;
2238 int ccx, ccy, ccsx, ccsy, consx, consy;
2240 if (g_canvasConfig > 0) consoleHost = g_canvasArray[1];
2243 consoleHost->GetSize(&ccsx, &ccsy);
2244 consoleHost->GetPosition(&ccx, &ccy);
2246 GetPrimaryCanvas()->GetSize(&ccsx, &ccsy);
2247 GetPrimaryCanvas()->GetPosition(&ccx, &ccy);
2248 consoleHost = GetPrimaryCanvas();
2251 int yTopOffset = 60;
2252 int yBottomOffset = 0;
2254 if (consoleHost->GetCompass()) {
2255 wxRect compass_rect = consoleHost->GetCompass()->
GetRect();
2257 if (compass_rect.y < 100)
2258 yTopOffset = compass_rect.y + compass_rect.height;
2260 if (consoleHost->GetMUIBar()) {
2261 wxRect mui_rect = consoleHost->GetMUIBarRect();
2262 yBottomOffset = ccsy - mui_rect.y;
2266 wxSize csz =
console->GetSize();
2269 int yAvail = ccsy - (yTopOffset + yBottomOffset);
2271 if (consy < yAvail) {
2272 yFinal = (yAvail - consy) / 2;
2273 yFinal += yTopOffset;
2274 }
else if (
console->GetCDI()->IsShown()) {
2275 int cdi_height =
console->GetCDI()->GetSize().y;
2276 int consy_no_cdi = consy - cdi_height;
2277 yFinal = (yAvail - consy_no_cdi) / 2;
2278 yFinal += yTopOffset;
2282 wxPoint in_canvas_pos = wxPoint(ccsx - consx - 2, yFinal);
2287void MyFrame::UpdateAllFonts() {
2296 DestroyPersistentDialogs();
2298 if (pWayPointMan) pWayPointMan->ClearRoutePointFonts();
2303void MyFrame::DestroyPersistentDialogs() {
2304 if (g_pais_query_dialog_active) {
2305 g_pais_query_dialog_active->Hide();
2306 g_pais_query_dialog_active->Destroy();
2307 g_pais_query_dialog_active = NULL;
2335void MyFrame::RefreshGroupIndices() {
2337 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2339 if (cc) cc->canvasRefreshGroupIndex();
2343void MyFrame::OnToolLeftClick(wxCommandEvent &event) {
2346 switch (event.GetId()) {
2347 case ID_MENU_SCALE_OUT:
2348 DoStackDelta(GetPrimaryCanvas(), 1);
2352 case ID_MENU_SCALE_IN:
2353 DoStackDelta(GetPrimaryCanvas(), -1);
2357 case ID_MENU_ZOOM_IN: {
2358 if (GetFocusCanvas()) {
2359 GetFocusCanvas()->
ZoomCanvas(g_plus_minus_zoom_factor,
false);
2364 case ID_MENU_ZOOM_OUT: {
2365 if (GetFocusCanvas()) {
2366 GetFocusCanvas()->
ZoomCanvas(1.0 / g_plus_minus_zoom_factor,
false);
2371 case ID_MENU_ROUTE_NEW: {
2372 if (GetFocusCanvas()) {
2373 if (0 == GetFocusCanvas()->m_routeState) {
2374 GetFocusCanvas()->StartRoute();
2376 GetFocusCanvas()->FinishRoute();
2382 case ID_MENU_TOOL_MEASURE: {
2383 GetPrimaryCanvas()->StartMeasureRoute();
2387 case ID_MENU_TOOL_NMEA_DBG_LOG:
2388 m_data_monitor->Show();
2389 m_data_monitor->Raise();
2392 case ID_MENU_TOOL_IO_MONITOR:
2393 m_data_monitor->Show();
2396 case ID_MENU_MARK_BOAT: {
2401 case ID_MENU_MARK_CURSOR: {
2406 case ID_MENU_NAV_FOLLOW: {
2407 if (
gFrame->GetPrimaryCanvas())
2408 gFrame->GetPrimaryCanvas()->TogglebFollow();
2412 case ID_MENU_CHART_OUTLINES: {
2413 ToggleChartOutlines(GetFocusCanvas());
2417 case ID_MENU_CHART_QUILTING: {
2418 ToggleQuiltMode(GetFocusCanvas());
2422 case ID_MENU_UI_CHARTBAR: {
2423 ToggleChartBar(GetFocusCanvas());
2427 case ID_MENU_ENC_TEXT:
2429 ToggleENCText(GetFocusCanvas());
2432 case ID_MENU_ENC_LIGHTS: {
2433 ToggleLights(GetFocusCanvas());
2436 case ID_MENU_ENC_SOUNDINGS: {
2437 ToggleSoundings(GetFocusCanvas());
2440 case ID_MENU_ENC_ANCHOR: {
2441 ToggleAnchor(GetFocusCanvas());
2444 case ID_MENU_ENC_DATA_QUALITY: {
2445 ToggleDataQuality(GetFocusCanvas());
2448 case ID_MENU_SHOW_NAVOBJECTS: {
2449 ToggleNavobjects(GetFocusCanvas());
2453 case ID_MENU_AIS_TARGETS: {
2454 ToggleAISDisplay(GetFocusCanvas());
2457 case ID_MENU_AIS_MOORED_TARGETS: {
2458 g_bHideMoored = !g_bHideMoored;
2461 case ID_MENU_AIS_SCALED_TARGETS: {
2462 ToggleAISMinimizeTargets(GetFocusCanvas());
2466 case ID_MENU_AIS_TARGETLIST: {
2467 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ShowAISTargetList();
2471 case ID_MENU_AIS_TRACKS: {
2472 g_bAISShowTracks = !g_bAISShowTracks;
2473 SetMenubarItemState(ID_MENU_AIS_TRACKS, g_bAISShowTracks);
2477 case ID_MENU_AIS_CPADIALOG: {
2478 g_bAIS_CPA_Alert = !g_bAIS_CPA_Alert;
2479 SetMenubarItemState(ID_MENU_AIS_CPADIALOG, g_bAIS_CPA_Alert);
2480 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert);
2481 if (g_bAIS_CPA_Alert) {
2482 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2487 case ID_MENU_AIS_CPASOUND: {
2488 g_bAIS_CPA_Alert_Audio = !g_bAIS_CPA_Alert_Audio;
2489 SetMenubarItemState(ID_MENU_AIS_CPASOUND, g_bAIS_CPA_Alert_Audio);
2493 case ID_MENU_AIS_CPAWARNING: {
2494 if (GetPrimaryCanvas()) GetPrimaryCanvas()->ToggleCPAWarn();
2495 SetMenubarItemState(ID_MENU_AIS_CPAWARNING, g_bCPAWarn);
2499 case wxID_PREFERENCES:
2506 case ID_SETTINGS_NEW: {
2511 case ID_SETTINGS_DELETE: {
2514 g_pOptions =
nullptr;
2518 case ID_RELOAD_CHARTS: {
2523 case ID_MENU_SETTINGS_BASIC: {
2526 androidDisableFullScreen();
2528 DoAndroidPreferences();
2535 case ID_MENU_UI_FULLSCREEN: {
2540 case ID_MENU_SHOW_CURRENTS: {
2541 GetFocusCanvas()->ShowCurrents(!GetFocusCanvas()->GetbShowCurrent());
2542 GetFocusCanvas()->ReloadVP();
2543 GetFocusCanvas()->Refresh(
false);
2547 case ID_MENU_SHOW_TIDES: {
2548 GetFocusCanvas()->ShowTides(!GetFocusCanvas()->GetbShowTide());
2549 GetFocusCanvas()->ReloadVP();
2550 GetFocusCanvas()->Refresh(
false);
2570 case ID_MENU_UI_COLSCHEME:
2571 case ID_COLSCHEME: {
2572 ToggleColorScheme();
2581 case ID_MENU_OQUIT: {
2586 case ID_MENU_ROUTE_MANAGER:
2587 case ID_ROUTEMANAGER: {
2588 pRouteManagerDialog = RouteManagerDialog::getInstance(
2591 if (pRouteManagerDialog->IsShown())
2592 pRouteManagerDialog->Hide();
2594 pRouteManagerDialog->UpdateRouteListCtrl();
2595 pRouteManagerDialog->UpdateTrkListCtrl();
2596 pRouteManagerDialog->UpdateWptListCtrl();
2597 pRouteManagerDialog->UpdateLayListCtrl();
2599 pRouteManagerDialog->Show();
2603 pRouteManagerDialog->Centre();
2604 pRouteManagerDialog->Raise();
2610 case ID_MENU_NAV_TRACK:
2612 if (!g_bTrackActive) {
2614 g_bTrackCarryOver =
true;
2617 g_bTrackCarryOver =
false;
2618 RefreshAllCanvas(
true);
2623 case ID_MENU_CHART_NORTHUP: {
2624 SetUpMode(GetPrimaryCanvas(), NORTH_UP_MODE);
2627 case ID_MENU_CHART_COGUP: {
2628 SetUpMode(GetPrimaryCanvas(), COURSE_UP_MODE);
2631 case ID_MENU_CHART_HEADUP: {
2632 SetUpMode(GetPrimaryCanvas(), HEAD_UP_MODE);
2636 case ID_MENU_MARK_MOB:
2642 case ID_MASTERTOGGLE: {
2644 wxString tip = _(
"Show Toolbar");
2645 if (!g_bmasterToolbarFull) tip = _(
"Hide Toolbar");
2647 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2649 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2652 if (g_bmasterToolbarFull)
2653 m_nMasterToolCountShown =
2657 m_nMasterToolCountShown = 2;
2659 m_nMasterToolCountShown =
2662 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2670 case ID_CMD_SELECT_CHART_TYPE: {
2671 selectChartDisplay(event.GetExtraLong(), -1);
2675 case ID_CMD_SELECT_CHART_FAMILY: {
2676 selectChartDisplay(-1, event.GetExtraLong());
2680 case ID_CMD_APPLY_SETTINGS: {
2681 applySettingsString(event.GetString());
2683 androidRestoreFullScreen();
2689 case ID_CMD_NULL_REFRESH: {
2694 case ID_CMD_SETVP: {
2695 setStringVP(event.GetString());
2699 case ID_CMD_INVALIDATE: {
2705 case ID_CMD_POST_JSON_TO_PLUGINS: {
2711 int numErrors = reader.
Parse(event.GetString(), &root);
2712 if (numErrors == 0) {
2713 if (root[
"MessageID"].IsString()) {
2714 wxString MsgID = root[
"MessageID"].
AsString();
2738 ArrayOfPlugInToolbarTools tool_array =
2740 for (
unsigned int i = 0; i < tool_array.size(); i++) {
2742 if (event.GetId() == pttc->id) {
2743 if (pttc->m_pplugin)
2765bool MyFrame::SetGlobalToolbarViz(
bool viz) {
2766 bool viz_now = g_bmasterToolbarFull;
2769 wxString tip = _(
"Show Toolbar");
2771 tip = _(
"Hide Toolbar");
2773 g_MainToolbar->GetToolbar()->SetToolShortHelp(ID_MASTERTOGGLE, tip);
2776 bool toggle =
false;
2777 if (viz && !g_bmasterToolbarFull)
2780 else if (!viz && g_bmasterToolbarFull)
2784 g_bmasterToolbarFull = !g_bmasterToolbarFull;
2787 if (g_bmasterToolbarFull)
2788 m_nMasterToolCountShown =
2792 m_nMasterToolCountShown = 2;
2794 m_nMasterToolCountShown =
2797 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2803void MyFrame::ScheduleReloadCharts() {
2804 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2805 evt.SetId(ID_RELOAD_CHARTS);
2806 GetEventHandler()->AddPendingEvent(evt);
2809void MyFrame::ScheduleDeleteSettingsDialog() {
2810 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2811 evt.SetId(ID_SETTINGS_DELETE);
2812 GetEventHandler()->AddPendingEvent(evt);
2815void MyFrame::ScheduleSettingsDialog() {
2816 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2817 evt.SetId(ID_SETTINGS);
2818 GetEventHandler()->AddPendingEvent(evt);
2821void MyFrame::ScheduleSettingsDialogNew() {
2822 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
2823 evt.SetId(ID_SETTINGS_NEW);
2824 GetEventHandler()->AddPendingEvent(evt);
2827void MyFrame::ScheduleReconfigAndSettingsReload(
bool reload,
bool new_dialog) {
2828 UpdateCanvasConfigDescriptors();
2830 if ((g_canvasConfig > 0) && (last_canvasConfig == 0))
2831 CreateCanvasLayout(
true);
2833 CreateCanvasLayout();
2837 ConfigureStatusBar();
2838 wxSize lastOptSize = options_lastWindowSize;
2843 options_lastWindowSize = lastOptSize;
2847 ScheduleSettingsDialogNew();
2849 ScheduleSettingsDialog();
2854 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2857 int index_hint = -1;
2858 if (i < pathArray.GetCount())
2859 index_hint =
ChartData->FinddbIndex(pathArray.Item(i));
2860 cc->canvasChartsRefresh(index_hint);
2861 if (index_hint != -1) cc->
SetVPScale(restoreScale[i]);
2870 return GetPrimaryCanvas();
2873void MyFrame::OnToolbarAnimateTimer(wxTimerEvent &event) {
2874 if (g_bmasterToolbarFull) {
2875#ifndef OCPN_TOOLBAR_ANIMATE
2876 m_nMasterToolCountShown = (int)
g_MainToolbar->GetToolCount();
2879 if (m_nMasterToolCountShown < (
int)
g_MainToolbar->GetToolCount()) {
2880 m_nMasterToolCountShown++;
2885 ToolbarAnimateTimer.Start(20, wxTIMER_ONE_SHOT);
2893#ifndef OCPN_TOOLBAR_ANIMATE
2894 m_nMasterToolCountShown = 1;
2896 if (m_nMasterToolCountShown > 1) {
2897 m_nMasterToolCountShown--;
2901 ToolbarAnimateTimer.Start(10, wxTIMER_ONE_SHOT);
2911void MyFrame::InvalidateAllGL() {
2914 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2924void MyFrame::RefreshAllCanvas(
bool bErase) {
2926 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2929 cc->Refresh(bErase);
2934void MyFrame::setStringVP(wxString VPS) {
2939 wxStringTokenizer tkz(VPS,
";");
2941 wxString token = tkz.GetNextToken();
2943 token.ToDouble(&lat);
2945 token = tkz.GetNextToken();
2947 token.ToDouble(&lon);
2949 token = tkz.GetNextToken();
2951 token.ToDouble(&scale_ppm);
2953 cc->
SetViewPoint(lat, lon, scale_ppm, 0, cc->GetVPRotation());
2956void MyFrame::DoSettingsNew() {
2963void MyFrame::DoSettings() {
2967 ApplyGlobalSettings(
true);
2970 bool b_loadHarmonics =
false;
2971 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
2974 if (cc->GetbShowCurrent() || cc->GetbShowTide()) b_loadHarmonics =
true;
2977 if (b_loadHarmonics) LoadHarmonics();
2985 g_bShowChartBar = !g_bShowChartBar;
2987 if (g_bShowChartBar) cc->m_brepaint_piano =
true;
2992 if (g_bShowChartBar) {
2994 UpdateControlBar(cc);
2997 SetMenubarItemState(ID_MENU_UI_CHARTBAR, g_bShowChartBar);
3000void MyFrame::ToggleColorScheme() {
3001 static bool lastIsNight;
3002 ColorScheme s = GetColorScheme();
3005 if (lastIsNight && is == 3)
3008 lastIsNight =
false;
3010 if (lastIsNight) is = 2;
3011 if (is == 3) lastIsNight =
true;
3012 s = (ColorScheme)is;
3013 if (s == N_COLOR_SCHEMES) s = GLOBAL_COLOR_SCHEME_RGB;
3015 SetAndApplyColorScheme(s);
3018void MyFrame::ToggleFullScreen() {
3019 bool to = !IsFullScreen();
3024 long style = wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION;
3026 ShowFullScreen(to, style);
3029 UpdateAllToolbars(global_color_scheme);
3031 UpdateControlBar(GetPrimaryCanvas());
3033 TriggerRecaptureTimer();
3036void MyFrame::ActivateMOB() {
3038 wxDateTime mob_time = wxDateTime::Now();
3039 wxString mob_label(_(
"MAN OVERBOARD"));
3040 mob_label += _(
" on ");
3041 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
3045 pWP_MOB->SetShared(
true);
3047 pWP_MOB->SetWaypointArrivalRadius(
3049 pWP_MOB->SetUseSca(
false);
3051 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
3059 new RoutePoint(zlat, zlon, g_default_wp_icon,
3060 wxString(_(
"1.0 NM along COG")), wxEmptyString);
3061 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_src);
3066 temp_route->AddPoint(pWP_src);
3067 temp_route->AddPoint(pWP_MOB);
3069 pSelect->AddSelectableRouteSegment(
gLat,
gLon, zlat, zlon, pWP_src, pWP_MOB,
3079 temp_route->SetRouteArrivalRadius(-1.0);
3085 v[
"GUID"] = temp_route->
m_GUID;
3086 wxString msg_id(
"OCPN_MAN_OVERBOARD");
3087 SendJSONMessageToAllPlugins(msg_id, v);
3090 if (RouteManagerDialog::getInstanceFlag()) {
3091 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3092 pRouteManagerDialog->UpdateRouteListCtrl();
3093 pRouteManagerDialog->UpdateWptListCtrl();
3098 RefreshAllCanvas(
false);
3100 wxString mob_message(_(
"MAN OVERBOARD"));
3101 mob_message += _(
" Time: ");
3102 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
3103 mob_message += _(
" Position: ");
3104 mob_message += toSDMM(1,
gLat);
3106 mob_message += toSDMM(2,
gLon);
3107 wxLogMessage(mob_message);
3109void MyFrame::TrackOn() {
3110 g_bTrackActive =
true;
3118 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3120 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
3122 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3125 androidSetTrackTool(
true);
3128 if (RouteManagerDialog::getInstanceFlag()) {
3129 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3130 pRouteManagerDialog->UpdateTrkListCtrl();
3131 pRouteManagerDialog->UpdateRouteListCtrl();
3137 if (name.IsEmpty()) {
3143 name = _(
"(Unnamed Track)");
3147 wxString msg_id(
"OCPN_TRK_ACTIVATED");
3148 SendJSONMessageToAllPlugins(msg_id, v);
3149 g_FlushNavobjChangesTimeout =
3153Track *MyFrame::TrackOff(
bool do_add_point) {
3158 wxString msg_id(
"OCPN_TRK_DEACTIVATED");
3160 SendJSONMessageToAllPlugins(msg_id, v);
3169 if (g_bTrackDaily) {
3174 NavObj_dB::GetInstance().UpdateTrack(pExtendTrack);
3175 return_val = pExtendTrack;
3182 g_bTrackActive =
false;
3184 if (RouteManagerDialog::getInstanceFlag()) {
3185 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3186 pRouteManagerDialog->UpdateTrkListCtrl();
3187 pRouteManagerDialog->UpdateRouteListCtrl();
3191 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
3193 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Enable Tracking"));
3194 SetMenubarItemState(ID_MENU_NAV_TRACK, g_bTrackActive);
3197 androidSetTrackTool(
false);
3201 m_target_rotate_time = wxInvalidDateTime;
3206void MyFrame::InitializeTrackRestart() {
3207 if (!g_bTrackDaily)
return;
3208 if (m_target_rotate_time.IsValid())
return;
3211 switch (g_track_rotate_time_type) {
3213 rotate_at = g_track_rotate_time + wxRound(
gLon * 3600. / 15.);
3215 case TIME_TYPE_COMPUTER:
3216 rotate_at = g_track_rotate_time;
3220 wxDateTime::Now().GetTicks() - wxDateTime::Now().ToUTC().GetTicks();
3221 rotate_at = g_track_rotate_time + utc_offset;
3224 if (rotate_at > 86400)
3226 else if (rotate_at < 0)
3229 wxTimeSpan rotate_seconds = wxTimeSpan(0, 0, rotate_at);
3230 m_target_rotate_time = wxDateTime::Today() + rotate_seconds;
3233 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3234 m_target_rotate_time += wxTimeSpan(24);
3238bool MyFrame::ShouldRestartTrack() {
3240 InitializeTrackRestart();
3242 if (wxDateTime::Now().IsLaterThan(m_target_rotate_time)) {
3243 m_target_rotate_time += wxTimeSpan(24);
3249void MyFrame::TrackDailyRestart() {
3251 Track *pPreviousTrack = TrackOff(
true);
3258 if (pPreviousTrack) {
3259 TrackPoint *pMidnightPoint = pPreviousTrack->GetLastPoint();
3263 if (RouteManagerDialog::getInstanceFlag()) {
3264 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
3265 pRouteManagerDialog->UpdateTrkListCtrl();
3266 pRouteManagerDialog->UpdateRouteListCtrl();
3271void MyFrame::SetUpMode(
ChartCanvas *cc,
int mode) {
3273 cc->SetUpMode(mode);
3275 SetMenubarItemState(ID_MENU_CHART_COGUP, mode == COURSE_UP_MODE);
3276 SetMenubarItemState(ID_MENU_CHART_NORTHUP, mode == NORTH_UP_MODE);
3277 SetMenubarItemState(ID_MENU_CHART_HEADUP, mode == HEAD_UP_MODE);
3280 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3285 cc->SetShowENCText(!cc->GetShowENCText());
3287 SetMenubarItemState(ID_MENU_ENC_TEXT, cc->GetShowENCText());
3295void MyFrame::SetENCDisplayCategory(
ChartCanvas *cc,
enum _DisCat nset) {
3298 cc->SetENCDisplayCategory(nset);
3300 UpdateGlobalMenuItems();
3311 cc->SetShowENCDepth(!cc->GetShowENCDepth());
3313 SetMenubarItemState(ID_MENU_ENC_SOUNDINGS, cc->GetShowENCDepth());
3322 cc->SetShowENCLights(!cc->GetShowENCLights());
3324 SetMenubarItemState(ID_MENU_ENC_LIGHTS, cc->GetShowENCLights());
3334void MyFrame::ToggleRocks(
void )
3340 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3341 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3342 if( !strncmp( pOLE->OBJLName,
"UWTROC", 6 ) ) {
3343 pOLE->nViz = !pOLE->nViz;
3347 for(
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount(); iPtr++ ) {
3348 OBJLElement *pOLE = (OBJLElement *) ( ps52plib->pOBJLArray->Item( iPtr ) );
3349 if( !strncmp( pOLE->OBJLName,
"OBSTRN", 6 ) ) {
3352 if( !strncmp( pOLE->OBJLName,
"WRECKS", 6 ) ) {
3356 ps52plib->GenerateStateHash();
3363 cc->SetShowENCAnchor(!cc->GetShowENCAnchor());
3365 SetMenubarItemState(ID_MENU_ENC_ANCHOR, cc->GetShowENCAnchor());
3373 cc->SetShowENCDataQual(!cc->GetShowENCDataQual());
3375 SetMenubarItemState(ID_MENU_ENC_DATA_QUALITY, cc->GetShowENCDataQual());
3390 cc->m_bShowNavobjects = !cc->m_bShowNavobjects;
3391 SetMenubarItemState(ID_MENU_SHOW_NAVOBJECTS, cc->m_bShowNavobjects);
3396 cc->SetShowAIS(!cc->GetShowAIS());
3397 SetMenubarItemState(ID_MENU_AIS_TARGETS, cc->GetShowAIS());
3401void MyFrame::ToggleAISMinimizeTargets(
ChartCanvas *cc) {
3402 cc->SetAttenAIS(!cc->GetAttenAIS());
3403 SetMenubarItemState(ID_MENU_AIS_SCALED_TARGETS, cc->GetAttenAIS());
3409 cc->m_bFollow =
true;
3412 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
true);
3416 SetChartUpdatePeriod();
3424 cc->m_bFollow =
false;
3426 SetMenubarItemState(ID_MENU_NAV_FOLLOW,
false);
3430 SetChartUpdatePeriod();
3433void MyFrame::ToggleChartOutlines(
ChartCanvas *cc) {
3434 cc->SetShowOutlines(!cc->GetShowOutlines());
3436 RefreshAllCanvas(
false);
3440 if (g_bopengl) InvalidateAllGL();
3443 SetMenubarItemState(ID_MENU_CHART_OUTLINES, cc->GetShowOutlines());
3446void MyFrame::ToggleTestPause() { g_bPauseTest = !g_bPauseTest; }
3448void MyFrame::SetMenubarItemState(
int item_id,
bool state) {
3450 bool enabled = m_pMenuBar->IsEnabled(item_id);
3451 m_pMenuBar->Enable(item_id,
false);
3452 m_pMenuBar->Check(item_id, state);
3453 m_pMenuBar->Enable(item_id, enabled);
3457void MyFrame::SetMasterToolbarItemState(
int tool_id,
bool state) {
3464void MyFrame::SetToolbarItemBitmaps(
int tool_id, wxBitmap *bmp,
3465 wxBitmap *bmpRollover) {
3467 g_MainToolbar->GetToolbar()->SetToolBitmaps(tool_id, bmp, bmpRollover);
3472void MyFrame::SetToolbarItemSVG(
int tool_id, wxString normalSVGfile,
3473 wxString rolloverSVGfile,
3474 wxString toggledSVGfile) {
3477 tool_id, normalSVGfile, rolloverSVGfile, toggledSVGfile);
3481void MyFrame::ConfigureStatusBar() {
3483 m_StatusBarFieldCount = g_Platform->GetStatusBarFieldCount();
3486 UseNativeStatusBar(
false);
3489 if (g_bShowStatusBar) {
3490 if (!m_pStatusBar) {
3492 CreateStatusBar(m_StatusBarFieldCount, 0);
3493 ApplyGlobalColorSchemetoStatusBar();
3498 m_pStatusBar->Destroy();
3499 m_pStatusBar = NULL;
3505void MyFrame::ApplyGlobalSettings(
bool bnewtoolbar) {
3506 ConfigureStatusBar();
3508 wxSize lastOptSize = options_lastWindowSize;
3514 options_lastWindowSize = lastOptSize;
3516 if (bnewtoolbar) UpdateAllToolbars(global_color_scheme);
3519wxString _menuText(wxString name, wxString shortcut) {
3523 menutext <<
"\t" << shortcut;
3528void MyFrame::BuildMenuBar() {
3534 bool showMenuBar =
true;
3536 bool showMenuBar = g_bShowMenuBar;
3548 m_pMenuBar =
new wxMenuBar();
3549 RegisterGlobalMenuItems();
3550 SetMenuBar(m_pMenuBar);
3554 UpdateGlobalMenuItems();
3559 m_pMenuBar->Destroy();
3565void MyFrame::RegisterGlobalMenuItems() {
3566 if (!m_pMenuBar)
return;
3568 wxMenu *nav_menu =
new wxMenu();
3569 nav_menu->AppendCheckItem(ID_MENU_NAV_FOLLOW,
3570 _menuText(_(
"Auto Follow"),
"Ctrl-A"));
3571 nav_menu->AppendCheckItem(ID_MENU_NAV_TRACK, _(
"Enable Tracking"));
3572 nav_menu->AppendSeparator();
3573 nav_menu->AppendRadioItem(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
3574 nav_menu->AppendRadioItem(ID_MENU_CHART_COGUP, _(
"Course Up Mode"));
3575 nav_menu->AppendRadioItem(ID_MENU_CHART_HEADUP, _(
"Head Up Mode"));
3576 nav_menu->AppendSeparator();
3578 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"+"));
3579 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"-"));
3581 nav_menu->Append(ID_MENU_ZOOM_IN, _menuText(_(
"Zoom In"),
"Alt-+"));
3582 nav_menu->Append(ID_MENU_ZOOM_OUT, _menuText(_(
"Zoom Out"),
"Alt--"));
3584 nav_menu->AppendSeparator();
3585 nav_menu->Append(ID_MENU_SCALE_IN,
3586 _menuText(_(
"Larger Scale Chart"),
"Ctrl-Left"));
3587 nav_menu->Append(ID_MENU_SCALE_OUT,
3588 _menuText(_(
"Smaller Scale Chart"),
"Ctrl-Right"));
3590 nav_menu->AppendSeparator();
3591 nav_menu->Append(ID_MENU_OQUIT, _menuText(_(
"Exit OpenCPN"),
"Ctrl-Q"));
3593 m_pMenuBar->Append(nav_menu, _(
"&Navigate"));
3595 wxMenu *view_menu =
new wxMenu();
3597 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3598 _menuText(_(
"Enable Chart Quilting"),
"Q"));
3599 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3600 _menuText(_(
"Show Chart Outlines"),
"O"));
3602 view_menu->AppendCheckItem(ID_MENU_CHART_QUILTING,
3603 _menuText(_(
"Enable Chart Quilting"),
"Alt-Q"));
3604 view_menu->AppendCheckItem(ID_MENU_CHART_OUTLINES,
3605 _menuText(_(
"Show Chart Outlines"),
"Alt-O"));
3607 view_menu->AppendCheckItem(ID_MENU_UI_CHARTBAR,
3608 _menuText(_(
"Show Chart Bar"),
"Ctrl-B"));
3610 view_menu->AppendSeparator();
3612 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3613 _menuText(_(
"Show ENC text"),
"T"));
3614 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3615 _menuText(_(
"Show ENC Lights"),
"L"));
3616 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3617 _menuText(_(
"Show ENC Soundings"),
"S"));
3618 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3619 _menuText(_(
"Show ENC Anchoring Info"),
"A"));
3620 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3621 _menuText(_(
"Show ENC Data Quality"),
"U"));
3622 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3623 _menuText(_(
"Show Navobjects"),
"V"));
3625 view_menu->AppendCheckItem(ID_MENU_ENC_TEXT,
3626 _menuText(_(
"Show ENC text"),
"Alt-T"));
3627 view_menu->AppendCheckItem(ID_MENU_ENC_LIGHTS,
3628 _menuText(_(
"Show ENC Lights"),
"Alt-L"));
3629 view_menu->AppendCheckItem(ID_MENU_ENC_SOUNDINGS,
3630 _menuText(_(
"Show ENC Soundings"),
"Alt-S"));
3631 view_menu->AppendCheckItem(ID_MENU_ENC_ANCHOR,
3632 _menuText(_(
"Show ENC Anchoring Info"),
"Alt-A"));
3633 view_menu->AppendCheckItem(ID_MENU_ENC_DATA_QUALITY,
3634 _menuText(_(
"Show ENC Data Quality"),
"Alt-U"));
3635 view_menu->AppendCheckItem(ID_MENU_SHOW_NAVOBJECTS,
3636 _menuText(_(
"Show Navobjects"),
"Alt-V"));
3638 view_menu->AppendSeparator();
3639 view_menu->AppendCheckItem(ID_MENU_SHOW_TIDES, _(
"Show Tides"));
3640 view_menu->AppendCheckItem(ID_MENU_SHOW_CURRENTS, _(
"Show Currents"));
3641 view_menu->AppendSeparator();
3643 view_menu->Append(ID_MENU_UI_COLSCHEME,
3644 _menuText(_(
"Change Color Scheme"),
"C"));
3646 view_menu->Append(ID_MENU_UI_COLSCHEME,
3647 _menuText(_(
"Change Color Scheme"),
"Alt-C"));
3650 view_menu->AppendSeparator();
3652 view_menu->Append(ID_MENU_UI_FULLSCREEN,
3653 _menuText(_(
"Toggle Full Screen"),
"F11"));
3655 m_pMenuBar->Append(view_menu, _(
"&View"));
3657 wxMenu *ais_menu =
new wxMenu();
3658 ais_menu->AppendCheckItem(ID_MENU_AIS_TARGETS, _(
"Show AIS Targets"));
3659 ais_menu->AppendCheckItem(ID_MENU_AIS_SCALED_TARGETS,
3660 _(
"Attenuate less critical AIS targets"));
3661 ais_menu->AppendSeparator();
3662 ais_menu->AppendCheckItem(ID_MENU_AIS_MOORED_TARGETS,
3663 _(
"Hide Moored AIS Targets"));
3664 ais_menu->AppendCheckItem(ID_MENU_AIS_TRACKS, _(
"Show AIS Target Tracks"));
3665 ais_menu->AppendCheckItem(ID_MENU_AIS_CPADIALOG, _(
"Show CPA Alert Dialogs"));
3666 ais_menu->AppendCheckItem(ID_MENU_AIS_CPASOUND, _(
"Sound CPA Alarms"));
3669 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3670 _menuText(_(
"Show CPA Warnings"),
"W"));
3672 ais_menu->AppendCheckItem(ID_MENU_AIS_CPAWARNING,
3673 _menuText(_(
"Show CPA Warnings"),
"Alt-W"));
3676 ais_menu->AppendSeparator();
3677 ais_menu->Append(ID_MENU_AIS_TARGETLIST, _(
"AIS target list") +
"...");
3678 m_pMenuBar->Append(ais_menu, _(
"&AIS"));
3680 wxMenu *tools_menu =
new wxMenu();
3681 tools_menu->Append(ID_MENU_TOOL_NMEA_DBG_LOG,
3682 _menuText(_(
"Data Monitor"),
"Alt-C"));
3684 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3685 _menuText(_(
"Measure Distance"),
"M"));
3687 tools_menu->Append(ID_MENU_TOOL_MEASURE,
3688 _menuText(_(
"Measure Distance"),
"Alt-M"));
3691 tools_menu->AppendSeparator();
3692 tools_menu->Append(ID_MENU_ROUTE_MANAGER, _(
"Route && Mark Manager..."));
3693 tools_menu->Append(ID_MENU_ROUTE_NEW, _menuText(_(
"Create Route"),
"Ctrl-R"));
3694 tools_menu->AppendSeparator();
3695 tools_menu->Append(ID_MENU_MARK_BOAT,
3696 _menuText(_(
"Drop Mark at Boat"),
"Ctrl-O"));
3697 tools_menu->Append(ID_MENU_MARK_CURSOR,
3698 _menuText(_(
"Drop Mark at Cursor"),
"Ctrl-M"));
3699 tools_menu->AppendSeparator();
3703 _menuText(_(
"Drop MOB Marker"),
3705 tools_menu->AppendSeparator();
3706 tools_menu->Append(wxID_PREFERENCES,
3707 _menuText(_(
"Preferences") +
"...",
"Ctrl-,"));
3709 tools_menu->Append(ID_MENU_MARK_MOB,
3710 _menuText(_(
"Drop MOB Marker"),
"Ctrl-Space"));
3711 tools_menu->AppendSeparator();
3712 tools_menu->Append(wxID_PREFERENCES,
3713 _menuText(_(
"Options") +
"...",
"Ctrl-,"));
3715 m_pMenuBar->Append(tools_menu, _(
"&Tools"));
3718 wxMenu *window_menu =
new wxMenu();
3719 m_pMenuBar->Append(window_menu, _(
"&Window"));
3722 wxMenu *help_menu =
new wxMenu();
3723 help_menu->Append(wxID_ABOUT, _(
"About OpenCPN"));
3724 help_menu->Append(wxID_HELP, _(
"OpenCPN Help"));
3725 m_pMenuBar->Append(help_menu, _(
"&Help"));
3728 UpdateGlobalMenuItems();
3731void MyFrame::UpdateGlobalMenuItems() {
3732 if (!m_pMenuBar)
return;
3734 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)
3735 ->Check(GetPrimaryCanvas()->m_bFollow);
3736 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)
3737 ->Check(GetPrimaryCanvas()->GetUpMode() == NORTH_UP_MODE);
3738 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)
3739 ->Check(GetPrimaryCanvas()->GetUpMode() == COURSE_UP_MODE);
3740 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)
3741 ->Check(GetPrimaryCanvas()->GetUpMode() == HEAD_UP_MODE);
3742 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3743 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(g_bShowOutlines);
3744 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(g_bQuiltEnable);
3745 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(g_bShowChartBar);
3746 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(g_bShowAIS);
3747 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3748 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(g_bShowScaled);
3749 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3750 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3751 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3752 if (g_bAIS_CPA_Alert) {
3753 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3754 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
true);
3756 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(
false);
3757 m_pMenuBar->Enable(ID_MENU_AIS_CPASOUND,
false);
3760 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3761 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)
3762 ->Check(GetPrimaryCanvas()->m_bShowNavobjects);
3765 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(ps52plib->GetShowS57Text());
3766 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)
3767 ->Check(ps52plib->GetShowSoundings());
3769 bool light_state =
false;
3771 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3773 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3774 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3775 light_state = (pOLE->nViz == 1);
3780 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)
3781 ->Check((!ps52plib->IsObjNoshow(
"LIGHTS")) && light_state);
3785 DisCat nset = ps52plib->GetDisplayCategory();
3786 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3787 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)
3788 ->Check(!ps52plib->IsObjNoshow(
"SBDARE"));
3789 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3790 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3791 ->Check(!ps52plib->IsObjNoshow(
"M_QUAL"));
3792 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3794 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3795 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3796 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3801void MyFrame::UpdateGlobalMenuItems(
ChartCanvas *cc) {
3802 if (!m_pMenuBar)
return;
3804 m_pMenuBar->FindItem(ID_MENU_NAV_FOLLOW)->Check(cc->m_bFollow);
3806 if (cc->GetUpMode() == NORTH_UP_MODE)
3807 m_pMenuBar->FindItem(ID_MENU_CHART_NORTHUP)->Check(
true);
3808 else if (cc->GetUpMode() == COURSE_UP_MODE)
3809 m_pMenuBar->FindItem(ID_MENU_CHART_COGUP)->Check(
true);
3811 m_pMenuBar->FindItem(ID_MENU_CHART_HEADUP)->Check(
true);
3813 m_pMenuBar->FindItem(ID_MENU_NAV_TRACK)->Check(g_bTrackActive);
3814 m_pMenuBar->FindItem(ID_MENU_CHART_OUTLINES)->Check(cc->GetShowOutlines());
3815 m_pMenuBar->FindItem(ID_MENU_CHART_QUILTING)->Check(cc->GetQuiltMode());
3816 m_pMenuBar->FindItem(ID_MENU_UI_CHARTBAR)->Check(cc->GetShowChartbar());
3817 m_pMenuBar->FindItem(ID_MENU_AIS_TARGETS)->Check(cc->GetShowAIS());
3818 m_pMenuBar->FindItem(ID_MENU_AIS_MOORED_TARGETS)->Check(g_bHideMoored);
3819 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Check(cc->GetAttenAIS());
3820 m_pMenuBar->FindItem(ID_MENU_AIS_SCALED_TARGETS)->Enable(g_bAllowShowScaled);
3821 m_pMenuBar->FindItem(ID_MENU_AIS_TRACKS)->Check(g_bAISShowTracks);
3822 m_pMenuBar->FindItem(ID_MENU_AIS_CPADIALOG)->Check(g_bAIS_CPA_Alert);
3823 m_pMenuBar->FindItem(ID_MENU_AIS_CPASOUND)->Check(g_bAIS_CPA_Alert_Audio);
3824 m_pMenuBar->FindItem(ID_MENU_AIS_CPAWARNING)->Check(g_bCPAWarn);
3825 m_pMenuBar->FindItem(ID_MENU_SHOW_NAVOBJECTS)->Check(cc->m_bShowNavobjects);
3826 m_pMenuBar->FindItem(ID_MENU_SHOW_TIDES)->Check(cc->GetbShowTide());
3827 m_pMenuBar->FindItem(ID_MENU_SHOW_CURRENTS)->Check(cc->GetbShowCurrent());
3830 m_pMenuBar->FindItem(ID_MENU_ENC_TEXT)->Check(cc->GetShowENCText());
3831 m_pMenuBar->FindItem(ID_MENU_ENC_SOUNDINGS)->Check(cc->GetShowENCDepth());
3834 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
3836 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
3837 if (!strncmp(pOLE->OBJLName,
"LIGHTS", 6)) {
3842 m_pMenuBar->FindItem(ID_MENU_ENC_LIGHTS)->Check(cc->GetShowENCLights());
3846 DisCat nset = (DisCat)cc->GetENCDisplayCategory();
3847 if ((nset == MARINERS_STANDARD) || (nset == OTHER)) {
3848 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(cc->GetShowENCAnchor());
3849 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
true);
3850 m_pMenuBar->FindItem(ID_MENU_ENC_DATA_QUALITY)
3851 ->Check(cc->GetShowENCDataQual());
3852 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
true);
3854 m_pMenuBar->FindItem(ID_MENU_ENC_ANCHOR)->Check(
false);
3855 m_pMenuBar->Enable(ID_MENU_ENC_ANCHOR,
false);
3856 m_pMenuBar->Enable(ID_MENU_ENC_DATA_QUALITY,
false);
3861void MyFrame::InvalidateAllCanvasUndo() {
3863 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3865 if (cc) cc->undo->InvalidateUndo();
3869void MyFrame::SubmergeAllCanvasToolbars() {
3871 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3873 if (cc) cc->SubmergeToolbar();
3877void MyFrame::SurfaceAllCanvasToolbars() {
3878 if (g_bshowToolbar) {
3880 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
3882 if (cc && cc->GetToolbarEnable()) cc->SurfaceToolbar();
3889void MyFrame::JumpToPosition(
ChartCanvas *cc,
double lat,
double lon,
3891 if (lon > 180.0) lon -= 360.0;
3896 cc->JumpToPosition(lat, lon,
scale);
3899 g_pi_manager->SendViewPortToRequestingPlugIns(cc->GetVP());
3903void MyFrame::UpdateCanvasConfigDescriptors() {
3905 for (
unsigned int i = 0;
3906 i < ConfigMgr::Get().GetCanvasConfigArray().GetCount(); i++) {
3907 canvasConfig *cc = ConfigMgr::Get().GetCanvasConfigArray().Item(i);
3915 cc->DBindex = chart->GetQuiltReferenceChartIndex();
3916 cc->GroupID = chart->m_groupIndex;
3919 cc->
bQuilt = chart->GetQuiltMode();
3926 cc->
bFollow = chart->m_bFollow;
3931 int upmode = chart->GetUpMode();
3932 if (upmode == COURSE_UP_MODE)
3934 else if (upmode == HEAD_UP_MODE)
3941void MyFrame::CenterView(
ChartCanvas *cc,
const LLBBox &RBBox) {
3942 if (!RBBox.GetValid())
return;
3944 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
3945 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
3948 if (RBBox.GetMinLat() == RBBox.GetMaxLat() &&
3949 RBBox.GetMinLon() == RBBox.GetMaxLon()) {
3957 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3958 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
3960 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
3961 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
3963 cc->GetSize(&ww, &wh);
3965 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
3967 ppm = wxMin(ppm, 1.0);
3973void MyFrame::PrepareOptionsClose(
options *settings,
3974 int settings_return_value) {
3976 options_lastPage = settings->lastPage;
3981 if (options_lastPage == 1) options_lastPage = 0;
3983 options_subpage = settings->lastSubPage;
3984 options_lastWindowPos = settings->lastWindowPos;
3985 options_lastWindowSize = settings->lastWindowSize;
3988 androidEnableBackButton(
true);
3989 androidEnableOptionsMenu(
true);
3990 androidRestoreFullScreen();
3991 androidEnableRotation();
3996void MyFrame::DoOptionsDialog() {
3998 AbstractPlatform::ShowBusySpinner();
4001 pConfig->SetPath(
"/Settings");
4002 pConfig->Read(
"OptionsSizeX", &sx, -1);
4003 pConfig->Read(
"OptionsSizeY", &sy, -1);
4005 wxWindow *optionsParent =
this;
4007 optionsParent = GetPrimaryCanvas();
4012 AbstractPlatform::HideBusySpinner();
4016 g_options->SetInitChartDir(*pInit_Chart_Dir);
4020 ArrayOfCDI *pWorkDirArray =
new ArrayOfCDI;
4021 g_options->SetWorkDirListPtr(pWorkDirArray);
4027 prev_locale = g_locale;
4028 g_options->SetInitialPage(options_lastPage, options_subpage);
4031 g_options->lastWindowPos = options_lastWindowPos;
4032 if (options_lastWindowPos != wxPoint(0, 0)) {
4034 g_options->SetSize(options_lastWindowSize);
4038 if (options_lastWindowSize != wxSize(0, 0)) {
4039 g_options->SetSize(options_lastWindowSize);
4044 androidEnableBackButton(
false);
4045 androidEnableOptionsMenu(
false);
4046 androidDisableFullScreen();
4054 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4057 wxString chart_file_name;
4058 if (cc->GetQuiltMode()) {
4059 int dbi = cc->GetQuiltRefChartdbIndex();
4060 chart_file_name =
ChartData->GetDBChartFileName(dbi);
4062 if (cc->m_singleChart)
4063 chart_file_name = cc->m_singleChart->GetFullPath();
4066 pathArray.Add(chart_file_name);
4072 last_canvasConfig = g_canvasConfig;
4075 g_last_ChartScaleFactor = g_ChartScaleFactor;
4081void MyFrame::ProcessOptionsDialog(
int rr, ArrayOfCDI *pNewDirArray) {
4082 bool b_need_refresh =
false;
4084 if ((rr & VISIT_CHARTS) &&
4085 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) {
4087 UpdateChartDatabaseInplace(*pNewDirArray,
4088 ((rr & FORCE_UPDATE) == FORCE_UPDATE),
true,
4091 b_need_refresh =
true;
4095 if (rr & STYLE_CHANGED) {
4098 _(
"Please restart OpenCPN to activate language or style changes."),
4099 _(
"OpenCPN Info"), wxOK | wxICON_INFORMATION);
4102 bool b_groupchange =
false;
4103 if (((rr & VISIT_CHARTS) &&
4104 ((rr & CHANGE_CHARTS) || (rr & FORCE_UPDATE) || (rr & SCAN_UPDATE))) ||
4105 (rr & GROUPS_CHANGED)) {
4106 b_groupchange = ScrubGroupArray();
4108 RefreshGroupIndices();
4111 if (rr & GROUPS_CHANGED || b_groupchange) {
4112 pConfig->DestroyConfigGroups();
4116 if (rr & TIDES_CHANGED) {
4122 if (rr & S52_CHANGED) {
4123 WayPointmanGui(*pWayPointMan).ReloadAllIcons(g_Platform->GetDisplayDPmm());
4126 pConfig->UpdateSettings();
4134 g_Platform->GetDisplayDPmm());
4137 double stuffcog = NAN;
4138 double stuffsog = NAN;
4139 if (!std::isnan(
gCog)) stuffcog =
gCog;
4140 if (!std::isnan(
gSog)) stuffsog =
gSog;
4142 for (
int i = 0; i < MAX_COGSOG_FILTER_SECONDS; i++) {
4143 COGFilterTable[i] = stuffcog;
4144 SOGFilterTable[i] = stuffsog;
4147 SetChartUpdatePeriod();
4149 if (rr & GL_CHANGED) {
4153 b_need_refresh =
true;
4156 if (rr & S52_CHANGED) {
4157 b_need_refresh =
true;
4161 if (rr & REBUILD_RASTER_CACHE) {
4163 GetPrimaryCanvas()->Disable();
4165 GetPrimaryCanvas()->Enable();
4170 if (g_config_display_size_manual &&
4178 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4185 int rrt = rr & S52_CHANGED;
4187 (rrt == S52_CHANGED) ||
4188 (g_last_ChartScaleFactor != g_ChartScaleFactor));
4198 ps52plib->SetScaleFactorExp(
4199 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
4200 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
4204 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4206 if (cc) cc->ApplyGlobalSettings();
4211 bool ztc = g_bEnableZoomToCursor;
4212 g_bEnableZoomToCursor =
4216 if (!GetPrimaryCanvas()->IsFrozen())
4218 g_bEnableZoomToCursor = ztc;
4221 if (g_last_ChartScaleFactor != g_ChartScaleFactor) {
4230 SetGPSCompassScale();
4232 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4235 cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
4236 cc->UpdateCanvasControlBar();
4239 UpdateGPSCompassStatusBoxes();
4241 SetAllToolbarScale();
4242 RequestNewToolbars();
4245 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4248 cc->RebuildCursors();
4253 bool b_masterScaleChange =
false;
4254 if (fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor) > 0.01f)
4255 b_masterScaleChange =
true;
4257 if ((rr & TOOLBAR_CHANGED) || b_masterScaleChange)
4258 RequestNewMasterToolbar(
true);
4260 bool bMuiChange =
false;
4266 if (b_masterScaleChange || bMuiChange) {
4268 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4271 cc->ProcessNewGUIScale();
4277 if (rr & LOCALE_CHANGED) {
4278 g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang);
4280 rr |= NEED_NEW_OPTIONS;
4289 g_last_ChartScaleFactor = g_ChartScaleFactor;
4291 if (rr & FORCE_RELOAD) ScheduleReloadCharts();
4296bool MyFrame::CheckGroup(
int igroup) {
4297 if (igroup == 0)
return true;
4301 if (!pGroup->m_element_array.size())
4304 for (
const auto &elem : pGroup->m_element_array) {
4305 for (
unsigned int ic = 0;
4306 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4308 wxString chart_full_path(pcte->GetpFullPath(), wxConvUTF8);
4310 if (chart_full_path.StartsWith(elem.m_element_name))
return true;
4317bool MyFrame::ScrubGroupArray() {
4322 bool b_change =
false;
4323 unsigned int igroup = 0;
4324 while (igroup < g_pGroupArray->GetCount()) {
4325 bool b_chart_in_element =
false;
4328 for (
unsigned int j = 0; j < pGroup->m_element_array.size(); j++) {
4329 const wxString &element_root = pGroup->m_element_array[j].m_element_name;
4331 for (
unsigned int ic = 0;
4332 ic < (
unsigned int)
ChartData->GetChartTableEntries(); ic++) {
4334 wxString chart_full_path = pcte->GetFullSystemPath();
4336 if (chart_full_path.StartsWith(element_root)) {
4337 b_chart_in_element =
true;
4343 if (!b_chart_in_element) {
4344 wxString test_string =
"GSHH";
4345 if (element_root.Upper().Contains(test_string))
4346 b_chart_in_element =
true;
4349 if (!b_chart_in_element)
4351 pGroup->m_element_array.erase(pGroup->m_element_array.begin() + j);
4363void MyFrame::RefreshCanvasOther(
ChartCanvas *ccThis) {
4365 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4367 if (cc && (cc != ccThis)) cc->Refresh();
4372void MyFrame::ChartsRefresh() {
4375 AbstractPlatform::ShowBusySpinner();
4377 bool b_run = FrameTimer1.IsRunning();
4380 FrameTenHzTimer.Stop();
4383 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4386 int currentIndex = cc->GetpCurrentStack()->GetCurrentEntrydbIndex();
4387 if (cc->GetQuiltMode()) {
4388 currentIndex = cc->GetQuiltReferenceChartIndex();
4390 cc->canvasChartsRefresh(currentIndex);
4394 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4395 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4397 AbstractPlatform::HideBusySpinner();
4400void MyFrame::InvalidateAllQuilts() {
4401 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4404 cc->InvalidateQuilt();
4405 cc->SetQuiltRefChart(-1);
4406 cc->m_singleChart = NULL;
4411bool MyFrame::UpdateChartDatabaseInplace(ArrayOfCDI &DirArray,
bool b_force,
4413 const wxString &ChartListFileName) {
4414 bool b_run = FrameTimer1.IsRunning();
4416 FrameTenHzTimer.Stop();
4418 bool b_runCOGTimer = FrameCOGTimer.IsRunning();
4419 FrameCOGTimer.Stop();
4422 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4425 cc->InvalidateQuilt();
4426 cc->SetQuiltRefChart(-1);
4427 cc->m_singleChart = NULL;
4437 AbstractPlatform::ShowBusySpinner();
4439 wxGenericProgressDialog *pprog =
nullptr;
4441 wxString longmsg = _(
"OpenCPN Chart Update");
4443 ".................................................................."
4446 pprog =
new wxGenericProgressDialog();
4449 pprog->SetFont(*qFont);
4451 pprog->Create(_(
"OpenCPN Chart Update"), longmsg, 100,
gFrame,
4452 wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
4453 wxPD_REMAINING_TIME);
4460 wxLogMessage(
"Starting chart database Update...");
4461 wxString gshhg_chart_loc = gWorldMapLocation;
4462 gWorldMapLocation = wxEmptyString;
4466 ChartData->SaveBinary(ChartListFileName);
4467 wxLogMessage(
"Finished chart database Update");
4469 if (gWorldMapLocation.empty()) {
4473 gWorldMapLocation = gDefaultWorldMapLocation;
4474 gshhg_chart_loc = wxEmptyString;
4477 if (gWorldMapLocation != gshhg_chart_loc) {
4479 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4481 if (cc) cc->ResetWorldBackgroundChart();
4484 gshhsCrossesLandReset();
4489 AbstractPlatform::HideBusySpinner();
4491 pConfig->UpdateChartDirs(DirArray);
4494 if (b_run) FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4495 if (b_run) FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4497 if (b_runCOGTimer) {
4499 int period_ms = 100;
4501 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
4508 cc->ToggleCanvasQuiltMode();
4510 bool cur_mode = cc->GetQuiltMode();
4512 if( !cc->GetQuiltMode() )
4513 cc->SetQuiltMode(
true );
4515 if( cc->GetQuiltMode() ) {
4516 cc->SetQuiltMode(
false );
4517 g_sticky_chart = cc->GetQuiltReferenceChartIndex();
4521 if( cur_mode != cc->GetQuiltMode() ){
4527 g_bQuiltEnable = cc->GetQuiltMode();
4531 ps52plib->GenerateStateHash();
4536void MyFrame::DoStackDown(
ChartCanvas *cc) { DoStackDelta(cc, -1); }
4538void MyFrame::DoStackUp(
ChartCanvas *cc) { DoStackDelta(cc, 1); }
4540void MyFrame::DoStackDelta(
ChartCanvas *cc,
int direction) {
4542 cc->DoCanvasStackDelta(direction);
4546void MyFrame::PositionIENCToolbar() {
4550 posn.x = (GetPrimaryCanvas()->GetSize().x -
g_iENCToolbar->GetSize().x) / 2;
4552 g_iENCToolbar->Move(GetPrimaryCanvas()->ClientToScreen(posn));
4560void MyFrame::OnInitTimer(wxTimerEvent &event) {
4563 msg.Printf(
"OnInitTimer...%d", m_iInitCount);
4567 wxLog::FlushActive();
4569 switch (m_iInitCount++) {
4574 if (g_bInlandEcdis) {
4575 double range = GetPrimaryCanvas()->GetCanvasRangeMeters();
4576 double range_set = 500.;
4578 range = wxRound(range * 10) / 10.;
4582 else if (range > 2000.)
4584 else if (range > 1600.)
4586 else if (range > 1200.)
4588 else if (range > 800.)
4593 GetPrimaryCanvas()->SetCanvasRangeMeters(range_set);
4597 g_Platform->SetFullscreen(g_bFullscreen);
4601 RebuildChartDatabase();
4602 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4605 cc->SetGroupIndex(0,
false);
4613 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4614 CHART_FAMILY_RASTER)) {
4619 if (
ChartData->GetCentroidOfLargestScaleChart(&clat, &clon,
4620 CHART_FAMILY_VECTOR)) {
4633 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4636 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4638 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4641 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4645 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4646 NavObj_dB::GetInstance().LoadNavObjects();
4649 if (!g_AW1GUID.IsEmpty()) {
4652 if (!g_AW2GUID.IsEmpty()) {
4658 appendOSDirSlash(&layerdir);
4659 layerdir.Append(
"layers");
4661 if (wxDir::Exists(layerdir)) {
4663 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4664 wxLogMessage(laymsg);
4665 pConfig->LoadLayers(layerdir);
4675 if (
g_pi_manager->IsAnyPlugInChartEnabled()) b_reloadForPlugins =
true;
4689 3 * GetCharHeight());
4691 m_data_monitor->Center();
4699 pConfig->SetPath(
"/Settings");
4700 pConfig->Read(
"OptionsSizeX", &sx, -1);
4701 pConfig->Read(
"OptionsSizeY", &sy, -1);
4703 wxWindow *optionsParent =
this;
4705 optionsParent = GetPrimaryCanvas();
4711 BuildiENCToolbar(
true);
4718 if (!g_params.empty()) {
4719 for (
size_t n = 0; n < g_params.size(); n++) {
4720 wxString path = g_params[n];
4721 if (::wxFileExists(path)) {
4723 pSet->load_file(path.fn_str());
4726 pSet->LoadAllGPXObjects(
4727 !pSet->IsOpenCPN(), wpt_dups,
4729 LLBBox box = pSet->GetBBox();
4730 if (box.GetValid()) {
4731 CenterView(GetPrimaryCanvas(), box);
4740 InitAppMsgBusListener();
4745 auto loader = PluginLoader::GetInstance();
4746 bool b_haveWMM = loader && loader->IsPlugInAvailable(
"WMM");
4747 if (!b_haveWMM)
gVar = g_UserVar;
4755 auto colour_func = [](wxString c) {
return GetGlobalColor(c); };
4758 .SetColorScheme(global_color_scheme, g_Platform->GetDisplayDPmm());
4760 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4763 if (cc->SetUserOwnship()) cc->SetColorScheme(global_color_scheme);
4767 NavObj_dB::GetInstance().ImportLegacyNavobj(
this);
4768 NavObj_dB::GetInstance().LoadNavObjects();
4771 if (!g_AW1GUID.IsEmpty()) {
4774 if (!g_AW2GUID.IsEmpty()) {
4780 appendOSDirSlash(&layerdir);
4781 layerdir.Append(
"layers");
4783 if (wxDir::Exists(layerdir)) {
4785 laymsg.Printf(
"Getting .gpx layer files from: %s", layerdir.c_str());
4786 wxLogMessage(laymsg);
4787 pConfig->LoadLayers(layerdir);
4794 wxLogMessage(
"OnInitTimer...Last Call");
4798 RequestNewMasterToolbar();
4800 PositionIENCToolbar();
4802 g_bDeferredInitDone =
true;
4812 GetPrimaryCanvas()->SetFocus();
4813 GetPrimaryCanvas()->Enable();
4820 if (b_reloadForPlugins) {
4826 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4828 if (cc) cc->SetFirstAuto(
true);
4836 wxLogMessage(
"OnInitTimer...Finalize Canvases");
4838 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
4842 cc->CheckGroupValid();
4847 androidEnableBackButton(
true);
4848 androidEnableRotation();
4849 androidEnableOptionItems(
true);
4855 if (g_start_fullscreen && !IsFullScreen()) ToggleFullScreen();
4861 gFrame->FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
4863 gFrame->FrameCOGTimer.Start(2000, wxTIMER_CONTINUOUS);
4865 gFrame->FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
4871 if (!g_bDeferredInitDone) InitTimer.Start(10, wxTIMER_ONE_SHOT);
4873 wxLog::FlushActive();
4875 RefreshAllCanvas(
true);
4876 UsbWatchDaemon::GetInstance().Start();
4882void MyFrame::InitAppMsgBusListener() {
4883 auto &msgbus = AppMsgBus::GetInstance();
4886 AppMsg msg_basic(AppMsg::Type::BasicNavData);
4887 listener_basic_navdata.
Listen(msg_basic,
this, EVT_BASIC_NAV_DATA);
4891 auto basicnav_msg = std::static_pointer_cast<const BasicNavDataMsg>(ptr);
4892 HandleBasicNavMsg(basicnav_msg);
4896 AppMsg msg_watchdog(AppMsg::Type::GPSWatchdog);
4897 listener_gps_watchdog.
Listen(msg_watchdog,
this, EVT_GPS_WATCHDOG);
4901 auto msg = std::static_pointer_cast<const GPSWatchdogMsg>(ptr);
4902 HandleGPSWatchdogMsg(msg);
4909void MyFrame::ReleaseApiListeners() {}
4914 m_on_raise_listener.
Init(server.on_raise, [&](
ObservedEvt) { Raise(); });
4915 m_on_quit_listener.
Init(server.on_quit, [&](
ObservedEvt) { FastClose(); });
4916 server.SetGetRestApiEndpointCb([&] {
return m_rest_server.
GetEndpoint(); });
4917 server.open_file_cb = [&](
const std::string &path) {
4918 return m_open_gpx_file(path);
4925void MyFrame::HandleGPSWatchdogMsg(std::shared_ptr<const GPSWatchdogMsg> msg) {
4926 if (msg->gps_watchdog <= 0) {
4927 if (msg->wd_source == GPSWatchdogMsg::WDSource::position) {
4931 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
4936 if (m_fix_start_time.IsValid()) {
4937 wxDateTime now = wxDateTime::Now();
4938 wxTimeSpan span = now - m_fix_start_time;
4939 if (span.IsLongerThan(wxTimeSpan(0, 5))) {
4940 auto ¬eman = NotificationManager::GetInstance();
4941 wxString msg = _(
"GNSS Position fix lost");
4942 noteman.AddNotification(NotificationSeverity::kCritical,
4944 m_fix_start_time = wxInvalidDateTime;
4948 }
else if (msg->wd_source == GPSWatchdogMsg::WDSource::velocity) {
4949 bool last_bVelocityValid = bVelocityValid;
4950 bVelocityValid =
false;
4957void MyFrame::CalculateCOGAverage() {
4959 if (!std::isnan(
gCog)) {
4962 for (
int i =
g_COGAvgSec - 1; i > 0; i--) COGTable[i] = COGTable[i - 1];
4965 double sum = 0., count = 0;
4967 double adder = COGTable[i];
4968 if (std::isnan(adder))
continue;
4970 if (fabs(adder -
g_COGAvg) > 180.) {
4984 else if (sum >= 360.)
4993void MyFrame::HandleBasicNavMsg(std::shared_ptr<const BasicNavDataMsg> msg) {
4994 m_fixtime = msg->time;
4995 double hdt_data_interval = 0;
4996 double fix_time_interval = 0;
4998 double msgtime = msg->set_time.tv_sec;
4999 double m1 = msg->set_time.tv_nsec / 1e9;
5002 if (((msg->vflag & POS_UPDATE) == POS_UPDATE) &&
5003 ((msg->vflag & POS_VALID) == POS_VALID)) {
5005 if (!m_fix_start_time.IsValid()) {
5006 m_fix_start_time = wxDateTime::Now();
5011 DistanceBearingMercator(
gLat,
gLon, gLat_gt, gLon_gt, &brg, &dist);
5014 fix_time_gt_last = fix_time_gt;
5015 uint64_t fix_time_gt_now =
5016 msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5017 fix_time_interval = (fix_time_gt_now - fix_time_gt_last) / (
double)1e9;
5021 double implied_sog = dist / (fix_time_interval / 3600);
5026 gLat_gt_m1 = gLat_gt;
5027 gLon_gt_m1 = gLon_gt;
5031 fix_time_gt = fix_time_gt_now;
5035 if (((msg->vflag & COG_UPDATE) == COG_UPDATE) &&
5036 ((msg->vflag & SOG_UPDATE) == SOG_UPDATE)) {
5037 gCog_gt_m1 = gCog_gt;
5047 if (!std::isnan(gCog_gt_m1)) {
5049 if ((fabs(
gSog - implied_sog) /
gSog) > 0.5) {
5056 if ((fix_time_gt - fix_time_gt_last) > .08) {
5061 if (gCog_gt > gCog_gt_m1) {
5062 if ((gCog_gt - gCog_gt_m1) > 180.)
5067 if ((gCog_gt_m1 - gCog_gt) > 180.)
5072 difft = fabs(gCog_gt - gCog_gt_m1);
5073 if (fabs(difft > 180.)) difft = fabs(difft - 360.);
5081 double tentative_cog_rate_gt = diff / (fix_time_gt - fix_time_gt_last);
5082 tentative_cog_rate_gt *= 1e9;
5083 cog_rate_gt = tentative_cog_rate_gt;
5091 if ((msg->vflag & HDT_UPDATE) == HDT_UPDATE) {
5094static double hdt_avg;
5095 double hdt_norm =
gHdt;
5096 if(
gHdt > 180) hdt_norm -= 360;
5099 hdt_avg += hdt_norm * 0.1;
5104 if (!std::isnan(
gHdt)) {
5106 uint64_t hdt_time_gt_last = hdt_time_gt;
5107 hdt_time_gt = msg->set_time.tv_sec * 1e9 + msg->set_time.tv_nsec;
5108 hdt_data_interval = (hdt_time_gt - hdt_time_gt_last) / 1e9;
5111 if (hdt_data_interval > .09) {
5113 gHdt_gt_m1 = gHdt_gt;
5116 if (!std::isnan(gHdt_gt_m1)) {
5118 double tentative_hdt_rate_gt =
5119 (gHdt_gt - gHdt_gt_m1) / (hdt_time_gt - hdt_time_gt_last);
5120 tentative_hdt_rate_gt *= 1e9;
5122 if (fabs(tentative_hdt_rate_gt - hdt_rate_gt) < 180.)
5123 hdt_rate_gt = tentative_hdt_rate_gt;
5131 if (std::isnan(
gHdt)) gHdt_gt = NAN;
5134 CalculateCOGAverage();
5142 if ((msg->vflag & POS_UPDATE) == POS_UPDATE) {
5143 if ((msg->vflag & POS_VALID) == POS_VALID)
5148 if (last_bGPSValid !=
bGPSValid) UpdateGPSCompassStatusBoxes(
true);
5150 bVelocityValid =
true;
5154void MyFrame::UpdateStatusBar() {
5157 unsigned long uiCurrentTickCount;
5158 m_MMEAeventTime.SetToCurrent();
5159 uiCurrentTickCount =
5160 m_MMEAeventTime.GetMillisecond() / 100;
5161 uiCurrentTickCount += m_MMEAeventTime.GetTicks() * 10;
5162 if (uiCurrentTickCount > m_ulLastNMEATicktime + 1) {
5163 m_ulLastNMEATicktime = uiCurrentTickCount;
5165 if (m_tick_idx++ > 6) m_tick_idx = 0;
5170 if (NULL != GetStatusBar()) {
5173 tick_buf[0] = nmea_tick_chars[m_tick_idx];
5176 wxString s1(tick_buf, wxConvUTF8);
5178 s1 += toSDMM(1,
gLat);
5180 s1 += toSDMM(2,
gLon);
5182 if (STAT_FIELD_TICK >= 0) SetStatusText(s1, STAT_FIELD_TICK);
5186 if (!std::isnan(
gSog))
5187 sogcog.Printf(
"SOG %2.2f " + getUsrSpeedUnit() +
" ", toUsrSpeed(
gSog));
5189 sogcog.Printf(
"SOG --- ");
5193 if (!std::isnan(
gCog) && !std::isnan(
gSog) && (
gSog > 0.05)) {
5195 cogs << wxString::Format(wxString(
"COG %03d%c "), (
int)
gCog, 0x00B0);
5197 cogs << wxString::Format(wxString(
"COG %03d%c(M) "),
5198 (
int)toMagnetic(
gCog), 0x00B0);
5200 cogs.Printf((
"COG ---%c"), 0x00B0);
5202 sogcog.Append(cogs);
5203 SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5208void MyFrame::OnMemFootTimer(wxTimerEvent &event) {
5209 MemFootTimer.Stop();
5211 int memsize = GetApplicationMemoryUse();
5214 printf(
"Memsize: %d \n", memsize);
5217 if (memsize > (g_MemFootMB * 1000)) {
5221 wxArrayPtrVoid *pCache =
ChartData->GetChartCache();
5222 unsigned int nCache = pCache->GetCount();
5225 for (
unsigned int i = 0; i < nCache; i++) {
5235 for (
unsigned int i = 0; i < nCache - 1; i++) {
5236 if (pcea[i].RecentTime > pcea[i + 1].RecentTime) {
5238 pcea[i] = pcea[i + 1];
5249 unsigned int idelete = 0;
5250 unsigned int idelete_max = pCache->GetCount();
5253 unsigned int minimum_cache = 1;
5254 if (cc->GetQuiltMode()) minimum_cache = cc->GetQuiltChartCount();
5256 while ((memsize > (g_MemFootMB * 1000)) &&
5257 (pCache->GetCount() > minimum_cache) &&
5258 (idelete < idelete_max)) {
5259 int memsizeb = memsize;
5263 memsize = GetApplicationMemoryUse();
5264 printf(
"delete, before: %d after: %d\n", memsizeb, memsize);
5272 MemFootTimer.Start(9000, wxTIMER_CONTINUOUS);
5277void MyFrame::CheckToolbarPosition() {
5280 static bool bMaximized;
5282 if (IsMaximized() && !bMaximized) {
5289 PositionIENCToolbar();
5290 }
else if (!IsMaximized() && bMaximized) {
5298 PositionIENCToolbar();
5303void MyFrame::ProcessUnitTest() {
5304 if (!g_bPauseTest && (g_unit_test_1 || g_unit_test_2)) {
5311 cc->m_bFollow =
false;
5313 g_MainToolbar->GetToolbar()->ToggleTool(ID_FOLLOW, cc->m_bFollow);
5314 int ut_index_max = ((g_unit_test_1 > 0) ? (g_unit_test_1 - 1) : INT_MAX);
5317 if (cc->m_groupIndex > 0) {
5318 while (ut_index < ChartData->GetChartTableEntries() &&
5319 !
ChartData->IsChartInGroup(ut_index, cc->m_groupIndex)) {
5323 if (ut_index < ChartData->GetChartTableEntries()) {
5327 double clat = (cte->GetLatMax() + cte->GetLatMin()) / 2;
5328 double clon = (cte->GetLonMax() + cte->GetLonMin()) / 2;
5335 if (cc->GetQuiltMode()) {
5336 if (cc->IsChartQuiltableRef(ut_index))
5337 cc->SelectQuiltRefdbChart(ut_index);
5339 cc->SelectdbChart(ut_index);
5342 if (g_unit_test_1) {
5350 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5351 cte->GetLatMin(), cte->GetLonMax(), NULL,
5355 DistanceBearingMercator(cte->GetLatMin(), cte->GetLonMin(),
5356 cte->GetLatMax(), cte->GetLonMin(), NULL,
5359 cc->GetSize(&ww, &wh);
5360 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) /
5362 ppm = wxMin(ppm, 1.0);
5369 if (ut_index > ut_index_max) exit(0);
5380 bool b_rotate =
false;
5382 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5385 if (!b_rotate && !g_btenhertz)
return;
5387 bool b_update =
false;
5389 if (!std::isnan(
gCog) && !std::isnan(
gSog)) {
5392 struct timespec now;
5393 clock_gettime(CLOCK_MONOTONIC, &now);
5394 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - fix_time_gt;
5395 double diffc = diff / 1e9;
5398 double gCog_tentative = gCog_gt_m1 + (cog_rate_gt * diffc);
5399 if (gCog_tentative >= 360.) gCog_tentative -= 360.;
5400 if (gCog_tentative < 0.) gCog_tentative += 360.;
5401 gCog = gCog_tentative;
5405 if (!std::isnan(gHdt_gt) && !std::isnan(gHdt_gt_m1)) {
5406 uint64_t diff = 1e9 * (now.tv_sec) + now.tv_nsec - hdt_time_gt;
5407 double diffc = diff / 1e9;
5408 gHdt = gHdt_gt_m1 + (hdt_rate_gt * diffc);
5412 if (gSog_gt && !std::isnan(gCog_gt)) {
5413 double delta_t = diffc / 3600;
5414 double distance = gSog_gt * delta_t;
5417 double angr = gCog_gt / 180 * M_PI;
5418 double latr = gLat_gt * M_PI / 180;
5419 double D = distance / 3443;
5420 double sD = sin(D), cD = cos(D);
5421 double sy = sin(latr), cy = cos(latr);
5422 double sa = sin(angr), ca = cos(angr);
5424 gLon = gLon_gt + asin(sa * sD / cy) * 180 / M_PI;
5425 gLat = asin(sy * cD + cy * sD * ca) * 180 / M_PI;
5435 if (cc) cc->DoCanvasCOGSet();
5444 if (cc->GetUpMode() != NORTH_UP_MODE || cc->m_bFollow) {
5445 cc->DoCanvasUpdate();
5454 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5457bool MyFrame::ProcessQuitFlag() {
5461 FrameTenHzTimer.Stop();
5463 wxWindow *top = wxTheApp ? wxTheApp->GetTopWindow() :
nullptr;
5464 if (top) top->Close(
true);
5471void MyFrame::ProcessDeferredTrackOn() {
5474 if (g_bDeferredStartTrack) {
5475 if (!g_bTrackActive) {
5478 g_bDeferredStartTrack =
false;
5481 g_bDeferredStartTrack =
false;
5486void MyFrame::ProcessAnchorWatch() {
5494 double d = g_nAWMax;
5496 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5497 bool toofar =
false;
5498 bool tooclose =
false;
5499 if (d >= 0.0) toofar = (dist * 1852. > d);
5500 if (d < 0.0) tooclose = (dist * 1852 < -d);
5502 if (tooclose || toofar)
5503 AnchorAlertOn1 =
true;
5505 AnchorAlertOn1 =
false;
5507 AnchorAlertOn1 =
false;
5515 double d = g_nAWMax;
5517 d = AnchorDistFix(d, AnchorPointMinDist, g_nAWMax);
5518 bool toofar =
false;
5519 bool tooclose =
false;
5520 if (d >= 0) toofar = (dist * 1852. > d);
5521 if (d < 0) tooclose = (dist * 1852 < -d);
5523 if (tooclose || toofar)
5524 AnchorAlertOn2 =
true;
5526 AnchorAlertOn2 =
false;
5528 AnchorAlertOn2 =
false;
5531 AnchorAlertOn1 =
true;
5534void MyFrame::SendFixToPlugins() {
5545 GPSData.
nSats = g_SatsInView;
5547 wxDateTime tCheck((time_t)m_fixtime);
5548 if (tCheck.IsValid()) {
5557 GPSData.
FixTime = wxDateTime::Now().GetTicks();
5560 SendPositionFixToAllPlugIns(&GPSData);
5564void MyFrame::ProcessLogAndBells() {
5567 wxDateTime lognow = wxDateTime::Now();
5568 int hourLOC = lognow.GetHour();
5569 int minuteLOC = lognow.GetMinute();
5571 int minuteUTC = lognow.GetMinute();
5572 int second = lognow.GetSecond();
5574 wxTimeSpan logspan = lognow.Subtract(g_loglast_time);
5575 if ((logspan.IsLongerThan(wxTimeSpan(0, 30, 0, 0))) || (minuteUTC == 0) ||
5576 (minuteUTC == 30)) {
5577 if (logspan.IsLongerThan(wxTimeSpan(0, 1, 0, 0))) {
5578 wxString day = lognow.FormatISODate();
5579 wxString utc = lognow.FormatISOTime();
5580 wxString navmsg =
"LOGBOOK: ";
5588 data.Printf(
" GPS Lat %10.5f Lon %10.5f ",
gLat,
gLon);
5592 if (std::isnan(
gCog))
5593 cog.Printf(
"COG ----- ");
5595 cog.Printf(
"COG %10.5f ",
gCog);
5598 if (std::isnan(
gSog))
5599 sog.Printf(
"SOG ----- ");
5601 sog.Printf(
"SOG %6.2f " + getUsrSpeedUnit(), toUsrSpeed(
gSog));
5607 data.Printf(
" DR Lat %10.5f Lon %10.5f",
gLat,
gLon);
5610 wxLogMessage(navmsg);
5611 g_loglast_time = lognow;
5613 int bells = (hourLOC % 4) * 2;
5614 if (minuteLOC != 0) bells++;
5615 if (!bells) bells = 8;
5617 if (g_bPlayShipsBells && ((minuteLOC == 0) || (minuteLOC == 30))) {
5618 m_BellsToPlay = bells;
5619 wxCommandEvent ev(BELLS_PLAYED_EVTYPE);
5620 wxPostEvent(
this, ev);
5627 CheckToolbarPosition();
5631 if (ProcessQuitFlag())
return;
5633 if (bDBUpdateInProgress)
return;
5636 FrameTenHzTimer.Stop();
5638 ProcessDeferredTrackOn();
5640 ProcessAnchorWatch();
5641 ProcessLogAndBells();
5643 if (ShouldRestartTrack()) TrackDailyRestart();
5646 if (g_bSleep && !AnchorAlertOn1 && !AnchorAlertOn2) {
5647 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5648 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5654 if (
gSog > 3.0) g_bCruising =
true;
5660 wxString sogcog(
"SOG --- " + getUsrSpeedUnit() + +
" " +
5662 if (GetStatusBar()) SetStatusText(sogcog, STAT_FIELD_SOGCOG);
5668 bool bnew_view =
false;
5669 if (!g_btenhertz) bnew_view = DoChartUpdate();
5676 bool bactiveRouteUpdate =
RoutemanGui(*g_pRouteMan).UpdateProgress();
5679 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5682 cc->DrawBlinkObjects();
5685 if (bactiveRouteUpdate) {
5692 cc->SetOwnShipState(SHIP_NORMAL);
5694 if (cc->GetQuiltMode()) {
5695 double erf = cc->GetQuiltMaxErrorFactor();
5696 if (erf > 0.02) cc->SetOwnShipState(SHIP_LOWACCURACY);
5698 if (cc->m_singleChart) {
5699 if (cc->m_singleChart->GetChart_Error_Factor() > 0.02)
5700 cc->SetOwnShipState(SHIP_LOWACCURACY);
5704 if (!
bGPSValid) cc->SetOwnShipState(SHIP_INVALID);
5707 (bVelocityValid != m_last_bVelocityValid) ||
5708 (!isnan(
gHdt) && (
gHdt != m_last_hdt))) {
5709 if (!g_bopengl) cc->UpdateShips();
5717 m_last_bVelocityValid = bVelocityValid;
5722 bool brq_dynamic =
false;
5724 auto *pplugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
5725 for (
unsigned int i = 0; i < pplugin_array->GetCount(); i++) {
5727 if (pic->m_enabled && pic->m_init_state) {
5728 if (pic->
m_cap_flag & WANTS_DYNAMIC_OPENGL_OVERLAY_CALLBACK) {
5735 if (brq_dynamic) bnew_view =
true;
5739 if (AnchorAlertOn1 || AnchorAlertOn2) bnew_view =
true;
5742 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5747 if (cc->GetglCanvas()) {
5749 bool b_rotate = cc->GetUpMode() != NORTH_UP_MODE;
5752 if (cc->m_bFollow) {
5753 cc->DoCanvasUpdate();
5770 if ((!cc->m_bFollow) || (cc->GetUpMode() != NORTH_UP_MODE)) {
5784 if (g_pais_query_dialog_active && g_pais_query_dialog_active->IsShown())
5785 g_pais_query_dialog_active->UpdateText();
5788 if (g_pAISTargetList && (0 == (g_tick % (5))))
5789 g_pAISTargetList->UpdateAISTargetList();
5792 UpdateGPSCompassStatusBoxes();
5797 console->RefreshConsoleData();
5804 if (m_bdefer_resize) {
5805 if (0 == (g_tick % (5))) {
5806 printf(
"___RESIZE\n");
5807 SetSize(m_defer_size);
5809 m_bdefer_resize =
false;
5816 FrameTimer1.Start(TIMER_GFRAME_1 * 3, wxTIMER_CONTINUOUS);
5818 FrameTimer1.Start(TIMER_GFRAME_1, wxTIMER_CONTINUOUS);
5819 FrameTenHzTimer.Start(100, wxTIMER_CONTINUOUS);
5823double MyFrame::GetMag(
double a,
double lat,
double lon) {
5824 double Variance = std::isnan(
gVar) ? g_UserVar :
gVar;
5825 auto loader = PluginLoader::GetInstance();
5826 if (loader && loader->IsPlugInAvailable(
"WMM")) {
5833 wxDateTime now = wxDateTime::Now();
5834 SendJSON_WMM_Var_Request(lat, lon, now);
5835 if (fabs(gQueryVar) < 360.0)
5836 Variance = gQueryVar;
5838 return toMagnetic(a, Variance);
5841bool MyFrame::SendJSON_WMM_Var_Request(
double lat,
double lon,
5847 v[
"Year"] = date.GetYear();
5848 v[
"Month"] = date.GetMonth();
5849 v[
"Day"] = date.GetDay();
5851 SendJSONMessageToAllPlugins(
"WMM_VARIATION_REQUEST", v);
5857void MyFrame::TouchAISActive() {
5859 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5861 if (cc) cc->TouchAISToolActive();
5865void MyFrame::UpdateAISTool() {
5869 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5871 if (cc) cc->UpdateAISTBTool();
5876void MyFrame::OnFrameTCTimer(wxTimerEvent &event) {
5878 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5880 if (cc) cc->SetbTCUpdate(
true);
5883 RefreshAllCanvas(
false);
5888void MyFrame::OnFrameCOGTimer(wxTimerEvent &event) {
5892 bool b_rotate =
false;
5893 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5895 if (cc) b_rotate |= (cc->GetUpMode() != NORTH_UP_MODE);
5899 FrameCOGTimer.Stop();
5906 int period_ms = 100;
5908 FrameCOGTimer.Start(period_ms, wxTIMER_CONTINUOUS);
5911void MyFrame::DoCOGSet() {
5913 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5915 if (cc) cc->DoCanvasCOGSet();
5919void RenderShadowText(wxDC *pdc, wxFont *pFont, wxString &str,
int x,
int y) {
5925 wxFont oldfont = pdc->GetFont();
5927 pdc->SetFont(*pFont);
5928 pdc->SetTextForeground(GetGlobalColor(
"CHGRF"));
5929 pdc->SetBackgroundMode(wxTRANSPARENT);
5931 pdc->DrawText(str, x, y + 1);
5932 pdc->DrawText(str, x, y - 1);
5933 pdc->DrawText(str, x + 1, y);
5934 pdc->DrawText(str, x - 1, y);
5936 pdc->SetTextForeground(GetGlobalColor(
"CHBLK"));
5938 pdc->DrawText(str, x, y);
5940 pdc->SetFont(oldfont);
5944void MyFrame::UpdateRotationState(
double rotation) {
5946 g_bCourseUp =
false;
5948 if (fabs(rotation) > .001) {
5949 SetMenubarItemState(ID_MENU_CHART_COGUP,
false);
5950 SetMenubarItemState(ID_MENU_CHART_NORTHUP,
true);
5952 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"Rotated Mode"));
5955 SetMenubarItemState(ID_MENU_CHART_COGUP, g_bCourseUp);
5956 SetMenubarItemState(ID_MENU_CHART_NORTHUP, !g_bCourseUp);
5958 m_pMenuBar->SetLabel(ID_MENU_CHART_NORTHUP, _(
"North Up Mode"));
5962 UpdateGPSCompassStatusBoxes(
true);
5966void MyFrame::UpdateGPSCompassStatusBoxes(
bool b_force_new) {
5968 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
5970 if (cc) cc->UpdateGPSCompassStatusBox(b_force_new);
5976int MyFrame::GetApplicationMemoryUse() {
5982 wxWindow *fWin = wxWindow::FindFocus();
5984 wxArrayString outputArray;
5985 wxString cmd(
"ps --no-headers -o vsize ");
5986 unsigned long pid = wxGetProcessId();
5988 cmd1.Printf(
"%ld", pid);
5990 wxExecute(cmd, outputArray);
5992 if (outputArray.GetCount()) {
5993 wxString s = outputArray.Item(0);
5995 if (s.ToLong(&vtmp)) memsize = vtmp;
5998 if (fWin) fWin->SetFocus();
6004 PROCESS_MEMORY_COUNTERS pmc;
6006 unsigned long processID = wxGetProcessId();
6008 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
6010 if (NULL == hProcess)
return 0;
6012 if (GetProcessMemoryInfo(hProcess, &pmc,
sizeof(pmc))) {
6030 memsize = pmc.WorkingSetSize / 1024;
6033 CloseHandle(hProcess);
6040double MyFrame::GetBestVPScale(
ChartBase *pchart) {
6041 return GetPrimaryCanvas()->GetBestVPScale(pchart);
6044void MyFrame::SetChartUpdatePeriod() {
6047 g_ChartUpdatePeriod = 0;
6052 bool bskewdc =
false;
6053 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6056 if (!g_bopengl && !cc->GetVP().b_quilt) {
6057 if (fabs(cc->GetVP().
skew) > 0.0001) bskewdc =
true;
6059 if (cc->m_bFollow) g_ChartUpdatePeriod = 1;
6063 if (bskewdc) g_ChartUpdatePeriod = g_SkewCompUpdatePeriod;
6065 m_ChartUpdatePeriod = g_ChartUpdatePeriod;
6070 cc->UpdateCanvasControlBar();
6073void MyFrame::selectChartDisplay(
int type,
int family) {
6075 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6077 if (cc) cc->selectCanvasChartDisplay(type, family);
6080 UpdateGlobalMenuItems();
6089bool MyFrame::DoChartUpdate() {
6090 bool return_val =
false;
6093 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6095 if (cc) return_val |= cc->DoCanvasUpdate();
6101void MyFrame::MouseEvent(wxMouseEvent &event) {
6103 event.GetPosition(&x, &y);
6108#include <mach/mach.h>
6109#include <mach/message.h>
6110#include <mach/kern_return.h>
6111#include <mach/task_info.h>
6113#include <malloc/malloc.h>
6120#if defined(__linux__)
6121#include "sys/types.h"
6122#include "sys/sysinfo.h"
6125void MyFrame::DoPrint(
void) {
6127 g_PrintingInProgress =
true;
6130 GetPrimaryCanvas()->GetglCanvas()->Render();
6131 GetPrimaryCanvas()->GetglCanvas()->SwapBuffers();
6141 printer.Initialize(wxLANDSCAPE);
6142 printer.EnablePageNumbers(
false);
6143 printer.Print(
this, &printout);
6161 g_PrintingInProgress =
false;
6164 GetPrimaryCanvas()->SetFocus();
6170 wxString message_ID =
event.GetID();
6171 wxString message_JSONText =
event.GetJSONText();
6179 if (message_ID ==
"WMM_VARIATION_BOAT") {
6187 int numErrors = reader.
Parse(message_JSONText, &root);
6188 if (numErrors > 0) {
6194 wxString decl = root[
"Decl"].
AsString();
6196 decl.ToDouble(&decl_val);
6202 if (message_ID ==
"WMM_VARIATION") {
6210 int numErrors = reader.
Parse(message_JSONText, &root);
6211 if (numErrors > 0) {
6217 wxString decl = root[
"Decl"].
AsString();
6219 decl.ToDouble(&decl_val);
6221 gQueryVar = decl_val;
6224 if (message_ID ==
"GRIB_TIMELINE") {
6227 int numErrors = r.
Parse(message_JSONText, &v);
6229 if (numErrors > 0) {
6230 wxLogMessage(
"GRIB_TIMELINE: JSON parse error");
6235 wxDateTime oldTimeSource = gTimeSource;
6237 if (v[
"Day"].AsInt() == -1) {
6238 gTimeSource = wxInvalidDateTime;
6239 wxLogMessage(
"GRIB_TIMELINE: Reset to system time");
6241 gTimeSource.Set(v[
"Day"].AsInt(), (wxDateTime::Month)v[
"Month"].AsInt(),
6242 v[
"Year"].AsInt(), v[
"Hour"].AsInt(), v[
"Minute"].AsInt(),
6243 v[
"Second"].AsInt());
6247 if (oldTimeSource != gTimeSource) {
6249 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6251 if (cc && (cc->GetbShowTide() || cc->GetbShowCurrent())) {
6256 cc->pCwin->Refresh(
false);
6262 if (message_ID ==
"OCPN_TRACK_REQUEST") {
6265 wxString trk_id = wxEmptyString;
6267 int numErrors = reader.
Parse(message_JSONText, &root);
6268 if (numErrors > 0)
return;
6273 v[
"Track_ID"] = trk_id;
6275 wxString name = wxEmptyString;
6276 if (ptrack->m_GUID == trk_id) {
6277 name = ptrack->GetName();
6278 if (name.IsEmpty()) {
6284 name = _(
"(Unnamed Track)");
6291 v[
"TotalNodes"] = ptrack->GetnPoints();
6292 for (
int j = 0; j < ptrack->GetnPoints(); j++) {
6294 v[
"lat"] = tp->m_lat;
6295 v[
"lon"] = tp->m_lon;
6298 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6299 SendJSONMessageToAllPlugins(msg_id, v);
6305 wxString msg_id(
"OCPN_TRACKPOINTS_COORDS");
6306 SendJSONMessageToAllPlugins(msg_id, v);
6308 }
else if (message_ID ==
"OCPN_ROUTE_REQUEST") {
6311 wxString guid = wxEmptyString;
6313 int numErrors = reader.
Parse(message_JSONText, &root);
6314 if (numErrors > 0) {
6323 wxString name = wxEmptyString;
6325 if ((*it)->m_GUID == guid) {
6326 name = (*it)->m_RouteNameString;
6327 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6333 for (RoutePointList::iterator itp = (*it)->pRoutePointList->begin();
6334 itp != (*it)->pRoutePointList->end(); itp++) {
6335 w[i][
"lat"] = (*itp)->m_lat;
6336 w[i][
"lon"] = (*itp)->m_lon;
6337 w[i][
"Name"] = (*itp)->GetName();
6338 w[i][
"Description"] = (*itp)->GetDescription();
6339 w[i][
"GUID"] = (*itp)->m_GUID;
6340 w[i][
"ArrivalRadius"] = (*itp)->GetWaypointArrivalRadius();
6342 auto node = (*itp)->m_HyperlinkList->begin();
6343 if (node != (*itp)->m_HyperlinkList->end()) {
6345 while (node != (*itp)->m_HyperlinkList->end()) {
6347 v[i][
"WPLink" + wxString::Format(
"%d", n)] = httpLink->Link;
6348 v[i][
"WPLinkDesciption" + wxString::Format(
"%d", n++)] =
6349 httpLink->DescrText;
6356 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6357 SendJSONMessageToAllPlugins(msg_id, v);
6364 wxString msg_id(
"OCPN_ROUTE_RESPONSE");
6365 SendJSONMessageToAllPlugins(msg_id, v);
6366 }
else if (message_ID ==
"OCPN_ROUTELIST_REQUEST") {
6371 int numErrors = reader.
Parse(message_JSONText, &root);
6372 if (numErrors > 0)
return;
6375 wxString str = root[
"mode"].
AsString();
6376 if (str ==
"Track") route =
false;
6381 for (RouteList::iterator it =
pRouteList->begin();
6383 wxString name = (*it)->m_RouteNameString;
6384 if (name.IsEmpty()) name = _(
"(Unnamed Route)");
6386 v[i][
"error"] =
false;
6387 v[i][
"name"] = name;
6388 v[i][
"GUID"] = (*it)->m_GUID;
6389 v[i][
"active"] = (*it)->IsActive();
6394 wxString name = ptrack->GetName();
6395 if (name.IsEmpty()) {
6401 name = _(
"(Unnamed Track)");
6403 v[i][
"error"] =
false;
6404 v[i][
"name"] = name;
6405 v[i][
"GUID"] = ptrack->m_GUID;
6410 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6411 SendJSONMessageToAllPlugins(msg_id, v);
6414 v[0][
"error"] =
true;
6415 wxString msg_id(
"OCPN_ROUTELIST_RESPONSE");
6416 SendJSONMessageToAllPlugins(msg_id, v);
6418 }
else if (message_ID ==
"OCPN_ACTIVE_ROUTELEG_REQUEST") {
6420 v[0][
"error"] =
true;
6423 v[0][
"error"] =
false;
6424 v[0][
"range"] =
g_pRouteMan->GetCurrentRngToActivePoint();
6425 v[0][
"bearing"] =
g_pRouteMan->GetCurrentBrgToActivePoint();
6426 v[0][
"XTE"] =
g_pRouteMan->GetCurrentXTEToActivePoint();
6427 v[0][
"active_route_GUID"] =
g_pRouteMan->GetpActiveRoute()->GetGUID();
6428 v[0][
"active_waypoint_lat"] =
6430 v[0][
"active_waypoint_lon"] =
6434 wxString msg_id(
"OCPN_ACTIVE_ROUTELEG_RESPONSE");
6435 SendJSONMessageToAllPlugins(msg_id, v);
6439void MyFrame::FilterCogSog() {
6440 if (g_bfilter_cogsog && !g_own_ship_sog_cog_calc) {
6442 double cog_last =
gCog;
6445 for (
int i = g_COGFilterSec - 1; i > 0; i--)
6446 COGFilterTable[i] = COGFilterTable[i - 1];
6447 COGFilterTable[0] = cog_last;
6450 if (!std::isnan(cog_last)) {
6452 double sum = 0., count = 0;
6453 for (
int i = 0; i < g_COGFilterSec; i++) {
6454 double adder = COGFilterTable[i];
6455 if (std::isnan(adder))
continue;
6457 if (fabs(adder - cog_last) > 180.) {
6458 if ((adder - cog_last) > 0.)
6471 else if (sum >= 360.)
6478 double sog_last =
gSog;
6481 for (
int i = g_SOGFilterSec - 1; i > 0; i--)
6482 SOGFilterTable[i] = SOGFilterTable[i - 1];
6483 SOGFilterTable[0] = sog_last;
6486 if (!std::isnan(
gSog)) {
6487 double sum = 0., count = 0;
6488 for (
int i = 0; i < g_SOGFilterSec; i++) {
6489 if (std::isnan(SOGFilterTable[i]))
continue;
6491 sum += SOGFilterTable[i];
6501void MyFrame::LoadHarmonics() {
6504 ptcmgr->LoadDataSources(TideCurrentDataSet);
6506 bool b_newdataset =
false;
6509 for (
auto a :
ptcmgr->GetDataSet()) {
6510 bool b_foundi =
false;
6511 for (
auto b : TideCurrentDataSet) {
6518 b_newdataset =
true;
6523 for (
auto a : TideCurrentDataSet) {
6524 bool b_foundi =
false;
6525 for (
auto b :
ptcmgr->GetDataSet()) {
6532 b_newdataset =
true;
6537 if (b_newdataset)
ptcmgr->LoadDataSources(TideCurrentDataSet);
6541void MyFrame::ActivateAISMOBRoute(
const AisTargetData *ptarget) {
6542 if (!ptarget)
return;
6545 wxDateTime mob_time = wxDateTime::Now();
6546 wxString mob_label(_(
"AIS MAN OVERBOARD"));
6547 mob_label += _(
" on ");
6548 mob_label += ocpn::toUsrDateTimeFormat(mob_time);
6551 mob_label, wxEmptyString);
6552 pWP_MOB->SetShared(
true);
6554 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, pWP_MOB);
6556 NavObj_dB::GetInstance().InsertRoutePoint(pWP_MOB);
6558 pWP_MOB->SetUseSca(
false);
6566 wxString(_(
"Own ship")), wxEmptyString);
6568 pWP_MOB->SetUseSca(
false);
6575 pSelect->AddSelectableRouteSegment(ptarget->Lat, ptarget->Lon,
gLat,
gLon,
6591 wxString msg_id(
"OCPN_MAN_OVERBOARD");
6592 SendJSONMessageToAllPlugins(msg_id, v);
6595 if (RouteManagerDialog::getInstanceFlag()) {
6596 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
6597 pRouteManagerDialog->UpdateRouteListCtrl();
6598 pRouteManagerDialog->UpdateWptListCtrl();
6602 RefreshAllCanvas(
false);
6604 wxString mob_message(_(
"AIS MAN OVERBOARD"));
6605 mob_message += _(
" Time: ");
6606 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6607 mob_message += _(
" Ownship Position: ");
6608 mob_message += toSDMM(1,
gLat);
6610 mob_message += toSDMM(2,
gLon);
6611 mob_message += _(
" MOB Position: ");
6612 mob_message += toSDMM(1, ptarget->Lat);
6614 mob_message += toSDMM(2, ptarget->Lon);
6615 wxLogMessage(mob_message);
6618void MyFrame::UpdateAISMOBRoute(
const AisTargetData *ptarget) {
6622 OwnPoint->m_lat =
gLat;
6623 OwnPoint->m_lon =
gLon;
6625 pSelect->DeleteSelectableRoutePoint(OwnPoint);
6630 MOB_Point->m_lat = ptarget->Lat;
6631 MOB_Point->m_lon = ptarget->Lon;
6633 pSelect->DeleteSelectableRoutePoint(MOB_Point);
6634 pSelect->AddSelectableRoutePoint(ptarget->Lat, ptarget->Lon, MOB_Point);
6636 pSelect->UpdateSelectableRouteSegments(OwnPoint);
6637 pSelect->UpdateSelectableRouteSegments(MOB_Point);
6640 RefreshAllCanvas(
false);
6643 wxDateTime mob_time = wxDateTime::Now();
6645 wxString mob_message(_(
"AIS MAN OVERBOARD UPDATE"));
6646 mob_message += _(
" Time: ");
6647 mob_message += ocpn::toUsrDateTimeFormat(mob_time);
6648 mob_message += _(
" Ownship Position: ");
6649 mob_message += toSDMM(1,
gLat);
6651 mob_message += toSDMM(2,
gLon);
6652 mob_message += _(
" MOB Position: ");
6653 mob_message += toSDMM(1, ptarget->Lat);
6655 mob_message += toSDMM(2, ptarget->Lon);
6657 wxLogMessage(mob_message);
6661void MyFrame::applySettingsString(wxString settings) {
6663 int last_UIScaleFactor = g_GUIScaleFactor;
6664 bool previous_expert = g_bUIexpert;
6665 g_last_ChartScaleFactor = g_ChartScaleFactor;
6666 ArrayOfCDI *pNewDirArray =
new ArrayOfCDI;
6669 g_Platform->platformApplyPrivateSettingsString(settings, pNewDirArray);
6672 pConfig->UpdateSettings();
6675 if (g_last_ChartScaleFactor != g_ChartScaleFactor) rr |= S52_CHANGED;
6677 if (rr & S52_CHANGED) {
6679 ps52plib->FlushSymbolCaches(ChartCtxFactory());
6681 ->ClearCNSYLUPArray();
6682 ps52plib->GenerateStateHash();
6686 ProcessOptionsDialog(rr, pNewDirArray);
6691 bool b_newToolbar =
false;
6693 if (g_GUIScaleFactor != last_UIScaleFactor) b_newToolbar =
true;
6695 if (previous_expert != g_bUIexpert) b_newToolbar =
true;
6697 if (rr & TOOLBAR_CHANGED) {
6698 b_newToolbar =
true;
6703 if (previous_expert && !g_bUIexpert) {
6704 androidForceFullRepaint();
6708 if (previous_expert != g_bUIexpert) g_Platform->applyExpertMode(g_bUIexpert);
6712 SetGPSCompassScale();
6714 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
6716 if (cc) cc->GetCompass()->SetScaleFactor(g_compass_scalefactor);
6718 UpdateGPSCompassStatusBoxes(
true);
6721 AbstractPlatform::ShowBusySpinner();
6723 SetAllToolbarScale();
6727 AbstractPlatform::HideBusySpinner();
6729 RequestNewMasterToolbar(
true);
6736 UpdateControlBar(GetPrimaryCanvas());
6742 if (m_data_monitor->
IsVisible()) m_data_monitor->Raise();
6745#ifdef wxHAS_POWER_EVENTS
6746void MyFrame::OnSuspending(wxPowerEvent &event) {
6750 wxLogMessage(
"System suspend starting...");
6753void MyFrame::OnSuspended(wxPowerEvent &WXUNUSED(event)) {
6756 wxLogMessage(
"System is going to suspend.");
6759void MyFrame::OnSuspendCancel(wxPowerEvent &WXUNUSED(event)) {
6762 wxLogMessage(
"System suspend was cancelled.");
6765int g_last_resume_ticks;
6766void MyFrame::OnResume(wxPowerEvent &WXUNUSED(event)) {
6767 wxDateTime now = wxDateTime::Now();
6768 wxLogMessage(
"System resumed from suspend.");
6770 if ((now.GetTicks() - g_last_resume_ticks) > 5) {
6773 wxLogMessage(
"Restarting streams.");
6774 g_last_resume_ticks = now.GetTicks();
6778 g_pMUX->ClearStreams();
6780 g_pMUX->StartAllStreams();
6789 if (IsMaximized()) {
6794 wxSize sz = GetSize();
6795 SetSize(wxSize(sz.x - 1, sz.y));
6807void MyFrame::RequestNewMasterToolbar(
bool bforcenew) {
6808 bool btbRebuild =
false;
6810 bool b_reshow =
true;
6813 float ff = fabs(
g_MainToolbar->GetScaleFactor() - g_toolbar_scalefactor);
6814 if ((ff > 0.01f) || bforcenew) {
6824 long orient = g_Platform->GetDefaultToolbarOrientation();
6825 wxWindow *toolbarParent =
this;
6827 toolbarParent = GetPrimaryCanvas();
6830 toolbarParent, wxPoint(-1, -1), orient, g_toolbar_scalefactor);
6832 g_MainToolbar->SetToolbarHideMethod(TOOLBAR_HIDE_TO_FIRST_TOOL);
6839 g_bmasterToolbarFull =
true;
6843 CreateMasterToolbar();
6858bool MyFrame::CollapseGlobalToolbar() {
6860 m_nMasterToolCountShown = 1;
6864 g_bmasterToolbarFull =
false;
6880 ID_MASTERTOGGLE, style->GetToolIcon(
"MUI_menu", TOOLICON_NORMAL),
6881 wxITEM_NORMAL, _(
"Hide Toolbar"),
"MUI_menu");
6882 tic->m_bRequired =
true;
6887 ID_SETTINGS, style->GetToolIcon(
"MUI_settings", TOOLICON_NORMAL),
6888 wxITEM_NORMAL, _(
"Options"),
"MUI_settings");
6892 ID_MENU_ROUTE_NEW, style->GetToolIcon(
"MUI_route", TOOLICON_NORMAL),
6893 style->GetToolIcon(
"MUI_route", TOOLICON_TOGGLED), wxITEM_CHECK,
6894 wxString(_(
"Create Route")) <<
" (Ctrl-R)",
"MUI_route");
6899 ID_ROUTEMANAGER, style->GetToolIcon(
"MUI_RMD", TOOLICON_NORMAL),
6900 wxITEM_NORMAL, _(
"Route & Mark Manager"),
"MUI_RMD");
6904 ID_TRACK, style->GetToolIcon(
"MUI_track", TOOLICON_NORMAL),
6905 style->GetToolIcon(
"MUI_track", TOOLICON_TOGGLED), wxITEM_CHECK,
6906 _(
"Enable Tracking"),
"MUI_track");
6910 ID_COLSCHEME, style->GetToolIcon(
"MUI_colorscheme", TOOLICON_NORMAL),
6911 wxITEM_NORMAL, _(
"Change Color Scheme"),
"MUI_colorscheme");
6923 ID_PRINT, style->GetToolIcon(
"MUI_print", TOOLICON_NORMAL), wxITEM_NORMAL,
6924 _(
"Print Chart"),
"MUI_print");
6928 ID_ABOUT, style->GetToolIcon(
"MUI_help", TOOLICON_NORMAL), wxITEM_NORMAL,
6929 _(
"About OpenCPN"),
"MUI_help");
6933 AddDefaultPositionPlugInTools();
6937 ID_MOB, style->GetToolIcon(
"mob_btn", TOOLICON_NORMAL), wxITEM_NORMAL,
6938 wxString(_(
"Drop MOB Marker")) << _(
" (Ctrl-Space)"),
"mob_btn");
6949 ArrayOfPlugInToolbarTools tool_array =
6951 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6953 if (!pttc->b_viz)
continue;
6955 if (pttc->kind == wxITEM_CHECK) tb->ToggleTool(pttc->id, pttc->b_toggle);
6958 SetMasterToolbarItemState(ID_TRACK, g_bTrackActive);
6959 if (g_bTrackActive) {
6960 g_MainToolbar->SetToolShortHelp(ID_TRACK, _(
"Disable Tracking"));
6967bool MyFrame::CheckAndAddPlugInTool() {
6975 if (!tb)
return false;
6977 int n_tools = tb->GetToolsCount();
6981 ArrayOfPlugInToolbarTools tool_array =
6984 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
6986 if (pttc->position == n_tools) {
6987 wxBitmap *ptool_bmp;
6989 switch (global_color_scheme) {
6990 case GLOBAL_COLOR_SCHEME_DAY:
6991 ptool_bmp = pttc->bitmap_day;
6994 case GLOBAL_COLOR_SCHEME_DUSK:
6995 ptool_bmp = pttc->bitmap_dusk;
6997 case GLOBAL_COLOR_SCHEME_NIGHT:
6998 ptool_bmp = pttc->bitmap_night;
7001 ptool_bmp = pttc->bitmap_day;
7006 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7008 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7009 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7010 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7011 tic->m_bPlugin =
true;
7020 while (CheckAndAddPlugInTool()) {
7026bool MyFrame::AddDefaultPositionPlugInTools() {
7033 ArrayOfPlugInToolbarTools tool_array =
7036 for (
unsigned int i = 0; i < tool_array.GetCount(); i++) {
7040 if (!pttc->b_viz)
continue;
7042 if (pttc->position == -1)
7044 wxBitmap *ptool_bmp;
7046 switch (global_color_scheme) {
7047 case GLOBAL_COLOR_SCHEME_DAY:
7048 ptool_bmp = pttc->bitmap_day;
7050 case GLOBAL_COLOR_SCHEME_DUSK:
7051 ptool_bmp = pttc->bitmap_dusk;
7053 case GLOBAL_COLOR_SCHEME_NIGHT:
7054 ptool_bmp = pttc->bitmap_night;
7057 ptool_bmp = pttc->bitmap_day;
7062 pttc->id, *(ptool_bmp), pttc->kind, pttc->shortHelp,
"");
7064 tic->m_NormalIconSVG = pttc->pluginNormalIconSVG;
7065 tic->m_RolloverIconSVG = pttc->pluginRolloverIconSVG;
7066 tic->m_ToggledIconSVG = pttc->pluginToggledIconSVG;
7067 tic->m_bPlugin =
true;
7082wxColour GetGlobalColor(wxString colorName);
7084static const char *usercolors[] = {
7091 "GREEN1;120;255;120;",
"GREEN2; 45;150; 45;",
"GREEN3;200;220;200;",
7092 "GREEN4; 0;255; 0;",
"GREEN5;170;254; 0;",
"BLUE1; 170;170;255;",
7093 "BLUE2; 45; 45;170;",
"BLUE3; 0; 0;255;",
"GREY1; 200;200;200;",
7094 "GREY2; 230;230;230;",
"RED1; 220;200;200;",
"YELO1; 243;229; 47;",
7095 "YELO2; 128; 80; 0;",
"TEAL1; 0;128;128;",
7099 "UWHIT; 255;255;255;",
7102 "COMPT; 245;247;244",
7106 "DILG0; 255;255;255;",
7108 "DILG0; 238;239;242;",
7110 "DILG1; 212;208;200;",
7111 "DILG2; 255;255;255;",
7123 "CHGRF; 163; 180; 183;",
7125 "CHYLW; 244; 218; 72;",
7126 "CHWHT; 212; 234; 238;",
7129 "UINFM; 197; 69; 195;",
7131 "UINFG; 104; 228; 86;",
7133 "UINFR; 241; 84; 105;",
7134 "UINFF; 125; 137; 140;",
7138 "UDKRD; 124; 16; 0;",
7140 "UARTE; 200; 0; 0;",
7143 "NODTA; 163; 180; 183;",
7145 "SNDG1; 125; 137; 140;",
7147 "SCLBR; 235; 125; 54;",
7150 "UIBDR; 125; 137; 140;",
7151 "UIBCK; 212; 234; 238;",
7152 "UINFB; 58; 120; 240;",
7155 "UINFO; 235; 125; 54;",
7158 "PLRTE; 220; 64; 37;",
7159 "CHMGD; 197; 69; 195;",
7163 "DASHB; 255;255;255;",
7164 "DASHL; 175;175;175;",
7165 "DASHF; 50; 50; 50;",
7166 "DASHR; 200; 0; 0;",
7168 "DASHN; 200;120; 0;",
7169 "DASH1; 204;204;255;",
7170 "DASH2; 122;131;172;",
7171 "COMP1; 211;211;211;",
7174 "GREY3; 40; 40; 40;",
7175 "BLUE4; 100;100;200;",
7176 "VIO01; 171; 33;141;",
7177 "VIO02; 209;115;213;",
7178 "BLUEBACK; 212;234;238;",
7179 "LANDBACK; 201;185;122;",
7185 "Table:DUSK",
"GREEN1; 60;128; 60;",
"GREEN2; 22; 75; 22;",
7186 "GREEN3; 80;100; 80;",
"GREEN4; 0;128; 0;",
"BLUE1; 80; 80;160;",
7187 "BLUE2; 30; 30;120;",
"BLUE3; 0; 0;128;",
"GREY1; 100;100;100;",
7188 "GREY2; 128;128;128;",
"RED1; 150;100;100;",
"UBLCK; 0; 0; 0;",
7189 "UWHIT; 255;255;255;",
"URED; 120; 54; 11;",
"UGREN; 35;110; 20;",
7190 "YELO1; 120;115; 24;",
"YELO2; 64; 40; 0;",
"TEAL1; 0; 64; 64;",
7191 "GREEN5; 85;128; 0;",
"COMPT; 124;126;121",
7193 "CHGRF; 41; 46; 46;",
"UINFM; 58; 20; 57;",
"UINFG; 35; 76; 29;",
7194 "UINFF; 41; 46; 46;",
"UINFR; 80; 28; 35;",
"SHIPS; 71; 78; 79;",
7195 "CHYLW; 81; 73; 24;",
"CHWHT; 71; 78; 79;",
7197 "DILG0; 110;110;110;",
7198 "DILG1; 110;110;110;",
7200 "DILG3; 130;130;130;",
7202 "UITX1; 41; 46; 46;",
7205 "UARTE; 64; 64; 64;",
7207 "NODTA; 41; 46; 46;",
"CHBLK; 54; 60; 61;",
"SNDG1; 41; 46; 46;",
7208 "SNDG2; 71; 78; 79;",
"SCLBR; 75; 38; 19;",
"UIBDR; 54; 60; 61;",
7209 "UINFB; 19; 40; 80;",
"UINFD; 71; 78; 79;",
"UINFO; 75; 38; 19;",
7210 "PLRTE; 73; 21; 12;",
"CHMGD; 74; 58; 81;",
"UIBCK; 7; 7; 7;",
7212 "DASHB; 77; 77; 77;",
7213 "DASHL; 54; 54; 54;",
7215 "DASHR; 58; 21; 21;",
7216 "DASHG; 21; 58; 21;",
7217 "DASHN; 100; 50; 0;",
7218 "DASH1; 76; 76;113;",
7219 "DASH2; 48; 52; 72;",
7220 "COMP1; 107;107;107;",
7222 "GREY3; 20; 20; 20;",
7223 "BLUE4; 80; 80;160;",
7224 "VIO01; 128; 25;108;",
"VIO02; 171; 33;141;",
"BLUEBACK; 186;213;235;",
7225 "LANDBACK; 201;185;122;",
7231 "Table:NIGHT",
"GREEN1; 30; 80; 30;",
"GREEN2; 15; 60; 15;",
7232 "GREEN3; 12; 23; 9;",
"GREEN4; 0; 64; 0;",
"BLUE1; 60; 60;100;",
7233 "BLUE2; 22; 22; 85;",
"BLUE3; 0; 0; 40;",
"GREY1; 48; 48; 48;",
7234 "GREY2; 32; 32; 32;",
"RED1; 100; 50; 50;",
"UWHIT; 255;255;255;",
7235 "UBLCK; 0; 0; 0;",
"URED; 60; 27; 5;",
"UGREN; 17; 55; 10;",
7236 "YELO1; 60; 65; 12;",
"YELO2; 32; 20; 0;",
"TEAL1; 0; 32; 32;",
7237 "GREEN5; 44; 64; 0;",
"COMPT; 48; 49; 51",
7238 "DILG0; 80; 80; 80;",
7239 "DILG1; 80; 80; 80;",
7241 "DILG3; 65; 65; 65;",
7242 "DILG4; 220;220;220;",
7243 "UITX1; 31; 34; 35;",
7246 "UARTE; 64; 64; 64;",
7248 "CHGRF; 16; 18; 18;",
"UINFM; 52; 18; 52;",
"UINFG; 22; 24; 7;",
7249 "UINFF; 31; 34; 35;",
"UINFR; 59; 17; 10;",
"SHIPS; 37; 41; 41;",
7250 "CHYLW; 31; 33; 10;",
"CHWHT; 37; 41; 41;",
7252 "NODTA; 7; 7; 7;",
"CHBLK; 31; 34; 35;",
"SNDG1; 31; 34; 35;",
7253 "SNDG2; 43; 48; 48;",
"SCLBR; 52; 28; 12;",
"UIBDR; 31; 34; 35;",
7254 "UINFB; 21; 29; 69;",
"UINFD; 43; 48; 58;",
"UINFO; 52; 28; 12;",
7255 "PLRTE; 66; 19; 11;",
"CHMGD; 52; 18; 52;",
"UIBCK; 7; 7; 7;",
7258 "DASHL; 20; 20; 20;",
7259 "DASHF; 64; 64; 64;",
7260 "DASHR; 70; 15; 15;",
7261 "DASHG; 15; 70; 15;",
7262 "DASHN; 17; 80; 56;",
7263 "DASH1; 48; 52; 72;",
7264 "DASH2; 36; 36; 53;",
7265 "COMP1; 24; 24; 24;",
7267 "GREY3; 10; 10; 10;",
7268 "BLUE4; 70; 70;140;",
7269 "VIO01; 85; 16; 72;",
"VIO02; 128; 25;108;",
"BLUEBACK; 186;213;235;",
7270 "LANDBACK; 201;185;122;",
7274int get_static_line(
char *d,
const char **p,
int index,
int n) {
7275 if (!strcmp(p[index],
"*****"))
return 0;
7277 strncpy(d, p[index], n);
7281void InitializeUserColors() {
7282 const char **p = usercolors;
7290 UserColorTableArray =
new wxArrayPtrVoid;
7291 UserColourHashTableArray =
new wxArrayPtrVoid;
7295 ct->tableName =
new wxString(
"DAY");
7296 ct->color =
new wxArrayPtrVoid;
7297 UserColorTableArray->Add((
void *)ct);
7300 ct->tableName =
new wxString(
"DUSK");
7301 ct->color =
new wxArrayPtrVoid;
7302 UserColorTableArray->Add((
void *)ct);
7305 ct->tableName =
new wxString(
"NIGHT");
7306 ct->color =
new wxArrayPtrVoid;
7307 UserColorTableArray->Add((
void *)ct);
7309 while ((get_static_line(buf, p, index,
sizeof(buf) - 1))) {
7310 if (!strncmp(buf,
"Table", 5)) {
7311 sscanf(buf,
"Table:%s", TableName);
7313 for (
unsigned int it = 0; it < UserColorTableArray->GetCount(); it++) {
7314 ctp = (colTable *)(UserColorTableArray->Item(it));
7315 if (!strcmp(TableName, ctp->tableName->mb_str())) {
7324 while (buf[j] !=
';' && j < 20) {
7330 S52color *c =
new S52color;
7331 strcpy(c->colName, name);
7333 sscanf(&buf[j],
";%i;%i;%i", &R, &G, &B);
7346 for (
unsigned int its = 0; its < UserColorTableArray->GetCount(); its++) {
7347 wxColorHashMap *phash =
new wxColorHashMap;
7348 UserColourHashTableArray->Add((
void *)phash);
7350 colTable *ctp = (colTable *)(UserColorTableArray->Item(its));
7352 for (
unsigned int ic = 0; ic < ctp->color->GetCount(); ic++) {
7353 S52color *c2 = (S52color *)(ctp->color->Item(ic));
7355 wxColour c(c2->R, c2->G, c2->B);
7356 wxString key(c2->colName, wxConvUTF8);
7364 (wxColorHashMap *)UserColourHashTableArray->Item(0);
7367void DeInitializeUserColors() {
7368 if (!UserColorTableArray)
return;
7369 for (
unsigned i = 0; i < UserColorTableArray->GetCount(); i++) {
7370 colTable *ct = (colTable *)UserColorTableArray->Item(i);
7372 for (
unsigned int j = 0; j < ct->color->GetCount(); j++) {
7373 S52color *c = (S52color *)ct->color->Item(j);
7377 delete ct->tableName;
7383 delete UserColorTableArray;
7385 for (
unsigned i = 0; i < UserColourHashTableArray->GetCount(); i++) {
7386 wxColorHashMap *phash = (wxColorHashMap *)UserColourHashTableArray->Item(i);
7390 delete UserColourHashTableArray;
7397typedef struct _MSW_COLOR_SPEC {
7399 wxString S52_RGB_COLOR;
7403MSW_COLOR_SPEC color_spec[] = {{COLOR_MENU,
"UIBCK", 0},
7404 {COLOR_MENUTEXT,
"UITX1", 0},
7405 {COLOR_BTNSHADOW,
"UIBCK", 0},
7408void SaveSystemColors() {
7422 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7423 while (pcspec->COLOR_NAME != -1) {
7424 pcspec->SysRGB_COLOR = pGetSysColor(pcspec->COLOR_NAME);
7429void RestoreSystemColors() {
7430 int element[NCOLORS];
7431 int rgbcolor[NCOLORS];
7434 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7435 while (pcspec->COLOR_NAME != -1) {
7436 element[i] = pcspec->COLOR_NAME;
7437 rgbcolor[i] = pcspec->SysRGB_COLOR;
7442 if (pSetSysColors) {
7443 pSetSysColors(i, (
unsigned long *)&element[0],
7444 (
unsigned long *)&rgbcolor[0]);
7450void SetSystemColors(ColorScheme cs) {
7452 int element[NCOLORS];
7453 int rgbcolor[NCOLORS];
7455 if ((GLOBAL_COLOR_SCHEME_DUSK == cs) || (GLOBAL_COLOR_SCHEME_NIGHT == cs)) {
7456 MSW_COLOR_SPEC *pcspec = &color_spec[0];
7457 while (pcspec->COLOR_NAME != -1) {
7458 wxColour color = GetGlobalColor(pcspec->S52_RGB_COLOR);
7459 rgbcolor[i] = (color.Red() << 16) + (color.Green() << 8) + color.Blue();
7460 element[i] = pcspec->COLOR_NAME;
7466 pSetSysColors(i, (
unsigned long *)&element[0],
7467 (
unsigned long *)&rgbcolor[0]);
7471 RestoreSystemColors();
7476wxColor GetDimColor(wxColor c) {
7477 if ((global_color_scheme == GLOBAL_COLOR_SCHEME_DAY) ||
7478 (global_color_scheme == GLOBAL_COLOR_SCHEME_RGB))
7482 if (global_color_scheme == GLOBAL_COLOR_SCHEME_DUSK) factor = 0.5;
7483 if (global_color_scheme == GLOBAL_COLOR_SCHEME_NIGHT) factor = 0.25;
7485 wxImage::RGBValue rgb(c.Red(), c.Green(), c.Blue());
7486 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
7487 hsv.value = hsv.value * factor;
7488 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
7490 return wxColor(nrgb.red, nrgb.green, nrgb.blue);
7496double AnchorDistFix(
double const d,
double const AnchorPointMinDist,
7497 double const AnchorPointMaxDist)
7500 if (d < AnchorPointMinDist)
7501 return AnchorPointMinDist;
7502 else if (d > AnchorPointMaxDist)
7503 return AnchorPointMaxDist;
7509 if (d > -AnchorPointMinDist)
7510 return -AnchorPointMinDist;
7511 else if (d < -AnchorPointMaxDist)
7512 return -AnchorPointMaxDist;
7519static const WORD MAX_CONSOLE_LINES =
7524void RedirectIOToConsole()
7529 wxIntPtr lStdHandle;
7531 CONSOLE_SCREEN_BUFFER_INFO coninfo;
7541 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
7542 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
7543 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
7547 lStdHandle = (wxIntPtr)GetStdHandle(STD_OUTPUT_HANDLE);
7548 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7549 fp = _fdopen(hConHandle,
"w");
7551 setvbuf(stdout, NULL, _IONBF, 0);
7555 lStdHandle = (wxIntPtr)GetStdHandle(STD_INPUT_HANDLE);
7556 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7557 fp = _fdopen(hConHandle,
"r");
7559 setvbuf(stdin, NULL, _IONBF, 0);
7563 lStdHandle = (wxIntPtr)GetStdHandle(STD_ERROR_HANDLE);
7564 hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
7565 fp = _fdopen(hConHandle,
"w");
7567 setvbuf(stderr, NULL, _IONBF, 0);
7579bool TestGLCanvas(wxString prog_dir) {
7581 wxString test_app = prog_dir;
7582 test_app +=
"ocpn_gltest1.exe";
7584 if (::wxFileExists(test_app)) {
7585 long proc_return = ::wxExecute(test_app, wxEXEC_SYNC);
7586 printf(
"OpenGL Test Process returned %0X\n", proc_return);
7587 if (proc_return == 0)
7588 printf(
"GLCanvas OK\n");
7590 printf(
"GLCanvas failed to start, disabling OpenGL.\n");
7592 return (proc_return == 0);
7602bool ReloadLocale() {
7607 (!g_Platform->ChangeLocale(g_locale, plocale_def_lang, &plocale_def_lang)
7614 FontMgr::Get().SetLocale(g_locale);
7628 if (pRouteManagerDialog) {
7629 pRouteManagerDialog->Hide();
7630 pRouteManagerDialog->Destroy();
7631 pRouteManagerDialog = NULL;
7635 if (g_pais_query_dialog_active) {
7636 g_pais_query_dialog_active->Destroy();
7637 g_pais_query_dialog_active = NULL;
7640 auto alert_dlg_active =
7642 if (alert_dlg_active) {
7643 alert_dlg_active->Destroy();
7644 g_pais_alert_dialog_active =
nullptr;
7647 if (g_pAISTargetList) {
7649 g_pAISTargetList->Disconnect_decoder();
7650 g_pAISTargetList->Destroy();
7651 g_pAISTargetList = NULL;
7655 if (gFrame->m_pMenuBar) {
7656 gFrame->SetMenuBar(NULL);
7657 gFrame->m_pMenuBar->Destroy();
7658 gFrame->m_pMenuBar = NULL;
7660 gFrame->BuildMenuBar();
7663 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); i++) {
7665 if (cc) cc->CanvasApplyLocale();
7670 wxString perspective;
7671 pConfig->SetPath(
"/AUI");
7672 pConfig->Read(
"AUIPerspective", &perspective);
7686 bool bno_load =
false;
7687 wxAuiPaneInfoArray pane_array_val =
g_pauimgr->GetAllPanes();
7689 for (
unsigned int i = 0; i < pane_array_val.GetCount(); i++) {
7690 wxAuiPaneInfo pane = pane_array_val[i];
7691 if (perspective.Find(pane.name) == wxNOT_FOUND) {
7697 if (!bno_load)
g_pauimgr->LoadPerspective(perspective,
false);
7702 gFrame->RequestNewToolbars(
true);
7703 gFrame->RequestNewMasterToolbar(
true);
7720 g_csv_locn = g_Platform->GetSharedDataDir();
7721 g_csv_locn.Append(
"s57data");
7725 appendOSDirSlash(&g_csv_locn);
7726 g_csv_locn.Append(
"s57data");
7731 if (g_SENCPrefix.IsEmpty()) {
7733 appendOSDirSlash(&g_SENCPrefix);
7734 g_SENCPrefix.Append(
"SENC");
7738 wxFileName f(g_SENCPrefix);
7740 g_SENCPrefix = f.GetFullPath();
7742 g_SENCPrefix =
"SENC";
7748 bool b_force_legacy =
false;
7750 if (g_UserPresLibData.IsEmpty()) {
7751 plib_data = g_csv_locn;
7752 appendOSDirSlash(&plib_data);
7753 plib_data.Append(
"S52RAZDS.RLE");
7755 plib_data = g_UserPresLibData;
7756 b_force_legacy =
true;
7759 ps52plib =
new s52plib(plib_data, b_force_legacy);
7774 if (!ps52plib->m_bOK) {
7777 wxStandardPaths &std_path = g_Platform->GetStdPaths();
7779 wxString look_data_dir;
7780 look_data_dir.Append(std_path.GetUserDataDir());
7781 appendOSDirSlash(&look_data_dir);
7782 wxString tentative_SData_Locn = look_data_dir;
7783 look_data_dir.Append(
"s57data");
7785 plib_data = look_data_dir;
7786 appendOSDirSlash(&plib_data);
7787 plib_data.Append(
"S52RAZDS.RLE");
7789 wxLogMessage(
"Looking for s57data in " + look_data_dir);
7790 ps52plib =
new s52plib(plib_data);
7792 if (ps52plib->m_bOK) {
7793 g_csv_locn = look_data_dir;
7802 if (!ps52plib->m_bOK) {
7805 wxString look_data_dir;
7806 look_data_dir = g_Platform->GetSharedDataDir();
7807 look_data_dir.Append(
"s57data");
7809 plib_data = look_data_dir;
7810 appendOSDirSlash(&plib_data);
7811 plib_data.Append(
"S52RAZDS.RLE");
7813 wxLogMessage(
"Looking for s57data in " + look_data_dir);
7814 ps52plib =
new s52plib(plib_data);
7816 if (ps52plib->m_bOK) g_csv_locn = look_data_dir;
7819 if (ps52plib->m_bOK) {
7820 wxLogMessage(
"Using s57data in " + g_csv_locn);
7822 new s57RegistrarMgr(g_csv_locn, g_Platform->GetLogFilePtr());
7827 for (
unsigned int iPtr = 0; iPtr < ps52plib->pOBJLArray->GetCount();
7829 OBJLElement *pOLE = (OBJLElement *)(ps52plib->pOBJLArray->Item(iPtr));
7830 if (!strncmp(pOLE->OBJLName,
"DEPARE", 6)) pOLE->nViz = 1;
7831 if (!strncmp(pOLE->OBJLName,
"LNDARE", 6)) pOLE->nViz = 1;
7832 if (!strncmp(pOLE->OBJLName,
"COALNE", 6)) pOLE->nViz = 1;
7835 pConfig->LoadS57Config();
7836 ps52plib->SetPLIBColorScheme(global_color_scheme, ChartCtxFactory());
7842 ps52plib->SetDIPFactor(dip_factor);
7847 ps52plib->SetScaleFactorExp(
7848 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor));
7849 ps52plib->SetScaleFactorZoomMod(g_chart_zoom_modifier_vector);
7856 wxString renderer = wxString(GL_Caps->Renderer.c_str());
7857 ps52plib->SetGLRendererString(renderer);
7860 ps52plib->SetGLOptions(
7861 glChartCanvas::s_b_useStencil, glChartCanvas::s_b_useStencilAP,
7862 glChartCanvas::s_b_useScissorTest, glChartCanvas::s_b_useFBO,
7863 g_b_EnableVBO, g_texture_rectangle_format, 1, 1);
7868 wxLogMessage(
" S52PLIB Initialization failed, disabling Vector charts.");
7877 : wxThread(wxTHREAD_JOINABLE) {
7878 m_filename = filename;
7889 newChart->SetNativeScale(m_scale);
7890 newChart->SetFullExtent(m_ext);
7892 newChart->FindOrCreateSenc(m_filename);
7897 wxString m_filename;
7903static double chart_dist(
int index) {
7909 if (cte.GetBBox().Contains(
gLat,
gLon))
7914 clon = (cte.GetLonMax() + cte.GetLonMin()) / 2;
7915 d = DistGreatCircle(cte.GetLatMax(), clon,
gLat,
gLon);
7916 t = DistGreatCircle(cte.GetLatMin(), clon,
gLat,
gLon);
7919 clat = (cte.GetLatMax() + cte.GetLatMin()) / 2;
7920 t = DistGreatCircle(clat, cte.GetLonMin(),
gLat,
gLon);
7922 t = DistGreatCircle(clat, cte.GetLonMax(),
gLat,
gLon);
7928WX_DEFINE_SORTED_ARRAY_INT(
int, MySortedArrayInt);
7929static int CompareInts(
int n1,
int n2) {
7930 double d1 = chart_dist(n1);
7931 double d2 = chart_dist(n2);
7932 return (
int)(d1 - d2);
7937 wxString chart_path;
7942WX_DEFINE_OBJARRAY(ArrayOfCompressTargets);
7944#include <wx/arrimpl.cpp>
7947void ParseAllENC(wxWindow *parent) {
7948 MySortedArrayInt idx_sorted_by_distance(CompareInts);
7956 for (
int i = 0; i <
ChartData->GetChartTableEntries(); i++) {
7959 if (CHART_TYPE_S57 != cte.GetChartType())
continue;
7961 idx_sorted_by_distance.Add(i);
7965 if (count == 0)
return;
7967 wxLogMessage(wxString::Format(
"ParseAllENC() count = %d", count));
7973 ArrayOfCompressTargets ct_array;
7974 for (
unsigned int j = 0; j < idx_sorted_by_distance.GetCount(); j++) {
7975 int i = idx_sorted_by_distance[j];
7978 double distance = chart_dist(i);
7980 wxString filename(cte.GetpFullPath(), wxConvUTF8);
7983 pct->distance = distance;
7984 pct->chart_path = filename;
7986 ct_array.push_back(pct);
7989 int thread_count = 0;
7992 if (g_nCPUCount > 0)
7993 thread_count = g_nCPUCount;
7995 thread_count = wxThread::GetCPUCount();
7997 if (thread_count < 1) {
8006 for(
int t = 0; t < thread_count; t++)
8010 wxGenericProgressDialog *prog =
nullptr;
8014 long style = wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
8015 wxPD_REMAINING_TIME | wxPD_CAN_SKIP;
8017 prog =
new wxGenericProgressDialog();
8019 prog->SetFont(*qFont);
8021 prog->Create(_(
"OpenCPN ENC Prepare"),
"Longgggggggggggggggggggggggggggg",
8022 count + 1, parent, style);
8031 prog->ShowWindowModal();
8040 for (
unsigned int j = 0; j < ct_array.size(); j++) {
8041 wxString filename = ct_array[j].chart_path;
8042 double distance = ct_array[j].distance;
8043 int index =
ChartData->FinddbIndex(filename);
8044 if (index < 0)
continue;
8047 ext.NLAT = cte.GetLatMax();
8048 ext.SLAT = cte.GetLatMin();
8049 ext.WLON = cte.GetLonMin();
8050 ext.ELON = cte.GetLonMax();
8052 int scale = cte.GetScale();
8055 msg.Printf(_(
"Distance from Ownship: %4.0f NMi"), distance);
8058 if (wxThread::IsMain()) {
8060 wxSize sz = prog->GetSize();
8065 prog->Update(count, msg, &skip);
8077 newChart->SetNativeScale(
scale);
8078 newChart->SetFullExtent(ext);
8079 newChart->DisableBackgroundSENC();
8081 newChart->FindOrCreateSenc(filename,
8085 if (wxThread::IsMain()) {
8086 msg.Printf(_(
"ENC Completed."));
8088 prog->Update(count, msg, &skip);
8098 for (
int t = 0;; t = (t + 1) % thread_count) {
8105 if (!workers[t]->IsAlive()) {
8118#if defined(__WXMSW__) || defined(__WXOSX__)
8125 for(
int t = 0; t<thread_count; t++) {
AboutFrameImpl * g_pAboutDlg
Global instance.
About * g_pAboutDlgLegacy
Global instance.
AisDecoder * g_pAIS
Global instance.
Class AisDecoder and helpers.
Global state for AIS decoder.
Class AISTargetAlertDialog and helpers.
Class AISTargetListDialog.
Class AISTargetQueryDialog.
bool SendNoRouteRmbRmc(Routeman &routeman)
Send RMC + a faked RMB when there is no active route.
Autopilot output support.
Chart canvas configuration state
Class CanvasOptions and helpers – Canvas options Window/Dialog.
Wrapper for creating a ChartCtx based on global vars.
General chart base definitions.
ChartDB * ChartData
Global instance.
Charts database management
ChartGroupArray * g_pGroupArray
Global instance.
ChartCanvas * g_focusCanvas
Global instance.
Generic Chart canvas base.
Dialog for displaying AIS target alerts.
Dialog for querying detailed information about an AIS target.
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &caption=_("Object Query"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=AIS_TARGET_QUERY_STYLE)
Creation.
Extends AboutFrame, providing implementation for various event handlers and additional methods.
The OpenCPN About dialog displaying information including version, authors, license,...
Represents an active track that is currently being recorded.
Handles the AIS information GUI and sound alerts.
Base class for all chart types.
ChartCanvas - Main chart display and interaction component.
double m_cursor_lat
The latitude in degrees corresponding to the most recently processed cursor position.
double GetCanvasScaleFactor()
Return the number of logical pixels per meter for the screen.
void SetDisplaySizeMM(double size)
Set the width of the screen in millimeters.
float GetVPScale()
Return the ViewPort scale factor, in physical pixels per meter.
void ZoomCanvasSimple(double factor)
Perform an immediate zoom operation without smooth transitions.
bool SetVPScale(double sc, bool b_refresh=true)
Sets the viewport scale while maintaining the center point.
double m_cursor_lon
The longitude in degrees corresponding to the most recently processed cursor position.
void ZoomCanvas(double factor, bool can_zoom_to_cursor=true, bool stoptimer=true)
Perform a smooth zoom operation on the chart canvas by the specified factor.
bool SetViewPoint(double lat, double lon)
Centers the view on a specific lat/lon position.
Manages the chart database and provides access to chart data.
bool Create(ArrayOfCDI &dir_array, wxGenericProgressDialog *pprog)
Creates a new chart database from a list of directories.
bool Update(ArrayOfCDI &dir_array, bool bForce, wxGenericProgressDialog *pprog)
Updates the chart database.
Represents a user-defined collection of logically related charts.
void GenerateGLbmp()
In OpenGL mode, make the bitmap capture of the screen before the print method starts as to be sure th...
Overall logging handler, outputs to screen and log file.
bool IsVisible() const override
Return true if log is visible i.e., if it's any point using Add().
void Notify() override
Notify all listeners, no data supplied.
wxFont * FindOrCreateFont(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline=false, const wxString &facename=wxEmptyString, wxFontEncoding encoding=wxFONTENCODING_DEFAULT)
Creates or finds a matching font in the font cache.
void ScrubList()
Cleans up stale font entries after a locale change.
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Get a font object for a UI element.
EventVar color_scheme_change
Notified when the day/dusk/night color scheme changes.
static void ReleaseInstance()
Release Instance.
static LocalServerApi & GetInstance()
Handle logging and forwarding of incoming n0183/n2k messages.
void OnFrameTimer1(wxTimerEvent &event)
Main application timer handler called approximately once per second.
void InitApiListeners()
Setup handling of events from the local ipc/dbus API.
void OnFrameTenHzTimer(wxTimerEvent &event)
High-frequency timer handler running at 10Hz for smooth navigation updates.
virtual bool IsVisible() const =0
Return true if log is visible i.e., if it's any point using Add().
virtual void Add(const Logline &l)=0
Add a formatted string to log output.
void Init(const KeyProvider &kp, const std::function< void(ObservedEvt &ev)> &action)
Initiate an object yet not listening.
void Listen(const std::string &key, wxEvtHandler *listener, wxEventType evt)
Set object to send wxEventType ev to listener on changes in key.
Custom event class for OpenCPN's notification system.
std::shared_ptr< const void > GetSharedPtr() const
Gets the event's payload data.
Data for a loaded plugin, including dl-loaded library.
int m_cap_flag
PlugIn Capabilities descriptor.
bool LoadAllPlugIns(bool enabled_plugins, bool keep_orphans=false)
Update catalog with imported metadata and load all plugin library files.
bool UnLoadAllPlugIns()
Unload allplugins i.
bool UpdatePlugIns()
Update the GetPlugInArray() list by reloading all plugins from disk.
const ArrayOfPlugIns * GetPlugInArray()
Return list of currently loaded plugins.
bool DeactivateAllPlugIns()
Deactivate all plugins.
static PrintDialog & GetInstance()
Get instance to handle the print process,.
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.
EventVar on_routes_update
Notified when list of routes is updated (no data in event)
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
Manager for S57 chart SENC creation threads.
EventVar evt_resume
Notified when resuming from hibernate.
Represents a single point in a track.
wxDateTime GetCreateTime(void)
Retrieves the creation timestamp of a track point as a wxDateTime object.
Represents a track, which is a series of connected track points.
double view_scale_ppm
Requested view scale in physical pixels per meter (ppm), before applying projections.
double rotation
Rotation angle of the viewport in radians.
double skew
Angular distortion (shear transform) applied to the viewport in radians.
double clon
Center longitude of the viewport in degrees.
double clat
Center latitude of the viewport in degrees.
Encapsulates persistent canvas configuration.
double iLat
Latitude of the center of the chart, in degrees.
bool bShowOutlines
Display chart outlines.
wxSize canvasSize
Canvas dimensions.
bool bShowDepthUnits
Display depth unit indicators.
double iLon
Longitude of the center of the chart, in degrees.
double iRotation
Initial rotation angle in radians.
bool bCourseUp
Orient display to course up.
bool bQuilt
Enable chart quilting.
bool bFollow
Enable vessel following mode.
double iScale
Initial chart scale factor.
bool bShowGrid
Display coordinate grid.
ChartCanvas * canvas
Pointer to associated chart canvas.
bool bShowCurrents
Display current information.
bool bShowTides
Display tide information.
bool bLookahead
Enable lookahead mode.
bool bHeadUp
Orient display to heading up.
wxRect GetRect(void) const
Return the coordinates of the compass widget, in physical pixels relative to the canvas window.
virtual void OnToolbarToolCallback(int id)
Handles toolbar tool clicks.
Represents an S57 format electronic navigational chart in OpenCPN.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
bool HasMember(unsigned index) const
Return TRUE if the object contains an element at the specified index.
wxString AsString() const
Return the stored value as a wxWidget's string.
CM93OffsetDialog * g_pCM93OffsetDialog
Global instance.
Class cm93chart and helpers – CM93 chart state.
Global variables reflecting command line options and arguments.
wxColorHashMap * pcurrent_user_color_hash
Global instance.
Global color handling by name.
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.
Options | Connections GUI tab managing connections
Extern C linked utilities.
New NMEA Debugger successor main window.
std::vector< OCPN_MonitorInfo > g_monitor_info
Information about the monitors connected to the system.
OpenGL chart rendering canvas.
glTextureManager * g_glTextureManager
Global instance.
Hooks into gui available in model.
Misc GUI event vars, a singleton.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
General purpose GUI support.
size_t g_current_monitor
Current monitor displaying main application frame.
double vLat
Virtual lat from chcanv popup.
double vLon
Virtual lon from chcanv popup.
bool b_inCompressAllCharts
Flag to control adaptive UI scaling.
int g_NeedDBUpdate
0 - No update needed, 1 - Update needed because there is no chart database, inform user 2 - Start upd...
double g_current_monitor_dip_px_ratio
ratio to convert between DIP and physical pixels.
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
GUI constant definitions.
The local API has a server side handling commands and a client part issuing commands.
Enhanced logging interface on top of wx/log.h.
MarkInfoDlg * g_pMarkInfoDialog
global instance
Waypoint properties maintenance dialog.
MUI (Modern User Interface) Control bar.
Multiplexer class and helpers.
MySQL based storage for routes, tracks, etc.
Navigation Utility Functions without GUI dependencies.
User notifications manager.
s57RegistrarMgr * m_pRegistrarMan
Global instance.
OCPN_AUIManager * g_pauimgr
Global instance.
MyFrame * gFrame
Global instance.
PlugIn Object Definition/API.
wxWindow * GetOCPNCanvasWindow()
Gets OpenCPN's main canvas window.
double OCPN_GetDisplayContentScaleFactor()
Gets content scaling factor for current display.
void JumpToPosition(double lat, double lon, double scale)
Centers chart display on specified position at given scale.
wxWindow * GetCanvasUnderMouse()
Gets canvas window under mouse cursor.
void SendPluginMessage(wxString message_id, wxString message_body)
Sends message to other plugins.
options * g_options
Global instance.
bool bGPSValid
Indicate whether the Global Navigation Satellite System (GNSS) has a valid position.
double gHdm
Magnetic heading in degrees (0-359.99).
double gVar
Magnetic variation in degrees.
double gHdt
True heading in degrees (0-359.99).
double gLat
Vessel's current latitude in decimal degrees.
double gCog
Course over ground in degrees (0-359.99).
double gSog
Speed over ground in knots.
double gLon
Vessel's current longitude in decimal degrees.
Position, course, speed, etc.
Tools to send data to plugins.
Low level code to load plugins from disk, notably the PluginLoader class.
PlugInManager * g_pi_manager
Global instance.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
Generic, styled prit dialog.
Print chart canvas mix-in.
wxRect g_blink_rect
Global instance.
Purpose: Track and Trackpoint drawing stuff.
RoutePropDlgImpl * pRoutePropDialog
Global instance.
RoutePoint * pAnchorWatchPoint2
Global instance.
Routeman * g_pRouteMan
Global instance.
RouteList * pRouteList
Global instance.
RoutePoint * pAnchorWatchPoint1
Global instance.
Route * pAISMOBRoute
Global instance.
S57QueryDialog * g_pObjectQueryDialog
Global instance.
S57 object query result window.
Select * pSelect
Global instance.
Selected route, segment, waypoint, etc.
const wxEventType wxEVT_OCPN_BUILDSENCTHREAD
Global instance.
SENCThreadManager * g_SencThreadManager
Global instance.
Class StdIcon, typically a small monochrome svg icon.
Represents an entry in the chart table, containing information about a single chart.
A generic position and navigation data structure.
double kCog
Course over ground in degrees.
double kHdt
True heading in degrees.
int nSats
Number of satellites used in the fix.
double kHdm
Magnetic heading in degrees.
time_t FixTime
UTC time of fix.
double kLat
Latitude in decimal degrees.
double kSog
Speed over ground in knots.
double kVar
Magnetic variation in degrees.
double kLon
Longitude in decimal degrees.
Suspend/resume and new devices events exchange point.
Tide and currents window.
TCMgr * ptcmgr
Global instance.
Tide and Current Manager @TODO Add original author copyright.
Timer identification constants.
ActiveTrack * g_pActiveTrack
global instance
std::vector< Track * > g_TrackList
Global instance.
Recorded track abstraction.
TrackPropDlg * pTrackPropDialog
Global instance.
void DestroyDeviceNotFoundDialogs()
Destroy all open "Device not found" dialog windows.
Access checks for comm devices and dongle.
Generic hardware events interface.
WaypointMan drawing stuff.