38#include <wx/filename.h>
39#include <wx/fontdlg.h>
42#include "dashboard_pi.h"
44#include "wx/jsonreader.h"
45#include "wx/jsonwriter.h"
47#include "../../../gui/include/gui/ocpn_fontdlg.h"
50wxFontData *g_pFontTitle;
51wxFontData *g_pFontData;
52wxFontData *g_pFontLabel;
53wxFontData *g_pFontSmall;
55wxFontData g_FontTitle;
57wxFontData g_FontLabel;
58wxFontData g_FontSmall;
60wxFontData *g_pUSFontTitle;
61wxFontData *g_pUSFontData;
62wxFontData *g_pUSFontLabel;
63wxFontData *g_pUSFontSmall;
65wxFontData g_USFontTitle;
66wxFontData g_USFontData;
67wxFontData g_USFontLabel;
68wxFontData g_USFontSmall;
77int g_iDashDistanceUnit;
78int g_iDashWindSpeedUnit;
80double g_dDashDBTOffset;
81bool g_bUseInternSumLog;
84int logCount, confprint;
85bool g_bDBtrueWindGround;
89int g_dashPrefWidth, g_dashPrefHeight;
91wxColor g_BackgroundColor;
92bool g_ForceBackgroundColor;
93wxAlignment g_TitleAlignment;
94double g_TitleVerticalOffset;
97wxAlignment g_DataAlignment;
99int g_iInstrumentSpacing;
103static const long long lNaN = 0xfff8000000000000;
104#define NAN (*(double *)&lNaN)
107#ifdef __OCPN__ANDROID__
117extern "C" DECL_EXP
void destroy_pi(
opencpn_plugin *p) {
delete p; }
119#ifdef __OCPN__ANDROID__
121QString qtStyleSheet =
122 "QScrollBar:horizontal {\
123border: 0px solid grey;\
124background-color: rgb(240, 240, 240);\
126margin: 0px 1px 0 1px;\
128QScrollBar::handle:horizontal {\
129background-color: rgb(200, 200, 200);\
133QScrollBar::add-line:horizontal {\
134border: 0px solid grey;\
137subcontrol-position: right;\
138subcontrol-origin: margin;\
140QScrollBar::sub-line:horizontal {\
141border: 0px solid grey;\
144subcontrol-position: left;\
145subcontrol-origin: margin;\
147QScrollBar:vertical {\
148border: 0px solid grey;\
149background-color: rgb(240, 240, 240);\
151margin: 1px 0px 1px 0px;\
153QScrollBar::handle:vertical {\
154background-color: rgb(200, 200, 200);\
158QScrollBar::add-line:vertical {\
159border: 0px solid grey;\
162subcontrol-position: top;\
163subcontrol-origin: margin;\
165QScrollBar::sub-line:vertical {\
166border: 0px solid grey;\
169subcontrol-position: bottom;\
170subcontrol-origin: margin;\
175QCheckBox::indicator {\
183#ifdef __OCPN__ANDROID__
184#include <QtWidgets/QScroller>
256bool IsObsolete(
int id) {
265wxString getInstrumentCaption(
unsigned int id) {
268 return _(
"Position");
272 return _(
"Speed SOG");
274 return _(
"Speed STW");
280 return _(
"GNSS Compass");
282 return _(
"True Compass");
286 return _(
"True HDG");
291 return _(
"App. Wind Angle & Speed");
292 case ID_DBP_D_AWA_TWA:
293 return _(
"App & True Wind Angle");
295 return _(
"App. Wind Speed");
297 return _(
"App. Wind Speed");
299 return _(
"True Wind Angle & Speed");
301 return _(
"Altitude");
303 return _(
"Altitude Trace");
309 return _(
"Barometric pressure");
311 return _(
"Barometric pressure");
313 return _(
"Water Temp.");
315 return _(
"Air Temp.");
317 return _(
"App. Wind Angle");
319 return _(
"True Wind Angle");
321 return _(
"True Wind Direction");
323 return _(
"True Wind Speed");
325 return _(
"True Wind Dir. & Speed");
331 return _(
"VMG Wind");
333 return _(
"Rudder Angle");
335 return _(
"Rudder Angle");
337 return _(
"GNSS in use");
339 return _(
"GNSS Status");
342 case ID_DBP_I_GPSUTC:
343 return _(
"GNSS Clock");
345 return _(
"Sunrise/Sunset");
347 return _(
"Moon phase");
349 return _(
"Wind history");
351 return _(
"Barometric history");
353 return _(
"Trip Log");
357 return _(
"From Ownship");
362 case ID_DBP_I_GPSLCL:
363 return _(
"Local GNSS Clock");
364 case ID_DBP_I_CPULCL:
365 return _(
"Local CPU Clock");
366 case ID_DBP_I_SUNLCL:
367 return _(
"Local Sunrise/Sunset");
369 return _(
"Humidity");
371 return _(
"Windlass");
376void getListItemForInstrument(wxListItem &item,
unsigned int id) {
378 item.SetText(getInstrumentCaption(
id));
401 case ID_DBP_I_GPSUTC:
402 case ID_DBP_I_GPSLCL:
403 case ID_DBP_I_CPULCL:
405 case ID_DBP_I_SUNLCL:
423 case ID_DBP_D_AWA_TWA:
441int GetRandomNumber(
int range_min,
int range_max) {
442 long u = (long)wxRound(
443 ((
double)rand() / ((
double)(RAND_MAX) + 1) * (range_max - range_min)) +
449wxString GetUUID(
void) {
454 int time_hi_and_version;
455 int clock_seq_hi_and_rsv;
461 uuid.time_low = GetRandomNumber(
464 uuid.time_mid = GetRandomNumber(0, 65535);
465 uuid.time_hi_and_version = GetRandomNumber(0, 65535);
466 uuid.clock_seq_hi_and_rsv = GetRandomNumber(0, 255);
467 uuid.clock_seq_low = GetRandomNumber(0, 255);
468 uuid.node_hi = GetRandomNumber(0, 65535);
469 uuid.node_low = GetRandomNumber(0, 2147483647);
473 uuid.clock_seq_hi_and_rsv = (uuid.clock_seq_hi_and_rsv & 0x3F) | 0x80;
477 uuid.time_hi_and_version = (uuid.time_hi_and_version & 0x0fff) | 0x4000;
479 str.Printf(_T(
"%08x-%04x-%04x-%02x%02x-%04x%08x"), uuid.time_low,
480 uuid.time_mid, uuid.time_hi_and_version, uuid.clock_seq_hi_and_rsv,
481 uuid.clock_seq_low, uuid.node_hi, uuid.node_low);
486wxString MakeName() {
return _T(
"DASH_") + GetUUID(); }
494dashboard_pi::dashboard_pi(
void *ppimgr)
499 mCOGFilter.setType(IIRFILTER_TYPE_DEG);
500 mAWAFilter.setType(IIRFILTER_TYPE_DEG);
501 mAWSFilter.setType(IIRFILTER_TYPE_LINEAR);
504dashboard_pi::~dashboard_pi(
void) {
505 delete _img_dashboard_pi;
506 delete _img_dashboard;
508 delete _img_instrument;
538 m_config_version = -1;
547 mDPT_DBT_Watchdog = 2;
565 g_pFontTitle =
new wxFontData();
566 g_pFontTitle->SetChosenFont(
567 wxFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL));
569 g_pFontData =
new wxFontData();
570 g_pFontData->SetChosenFont(
571 wxFont(14, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
573 g_pFontLabel =
new wxFontData();
574 g_pFontLabel->SetChosenFont(
575 wxFont(8, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
577 g_pFontSmall =
new wxFontData();
578 g_pFontSmall->SetChosenFont(
579 wxFont(8, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
581 g_pUSFontTitle = &g_USFontTitle;
582 g_pUSFontData = &g_USFontData;
583 g_pUSFontLabel = &g_USFontLabel;
584 g_pUSFontSmall = &g_USFontSmall;
587 m_pauimgr->Connect(wxEVT_AUI_PANE_CLOSE,
588 wxAuiManagerEventHandler(dashboard_pi::OnPaneClose), NULL,
604 wxFileName::GetPathSeparator() + _T(
"dashboard_pi") +
605 wxFileName::GetPathSeparator() + _T(
"data") +
606 wxFileName::GetPathSeparator();
608 wxString normalIcon = shareLocn + _T(
"Dashboard.svg");
609 wxString toggledIcon = shareLocn + _T(
"Dashboard_toggled.svg");
610 wxString rolloverIcon = shareLocn + _T(
"Dashboard_rollover.svg");
616 toggledIcon = _T(
"");
617 rolloverIcon = _T(
"");
621 _T(
""), normalIcon, rolloverIcon, toggledIcon, wxITEM_CHECK,
622 _(
"Dashboard"), _T(
""), NULL, DASHBOARD_TOOL_POSITION, 0,
this);
627 if (m_config_version == 1) {
632 logCount = confprint = 0;
634 if (g_bUseInternSumLog) UpdateSumLog(
false);
642 listener_127245 =
GetListener(id_127245, EVT_N2K_127245,
this);
643 Bind(EVT_N2K_127245, [&](
ObservedEvt ev) { HandleN2K_127245(ev); });
648 listener_127257 =
GetListener(id_127257, EVT_N2K_127257,
this);
649 Bind(EVT_N2K_127257, [&](
ObservedEvt ev) { HandleN2K_127257(ev); });
654 listener_128259 =
GetListener(id_128259, EVT_N2K_128259,
this);
655 Bind(EVT_N2K_128259, [&](
ObservedEvt ev) { HandleN2K_128259(ev); });
660 listener_128267 =
GetListener(id_128267, EVT_N2K_128267,
this);
661 Bind(EVT_N2K_128267, [&](
ObservedEvt ev) { HandleN2K_128267(ev); });
666 listener_128275 =
GetListener(id_128275, EVT_N2K_128275,
this);
667 Bind(EVT_N2K_128275, [&](
ObservedEvt ev) { HandleN2K_128275(ev); });
672 listener_128777 =
GetListener(id_128777, EVT_N2K_128777,
this);
673 Bind(EVT_N2K_128777, [&](
ObservedEvt ev) { HandleN2K_128777(ev); });
678 listener_129029 =
GetListener(id_129029, EVT_N2K_129029,
this);
679 Bind(EVT_N2K_129029, [&](
ObservedEvt ev) { HandleN2K_129029(ev); });
684 listener_129540 =
GetListener(id_129540, EVT_N2K_129540,
this);
685 Bind(EVT_N2K_129540, [&](
ObservedEvt ev) { HandleN2K_129540(ev); });
690 listener_130306 =
GetListener(id_130306, EVT_N2K_130306,
this);
691 Bind(EVT_N2K_130306, [&](
ObservedEvt ev) { HandleN2K_130306(ev); });
696 listener_130310 =
GetListener(id_130310, EVT_N2K_130310,
this);
697 Bind(EVT_N2K_130310, [&](
ObservedEvt ev) { HandleN2K_130310(ev); });
702 listener_130313 =
GetListener(id_130313, EVT_N2K_130313,
this);
703 Bind(EVT_N2K_130313, [&](
ObservedEvt ev) { HandleN2K_130313(ev); });
705 Start(1000, wxTIMER_CONTINUOUS);
717 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
719 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow;
720 if (dashboard_window) {
721 m_pauimgr->DetachPane(dashboard_window);
722 dashboard_window->Close();
723 dashboard_window->Destroy();
724 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow = NULL;
728 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
743 if (value.IsDouble()) {
744 d_ret = value.AsDouble();
746 }
else if (value.IsLong()) {
747 int i_ret = value.AsLong();
754void dashboard_pi::Notify() {
755 SendUtcTimeToAllInstruments(mUTCDateTime);
756 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
758 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow;
759 if (dashboard_window) {
760 dashboard_window->Refresh();
761#ifdef __OCPN__ANDROID__
762 wxWindowList list = dashboard_window->GetChildren();
763 wxWindowListNode *node = list.GetFirst();
764 for (
size_t i = 0; i < list.GetCount(); i++) {
765 wxWindow *win = node->GetData();
768 node = node->GetNext();
776 if (mHDx_Watchdog <= 0) {
779 SendSentenceToAllInstruments(OCPN_DBP_STC_HDM, mHdm, _T(
"\u00B0"));
780 mHDx_Watchdog = gps_watchdog_timeout_ticks;
784 if (mHDT_Watchdog <= 0) {
786 SendSentenceToAllInstruments(OCPN_DBP_STC_HDT, NAN, _T(
"\u00B0T"));
787 mHDT_Watchdog = gps_watchdog_timeout_ticks;
791 if (mVar_Watchdog <= 0) {
794 SendSentenceToAllInstruments(OCPN_DBP_STC_HMV, NAN, _T(
"\u00B0T"));
795 mVar_Watchdog = gps_watchdog_timeout_ticks;
799 if (mSatsUsed_Wdog <= 0) {
802 SendSentenceToAllInstruments(OCPN_DBP_STC_SAT, NAN, _T(
""));
803 mSatsUsed_Wdog = gps_watchdog_timeout_ticks;
806 if (m_PriN2kTalker < -1e6) m_PriN2kTalker = 0;
809 if (mSatStatus_Wdog <= 0) {
811 for (
int i = 0; i < 4; i++) {
812 sats[i].SatNumber = 0;
813 sats[i].SignalToNoiseRatio = 0;
815 SendSatInfoToAllInstruments(0, 1, wxEmptyString, sats);
816 SendSatInfoToAllInstruments(0, 2, wxEmptyString, sats);
817 SendSatInfoToAllInstruments(0, 3, wxEmptyString, sats);
819 mSatStatus_Wdog = gps_watchdog_timeout_ticks;
826 std::string satID = PriorityIDs[4].substr(0, PriorityIDs[4].find(
':'));
827 if (satID.find(
"nmea0183") != std::string::npos)
829 else if (satID.find(
"ignal") != std::string::npos)
831 else if (satID.find(
"N2k") != std::string::npos) {
832 prioN2kPGNsat = PriorityIDs[4];
837 if (mMWVA_Watchdog <= 0) {
838 SendSentenceToAllInstruments(OCPN_DBP_STC_AWA, NAN, _T(
"-"));
839 SendSentenceToAllInstruments(OCPN_DBP_STC_AWS, NAN, _T(
"-"));
841 mMWVA_Watchdog = gps_watchdog_timeout_ticks;
845 if (mMWVT_Watchdog <= 0) {
846 SendSentenceToAllInstruments(OCPN_DBP_STC_TWA, NAN, _T(
"-"));
847 SendSentenceToAllInstruments(OCPN_DBP_STC_TWS, NAN, _T(
"-"));
848 SendSentenceToAllInstruments(OCPN_DBP_STC_TWS2, NAN, _T(
"-"));
850 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
854 if (mDPT_DBT_Watchdog <= 0) {
856 SendSentenceToAllInstruments(OCPN_DBP_STC_DPT, NAN, _T(
"-"));
857 mDPT_DBT_Watchdog = gps_watchdog_timeout_ticks;
861 if (mSTW_Watchdog <= 0) {
863 SendSentenceToAllInstruments(OCPN_DBP_STC_STW, NAN, _T(
"-"));
864 mSTW_Watchdog = gps_watchdog_timeout_ticks;
868 if (mWTP_Watchdog <= 0) {
870 SendSentenceToAllInstruments(OCPN_DBP_STC_TMP, NAN,
"-");
871 mWTP_Watchdog = no_nav_watchdog_timeout_ticks;
874 if (mRSA_Watchdog <= 0) {
876 SendSentenceToAllInstruments(OCPN_DBP_STC_RSA, NAN,
"-");
877 mRSA_Watchdog = gps_watchdog_timeout_ticks;
880 if (mVMG_Watchdog <= 0) {
881 SendSentenceToAllInstruments(OCPN_DBP_STC_VMG, NAN,
"-");
882 mVMG_Watchdog = gps_watchdog_timeout_ticks;
885 if (mVMGW_Watchdog <= 0) {
886 SendSentenceToAllInstruments(OCPN_DBP_STC_VMGW, NAN,
"-");
887 mVMGW_Watchdog = gps_watchdog_timeout_ticks;
890 if (mUTC_Watchdog <= 0) {
892 mUTC_Watchdog = gps_watchdog_timeout_ticks;
895 if (mATMP_Watchdog <= 0) {
896 SendSentenceToAllInstruments(OCPN_DBP_STC_ATMP, NAN,
"-");
898 mATMP_Watchdog = gps_watchdog_timeout_ticks;
901 if (mWDN_Watchdog <= 0) {
902 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, NAN, _T(
"-"));
904 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
907 if (mMDA_Watchdog <= 0) {
908 SendSentenceToAllInstruments(OCPN_DBP_STC_MDA, NAN, _T(
"-"));
910 mMDA_Watchdog = gps_watchdog_timeout_ticks;
913 if (mPITCH_Watchdog <= 0) {
915 SendSentenceToAllInstruments(OCPN_DBP_STC_PITCH, NAN, _T(
"-"));
916 mPITCH_Watchdog = gps_watchdog_timeout_ticks;
919 if (mHEEL_Watchdog <= 0) {
921 SendSentenceToAllInstruments(OCPN_DBP_STC_HEEL, NAN, _T(
"-"));
922 mHEEL_Watchdog = gps_watchdog_timeout_ticks;
925 if (mALT_Watchdog <= 0) {
927 SendSentenceToAllInstruments(OCPN_DBP_STC_ALTI, NAN, _T(
"-"));
928 mALT_Watchdog = gps_watchdog_timeout_ticks;
932 if (mLOG_Watchdog <= 0) {
933 if (g_bUseInternSumLog) {
936 SendSentenceToAllInstruments(OCPN_DBP_STC_VLW2, NAN, _T(
"-"));
937 mLOG_Watchdog = no_nav_watchdog_timeout_ticks;
941 if (mTrLOG_Watchdog <= 0) {
942 SendSentenceToAllInstruments(OCPN_DBP_STC_VLW1, NAN, _T(
"-"));
943 mTrLOG_Watchdog = no_nav_watchdog_timeout_ticks;
946 if (mHUM_Watchdog <= 0) {
948 SendSentenceToAllInstruments(OCPN_DBP_STC_HUM, NAN, _T(
"-"));
949 mHUM_Watchdog = no_nav_watchdog_timeout_ticks;
952 if (mWCC_Watchdog <= 0) {
953 SendSentenceToAllInstruments(OCPN_DBP_STC_WCC, NAN, _T(
"-"));
954 mWCC_Watchdog = no_nav_watchdog_timeout_ticks;
971 return _(
"Dashboard PlugIn for OpenCPN");
976 "Dashboard PlugIn for OpenCPN\n\
977Provides navigation instrument display from NMEA source.");
980void dashboard_pi::SendSentenceToAllInstruments(DASH_CAP st,
double value,
982 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
984 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow;
985 if (dashboard_window)
986 dashboard_window->SendSentenceToAllInstruments(st, value,
unit);
988 if (st == OCPN_DBP_STC_HDT) {
991 if (st == OCPN_DBP_STC_SOG) {
994 if (st == OCPN_DBP_STC_COG) {
999void dashboard_pi::SendUtcTimeToAllInstruments(wxDateTime value) {
1000 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
1002 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow;
1003 if (dashboard_window) dashboard_window->SendUtcTimeToAllInstruments(value);
1007void dashboard_pi::SendSatInfoToAllInstruments(
int cnt,
int seq, wxString talk,
1009 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
1011 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow;
1012 if (dashboard_window)
1013 dashboard_window->SendSatInfoToAllInstruments(cnt, seq, talk, sats);
1019 m_NMEA0183 << sentence;
1021 if (m_NMEA0183.PreParse()) {
1022 if (m_NMEA0183.LastSentenceIDReceived == _T(
"DBT")) {
1023 if (mPriDepth >= 5) {
1024 if (m_NMEA0183.Parse()) {
1031 if (!std::isnan(m_NMEA0183.Dbt.DepthMeters))
1032 depth = m_NMEA0183.Dbt.DepthMeters;
1033 else if (!std::isnan(m_NMEA0183.Dbt.DepthFeet))
1034 depth = m_NMEA0183.Dbt.DepthFeet * 0.3048;
1035 else if (!std::isnan(m_NMEA0183.Dbt.DepthFathoms))
1036 depth = m_NMEA0183.Dbt.DepthFathoms * 1.82880;
1037 if (!std::isnan(depth)) depth += g_dDashDBTOffset;
1038 if (!std::isnan(depth)) {
1039 SendSentenceToAllInstruments(
1044 mDPT_DBT_Watchdog = gps_watchdog_timeout_ticks;
1050 else if (m_NMEA0183.LastSentenceIDReceived == _T(
"DPT")) {
1051 if (mPriDepth >= 4) {
1052 if (m_NMEA0183.Parse()) {
1057 double depth = m_NMEA0183.Dpt.DepthMeters;
1058 if (!std::isnan(m_NMEA0183.Dpt.OffsetFromTransducerMeters)) {
1059 depth += m_NMEA0183.Dpt.OffsetFromTransducerMeters;
1061 depth += g_dDashDBTOffset;
1062 if (!std::isnan(depth)) {
1063 SendSentenceToAllInstruments(
1068 mDPT_DBT_Watchdog = gps_watchdog_timeout_ticks;
1074 else if (m_NMEA0183.LastSentenceIDReceived == _T(
"GGA")) {
1076 printf(
"GGA mPriPosition=%d mPriSatUsed=%d \tnSat=%d alt=%3.2f\n",
1077 mPriPosition, mPriSatUsed,
1078 m_NMEA0183.Gga.NumberOfSatellitesInUse,
1079 m_NMEA0183.Gga.AntennaAltitudeMeters);
1080 if (mPriAlt >= 3 && (mPriPosition >= 1 || mPriSatUsed >= 1)) {
1081 if (m_NMEA0183.Parse()) {
1082 if (m_NMEA0183.Gga.GPSQuality > 0 &&
1083 m_NMEA0183.Gga.NumberOfSatellitesInUse >= 5) {
1086 double alt = m_NMEA0183.Gga.AntennaAltitudeMeters;
1087 SendSentenceToAllInstruments(OCPN_DBP_STC_ALTI, alt, _T(
"m"));
1089 mALT_Watchdog = gps_watchdog_timeout_ticks;
1093 if (mPriPosition >= 4 || mPriSatUsed >= 3) {
1094 if (m_NMEA0183.Parse()) {
1095 if (m_NMEA0183.Gga.GPSQuality > 0) {
1096 if (mPriPosition >= 4) {
1099 float llt = m_NMEA0183.Gga.Position.Latitude.Latitude;
1100 int lat_deg_int = (int)(llt / 100);
1101 float lat_deg = lat_deg_int;
1102 float lat_min = llt - (lat_deg * 100);
1103 lat = lat_deg + (lat_min / 60.);
1104 if (m_NMEA0183.Gga.Position.Latitude.Northing == South)
1106 SendSentenceToAllInstruments(OCPN_DBP_STC_LAT, lat, _T(
"SDMM"));
1108 float lln = m_NMEA0183.Gga.Position.Longitude.Longitude;
1109 int lon_deg_int = (int)(lln / 100);
1110 float lon_deg = lon_deg_int;
1111 float lon_min = lln - (lon_deg * 100);
1112 lon = lon_deg + (lon_min / 60.);
1113 if (m_NMEA0183.Gga.Position.Longitude.Easting == West) lon = -lon;
1114 SendSentenceToAllInstruments(OCPN_DBP_STC_LON, lon, _T(
"SDMM"));
1116 if (mPriSatUsed >= 3) {
1117 mSatsInUse = m_NMEA0183.Gga.NumberOfSatellitesInUse;
1118 SendSentenceToAllInstruments(OCPN_DBP_STC_SAT, mSatsInUse,
1121 mSatsUsed_Wdog = gps_watchdog_timeout_ticks;
1135 else if (m_NMEA0183.LastSentenceIDReceived == _T(
"GLL")) {
1136 if (mPriPosition >= 3) {
1137 if (m_NMEA0183.Parse()) {
1138 if (m_NMEA0183.Gll.IsDataValid == NTrue) {
1140 float llt = m_NMEA0183.Gll.Position.Latitude.Latitude;
1141 int lat_deg_int = (int)(llt / 100);
1142 float lat_deg = lat_deg_int;
1143 float lat_min = llt - (lat_deg * 100);
1144 lat = lat_deg + (lat_min / 60.);
1145 if (m_NMEA0183.Gll.Position.Latitude.Northing == South) lat = -lat;
1146 SendSentenceToAllInstruments(OCPN_DBP_STC_LAT, lat, _T(
"SDMM"));
1148 float lln = m_NMEA0183.Gll.Position.Longitude.Longitude;
1149 int lon_deg_int = (int)(lln / 100);
1150 float lon_deg = lon_deg_int;
1151 float lon_min = lln - (lon_deg * 100);
1152 lon = lon_deg + (lon_min / 60.);
1153 if (m_NMEA0183.Gll.Position.Longitude.Easting == West) lon = -lon;
1154 SendSentenceToAllInstruments(OCPN_DBP_STC_LON, lon, _T(
"SDMM"));
1169 else if (m_NMEA0183.LastSentenceIDReceived == _T(
"GSV")) {
1170 if (mPriSatStatus >= 3 || mPriSatUsed >= 5) {
1171 if (m_NMEA0183.Parse()) {
1172 if (m_NMEA0183.Gsv.MessageNumber == 1) {
1175 mSatsInView = m_NMEA0183.Gsv.SatsInView;
1177 if (mPriSatUsed >= 5) {
1178 SendSentenceToAllInstruments(OCPN_DBP_STC_SAT,
1179 m_NMEA0183.Gsv.SatsInView, _T (
""));
1181 mSatsUsed_Wdog = gps_watchdog_timeout_ticks;
1185 if (mPriSatStatus >= 3) {
1186 SendSatInfoToAllInstruments(
1187 mSatsInView, m_NMEA0183.Gsv.MessageNumber, m_NMEA0183.TalkerID,
1188 m_NMEA0183.Gsv.SatInfo);
1190 mSatStatus_Wdog = gps_watchdog_timeout_ticks;
1196 else if (m_NMEA0183.LastSentenceIDReceived == _T(
"HDG")) {
1197 if (mPriVar >= 3 || mPriHeadingM >= 3 || mPriHeadingT >= 7) {
1198 if (m_NMEA0183.Parse()) {
1203 if ((!std::isnan(m_NMEA0183.Hdg.MagneticVariationDegrees)) &&
1204 0.0 != m_NMEA0183.Hdg.MagneticVariationDegrees) {
1206 if (m_NMEA0183.Hdg.MagneticVariationDirection == East)
1207 mVar = m_NMEA0183.Hdg.MagneticVariationDegrees;
1208 else if (m_NMEA0183.Hdg.MagneticVariationDirection == West)
1209 mVar = -m_NMEA0183.Hdg.MagneticVariationDegrees;
1210 SendSentenceToAllInstruments(OCPN_DBP_STC_HMV, mVar,
1214 if (mPriHeadingM >= 3) {
1215 if (!std::isnan(m_NMEA0183.Hdg.MagneticSensorHeadingDegrees)) {
1217 mHdm = m_NMEA0183.Hdg.MagneticSensorHeadingDegrees;
1218 SendSentenceToAllInstruments(OCPN_DBP_STC_HDM, mHdm,
1222 if (!std::isnan(m_NMEA0183.Hdg.MagneticSensorHeadingDegrees))
1223 mHDx_Watchdog = gps_watchdog_timeout_ticks;
1227 if (!std::isnan(m_NMEA0183.Hdg.MagneticSensorHeadingDegrees)) {
1228 if (!std::isnan(mVar) && (mPriHeadingT >= 7)) {
1230 double heading = mHdm + mVar;
1233 else if (heading >= 360.0)
1235 SendSentenceToAllInstruments(OCPN_DBP_STC_HDT, heading,
1237 mHDT_Watchdog = gps_watchdog_timeout_ticks;
1244 else if (m_NMEA0183.LastSentenceIDReceived == _T(
"HDM")) {
1245 if (mPriHeadingM >= 4 || mPriHeadingT >= 5) {
1246 if (m_NMEA0183.Parse()) {
1247 if (mPriHeadingM >= 4) {
1248 if (!std::isnan(m_NMEA0183.Hdm.DegreesMagnetic)) {
1250 mHdm = m_NMEA0183.Hdm.DegreesMagnetic;
1251 SendSentenceToAllInstruments(OCPN_DBP_STC_HDM, mHdm,
1253 mHDx_Watchdog = gps_watchdog_timeout_ticks;
1259 if (!std::isnan(m_NMEA0183.Hdm.DegreesMagnetic)) {
1260 if (!std::isnan(mVar) && (mPriHeadingT >= 5)) {
1262 double heading = mHdm + mVar;
1265 else if (heading >= 360.0)
1267 SendSentenceToAllInstruments(OCPN_DBP_STC_HDT, heading,
1269 mHDT_Watchdog = gps_watchdog_timeout_ticks;
1276 else if (m_NMEA0183.LastSentenceIDReceived == _T(
"HDT")) {
1277 if (mPriHeadingT >= 3) {
1278 if (m_NMEA0183.Parse()) {
1279 if (!std::isnan(m_NMEA0183.Hdt.DegreesTrue)) {
1280 SendSentenceToAllInstruments(
1281 OCPN_DBP_STC_HDT, m_NMEA0183.Hdt.DegreesTrue, _T(
"\u00B0T"));
1283 mHDT_Watchdog = gps_watchdog_timeout_ticks;
1287 }
else if (m_NMEA0183.LastSentenceIDReceived ==
1289 if (mPriATMP >= 3) {
1290 if (m_NMEA0183.Parse()) {
1292 SendSentenceToAllInstruments(
1296 mATMP_Watchdog = gps_watchdog_timeout_ticks;
1299 }
else if (m_NMEA0183.LastSentenceIDReceived == _T(
"MDA") &&
1300 (mPriMDA >= 5 || mPriATMP >= 5 || mPriHUM >= 4)) {
1302 if (m_NMEA0183.Parse()) {
1308 if (mPriMDA >= 5 && m_NMEA0183.Mda.Pressure > .8 &&
1309 m_NMEA0183.Mda.Pressure < 1.1) {
1310 SendSentenceToAllInstruments(
1311 OCPN_DBP_STC_MDA, m_NMEA0183.Mda.Pressure * 1000, _T(
"hPa"));
1313 mMDA_Watchdog = no_nav_watchdog_timeout_ticks;
1315 if (mPriATMP >= 5) {
1316 double airtemp = m_NMEA0183.Mda.AirTemp;
1317 if (!std::isnan(airtemp) && airtemp < 999.0) {
1318 SendSentenceToAllInstruments(
1321 mATMP_Watchdog = no_nav_watchdog_timeout_ticks;
1326 double humidity = m_NMEA0183.Mda.Humidity;
1327 if (!std::isnan(humidity)) {
1328 SendSentenceToAllInstruments(OCPN_DBP_STC_HUM, humidity,
"%");
1329 mHUM_Watchdog = no_nav_watchdog_timeout_ticks;
1335 }
else if (m_NMEA0183.LastSentenceIDReceived == _T(
"MTW")) {
1337 if (m_NMEA0183.Parse()) {
1339 SendSentenceToAllInstruments(
1343 mWTP_Watchdog = no_nav_watchdog_timeout_ticks;
1347 }
else if (m_NMEA0183.LastSentenceIDReceived == _T(
"VLW")) {
1348 if (m_NMEA0183.Parse()) {
1353 SendSentenceToAllInstruments(
1356 g_iDashDistanceUnit),
1358 mTrLOG_Watchdog = no_nav_watchdog_timeout_ticks;
1360 SendSentenceToAllInstruments(
1363 g_iDashDistanceUnit),
1365 mLOG_Watchdog = no_nav_watchdog_timeout_ticks;
1370 else if (m_NMEA0183.LastSentenceIDReceived == _T(
"MWD")) {
1372 if (m_NMEA0183.Parse()) {
1375 if (!std::isnan(m_NMEA0183.Mwd.WindAngleTrue)) {
1377 SendSentenceToAllInstruments(
1378 OCPN_DBP_STC_TWD, m_NMEA0183.Mwd.WindAngleTrue, _T(
"\u00B0"));
1381 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
1382 }
else if (!std::isnan(m_NMEA0183.Mwd.WindAngleMagnetic)) {
1384 if (!std::isnan(mVar)) {
1385 double twd = m_NMEA0183.Mwd.WindAngleMagnetic;
1389 }
else if (twd < 0.) {
1392 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, twd, _T(
"\u00B0"));
1394 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
1397 SendSentenceToAllInstruments(
1400 g_iDashWindSpeedUnit),
1402 SendSentenceToAllInstruments(
1405 g_iDashWindSpeedUnit),
1407 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
1414 else if (m_NMEA0183.LastSentenceIDReceived == _T(
"MWV")) {
1415 if (mPriAWA >= 4 || mPriTWA >= 5 || mPriWDN >= 5) {
1416 if (m_NMEA0183.Parse()) {
1417 if (m_NMEA0183.Mwv.IsDataValid == NTrue) {
1420 double m_wSpeedFactor = 1.0;
1421 if (m_NMEA0183.Mwv.WindSpeedUnits == _T(
"K"))
1422 m_wSpeedFactor = 0.53995;
1423 if (m_NMEA0183.Mwv.WindSpeedUnits == _T(
"M"))
1424 m_wSpeedFactor = 1.94384;
1426 if (m_NMEA0183.Mwv.Reference ==
1433 if (m_NMEA0183.Mwv.WindAngle > 180) {
1434 m_awaunit = _T(
"\u00B0L");
1435 m_awaangle = 180.0 - (m_NMEA0183.Mwv.WindAngle - 180.0);
1437 m_awaunit = _T(
"\u00B0R");
1438 m_awaangle = m_NMEA0183.Mwv.WindAngle;
1440 SendSentenceToAllInstruments(
1441 OCPN_DBP_STC_AWA, mAWAFilter.filter(m_awaangle), m_awaunit);
1442 SendSentenceToAllInstruments(
1445 mAWSFilter.filter(m_NMEA0183.Mwv.WindSpeed) *
1447 g_iDashWindSpeedUnit),
1449 mMWVA_Watchdog = gps_watchdog_timeout_ticks;
1457 CalculateAndUpdateTWDS(
1458 m_NMEA0183.Mwv.WindSpeed * m_wSpeedFactor,
1459 m_NMEA0183.Mwv.WindAngle);
1461 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
1462 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
1464 }
else if (m_NMEA0183.Mwv.Reference ==
1472 if (m_NMEA0183.Mwv.WindAngle > 180) {
1473 m_twaunit = _T(
"\u00B0L");
1474 m_twaangle = 180.0 - (m_NMEA0183.Mwv.WindAngle - 180.0);
1476 m_twaunit = _T(
"\u00B0R");
1477 m_twaangle = m_NMEA0183.Mwv.WindAngle;
1480 SendSentenceToAllInstruments(OCPN_DBP_STC_TWA, m_twaangle,
1488 if (g_dHDT < 361. && g_dHDT >= 0.0) {
1489 double g_dCalWdir = (m_NMEA0183.Mwv.WindAngle) + g_dHDT;
1490 if (g_dCalWdir > 360.) {
1492 }
else if (g_dCalWdir < 0.) {
1495 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, g_dCalWdir,
1498 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
1502 SendSentenceToAllInstruments(
1505 g_iDashWindSpeedUnit),
1507 SendSentenceToAllInstruments(
1510 g_iDashWindSpeedUnit),
1512 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
1520 else if (m_NMEA0183.LastSentenceIDReceived == _T(
"RMC")) {
1521 if (mPriPosition >= 5 || mPriCOGSOG >= 3 || mPriVar >= 4 ||
1522 mPriDateTime >= 3) {
1523 if (m_NMEA0183.Parse()) {
1524 if (m_NMEA0183.Rmc.IsDataValid == NTrue) {
1525 if (mPriPosition >= 5) {
1528 float llt = m_NMEA0183.Rmc.Position.Latitude.Latitude;
1529 int lat_deg_int = (int)(llt / 100);
1530 float lat_deg = lat_deg_int;
1531 float lat_min = llt - (lat_deg * 100);
1532 lat = lat_deg + (lat_min / 60.);
1533 if (m_NMEA0183.Rmc.Position.Latitude.Northing == South)
1535 SendSentenceToAllInstruments(OCPN_DBP_STC_LAT, lat, _T(
"SDMM"));
1537 float lln = m_NMEA0183.Rmc.Position.Longitude.Longitude;
1538 int lon_deg_int = (int)(lln / 100);
1539 float lon_deg = lon_deg_int;
1540 float lon_min = lln - (lon_deg * 100);
1541 lon = lon_deg + (lon_min / 60.);
1542 if (m_NMEA0183.Rmc.Position.Longitude.Easting == West) lon = -lon;
1543 SendSentenceToAllInstruments(OCPN_DBP_STC_LON, lon, _T(
"SDMM"));
1546 if (mPriCOGSOG >= 3) {
1548 if (!std::isnan(m_NMEA0183.Rmc.SpeedOverGroundKnots)) {
1549 SendSentenceToAllInstruments(
1552 mSOGFilter.filter(m_NMEA0183.Rmc.SpeedOverGroundKnots),
1557 if (!std::isnan(m_NMEA0183.Rmc.TrackMadeGoodDegreesTrue)) {
1558 SendSentenceToAllInstruments(
1560 mCOGFilter.filter(m_NMEA0183.Rmc.TrackMadeGoodDegreesTrue),
1563 if (!std::isnan(m_NMEA0183.Rmc.TrackMadeGoodDegreesTrue) &&
1564 !std::isnan(m_NMEA0183.Rmc.MagneticVariation)) {
1565 double dMagneticCOG;
1566 if (m_NMEA0183.Rmc.MagneticVariationDirection == East) {
1568 mCOGFilter.get() - m_NMEA0183.Rmc.MagneticVariation;
1569 if (dMagneticCOG < 0.0) dMagneticCOG = 360.0 + dMagneticCOG;
1572 mCOGFilter.get() + m_NMEA0183.Rmc.MagneticVariation;
1573 if (dMagneticCOG > 360.0) dMagneticCOG = dMagneticCOG - 360.0;
1575 SendSentenceToAllInstruments(OCPN_DBP_STC_MCOG, dMagneticCOG,
1584 if ((!std::isnan(m_NMEA0183.Rmc.MagneticVariation)) &&
1585 0.0 != m_NMEA0183.Rmc.MagneticVariation) {
1587 if (m_NMEA0183.Rmc.MagneticVariationDirection == East)
1588 mVar = m_NMEA0183.Rmc.MagneticVariation;
1589 else if (m_NMEA0183.Rmc.MagneticVariationDirection == West)
1590 mVar = -m_NMEA0183.Rmc.MagneticVariation;
1591 mVar_Watchdog = gps_watchdog_timeout_ticks;
1593 SendSentenceToAllInstruments(OCPN_DBP_STC_HMV, mVar,
1598 if (mPriDateTime >= 3) {
1600 wxString dt = m_NMEA0183.Rmc.Date + m_NMEA0183.Rmc.UTCTime;
1601 mUTCDateTime.ParseFormat(dt.c_str(), _T(
"%d%m%y%H%M%S"));
1602 mUTC_Watchdog = gps_watchdog_timeout_ticks;
1609 else if (m_NMEA0183.LastSentenceIDReceived == _T(
"RSA")) {
1611 if (m_NMEA0183.Parse()) {
1612 if (m_NMEA0183.Rsa.IsStarboardDataValid == NTrue) {
1613 SendSentenceToAllInstruments(
1614 OCPN_DBP_STC_RSA, m_NMEA0183.Rsa.Starboard, _T(
"\u00B0"));
1615 }
else if (m_NMEA0183.Rsa.IsPortDataValid == NTrue) {
1616 SendSentenceToAllInstruments(OCPN_DBP_STC_RSA, -m_NMEA0183.Rsa.Port,
1619 mRSA_Watchdog = gps_watchdog_timeout_ticks;
1625 else if (m_NMEA0183.LastSentenceIDReceived == _T(
"VHW")) {
1626 if (mPriHeadingT >= 4 || mPriHeadingM >= 5 || mPriSTW >= 3) {
1627 if (m_NMEA0183.Parse()) {
1628 if (mPriHeadingT >= 4) {
1629 if (!std::isnan(m_NMEA0183.Vhw.DegreesTrue)) {
1631 SendSentenceToAllInstruments(
1632 OCPN_DBP_STC_HDT, m_NMEA0183.Vhw.DegreesTrue, _T(
"\u00B0T"));
1633 mHDT_Watchdog = gps_watchdog_timeout_ticks;
1636 if (mPriHeadingM >= 5) {
1637 if (!std::isnan(m_NMEA0183.Vhw.DegreesMagnetic)) {
1639 SendSentenceToAllInstruments(OCPN_DBP_STC_HDM,
1640 m_NMEA0183.Vhw.DegreesMagnetic,
1642 mHDx_Watchdog = gps_watchdog_timeout_ticks;
1646 double stw_kn = NAN;
1647 if (!std::isnan(m_NMEA0183.Vhw.Knots))
1648 stw_kn = m_NMEA0183.Vhw.Knots;
1649 else if (!std::isnan(m_NMEA0183.Vhw.KilometersPerHour))
1650 stw_kn = m_NMEA0183.Vhw.KilometersPerHour * 0.53995;
1652 if (!std::isnan(stw_kn)) {
1653 SendSentenceToAllInstruments(
1656 mSTW_Watchdog = gps_watchdog_timeout_ticks;
1664 else if (m_NMEA0183.LastSentenceIDReceived == _T(
"VTG")) {
1665 if (mPriCOGSOG >= 2) {
1666 if (m_NMEA0183.Parse()) {
1669 if (!std::isnan(m_NMEA0183.Vtg.SpeedKnots)) {
1670 SendSentenceToAllInstruments(
1677 if (!std::isnan(m_NMEA0183.Vtg.TrackDegreesTrue)) {
1678 SendSentenceToAllInstruments(
1680 mCOGFilter.filter(m_NMEA0183.Vtg.TrackDegreesTrue),
1694 else if (m_NMEA0183.LastSentenceIDReceived == _T(
"VWR")) {
1696 if (m_NMEA0183.Parse()) {
1697 if (m_NMEA0183.Vwr.WindDirectionMagnitude < 200) {
1701 awaunit = m_NMEA0183.Vwr.DirectionOfWind == Left ? _T(
"\u00B0L")
1703 SendSentenceToAllInstruments(OCPN_DBP_STC_AWA,
1704 m_NMEA0183.Vwr.WindDirectionMagnitude,
1706 SendSentenceToAllInstruments(
1709 g_iDashWindSpeedUnit),
1711 mMWVA_Watchdog = gps_watchdog_timeout_ticks;
1723 double awa = m_NMEA0183.Vwr.WindDirectionMagnitude;
1724 if (m_NMEA0183.Vwr.DirectionOfWind == Left)
1725 awa = 360. - m_NMEA0183.Vwr.WindDirectionMagnitude;
1726 CalculateAndUpdateTWDS(m_NMEA0183.Vwr.WindSpeedKnots, awa);
1728 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
1729 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
1740 else if (m_NMEA0183.LastSentenceIDReceived == _T(
"VWT")) {
1742 if (m_NMEA0183.Parse()) {
1743 if (m_NMEA0183.Vwt.WindDirectionMagnitude < 200) {
1746 vwtunit = m_NMEA0183.Vwt.DirectionOfWind == Left ? _T(
"\u00B0L")
1748 SendSentenceToAllInstruments(OCPN_DBP_STC_TWA,
1749 m_NMEA0183.Vwt.WindDirectionMagnitude,
1751 SendSentenceToAllInstruments(
1754 g_iDashWindSpeedUnit),
1756 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
1766 else if (m_NMEA0183.LastSentenceIDReceived ==
1781 if (m_NMEA0183.Parse()) {
1784 for (
int i = 0; i < m_NMEA0183.Xdr.TransducerCnt; i++) {
1785 xdrdata = m_NMEA0183.Xdr.TransducerInfo[i].MeasurementData;
1787 if (m_NMEA0183.Xdr.TransducerInfo[i].TransducerType == _T(
"C")) {
1788 if (m_NMEA0183.Xdr.TransducerInfo[i]
1789 .TransducerName.MakeUpper()
1790 .Contains(_T(
"AIR")) ||
1791 m_NMEA0183.Xdr.TransducerInfo[i].TransducerName == _T(
"Te") ||
1792 m_NMEA0183.Xdr.TransducerInfo[i].TransducerName ==
1793 _T(
"ENV_OUTAIR_T") ||
1794 m_NMEA0183.Xdr.TransducerInfo[i].TransducerName ==
1795 _T(
"ENV_OUTSIDE_T")) {
1796 if (mPriATMP >= 4) {
1798 SendSentenceToAllInstruments(
1802 mATMP_Watchdog = no_nav_watchdog_timeout_ticks;
1806 if (m_NMEA0183.Xdr.TransducerInfo[i]
1807 .TransducerName.MakeUpper()
1808 .Contains(
"WATER") ||
1809 m_NMEA0183.Xdr.TransducerInfo[i].TransducerName ==
"WTHI") {
1812 SendSentenceToAllInstruments(
1815 m_NMEA0183.Xdr.TransducerInfo[i].MeasurementData,
1818 mWTP_Watchdog = no_nav_watchdog_timeout_ticks;
1824 if (m_NMEA0183.Xdr.TransducerInfo[i].TransducerType ==
"P") {
1825 if (m_NMEA0183.Xdr.TransducerInfo[i]
1826 .TransducerName.MakeUpper()
1827 .Contains(_T(
"BARO")) &&
1829 if (m_NMEA0183.Xdr.TransducerInfo[i].UnitOfMeasurement ==
"B") {
1831 SendSentenceToAllInstruments(OCPN_DBP_STC_MDA, xdrdata,
1834 mMDA_Watchdog = no_nav_watchdog_timeout_ticks;
1840 if (m_NMEA0183.Xdr.TransducerInfo[i].TransducerType == _T(
"A")) {
1841 if (m_NMEA0183.Xdr.TransducerInfo[i].TransducerName.Contains(
1843 m_NMEA0183.Xdr.TransducerInfo[i].TransducerName.Contains(
1845 if (mPriPitchRoll >= 3) {
1846 if (m_NMEA0183.Xdr.TransducerInfo[i].MeasurementData > 0) {
1847 xdrunit = _T(
"\u00B0\u2191") + _(
"Up");
1848 }
else if (m_NMEA0183.Xdr.TransducerInfo[i].MeasurementData <
1850 xdrunit = _T(
"\u00B0\u2193") + _(
"Down");
1853 xdrunit = _T(
"\u00B0");
1855 SendSentenceToAllInstruments(OCPN_DBP_STC_PITCH, xdrdata,
1857 mPITCH_Watchdog = gps_watchdog_timeout_ticks;
1863 if (m_NMEA0183.Xdr.TransducerInfo[i].TransducerName.Contains(
1865 if (mPriPitchRoll >= 3) {
1866 if (m_NMEA0183.Xdr.TransducerInfo[i].MeasurementData > 0) {
1867 xdrunit = _T(
"\u00B0\u003E") + _(
"Stbd");
1868 }
else if (m_NMEA0183.Xdr.TransducerInfo[i].MeasurementData <
1870 xdrunit = _T(
"\u00B0\u003C") + _(
"Port");
1873 xdrunit = _T(
"\u00B0");
1875 SendSentenceToAllInstruments(OCPN_DBP_STC_HEEL, xdrdata,
1877 mHEEL_Watchdog = gps_watchdog_timeout_ticks;
1883 if (m_NMEA0183.Xdr.TransducerInfo[i]
1884 .TransducerName.MakeUpper()
1885 .Contains(
"RUDDER")) {
1887 SendSentenceToAllInstruments(OCPN_DBP_STC_RSA, xdrdata,
1889 mRSA_Watchdog = gps_watchdog_timeout_ticks;
1896 if ((m_NMEA0183.Xdr.TransducerInfo[i].TransducerType ==
"D")) {
1897 bool good_depth =
false;
1898 if (m_NMEA0183.Xdr.TransducerInfo[i].TransducerName ==
"XDHI" &&
1902 }
else if (m_NMEA0183.Xdr.TransducerInfo[i].TransducerName ==
1909 else if (m_NMEA0183.Xdr.TransducerInfo[i].TransducerName ==
1911 m_NMEA0183.Xdr.TransducerInfo[i].TransducerName ==
1914 m_NMEA0183.Xdr.TransducerInfo[i].UnitOfMeasurement;
1915 if (
unit == wxEmptyString)
unit =
"m";
1917 SendSentenceToAllInstruments(OCPN_DBP_STC_WCC, xdrdata,
unit);
1918 mWCC_Watchdog = no_nav_watchdog_timeout_ticks;
1922 wxString
unit = m_NMEA0183.Xdr.TransducerInfo[i]
1923 .UnitOfMeasurement.MakeLower();
1927 if (!std::isnan(depth)) {
1928 depth += g_dDashDBTOffset;
1929 SendSentenceToAllInstruments(
1933 mDPT_DBT_Watchdog = gps_watchdog_timeout_ticks;
1939 if (m_NMEA0183.Xdr.TransducerInfo[i].TransducerType ==
"H") {
1941 if (m_NMEA0183.Xdr.TransducerInfo[i].UnitOfMeasurement ==
"P") {
1942 SendSentenceToAllInstruments(OCPN_DBP_STC_HUM, xdrdata,
"%");
1944 mHUM_Watchdog = no_nav_watchdog_timeout_ticks;
1950 }
else if (m_NMEA0183.LastSentenceIDReceived == _T(
"ZDA")) {
1951 if (mPriDateTime >= 2) {
1952 if (m_NMEA0183.Parse()) {
1963 dt.Printf(_T(
"%4d%02d%02d"), m_NMEA0183.Zda.Year,
1964 m_NMEA0183.Zda.Month, m_NMEA0183.Zda.Day);
1965 dt.Append(m_NMEA0183.Zda.UTCTime);
1966 mUTCDateTime.ParseFormat(dt.c_str(), _T(
"%Y%m%d%H%M%S"));
1967 mUTC_Watchdog = gps_watchdog_timeout_ticks;
1973 else if (sentence.Mid(1, 5).IsSameAs(_T(
"AIVDO"))) {
1976 if (!std::isnan(gpd.
Lat))
1977 SendSentenceToAllInstruments(OCPN_DBP_STC_LAT, gpd.
Lat, _T(
"SDMM"));
1979 if (!std::isnan(gpd.
Lon))
1980 SendSentenceToAllInstruments(OCPN_DBP_STC_LON, gpd.
Lon, _T(
"SDMM"));
1982 SendSentenceToAllInstruments(
1986 SendSentenceToAllInstruments(OCPN_DBP_STC_COG, mCOGFilter.filter(gpd.
Cog),
1988 if (!std::isnan(gpd.
Hdt)) {
1989 SendSentenceToAllInstruments(OCPN_DBP_STC_HDT, gpd.
Hdt, _T(
"\u00B0T"));
1990 mHDT_Watchdog = gps_watchdog_timeout_ticks;
2001void dashboard_pi::CalculateAndUpdateTWDS(
double awsKnots,
double awaDegrees) {
2002 if (!std::isnan(g_dHDT)) {
2004 double awsx = awsKnots * cos(awaDegrees * PI / 180.);
2005 double awsy = awsKnots * sin(awaDegrees * PI / 180.);
2010 if ((!std::isnan(g_dSOG)) && (!std::isnan(g_dCOG))) {
2011 bsx = g_dSOG * cos((g_dCOG - g_dHDT) * PI / 180.);
2012 bsy = g_dSOG * sin((g_dCOG - g_dHDT) * PI / 180.);
2017 double twdx = awsx - bsx;
2018 double twdy = awsy - bsy;
2021 double tws = pow(((twdx * twdx) + (twdy * twdy)), 0.5);
2024 double twd = atan2(twdy, twdx) * 180. / PI;
2026 SendSentenceToAllInstruments(OCPN_DBP_STC_TWA, -twd, _T(
"\u00B0L"));
2028 SendSentenceToAllInstruments(OCPN_DBP_STC_TWA, twd, _T(
"\u00B0R"));
2031 double twdc = twd + g_dHDT;
2034 if (twdc < 0) twdc += 360.;
2035 if (twdc > 360.) twdc -= 360;
2039 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, twdc, _T(
"\u00B0"));
2041 SendSentenceToAllInstruments(OCPN_DBP_STC_TWS,
2044 SendSentenceToAllInstruments(OCPN_DBP_STC_TWS2,
2054void dashboard_pi::HandleN2K_127245(
ObservedEvt ev) {
2059 unsigned char source_id = v.at(7);
2061 sprintf(ss,
"%d", source_id);
2062 std::string ident = std::string(ss);
2064 source +=
":" + ident;
2069 if (source != prio127245)
return;
2072 prio127245 = source;
2075 double RudderPosition, AngleOrder;
2076 unsigned char Instance;
2077 tN2kRudderDirectionOrder RudderDirectionOrder;
2080 if (ParseN2kPGN127245(v, RudderPosition, Instance, RudderDirectionOrder,
2082 if (!N2kIsNA(RudderPosition)) {
2083 double m_rudangle = GEODESIC_RAD2DEG(RudderPosition);
2084 SendSentenceToAllInstruments(OCPN_DBP_STC_RSA, m_rudangle,
2086 mRSA_Watchdog = gps_watchdog_timeout_ticks;
2094void dashboard_pi::HandleN2K_127257(
ObservedEvt ev) {
2099 unsigned char source_id = v.at(7);
2101 sprintf(ss,
"%d", source_id);
2102 std::string ident = std::string(ss);
2104 source +=
":" + ident;
2106 if (mPriPitchRoll >= 1) {
2107 if (mPriPitchRoll == 1) {
2109 if (source != prio127257)
return;
2112 prio127257 = source;
2116 double Yaw, Pitch, Roll;
2119 if (ParseN2kPGN127257(v, SID, Yaw, Pitch, Roll)) {
2120 if (!N2kIsNA(Pitch)) {
2121 double m_pitch = GEODESIC_RAD2DEG(Pitch);
2122 wxString p_unit = _T(
"\u00B0\u2191") + _(
"Up");
2124 p_unit = _T(
"\u00B0\u2193") + _(
"Down");
2127 SendSentenceToAllInstruments(OCPN_DBP_STC_PITCH, m_pitch, p_unit);
2128 mPITCH_Watchdog = gps_watchdog_timeout_ticks;
2131 if (!N2kIsNA(Roll)) {
2132 double m_heel = GEODESIC_RAD2DEG(Roll);
2133 wxString h_unit = _T(
"\u00B0\u003E") + _(
"Stbd");
2135 h_unit = _T(
"\u00B0\u003C") + _(
"Port");
2138 SendSentenceToAllInstruments(OCPN_DBP_STC_HEEL, m_heel, h_unit);
2139 mHEEL_Watchdog = gps_watchdog_timeout_ticks;
2146void dashboard_pi::HandleN2K_128267(
ObservedEvt ev) {
2151 unsigned char source_id = v.at(7);
2153 sprintf(ss,
"%d", source_id);
2154 std::string ident = std::string(ss);
2156 source +=
":" + ident;
2158 if (mPriDepth >= 1) {
2159 if (mPriDepth == 1) {
2160 if (source != prio128267)
return;
2162 prio128267 = source;
2166 double DepthBelowTransducer, Offset, Range;
2169 if (ParseN2kPGN128267(v, SID, DepthBelowTransducer, Offset, Range)) {
2170 if (!N2kIsNA(DepthBelowTransducer)) {
2171 double depth = DepthBelowTransducer;
2173 if (!std::isnan(Offset) && !N2kIsNA(Offset))
2176 (depth += g_dDashDBTOffset);
2178 SendSentenceToAllInstruments(
2183 mDPT_DBT_Watchdog = gps_watchdog_timeout_ticks;
2189void dashboard_pi::HandleN2K_128275(
ObservedEvt ev) {
2192 uint16_t DaysSince1970;
2193 double SecondsSinceMidnight;
2194 uint32_t Log, TripLog;
2197 if (ParseN2kPGN128275(v, DaysSince1970, SecondsSinceMidnight, Log, TripLog)) {
2198 if (!N2kIsNA(Log)) {
2199 double m_slog = METERS2NM((
double)Log);
2200 SendSentenceToAllInstruments(
2203 mLOG_Watchdog = no_nav_watchdog_timeout_ticks;
2206 if (!N2kIsNA(TripLog)) {
2207 double m_tlog = METERS2NM((
double)TripLog);
2208 SendSentenceToAllInstruments(
2211 mTrLOG_Watchdog = no_nav_watchdog_timeout_ticks;
2215void dashboard_pi::HandleN2K_128259(
ObservedEvt ev) {
2220 unsigned char source_id = v.at(7);
2222 sprintf(ss,
"%d", source_id);
2223 std::string ident = std::string(ss);
2225 source +=
":" + ident;
2229 if (source != prio128259)
return;
2231 prio128259 = source;
2235 double WaterReferenced, GroundReferenced;
2236 tN2kSpeedWaterReferenceType SWRT;
2239 if (ParseN2kPGN128259(v, SID, WaterReferenced, GroundReferenced, SWRT)) {
2240 if (!N2kIsNA(WaterReferenced)) {
2241 double stw_knots = MS2KNOTS(WaterReferenced);
2242 SendSentenceToAllInstruments(
2246 mSTW_Watchdog = gps_watchdog_timeout_ticks;
2252void dashboard_pi::HandleN2K_128777(
ObservedEvt ev) {
2257 unsigned char WindlassIdentifier;
2258 double RodeCounterValue;
2259 double WindlassLineSpeed;
2260 tN2kWindlassMotionStates WindlassMotionStatus;
2261 tN2kRodeTypeStates RodeTypeStatus;
2262 tN2kAnchorDockingStates AnchorDockingStatus;
2263 tN2kWindlassOperatingEvents WindlassOperatingEvents;
2265 if (ParseN2kPGN128777(v, SID, WindlassIdentifier, RodeCounterValue,
2266 WindlassLineSpeed, WindlassMotionStatus, RodeTypeStatus,
2267 AnchorDockingStatus, WindlassOperatingEvents)) {
2268 if (!N2kIsNA(RodeCounterValue)) {
2269 SendSentenceToAllInstruments(OCPN_DBP_STC_WCC, RodeCounterValue,
"m");
2270 mWCC_Watchdog = no_nav_watchdog_timeout_ticks;
2275wxString talker_N2k = wxEmptyString;
2276void dashboard_pi::HandleN2K_129029(
ObservedEvt ev) {
2280 unsigned char source_id = v.at(7);
2282 sprintf(ss,
"%d", source_id);
2283 std::string ident = std::string(ss);
2285 std::string prio_ID(prioN2kPGNsat.substr(prioN2kPGNsat.find(
':') + 1, 5));
2286 if (prio_ID.find(ident) == std::string::npos)
return;
2289 uint16_t DaysSince1970;
2290 double SecondsSinceMidnight;
2291 double Latitude, Longitude, Altitude;
2292 tN2kGNSStype GNSStype;
2293 tN2kGNSSmethod GNSSmethod;
2294 unsigned char nSatellites;
2295 double HDOP, PDOP, GeoidalSeparation;
2296 unsigned char nReferenceStations;
2297 tN2kGNSStype ReferenceStationType;
2298 uint16_t ReferenceSationID;
2299 double AgeOfCorrection;
2302 if (ParseN2kPGN129029(v, SID, DaysSince1970, SecondsSinceMidnight, Latitude,
2303 Longitude, Altitude, GNSStype, GNSSmethod, nSatellites,
2304 HDOP, PDOP, GeoidalSeparation, nReferenceStations,
2305 ReferenceStationType, ReferenceSationID,
2315 talker_N2k =
"GPSGLONAS";
2321 talker_N2k =
"GPSGLONAS";
2324 talker_N2k =
"Chayka";
2330 talker_N2k = wxEmptyString;
2332 if (!N2kIsNA(Altitude)) {
2334 SendSentenceToAllInstruments(OCPN_DBP_STC_ALTI, Altitude, _T(
"m"));
2336 mALT_Watchdog = gps_watchdog_timeout_ticks;
2342void dashboard_pi::HandleN2K_129540(
ObservedEvt ev) {
2347 unsigned char source_id = v.at(7);
2349 sprintf(ss,
"%d", source_id);
2350 std::string ident = std::string(ss);
2352 std::string prio_ID(prioN2kPGNsat.substr(prioN2kPGNsat.find(
':') + 1, 5));
2353 if (prio_ID.find(ident) == std::string::npos)
return;
2356 tN2kRangeResidualMode Mode;
2357 uint8_t NumberOfSVs;
2360 if (ParseN2kPGN129540(v, SID, Mode, NumberOfSVs)) {
2361 if (!N2kIsNA(NumberOfSVs) && mPriSatStatus == 1) {
2364 SAT_INFO N2K_SatInfo[4];
2367 double dElevRad = 0;
2368 double dAzimRad = 0;
2371 for (
int iMesNum = 0; iMesNum < 3; iMesNum++) {
2372 for (idx = 0; idx < 4; idx++) {
2373 tSatelliteInfo SatelliteInfo;
2374 index = idx + 4 * iMesNum;
2375 if (index >= NumberOfSVs - 1)
break;
2376 if (ParseN2kPGN129540(v, index, SatelliteInfo)) {
2377 iPRN = (int)SatelliteInfo.PRN;
2378 dElevRad = SatelliteInfo.Elevation;
2379 dAzimRad = SatelliteInfo.Azimuth;
2380 iSNR = N2kIsNA(SatelliteInfo.SNR) ? 0 : (int)SatelliteInfo.SNR;
2382 N2K_SatInfo[idx].SatNumber = iPRN;
2383 N2K_SatInfo[idx].ElevationDegrees = GEODESIC_RAD2DEG(dElevRad);
2384 N2K_SatInfo[idx].AzimuthDegreesTrue = GEODESIC_RAD2DEG(dAzimRad);
2385 N2K_SatInfo[idx].SignalToNoiseRatio = iSNR;
2390 SendSatInfoToAllInstruments(NumberOfSVs, iMesNum + 1, talker_N2k,
2393 mSatStatus_Wdog = gps_watchdog_timeout_ticks;
2401void dashboard_pi::HandleN2K_130306(
ObservedEvt ev) {
2409 double WindSpeed, WindAngle;
2410 tN2kWindReference WindReference;
2413 if (ParseN2kPGN130306(v, SID, WindSpeed, WindAngle, WindReference)) {
2414 if (!N2kIsNA(WindSpeed) && !N2kIsNA(WindAngle)) {
2415 double wind_angle_degr = GEODESIC_RAD2DEG(WindAngle);
2416 double wind_speed_kn = MS2KNOTS(WindSpeed);
2417 bool sendTWA =
false, sendTWS =
false;
2419 switch (WindReference) {
2422 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, wind_angle_degr,
2426 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
2432 if (!std::isnan(mVar)) {
2433 wind_angle_degr += mVar;
2434 if (wind_angle_degr > 360.) {
2435 wind_angle_degr -= 360;
2436 }
else if (wind_angle_degr < 0.) {
2437 wind_angle_degr += 360;
2440 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, wind_angle_degr,
2444 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
2449 double calc_angle = wind_angle_degr;
2451 wxString m_awaunit = _T(
"\u00B0R");
2453 if (wind_angle_degr > 180.0) {
2454 wind_angle_degr = 360.0 - wind_angle_degr;
2455 m_awaunit = _T(
"\u00B0L");
2457 SendSentenceToAllInstruments(OCPN_DBP_STC_AWA,
2458 mAWAFilter.filter(wind_angle_degr),
2461 SendSentenceToAllInstruments(
2464 g_iDashWindSpeedUnit),
2468 mMWVA_Watchdog = gps_watchdog_timeout_ticks;
2473 if (calc_angle > 180) calc_angle -= 360.0;
2474 CalculateAndUpdateTWDS(wind_speed_kn, calc_angle);
2477 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
2478 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
2483 if (mPriTWA >= 1 && g_bDBtrueWindGround) {
2490 if (mPriTWA >= 1 && !g_bDBtrueWindGround) {
2506 wxString m_twaunit = _T(
"\u00B0R");
2508 if (wind_angle_degr > 180.0) {
2509 wind_angle_degr = 360.0 - wind_angle_degr;
2510 m_twaunit = _T(
"\u00B0L");
2512 SendSentenceToAllInstruments(OCPN_DBP_STC_TWA, wind_angle_degr,
2518 SendSentenceToAllInstruments(
2522 SendSentenceToAllInstruments(
2526 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
2532void dashboard_pi::HandleN2K_130310(
ObservedEvt ev) {
2536 double WaterTemperature, OutsideAmbientAirTemperature, AtmosphericPressure;
2539 if (ParseN2kPGN130310(v, SID, WaterTemperature, OutsideAmbientAirTemperature,
2540 AtmosphericPressure)) {
2542 if (!N2kIsNA(WaterTemperature)) {
2543 double m_wtemp KELVIN2C(WaterTemperature);
2544 SendSentenceToAllInstruments(OCPN_DBP_STC_TMP,
2548 mWTP_Watchdog = no_nav_watchdog_timeout_ticks;
2552 if (mPriATMP >= 1) {
2553 if (!N2kIsNA(OutsideAmbientAirTemperature)) {
2554 double m_airtemp = KELVIN2C(OutsideAmbientAirTemperature);
2555 if (m_airtemp > -60 && m_airtemp < 100) {
2556 SendSentenceToAllInstruments(
2560 mATMP_Watchdog = no_nav_watchdog_timeout_ticks;
2565 if (!N2kIsNA(AtmosphericPressure) && mPriMDA >= 1) {
2566 double m_press = PA2HPA(AtmosphericPressure);
2567 SendSentenceToAllInstruments(OCPN_DBP_STC_MDA, m_press, _T(
"hPa"));
2569 mMDA_Watchdog = no_nav_watchdog_timeout_ticks;
2574void dashboard_pi::HandleN2K_130313(
ObservedEvt ev) {
2577 unsigned char SID, HumidityInstance;
2578 tN2kHumiditySource HumiditySource;
2579 double ActualHumidity, SetHumidity;
2581 if (ParseN2kPGN130313(v, SID, HumidityInstance, HumiditySource,
2582 ActualHumidity, SetHumidity)) {
2584 if (!N2kIsNA(ActualHumidity)) {
2585 SendSentenceToAllInstruments(OCPN_DBP_STC_HUM, ActualHumidity,
"%");
2587 mHUM_Watchdog = no_nav_watchdog_timeout_ticks;
2594void dashboard_pi::ParseSignalK(wxString &msg) {
2598 int errors = jsonReader.
Parse(msg, &root);
2606 if (root[
"self"].AsString().StartsWith(_T(
"vessels.")))
2607 m_self = (root[
"self"].
AsString());
2609 else if (root[
"self"].AsString().Length())
2611 _T(
"vessels.") + (root[
"self"].
AsString());
2615 auto context = root[
"context"].
AsString();
2616 if (context != m_self) {
2623 for (
int i = 0; i < updates.
Size(); ++i) {
2624 handleSKUpdate(updates[i]);
2629void dashboard_pi::handleSKUpdate(
wxJSONValue &update) {
2630 wxString sfixtime =
"";
2633 sfixtime = update[
"timestamp"].
AsString();
2635 if (update.
HasMember(
"values") && update[
"values"].IsArray()) {
2636 wxString talker = wxEmptyString;
2638 if (update[
"source"].HasMember(
"talker")) {
2639 if (update[
"source"][
"talker"].IsString()) {
2640 talker = update[
"source"][
"talker"].
AsString();
2644 for (
int j = 0; j < update[
"values"].
Size(); ++j) {
2646 updateSKItem(item, talker, sfixtime);
2651void dashboard_pi::updateSKItem(
wxJSONValue &item, wxString &talker,
2652 wxString &sfixtime) {
2654 const wxString &update_path = item[
"path"].
AsString();
2658 static wxString talkerID = wxEmptyString;
2660 static double skAWA;
2662 if (update_path == _T(
"navigation.position")) {
2663 if (mPriPosition >= 2) {
2664 if (value[
"latitude"].IsDouble() && value[
"longitude"].IsDouble()) {
2665 double lat = value[
"latitude"].
AsDouble();
2666 double lon = value[
"longitude"].AsDouble();
2667 SendSentenceToAllInstruments(OCPN_DBP_STC_LAT, lat, _T(
"SDMM"));
2668 SendSentenceToAllInstruments(OCPN_DBP_STC_LON, lon, _T(
"SDMM"));
2672 }
else if (update_path == _T(
"navigation.speedOverGround") &&
2673 2 == mPriPosition) {
2674 double sog_knot = GetJsonDouble(value);
2675 if (std::isnan(sog_knot))
return;
2677 SendSentenceToAllInstruments(
2681 }
else if (update_path == _T(
"navigation.courseOverGroundTrue") &&
2682 2 == mPriPosition) {
2683 double cog_rad = GetJsonDouble(value);
2684 if (std::isnan(cog_rad))
return;
2686 double cog_deg = GEODESIC_RAD2DEG(cog_rad);
2687 SendSentenceToAllInstruments(OCPN_DBP_STC_COG, mCOGFilter.filter(cog_deg),
2689 }
else if (update_path == _T(
"navigation.headingTrue")) {
2690 if (mPriHeadingT >= 2) {
2691 double hdt = GetJsonDouble(value);
2692 if (std::isnan(hdt))
return;
2694 hdt = GEODESIC_RAD2DEG(hdt);
2695 SendSentenceToAllInstruments(OCPN_DBP_STC_HDT, hdt, _T(
"\u00B0T"));
2697 mHDT_Watchdog = gps_watchdog_timeout_ticks;
2699 }
else if (update_path == _T(
"navigation.headingMagnetic")) {
2700 if (mPriHeadingM >= 2) {
2701 double hdm = GetJsonDouble(value);
2702 if (std::isnan(hdm))
return;
2704 hdm = GEODESIC_RAD2DEG(hdm);
2705 SendSentenceToAllInstruments(OCPN_DBP_STC_HDM, hdm, _T(
"\u00B0M"));
2707 mHDx_Watchdog = gps_watchdog_timeout_ticks;
2710 if (mPriHeadingT >= 6 && (!std::isnan(mVar))) {
2711 double heading = hdm + mVar;
2714 else if (heading >= 360.0)
2716 SendSentenceToAllInstruments(OCPN_DBP_STC_HDT, heading, _T(
"\u00B0"));
2718 mHDT_Watchdog = gps_watchdog_timeout_ticks;
2721 }
else if (update_path == _T(
"navigation.speedThroughWater")) {
2723 double stw_knots = GetJsonDouble(value);
2724 if (std::isnan(stw_knots))
return;
2726 stw_knots = MS2KNOTS(stw_knots);
2727 SendSentenceToAllInstruments(
2731 mSTW_Watchdog = gps_watchdog_timeout_ticks;
2733 }
else if (update_path == _T(
"navigation.magneticVariation")) {
2735 double dvar = GetJsonDouble(value);
2736 if (std::isnan(dvar))
return;
2738 dvar = GEODESIC_RAD2DEG(dvar);
2740 SendSentenceToAllInstruments(OCPN_DBP_STC_HMV, dvar, _T(
"\u00B0"));
2742 mVar_Watchdog = gps_watchdog_timeout_ticks;
2745 }
else if (update_path == _T(
"environment.wind.angleApparent")) {
2747 double m_awaangle = GetJsonDouble(value);
2748 if (std::isnan(m_awaangle))
return;
2750 m_awaangle = GEODESIC_RAD2DEG(m_awaangle);
2752 wxString m_awaunit = _T(
"\u00B0R");
2753 if (m_awaangle < 0) {
2754 m_awaunit = _T(
"\u00B0L");
2757 SendSentenceToAllInstruments(OCPN_DBP_STC_AWA,
2758 mAWAFilter.filter(m_awaangle), m_awaunit);
2760 mMWVA_Watchdog = gps_watchdog_timeout_ticks;
2762 }
else if (update_path == _T(
"environment.wind.speedApparent")) {
2764 double m_awaspeed_kn = GetJsonDouble(value);
2765 if (std::isnan(m_awaspeed_kn))
return;
2767 m_awaspeed_kn = MS2KNOTS(m_awaspeed_kn);
2768 SendSentenceToAllInstruments(
2771 g_iDashWindSpeedUnit),
2775 if (mPriTWA >= 6 && !std::isnan(skAWA)) {
2776 CalculateAndUpdateTWDS(m_awaspeed_kn, skAWA);
2778 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
2779 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
2782 }
else if ((update_path == _T(
"environment.wind.angleTrueWater") &&
2783 !g_bDBtrueWindGround) ||
2784 (update_path == _T(
"environment.wind.angleTrueGround") &&
2785 g_bDBtrueWindGround)) {
2787 double m_twaangle = GetJsonDouble(value);
2788 if (std::isnan(m_twaangle))
return;
2790 m_twaangle = GEODESIC_RAD2DEG(m_twaangle);
2791 double m_twaangle_raw = m_twaangle;
2792 wxString m_twaunit = _T(
"\u00B0R");
2793 if (m_twaangle < 0) {
2794 m_twaunit = _T(
"\u00B0L");
2797 SendSentenceToAllInstruments(OCPN_DBP_STC_TWA, m_twaangle, m_twaunit);
2799 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
2806 if (g_dHDT < 361. && g_dHDT >= 0.0) {
2807 double g_dCalWdir = (m_twaangle_raw) + g_dHDT;
2808 if (g_dCalWdir > 360.) {
2810 }
else if (g_dCalWdir < 0.) {
2813 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, g_dCalWdir,
2816 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
2820 }
else if ((update_path == _T(
"environment.wind.speedTrue") &&
2821 !g_bDBtrueWindGround) ||
2822 (update_path == _T(
"environment.wind.speedOverGround") &&
2823 g_bDBtrueWindGround)) {
2825 double m_twaspeed_kn = GetJsonDouble(value);
2826 if (std::isnan(m_twaspeed_kn))
return;
2828 m_twaspeed_kn = MS2KNOTS(m_twaspeed_kn);
2829 SendSentenceToAllInstruments(
2833 SendSentenceToAllInstruments(
2838 }
else if (update_path == _T(
"environment.depth.belowSurface")) {
2839 if (mPriDepth >= 3) {
2840 double depth = GetJsonDouble(value);
2841 if (std::isnan(depth))
return;
2844 depth += g_dDashDBTOffset;
2846 SendSentenceToAllInstruments(
2849 mDPT_DBT_Watchdog = gps_watchdog_timeout_ticks;
2851 }
else if (update_path == _T(
"environment.depth.belowTransducer")) {
2852 if (mPriDepth >= 3) {
2853 double depth = GetJsonDouble(value);
2854 if (std::isnan(depth))
return;
2857 depth += g_dDashDBTOffset;
2859 SendSentenceToAllInstruments(
2862 mDPT_DBT_Watchdog = gps_watchdog_timeout_ticks;
2864 }
else if (update_path == _T(
"environment.water.temperature")) {
2866 double m_wtemp = GetJsonDouble(value);
2867 if (std::isnan(m_wtemp))
return;
2869 m_wtemp = KELVIN2C(m_wtemp);
2870 if (m_wtemp > -60 && m_wtemp < 200 && !std::isnan(m_wtemp)) {
2871 SendSentenceToAllInstruments(
2875 mWTP_Watchdog = no_nav_watchdog_timeout_ticks;
2878 }
else if (update_path ==
2879 _T(
"navigation.courseRhumbline.nextPoint.velocityMadeGood")) {
2880 double m_vmg_kn = GetJsonDouble(value);
2881 if (std::isnan(m_vmg_kn))
return;
2883 m_vmg_kn = MS2KNOTS(m_vmg_kn);
2884 SendSentenceToAllInstruments(
2887 mVMG_Watchdog = gps_watchdog_timeout_ticks;
2890 else if (update_path == _T(
"performance.velocityMadeGood")) {
2891 double m_vmgw_kn = GetJsonDouble(value);
2892 if (std::isnan(m_vmgw_kn))
return;
2894 m_vmgw_kn = MS2KNOTS(m_vmgw_kn);
2895 SendSentenceToAllInstruments(
2898 mVMGW_Watchdog = gps_watchdog_timeout_ticks;
2901 else if (update_path == _T(
"steering.rudderAngle")) {
2903 double m_rudangle = GetJsonDouble(value);
2904 if (std::isnan(m_rudangle))
return;
2906 m_rudangle = GEODESIC_RAD2DEG(m_rudangle);
2907 SendSentenceToAllInstruments(OCPN_DBP_STC_RSA, m_rudangle,
2909 mRSA_Watchdog = gps_watchdog_timeout_ticks;
2912 }
else if (update_path ==
2913 _T(
"navigation.gnss.satellites")) {
2914 if (mPriSatUsed >= 2) {
2915 int usedSats = (value).AsInt();
2916 if (usedSats < 1)
return;
2917 SendSentenceToAllInstruments(OCPN_DBP_STC_SAT, usedSats, _T (
""));
2919 mSatsUsed_Wdog = gps_watchdog_timeout_ticks;
2921 }
else if (update_path == _T(
"navigation.gnss.type")) {
2922 if (value.IsString() && value.AsString() != wxEmptyString) {
2923 talkerID = (value.AsString());
2924 talkerID.MakeUpper();
2925 m_PriN2kTalker = gps_watchdog_timeout_ticks;
2926 if ((talkerID.Contains(_T(
"GPS"))) &&
2927 (talkerID.Contains(_T(
"GLONASS"))))
2928 talkerID = _T(
"GPSGLONAS");
2929 else if (talkerID.Contains(_T(
"GPS")))
2930 talkerID = _T(
"GP");
2931 else if (talkerID.Contains(_T(
"GLONASS")))
2932 talkerID = _T(
"GL");
2933 else if (talkerID.Contains(_T(
"GALILEO")))
2934 talkerID = _T(
"GA");
2935 else if (talkerID.Contains(_T(
"BEIDOU")))
2936 talkerID = _T(
"GI");
2938 }
else if (update_path ==
2939 _T(
"navigation.gnss.satellitesInView")) {
2941 if (mPriSatUsed >= 4) {
2942 if (value.HasMember(
"count") && value[
"count"].IsInt()) {
2943 double m_SK_SatsInView = (value[
"count"].AsInt());
2944 SendSentenceToAllInstruments(OCPN_DBP_STC_SAT, m_SK_SatsInView,
2947 mSatsUsed_Wdog = gps_watchdog_timeout_ticks;
2950 if (mPriSatStatus == 2) {
2951 if (value.HasMember(
"satellites") && value[
"satellites"].IsArray()) {
2954 if (value.HasMember(
"count") && value[
"count"].IsInt()) {
2955 iNumSats = (value[
"count"].AsInt());
2957 iNumSats = value[_T (
"satellites")].Size();
2959 SAT_INFO SK_SatInfo[4];
2960 for (
int idx = 0; idx < 4; idx++) {
2961 SK_SatInfo[idx].SatNumber = 0;
2962 SK_SatInfo[idx].ElevationDegrees = 0;
2963 SK_SatInfo[idx].AzimuthDegreesTrue = 0;
2964 SK_SatInfo[idx].SignalToNoiseRatio = 0;
2971 double dElevRad = 0;
2972 double dAzimRad = 0;
2975 for (
int iMesNum = 0; iMesNum < 3; iMesNum++) {
2976 for (idx = 0; idx < 4; idx++) {
2977 arr = idx + 4 * iMesNum;
2978 if (value[
"satellites"][arr][
"id"].IsInt())
2979 iID = value[
"satellites"][arr][
"id"].AsInt();
2980 if (value[
"satellites"][arr][
"elevation"].IsDouble())
2981 dElevRad = value[
"satellites"][arr][
"elevation"].AsDouble();
2982 if (value[
"satellites"][arr][
"azimuth"].IsDouble())
2983 dAzimRad = value[
"satellites"][arr][
"azimuth"].AsDouble();
2984 if (value[
"satellites"][arr][
"SNR"].IsInt())
2985 iSNR = value[
"satellites"][arr][
"SNR"].AsInt();
2988 SK_SatInfo[idx].SatNumber = iID;
2989 SK_SatInfo[idx].ElevationDegrees = GEODESIC_RAD2DEG(dElevRad);
2990 SK_SatInfo[idx].AzimuthDegreesTrue = GEODESIC_RAD2DEG(dAzimRad);
2991 SK_SatInfo[idx].SignalToNoiseRatio = iSNR;
2994 if (m_PriN2kTalker <= 0 && talker != wxEmptyString &&
2995 (talker.StartsWith(_T(
"G")) ||
2996 talker.StartsWith(_T(
"BD")))) {
2999 SendSatInfoToAllInstruments(iNumSats, iMesNum + 1, talkerID,
3002 mSatStatus_Wdog = gps_watchdog_timeout_ticks;
3010 }
else if (update_path == _T(
"navigation.gnss.antennaAltitude")) {
3012 double m_alt = GetJsonDouble(value);
3013 if (std::isnan(m_alt))
return;
3015 SendSentenceToAllInstruments(OCPN_DBP_STC_ALTI, m_alt, _T(
"m"));
3017 mALT_Watchdog = gps_watchdog_timeout_ticks;
3020 }
else if (update_path == _T(
"navigation.datetime")) {
3021 if (mPriDateTime >= 1) {
3023 wxString s_dt = (value.AsString());
3024 s_dt.Replace(
'-', wxEmptyString);
3025 s_dt.Replace(
':', wxEmptyString);
3026 wxString utc_dt = s_dt.BeforeFirst(
'T');
3027 utc_dt.Append(s_dt.AfterFirst(
'T').Left(6));
3028 mUTCDateTime.ParseFormat(utc_dt.c_str(), _T(
"%Y%m%d%H%M%S"));
3029 mUTC_Watchdog = gps_watchdog_timeout_ticks;
3031 }
else if (update_path == _T(
"environment.outside.temperature")) {
3032 if (mPriATMP >= 2) {
3033 double m_airtemp = GetJsonDouble(value);
3034 if (std::isnan(m_airtemp))
return;
3036 m_airtemp = KELVIN2C(m_airtemp);
3037 if (m_airtemp > -60 && m_airtemp < 100) {
3038 SendSentenceToAllInstruments(
3042 mATMP_Watchdog = no_nav_watchdog_timeout_ticks;
3045 }
else if (update_path == _T(
"environment.outside.humidity") ||
3046 update_path == _T(
"environment.outside.relativeHumidity")) {
3048 double m_hum = GetJsonDouble(value) * 100;
3049 if (std::isnan(m_hum))
return;
3050 SendSentenceToAllInstruments(OCPN_DBP_STC_HUM, m_hum,
"%");
3052 mHUM_Watchdog = no_nav_watchdog_timeout_ticks;
3054 }
else if (update_path ==
3055 _T(
"environment.wind.directionTrue")) {
3057 double m_twdT = GetJsonDouble(value);
3058 if (std::isnan(m_twdT))
return;
3060 m_twdT = GEODESIC_RAD2DEG(m_twdT);
3061 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, m_twdT, _T(
"\u00B0"));
3063 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
3065 }
else if (update_path == _T(
"environment.wind.directionMagnetic")) {
3068 double m_twdM = GetJsonDouble(value);
3069 if (std::isnan(m_twdM))
return;
3070 m_twdM = GEODESIC_RAD2DEG(m_twdM);
3072 if (!std::isnan(mVar)) {
3073 m_twdM = (m_twdM) + mVar;
3074 if (m_twdM > 360.) {
3076 }
else if (m_twdM < 0.) {
3080 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, m_twdM, _T(
"\u00B0"));
3082 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
3084 }
else if (update_path == _T(
"navigation.trip.log")) {
3085 double m_tlog = GetJsonDouble(value);
3086 if (std::isnan(m_tlog))
return;
3088 m_tlog = METERS2NM(m_tlog);
3089 SendSentenceToAllInstruments(
3092 mTrLOG_Watchdog = no_nav_watchdog_timeout_ticks;
3093 }
else if (update_path == _T(
"navigation.log")) {
3094 double m_slog = GetJsonDouble(value);
3095 if (std::isnan(m_slog))
return;
3097 m_slog = METERS2NM(m_slog);
3098 SendSentenceToAllInstruments(
3101 mLOG_Watchdog = no_nav_watchdog_timeout_ticks;
3102 }
else if (update_path == _T(
"environment.outside.pressure") &&
3104 double m_press = GetJsonDouble(value);
3105 if (std::isnan(m_press))
return;
3107 m_press = PA2HPA(m_press);
3108 SendSentenceToAllInstruments(OCPN_DBP_STC_MDA, m_press, _T(
"hPa"));
3110 mMDA_Watchdog = no_nav_watchdog_timeout_ticks;
3111 }
else if (update_path == _T(
"navigation.attitude")) {
3112 if (mPriPitchRoll >= 2) {
3113 if (value[
"roll"].AsString() !=
"0") {
3114 double m_heel = GEODESIC_RAD2DEG(value[
"roll"].AsDouble());
3115 wxString h_unit = _T(
"\u00B0\u003E") + _(
"Stbd");
3117 h_unit = _T(
"\u00B0\u003C") + _(
"Port");
3120 SendSentenceToAllInstruments(OCPN_DBP_STC_HEEL, m_heel, h_unit);
3121 mHEEL_Watchdog = gps_watchdog_timeout_ticks;
3124 if (value[
"pitch"].AsString() !=
"0") {
3125 double m_pitch = GEODESIC_RAD2DEG(value[
"pitch"].AsDouble());
3126 wxString p_unit = _T(
"\u00B0\u2191") + _(
"Up");
3128 p_unit = _T(
"\u00B0\u2193") + _(
"Down");
3131 SendSentenceToAllInstruments(OCPN_DBP_STC_PITCH, m_pitch, p_unit);
3132 mPITCH_Watchdog = gps_watchdog_timeout_ticks;
3142 if (mPriPosition >= 1) {
3144 SendSentenceToAllInstruments(OCPN_DBP_STC_LAT, pfix.
Lat, _T(
"SDMM"));
3145 SendSentenceToAllInstruments(OCPN_DBP_STC_LON, pfix.
Lon, _T(
"SDMM"));
3147 if (mPriCOGSOG >= 1) {
3148 double dMagneticCOG;
3150 SendSentenceToAllInstruments(
3154 SendSentenceToAllInstruments(OCPN_DBP_STC_COG, mCOGFilter.filter(pfix.
Cog),
3158 double logSOG = mSOGFilter.filter(pfix.
Sog);
3160 d_tripNM += logSOG / 3600;
3162 if (++logCount > 60) {
3169 dMagneticCOG = mCOGFilter.get() - pfix.
Var;
3170 if (dMagneticCOG < 0.0) dMagneticCOG = 360.0 + dMagneticCOG;
3171 if (dMagneticCOG > 360.0) dMagneticCOG = dMagneticCOG - 360.0;
3172 SendSentenceToAllInstruments(OCPN_DBP_STC_MCOG, dMagneticCOG,
3176 if (!std::isnan(pfix.
Var)) {
3179 mVar_Watchdog = gps_watchdog_timeout_ticks;
3181 SendSentenceToAllInstruments(OCPN_DBP_STC_HMV, pfix.
Var, _T(
"\u00B0"));
3184 if (mPriDateTime >= 6) {
3189 mUTCDateTime.Set(pfix.
FixTime);
3191 mUTCDateTime = wxInvalidDateTime;
3192 if (mUTCDateTime.IsValid()) {
3194 mUTCDateTime = mUTCDateTime.ToUTC();
3195 mUTC_Watchdog = gps_watchdog_timeout_ticks;
3198 if (mPriSatUsed >= 1) {
3199 mSatsInUse = pfix.
nSats;
3200 if (mSatsInUse > 0) {
3201 SendSentenceToAllInstruments(OCPN_DBP_STC_SAT, mSatsInUse, _T(
""));
3203 mSatsUsed_Wdog = gps_watchdog_timeout_ticks;
3206 if (mPriHeadingT >= 1) {
3207 double hdt = pfix.
Hdt;
3208 if (std::isnan(hdt))
return;
3209 SendSentenceToAllInstruments(OCPN_DBP_STC_HDT, hdt, _T(
"\u00B0T"));
3211 mHDT_Watchdog = gps_watchdog_timeout_ticks;
3213 if (mPriHeadingM >= 1) {
3214 double hdm = pfix.
Hdm;
3215 if (std::isnan(hdm) && !std::isnan(pfix.
Hdt) && !std::isnan(pfix.
Var)) {
3216 hdm = pfix.
Hdt - pfix.
Var;
3219 else if (hdm >= 360.0)
3222 if (std::isnan(hdm))
return;
3223 SendSentenceToAllInstruments(OCPN_DBP_STC_HDM, hdm, _T(
"\u00B0M"));
3225 mHDx_Watchdog = gps_watchdog_timeout_ticks;
3230 SendSentenceToAllInstruments(OCPN_DBP_STC_PLA, lat, _T(
"SDMM"));
3231 SendSentenceToAllInstruments(OCPN_DBP_STC_PLO, lon, _T(
"SDMM"));
3234void dashboard_pi::SetPluginMessage(wxString &message_id,
3235 wxString &message_body) {
3236 if (message_id == _T(
"WMM_VARIATION_BOAT")) {
3244 int numErrors = reader.
Parse(message_body, &root);
3245 if (numErrors > 0) {
3251 wxString decl = root[_T(
"Decl")].
AsString();
3253 decl.ToDouble(&decl_val);
3258 mVar_Watchdog = gps_watchdog_timeout_ticks;
3259 SendSentenceToAllInstruments(OCPN_DBP_STC_HMV, mVar, _T(
"\u00B0"));
3261 }
else if (message_id == _T(
"OCPN_CORE_SIGNALK")) {
3262 ParseSignalK(message_body);
3270 parent, wxID_ANY, m_ArrayOfDashboardWindow);
3272 dialog->RecalculateSize();
3274#ifdef __OCPN__ANDROID__
3275 dialog->GetHandle()->setStyleSheet(qtStyleSheet);
3278#ifdef __OCPN__ANDROID__
3282 int xmax = ccwin->GetSize().GetWidth();
3283 int ymax = ccwin->GetParent()
3286 dialog->SetSize(xmax, ymax);
3293 if (dialog->ShowModal() == wxID_OK) {
3294 double scaler = 1.0;
3297 scaler = wxMax(1.0, scaler);
3299 g_USFontTitle = *(dialog->m_pFontPickerTitle->GetFontData());
3300 g_FontTitle = *g_pUSFontTitle;
3301 g_FontTitle.SetChosenFont(g_pUSFontTitle->GetChosenFont().Scaled(scaler));
3302 g_FontTitle.SetColour(g_pUSFontTitle->GetColour());
3303 g_USFontTitle = *g_pUSFontTitle;
3305 g_USFontData = *(dialog->m_pFontPickerData->GetFontData());
3306 g_FontData = *g_pUSFontData;
3307 g_FontData.SetChosenFont(g_pUSFontData->GetChosenFont().Scaled(scaler));
3308 g_FontData.SetColour(g_pUSFontData->GetColour());
3309 g_USFontData = *g_pUSFontData;
3311 g_USFontLabel = *(dialog->m_pFontPickerLabel->GetFontData());
3312 g_FontLabel = *g_pUSFontLabel;
3313 g_FontLabel.SetChosenFont(g_pUSFontLabel->GetChosenFont().Scaled(scaler));
3314 g_FontLabel.SetColour(g_pUSFontLabel->GetColour());
3315 g_USFontLabel = *g_pUSFontLabel;
3317 g_USFontSmall = *(dialog->m_pFontPickerSmall->GetFontData());
3318 g_FontSmall = *g_pUSFontSmall;
3319 g_FontSmall.SetChosenFont(g_pUSFontSmall->GetChosenFont().Scaled(scaler));
3320 g_FontSmall.SetColour(g_pUSFontSmall->GetColour());
3321 g_USFontSmall = *g_pUSFontSmall;
3325 g_dashPrefWidth = dialog->GetSize().x;
3326 g_dashPrefHeight = dialog->GetSize().y;
3328 dialog->SaveDashboardConfig();
3329 m_ArrayOfDashboardWindow.Clear();
3330 m_ArrayOfDashboardWindow = dialog->m_Config;
3340 aktuellColorScheme = cs;
3341 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3343 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow;
3344 if (dashboard_window) dashboard_window->SetColorScheme(cs);
3348int dashboard_pi::GetDashboardWindowShownCount() {
3351 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3353 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow;
3354 if (dashboard_window) {
3355 wxAuiPaneInfo &pane = m_pauimgr->GetPane(dashboard_window);
3356 if (pane.IsOk() && pane.IsShown()) cnt++;
3362void dashboard_pi::OnPaneClose(wxAuiManagerEvent &event) {
3366 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3371 if (dashboard_window != d_w) {
3372 wxAuiPaneInfo &pane = m_pauimgr->GetPane(d_w);
3373 if (pane.IsOk() && pane.IsShown()) cnt++;
3375 cont->m_bIsVisible =
false;
3385 int cnt = GetDashboardWindowShownCount();
3387 bool b_anyviz =
false;
3388 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3390 if (cont->m_bIsVisible) {
3396 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3399 if (dashboard_window) {
3400 wxAuiPaneInfo &pane = m_pauimgr->GetPane(dashboard_window);
3402 bool b_reset_pos =
false;
3409 RECT frame_title_rect;
3410 frame_title_rect.left = pane.floating_pos.x;
3411 frame_title_rect.top = pane.floating_pos.y;
3412 frame_title_rect.right = pane.floating_pos.x + pane.floating_size.x;
3413 frame_title_rect.bottom = pane.floating_pos.y + 30;
3415 if (NULL == MonitorFromRect(&frame_title_rect, MONITOR_DEFAULTTONULL))
3421 wxRect window_title_rect;
3422 window_title_rect.x = pane.floating_pos.x;
3423 window_title_rect.y = pane.floating_pos.y;
3424 window_title_rect.width = pane.floating_size.x;
3425 window_title_rect.height = 30;
3427 wxRect ClientRect = wxGetClientDisplayRect();
3430 if (!ClientRect.Intersects(window_title_rect)) b_reset_pos =
true;
3434 if (b_reset_pos) pane.FloatingPosition(50, 50);
3438 pane.Show(cont->m_bIsVisible);
3440 cont->m_bIsVisible = cont->m_bPersVisible;
3441 pane.Show(cont->m_bIsVisible);
3448 if (pane.IsShown() && pane.IsDocked()) {
3449 pane.BestSize(cont->m_best_size);
3450 m_pauimgr->Update();
3461 if ((pane.dock_direction == wxAUI_DOCK_BOTTOM) && pane.IsDocked())
3468 GetDashboardWindowShownCount() != 0 );
3469 m_pauimgr->Update();
3479 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3481 wxAuiPaneInfo &pane = m_pauimgr->GetPane(cont->m_pDashboardWindow);
3483 cont->m_bIsVisible = (pane.IsOk() && pane.IsShown());
3487 if (pane.IsDocked()) {
3488 if ((cont->m_persist_size.x > 50) && (cont->m_persist_size.y > 50))
3489 cont->m_pDashboardWindow->SetSize(cont->m_persist_size);
3493 if (pane.IsShown()) {
3495 m_pauimgr->Update();
3497 m_pauimgr->Update();
3501 m_pauimgr->Update();
3509bool dashboard_pi::LoadConfig(
void) {
3510 wxFileConfig *pConf = (wxFileConfig *)m_pconfig;
3513 pConf->SetPath(_T(
"/PlugIns/Dashboard"));
3516 pConf->Read(_T(
"Version"), &version, wxEmptyString);
3525#ifdef __OCPN__ANDROID__
3526 TitleFont = _T(
"Roboto,16,-1,5,50,0,0,0,0,0");
3527 DataFont = _T(
"Roboto,16,-1,5,50,0,0,0,0,0");
3528 LabelFont = _T(
"Roboto,16,-1,5,50,0,0,0,0,0");
3529 SmallFont = _T(
"Roboto,14,-1,5,50,0,0,0,0,0");
3531 TitleFont = g_pFontTitle->GetChosenFont().GetNativeFontInfoDesc();
3532 DataFont = g_pFontData->GetChosenFont().GetNativeFontInfoDesc();
3533 LabelFont = g_pFontLabel->GetChosenFont().GetNativeFontInfoDesc();
3534 SmallFont = g_pFontSmall->GetChosenFont().GetNativeFontInfoDesc();
3537 double scaler = 1.0;
3539 wxFont *pDF = &DummyFont;
3543 scaler = wxMax(1.0, scaler);
3545 g_pFontTitle = &g_FontTitle;
3546 pConf->Read(_T(
"FontTitle"), &config, TitleFont);
3547 LoadFont(&pDF, config);
3548 wxFont DummyFontTitle = *pDF;
3549 pConf->Read(_T(
"ColorTitle"), &config,
"#000000");
3550 wxColour DummyColor(config);
3551 g_pUSFontTitle->SetChosenFont(DummyFontTitle);
3552 g_pUSFontTitle->SetColour(DummyColor);
3554 g_FontTitle = *g_pUSFontTitle;
3555 g_FontTitle.SetChosenFont(g_pUSFontTitle->GetChosenFont().Scaled(scaler));
3556 g_USFontTitle = *g_pUSFontTitle;
3558 g_pFontData = &g_FontData;
3559 pConf->Read(_T(
"FontData"), &config, DataFont);
3560 LoadFont(&pDF, config);
3561 wxFont DummyFontData = *pDF;
3562 pConf->Read(_T(
"ColorData"), &config,
"#000000");
3563 DummyColor.Set(config);
3564 g_pUSFontData->SetChosenFont(DummyFontData);
3565 g_pUSFontData->SetColour(DummyColor);
3566 g_FontData = *g_pUSFontData;
3567 g_FontData.SetChosenFont(g_pUSFontData->GetChosenFont().Scaled(scaler));
3568 g_USFontData = *g_pUSFontData;
3570 pConf->Read(_T(
"ForceBackgroundColor"), &g_ForceBackgroundColor, 0);
3571 pConf->Read(_T(
"BackgroundColor"), &config,
"DASHL");
3572 g_BackgroundColor.Set(config);
3575 pConf->Read(_T(
"TitleAlignment"), &alignment, (
int)wxALIGN_LEFT);
3576 g_TitleAlignment = (wxAlignment)alignment;
3577 if (g_TitleAlignment == wxALIGN_INVALID) g_TitleAlignment = wxALIGN_LEFT;
3578 pConf->Read(_T(
"TitleMargin"), &g_iTitleMargin, 5);
3579 pConf->Read(_T(
"DataShowUnit"), &g_bShowUnit,
true);
3580 pConf->Read(_T(
"DataAlignment"), &alignment, (int)wxALIGN_LEFT);
3581 g_DataAlignment = (wxAlignment)alignment;
3582 if (g_DataAlignment == wxALIGN_INVALID) g_DataAlignment = wxALIGN_LEFT;
3583 pConf->Read(_T(
"DataMargin"), &g_iDataMargin, 10);
3584 pConf->Read(_T(
"InstrumentSpacing"), &g_iInstrumentSpacing, 0);
3585 pConf->Read(_T(
"TitleVerticalOffset"), &g_TitleVerticalOffset, 0.0);
3587 g_pFontLabel = &g_FontLabel;
3588 pConf->Read(_T(
"FontLabel"), &config, LabelFont);
3589 LoadFont(&pDF, config);
3590 wxFont DummyFontLabel = *pDF;
3591 pConf->Read(_T(
"ColorLabel"), &config,
"#000000");
3592 DummyColor.Set(config);
3593 g_pUSFontLabel->SetChosenFont(DummyFontLabel);
3594 g_pUSFontLabel->SetColour(DummyColor);
3595 g_FontLabel = *g_pUSFontLabel;
3596 g_FontLabel.SetChosenFont(g_pUSFontLabel->GetChosenFont().Scaled(scaler));
3597 g_USFontLabel = *g_pUSFontLabel;
3599 g_pFontSmall = &g_FontSmall;
3600 pConf->Read(_T(
"FontSmall"), &config, SmallFont);
3601 LoadFont(&pDF, config);
3602 wxFont DummyFontSmall = *pDF;
3603 pConf->Read(_T(
"ColorSmall"), &config,
"#000000");
3604 DummyColor.Set(config);
3605 g_pUSFontSmall->SetChosenFont(DummyFontSmall);
3606 g_pUSFontSmall->SetColour(DummyColor);
3607 g_FontSmall = *g_pUSFontSmall;
3608 g_FontSmall.SetChosenFont(g_pUSFontSmall->GetChosenFont().Scaled(scaler));
3609 g_USFontSmall = *g_pUSFontSmall;
3611 pConf->Read(_T(
"SpeedometerMax"), &g_iDashSpeedMax, 12);
3612 pConf->Read(_T(
"COGDamp"), &g_iDashCOGDamp, 0);
3613 pConf->Read(_T(
"SpeedUnit"), &g_iDashSpeedUnit, 0);
3614 pConf->Read(_T(
"SOGDamp"), &g_iDashSOGDamp, 0);
3615 pConf->Read(_T(
"DepthUnit"), &g_iDashDepthUnit, 3);
3616 g_iDashDepthUnit = wxMax(g_iDashDepthUnit, 3);
3617 pConf->Read(_T(
"AWADamp"), &g_iDashAWADamp, 0);
3618 pConf->Read(_T(
"AWSDamp"), &g_iDashAWSDamp, 0);
3620 pConf->Read(_T(
"DepthOffset"), &g_dDashDBTOffset, 0);
3622 pConf->Read(_T(
"DistanceUnit"), &g_iDashDistanceUnit, 0);
3623 pConf->Read(_T(
"WindSpeedUnit"), &g_iDashWindSpeedUnit, 0);
3624 pConf->Read(_T(
"UseSignKtruewind"), &g_bDBtrueWindGround, 0);
3625 pConf->Read(
"UseInternSumlog", &g_bUseInternSumLog, 0);
3626 pConf->Read(
"SumLogNM", &g_dSumLogNM, 0.0);
3627 pConf->Read(_T(
"TemperatureUnit"), &g_iDashTempUnit, 0);
3629 pConf->Read(_T(
"UTCOffset"), &g_iUTCOffset, 0);
3631 pConf->Read(_T(
"PrefWidth"), &g_dashPrefWidth, 0);
3632 pConf->Read(_T(
"PrefHeight"), &g_dashPrefHeight, 0);
3635 pConf->Read(_T(
"DashboardCount"), &d_cnt, -1);
3637 m_ArrayOfDashboardWindow.Clear();
3638 if (version.IsEmpty() && d_cnt == -1) {
3639 m_config_version = 1;
3642 pConf->Read(_T(
"InstrumentCount"), &i_cnt, -1);
3644 wxArrayOfInstrumentProperties Property;
3646 for (
int i = 0; i < i_cnt; i++) {
3648 pConf->Read(wxString::Format(_T(
"Instrument%d"), i + 1), &
id, -1);
3649 if (
id != -1) ar.Add(
id);
3653#ifndef __OCPN__ANDROID__
3654 ar.Add(ID_DBP_I_POS);
3655 ar.Add(ID_DBP_D_COG);
3656 ar.Add(ID_DBP_D_GPS);
3658 ar.Add(ID_DBP_I_POS);
3659 ar.Add(ID_DBP_D_COG);
3660 ar.Add(ID_DBP_I_SOG);
3666 NULL, MakeName(), _(
"Dashboard"), _T(
"V"), ar, Property);
3667 cont->m_bPersVisible =
true;
3668 m_ArrayOfDashboardWindow.Add(cont);
3672 m_config_version = 2;
3673 bool b_onePersisted =
false;
3675 wxSize persist_size;
3676 for (
int k = 0; k < d_cnt; k++) {
3678 wxString::Format(_T(
"/PlugIns/Dashboard/Dashboard%d"), k + 1));
3680 pConf->Read(_T(
"Name"), &name, MakeName());
3682 pConf->Read(_T(
"Caption"), &caption, _(
"Dashboard"));
3684 pConf->Read(_T(
"Orientation"), &orient, _T(
"V"));
3686 pConf->Read(_T(
"InstrumentCount"), &i_cnt, -1);
3688 pConf->Read(_T(
"Persistence"), &b_persist, 1);
3690 pConf->Read(_T(
"BestSizeX"), &val, DefaultWidth);
3692 pConf->Read(_T(
"BestSizeY"), &val, DefaultWidth);
3694 pConf->Read(_T(
"PersistSizeX"), &val, DefaultWidth);
3695 persist_size.x = val;
3696 pConf->Read(_T(
"PersistSizeY"), &val, DefaultWidth);
3697 persist_size.y = val;
3700 wxArrayOfInstrumentProperties Property;
3701 for (
int i = 0; i < i_cnt; i++) {
3703 pConf->Read(wxString::Format(_T(
"Instrument%d"), i + 1), &
id, -1);
3707 if (pConf->Exists(wxString::Format(_T(
"InstTitleFont%d"), i + 1))) {
3710 pConf->Read(wxString::Format(_T(
"InstTitleFont%d"), i + 1),
3711 &config, TitleFont);
3712 LoadFont(&pDF, config);
3713 wxFont DummyFontTitleA = *pDF;
3714 pConf->Read(wxString::Format(_T(
"InstTitleColor%d"), i + 1),
3715 &config,
"#000000");
3716 DummyColor.Set(config);
3717 instp->m_USTitleFont.SetChosenFont(DummyFontTitleA);
3718 instp->m_USTitleFont.SetColour(DummyColor);
3719 instp->m_TitleFont = instp->m_USTitleFont;
3720 instp->m_TitleFont.SetChosenFont(
3721 instp->m_USTitleFont.GetChosenFont().Scaled(scaler));
3723 pConf->Read(wxString::Format(_T(
"InstDataShowUnit%d"), i + 1),
3724 &instp->m_ShowUnit, -1);
3725 pConf->Read(wxString::Format(_T(
"InstDataMargin%d"), i + 1),
3726 &instp->m_DataMargin, -1);
3727 pConf->Read(wxString::Format(_T(
"InstDataAlignment%d"), i + 1),
3728 &alignment, (
int)wxALIGN_INVALID);
3729 instp->m_DataAlignment = (wxAlignment)alignment;
3731 wxString::Format(_T(
"InstInstrumentSpacing%d"), i + 1),
3732 &instp->m_InstrumentSpacing, -1);
3733 pConf->Read(wxString::Format(_T(
"InstDataFormat%d"), i + 1),
3734 &instp->m_Format,
"");
3735 pConf->Read(wxString::Format(_T(
"InstTitle%d"), i + 1),
3736 &instp->m_Title,
"");
3738 pConf->Read(wxString::Format(_T(
"InstDataFont%d"), i + 1),
3740 LoadFont(&pDF, config);
3741 wxFont DummyFontDataA = *pDF;
3742 pConf->Read(wxString::Format(_T(
"InstDataColor%d"), i + 1),
3743 &config,
"#000000");
3744 DummyColor.Set(config);
3745 instp->m_USDataFont.SetChosenFont(DummyFontDataA);
3746 instp->m_USDataFont.SetColour(DummyColor);
3747 instp->m_DataFont = instp->m_USDataFont;
3748 instp->m_DataFont.SetChosenFont(
3749 instp->m_USDataFont.GetChosenFont().Scaled(scaler));
3751 pConf->Read(wxString::Format(_T(
"InstLabelFont%d"), i + 1),
3752 &config, LabelFont);
3753 LoadFont(&pDF, config);
3754 wxFont DummyFontLabelA = *pDF;
3755 pConf->Read(wxString::Format(_T(
"InstLabelColor%d"), i + 1),
3756 &config,
"#000000");
3757 DummyColor.Set(config);
3758 instp->m_USLabelFont.SetChosenFont(DummyFontLabelA);
3759 instp->m_USLabelFont.SetColour(DummyColor);
3760 instp->m_LabelFont = instp->m_USLabelFont;
3761 instp->m_LabelFont.SetChosenFont(
3762 instp->m_USLabelFont.GetChosenFont().Scaled(scaler));
3764 pConf->Read(wxString::Format(_T(
"InstSmallFont%d"), i + 1),
3765 &config, SmallFont);
3766 LoadFont(&pDF, config);
3767 wxFont DummyFontSmallA = *pDF;
3768 pConf->Read(wxString::Format(_T(
"InstSmallColor%d"), i + 1),
3769 &config,
"#000000");
3770 DummyColor.Set(config);
3771 instp->m_USSmallFont.SetChosenFont(DummyFontSmallA);
3772 instp->m_USSmallFont.SetColour(DummyColor);
3773 instp->m_SmallFont = instp->m_USSmallFont;
3774 instp->m_SmallFont.SetChosenFont(
3775 instp->m_USSmallFont.GetChosenFont().Scaled(scaler));
3777 pConf->Read(wxString::Format(_T(
"TitleBackColor%d"), i + 1),
3779 instp->m_TitleBackgroundColour.Set(config);
3781 pConf->Read(wxString::Format(_T(
"DataBackColor%d"), i + 1),
3783 instp->m_DataBackgroundColour.Set(config);
3785 pConf->Read(wxString::Format(_T(
"ArrowFirst%d"), i + 1), &config,
3787 instp->m_Arrow_First_Colour.Set(config);
3789 pConf->Read(wxString::Format(_T(
"ArrowSecond%d"), i + 1), &config,
3791 instp->m_Arrow_Second_Colour.Set(config);
3793 Property.Add(instp);
3800 NULL, name, caption, orient, ar, Property);
3801 cont->m_bPersVisible = b_persist;
3802 cont->m_conf_best_size = best_size;
3803 cont->m_persist_size = persist_size;
3805 if (b_persist) b_onePersisted =
true;
3807 m_ArrayOfDashboardWindow.Add(cont);
3811 if (m_ArrayOfDashboardWindow.Count() && !b_onePersisted) {
3813 if (cont) cont->m_bPersVisible =
true;
3822void dashboard_pi::LoadFont(wxFont **target, wxString native_info) {
3823 if (!native_info.IsEmpty()) {
3824#ifdef __OCPN__ANDROID__
3825 wxFont *nf =
new wxFont(native_info);
3828 (*target)->SetNativeFontInfo(native_info);
3833bool dashboard_pi::SaveConfig(
void) {
3834 wxFileConfig *pConf = (wxFileConfig *)m_pconfig;
3837 pConf->SetPath(_T(
"/PlugIns/Dashboard"));
3838 pConf->Write(_T(
"Version"), _T(
"2"));
3839 pConf->Write(_T(
"FontTitle"),
3840 g_pUSFontTitle->GetChosenFont().GetNativeFontInfoDesc());
3841 pConf->Write(_T(
"ColorTitle"),
3842 g_pUSFontTitle->GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3843 pConf->Write(_T(
"FontData"),
3844 g_pUSFontData->GetChosenFont().GetNativeFontInfoDesc());
3845 pConf->Write(_T(
"ColorData"),
3846 g_pUSFontData->GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3847 pConf->Write(_T(
"FontLabel"),
3848 g_pUSFontLabel->GetChosenFont().GetNativeFontInfoDesc());
3849 pConf->Write(_T(
"ColorLabel"),
3850 g_pUSFontLabel->GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3851 pConf->Write(_T(
"FontSmall"),
3852 g_pUSFontSmall->GetChosenFont().GetNativeFontInfoDesc());
3853 pConf->Write(_T(
"ColorSmall"),
3854 g_pUSFontSmall->GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3855 pConf->Write(_T(
"SpeedometerMax"), g_iDashSpeedMax);
3856 pConf->Write(_T(
"COGDamp"), g_iDashCOGDamp);
3857 pConf->Write(_T(
"SpeedUnit"), g_iDashSpeedUnit);
3858 pConf->Write(_T(
"SOGDamp"), g_iDashSOGDamp);
3859 pConf->Write(_T(
"AWSDamp"), g_iDashAWSDamp);
3860 pConf->Write(_T(
"AWADamp"), g_iDashAWADamp);
3861 pConf->Write(_T(
"DepthUnit"), g_iDashDepthUnit);
3862 pConf->Write(_T(
"DepthOffset"), g_dDashDBTOffset);
3863 pConf->Write(_T(
"DistanceUnit"), g_iDashDistanceUnit);
3864 pConf->Write(_T(
"WindSpeedUnit"), g_iDashWindSpeedUnit);
3865 pConf->Write(
"UseInternSumlog", g_bUseInternSumLog);
3866 pConf->Write(
"SumLogNM", g_dSumLogNM);
3867 pConf->Write(_T(
"UTCOffset"), g_iUTCOffset);
3868 pConf->Write(_T(
"UseSignKtruewind"), g_bDBtrueWindGround);
3869 pConf->Write(_T(
"TemperatureUnit"), g_iDashTempUnit);
3870 pConf->Write(_T(
"PrefWidth"), g_dashPrefWidth);
3871 pConf->Write(_T(
"PrefHeight"), g_dashPrefHeight);
3873 pConf->Write(_T(
"DashboardCount" ),
3874 (int)m_ArrayOfDashboardWindow.GetCount());
3876 for (
size_t i = m_ArrayOfDashboardWindow.GetCount(); i < 20; i++) {
3878 wxString::Format(_T(
"/PlugIns/Dashboard/Dashboard%zu"), i + 1))) {
3880 wxString::Format(_T(
"/PlugIns/Dashboard/Dashboard%zu"), i + 1));
3883 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3886 wxString::Format(_T(
"/PlugIns/Dashboard/Dashboard%zu"), i + 1));
3887 pConf->Write(_T(
"Name"), cont->m_sName);
3888 pConf->Write(_T(
"Caption"), cont->m_sCaption);
3889 pConf->Write(_T(
"Orientation"), cont->m_sOrientation);
3890 pConf->Write(_T(
"Persistence"), cont->m_bPersVisible);
3891 pConf->Write(_T(
"InstrumentCount"),
3892 (int)cont->m_aInstrumentList.GetCount());
3893 pConf->Write(_T(
"BestSizeX"), cont->m_best_size.x);
3894 pConf->Write(_T(
"BestSizeY"), cont->m_best_size.y);
3895 pConf->Write(_T(
"PersistSizeX"), cont->m_pDashboardWindow->GetSize().x);
3896 pConf->Write(_T(
"PersistSizeY"), cont->m_pDashboardWindow->GetSize().y);
3899 for (
size_t i = cont->m_aInstrumentList.GetCount(); i < 40; i++) {
3900 if (pConf->Exists(wxString::Format(_T(
"Instrument%zu"), i + 1))) {
3901 pConf->DeleteEntry(wxString::Format(_T(
"Instrument%zu"), i + 1));
3902 if (pConf->Exists(wxString::Format(_T(
"InstTitleFont%zu"), i + 1))) {
3903 pConf->DeleteEntry(wxString::Format(_T(
"InstTitleFont%zu"), i + 1));
3905 wxString::Format(_T(
"InstTitleColor%zu"), i + 1));
3906 pConf->DeleteEntry(wxString::Format(_T(
"InstTitle%zu"), i + 1));
3908 wxString::Format(_T(
"InstDataShowUnit%zu"), i + 1));
3910 wxString::Format(_T(
"InstDataMargin%zu"), i + 1));
3912 wxString::Format(_T(
"InstDataAlignment%zu"), i + 1));
3914 wxString::Format(_T(
"InstDataFormat%zu"), i + 1));
3915 pConf->DeleteEntry(wxString::Format(_T(
"InstDataFont%zu"), i + 1));
3916 pConf->DeleteEntry(wxString::Format(_T(
"InstDataColor%zu"), i + 1));
3917 pConf->DeleteEntry(wxString::Format(_T(
"InstLabelFont%zu"), i + 1));
3919 wxString::Format(_T(
"InstLabelColor%zu"), i + 1));
3920 pConf->DeleteEntry(wxString::Format(_T(
"InstSmallFont%zu"), i + 1));
3922 wxString::Format(_T(
"InstSmallColor%zu"), i + 1));
3924 wxString::Format(_T(
"TitleBackColor%zu"), i + 1));
3925 pConf->DeleteEntry(wxString::Format(_T(
"DataBackColor%zu"), i + 1));
3926 pConf->DeleteEntry(wxString::Format(_T(
"ArrowFirst%zu"), i + 1));
3927 pConf->DeleteEntry(wxString::Format(_T(
"ArrowSecond%zu"), i + 1));
3931 for (
size_t j = 0; j < cont->m_aInstrumentList.GetCount(); j++) {
3932 pConf->Write(wxString::Format(_T(
"Instrument%zu"), j + 1),
3933 cont->m_aInstrumentList.Item(j));
3936 if (pConf->Exists(wxString::Format(_T(
"InstTitleFont%zu"), j + 1))) {
3938 for (
size_t i = 0; i < cont->m_aInstrumentPropertyList.GetCount();
3940 Inst = cont->m_aInstrumentPropertyList.Item(i);
3941 if (Inst->m_Listplace == (
int)j) {
3947 pConf->DeleteEntry(wxString::Format(_T(
"InstTitleFont%zu"), j + 1));
3949 wxString::Format(_T(
"InstTitleColor%zu"), j + 1));
3950 pConf->DeleteEntry(wxString::Format(_T(
"InstTitle%zu"), j + 1));
3952 wxString::Format(_T(
"InstDataShowUnit%zu"), i + 1));
3954 wxString::Format(_T(
"InstDataMargin%zu"), i + 1));
3956 wxString::Format(_T(
"InstDataAlignment%zu"), i + 1));
3958 wxString::Format(_T(
"InstDataFormat%zu"), i + 1));
3959 pConf->DeleteEntry(wxString::Format(_T(
"InstDataFont%zu"), j + 1));
3960 pConf->DeleteEntry(wxString::Format(_T(
"InstDataColor%zu"), j + 1));
3961 pConf->DeleteEntry(wxString::Format(_T(
"InstLabelFont%zu"), j + 1));
3963 wxString::Format(_T(
"InstLabelColor%zu"), j + 1));
3964 pConf->DeleteEntry(wxString::Format(_T(
"InstSmallFont%zu"), j + 1));
3966 wxString::Format(_T(
"InstSmallColor%zu"), j + 1));
3968 wxString::Format(_T(
"TitleBackColor%zu"), i + 1));
3969 pConf->DeleteEntry(wxString::Format(_T(
"DataBackColor%zu"), i + 1));
3970 pConf->DeleteEntry(wxString::Format(_T(
"ArrowFirst%zu"), i + 1));
3971 pConf->DeleteEntry(wxString::Format(_T(
"ArrowSecond%zu"), i + 1));
3975 for (
size_t i = 0; i < (cont->m_aInstrumentPropertyList.GetCount());
3977 Inst = cont->m_aInstrumentPropertyList.Item(i);
3978 if (Inst->m_Listplace == (
int)j) {
3980 wxString::Format(_T(
"InstTitleFont%zu"), j + 1),
3981 Inst->m_USTitleFont.GetChosenFont().GetNativeFontInfoDesc());
3983 wxString::Format(_T(
"InstTitleColor%zu"), j + 1),
3984 Inst->m_USTitleFont.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3986 wxString::Format(_T(
"InstDataFont%zu"), j + 1),
3987 Inst->m_USDataFont.GetChosenFont().GetNativeFontInfoDesc());
3989 wxString::Format(_T(
"InstDataColor%zu"), j + 1),
3990 Inst->m_USDataFont.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3992 wxString::Format(_T(
"InstLabelFont%zu"), j + 1),
3993 Inst->m_USLabelFont.GetChosenFont().GetNativeFontInfoDesc());
3995 wxString::Format(_T(
"InstLabelColor%zu"), j + 1),
3996 Inst->m_USLabelFont.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3998 wxString::Format(_T(
"InstSmallFont%zu"), j + 1),
3999 Inst->m_USSmallFont.GetChosenFont().GetNativeFontInfoDesc());
4001 wxString::Format(_T(
"InstSmallColor%zu"), j + 1),
4002 Inst->m_USSmallFont.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
4004 wxString::Format(_T(
"TitleBackColor%zu"), j + 1),
4005 Inst->m_TitleBackgroundColour.GetAsString(wxC2S_HTML_SYNTAX));
4007 wxString::Format(_T(
"DataBackColor%zu"), j + 1),
4008 Inst->m_DataBackgroundColour.GetAsString(wxC2S_HTML_SYNTAX));
4010 wxString::Format(_T(
"ArrowFirst%zu"), j + 1),
4011 Inst->m_Arrow_First_Colour.GetAsString(wxC2S_HTML_SYNTAX));
4013 wxString::Format(_T(
"ArrowSecond%zu"), j + 1),
4014 Inst->m_Arrow_Second_Colour.GetAsString(wxC2S_HTML_SYNTAX));
4026void dashboard_pi::ApplyConfig(
void) {
4028 for (
size_t i = m_ArrayOfDashboardWindow.GetCount(); i > 0; i--) {
4030 int orient = (cont->m_sOrientation == _T(
"V") ? wxVERTICAL : wxHORIZONTAL);
4031 if (cont->m_bIsDeleted) {
4032 if (cont->m_pDashboardWindow) {
4033 m_pauimgr->DetachPane(cont->m_pDashboardWindow);
4034 cont->m_pDashboardWindow->Close();
4035 cont->m_pDashboardWindow->Destroy();
4036 cont->m_pDashboardWindow = NULL;
4038 m_ArrayOfDashboardWindow.Remove(cont);
4041 }
else if (!cont->m_pDashboardWindow) {
4045 cont->m_pDashboardWindow->SetInstrumentList(
4046 cont->m_aInstrumentList, &(cont->m_aInstrumentPropertyList));
4047 bool vertical = orient == wxVERTICAL;
4048 wxSize sz = cont->m_pDashboardWindow->GetMinSize();
4049 wxSize best = cont->m_conf_best_size;
4050 if (best.x < 100) best = sz;
4054 if (sz.x == 0) sz.IncTo(wxSize(160, 388));
4056 wxAuiPaneInfo p = wxAuiPaneInfo()
4057 .Name(cont->m_sName)
4058 .Caption(cont->m_sCaption)
4059 .CaptionVisible(
false)
4060 .TopDockable(!vertical)
4061 .BottomDockable(!vertical)
4062 .LeftDockable(vertical)
4063 .RightDockable(vertical)
4067 .FloatingPosition(100, 100)
4069 .Show(cont->m_bIsVisible)
4072 m_pauimgr->AddPane(cont->m_pDashboardWindow, p);
4079#ifdef __OCPN__ANDROID__
4080 wxAuiPaneInfo &pane = m_pauimgr->GetPane(cont->m_pDashboardWindow);
4081 pane.Dockable(
false);
4086 wxAuiPaneInfo &pane = m_pauimgr->GetPane(cont->m_pDashboardWindow);
4087 pane.Caption(cont->m_sCaption).Show(cont->m_bIsVisible);
4088 if (!cont->m_pDashboardWindow->isInstrumentListEqual(
4089 cont->m_aInstrumentList)) {
4090 cont->m_pDashboardWindow->SetInstrumentList(
4091 cont->m_aInstrumentList, &(cont->m_aInstrumentPropertyList));
4092 wxSize sz = cont->m_pDashboardWindow->GetMinSize();
4093 pane.MinSize(sz).BestSize(sz).FloatingSize(sz);
4095 if (cont->m_pDashboardWindow->GetSizerOrientation() != orient) {
4096 cont->m_pDashboardWindow->ChangePaneOrientation(orient,
false);
4100 m_pauimgr->Update();
4103 double sogFC = g_iDashSOGDamp ? 1.0 / (2.0 * g_iDashSOGDamp) : 0.0;
4104 double cogFC = g_iDashCOGDamp ? 1.0 / (2.0 * g_iDashCOGDamp) : 0.0;
4105 double awaFC = g_iDashAWADamp ? 1.0 / (2.0 * g_iDashAWADamp) : 0.0;
4106 double awsFC = g_iDashAWSDamp ? 1.0 / (2.0 * g_iDashAWSDamp) : 0.0;
4108 if (abs(sogFC - mSOGFilter.getFc()) > 1e-6) {
4109 mSOGFilter.setFC(sogFC);
4111 if (abs(cogFC - mCOGFilter.getFc()) > 1e-6) {
4112 mCOGFilter.setFC(cogFC);
4114 if (abs(awaFC - mAWAFilter.getFc()) > 1e-6) {
4115 mAWAFilter.setFC(awaFC);
4117 if (abs(awsFC - mAWSFilter.getFc()) > 1e-6) {
4118 mAWSFilter.setFC(awsFC);
4122void dashboard_pi::PopulateContextMenu(wxMenu *menu) {
4124 wxMenuItem *visItem = 0;
4125 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
4127 wxMenuItem *item = menu->AppendCheckItem(i + 1, cont->m_sCaption);
4128 item->Check(cont->m_bIsVisible);
4129 if (cont->m_bIsVisible) {
4134 if (nvis == 1 && visItem) visItem->Enable(
false);
4137void dashboard_pi::ShowDashboard(
size_t id,
bool visible) {
4138 if (
id < m_ArrayOfDashboardWindow.GetCount()) {
4140 m_pauimgr->GetPane(cont->m_pDashboardWindow).Show(visible);
4141 cont->m_bIsVisible = visible;
4142 cont->m_bPersVisible = visible;
4143 m_pauimgr->Update();
4151DashboardPreferencesDialog::DashboardPreferencesDialog(
4152 wxWindow *parent, wxWindowID
id, wxArrayOfDashboard config)
4153 : wxDialog(parent, id, _(
"Dashboard preferences"), wxDefaultPosition,
4154 wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
4160 int display_width, display_height;
4161 wxDisplaySize(&display_width, &display_height);
4164 wxFileName::GetPathSeparator() + _T(
"dashboard_pi") +
4165 wxFileName::GetPathSeparator() + _T(
"data") +
4166 wxFileName::GetPathSeparator();
4168 Connect(wxEVT_CLOSE_WINDOW,
4169 wxCloseEventHandler(DashboardPreferencesDialog::OnCloseDialog), NULL,
4173 m_Config = wxArrayOfDashboard(config);
4175 int border_size = 2;
4177 wxBoxSizer *itemBoxSizerMainPanel =
new wxBoxSizer(wxVERTICAL);
4178 SetSizer(itemBoxSizerMainPanel);
4180 wxWindow *dparent =
this;
4181 wxScrolledWindow *scrollWin =
new wxScrolledWindow(
4182 this, wxID_ANY, wxDefaultPosition, wxSize(-1, -1), wxVSCROLL | wxHSCROLL);
4184 scrollWin->SetScrollRate(1, 1);
4185 itemBoxSizerMainPanel->Add(scrollWin, 1, wxEXPAND | wxALL, 0);
4187 dparent = scrollWin;
4189 wxBoxSizer *itemBoxSizer2 =
new wxBoxSizer(wxVERTICAL);
4190 scrollWin->SetSizer(itemBoxSizer2);
4192 auto *DialogButtonSizer =
new wxStdDialogButtonSizer();
4193 DialogButtonSizer->AddButton(
new wxButton(
this, wxID_OK));
4194 DialogButtonSizer->AddButton(
new wxButton(
this, wxID_CANCEL));
4195 wxButton *help_btn =
new wxButton(
this, wxID_HELP);
4196 help_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [&](wxCommandEvent) {
4198 Manual(
this, datadir.ToStdString()).Launch(
"Dashboard");
4200 DialogButtonSizer->AddButton(help_btn);
4201 DialogButtonSizer->Realize();
4203 itemBoxSizerMainPanel->Add(DialogButtonSizer, 0, wxALIGN_RIGHT | wxALL, 5);
4205 wxNotebook *itemNotebook =
new wxNotebook(
4206 dparent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP);
4207 itemBoxSizer2->Add(itemNotebook, 0, wxALL | wxEXPAND, border_size);
4209 wxPanel *itemPanelNotebook01 =
4210 new wxPanel(itemNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
4212 wxFlexGridSizer *itemFlexGridSizer01 =
new wxFlexGridSizer(2);
4213 itemFlexGridSizer01->AddGrowableCol(1);
4214 itemPanelNotebook01->SetSizer(itemFlexGridSizer01);
4215 itemNotebook->AddPage(itemPanelNotebook01, _(
"Dashboard"));
4217 wxBoxSizer *itemBoxSizer01 =
new wxBoxSizer(wxVERTICAL);
4218 itemFlexGridSizer01->Add(itemBoxSizer01, 1, wxEXPAND | wxTOP | wxLEFT,
4222 int imageRefSize = GetCharWidth() * 4;
4224 wxImageList *imglist1 =
new wxImageList(imageRefSize, imageRefSize,
true, 1);
4226 wxBitmap bmDashBoard;
4228 wxString filename = shareLocn + _T(
"Dashboard.svg");
4231 wxImage dash1 = wxBitmap(*_img_dashboard_pi).ConvertToImage();
4233 dash1.Scale(imageRefSize, imageRefSize, wxIMAGE_QUALITY_HIGH);
4234 bmDashBoard = wxBitmap(dash1s);
4237 imglist1->Add(bmDashBoard);
4239 m_pListCtrlDashboards =
4240 new wxListCtrl(itemPanelNotebook01, wxID_ANY, wxDefaultPosition,
4241 wxSize(imageRefSize * 3 / 2, 200),
4242 wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL);
4244 m_pListCtrlDashboards->AssignImageList(imglist1, wxIMAGE_LIST_SMALL);
4245 m_pListCtrlDashboards->InsertColumn(0, _T(
""));
4246 m_pListCtrlDashboards->Connect(
4247 wxEVT_COMMAND_LIST_ITEM_SELECTED,
4248 wxListEventHandler(DashboardPreferencesDialog::OnDashboardSelected), NULL,
4250 m_pListCtrlDashboards->Connect(
4251 wxEVT_COMMAND_LIST_ITEM_DESELECTED,
4252 wxListEventHandler(DashboardPreferencesDialog::OnDashboardSelected), NULL,
4254 itemBoxSizer01->Add(m_pListCtrlDashboards, 1, wxEXPAND, 0);
4256 wxBoxSizer *itemBoxSizer02 =
new wxBoxSizer(wxHORIZONTAL);
4257 itemBoxSizer01->Add(itemBoxSizer02);
4259 wxBitmap bmPlus, bmMinus;
4260 int bmSize = imageRefSize * 100 / 275;
4262#ifdef __OCPN__ANDROID__
4263 bmSize = imageRefSize / 2;
4270 wxImage plus1 = wxBitmap(*_img_plus).ConvertToImage();
4271 wxImage plus1s = plus1.Scale(bmSize, bmSize, wxIMAGE_QUALITY_HIGH);
4272 bmPlus = wxBitmap(plus1s);
4274 wxImage minus1 = wxBitmap(*_img_minus).ConvertToImage();
4275 wxImage minus1s = minus1.Scale(bmSize, bmSize, wxIMAGE_QUALITY_HIGH);
4276 bmMinus = wxBitmap(minus1s);
4279 m_pButtonAddDashboard =
new wxBitmapButton(
4280 itemPanelNotebook01, wxID_ANY, bmPlus, wxDefaultPosition, wxDefaultSize);
4281 itemBoxSizer02->Add(m_pButtonAddDashboard, 0, wxALIGN_CENTER, 2);
4282 m_pButtonAddDashboard->Connect(
4283 wxEVT_COMMAND_BUTTON_CLICKED,
4284 wxCommandEventHandler(DashboardPreferencesDialog::OnDashboardAdd), NULL,
4287 m_pButtonDeleteDashboard =
new wxBitmapButton(
4288 itemPanelNotebook01, wxID_ANY, bmMinus, wxDefaultPosition, wxDefaultSize);
4289 itemBoxSizer02->Add(m_pButtonDeleteDashboard, 0, wxALIGN_CENTER, 2);
4290 m_pButtonDeleteDashboard->Connect(
4291 wxEVT_COMMAND_BUTTON_CLICKED,
4292 wxCommandEventHandler(DashboardPreferencesDialog::OnDashboardDelete),
4296 new wxPanel(itemPanelNotebook01, wxID_ANY, wxDefaultPosition,
4297 wxDefaultSize, wxBORDER_SUNKEN);
4298 itemFlexGridSizer01->Add(m_pPanelDashboard, 1, wxEXPAND | wxTOP | wxRIGHT,
4301 wxBoxSizer *itemBoxSizer03 =
new wxBoxSizer(wxVERTICAL);
4302 m_pPanelDashboard->SetSizer(itemBoxSizer03);
4304 wxStaticBox *itemStaticBox02 =
4305 new wxStaticBox(m_pPanelDashboard, wxID_ANY, _(
"Dashboard"));
4306 wxStaticBoxSizer *itemStaticBoxSizer02 =
4307 new wxStaticBoxSizer(itemStaticBox02, wxHORIZONTAL);
4308 itemBoxSizer03->Add(itemStaticBoxSizer02, 0, wxEXPAND | wxALL, border_size);
4309 wxFlexGridSizer *itemFlexGridSizer =
new wxFlexGridSizer(2);
4310 itemFlexGridSizer->AddGrowableCol(1);
4311 itemStaticBoxSizer02->Add(itemFlexGridSizer, 1, wxEXPAND | wxALL, 0);
4313 m_pCheckBoxIsVisible =
4314 new wxCheckBox(m_pPanelDashboard, wxID_ANY, _(
"show this dashboard"),
4315 wxDefaultPosition, wxDefaultSize, 0);
4316 m_pCheckBoxIsVisible->SetMinSize(wxSize(25 * GetCharWidth(), -1));
4318 itemFlexGridSizer->Add(m_pCheckBoxIsVisible, 0, wxEXPAND | wxALL,
4320 wxStaticText *itemDummy01 =
4321 new wxStaticText(m_pPanelDashboard, wxID_ANY, _T(
""));
4322 itemFlexGridSizer->Add(itemDummy01, 0, wxEXPAND | wxALL, border_size);
4324 wxStaticText *itemStaticText01 =
4325 new wxStaticText(m_pPanelDashboard, wxID_ANY, _(
"Caption:"),
4326 wxDefaultPosition, wxDefaultSize, 0);
4327 itemFlexGridSizer->Add(itemStaticText01, 0, wxEXPAND | wxALL, border_size);
4328 m_pTextCtrlCaption =
new wxTextCtrl(m_pPanelDashboard, wxID_ANY, _T(
""),
4329 wxDefaultPosition, wxDefaultSize);
4330 m_pCheckBoxIsVisible->SetMinSize(wxSize(30 * GetCharWidth(), -1));
4331 itemFlexGridSizer->Add(m_pTextCtrlCaption, 0, wxALIGN_RIGHT | wxALL,
4334 wxStaticText *itemStaticText02 =
4335 new wxStaticText(m_pPanelDashboard, wxID_ANY, _(
"Orientation:"),
4336 wxDefaultPosition, wxDefaultSize, 0);
4337 itemFlexGridSizer->Add(itemStaticText02, 0, wxEXPAND | wxALL, border_size);
4338 m_pChoiceOrientation =
new wxChoice(m_pPanelDashboard, wxID_ANY,
4339 wxDefaultPosition, wxDefaultSize);
4340 m_pChoiceOrientation->SetMinSize(wxSize(15 * GetCharWidth(), -1));
4341 m_pChoiceOrientation->Append(_(
"Vertical"));
4342 m_pChoiceOrientation->Append(_(
"Horizontal"));
4343 itemFlexGridSizer->Add(m_pChoiceOrientation, 0, wxALIGN_RIGHT | wxALL,
4348 wxImageList *imglist =
4349 new wxImageList(instImageRefSize, instImageRefSize,
true, 2);
4351 wxBitmap bmDial, bmInst;
4356 instImageRefSize, instImageRefSize);
4358 wxImage dial1 = wxBitmap(*_img_dial).ConvertToImage();
4360 dial1.Scale(instImageRefSize, instImageRefSize, wxIMAGE_QUALITY_HIGH);
4361 bmDial = wxBitmap(dial1);
4363 wxImage inst1 = wxBitmap(*_img_instrument).ConvertToImage();
4365 inst1.Scale(instImageRefSize, instImageRefSize, wxIMAGE_QUALITY_HIGH);
4366 bmInst = wxBitmap(inst1s);
4369 imglist->Add(bmInst);
4370 imglist->Add(bmDial);
4372 wxStaticBox *itemStaticBox03 =
4373 new wxStaticBox(m_pPanelDashboard, wxID_ANY, _(
"Instruments"));
4374 wxStaticBoxSizer *itemStaticBoxSizer03 =
4375 new wxStaticBoxSizer(itemStaticBox03, wxHORIZONTAL);
4376 itemBoxSizer03->Add(itemStaticBoxSizer03, 1, wxEXPAND | wxALL, border_size);
4379 wxSize list_size = wxSize(-1, dsize.y * 35 / 100);
4382 int xsize = GetCharWidth() * 30;
4383 list_size = wxSize(xsize, dsize.y * 50 / 100);
4386 m_pListCtrlInstruments =
4387 new wxListCtrl(m_pPanelDashboard, wxID_ANY, wxDefaultPosition, list_size,
4388 wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL);
4390 itemStaticBoxSizer03->Add(m_pListCtrlInstruments, 1, wxEXPAND | wxALL,
4392 m_pListCtrlInstruments->AssignImageList(imglist, wxIMAGE_LIST_SMALL);
4393 m_pListCtrlInstruments->InsertColumn(0, _(
"Instruments"));
4394 m_pListCtrlInstruments->Connect(
4395 wxEVT_COMMAND_LIST_ITEM_SELECTED,
4396 wxListEventHandler(DashboardPreferencesDialog::OnInstrumentSelected),
4398 m_pListCtrlInstruments->Connect(
4399 wxEVT_COMMAND_LIST_ITEM_DESELECTED,
4400 wxListEventHandler(DashboardPreferencesDialog::OnInstrumentSelected),
4403 wxBoxSizer *itemBoxSizer04 =
new wxBoxSizer(wxVERTICAL);
4404 itemStaticBoxSizer03->Add(itemBoxSizer04, 0, wxALIGN_TOP | wxALL,
4406 m_pButtonAdd =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Add"),
4407 wxDefaultPosition, wxSize(-1, -1));
4408 itemBoxSizer04->Add(m_pButtonAdd, 0, wxEXPAND | wxALL, border_size);
4409 m_pButtonAdd->Connect(
4410 wxEVT_COMMAND_BUTTON_CLICKED,
4411 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentAdd), NULL,
4415 m_pButtonEdit =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Edit"),
4416 wxDefaultPosition, wxDefaultSize);
4417 itemBoxSizer04->Add(m_pButtonEdit, 0, wxEXPAND | wxALL, border_size);
4418 m_pButtonEdit->Connect(
4419 wxEVT_COMMAND_BUTTON_CLICKED,
4420 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentEdit), NULL,
4431 m_pButtonDelete =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Delete"),
4432 wxDefaultPosition, wxSize(-1, -1));
4433 itemBoxSizer04->Add(m_pButtonDelete, 0, wxEXPAND | wxALL, border_size);
4434 m_pButtonDelete->Connect(
4435 wxEVT_COMMAND_BUTTON_CLICKED,
4436 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentDelete),
4438 itemBoxSizer04->AddSpacer(10);
4439 m_pButtonUp =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Up"),
4440 wxDefaultPosition, wxDefaultSize);
4441 itemBoxSizer04->Add(m_pButtonUp, 0, wxEXPAND | wxALL, border_size);
4442 m_pButtonUp->Connect(
4443 wxEVT_COMMAND_BUTTON_CLICKED,
4444 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentUp), NULL,
4446 m_pButtonDown =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Down"),
4447 wxDefaultPosition, wxDefaultSize);
4448 itemBoxSizer04->Add(m_pButtonDown, 0, wxEXPAND | wxALL, border_size);
4449 m_pButtonDown->Connect(
4450 wxEVT_COMMAND_BUTTON_CLICKED,
4451 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentDown), NULL,
4454 wxPanel *itemPanelNotebook02 =
4455 new wxPanel(itemNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
4457 wxBoxSizer *itemBoxSizer05 =
new wxBoxSizer(wxVERTICAL);
4458 itemPanelNotebook02->SetSizer(itemBoxSizer05);
4459 itemNotebook->AddPage(itemPanelNotebook02, _(
"Appearance"));
4461 wxStaticBox *itemStaticBox01 =
4462 new wxStaticBox(itemPanelNotebook02, wxID_ANY, _(
"Fonts"));
4463 wxStaticBoxSizer *itemStaticBoxSizer01 =
4464 new wxStaticBoxSizer(itemStaticBox01, wxHORIZONTAL);
4465 itemBoxSizer05->Add(itemStaticBoxSizer01, 0, wxEXPAND | wxALL, border_size);
4466 wxFlexGridSizer *itemFlexGridSizer03 =
new wxFlexGridSizer(2);
4467 itemFlexGridSizer03->AddGrowableCol(1);
4468 itemStaticBoxSizer01->Add(itemFlexGridSizer03, 1, wxEXPAND | wxALL, 0);
4470 wxStaticText *itemStaticText04 =
4471 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Title:"),
4472 wxDefaultPosition, wxDefaultSize, 0);
4473 itemFlexGridSizer03->Add(itemStaticText04, 0, wxEXPAND | wxALL, border_size);
4475 m_pFontPickerTitle =
4476 new wxFontPickerCtrl(itemPanelNotebook02, wxID_ANY, g_USFontTitle,
4477 wxDefaultPosition, wxDefaultSize);
4478 itemFlexGridSizer03->Add(m_pFontPickerTitle, 0, wxALIGN_RIGHT | wxALL, 0);
4480 wxStaticText *itemStaticText05 =
4481 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Data:"),
4482 wxDefaultPosition, wxDefaultSize, 0);
4483 itemFlexGridSizer03->Add(itemStaticText05, 0, wxEXPAND | wxALL, border_size);
4485 new wxFontPickerCtrl(itemPanelNotebook02, wxID_ANY, g_USFontData,
4486 wxDefaultPosition, wxDefaultSize);
4487 itemFlexGridSizer03->Add(m_pFontPickerData, 0, wxALIGN_RIGHT | wxALL, 0);
4489 wxStaticText *itemStaticText06 =
4490 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Label:"),
4491 wxDefaultPosition, wxDefaultSize, 0);
4492 itemFlexGridSizer03->Add(itemStaticText06, 0, wxEXPAND | wxALL, border_size);
4493 m_pFontPickerLabel =
4494 new wxFontPickerCtrl(itemPanelNotebook02, wxID_ANY, g_USFontLabel,
4495 wxDefaultPosition, wxDefaultSize);
4496 itemFlexGridSizer03->Add(m_pFontPickerLabel, 0, wxALIGN_RIGHT | wxALL, 0);
4498 wxStaticText *itemStaticText07 =
4499 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Small:"),
4500 wxDefaultPosition, wxDefaultSize, 0);
4501 itemFlexGridSizer03->Add(itemStaticText07, 0, wxEXPAND | wxALL, border_size);
4502 m_pFontPickerSmall =
4503 new wxFontPickerCtrl(itemPanelNotebook02, wxID_ANY, g_USFontSmall,
4504 wxDefaultPosition, wxDefaultSize);
4505 itemFlexGridSizer03->Add(m_pFontPickerSmall, 0, wxALIGN_RIGHT | wxALL, 0);
4508 wxStaticText *itemStaticText80 =
4509 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Reset:"),
4510 wxDefaultPosition, wxDefaultSize, 0);
4511 itemFlexGridSizer03->Add(itemStaticText80, 0, wxEXPAND | wxALL, border_size);
4513 m_pButtondefaultFont =
new wxButton(itemPanelNotebook02, wxID_ANY,
4514 _(
"Set dashboard default fonts"),
4515 wxDefaultPosition, wxSize(-1, -1));
4516 itemFlexGridSizer03->Add(m_pButtondefaultFont, 0, wxALIGN_RIGHT | wxALL, 0);
4517 m_pButtondefaultFont->Connect(
4518 wxEVT_COMMAND_BUTTON_CLICKED,
4519 wxCommandEventHandler(DashboardPreferencesDialog::OnDashboarddefaultFont),
4522 wxStaticBox *itemStaticBox04 =
new wxStaticBox(itemPanelNotebook02, wxID_ANY,
4523 _(
"Units, Ranges, Formats"));
4524 wxStaticBoxSizer *itemStaticBoxSizer04 =
4525 new wxStaticBoxSizer(itemStaticBox04, wxHORIZONTAL);
4526 itemBoxSizer05->Add(itemStaticBoxSizer04, 0, wxEXPAND | wxALL, border_size);
4527 wxFlexGridSizer *itemFlexGridSizer04 =
new wxFlexGridSizer(2);
4528 itemFlexGridSizer04->AddGrowableCol(1);
4529 itemStaticBoxSizer04->Add(itemFlexGridSizer04, 1, wxEXPAND | wxALL, 0);
4530 wxStaticText *itemStaticText08 =
new wxStaticText(
4531 itemPanelNotebook02, wxID_ANY, _(
"Speedometer max value:"),
4532 wxDefaultPosition, wxDefaultSize, 0);
4533 itemFlexGridSizer04->Add(itemStaticText08, 0, wxEXPAND | wxALL, border_size);
4534 m_pSpinSpeedMax =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4535 wxDefaultPosition, wxDefaultSize,
4536 wxSP_ARROW_KEYS, 10, 100, g_iDashSpeedMax);
4537 itemFlexGridSizer04->Add(m_pSpinSpeedMax, 0, wxALIGN_RIGHT | wxALL, 0);
4539 wxStaticText *itemStaticText10 =
new wxStaticText(
4540 itemPanelNotebook02, wxID_ANY, _(
"Speed Over Ground Damping Factor:"),
4541 wxDefaultPosition, wxDefaultSize, 0);
4542 itemFlexGridSizer04->Add(itemStaticText10, 0, wxEXPAND | wxALL, border_size);
4543 m_pSpinSOGDamp =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4544 wxDefaultPosition, wxDefaultSize,
4545 wxSP_ARROW_KEYS, 0, 100, g_iDashSOGDamp);
4546 itemFlexGridSizer04->Add(m_pSpinSOGDamp, 0, wxALIGN_RIGHT | wxALL, 0);
4548 wxStaticText *itemStaticText11 =
4549 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"COG Damping Factor:"),
4550 wxDefaultPosition, wxDefaultSize, 0);
4551 itemFlexGridSizer04->Add(itemStaticText11, 0, wxEXPAND | wxALL, border_size);
4552 m_pSpinCOGDamp =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4553 wxDefaultPosition, wxDefaultSize,
4554 wxSP_ARROW_KEYS, 0, 100, g_iDashCOGDamp);
4555 itemFlexGridSizer04->Add(m_pSpinCOGDamp, 0, wxALIGN_RIGHT | wxALL, 0);
4557 wxStaticText *itemStaticText13 =
new wxStaticText(
4558 itemPanelNotebook02, wxID_ANY, _(
"Wind speed Damping Factor:"),
4559 wxDefaultPosition, wxDefaultSize, 0);
4560 itemFlexGridSizer04->Add(itemStaticText13, 0, wxEXPAND | wxALL, border_size);
4561 m_pSpinAWSDamp =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4562 wxDefaultPosition, wxDefaultSize,
4563 wxSP_ARROW_KEYS, 0, 100, g_iDashAWSDamp);
4564 itemFlexGridSizer04->Add(m_pSpinAWSDamp, 0, wxALIGN_RIGHT | wxALL, 0);
4566 wxStaticText *itemStaticText14 =
new wxStaticText(
4567 itemPanelNotebook02, wxID_ANY, _(
"Wind angle Damping Factor:"),
4568 wxDefaultPosition, wxDefaultSize, 0);
4569 itemFlexGridSizer04->Add(itemStaticText14, 0, wxEXPAND | wxALL, border_size);
4570 m_pSpinAWADamp =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4571 wxDefaultPosition, wxDefaultSize,
4572 wxSP_ARROW_KEYS, 0, 100, g_iDashAWADamp);
4573 itemFlexGridSizer04->Add(m_pSpinAWADamp, 0, wxALIGN_RIGHT | wxALL, 0);
4575 wxStaticText *itemStaticText12 =
new wxStaticText(
4576 itemPanelNotebook02, wxID_ANY, _(
"Local Time Offset From UTC:"),
4577 wxDefaultPosition, wxDefaultSize, 0);
4578 itemFlexGridSizer04->Add(itemStaticText12, 0, wxEXPAND | wxALL, border_size);
4579 wxString m_UTCOffsetChoices[] = {
4580 _T(
"-12:00" ), _T(
"-11:30" ), _T(
"-11:00" ), _T(
"-10:30" ),
4581 _T(
"-10:00" ), _T(
"-09:30" ), _T(
"-09:00" ), _T(
"-08:30" ),
4582 _T(
"-08:00" ), _T(
"-07:30" ), _T(
"-07:00" ), _T(
"-06:30" ),
4583 _T(
"-06:00" ), _T(
"-05:30" ), _T(
"-05:00" ), _T(
"-04:30" ),
4584 _T(
"-04:00" ), _T(
"-03:30" ), _T(
"-03:00" ), _T(
"-02:30" ),
4585 _T(
"-02:00" ), _T(
"-01:30" ), _T(
"-01:00" ), _T(
"-00:30" ),
4586 _T(
" 00:00" ), _T(
" 00:30" ), _T(
" 01:00" ), _T(
" 01:30" ),
4587 _T(
" 02:00" ), _T(
" 02:30" ), _T(
" 03:00" ), _T(
" 03:30" ),
4588 _T(
" 04:00" ), _T(
" 04:30" ), _T(
" 05:00" ), _T(
" 05:30" ),
4589 _T(
" 06:00" ), _T(
" 06:30" ), _T(
" 07:00" ), _T(
" 07:30" ),
4590 _T(
" 08:00" ), _T(
" 08:30" ), _T(
" 09:00" ), _T(
" 09:30" ),
4591 _T(
" 10:00" ), _T(
" 10:30" ), _T(
" 11:00" ), _T(
" 11:30" ),
4593 int m_UTCOffsetNChoices =
sizeof(m_UTCOffsetChoices) /
sizeof(wxString);
4594 m_pChoiceUTCOffset =
4595 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition,
4596 wxDefaultSize, m_UTCOffsetNChoices, m_UTCOffsetChoices, 0);
4597 m_pChoiceUTCOffset->SetSelection(g_iUTCOffset + 24);
4598 itemFlexGridSizer04->Add(m_pChoiceUTCOffset, 0, wxALIGN_RIGHT | wxALL, 0);
4600 wxStaticText *itemStaticText09 =
4601 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Boat speed units:"),
4602 wxDefaultPosition, wxDefaultSize, 0);
4603 itemFlexGridSizer04->Add(itemStaticText09, 0, wxEXPAND | wxALL, border_size);
4604 wxString m_SpeedUnitChoices[] = {_(
"Honor OpenCPN settings"), _(
"Kts"),
4605 _(
"mph"), _(
"km/h"), _(
"m/s")};
4606 int m_SpeedUnitNChoices =
sizeof(m_SpeedUnitChoices) /
sizeof(wxString);
4607 wxSize szSpeedUnit = wxDefaultSize;
4608 m_pChoiceSpeedUnit =
4609 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition,
4610 szSpeedUnit, m_SpeedUnitNChoices, m_SpeedUnitChoices, 0);
4611 for (
auto const &iUnit : m_SpeedUnitChoices) {
4612 szSpeedUnit.IncTo(m_pChoiceSpeedUnit->GetTextExtent(iUnit));
4614 m_pChoiceSpeedUnit->SetSize(szSpeedUnit);
4615 m_pChoiceSpeedUnit->SetSelection(g_iDashSpeedUnit + 1);
4616 itemFlexGridSizer04->Add(m_pChoiceSpeedUnit, 0, wxALIGN_RIGHT | wxALL, 0);
4618 wxStaticText *itemStaticTextDepthU =
4619 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Depth units:"),
4620 wxDefaultPosition, wxDefaultSize, 0);
4621 itemFlexGridSizer04->Add(itemStaticTextDepthU, 0, wxEXPAND | wxALL,
4623 wxString m_DepthUnitChoices[] = {_(
"Meters"), _(
"Feet"), _(
"Fathoms"),
4624 _(
"Inches"), _(
"Centimeters")};
4625 int m_DepthUnitNChoices =
sizeof(m_DepthUnitChoices) /
sizeof(wxString);
4626 wxSize szDepthUnit = wxDefaultSize;
4627 m_pChoiceDepthUnit =
4628 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition,
4629 szDepthUnit, m_DepthUnitNChoices, m_DepthUnitChoices, 0);
4630 for (
auto const &iUnit : m_DepthUnitChoices) {
4631 szDepthUnit.IncTo(m_pChoiceDepthUnit->GetTextExtent(iUnit));
4633 m_pChoiceDepthUnit->SetSize(szDepthUnit);
4634 m_pChoiceDepthUnit->SetSelection(g_iDashDepthUnit - 3);
4635 itemFlexGridSizer04->Add(m_pChoiceDepthUnit, 0, wxALIGN_RIGHT | wxALL, 0);
4636 wxString dMess = wxString::Format(_(
"Depth Offset (%s):"),
4637 m_DepthUnitChoices[g_iDashDepthUnit - 3]);
4638 wxStaticText *itemStaticDepthO =
4639 new wxStaticText(itemPanelNotebook02, wxID_ANY, dMess, wxDefaultPosition,
4642 switch (g_iDashDepthUnit - 3) {
4644 DepthOffset = g_dDashDBTOffset * 3.2808399;
4647 DepthOffset = g_dDashDBTOffset * 0.54680665;
4650 DepthOffset = g_dDashDBTOffset * 39.3700787;
4653 DepthOffset = g_dDashDBTOffset * 100;
4656 DepthOffset = g_dDashDBTOffset;
4658 itemFlexGridSizer04->Add(itemStaticDepthO, 0, wxEXPAND | wxALL, border_size);
4659 m_pSpinDBTOffset =
new wxSpinCtrlDouble(
4660 itemPanelNotebook02, wxID_ANY, wxEmptyString, wxDefaultPosition,
4661 wxDefaultSize, wxSP_ARROW_KEYS, -100, 100, DepthOffset, 0.1);
4662 itemFlexGridSizer04->Add(m_pSpinDBTOffset, 0, wxALIGN_RIGHT | wxALL, 0);
4664 wxStaticText *itemStaticText0b =
4665 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Distance units:"),
4666 wxDefaultPosition, wxDefaultSize, 0);
4667 itemFlexGridSizer04->Add(itemStaticText0b, 0, wxEXPAND | wxALL, border_size);
4668 wxString m_DistanceUnitChoices[] = {_(
"Honor OpenCPN settings"),
4669 _(
"Nautical miles"), _(
"Statute miles"),
4670 _(
"Kilometers"), _(
"Meters")};
4671 wxSize szDistanceUnit = wxDefaultSize;
4672 int m_DistanceUnitNChoices =
sizeof(m_DistanceUnitChoices) /
sizeof(wxString);
4673 m_pChoiceDistanceUnit =
new wxChoice(
4674 itemPanelNotebook02, wxID_ANY, wxDefaultPosition, szDistanceUnit,
4675 m_DistanceUnitNChoices, m_DistanceUnitChoices, 0);
4676 for (
auto const &iUnit : m_DistanceUnitChoices) {
4677 szDistanceUnit.IncTo(m_pChoiceDistanceUnit->GetTextExtent(iUnit));
4679 m_pChoiceDistanceUnit->SetSize(szDistanceUnit);
4680 m_pChoiceDistanceUnit->SetSelection(g_iDashDistanceUnit + 1);
4681 itemFlexGridSizer04->Add(m_pChoiceDistanceUnit, 0, wxALIGN_RIGHT | wxALL, 0);
4682 m_pChoiceDistanceUnit->Connect(
4683 wxEVT_COMMAND_CHOICE_SELECTED,
4684 wxCommandEventHandler(DashboardPreferencesDialog::OnDistanceUnitSelect),
4687 wxStaticText *itemStaticText0a =
4688 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Wind speed units:"),
4689 wxDefaultPosition, wxDefaultSize, 0);
4690 itemFlexGridSizer04->Add(itemStaticText0a, 0, wxEXPAND | wxALL, border_size);
4691 wxString m_WSpeedUnitChoices[] = {_(
"Kts"), _(
"mph"), _(
"km/h"), _(
"m/s")};
4692 int m_WSpeedUnitNChoices =
sizeof(m_WSpeedUnitChoices) /
sizeof(wxString);
4693 wxSize szWSpeedUnit = wxDefaultSize;
4694 m_pChoiceWindSpeedUnit =
4695 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition,
4696 szWSpeedUnit, m_WSpeedUnitNChoices, m_WSpeedUnitChoices, 0);
4697 for (
auto const &iUnit : m_WSpeedUnitChoices) {
4698 szWSpeedUnit.IncTo(m_pChoiceWindSpeedUnit->GetTextExtent(iUnit));
4700 m_pChoiceWindSpeedUnit->SetSize(szWSpeedUnit);
4701 m_pChoiceWindSpeedUnit->SetSelection(g_iDashWindSpeedUnit);
4702 itemFlexGridSizer04->Add(m_pChoiceWindSpeedUnit, 0, wxALIGN_RIGHT | wxALL, 0);
4704 wxStaticText *itemStaticText0c =
4705 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Temperature units:"),
4706 wxDefaultPosition, wxDefaultSize, 0);
4707 itemFlexGridSizer04->Add(itemStaticText0c, 0, wxEXPAND | wxALL, border_size);
4708 wxString m_TempUnitChoices[] = {_(
"Celsius"), _(
"Fahrenheit"), _(
"Kelvin")};
4709 int m_TempUnitNChoices =
sizeof(m_TempUnitChoices) /
sizeof(wxString);
4710 wxSize szTempUnit = wxDefaultSize;
4712 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition, szTempUnit,
4713 m_TempUnitNChoices, m_TempUnitChoices, 0);
4714 for (
auto const &iUnit : m_TempUnitChoices) {
4715 szTempUnit.IncTo(m_pChoiceTempUnit->GetTextExtent(iUnit));
4717 m_pChoiceTempUnit->SetSize(szTempUnit);
4718 m_pChoiceTempUnit->SetSelection(g_iDashTempUnit);
4719 itemFlexGridSizer04->Add(m_pChoiceTempUnit, 0, wxALIGN_RIGHT | wxALL, 0);
4723 wxStaticBox *itemStaticBox05 =
4724 new wxStaticBox(itemPanelNotebook02, wxID_ANY, _(
"Other selections"));
4725 wxStaticBoxSizer *itemStaticBoxSizer05 =
4726 new wxStaticBoxSizer(itemStaticBox05, wxHORIZONTAL);
4727 itemBoxSizer05->Add(itemStaticBoxSizer05, 0, wxEXPAND | wxALL, border_size);
4729 wxFlexGridSizer *itemFlexGridSizer05 =
new wxFlexGridSizer(3);
4730 itemFlexGridSizer05->AddGrowableCol(1);
4731 itemStaticBoxSizer05->Add(itemFlexGridSizer05, 1, wxEXPAND | wxALL, 0);
4733 m_pUseInternSumLog =
new wxCheckBox(itemPanelNotebook02, wxID_ANY,
4734 _(
"Use internal Sumlog.") +
" " +
4735 _(
"Enter new value if desired"));
4736 itemFlexGridSizer05->Add(m_pUseInternSumLog, 1, wxALIGN_LEFT, border_size);
4737 m_pUseInternSumLog->SetValue(g_bUseInternSumLog);
4740 new wxStaticText(itemPanelNotebook02, wxID_ANY,
4742 wxDefaultPosition, wxDefaultSize, 0);
4743 itemFlexGridSizer05->Add(m_SumLogUnit, 1, wxALIGN_RIGHT, 0);
4745 m_pSumLogValue =
new wxTextCtrl(itemPanelNotebook02, wxID_ANY,
"");
4746 itemFlexGridSizer05->Add(m_pSumLogValue, 1, wxALIGN_LEFT, 1);
4747 m_pSumLogValue->SetValue(wxString::Format(
4750 m_pUseTrueWinddata =
new wxCheckBox(itemPanelNotebook02, wxID_ANY,
4751 _(
"Use N2K & SignalK true wind data over "
4752 "ground.\n(Instead of through water)"));
4753 itemFlexGridSizer05->Add(m_pUseTrueWinddata, 1, wxALIGN_LEFT, border_size);
4754 m_pUseTrueWinddata->SetValue(g_bDBtrueWindGround);
4758 wxStaticBox *itemStaticBox05 =
4759 new wxStaticBox(itemPanelNotebook02, wxID_ANY, _(
"Other selections"));
4760 wxStaticBoxSizer *itemStaticBoxSizer05 =
4761 new wxStaticBoxSizer(itemStaticBox05, wxHORIZONTAL);
4762 itemBoxSizer05->Add(itemStaticBoxSizer05, 0, wxEXPAND | wxALL, border_size);
4764 wxFlexGridSizer *itemFlexGridSizer05 =
new wxFlexGridSizer(2);
4765 itemFlexGridSizer05->AddGrowableCol(1);
4766 itemStaticBoxSizer05->Add(itemFlexGridSizer05, 1, wxEXPAND | wxALL, 0);
4768 m_pUseInternSumLog =
new wxCheckBox(itemPanelNotebook02, wxID_ANY,
4769 _(
"Use internal Sumlog.") +
" ");
4770 itemFlexGridSizer05->Add(m_pUseInternSumLog, 0, wxALIGN_LEFT, border_size);
4771 m_pUseInternSumLog->SetValue(g_bUseInternSumLog);
4772 itemFlexGridSizer05->AddSpacer(0);
4775 new wxStaticText(itemPanelNotebook02, wxID_ANY,
4776 " " + _(
"Enter new value if desired") +
" ",
4777 wxDefaultPosition, wxDefaultSize, 0);
4778 itemFlexGridSizer05->Add(xtext, 1, wxALIGN_LEFT, 0);
4779 itemFlexGridSizer05->AddSpacer(0);
4781 m_SumLogUnit =
new wxStaticText(
4782 itemPanelNotebook02, wxID_ANY,
4784 wxDefaultPosition, wxDefaultSize, 0);
4785 itemFlexGridSizer05->Add(m_SumLogUnit, 1, wxALIGN_RIGHT, 0);
4787 m_pSumLogValue =
new wxTextCtrl(itemPanelNotebook02, wxID_ANY,
"");
4788 itemFlexGridSizer05->Add(m_pSumLogValue, 1, wxALIGN_LEFT, 1);
4789 m_pSumLogValue->SetValue(wxString::Format(
4792 m_pUseTrueWinddata =
new wxCheckBox(itemPanelNotebook02, wxID_ANY,
4793 _(
"Use N2K & SignalK true wind data over "
4794 "ground.\n(Instead of through water)"));
4795 itemFlexGridSizer05->Add(m_pUseTrueWinddata, 1, wxALIGN_LEFT, border_size);
4796 m_pUseTrueWinddata->SetValue(g_bDBtrueWindGround);
4797 itemFlexGridSizer05->AddSpacer(0);
4799 auto xtext1 =
new wxStaticText(itemPanelNotebook02, wxID_ANY,
" ",
4800 wxDefaultPosition, wxDefaultSize, 0);
4801 itemFlexGridSizer05->Add(xtext1, 1, wxALIGN_LEFT, 0);
4802 itemFlexGridSizer05->AddSpacer(0);
4804 auto xtext2 =
new wxStaticText(itemPanelNotebook02, wxID_ANY,
" ",
4805 wxDefaultPosition, wxDefaultSize, 0);
4806 itemFlexGridSizer05->Add(xtext2, 1, wxALIGN_LEFT, 0);
4807 itemFlexGridSizer05->AddSpacer(0);
4812 for (
size_t i = 0; i < m_Config.GetCount(); i++) {
4813 m_pListCtrlDashboards->InsertItem(i, 0);
4815 m_pListCtrlDashboards->SetItemData(i, i);
4817 m_pListCtrlDashboards->SetColumnWidth(0, wxLIST_AUTOSIZE);
4819 m_pListCtrlDashboards->SetItemState(0, wxLIST_STATE_SELECTED,
4820 wxLIST_STATE_SELECTED);
4823 UpdateDashboardButtonsState();
4824 UpdateButtonsState();
4831 SetMaxSize(wxSize(display_width, display_height));
4834 if (display_height < 600) {
4835 if (g_dashPrefWidth > 0 && g_dashPrefHeight > 0)
4836 SetSize(wxSize(g_dashPrefWidth, g_dashPrefHeight));
4838 SetSize(wxSize(canvas_size.x * 8 / 10, canvas_size.y * 8 / 10));
4840 if (g_dashPrefWidth > 0 && g_dashPrefHeight > 0)
4841 SetSize(wxSize(g_dashPrefWidth, g_dashPrefHeight));
4843 SetSize(wxSize(canvas_size.x * 3 / 4, canvas_size.y * 8 / 10));
4850void DashboardPreferencesDialog::RecalculateSize(
void) {
4851#ifdef __OCPN__ANDROID__
4853 esize.x = GetCharWidth() * 110;
4854 esize.y = GetCharHeight() * 40;
4857 esize.y = wxMin(esize.y, dsize.y - (3 * GetCharHeight()));
4858 esize.x = wxMin(esize.x, dsize.x - (3 * GetCharHeight()));
4865void DashboardPreferencesDialog::OnCloseDialog(wxCloseEvent &event) {
4866 g_dashPrefWidth = GetSize().x;
4867 g_dashPrefHeight = GetSize().y;
4868 SaveDashboardConfig();
4872void DashboardPreferencesDialog::SaveDashboardConfig() {
4873 g_iDashSpeedMax = m_pSpinSpeedMax->GetValue();
4874 g_iDashCOGDamp = m_pSpinCOGDamp->GetValue();
4875 g_iDashSOGDamp = m_pSpinSOGDamp->GetValue();
4876 g_iDashAWADamp = m_pSpinAWADamp->GetValue();
4877 g_iDashAWSDamp = m_pSpinAWSDamp->GetValue();
4879 g_bUseInternSumLog = m_pUseInternSumLog->IsChecked();
4881 m_pSumLogValue->GetValue().ToDouble(&ursDist);
4884 g_iUTCOffset = m_pChoiceUTCOffset->GetSelection() - 24;
4885 g_iDashSpeedUnit = m_pChoiceSpeedUnit->GetSelection() - 1;
4886 double DashDBTOffset = m_pSpinDBTOffset->GetValue();
4887 switch (g_iDashDepthUnit - 3) {
4889 g_dDashDBTOffset = DashDBTOffset / 3.2808399;
4892 g_dDashDBTOffset = DashDBTOffset / 0.54680665;
4895 g_dDashDBTOffset = DashDBTOffset / 39.3700787;
4898 g_dDashDBTOffset = DashDBTOffset / 100;
4901 g_dDashDBTOffset = DashDBTOffset;
4903 g_iDashDepthUnit = m_pChoiceDepthUnit->GetSelection() + 3;
4904 g_iDashDistanceUnit = m_pChoiceDistanceUnit->GetSelection() - 1;
4905 g_iDashWindSpeedUnit = m_pChoiceWindSpeedUnit->GetSelection();
4906 g_bDBtrueWindGround = m_pUseTrueWinddata->GetValue();
4907 g_iDashTempUnit = m_pChoiceTempUnit->GetSelection();
4910 cont->m_bIsVisible = m_pCheckBoxIsVisible->IsChecked();
4911 cont->m_sCaption = m_pTextCtrlCaption->GetValue();
4912 cont->m_sOrientation =
4913 m_pChoiceOrientation->GetSelection() == 0 ? _T(
"V") : _T(
"H");
4914 cont->m_aInstrumentList.Clear();
4915 for (
int i = 0; i < m_pListCtrlInstruments->GetItemCount(); i++)
4916 cont->m_aInstrumentList.Add((
int)m_pListCtrlInstruments->GetItemData(i));
4920void DashboardPreferencesDialog::OnDashboardSelected(wxListEvent &event) {
4922 SaveDashboardConfig();
4923 UpdateDashboardButtonsState();
4926void DashboardPreferencesDialog::UpdateDashboardButtonsState() {
4928 item = m_pListCtrlDashboards->GetNextItem(item, wxLIST_NEXT_ALL,
4929 wxLIST_STATE_SELECTED);
4930 bool enable = (item != -1);
4934 bool delete_enable = enable;
4936 int sel = m_pListCtrlDashboards->GetItemData(item);
4939 if (dash_sel == GetParent()) delete_enable =
false;
4941 m_pButtonDeleteDashboard->Enable(delete_enable);
4943 m_pPanelDashboard->Enable(enable);
4946 curSel = m_pListCtrlDashboards->GetItemData(item);
4948 m_pCheckBoxIsVisible->SetValue(cont->m_bIsVisible);
4949 m_pTextCtrlCaption->SetValue(cont->m_sCaption);
4950 m_pChoiceOrientation->SetSelection(cont->m_sOrientation == _T(
"V") ? 0 : 1);
4951 m_pListCtrlInstruments->DeleteAllItems();
4952 for (
size_t i = 0; i < cont->m_aInstrumentList.GetCount(); i++) {
4954 getListItemForInstrument(item, cont->m_aInstrumentList.Item(i));
4955 item.SetId(m_pListCtrlInstruments->GetItemCount());
4956 m_pListCtrlInstruments->InsertItem(item);
4959 m_pListCtrlInstruments->SetColumnWidth(0, wxLIST_AUTOSIZE);
4962 m_pCheckBoxIsVisible->SetValue(
false);
4963 m_pTextCtrlCaption->SetValue(_T(
""));
4964 m_pChoiceOrientation->SetSelection(0);
4965 m_pListCtrlInstruments->DeleteAllItems();
4970void DashboardPreferencesDialog::OnDashboarddefaultFont(wxCommandEvent &event) {
4971 m_pFontPickerTitle->SetSelectedFont(
4972 wxFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL));
4973 m_pFontPickerTitle->SetSelectedColour(wxColour(0, 0, 0));
4974 m_pFontPickerData->SetSelectedFont(
4975 wxFont(14, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
4976 m_pFontPickerData->SetSelectedColour(wxColour(0, 0, 0));
4977 m_pFontPickerLabel->SetSelectedFont(
4978 wxFont(8, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
4979 m_pFontPickerLabel->SetSelectedColour(wxColour(0, 0, 0));
4980 m_pFontPickerSmall->SetSelectedFont(
4981 wxFont(8, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
4982 m_pFontPickerSmall->SetSelectedColour(wxColour(0, 0, 0));
4983 double scaler = 1.0;
4986 scaler = wxMax(1.0, scaler);
4988 g_USFontTitle = *(m_pFontPickerTitle->GetFontData());
4989 g_FontTitle = *g_pUSFontTitle;
4990 g_FontTitle.SetChosenFont(g_pUSFontTitle->GetChosenFont().Scaled(scaler));
4991 g_FontTitle.SetColour(g_pUSFontTitle->GetColour());
4992 g_USFontTitle = *g_pUSFontTitle;
4994 g_USFontData = *(m_pFontPickerData->GetFontData());
4995 g_FontData = *g_pUSFontData;
4996 g_FontData.SetChosenFont(g_pUSFontData->GetChosenFont().Scaled(scaler));
4997 g_FontData.SetColour(g_pUSFontData->GetColour());
4998 g_USFontData = *g_pUSFontData;
5000 g_USFontLabel = *(m_pFontPickerLabel->GetFontData());
5001 g_FontLabel = *g_pUSFontLabel;
5002 g_FontLabel.SetChosenFont(g_pUSFontLabel->GetChosenFont().Scaled(scaler));
5003 g_FontLabel.SetColour(g_pUSFontLabel->GetColour());
5004 g_USFontLabel = *g_pUSFontLabel;
5006 g_USFontSmall = *(m_pFontPickerSmall->GetFontData());
5007 g_FontSmall = *g_pUSFontSmall;
5008 g_FontSmall.SetChosenFont(g_pUSFontSmall->GetChosenFont().Scaled(scaler));
5009 g_FontSmall.SetColour(g_pUSFontSmall->GetColour());
5010 g_USFontSmall = *g_pUSFontSmall;
5013void DashboardPreferencesDialog::OnDashboardAdd(wxCommandEvent &event) {
5014 int idx = m_pListCtrlDashboards->GetItemCount();
5015 m_pListCtrlDashboards->InsertItem(idx, 0);
5017 m_pListCtrlDashboards->SetItemData(idx, m_Config.GetCount());
5019 wxArrayOfInstrumentProperties Property;
5021 NULL, MakeName(), _(
"Dashboard"), _T(
"V"), ar, Property);
5022 dwc->m_bIsVisible =
true;
5026void DashboardPreferencesDialog::OnDashboardDelete(wxCommandEvent &event) {
5028 itemID = m_pListCtrlDashboards->GetNextItem(itemID, wxLIST_NEXT_ALL,
5029 wxLIST_STATE_SELECTED);
5031 int idx = m_pListCtrlDashboards->GetItemData(itemID);
5032 m_pListCtrlDashboards->DeleteItem(itemID);
5033 m_Config.Item(idx)->m_bIsDeleted =
true;
5034 UpdateDashboardButtonsState();
5037void DashboardPreferencesDialog::OnInstrumentSelected(wxListEvent &event) {
5038 UpdateButtonsState();
5041void DashboardPreferencesDialog::UpdateButtonsState() {
5043 item = m_pListCtrlInstruments->GetNextItem(item, wxLIST_NEXT_ALL,
5044 wxLIST_STATE_SELECTED);
5045 bool enable = (item != -1);
5047 m_pButtonDelete->Enable(enable);
5048 m_pButtonEdit->Enable(enable);
5049 m_pButtonUp->Enable(item > 0);
5050 m_pButtonDown->Enable(item != -1 &&
5051 item < m_pListCtrlInstruments->GetItemCount() - 1);
5054void DashboardPreferencesDialog::OnInstrumentAdd(wxCommandEvent &event) {
5057#ifdef __OCPN__ANDROID__
5062 esize.x = GetCharWidth() * 110;
5063 esize.y = GetCharHeight() * 40;
5066 esize.y = wxMin(esize.y, dsize.y - (3 * GetCharHeight()));
5067 esize.x = wxMin(esize.x, dsize.x - (3 * GetCharHeight()));
5068 pdlg.SetSize(esize);
5070 pdlg.CentreOnScreen();
5073 if (pdlg.GetReturnCode() == wxID_OK) {
5075 getListItemForInstrument(item, pdlg.GetInstrumentAdded());
5076 item.SetId(m_pListCtrlInstruments->GetItemCount());
5077 m_pListCtrlInstruments->InsertItem(item);
5078 m_pListCtrlInstruments->SetColumnWidth(0, wxLIST_AUTOSIZE);
5079 UpdateButtonsState();
5083void DashboardPreferencesDialog::OnInstrumentDelete(wxCommandEvent &event) {
5084 long itemIDWindow = -1;
5085 itemIDWindow = m_pListCtrlDashboards->GetNextItem(
5086 itemIDWindow, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
5088 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5089 wxLIST_STATE_SELECTED);
5091 m_Config.Item(m_pListCtrlDashboards->GetItemData(itemIDWindow));
5095 for (
unsigned int i = 0; i < (cont->m_aInstrumentPropertyList.GetCount());
5097 Inst = cont->m_aInstrumentPropertyList.Item(i);
5098 if (Inst->m_aInstrument ==
5099 (
int)m_pListCtrlInstruments->GetItemData(itemID) &&
5100 Inst->m_Listplace == itemID) {
5101 cont->m_aInstrumentPropertyList.Remove(Inst);
5105 if (Inst->m_Listplace > itemID) Inst->m_Listplace--;
5109 m_pListCtrlInstruments->DeleteItem(itemID);
5111 cont->m_pDashboardWindow->SetInstrumentList(
5112 cont->m_aInstrumentList, &(cont->m_aInstrumentPropertyList));
5115 UpdateButtonsState();
5118inline void GetFontData(
OCPNFontButton *FontButton, wxFontData &UnScaledFont,
5119 wxFontData &ScaledFont,
double scaler) {
5120 UnScaledFont = *(FontButton->GetFontData());
5121 ScaledFont = UnScaledFont;
5122 ScaledFont.SetChosenFont(UnScaledFont.GetChosenFont().Scaled(scaler));
5125void DashboardPreferencesDialog::OnInstrumentEdit(wxCommandEvent &event) {
5128 long itemIDWindow = -1;
5129 itemIDWindow = m_pListCtrlDashboards->GetNextItem(
5130 itemIDWindow, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
5132 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5133 wxLIST_STATE_SELECTED);
5139 m_Config.Item(m_pListCtrlDashboards->GetItemData(itemIDWindow));
5142 for (
unsigned int i = 0; i < (cont->m_aInstrumentPropertyList.GetCount());
5144 Inst = cont->m_aInstrumentPropertyList.Item(
5146 if (Inst->m_aInstrument == (
int)m_pListCtrlInstruments->GetItemData(
5149 if (Inst->m_Listplace == itemID)
break;
5156 cont->m_aInstrumentPropertyList.Add(Inst);
5160 bool DefaultFont =
false;
5161 if (Edit->ShowModal() == wxID_OK) {
5163 double scaler = 1.0;
5166 scaler = wxMax(1.0, scaler);
5167 if (Edit->m_fontPicker2->GetFont().Scaled(scaler) !=
5168 g_FontTitle.GetChosenFont() ||
5169 Edit->m_fontPicker2->GetSelectedColour() != g_FontTitle.GetColour())
5170 DefaultFont =
false;
5171 if (Edit->m_fontPicker4->GetFont().Scaled(scaler) !=
5172 g_FontData.GetChosenFont() ||
5173 Edit->m_fontPicker4->GetSelectedColour() != g_FontData.GetColour())
5174 DefaultFont =
false;
5175 if (Edit->m_fontPicker5->GetFont().Scaled(scaler) !=
5176 g_FontLabel.GetChosenFont() ||
5177 Edit->m_fontPicker5->GetSelectedColour() != g_FontLabel.GetColour())
5178 DefaultFont =
false;
5179 if (Edit->m_fontPicker6->GetFont().Scaled(scaler) !=
5180 g_FontSmall.GetChosenFont() ||
5181 Edit->m_fontPicker6->GetSelectedColour() != g_FontSmall.GetColour())
5182 DefaultFont =
false;
5184 GetGlobalColor(_T(
"DASHL"), &dummy);
5185 if (Edit->m_colourPicker1->GetColour() != dummy) DefaultFont =
false;
5186 GetGlobalColor(_T(
"DASHB"), &dummy);
5187 if (Edit->m_colourPicker2->GetColour() != dummy) DefaultFont =
false;
5188 GetGlobalColor(_T(
"DASHN"), &dummy);
5189 if (Edit->m_colourPicker3->GetColour() != dummy) DefaultFont =
false;
5190 GetGlobalColor(_T(
"BLUE3"), &dummy);
5191 if (Edit->m_colourPicker4->GetColour() != dummy) DefaultFont =
false;
5193 cont->m_aInstrumentPropertyList.Remove(Inst);
5195 GetFontData(Edit->m_fontPicker2, Inst->m_USTitleFont, Inst->m_TitleFont,
5197 GetFontData(Edit->m_fontPicker4, Inst->m_USDataFont, Inst->m_DataFont,
5199 GetFontData(Edit->m_fontPicker5, Inst->m_USLabelFont, Inst->m_LabelFont,
5201 GetFontData(Edit->m_fontPicker6, Inst->m_USSmallFont, Inst->m_SmallFont,
5203 Inst->m_DataBackgroundColour = Edit->m_colourPicker2->GetColour();
5204 Inst->m_TitleBackgroundColour = Edit->m_colourPicker1->GetColour();
5205 Inst->m_Arrow_First_Colour = Edit->m_colourPicker3->GetColour();
5206 Inst->m_Arrow_Second_Colour = Edit->m_colourPicker4->GetColour();
5210 if (cont->m_pDashboardWindow) {
5211 cont->m_pDashboardWindow->SetInstrumentList(
5212 cont->m_aInstrumentList, &(cont->m_aInstrumentPropertyList));
5214 if (DefaultFont)
delete Inst;
5217void DashboardPreferencesDialog::OnInstrumentUp(wxCommandEvent &event) {
5218 long itemIDWindow = -1;
5219 itemIDWindow = m_pListCtrlDashboards->GetNextItem(
5220 itemIDWindow, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
5222 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5223 wxLIST_STATE_SELECTED);
5226 item.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_IMAGE | wxLIST_MASK_DATA);
5227 m_pListCtrlInstruments->GetItem(item);
5228 item.SetId(itemID - 1);
5232 m_Config.Item(m_pListCtrlDashboards->GetItemData(itemIDWindow));
5235 for (
unsigned int i = 0; i < (cont->m_aInstrumentPropertyList.GetCount());
5237 Inst = cont->m_aInstrumentPropertyList.Item(i);
5238 if (Inst->m_Listplace == (itemID - 1)) Inst->m_Listplace = itemID;
5239 if (Inst->m_aInstrument ==
5240 (
int)m_pListCtrlInstruments->GetItemData(itemID) &&
5241 Inst->m_Listplace == itemID) {
5242 cont->m_aInstrumentPropertyList.Item(i)->m_Listplace = itemID - 1;
5246 m_pListCtrlInstruments->DeleteItem(itemID);
5247 m_pListCtrlInstruments->InsertItem(item);
5248 for (
int i = 0; i < m_pListCtrlInstruments->GetItemCount(); i++)
5249 m_pListCtrlInstruments->SetItemState(i, 0, wxLIST_STATE_SELECTED);
5251 m_pListCtrlInstruments->SetItemState(itemID - 1, wxLIST_STATE_SELECTED,
5252 wxLIST_STATE_SELECTED);
5254 UpdateButtonsState();
5257void DashboardPreferencesDialog::OnInstrumentDown(wxCommandEvent &event) {
5258 long itemIDWindow = -1;
5259 itemIDWindow = m_pListCtrlDashboards->GetNextItem(
5260 itemIDWindow, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
5262 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5263 wxLIST_STATE_SELECTED);
5267 item.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_IMAGE | wxLIST_MASK_DATA);
5268 m_pListCtrlInstruments->GetItem(item);
5269 item.SetId(itemID + 1);
5273 m_Config.Item(m_pListCtrlDashboards->GetItemData(itemIDWindow));
5276 for (
unsigned int i = 0; i < (cont->m_aInstrumentPropertyList.GetCount());
5278 Inst = cont->m_aInstrumentPropertyList.Item(i);
5279 if (Inst->m_Listplace == (itemID + 1) &&
5280 Inst->m_aInstrument !=
5281 (int)m_pListCtrlInstruments->GetItemData(itemID))
5282 Inst->m_Listplace = itemID;
5283 if (Inst->m_aInstrument ==
5284 (
int)m_pListCtrlInstruments->GetItemData(itemID) &&
5285 Inst->m_Listplace == itemID) {
5286 cont->m_aInstrumentPropertyList.Item(i)->m_Listplace = itemID + 1;
5291 m_pListCtrlInstruments->DeleteItem(itemID);
5292 m_pListCtrlInstruments->InsertItem(item);
5293 for (
int i = 0; i < m_pListCtrlInstruments->GetItemCount(); i++)
5294 m_pListCtrlInstruments->SetItemState(i, 0, wxLIST_STATE_SELECTED);
5296 m_pListCtrlInstruments->SetItemState(itemID + 1, wxLIST_STATE_SELECTED,
5297 wxLIST_STATE_SELECTED);
5299 UpdateButtonsState();
5302void DashboardPreferencesDialog::OnDistanceUnitSelect(wxCommandEvent &event) {
5304 g_iDashDistanceUnit = m_pChoiceDistanceUnit->GetSelection() - 1;
5306 m_pSumLogValue->SetValue(wxString::Format(
5316AddInstrumentDlg::AddInstrumentDlg(wxWindow *pparent, wxWindowID
id)
5317 : wxDialog(pparent, id, _(
"Add instrument"), wxDefaultPosition,
5318 wxDefaultSize, wxDEFAULT_DIALOG_STYLE) {
5319 wxBoxSizer *itemBoxSizer01 =
new wxBoxSizer(wxVERTICAL);
5320 SetSizer(itemBoxSizer01);
5321 wxStaticText *itemStaticText01 =
5322 new wxStaticText(
this, wxID_ANY, _(
"Select instrument to add:"),
5323 wxDefaultPosition, wxDefaultSize, 0);
5324 itemBoxSizer01->Add(itemStaticText01, 0, wxEXPAND | wxALL, 5);
5328 wxImageList *imglist =
5329 new wxImageList(instImageRefSize, instImageRefSize,
true, 2);
5331 wxImage inst1 = wxBitmap(*_img_instrument).ConvertToImage();
5333 inst1.Scale(instImageRefSize, instImageRefSize, wxIMAGE_QUALITY_HIGH);
5334 imglist->Add(wxBitmap(inst1s));
5336 wxImage dial1 = wxBitmap(*_img_dial).ConvertToImage();
5338 dial1.Scale(instImageRefSize, instImageRefSize, wxIMAGE_QUALITY_HIGH);
5339 imglist->Add(wxBitmap(dial1s));
5342 int vsize = dsize.y * 50 / 100;
5344#ifdef __OCPN__ANDROID__
5346 wxDisplaySize(&dw, &dh);
5347 vsize = dh * 50 / 100;
5350 m_pListCtrlInstruments =
new wxListCtrl(
5351 this, wxID_ANY, wxDefaultPosition, wxSize(-1, vsize ),
5352 wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING);
5353 itemBoxSizer01->Add(m_pListCtrlInstruments, 0, wxEXPAND | wxALL, 5);
5354 m_pListCtrlInstruments->AssignImageList(imglist, wxIMAGE_LIST_SMALL);
5355 m_pListCtrlInstruments->InsertColumn(0, _(
"Instruments"));
5358 m_pListCtrlInstruments->SetFont(*pF);
5360#ifdef __OCPN__ANDROID__
5361 m_pListCtrlInstruments->GetHandle()->setStyleSheet(qtStyleSheet);
5365 wxStdDialogButtonSizer *DialogButtonSizer =
5366 CreateStdDialogButtonSizer(wxOK | wxCANCEL);
5367 itemBoxSizer01->Add(DialogButtonSizer, 0, wxALIGN_RIGHT | wxALL, 5);
5370 for (
unsigned int i = ID_DBP_I_POS; i < ID_DBP_LAST_ENTRY;
5374 if (IsObsolete(i))
continue;
5375 getListItemForInstrument(item, i);
5377 m_pListCtrlInstruments->InsertItem(item);
5381 m_pListCtrlInstruments->SetColumnWidth(0, wxLIST_AUTOSIZE);
5382 m_pListCtrlInstruments->SetItemState(0, wxLIST_STATE_SELECTED,
5383 wxLIST_STATE_SELECTED);
5387unsigned int AddInstrumentDlg::GetInstrumentAdded() {
5389 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5390 wxLIST_STATE_SELECTED);
5392 return (
int)m_pListCtrlInstruments->GetItemData(itemID);
5402DashboardWindow::DashboardWindow(wxWindow *pparent, wxWindowID
id,
5405 : wxWindow(pparent, id, wxDefaultPosition, wxDefaultSize, 0) {
5411 m_Container = mycont;
5414 itemBoxSizer =
new wxBoxSizer(orient);
5415 SetSizer(itemBoxSizer);
5416 Connect(wxEVT_SIZE, wxSizeEventHandler(DashboardWindow::OnSize), NULL,
this);
5417 Connect(wxEVT_CONTEXT_MENU,
5418 wxContextMenuEventHandler(DashboardWindow::OnContextMenu), NULL,
5420 Connect(wxEVT_COMMAND_MENU_SELECTED,
5421 wxCommandEventHandler(DashboardWindow::OnContextMenuSelect), NULL,
5424#ifdef __OCPN__ANDROID__
5425 Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(DashboardWindow::OnMouseEvent));
5426 Connect(wxEVT_LEFT_UP, wxMouseEventHandler(DashboardWindow::OnMouseEvent));
5427 Connect(wxEVT_MOTION, wxMouseEventHandler(DashboardWindow::OnMouseEvent));
5429 GetHandle()->setAttribute(Qt::WA_AcceptTouchEvents);
5430 GetHandle()->grabGesture(Qt::PinchGesture);
5431 GetHandle()->grabGesture(Qt::PanGesture);
5433 Connect(wxEVT_QT_PINCHGESTURE,
5438 wxEVT_QT_PANGESTURE,
5439 (wxObjectEventFunction)(wxEventFunction)&DashboardWindow::OnEvtPanGesture,
5445 m_binResize =
false;
5449DashboardWindow::~DashboardWindow() {
5450 for (
size_t i = 0; i < m_ArrayOfInstrument.GetCount(); i++) {
5456#ifdef __OCPN__ANDROID__
5457void DashboardWindow::OnEvtPinchGesture(wxQT_PinchGestureEvent &event) {
5458 float zoom_gain = 0.3;
5460 float total_zoom_val;
5462 if (event.GetScaleFactor() > 1)
5463 zoom_val = ((
event.GetScaleFactor() - 1.0) * zoom_gain) + 1.0;
5465 zoom_val = 1.0 - ((1.0 -
event.GetScaleFactor()) * zoom_gain);
5467 if (event.GetTotalScaleFactor() > 1)
5468 total_zoom_val = ((event.GetTotalScaleFactor() - 1.0) * zoom_gain) + 1.0;
5470 total_zoom_val = 1.0 - ((1.0 -
event.GetTotalScaleFactor()) * zoom_gain);
5472 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5474 wxSize currentSize = wxSize(pane.floating_size.x, pane.floating_size.y);
5475 double aRatio = (double)currentSize.y / (
double)currentSize.x;
5478 wxPoint par_pos = wxPoint(pane.floating_pos.x, pane.floating_pos.y);
5480 switch (event.GetState()) {
5481 case GestureStarted:
5485 case GestureUpdated:
5486 currentSize.y *= zoom_val;
5487 currentSize.x *= zoom_val;
5489 if ((par_pos.y + currentSize.y) > par_size.y)
5490 currentSize.y = par_size.y - par_pos.y;
5492 if ((par_pos.x + currentSize.x) > par_size.x)
5493 currentSize.x = par_size.x - par_pos.x;
5496 currentSize.x = currentSize.y / aRatio;
5498 currentSize.x = wxMax(currentSize.x, 150);
5499 currentSize.y = wxMax(currentSize.y, 150);
5501 pane.FloatingSize(currentSize);
5502 m_pauimgr->Update();
5506 case GestureFinished: {
5507 if (itemBoxSizer->GetOrientation() == wxVERTICAL) {
5508 currentSize.y *= total_zoom_val;
5509 currentSize.x = currentSize.y / aRatio;
5511 currentSize.x *= total_zoom_val;
5512 currentSize.y = currentSize.x * aRatio;
5516 if ((par_pos.y + currentSize.y) > par_size.y)
5517 currentSize.y = par_size.y - par_pos.y;
5519 if ((par_pos.x + currentSize.x) > par_size.x)
5520 currentSize.x = par_size.x - par_pos.x;
5523 currentSize.x = wxMax(currentSize.x, 150);
5524 currentSize.y = wxMax(currentSize.y, 150);
5529 if (itemBoxSizer->GetOrientation() == wxVERTICAL) {
5531 for (
unsigned int i = 0; i < m_ArrayOfInstrument.size(); i++) {
5533 m_ArrayOfInstrument.Item(i)->m_pInstrument;
5535 inst->GetSize(itemBoxSizer->GetOrientation(), currentSize);
5539 currentSize.y = total_y;
5542 pane.FloatingSize(currentSize);
5545 for (
unsigned int i = 0; i < m_ArrayOfInstrument.size(); i++) {
5550 m_pauimgr->Update();
5553 m_binResize =
false;
5558 case GestureCanceled:
5560 m_binResize =
false;
5568void DashboardWindow::OnEvtPanGesture(wxQT_PanGestureEvent &event) {
5569 if (m_binPinch)
return;
5571 if (m_binResize)
return;
5573 int x =
event.GetOffset().x;
5574 int y =
event.GetOffset().y;
5576 int lx =
event.GetLastOffset().x;
5577 int ly =
event.GetLastOffset().y;
5582 switch (event.GetState()) {
5583 case GestureStarted:
5584 if (m_binPan)
break;
5589 case GestureUpdated:
5592 wxPoint par_pos_old = ClientToScreen(wxPoint(0, 0));
5594 wxPoint par_pos = par_pos_old;
5598 par_pos.x = wxMax(par_pos.x, 0);
5599 par_pos.y = wxMax(par_pos.y, 0);
5601 wxSize mySize = GetSize();
5603 if ((par_pos.y + mySize.y) > par_size.y)
5604 par_pos.y = par_size.y - mySize.y;
5606 if ((par_pos.x + mySize.x) > par_size.x)
5607 par_pos.x = par_size.x - mySize.x;
5609 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5610 pane.FloatingPosition(par_pos).Float();
5611 m_pauimgr->Update();
5615 case GestureFinished:
5622 case GestureCanceled:
5631void DashboardWindow::OnMouseEvent(wxMouseEvent &event) {
5632 if (m_binPinch)
return;
5635 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5636 wxSize currentSize = wxSize(pane.floating_size.x, pane.floating_size.y);
5637 double aRatio = (double)currentSize.y / (
double)currentSize.x;
5640 wxPoint par_pos = wxPoint(pane.floating_pos.x, pane.floating_pos.y);
5642 if (event.LeftDown()) {
5643 m_resizeStartPoint =
event.GetPosition();
5644 m_resizeStartSize = currentSize;
5645 m_binResize2 =
true;
5649 if (event.Dragging()) {
5650 wxPoint p =
event.GetPosition();
5652 wxSize dragSize = m_resizeStartSize;
5654 dragSize.y += p.y - m_resizeStartPoint.y;
5655 dragSize.x += p.x - m_resizeStartPoint.x;
5658 if ((par_pos.y + dragSize.y) > par_size.y)
5659 dragSize.y = par_size.y - par_pos.y;
5661 if ((par_pos.x + dragSize.x) > par_size.x)
5662 dragSize.x = par_size.x - par_pos.x;
5668 dragSize.x = wxMax(dragSize.x, 150);
5669 dragSize.y = wxMax(dragSize.y, 150);
5671 pane.FloatingSize(dragSize);
5672 m_pauimgr->Update();
5675 if (event.LeftUp()) {
5676 wxPoint p =
event.GetPosition();
5678 wxSize dragSize = m_resizeStartSize;
5680 dragSize.y += p.y - m_resizeStartPoint.y;
5681 dragSize.x += p.x - m_resizeStartPoint.x;
5684 if ((par_pos.y + dragSize.y) > par_size.y)
5685 dragSize.y = par_size.y - par_pos.y;
5687 if ((par_pos.x + dragSize.x) > par_size.x)
5688 dragSize.x = par_size.x - par_pos.x;
5691 dragSize.x = wxMax(dragSize.x, 150);
5692 dragSize.y = wxMax(dragSize.y, 150);
5699 pane.FloatingSize(dragSize);
5700 m_pauimgr->Update();
5702 m_binResize =
false;
5703 m_binResize2 =
false;
5710void DashboardWindow::OnSize(wxSizeEvent &event) {
5712 for (
unsigned int i = 0; i < m_ArrayOfInstrument.size(); i++) {
5715 inst->GetSize(itemBoxSizer->GetOrientation(), GetClientSize()));
5720 this->m_Container->m_best_size =
event.GetSize();
5723void DashboardWindow::OnContextMenu(wxContextMenuEvent &event) {
5724 wxMenu *contextMenu =
new wxMenu();
5731 new wxMenuItem(contextMenu, ID_DASH_PREFS, _(
"Preferences..."));
5732 item1->SetFont(*pf);
5733 contextMenu->Append(item1);
5736 new wxMenuItem(contextMenu, ID_DASH_RESIZE, _(
"Resize..."));
5737 item2->SetFont(*pf);
5738 contextMenu->Append(item2);
5742 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5743 if (pane.IsOk() && pane.IsDocked()) {
5744 contextMenu->Append(ID_DASH_UNDOCK, _(
"Undock"));
5746 wxMenuItem *btnVertical =
5747 contextMenu->AppendRadioItem(ID_DASH_VERTICAL, _(
"Vertical"));
5748 btnVertical->Check(itemBoxSizer->GetOrientation() == wxVERTICAL);
5749 wxMenuItem *btnHorizontal =
5750 contextMenu->AppendRadioItem(ID_DASH_HORIZONTAL, _(
"Horizontal"));
5751 btnHorizontal->Check(itemBoxSizer->GetOrientation() == wxHORIZONTAL);
5752 contextMenu->AppendSeparator();
5754 m_plugin->PopulateContextMenu(contextMenu);
5756 contextMenu->AppendSeparator();
5757 contextMenu->Append(ID_DASH_PREFS, _(
"Preferences..."));
5761 PopupMenu(contextMenu);
5765void DashboardWindow::OnContextMenuSelect(wxCommandEvent &event) {
5766 if (event.GetId() < ID_DASH_PREFS) {
5767 if (m_plugin->GetDashboardWindowShownCount() > 1 || event.IsChecked())
5768 m_plugin->ShowDashboard(event.GetId() - 1, event.IsChecked());
5770 m_plugin->ShowDashboard(event.GetId() - 1,
true);
5773 m_plugin->GetDashboardWindowShownCount() != 0);
5776 switch (event.GetId()) {
5777 case ID_DASH_PREFS: {
5778 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5780 wxPoint fp = pane.floating_pos;
5788 if (!pane.IsDocked())
5789 ChangePaneOrientation(GetSizerOrientation(),
true, fp.x, fp.y);
5791 if (g_bUseInternSumLog) m_plugin->UpdateSumLog(
false);
5794 case ID_DASH_RESIZE: {
5805 case ID_DASH_VERTICAL: {
5806 ChangePaneOrientation(wxVERTICAL,
true);
5807 m_Container->m_sOrientation = _T(
"V");
5810 case ID_DASH_HORIZONTAL: {
5811 ChangePaneOrientation(wxHORIZONTAL,
true);
5812 m_Container->m_sOrientation = _T(
"H");
5815 case ID_DASH_UNDOCK: {
5816 ChangePaneOrientation(GetSizerOrientation(),
true);
5820 m_plugin->SaveConfig();
5827 wxColour col = g_BackgroundColor;
5829 if (!g_ForceBackgroundColor) GetGlobalColor(_T(
"DASHL"), &col);
5830 SetBackgroundColour(col);
5835void DashboardWindow::ChangePaneOrientation(
int orient,
bool updateAUImgr,
5837 m_pauimgr->DetachPane(
this);
5838 SetSizerOrientation(orient);
5839 bool vertical = orient == wxVERTICAL;
5841 wxSize sz = GetMinSize();
5843 m_Container->m_sName = MakeName();
5844 m_pauimgr->AddPane(
this, wxAuiPaneInfo()
5845 .Name(m_Container->m_sName)
5846 .Caption(m_Container->m_sCaption)
5847 .CaptionVisible(
true)
5848 .TopDockable(!vertical)
5849 .BottomDockable(!vertical)
5850 .LeftDockable(vertical)
5851 .RightDockable(vertical)
5855 .FloatingPosition(fpx, fpy)
5857 .Show(m_Container->m_bIsVisible));
5859#ifdef __OCPN__ANDROID__
5860 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5861 pane.Dockable(
false);
5864 if (updateAUImgr) m_pauimgr->Update();
5867void DashboardWindow::SetSizerOrientation(
int orient) {
5868 itemBoxSizer->SetOrientation(orient);
5870 wxWindowListNode *node = GetChildren().GetFirst();
5872 node->GetData()->SetMinSize(wxDefaultSize);
5873 node = node->GetNext();
5875 SetMinSize(wxDefaultSize);
5877 SetMinSize(itemBoxSizer->GetMinSize());
5880int DashboardWindow::GetSizerOrientation() {
5881 return itemBoxSizer->GetOrientation();
5884bool isArrayIntEqual(
const wxArrayInt &l1,
const wxArrayOfInstrument &l2) {
5885 if (l1.GetCount() != l2.GetCount())
return false;
5887 for (
size_t i = 0; i < l1.GetCount(); i++)
5888 if (l1.Item(i) != l2.Item(i)->m_ID)
return false;
5893bool DashboardWindow::isInstrumentListEqual(
const wxArrayInt &list) {
5894 return isArrayIntEqual(list, m_ArrayOfInstrument);
5897void DashboardWindow::SetInstrumentList(
5898 wxArrayInt list, wxArrayOfInstrumentProperties *InstrumentPropertyList) {
5912 m_ArrayOfInstrument.Clear();
5913 itemBoxSizer->Clear(
true);
5914 for (
size_t i = 0; i < list.GetCount(); i++) {
5915 int id = list.Item(i);
5917 for (
size_t j = 0; j < InstrumentPropertyList->GetCount(); j++) {
5918 if (InstrumentPropertyList->Item(j)->m_aInstrument ==
id &&
5919 InstrumentPropertyList->Item(j)->m_Listplace == (
int)i) {
5920 Properties = InstrumentPropertyList->Item(j);
5928 this, wxID_ANY, getInstrumentCaption(
id), Properties);
5932 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5933 OCPN_DBP_STC_SOG, _T(
"%5.1f"));
5937 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5938 OCPN_DBP_STC_SOG, 0, g_iDashSpeedMax);
5940 ->SetOptionLabel(g_iDashSpeedMax / 20 + 1, DIAL_LABEL_HORIZONTAL);
5944 ->SetOptionMarker(0.5, DIAL_MARKER_SIMPLE, 2);
5946 ->SetOptionExtraValue(OCPN_DBP_STC_STW,
"STW %.1f",
5947 DIAL_POSITION_BOTTOMMIDDLE);
5951 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5952 OCPN_DBP_STC_STW, 0, g_iDashSpeedMax);
5954 ->SetOptionLabel(g_iDashSpeedMax / 20 + 1, DIAL_LABEL_HORIZONTAL);
5958 ->SetOptionMarker(0.5, DIAL_MARKER_SIMPLE, 2);
5960 ->SetOptionExtraValue(OCPN_DBP_STC_SOG,
"SOG %.1f",
5961 DIAL_POSITION_BOTTOMMIDDLE);
5965 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5966 OCPN_DBP_STC_COG, _T(
"%03.0f"));
5970 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5971 OCPN_DBP_STC_MCOG, _T(
"%03.0f"));
5975 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5978 ->SetOptionMarker(5, DIAL_MARKER_SIMPLE, 2);
5980 ->SetOptionLabel(30, DIAL_LABEL_ROTATED);
5982 ->SetOptionExtraValue(OCPN_DBP_STC_SOG, _T(
"SOG\n%.2f"),
5983 DIAL_POSITION_BOTTOMLEFT);
5987 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5990 ->SetOptionMarker(5, DIAL_MARKER_SIMPLE, 2);
5992 ->SetOptionLabel(30, DIAL_LABEL_ROTATED);
5994 ->SetOptionExtraValue(OCPN_DBP_STC_STW, _T(
"STW\n%.1f"),
5995 DIAL_POSITION_BOTTOMLEFT);
5999 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6000 OCPN_DBP_STC_STW, _T(
"%.1f"));
6005 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6006 OCPN_DBP_STC_HDT, _T(
"%03.0f"));
6010 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6011 OCPN_DBP_STC_HDM, _T(
"%03.0f"));
6016 getInstrumentCaption(
id),
6017 Properties, OCPN_DBP_STC_AWA);
6019 ->SetOptionMainValue(_T(
"%.0f"), DIAL_POSITION_BOTTOMLEFT);
6021 ->SetOptionExtraValue(OCPN_DBP_STC_AWS, _T(
"%.1f"),
6022 DIAL_POSITION_INSIDE);
6026 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6027 OCPN_DBP_STC_AWS, _T(
"%.1f"));
6031 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6032 OCPN_DBP_STC_AWS, 0, 45);
6034 ->SetOptionLabel(5, DIAL_LABEL_HORIZONTAL);
6036 ->SetOptionMarker(1, DIAL_MARKER_SIMPLE, 5);
6038 ->SetOptionMainValue(_T(
"A %.1f"), DIAL_POSITION_BOTTOMLEFT);
6040 ->SetOptionExtraValue(OCPN_DBP_STC_TWS, _T(
"T %.1f"),
6041 DIAL_POSITION_BOTTOMRIGHT);
6045 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6048 ->SetOptionMainValue(_T(
"%.0f"), DIAL_POSITION_BOTTOMLEFT);
6050 ->SetOptionExtraValue(OCPN_DBP_STC_TWS, _T(
"%.1f"),
6051 DIAL_POSITION_INSIDE);
6053 case ID_DBP_D_AWA_TWA:
6055 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6059 ->SetOptionMainValue(_T(
"%.0f"), DIAL_POSITION_NONE);
6061 ->SetOptionExtraValue(OCPN_DBP_STC_TWS, _T(
"%.1f"),
6062 DIAL_POSITION_NONE);
6064 ->SetOptionExtraValue(OCPN_DBP_STC_AWS, _T(
"%.1f"),
6065 DIAL_POSITION_NONE);
6069 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6072 ->SetOptionMainValue(_T(
"%.0f"), DIAL_POSITION_BOTTOMLEFT);
6074 ->SetOptionExtraValue(OCPN_DBP_STC_TWS2, _T(
"%.1f"),
6075 DIAL_POSITION_INSIDE);
6079 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6080 OCPN_DBP_STC_ALTI, _T(
"%6.1f"));
6084 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6088 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6089 OCPN_DBP_STC_DPT, _T(
"%5.2f"));
6093 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6097 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6098 OCPN_DBP_STC_TMP, _T(
"%2.1f"));
6102 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6103 OCPN_DBP_STC_MDA, _T(
"%5.1f"));
6107 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6108 OCPN_DBP_STC_MDA, 938, 1088);
6110 ->SetOptionLabel(15, DIAL_LABEL_HORIZONTAL);
6112 ->SetOptionMarker(7.5, DIAL_MARKER_SIMPLE, 1);
6114 ->SetOptionMainValue(_T(
"%5.1f"), DIAL_POSITION_INSIDE);
6118 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6119 OCPN_DBP_STC_ATMP, _T(
"%2.1f"));
6123 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6124 OCPN_DBP_STC_VLW1, _T(
"%2.1f"));
6129 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6130 OCPN_DBP_STC_VLW2, _T(
"%2.1f"));
6135 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6136 OCPN_DBP_STC_TWA, _T(
"%5.0f"));
6140 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6141 OCPN_DBP_STC_TWD, _T(
"%3.0f"));
6145 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6146 OCPN_DBP_STC_TWS, _T(
"%2.1f"));
6150 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6151 OCPN_DBP_STC_AWA, _T(
"%3.0f"));
6155 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6156 OCPN_DBP_STC_VMGW, _T(
"%2.1f"));
6160 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6161 OCPN_DBP_STC_VMG, _T(
"%5.1f"));
6165 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6166 OCPN_DBP_STC_VMG, 0, g_iDashSpeedMax);
6168 ->SetOptionLabel(1, DIAL_LABEL_HORIZONTAL);
6170 ->SetOptionMarker(0.5, DIAL_MARKER_SIMPLE, 2);
6172 ->SetOptionExtraValue(OCPN_DBP_STC_SOG, _T(
"SOG\n%.1f"),
6173 DIAL_POSITION_BOTTOMLEFT);
6177 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6178 OCPN_DBP_STC_RSA, _T(
"%5.0f"));
6182 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6186 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6187 OCPN_DBP_STC_SAT, _T(
"%5.0f"));
6191 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6195 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6196 OCPN_DBP_STC_PLA, OCPN_DBP_STC_PLO);
6198 case ID_DBP_I_GPSUTC:
6200 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6204 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6208 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6212 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6216 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6220 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6222 case ID_DBP_I_PITCH:
6224 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6225 OCPN_DBP_STC_PITCH, _T(
"%2.1f"));
6229 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6230 OCPN_DBP_STC_HEEL, _T(
"%2.1f"));
6234 case ID_DBP_I_SUNLCL:
6236 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6237 _T(
"%02i:%02i:%02i LCL" ));
6239 case ID_DBP_I_GPSLCL:
6241 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6242 OCPN_DBP_STC_CLK, _T(
"%02i:%02i:%02i LCL" ));
6244 case ID_DBP_I_CPULCL:
6246 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6247 _T(
"%02i:%02i:%02i LCL" ));
6251 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6252 OCPN_DBP_STC_HUM,
"%3.0f");
6256 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6257 OCPN_DBP_STC_WCC, _T(
"%5.1f"));
6261 instrument->instrumentTypeId = id;
6263 id, instrument, instrument->GetCapacity()));
6264 itemBoxSizer->Add(instrument, 0, wxEXPAND, 0);
6265 if (itemBoxSizer->GetOrientation() == wxHORIZONTAL) {
6266 itemBoxSizer->AddSpacer(5);
6277 wxSize Hint = wxSize(DefaultWidth, DefaultWidth);
6279 for (
unsigned int i = 0; i < m_ArrayOfInstrument.size(); i++) {
6281 inst->SetMinSize(inst->GetSize(itemBoxSizer->GetOrientation(), Hint));
6282 Hint = inst->GetMinSize();
6287 SetMinSize(itemBoxSizer->GetMinSize());
6290void DashboardWindow::SendSentenceToAllInstruments(DASH_CAP st,
double value,
6292 for (
size_t i = 0; i < m_ArrayOfInstrument.GetCount(); i++) {
6293 if (m_ArrayOfInstrument.Item(i)->m_cap_flag.test(st))
6294 m_ArrayOfInstrument.Item(i)->m_pInstrument->SetData(st, value,
unit);
6298void DashboardWindow::SendSatInfoToAllInstruments(
int cnt,
int seq,
6301 for (
size_t i = 0; i < m_ArrayOfInstrument.GetCount(); i++) {
6302 if ((m_ArrayOfInstrument.Item(i)->m_cap_flag.test(OCPN_DBP_STC_GPS)) &&
6304 m_ArrayOfInstrument.Item(i)->m_pInstrument))
6306 ->SetSatInfo(cnt, seq, talk, sats);
6310void DashboardWindow::SendUtcTimeToAllInstruments(wxDateTime value) {
6311 for (
size_t i = 0; i < m_ArrayOfInstrument.GetCount(); i++) {
6312 if ((m_ArrayOfInstrument.Item(i)->m_cap_flag.test(OCPN_DBP_STC_CLK)) &&
6314 m_ArrayOfInstrument.Item(i)->m_pInstrument))
6322 ->SetUtcTime(value);
6338bool OCPNFontButton::Create(wxWindow *parent, wxWindowID
id,
6339 const wxFontData &initial,
const wxPoint &pos,
6340 const wxSize &size,
long style,
6341 const wxValidator &validator,
6342 const wxString &name) {
6343 wxString label = (style & wxFNTP_FONTDESC_AS_LABEL)
6349 if (!wxButton::Create(parent,
id, label, pos, size, style, validator, name)) {
6350 wxFAIL_MSG(wxT(
"OCPNFontButton creation failed"));
6355 Connect(GetId(), wxEVT_BUTTON,
6356 wxCommandEventHandler(OCPNFontButton::OnButtonClick), NULL,
this);
6360 initial.GetChosenFont().IsOk() ? initial.GetChosenFont() : *wxNORMAL_FONT;
6366void OCPNFontButton::OnButtonClick(wxCommandEvent &WXUNUSED(ev)) {
6368 m_data.SetInitialFont(m_selectedFont);
6373 int display_height = wxGetDisplaySize().y;
6374 if (display_height < 800) {
6378 if (dlg.ShowModal() == wxID_OK) {
6379 m_data = dlg.GetFontData();
6380 m_selectedFont = m_data.GetChosenFont();
6382 wxFontPickerEvent event(
this, GetId(), m_selectedFont);
6383 GetEventHandler()->ProcessEvent(event);
6388 wxFontDialog dlg(
this, m_data);
6390 if (dlg.ShowModal() == wxID_OK) {
6391 m_data = dlg.GetFontData();
6392 m_selectedFont = m_data.GetChosenFont();
6394 wxFontPickerEvent event(
this, GetId(), m_selectedFont);
6395 GetEventHandler()->ProcessEvent(event);
6402 wxFontDialog dlg(
this, m_data);
6408 wxSize proposed_size = GetParent()->GetSize();
6410 float font_size = pF->GetPointSize();
6412 if ((proposed_size.y / font_size) < n_lines) {
6413 float new_font_size = proposed_size.y / n_lines;
6414 wxFont *smallFont =
new wxFont(*pF);
6415 smallFont->SetPointSize(new_font_size);
6416 dlg.SetFont(*smallFont);
6419 dlg.SetSize(GetParent()->GetSize());
6423 if (dlg.ShowModal() == wxID_OK) {
6424 m_data = dlg.GetFontData();
6425 m_selectedFont = m_data.GetChosenFont();
6428 wxFontPickerEvent event(
this, GetId(), m_selectedFont);
6429 GetEventHandler()->ProcessEvent(event);
6436void OCPNFontButton::UpdateFont() {
6437 if (!m_selectedFont.IsOk())
return;
6442 if (HasFlag(wxFNTP_USEFONT_FOR_LABEL)) {
6444 wxButton::SetFont(m_selectedFont);
6445 wxButton::SetForegroundColour(GetSelectedColour());
6449 wxString::Format(wxT(
"%s, %d"), m_selectedFont.GetFaceName().c_str(),
6450 m_selectedFont.GetPointSize());
6452 if (HasFlag(wxFNTP_FONTDESC_AS_LABEL)) {
6456 auto minsize = GetTextExtent(label);
6459 GetParent()->Layout();
6466 wxWindowID
id,
const wxString &title,
const wxPoint &pos,
6467 const wxSize &size,
long style)
6468 : wxDialog(parent, id, title, pos, size, style) {
6469 this->SetSizeHints(wxDefaultSize, wxDefaultSize);
6471 wxBoxSizer *bSizer5;
6472 bSizer5 =
new wxBoxSizer(wxVERTICAL);
6474 wxFlexGridSizer *fgSizer2;
6475 fgSizer2 =
new wxFlexGridSizer(0, 2, 0, 0);
6476 fgSizer2->SetFlexibleDirection(wxBOTH);
6477 fgSizer2->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
6479 m_staticText1 =
new wxStaticText(
this, wxID_ANY, _(
"Title:"),
6480 wxDefaultPosition, wxDefaultSize, 0);
6481 m_staticText1->Wrap(-1);
6482 fgSizer2->Add(m_staticText1, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6484 m_fontPicker2 =
new wxFontPickerCtrl(
this, wxID_ANY, Properties.m_USTitleFont,
6485 wxDefaultPosition, wxDefaultSize);
6486 fgSizer2->Add(m_fontPicker2, 0, wxALL, 5);
6488 m_staticText5 =
new wxStaticText(
this, wxID_ANY, _(
"Title background color:"),
6489 wxDefaultPosition, wxDefaultSize, 0);
6490 m_staticText5->Wrap(-1);
6491 fgSizer2->Add(m_staticText5, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6493 m_colourPicker1 =
new wxColourPickerCtrl(
6494 this, wxID_ANY, Properties.m_TitleBackgroundColour, wxDefaultPosition,
6495 wxDefaultSize, wxCLRP_DEFAULT_STYLE);
6496 fgSizer2->Add(m_colourPicker1, 0, wxALL, 5);
6498 m_staticText2 =
new wxStaticText(
this, wxID_ANY, _(
"Data:"),
6499 wxDefaultPosition, wxDefaultSize, 0);
6500 m_staticText2->Wrap(-1);
6501 fgSizer2->Add(m_staticText2, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6503 m_fontPicker4 =
new wxFontPickerCtrl(
this, wxID_ANY, Properties.m_USDataFont,
6504 wxDefaultPosition, wxDefaultSize);
6505 fgSizer2->Add(m_fontPicker4, 0, wxALL, 5);
6507 m_staticText6 =
new wxStaticText(
this, wxID_ANY, _(
"Data background color:"),
6508 wxDefaultPosition, wxDefaultSize, 0);
6509 m_staticText6->Wrap(-1);
6510 fgSizer2->Add(m_staticText6, 0, wxALL, 5);
6512 m_colourPicker2 =
new wxColourPickerCtrl(
6513 this, wxID_ANY, Properties.m_DataBackgroundColour, wxDefaultPosition,
6514 wxDefaultSize, wxCLRP_DEFAULT_STYLE);
6515 fgSizer2->Add(m_colourPicker2, 0, wxALL, 5);
6517 m_staticText3 =
new wxStaticText(
this, wxID_ANY, _(
"Label:"),
6518 wxDefaultPosition, wxDefaultSize, 0);
6519 m_staticText3->Wrap(-1);
6520 fgSizer2->Add(m_staticText3, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6522 m_fontPicker5 =
new wxFontPickerCtrl(
this, wxID_ANY, Properties.m_USLabelFont,
6523 wxDefaultPosition, wxDefaultSize);
6524 fgSizer2->Add(m_fontPicker5, 0, wxALL, 5);
6526 m_staticText4 =
new wxStaticText(
this, wxID_ANY, _(
"Small:"),
6527 wxDefaultPosition, wxDefaultSize, 0);
6528 m_staticText4->Wrap(-1);
6529 fgSizer2->Add(m_staticText4, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6531 m_fontPicker6 =
new wxFontPickerCtrl(
this, wxID_ANY, Properties.m_USSmallFont,
6532 wxDefaultPosition, wxDefaultSize);
6533 fgSizer2->Add(m_fontPicker6, 0, wxALL, 5);
6535 m_staticText9 =
new wxStaticText(
this, wxID_ANY, _(
"Arrow 1 Color :"),
6536 wxDefaultPosition, wxDefaultSize, 0);
6537 m_staticText9->Wrap(-1);
6538 fgSizer2->Add(m_staticText9, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6540 m_colourPicker3 =
new wxColourPickerCtrl(
6541 this, wxID_ANY, Properties.m_Arrow_First_Colour, wxDefaultPosition,
6542 wxDefaultSize, wxCLRP_DEFAULT_STYLE);
6543 fgSizer2->Add(m_colourPicker3, 0, wxALL, 5);
6545 m_staticText10 =
new wxStaticText(
this, wxID_ANY, _(
"Arrow 2 Color :"),
6546 wxDefaultPosition, wxDefaultSize, 0);
6547 m_staticText10->Wrap(-1);
6548 fgSizer2->Add(m_staticText10, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6550 m_colourPicker4 =
new wxColourPickerCtrl(
6551 this, wxID_ANY, Properties.m_Arrow_Second_Colour, wxDefaultPosition,
6552 wxDefaultSize, wxCLRP_DEFAULT_STYLE);
6553 fgSizer2->Add(m_colourPicker4, 0, wxALL, 5);
6555 m_staticline1 =
new wxStaticLine(
this, wxID_ANY, wxDefaultPosition,
6556 wxDefaultSize, wxLI_HORIZONTAL);
6557 fgSizer2->Add(m_staticline1, 0, wxEXPAND | wxALL, 5);
6559 m_staticline2 =
new wxStaticLine(
this, wxID_ANY, wxDefaultPosition,
6560 wxDefaultSize, wxLI_HORIZONTAL);
6561 fgSizer2->Add(m_staticline2, 0, wxEXPAND | wxALL, 5);
6563 fgSizer2->Add(0, 5, 1, wxEXPAND, 5);
6565 fgSizer2->Add(0, 0, 1, wxEXPAND, 5);
6567 m_staticText7 =
new wxStaticText(
this, wxID_ANY, wxEmptyString,
6568 wxDefaultPosition, wxDefaultSize, 0);
6569 m_staticText7->Wrap(-1);
6570 fgSizer2->Add(m_staticText7, 0, wxALL, 5);
6572 m_button1 =
new wxButton(
this, wxID_ANY, _(
"Set default"), wxDefaultPosition,
6574 fgSizer2->Add(m_button1, 0, wxALL, 5);
6576 fgSizer2->Add(0, 5, 1, wxEXPAND, 5);
6578 fgSizer2->Add(5, 0, 1, wxEXPAND, 5);
6580 bSizer5->Add(fgSizer2, 1, wxALL | wxEXPAND, 5);
6582 m_sdbSizer3 =
new wxStdDialogButtonSizer();
6583 m_sdbSizer3OK =
new wxButton(
this, wxID_OK);
6584 m_sdbSizer3->AddButton(m_sdbSizer3OK);
6585 m_sdbSizer3Cancel =
new wxButton(
this, wxID_CANCEL);
6586 m_sdbSizer3->AddButton(m_sdbSizer3Cancel);
6587 m_sdbSizer3->Realize();
6589 bSizer5->Add(m_sdbSizer3, 0, 0, 1);
6591 bSizer5->Add(0, 10, 0, wxEXPAND, 5);
6593 this->SetSizer(bSizer5);
6597 this->Centre(wxBOTH);
6600 m_button1->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
6601 wxCommandEventHandler(EditDialog::OnSetdefault), NULL,
6605EditDialog::~EditDialog() {
6607 m_button1->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED,
6608 wxCommandEventHandler(EditDialog::OnSetdefault), NULL,
6612void EditDialog::OnSetdefault(wxCommandEvent &event) {
6613 m_fontPicker2->SetSelectedFont(g_USFontTitle.GetChosenFont());
6614 m_fontPicker2->SetSelectedColour(g_USFontTitle.GetColour());
6615 m_fontPicker4->SetSelectedFont(g_USFontData.GetChosenFont());
6616 m_fontPicker4->SetSelectedColour(g_USFontData.GetColour());
6617 m_fontPicker5->SetSelectedFont(g_USFontLabel.GetChosenFont());
6618 m_fontPicker5->SetSelectedColour(g_USFontLabel.GetColour());
6619 m_fontPicker6->SetSelectedFont(g_USFontSmall.GetChosenFont());
6620 m_fontPicker6->SetSelectedColour(g_USFontSmall.GetColour());
6622 GetGlobalColor(_T(
"DASHL"), &dummy);
6623 m_colourPicker1->SetColour(dummy);
6624 GetGlobalColor(_T(
"DASHB"), &dummy);
6625 m_colourPicker2->SetColour(dummy);
6626 GetGlobalColor(_T(
"DASHN"), &dummy);
6627 m_colourPicker3->SetColour(dummy);
6628 GetGlobalColor(_T(
"BLUE3"), &dummy);
6629 m_colourPicker4->SetColour(dummy);
6635void dashboard_pi::UpdateSumLog(
bool write) {
6637 g_dSumLogNM += d_tripNM;
6640 if (++confprint > 10) {
6641 wxFileConfig *logConf = (wxFileConfig *)m_pconfig;
6643 logConf->SetPath(
"/PlugIns/Dashboard");
6644 logConf->Write(
"SumLogNM", g_dSumLogNM);
6650 if (g_bUseInternSumLog) {
6651 SendSentenceToAllInstruments(
6660 SendSentenceToAllInstruments(
6664 mLOG_Watchdog = no_nav_watchdog_timeout_ticks;
A dashboard instrument that displays the current computer time.
A dashboard instrument that displays the GNSS clock time, if available.
A dashboard instrument that displays current moon phase information.
A dashboard instrument that displays sunrise and sunset times.
Custom event class for OpenCPN's notification system.
Extended position fix information.
int nSats
Number of satellites used in the fix.
double Var
Magnetic variation in degrees, typically from RMC message.
double Cog
Course over ground in degrees [0-360).
double Lat
Latitude in decimal degrees.
double Hdm
Heading magnetic in degrees [0-360).
time_t FixTime
UTC time of fix.
double Lon
Longitude in decimal degrees.
double Sog
Speed over ground in knots.
double Hdt
Heading true in degrees [0-360).
void SetCursorLatLon(double lat, double lon)
Receives cursor lat/lon position updates.
void ShowPreferencesDialog(wxWindow *parent)
Shows the plugin preferences dialog.
void OnToolbarToolCallback(int id)
Handles toolbar tool clicks.
void SetColorScheme(PI_ColorScheme cs)
Updates plugin color scheme.
void SetPositionFixEx(PlugIn_Position_Fix_Ex &pfix)
Updates plugin with extended position fix data at regular intervals.
int GetToolbarToolCount(void)
Returns the number of toolbar tools this plugin provides.
wxString GetCommonName()
Get the plugin's common (short) name.
wxString GetShortDescription()
Get a brief description of the plugin.
void UpdateAuiStatus(void)
Updates AUI manager status.
int GetAPIVersionMinor()
Returns the minor version number of the plugin API that this plugin supports.
wxBitmap * GetPlugInBitmap()
Get the plugin's icon bitmap.
void SetNMEASentence(wxString &sentence)
Receive all NMEA 0183 sentences from OpenCPN.
int GetAPIVersionMajor()
Returns the major version number of the plugin API that this plugin supports.
wxString GetLongDescription()
Get detailed plugin information.
int GetPlugInVersionMinor()
Returns the minor version number of the plugin itself.
bool DeInit(void)
Clean up plugin resources.
int Init(void)
Initialize the plugin and declare its capabilities.
int GetPlugInVersionMajor()
Returns the major version number of the plugin itself.
Base class for OpenCPN plugins.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
bool IsArray() const
Return TRUE if the type of the value stored is an array type.
int Size() const
Return the size of the array or map stored in this value.
bool HasMember(unsigned index) const
Return TRUE if the object contains an element at the specified index.
double AsDouble() const
Return the stored value as a double.
bool IsString() const
Return TRUE if the type of the value stored is a wxString object.
wxString AsString() const
Return the stored value as a wxWidget's string.
#define WANTS_NMEA_EVENTS
Receive decoded NMEA events with parsed data.
PI_ColorScheme
Color schemes for different lighting conditions.
#define USES_AUI_MANAGER
Plugin uses wxAuiManager for window management.
#define WANTS_NMEA_SENTENCES
Receive raw NMEA 0183 sentences from all active ports.
#define WANTS_PREFERENCES
Plugin will add page(s) to global preferences dialog.
#define WANTS_CONFIG
Plugin requires persistent configuration storage.
#define WANTS_PLUGIN_MESSAGING
Enable message passing between plugins.
#define INSTALLS_TOOLBAR_TOOL
Plugin will add one or more toolbar buttons.
#define WANTS_CURSOR_LATLON
Receive updates when cursor moves over chart.
#define WANTS_TOOLBAR_CALLBACK
Receive notification when user left-clicks plugin's toolbar buttons.
double toUsrTemp_Plugin(double cel_temp, int unit)
Converts Celsius to user's preferred temperature unit.
wxWindow * GetOCPNCanvasWindow()
Gets OpenCPN's main canvas window.
wxFont * OCPNGetFont(wxString TextElement, int default_size)
Gets a font for UI elements.
wxString getUsrDistanceUnit_Plugin(int unit)
Gets display string for user's preferred distance unit.
wxFileConfig * GetOCPNConfigObject()
Gets OpenCPN's configuration object.
wxBitmap GetBitmapFromSVGFile(wxString filename, unsigned int width, unsigned int height)
Creates bitmap from SVG file.
double toUsrDistance_Plugin(double nm_distance, int unit)
Converts nautical miles to user's preferred distance unit.
int InsertPlugInToolSVG(wxString label, wxString SVGfile, wxString SVGfileRollover, wxString SVGfileToggled, wxItemKind kind, wxString shortHelp, wxString longHelp, wxObject *clientData, int position, int tool_sel, opencpn_plugin *pplugin)
Adds a tool using SVG graphics.
wxString getUsrSpeedUnit_Plugin(int unit)
Gets display string for user's preferred speed unit.
wxString * GetpSharedDataLocation()
Gets shared application data location.
void DimeWindow(wxWindow *win)
Applies system color scheme to window.
double GetOCPNGUIToolScaleFactor_PlugIn()
Gets current global GUI scaling factor.
wxString getUsrTempUnit_Plugin(int unit)
Gets display string for user's preferred temperature unit.
wxString GetActiveStyleName()
Gets name of currently active style sheet.
bool DecodeSingleVDOMessage(const wxString &str, PlugIn_Position_Fix_Ex *pos, wxString *accumulator)
Decodes a single VDO (Own Ship AIS) message.
wxAuiManager * GetFrameAuiManager()
Gets main frame AUI manager.
double toUsrSpeed_Plugin(double kts_speed, int unit)
Converts knots to user's preferred speed unit.
std::vector< std::string > GetActivePriorityIdentifiers()
Gets list of active priority identifiers.
void SetToolbarItemState(int item, bool toggle)
Sets toolbar item toggle state.
double OCPN_GetWinDIPScaleFactor()
Gets Windows-specific DPI scaling factor.
bool AddLocaleCatalog(wxString catalog)
Adds a locale catalog for translations.
double fromUsrDistance_Plugin(double usr_distance, int unit)
Converts from user's preferred distance unit to nautical miles.
shared_ptr< ObservableListener > GetListener(NMEA2000Id id, wxEventType et, wxEvtHandler *eh)
Gets listener for NMEA 2000 messages.
std::string GetN2000Source(NMEA2000Id id, ObservedEvt ev)
Return source identifier (iface) of a received n2000 message of type id in ev.
vector< uint8_t > GetN2000Payload(NMEA2000Id id, ObservedEvt ev)
Return N2K payload for a received n2000 message of type id in ev.
Identifier for NMEA 2000 message types.