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(
"nmea2000") != 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 source +=
":" + ident;
2287 if (source != prioN2kPGNsat)
return;
2290 uint16_t DaysSince1970;
2291 double SecondsSinceMidnight;
2292 double Latitude, Longitude, Altitude;
2293 tN2kGNSStype GNSStype;
2294 tN2kGNSSmethod GNSSmethod;
2295 unsigned char nSatellites;
2296 double HDOP, PDOP, GeoidalSeparation;
2297 unsigned char nReferenceStations;
2298 tN2kGNSStype ReferenceStationType;
2299 uint16_t ReferenceSationID;
2300 double AgeOfCorrection;
2303 if (ParseN2kPGN129029(v, SID, DaysSince1970, SecondsSinceMidnight, Latitude,
2304 Longitude, Altitude, GNSStype, GNSSmethod, nSatellites,
2305 HDOP, PDOP, GeoidalSeparation, nReferenceStations,
2306 ReferenceStationType, ReferenceSationID,
2316 talker_N2k =
"GPSGLONAS";
2322 talker_N2k =
"GPSGLONAS";
2325 talker_N2k =
"Chayka";
2331 talker_N2k = wxEmptyString;
2333 if (!N2kIsNA(Altitude)) {
2335 SendSentenceToAllInstruments(OCPN_DBP_STC_ALTI, Altitude, _T(
"m"));
2337 mALT_Watchdog = gps_watchdog_timeout_ticks;
2343void dashboard_pi::HandleN2K_129540(
ObservedEvt ev) {
2348 unsigned char source_id = v.at(7);
2350 sprintf(ss,
"%d", source_id);
2351 std::string ident = std::string(ss);
2353 source +=
":" + ident;
2355 if (source != prioN2kPGNsat)
return;
2358 tN2kRangeResidualMode Mode;
2359 uint8_t NumberOfSVs;
2362 if (ParseN2kPGN129540(v, SID, Mode, NumberOfSVs)) {
2363 if (!N2kIsNA(NumberOfSVs) && mPriSatStatus == 1) {
2366 SAT_INFO N2K_SatInfo[4];
2369 double dElevRad = 0;
2370 double dAzimRad = 0;
2373 for (
int iMesNum = 0; iMesNum < 3; iMesNum++) {
2374 for (idx = 0; idx < 4; idx++) {
2375 tSatelliteInfo SatelliteInfo;
2376 index = idx + 4 * iMesNum;
2377 if (index >= NumberOfSVs - 1)
break;
2378 if (ParseN2kPGN129540(v, index, SatelliteInfo)) {
2379 iPRN = (int)SatelliteInfo.PRN;
2380 dElevRad = SatelliteInfo.Elevation;
2381 dAzimRad = SatelliteInfo.Azimuth;
2382 iSNR = N2kIsNA(SatelliteInfo.SNR) ? 0 : (int)SatelliteInfo.SNR;
2384 N2K_SatInfo[idx].SatNumber = iPRN;
2385 N2K_SatInfo[idx].ElevationDegrees = GEODESIC_RAD2DEG(dElevRad);
2386 N2K_SatInfo[idx].AzimuthDegreesTrue = GEODESIC_RAD2DEG(dAzimRad);
2387 N2K_SatInfo[idx].SignalToNoiseRatio = iSNR;
2392 SendSatInfoToAllInstruments(NumberOfSVs, iMesNum + 1, talker_N2k,
2395 mSatStatus_Wdog = gps_watchdog_timeout_ticks;
2403void dashboard_pi::HandleN2K_130306(
ObservedEvt ev) {
2411 double WindSpeed, WindAngle;
2412 tN2kWindReference WindReference;
2415 if (ParseN2kPGN130306(v, SID, WindSpeed, WindAngle, WindReference)) {
2416 if (!N2kIsNA(WindSpeed) && !N2kIsNA(WindAngle)) {
2417 double wind_angle_degr = GEODESIC_RAD2DEG(WindAngle);
2418 double wind_speed_kn = MS2KNOTS(WindSpeed);
2419 bool sendTWA =
false, sendTWS =
false;
2421 switch (WindReference) {
2424 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, wind_angle_degr,
2428 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
2434 if (!std::isnan(mVar)) {
2435 wind_angle_degr += mVar;
2436 if (wind_angle_degr > 360.) {
2437 wind_angle_degr -= 360;
2438 }
else if (wind_angle_degr < 0.) {
2439 wind_angle_degr += 360;
2442 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, wind_angle_degr,
2446 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
2451 double calc_angle = wind_angle_degr;
2453 wxString m_awaunit = _T(
"\u00B0R");
2455 if (wind_angle_degr > 180.0) {
2456 wind_angle_degr = 360.0 - wind_angle_degr;
2457 m_awaunit = _T(
"\u00B0L");
2459 SendSentenceToAllInstruments(OCPN_DBP_STC_AWA,
2460 mAWAFilter.filter(wind_angle_degr),
2463 SendSentenceToAllInstruments(
2466 g_iDashWindSpeedUnit),
2470 mMWVA_Watchdog = gps_watchdog_timeout_ticks;
2475 if (calc_angle > 180) calc_angle -= 360.0;
2476 CalculateAndUpdateTWDS(wind_speed_kn, calc_angle);
2479 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
2480 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
2485 if (mPriTWA >= 1 && g_bDBtrueWindGround) {
2492 if (mPriTWA >= 1 && !g_bDBtrueWindGround) {
2508 wxString m_twaunit = _T(
"\u00B0R");
2510 if (wind_angle_degr > 180.0) {
2511 wind_angle_degr = 360.0 - wind_angle_degr;
2512 m_twaunit = _T(
"\u00B0L");
2514 SendSentenceToAllInstruments(OCPN_DBP_STC_TWA, wind_angle_degr,
2520 SendSentenceToAllInstruments(
2524 SendSentenceToAllInstruments(
2528 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
2534void dashboard_pi::HandleN2K_130310(
ObservedEvt ev) {
2538 double WaterTemperature, OutsideAmbientAirTemperature, AtmosphericPressure;
2541 if (ParseN2kPGN130310(v, SID, WaterTemperature, OutsideAmbientAirTemperature,
2542 AtmosphericPressure)) {
2544 if (!N2kIsNA(WaterTemperature)) {
2545 double m_wtemp KELVIN2C(WaterTemperature);
2546 SendSentenceToAllInstruments(OCPN_DBP_STC_TMP,
2550 mWTP_Watchdog = no_nav_watchdog_timeout_ticks;
2554 if (mPriATMP >= 1) {
2555 if (!N2kIsNA(OutsideAmbientAirTemperature)) {
2556 double m_airtemp = KELVIN2C(OutsideAmbientAirTemperature);
2557 if (m_airtemp > -60 && m_airtemp < 100) {
2558 SendSentenceToAllInstruments(
2562 mATMP_Watchdog = no_nav_watchdog_timeout_ticks;
2567 if (!N2kIsNA(AtmosphericPressure) && mPriMDA >= 1) {
2568 double m_press = PA2HPA(AtmosphericPressure);
2569 SendSentenceToAllInstruments(OCPN_DBP_STC_MDA, m_press, _T(
"hPa"));
2571 mMDA_Watchdog = no_nav_watchdog_timeout_ticks;
2576void dashboard_pi::HandleN2K_130313(
ObservedEvt ev) {
2579 unsigned char SID, HumidityInstance;
2580 tN2kHumiditySource HumiditySource;
2581 double ActualHumidity, SetHumidity;
2583 if (ParseN2kPGN130313(v, SID, HumidityInstance, HumiditySource,
2584 ActualHumidity, SetHumidity)) {
2586 if (!N2kIsNA(ActualHumidity)) {
2587 SendSentenceToAllInstruments(OCPN_DBP_STC_HUM, ActualHumidity,
"%");
2589 mHUM_Watchdog = no_nav_watchdog_timeout_ticks;
2596void dashboard_pi::ParseSignalK(wxString &msg) {
2600 int errors = jsonReader.
Parse(msg, &root);
2608 if (root[
"self"].AsString().StartsWith(_T(
"vessels.")))
2609 m_self = (root[
"self"].
AsString());
2611 else if (root[
"self"].AsString().Length())
2613 _T(
"vessels.") + (root[
"self"].
AsString());
2617 auto context = root[
"context"].
AsString();
2618 if (context != m_self) {
2625 for (
int i = 0; i < updates.
Size(); ++i) {
2626 handleSKUpdate(updates[i]);
2631void dashboard_pi::handleSKUpdate(
wxJSONValue &update) {
2632 wxString sfixtime =
"";
2635 sfixtime = update[
"timestamp"].
AsString();
2637 if (update.
HasMember(
"values") && update[
"values"].IsArray()) {
2638 wxString talker = wxEmptyString;
2640 if (update[
"source"].HasMember(
"talker")) {
2641 if (update[
"source"][
"talker"].IsString()) {
2642 talker = update[
"source"][
"talker"].
AsString();
2646 for (
int j = 0; j < update[
"values"].
Size(); ++j) {
2648 updateSKItem(item, talker, sfixtime);
2653void dashboard_pi::updateSKItem(
wxJSONValue &item, wxString &talker,
2654 wxString &sfixtime) {
2656 const wxString &update_path = item[
"path"].
AsString();
2660 static wxString talkerID = wxEmptyString;
2662 static double skAWA;
2664 if (update_path == _T(
"navigation.position")) {
2665 if (mPriPosition >= 2) {
2666 if (value[
"latitude"].IsDouble() && value[
"longitude"].IsDouble()) {
2667 double lat = value[
"latitude"].
AsDouble();
2668 double lon = value[
"longitude"].AsDouble();
2669 SendSentenceToAllInstruments(OCPN_DBP_STC_LAT, lat, _T(
"SDMM"));
2670 SendSentenceToAllInstruments(OCPN_DBP_STC_LON, lon, _T(
"SDMM"));
2674 }
else if (update_path == _T(
"navigation.speedOverGround") &&
2675 2 == mPriPosition) {
2676 double sog_knot = GetJsonDouble(value);
2677 if (std::isnan(sog_knot))
return;
2679 SendSentenceToAllInstruments(
2683 }
else if (update_path == _T(
"navigation.courseOverGroundTrue") &&
2684 2 == mPriPosition) {
2685 double cog_rad = GetJsonDouble(value);
2686 if (std::isnan(cog_rad))
return;
2688 double cog_deg = GEODESIC_RAD2DEG(cog_rad);
2689 SendSentenceToAllInstruments(OCPN_DBP_STC_COG, mCOGFilter.filter(cog_deg),
2691 }
else if (update_path == _T(
"navigation.headingTrue")) {
2692 if (mPriHeadingT >= 2) {
2693 double hdt = GetJsonDouble(value);
2694 if (std::isnan(hdt))
return;
2696 hdt = GEODESIC_RAD2DEG(hdt);
2697 SendSentenceToAllInstruments(OCPN_DBP_STC_HDT, hdt, _T(
"\u00B0T"));
2699 mHDT_Watchdog = gps_watchdog_timeout_ticks;
2701 }
else if (update_path == _T(
"navigation.headingMagnetic")) {
2702 if (mPriHeadingM >= 2) {
2703 double hdm = GetJsonDouble(value);
2704 if (std::isnan(hdm))
return;
2706 hdm = GEODESIC_RAD2DEG(hdm);
2707 SendSentenceToAllInstruments(OCPN_DBP_STC_HDM, hdm, _T(
"\u00B0M"));
2709 mHDx_Watchdog = gps_watchdog_timeout_ticks;
2712 if (mPriHeadingT >= 6 && (!std::isnan(mVar))) {
2713 double heading = hdm + mVar;
2716 else if (heading >= 360.0)
2718 SendSentenceToAllInstruments(OCPN_DBP_STC_HDT, heading, _T(
"\u00B0"));
2720 mHDT_Watchdog = gps_watchdog_timeout_ticks;
2723 }
else if (update_path == _T(
"navigation.speedThroughWater")) {
2725 double stw_knots = GetJsonDouble(value);
2726 if (std::isnan(stw_knots))
return;
2728 stw_knots = MS2KNOTS(stw_knots);
2729 SendSentenceToAllInstruments(
2733 mSTW_Watchdog = gps_watchdog_timeout_ticks;
2735 }
else if (update_path == _T(
"navigation.magneticVariation")) {
2737 double dvar = GetJsonDouble(value);
2738 if (std::isnan(dvar))
return;
2740 dvar = GEODESIC_RAD2DEG(dvar);
2742 SendSentenceToAllInstruments(OCPN_DBP_STC_HMV, dvar, _T(
"\u00B0"));
2744 mVar_Watchdog = gps_watchdog_timeout_ticks;
2747 }
else if (update_path == _T(
"environment.wind.angleApparent")) {
2749 double m_awaangle = GetJsonDouble(value);
2750 if (std::isnan(m_awaangle))
return;
2752 m_awaangle = GEODESIC_RAD2DEG(m_awaangle);
2754 wxString m_awaunit = _T(
"\u00B0R");
2755 if (m_awaangle < 0) {
2756 m_awaunit = _T(
"\u00B0L");
2759 SendSentenceToAllInstruments(OCPN_DBP_STC_AWA,
2760 mAWAFilter.filter(m_awaangle), m_awaunit);
2762 mMWVA_Watchdog = gps_watchdog_timeout_ticks;
2764 }
else if (update_path == _T(
"environment.wind.speedApparent")) {
2766 double m_awaspeed_kn = GetJsonDouble(value);
2767 if (std::isnan(m_awaspeed_kn))
return;
2769 m_awaspeed_kn = MS2KNOTS(m_awaspeed_kn);
2770 SendSentenceToAllInstruments(
2773 g_iDashWindSpeedUnit),
2777 if (mPriTWA >= 6 && !std::isnan(skAWA)) {
2778 CalculateAndUpdateTWDS(m_awaspeed_kn, skAWA);
2780 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
2781 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
2784 }
else if ((update_path == _T(
"environment.wind.angleTrueWater") &&
2785 !g_bDBtrueWindGround) ||
2786 (update_path == _T(
"environment.wind.angleTrueGround") &&
2787 g_bDBtrueWindGround)) {
2789 double m_twaangle = GetJsonDouble(value);
2790 if (std::isnan(m_twaangle))
return;
2792 m_twaangle = GEODESIC_RAD2DEG(m_twaangle);
2793 double m_twaangle_raw = m_twaangle;
2794 wxString m_twaunit = _T(
"\u00B0R");
2795 if (m_twaangle < 0) {
2796 m_twaunit = _T(
"\u00B0L");
2799 SendSentenceToAllInstruments(OCPN_DBP_STC_TWA, m_twaangle, m_twaunit);
2801 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
2808 if (g_dHDT < 361. && g_dHDT >= 0.0) {
2809 double g_dCalWdir = (m_twaangle_raw) + g_dHDT;
2810 if (g_dCalWdir > 360.) {
2812 }
else if (g_dCalWdir < 0.) {
2815 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, g_dCalWdir,
2818 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
2822 }
else if ((update_path == _T(
"environment.wind.speedTrue") &&
2823 !g_bDBtrueWindGround) ||
2824 (update_path == _T(
"environment.wind.speedOverGround") &&
2825 g_bDBtrueWindGround)) {
2827 double m_twaspeed_kn = GetJsonDouble(value);
2828 if (std::isnan(m_twaspeed_kn))
return;
2830 m_twaspeed_kn = MS2KNOTS(m_twaspeed_kn);
2831 SendSentenceToAllInstruments(
2835 SendSentenceToAllInstruments(
2840 }
else if (update_path == _T(
"environment.depth.belowSurface")) {
2841 if (mPriDepth >= 3) {
2842 double depth = GetJsonDouble(value);
2843 if (std::isnan(depth))
return;
2846 depth += g_dDashDBTOffset;
2848 SendSentenceToAllInstruments(
2851 mDPT_DBT_Watchdog = gps_watchdog_timeout_ticks;
2853 }
else if (update_path == _T(
"environment.depth.belowTransducer")) {
2854 if (mPriDepth >= 3) {
2855 double depth = GetJsonDouble(value);
2856 if (std::isnan(depth))
return;
2859 depth += g_dDashDBTOffset;
2861 SendSentenceToAllInstruments(
2864 mDPT_DBT_Watchdog = gps_watchdog_timeout_ticks;
2866 }
else if (update_path == _T(
"environment.water.temperature")) {
2868 double m_wtemp = GetJsonDouble(value);
2869 if (std::isnan(m_wtemp))
return;
2871 m_wtemp = KELVIN2C(m_wtemp);
2872 if (m_wtemp > -60 && m_wtemp < 200 && !std::isnan(m_wtemp)) {
2873 SendSentenceToAllInstruments(
2877 mWTP_Watchdog = no_nav_watchdog_timeout_ticks;
2880 }
else if (update_path ==
2881 _T(
"navigation.courseRhumbline.nextPoint.velocityMadeGood")) {
2882 double m_vmg_kn = GetJsonDouble(value);
2883 if (std::isnan(m_vmg_kn))
return;
2885 m_vmg_kn = MS2KNOTS(m_vmg_kn);
2886 SendSentenceToAllInstruments(
2889 mVMG_Watchdog = gps_watchdog_timeout_ticks;
2892 else if (update_path == _T(
"performance.velocityMadeGood")) {
2893 double m_vmgw_kn = GetJsonDouble(value);
2894 if (std::isnan(m_vmgw_kn))
return;
2896 m_vmgw_kn = MS2KNOTS(m_vmgw_kn);
2897 SendSentenceToAllInstruments(
2900 mVMGW_Watchdog = gps_watchdog_timeout_ticks;
2903 else if (update_path == _T(
"steering.rudderAngle")) {
2905 double m_rudangle = GetJsonDouble(value);
2906 if (std::isnan(m_rudangle))
return;
2908 m_rudangle = GEODESIC_RAD2DEG(m_rudangle);
2909 SendSentenceToAllInstruments(OCPN_DBP_STC_RSA, m_rudangle,
2911 mRSA_Watchdog = gps_watchdog_timeout_ticks;
2914 }
else if (update_path ==
2915 _T(
"navigation.gnss.satellites")) {
2916 if (mPriSatUsed >= 2) {
2917 int usedSats = (value).AsInt();
2918 if (usedSats < 1)
return;
2919 SendSentenceToAllInstruments(OCPN_DBP_STC_SAT, usedSats, _T (
""));
2921 mSatsUsed_Wdog = gps_watchdog_timeout_ticks;
2923 }
else if (update_path == _T(
"navigation.gnss.type")) {
2924 if (value.IsString() && value.AsString() != wxEmptyString) {
2925 talkerID = (value.AsString());
2926 talkerID.MakeUpper();
2927 m_PriN2kTalker = gps_watchdog_timeout_ticks;
2928 if ((talkerID.Contains(_T(
"GPS"))) &&
2929 (talkerID.Contains(_T(
"GLONASS"))))
2930 talkerID = _T(
"GPSGLONAS");
2931 else if (talkerID.Contains(_T(
"GPS")))
2932 talkerID = _T(
"GP");
2933 else if (talkerID.Contains(_T(
"GLONASS")))
2934 talkerID = _T(
"GL");
2935 else if (talkerID.Contains(_T(
"GALILEO")))
2936 talkerID = _T(
"GA");
2937 else if (talkerID.Contains(_T(
"BEIDOU")))
2938 talkerID = _T(
"GI");
2940 }
else if (update_path ==
2941 _T(
"navigation.gnss.satellitesInView")) {
2943 if (mPriSatUsed >= 4) {
2944 if (value.HasMember(
"count") && value[
"count"].IsInt()) {
2945 double m_SK_SatsInView = (value[
"count"].AsInt());
2946 SendSentenceToAllInstruments(OCPN_DBP_STC_SAT, m_SK_SatsInView,
2949 mSatsUsed_Wdog = gps_watchdog_timeout_ticks;
2952 if (mPriSatStatus == 2) {
2953 if (value.HasMember(
"satellites") && value[
"satellites"].IsArray()) {
2956 if (value.HasMember(
"count") && value[
"count"].IsInt()) {
2957 iNumSats = (value[
"count"].AsInt());
2959 iNumSats = value[_T (
"satellites")].Size();
2961 SAT_INFO SK_SatInfo[4];
2962 for (
int idx = 0; idx < 4; idx++) {
2963 SK_SatInfo[idx].SatNumber = 0;
2964 SK_SatInfo[idx].ElevationDegrees = 0;
2965 SK_SatInfo[idx].AzimuthDegreesTrue = 0;
2966 SK_SatInfo[idx].SignalToNoiseRatio = 0;
2973 double dElevRad = 0;
2974 double dAzimRad = 0;
2977 for (
int iMesNum = 0; iMesNum < 3; iMesNum++) {
2978 for (idx = 0; idx < 4; idx++) {
2979 arr = idx + 4 * iMesNum;
2980 if (value[
"satellites"][arr][
"id"].IsInt())
2981 iID = value[
"satellites"][arr][
"id"].AsInt();
2982 if (value[
"satellites"][arr][
"elevation"].IsDouble())
2983 dElevRad = value[
"satellites"][arr][
"elevation"].AsDouble();
2984 if (value[
"satellites"][arr][
"azimuth"].IsDouble())
2985 dAzimRad = value[
"satellites"][arr][
"azimuth"].AsDouble();
2986 if (value[
"satellites"][arr][
"SNR"].IsInt())
2987 iSNR = value[
"satellites"][arr][
"SNR"].AsInt();
2990 SK_SatInfo[idx].SatNumber = iID;
2991 SK_SatInfo[idx].ElevationDegrees = GEODESIC_RAD2DEG(dElevRad);
2992 SK_SatInfo[idx].AzimuthDegreesTrue = GEODESIC_RAD2DEG(dAzimRad);
2993 SK_SatInfo[idx].SignalToNoiseRatio = iSNR;
2996 if (m_PriN2kTalker <= 0 && talker != wxEmptyString &&
2997 (talker.StartsWith(_T(
"G")) ||
2998 talker.StartsWith(_T(
"BD")))) {
3001 SendSatInfoToAllInstruments(iNumSats, iMesNum + 1, talkerID,
3004 mSatStatus_Wdog = gps_watchdog_timeout_ticks;
3012 }
else if (update_path == _T(
"navigation.gnss.antennaAltitude")) {
3014 double m_alt = GetJsonDouble(value);
3015 if (std::isnan(m_alt))
return;
3017 SendSentenceToAllInstruments(OCPN_DBP_STC_ALTI, m_alt, _T(
"m"));
3019 mALT_Watchdog = gps_watchdog_timeout_ticks;
3022 }
else if (update_path == _T(
"navigation.datetime")) {
3023 if (mPriDateTime >= 1) {
3025 wxString s_dt = (value.AsString());
3026 s_dt.Replace(
'-', wxEmptyString);
3027 s_dt.Replace(
':', wxEmptyString);
3028 wxString utc_dt = s_dt.BeforeFirst(
'T');
3029 utc_dt.Append(s_dt.AfterFirst(
'T').Left(6));
3030 mUTCDateTime.ParseFormat(utc_dt.c_str(), _T(
"%Y%m%d%H%M%S"));
3031 mUTC_Watchdog = gps_watchdog_timeout_ticks;
3033 }
else if (update_path == _T(
"environment.outside.temperature")) {
3034 if (mPriATMP >= 2) {
3035 double m_airtemp = GetJsonDouble(value);
3036 if (std::isnan(m_airtemp))
return;
3038 m_airtemp = KELVIN2C(m_airtemp);
3039 if (m_airtemp > -60 && m_airtemp < 100) {
3040 SendSentenceToAllInstruments(
3044 mATMP_Watchdog = no_nav_watchdog_timeout_ticks;
3047 }
else if (update_path == _T(
"environment.outside.humidity") ||
3048 update_path == _T(
"environment.outside.relativeHumidity")) {
3050 double m_hum = GetJsonDouble(value) * 100;
3051 if (std::isnan(m_hum))
return;
3052 SendSentenceToAllInstruments(OCPN_DBP_STC_HUM, m_hum,
"%");
3054 mHUM_Watchdog = no_nav_watchdog_timeout_ticks;
3056 }
else if (update_path ==
3057 _T(
"environment.wind.directionTrue")) {
3059 double m_twdT = GetJsonDouble(value);
3060 if (std::isnan(m_twdT))
return;
3062 m_twdT = GEODESIC_RAD2DEG(m_twdT);
3063 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, m_twdT, _T(
"\u00B0"));
3065 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
3067 }
else if (update_path == _T(
"environment.wind.directionMagnetic")) {
3070 double m_twdM = GetJsonDouble(value);
3071 if (std::isnan(m_twdM))
return;
3072 m_twdM = GEODESIC_RAD2DEG(m_twdM);
3074 if (!std::isnan(mVar)) {
3075 m_twdM = (m_twdM) + mVar;
3076 if (m_twdM > 360.) {
3078 }
else if (m_twdM < 0.) {
3082 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, m_twdM, _T(
"\u00B0"));
3084 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
3086 }
else if (update_path == _T(
"navigation.trip.log")) {
3087 double m_tlog = GetJsonDouble(value);
3088 if (std::isnan(m_tlog))
return;
3090 m_tlog = METERS2NM(m_tlog);
3091 SendSentenceToAllInstruments(
3094 mTrLOG_Watchdog = no_nav_watchdog_timeout_ticks;
3095 }
else if (update_path == _T(
"navigation.log")) {
3096 double m_slog = GetJsonDouble(value);
3097 if (std::isnan(m_slog))
return;
3099 m_slog = METERS2NM(m_slog);
3100 SendSentenceToAllInstruments(
3103 mLOG_Watchdog = no_nav_watchdog_timeout_ticks;
3104 }
else if (update_path == _T(
"environment.outside.pressure") &&
3106 double m_press = GetJsonDouble(value);
3107 if (std::isnan(m_press))
return;
3109 m_press = PA2HPA(m_press);
3110 SendSentenceToAllInstruments(OCPN_DBP_STC_MDA, m_press, _T(
"hPa"));
3112 mMDA_Watchdog = no_nav_watchdog_timeout_ticks;
3113 }
else if (update_path == _T(
"navigation.attitude")) {
3114 if (mPriPitchRoll >= 2) {
3115 if (value[
"roll"].AsString() !=
"0") {
3116 double m_heel = GEODESIC_RAD2DEG(value[
"roll"].AsDouble());
3117 wxString h_unit = _T(
"\u00B0\u003E") + _(
"Stbd");
3119 h_unit = _T(
"\u00B0\u003C") + _(
"Port");
3122 SendSentenceToAllInstruments(OCPN_DBP_STC_HEEL, m_heel, h_unit);
3123 mHEEL_Watchdog = gps_watchdog_timeout_ticks;
3126 if (value[
"pitch"].AsString() !=
"0") {
3127 double m_pitch = GEODESIC_RAD2DEG(value[
"pitch"].AsDouble());
3128 wxString p_unit = _T(
"\u00B0\u2191") + _(
"Up");
3130 p_unit = _T(
"\u00B0\u2193") + _(
"Down");
3133 SendSentenceToAllInstruments(OCPN_DBP_STC_PITCH, m_pitch, p_unit);
3134 mPITCH_Watchdog = gps_watchdog_timeout_ticks;
3144 if (mPriPosition >= 1) {
3146 SendSentenceToAllInstruments(OCPN_DBP_STC_LAT, pfix.
Lat, _T(
"SDMM"));
3147 SendSentenceToAllInstruments(OCPN_DBP_STC_LON, pfix.
Lon, _T(
"SDMM"));
3149 if (mPriCOGSOG >= 1) {
3150 double dMagneticCOG;
3152 SendSentenceToAllInstruments(
3156 SendSentenceToAllInstruments(OCPN_DBP_STC_COG, mCOGFilter.filter(pfix.
Cog),
3160 double logSOG = mSOGFilter.filter(pfix.
Sog);
3162 d_tripNM += logSOG / 3600;
3164 if (++logCount > 60) {
3171 dMagneticCOG = mCOGFilter.get() - pfix.
Var;
3172 if (dMagneticCOG < 0.0) dMagneticCOG = 360.0 + dMagneticCOG;
3173 if (dMagneticCOG > 360.0) dMagneticCOG = dMagneticCOG - 360.0;
3174 SendSentenceToAllInstruments(OCPN_DBP_STC_MCOG, dMagneticCOG,
3178 if (!std::isnan(pfix.
Var)) {
3181 mVar_Watchdog = gps_watchdog_timeout_ticks;
3183 SendSentenceToAllInstruments(OCPN_DBP_STC_HMV, pfix.
Var, _T(
"\u00B0"));
3186 if (mPriDateTime >= 6) {
3191 mUTCDateTime.Set(pfix.
FixTime);
3193 mUTCDateTime = wxInvalidDateTime;
3194 if (mUTCDateTime.IsValid()) {
3196 mUTCDateTime = mUTCDateTime.ToUTC();
3197 mUTC_Watchdog = gps_watchdog_timeout_ticks;
3200 if (mPriSatUsed >= 1) {
3201 mSatsInUse = pfix.
nSats;
3202 if (mSatsInUse > 0) {
3203 SendSentenceToAllInstruments(OCPN_DBP_STC_SAT, mSatsInUse, _T(
""));
3205 mSatsUsed_Wdog = gps_watchdog_timeout_ticks;
3208 if (mPriHeadingT >= 1) {
3209 double hdt = pfix.
Hdt;
3210 if (std::isnan(hdt))
return;
3211 SendSentenceToAllInstruments(OCPN_DBP_STC_HDT, hdt, _T(
"\u00B0T"));
3213 mHDT_Watchdog = gps_watchdog_timeout_ticks;
3215 if (mPriHeadingM >= 1) {
3216 double hdm = pfix.
Hdm;
3217 if (std::isnan(hdm) && !std::isnan(pfix.
Hdt) && !std::isnan(pfix.
Var)) {
3218 hdm = pfix.
Hdt - pfix.
Var;
3221 else if (hdm >= 360.0)
3224 if (std::isnan(hdm))
return;
3225 SendSentenceToAllInstruments(OCPN_DBP_STC_HDM, hdm, _T(
"\u00B0M"));
3227 mHDx_Watchdog = gps_watchdog_timeout_ticks;
3232 SendSentenceToAllInstruments(OCPN_DBP_STC_PLA, lat, _T(
"SDMM"));
3233 SendSentenceToAllInstruments(OCPN_DBP_STC_PLO, lon, _T(
"SDMM"));
3236void dashboard_pi::SetPluginMessage(wxString &message_id,
3237 wxString &message_body) {
3238 if (message_id == _T(
"WMM_VARIATION_BOAT")) {
3246 int numErrors = reader.
Parse(message_body, &root);
3247 if (numErrors > 0) {
3253 wxString decl = root[_T(
"Decl")].
AsString();
3255 decl.ToDouble(&decl_val);
3260 mVar_Watchdog = gps_watchdog_timeout_ticks;
3261 SendSentenceToAllInstruments(OCPN_DBP_STC_HMV, mVar, _T(
"\u00B0"));
3263 }
else if (message_id == _T(
"OCPN_CORE_SIGNALK")) {
3264 ParseSignalK(message_body);
3272 parent, wxID_ANY, m_ArrayOfDashboardWindow);
3274 dialog->RecalculateSize();
3276#ifdef __OCPN__ANDROID__
3277 dialog->GetHandle()->setStyleSheet(qtStyleSheet);
3280#ifdef __OCPN__ANDROID__
3284 int xmax = ccwin->GetSize().GetWidth();
3285 int ymax = ccwin->GetParent()
3288 dialog->SetSize(xmax, ymax);
3295 if (dialog->ShowModal() == wxID_OK) {
3296 double scaler = 1.0;
3299 scaler = wxMax(1.0, scaler);
3301 g_USFontTitle = *(dialog->m_pFontPickerTitle->GetFontData());
3302 g_FontTitle = *g_pUSFontTitle;
3303 g_FontTitle.SetChosenFont(g_pUSFontTitle->GetChosenFont().Scaled(scaler));
3304 g_FontTitle.SetColour(g_pUSFontTitle->GetColour());
3305 g_USFontTitle = *g_pUSFontTitle;
3307 g_USFontData = *(dialog->m_pFontPickerData->GetFontData());
3308 g_FontData = *g_pUSFontData;
3309 g_FontData.SetChosenFont(g_pUSFontData->GetChosenFont().Scaled(scaler));
3310 g_FontData.SetColour(g_pUSFontData->GetColour());
3311 g_USFontData = *g_pUSFontData;
3313 g_USFontLabel = *(dialog->m_pFontPickerLabel->GetFontData());
3314 g_FontLabel = *g_pUSFontLabel;
3315 g_FontLabel.SetChosenFont(g_pUSFontLabel->GetChosenFont().Scaled(scaler));
3316 g_FontLabel.SetColour(g_pUSFontLabel->GetColour());
3317 g_USFontLabel = *g_pUSFontLabel;
3319 g_USFontSmall = *(dialog->m_pFontPickerSmall->GetFontData());
3320 g_FontSmall = *g_pUSFontSmall;
3321 g_FontSmall.SetChosenFont(g_pUSFontSmall->GetChosenFont().Scaled(scaler));
3322 g_FontSmall.SetColour(g_pUSFontSmall->GetColour());
3323 g_USFontSmall = *g_pUSFontSmall;
3327 g_dashPrefWidth = dialog->GetSize().x;
3328 g_dashPrefHeight = dialog->GetSize().y;
3330 dialog->SaveDashboardConfig();
3331 m_ArrayOfDashboardWindow.Clear();
3332 m_ArrayOfDashboardWindow = dialog->m_Config;
3342 aktuellColorScheme = cs;
3343 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3345 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow;
3346 if (dashboard_window) dashboard_window->SetColorScheme(cs);
3350int dashboard_pi::GetDashboardWindowShownCount() {
3353 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3355 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow;
3356 if (dashboard_window) {
3357 wxAuiPaneInfo &pane = m_pauimgr->GetPane(dashboard_window);
3358 if (pane.IsOk() && pane.IsShown()) cnt++;
3364void dashboard_pi::OnPaneClose(wxAuiManagerEvent &event) {
3368 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3373 if (dashboard_window != d_w) {
3374 wxAuiPaneInfo &pane = m_pauimgr->GetPane(d_w);
3375 if (pane.IsOk() && pane.IsShown()) cnt++;
3377 cont->m_bIsVisible =
false;
3387 int cnt = GetDashboardWindowShownCount();
3389 bool b_anyviz =
false;
3390 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3392 if (cont->m_bIsVisible) {
3398 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3401 if (dashboard_window) {
3402 wxAuiPaneInfo &pane = m_pauimgr->GetPane(dashboard_window);
3404 bool b_reset_pos =
false;
3411 RECT frame_title_rect;
3412 frame_title_rect.left = pane.floating_pos.x;
3413 frame_title_rect.top = pane.floating_pos.y;
3414 frame_title_rect.right = pane.floating_pos.x + pane.floating_size.x;
3415 frame_title_rect.bottom = pane.floating_pos.y + 30;
3417 if (NULL == MonitorFromRect(&frame_title_rect, MONITOR_DEFAULTTONULL))
3423 wxRect window_title_rect;
3424 window_title_rect.x = pane.floating_pos.x;
3425 window_title_rect.y = pane.floating_pos.y;
3426 window_title_rect.width = pane.floating_size.x;
3427 window_title_rect.height = 30;
3429 wxRect ClientRect = wxGetClientDisplayRect();
3432 if (!ClientRect.Intersects(window_title_rect)) b_reset_pos =
true;
3436 if (b_reset_pos) pane.FloatingPosition(50, 50);
3440 pane.Show(cont->m_bIsVisible);
3442 cont->m_bIsVisible = cont->m_bPersVisible;
3443 pane.Show(cont->m_bIsVisible);
3450 if (pane.IsShown() && pane.IsDocked()) {
3451 pane.BestSize(cont->m_best_size);
3452 m_pauimgr->Update();
3463 if ((pane.dock_direction == wxAUI_DOCK_BOTTOM) && pane.IsDocked())
3470 GetDashboardWindowShownCount() != 0 );
3471 m_pauimgr->Update();
3481 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3483 wxAuiPaneInfo &pane = m_pauimgr->GetPane(cont->m_pDashboardWindow);
3485 cont->m_bIsVisible = (pane.IsOk() && pane.IsShown());
3489 if (pane.IsDocked()) {
3490 if ((cont->m_persist_size.x > 50) && (cont->m_persist_size.y > 50))
3491 cont->m_pDashboardWindow->SetSize(cont->m_persist_size);
3495 if (pane.IsShown()) {
3497 m_pauimgr->Update();
3499 m_pauimgr->Update();
3503 m_pauimgr->Update();
3511bool dashboard_pi::LoadConfig(
void) {
3512 wxFileConfig *pConf = (wxFileConfig *)m_pconfig;
3515 pConf->SetPath(_T(
"/PlugIns/Dashboard"));
3518 pConf->Read(_T(
"Version"), &version, wxEmptyString);
3527#ifdef __OCPN__ANDROID__
3528 TitleFont = _T(
"Roboto,16,-1,5,50,0,0,0,0,0");
3529 DataFont = _T(
"Roboto,16,-1,5,50,0,0,0,0,0");
3530 LabelFont = _T(
"Roboto,16,-1,5,50,0,0,0,0,0");
3531 SmallFont = _T(
"Roboto,14,-1,5,50,0,0,0,0,0");
3533 TitleFont = g_pFontTitle->GetChosenFont().GetNativeFontInfoDesc();
3534 DataFont = g_pFontData->GetChosenFont().GetNativeFontInfoDesc();
3535 LabelFont = g_pFontLabel->GetChosenFont().GetNativeFontInfoDesc();
3536 SmallFont = g_pFontSmall->GetChosenFont().GetNativeFontInfoDesc();
3539 double scaler = 1.0;
3541 wxFont *pDF = &DummyFont;
3545 scaler = wxMax(1.0, scaler);
3547 g_pFontTitle = &g_FontTitle;
3548 pConf->Read(_T(
"FontTitle"), &config, TitleFont);
3549 LoadFont(&pDF, config);
3550 wxFont DummyFontTitle = *pDF;
3551 pConf->Read(_T(
"ColorTitle"), &config,
"#000000");
3552 wxColour DummyColor(config);
3553 g_pUSFontTitle->SetChosenFont(DummyFontTitle);
3554 g_pUSFontTitle->SetColour(DummyColor);
3556 g_FontTitle = *g_pUSFontTitle;
3557 g_FontTitle.SetChosenFont(g_pUSFontTitle->GetChosenFont().Scaled(scaler));
3558 g_USFontTitle = *g_pUSFontTitle;
3560 g_pFontData = &g_FontData;
3561 pConf->Read(_T(
"FontData"), &config, DataFont);
3562 LoadFont(&pDF, config);
3563 wxFont DummyFontData = *pDF;
3564 pConf->Read(_T(
"ColorData"), &config,
"#000000");
3565 DummyColor.Set(config);
3566 g_pUSFontData->SetChosenFont(DummyFontData);
3567 g_pUSFontData->SetColour(DummyColor);
3568 g_FontData = *g_pUSFontData;
3569 g_FontData.SetChosenFont(g_pUSFontData->GetChosenFont().Scaled(scaler));
3570 g_USFontData = *g_pUSFontData;
3572 pConf->Read(_T(
"ForceBackgroundColor"), &g_ForceBackgroundColor, 0);
3573 pConf->Read(_T(
"BackgroundColor"), &config,
"DASHL");
3574 g_BackgroundColor.Set(config);
3577 pConf->Read(_T(
"TitleAlignment"), &alignment, (
int)wxALIGN_LEFT);
3578 g_TitleAlignment = (wxAlignment)alignment;
3579 if (g_TitleAlignment == wxALIGN_INVALID) g_TitleAlignment = wxALIGN_LEFT;
3580 pConf->Read(_T(
"TitleMargin"), &g_iTitleMargin, 5);
3581 pConf->Read(_T(
"DataShowUnit"), &g_bShowUnit,
true);
3582 pConf->Read(_T(
"DataAlignment"), &alignment, (int)wxALIGN_LEFT);
3583 g_DataAlignment = (wxAlignment)alignment;
3584 if (g_DataAlignment == wxALIGN_INVALID) g_DataAlignment = wxALIGN_LEFT;
3585 pConf->Read(_T(
"DataMargin"), &g_iDataMargin, 10);
3586 pConf->Read(_T(
"InstrumentSpacing"), &g_iInstrumentSpacing, 0);
3587 pConf->Read(_T(
"TitleVerticalOffset"), &g_TitleVerticalOffset, 0.0);
3589 g_pFontLabel = &g_FontLabel;
3590 pConf->Read(_T(
"FontLabel"), &config, LabelFont);
3591 LoadFont(&pDF, config);
3592 wxFont DummyFontLabel = *pDF;
3593 pConf->Read(_T(
"ColorLabel"), &config,
"#000000");
3594 DummyColor.Set(config);
3595 g_pUSFontLabel->SetChosenFont(DummyFontLabel);
3596 g_pUSFontLabel->SetColour(DummyColor);
3597 g_FontLabel = *g_pUSFontLabel;
3598 g_FontLabel.SetChosenFont(g_pUSFontLabel->GetChosenFont().Scaled(scaler));
3599 g_USFontLabel = *g_pUSFontLabel;
3601 g_pFontSmall = &g_FontSmall;
3602 pConf->Read(_T(
"FontSmall"), &config, SmallFont);
3603 LoadFont(&pDF, config);
3604 wxFont DummyFontSmall = *pDF;
3605 pConf->Read(_T(
"ColorSmall"), &config,
"#000000");
3606 DummyColor.Set(config);
3607 g_pUSFontSmall->SetChosenFont(DummyFontSmall);
3608 g_pUSFontSmall->SetColour(DummyColor);
3609 g_FontSmall = *g_pUSFontSmall;
3610 g_FontSmall.SetChosenFont(g_pUSFontSmall->GetChosenFont().Scaled(scaler));
3611 g_USFontSmall = *g_pUSFontSmall;
3613 pConf->Read(_T(
"SpeedometerMax"), &g_iDashSpeedMax, 12);
3614 pConf->Read(_T(
"COGDamp"), &g_iDashCOGDamp, 0);
3615 pConf->Read(_T(
"SpeedUnit"), &g_iDashSpeedUnit, 0);
3616 pConf->Read(_T(
"SOGDamp"), &g_iDashSOGDamp, 0);
3617 pConf->Read(_T(
"DepthUnit"), &g_iDashDepthUnit, 3);
3618 g_iDashDepthUnit = wxMax(g_iDashDepthUnit, 3);
3619 pConf->Read(_T(
"AWADamp"), &g_iDashAWADamp, 0);
3620 pConf->Read(_T(
"AWSDamp"), &g_iDashAWSDamp, 0);
3622 pConf->Read(_T(
"DepthOffset"), &g_dDashDBTOffset, 0);
3624 pConf->Read(_T(
"DistanceUnit"), &g_iDashDistanceUnit, 0);
3625 pConf->Read(_T(
"WindSpeedUnit"), &g_iDashWindSpeedUnit, 0);
3626 pConf->Read(_T(
"UseSignKtruewind"), &g_bDBtrueWindGround, 0);
3627 pConf->Read(
"UseInternSumlog", &g_bUseInternSumLog, 0);
3628 pConf->Read(
"SumLogNM", &g_dSumLogNM, 0.0);
3629 pConf->Read(_T(
"TemperatureUnit"), &g_iDashTempUnit, 0);
3631 pConf->Read(_T(
"UTCOffset"), &g_iUTCOffset, 0);
3633 pConf->Read(_T(
"PrefWidth"), &g_dashPrefWidth, 0);
3634 pConf->Read(_T(
"PrefHeight"), &g_dashPrefHeight, 0);
3637 pConf->Read(_T(
"DashboardCount"), &d_cnt, -1);
3639 m_ArrayOfDashboardWindow.Clear();
3640 if (version.IsEmpty() && d_cnt == -1) {
3641 m_config_version = 1;
3644 pConf->Read(_T(
"InstrumentCount"), &i_cnt, -1);
3646 wxArrayOfInstrumentProperties Property;
3648 for (
int i = 0; i < i_cnt; i++) {
3650 pConf->Read(wxString::Format(_T(
"Instrument%d"), i + 1), &
id, -1);
3651 if (
id != -1) ar.Add(
id);
3655#ifndef __OCPN__ANDROID__
3656 ar.Add(ID_DBP_I_POS);
3657 ar.Add(ID_DBP_D_COG);
3658 ar.Add(ID_DBP_D_GPS);
3660 ar.Add(ID_DBP_I_POS);
3661 ar.Add(ID_DBP_D_COG);
3662 ar.Add(ID_DBP_I_SOG);
3668 NULL, MakeName(), _(
"Dashboard"), _T(
"V"), ar, Property);
3669 cont->m_bPersVisible =
true;
3670 m_ArrayOfDashboardWindow.Add(cont);
3674 m_config_version = 2;
3675 bool b_onePersisted =
false;
3677 wxSize persist_size;
3678 for (
int k = 0; k < d_cnt; k++) {
3680 wxString::Format(_T(
"/PlugIns/Dashboard/Dashboard%d"), k + 1));
3682 pConf->Read(_T(
"Name"), &name, MakeName());
3684 pConf->Read(_T(
"Caption"), &caption, _(
"Dashboard"));
3686 pConf->Read(_T(
"Orientation"), &orient, _T(
"V"));
3688 pConf->Read(_T(
"InstrumentCount"), &i_cnt, -1);
3690 pConf->Read(_T(
"Persistence"), &b_persist, 1);
3692 pConf->Read(_T(
"BestSizeX"), &val, DefaultWidth);
3694 pConf->Read(_T(
"BestSizeY"), &val, DefaultWidth);
3696 pConf->Read(_T(
"PersistSizeX"), &val, DefaultWidth);
3697 persist_size.x = val;
3698 pConf->Read(_T(
"PersistSizeY"), &val, DefaultWidth);
3699 persist_size.y = val;
3702 wxArrayOfInstrumentProperties Property;
3703 for (
int i = 0; i < i_cnt; i++) {
3705 pConf->Read(wxString::Format(_T(
"Instrument%d"), i + 1), &
id, -1);
3709 if (pConf->Exists(wxString::Format(_T(
"InstTitleFont%d"), i + 1))) {
3712 pConf->Read(wxString::Format(_T(
"InstTitleFont%d"), i + 1),
3713 &config, TitleFont);
3714 LoadFont(&pDF, config);
3715 wxFont DummyFontTitleA = *pDF;
3716 pConf->Read(wxString::Format(_T(
"InstTitleColor%d"), i + 1),
3717 &config,
"#000000");
3718 DummyColor.Set(config);
3719 instp->m_USTitleFont.SetChosenFont(DummyFontTitleA);
3720 instp->m_USTitleFont.SetColour(DummyColor);
3721 instp->m_TitleFont = instp->m_USTitleFont;
3722 instp->m_TitleFont.SetChosenFont(
3723 instp->m_USTitleFont.GetChosenFont().Scaled(scaler));
3725 pConf->Read(wxString::Format(_T(
"InstDataShowUnit%d"), i + 1),
3726 &instp->m_ShowUnit, -1);
3727 pConf->Read(wxString::Format(_T(
"InstDataMargin%d"), i + 1),
3728 &instp->m_DataMargin, -1);
3729 pConf->Read(wxString::Format(_T(
"InstDataAlignment%d"), i + 1),
3730 &alignment, (
int)wxALIGN_INVALID);
3731 instp->m_DataAlignment = (wxAlignment)alignment;
3733 wxString::Format(_T(
"InstInstrumentSpacing%d"), i + 1),
3734 &instp->m_InstrumentSpacing, -1);
3735 pConf->Read(wxString::Format(_T(
"InstDataFormat%d"), i + 1),
3736 &instp->m_Format,
"");
3737 pConf->Read(wxString::Format(_T(
"InstTitle%d"), i + 1),
3738 &instp->m_Title,
"");
3740 pConf->Read(wxString::Format(_T(
"InstDataFont%d"), i + 1),
3742 LoadFont(&pDF, config);
3743 wxFont DummyFontDataA = *pDF;
3744 pConf->Read(wxString::Format(_T(
"InstDataColor%d"), i + 1),
3745 &config,
"#000000");
3746 DummyColor.Set(config);
3747 instp->m_USDataFont.SetChosenFont(DummyFontDataA);
3748 instp->m_USDataFont.SetColour(DummyColor);
3749 instp->m_DataFont = instp->m_USDataFont;
3750 instp->m_DataFont.SetChosenFont(
3751 instp->m_USDataFont.GetChosenFont().Scaled(scaler));
3753 pConf->Read(wxString::Format(_T(
"InstLabelFont%d"), i + 1),
3754 &config, LabelFont);
3755 LoadFont(&pDF, config);
3756 wxFont DummyFontLabelA = *pDF;
3757 pConf->Read(wxString::Format(_T(
"InstLabelColor%d"), i + 1),
3758 &config,
"#000000");
3759 DummyColor.Set(config);
3760 instp->m_USLabelFont.SetChosenFont(DummyFontLabelA);
3761 instp->m_USLabelFont.SetColour(DummyColor);
3762 instp->m_LabelFont = instp->m_USLabelFont;
3763 instp->m_LabelFont.SetChosenFont(
3764 instp->m_USLabelFont.GetChosenFont().Scaled(scaler));
3766 pConf->Read(wxString::Format(_T(
"InstSmallFont%d"), i + 1),
3767 &config, SmallFont);
3768 LoadFont(&pDF, config);
3769 wxFont DummyFontSmallA = *pDF;
3770 pConf->Read(wxString::Format(_T(
"InstSmallColor%d"), i + 1),
3771 &config,
"#000000");
3772 DummyColor.Set(config);
3773 instp->m_USSmallFont.SetChosenFont(DummyFontSmallA);
3774 instp->m_USSmallFont.SetColour(DummyColor);
3775 instp->m_SmallFont = instp->m_USSmallFont;
3776 instp->m_SmallFont.SetChosenFont(
3777 instp->m_USSmallFont.GetChosenFont().Scaled(scaler));
3779 pConf->Read(wxString::Format(_T(
"TitleBackColor%d"), i + 1),
3781 instp->m_TitleBackgroundColour.Set(config);
3783 pConf->Read(wxString::Format(_T(
"DataBackColor%d"), i + 1),
3785 instp->m_DataBackgroundColour.Set(config);
3787 pConf->Read(wxString::Format(_T(
"ArrowFirst%d"), i + 1), &config,
3789 instp->m_Arrow_First_Colour.Set(config);
3791 pConf->Read(wxString::Format(_T(
"ArrowSecond%d"), i + 1), &config,
3793 instp->m_Arrow_Second_Colour.Set(config);
3795 Property.Add(instp);
3802 NULL, name, caption, orient, ar, Property);
3803 cont->m_bPersVisible = b_persist;
3804 cont->m_conf_best_size = best_size;
3805 cont->m_persist_size = persist_size;
3807 if (b_persist) b_onePersisted =
true;
3809 m_ArrayOfDashboardWindow.Add(cont);
3813 if (m_ArrayOfDashboardWindow.Count() && !b_onePersisted) {
3815 if (cont) cont->m_bPersVisible =
true;
3824void dashboard_pi::LoadFont(wxFont **target, wxString native_info) {
3825 if (!native_info.IsEmpty()) {
3826#ifdef __OCPN__ANDROID__
3827 wxFont *nf =
new wxFont(native_info);
3830 (*target)->SetNativeFontInfo(native_info);
3835bool dashboard_pi::SaveConfig(
void) {
3836 wxFileConfig *pConf = (wxFileConfig *)m_pconfig;
3839 pConf->SetPath(_T(
"/PlugIns/Dashboard"));
3840 pConf->Write(_T(
"Version"), _T(
"2"));
3841 pConf->Write(_T(
"FontTitle"),
3842 g_pUSFontTitle->GetChosenFont().GetNativeFontInfoDesc());
3843 pConf->Write(_T(
"ColorTitle"),
3844 g_pUSFontTitle->GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3845 pConf->Write(_T(
"FontData"),
3846 g_pUSFontData->GetChosenFont().GetNativeFontInfoDesc());
3847 pConf->Write(_T(
"ColorData"),
3848 g_pUSFontData->GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3849 pConf->Write(_T(
"FontLabel"),
3850 g_pUSFontLabel->GetChosenFont().GetNativeFontInfoDesc());
3851 pConf->Write(_T(
"ColorLabel"),
3852 g_pUSFontLabel->GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3853 pConf->Write(_T(
"FontSmall"),
3854 g_pUSFontSmall->GetChosenFont().GetNativeFontInfoDesc());
3855 pConf->Write(_T(
"ColorSmall"),
3856 g_pUSFontSmall->GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3857 pConf->Write(_T(
"SpeedometerMax"), g_iDashSpeedMax);
3858 pConf->Write(_T(
"COGDamp"), g_iDashCOGDamp);
3859 pConf->Write(_T(
"SpeedUnit"), g_iDashSpeedUnit);
3860 pConf->Write(_T(
"SOGDamp"), g_iDashSOGDamp);
3861 pConf->Write(_T(
"AWSDamp"), g_iDashAWSDamp);
3862 pConf->Write(_T(
"AWADamp"), g_iDashAWADamp);
3863 pConf->Write(_T(
"DepthUnit"), g_iDashDepthUnit);
3864 pConf->Write(_T(
"DepthOffset"), g_dDashDBTOffset);
3865 pConf->Write(_T(
"DistanceUnit"), g_iDashDistanceUnit);
3866 pConf->Write(_T(
"WindSpeedUnit"), g_iDashWindSpeedUnit);
3867 pConf->Write(
"UseInternSumlog", g_bUseInternSumLog);
3868 pConf->Write(
"SumLogNM", g_dSumLogNM);
3869 pConf->Write(_T(
"UTCOffset"), g_iUTCOffset);
3870 pConf->Write(_T(
"UseSignKtruewind"), g_bDBtrueWindGround);
3871 pConf->Write(_T(
"TemperatureUnit"), g_iDashTempUnit);
3872 pConf->Write(_T(
"PrefWidth"), g_dashPrefWidth);
3873 pConf->Write(_T(
"PrefHeight"), g_dashPrefHeight);
3875 pConf->Write(_T(
"DashboardCount" ),
3876 (int)m_ArrayOfDashboardWindow.GetCount());
3878 for (
size_t i = m_ArrayOfDashboardWindow.GetCount(); i < 20; i++) {
3880 wxString::Format(_T(
"/PlugIns/Dashboard/Dashboard%zu"), i + 1))) {
3882 wxString::Format(_T(
"/PlugIns/Dashboard/Dashboard%zu"), i + 1));
3885 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3888 wxString::Format(_T(
"/PlugIns/Dashboard/Dashboard%zu"), i + 1));
3889 pConf->Write(_T(
"Name"), cont->m_sName);
3890 pConf->Write(_T(
"Caption"), cont->m_sCaption);
3891 pConf->Write(_T(
"Orientation"), cont->m_sOrientation);
3892 pConf->Write(_T(
"Persistence"), cont->m_bPersVisible);
3893 pConf->Write(_T(
"InstrumentCount"),
3894 (int)cont->m_aInstrumentList.GetCount());
3895 pConf->Write(_T(
"BestSizeX"), cont->m_best_size.x);
3896 pConf->Write(_T(
"BestSizeY"), cont->m_best_size.y);
3897 pConf->Write(_T(
"PersistSizeX"), cont->m_pDashboardWindow->GetSize().x);
3898 pConf->Write(_T(
"PersistSizeY"), cont->m_pDashboardWindow->GetSize().y);
3901 for (
size_t i = cont->m_aInstrumentList.GetCount(); i < 40; i++) {
3902 if (pConf->Exists(wxString::Format(_T(
"Instrument%zu"), i + 1))) {
3903 pConf->DeleteEntry(wxString::Format(_T(
"Instrument%zu"), i + 1));
3904 if (pConf->Exists(wxString::Format(_T(
"InstTitleFont%zu"), i + 1))) {
3905 pConf->DeleteEntry(wxString::Format(_T(
"InstTitleFont%zu"), i + 1));
3907 wxString::Format(_T(
"InstTitleColor%zu"), i + 1));
3908 pConf->DeleteEntry(wxString::Format(_T(
"InstTitle%zu"), i + 1));
3910 wxString::Format(_T(
"InstDataShowUnit%zu"), i + 1));
3912 wxString::Format(_T(
"InstDataMargin%zu"), i + 1));
3914 wxString::Format(_T(
"InstDataAlignment%zu"), i + 1));
3916 wxString::Format(_T(
"InstDataFormat%zu"), i + 1));
3917 pConf->DeleteEntry(wxString::Format(_T(
"InstDataFont%zu"), i + 1));
3918 pConf->DeleteEntry(wxString::Format(_T(
"InstDataColor%zu"), i + 1));
3919 pConf->DeleteEntry(wxString::Format(_T(
"InstLabelFont%zu"), i + 1));
3921 wxString::Format(_T(
"InstLabelColor%zu"), i + 1));
3922 pConf->DeleteEntry(wxString::Format(_T(
"InstSmallFont%zu"), i + 1));
3924 wxString::Format(_T(
"InstSmallColor%zu"), i + 1));
3926 wxString::Format(_T(
"TitleBackColor%zu"), i + 1));
3927 pConf->DeleteEntry(wxString::Format(_T(
"DataBackColor%zu"), i + 1));
3928 pConf->DeleteEntry(wxString::Format(_T(
"ArrowFirst%zu"), i + 1));
3929 pConf->DeleteEntry(wxString::Format(_T(
"ArrowSecond%zu"), i + 1));
3933 for (
size_t j = 0; j < cont->m_aInstrumentList.GetCount(); j++) {
3934 pConf->Write(wxString::Format(_T(
"Instrument%zu"), j + 1),
3935 cont->m_aInstrumentList.Item(j));
3938 if (pConf->Exists(wxString::Format(_T(
"InstTitleFont%zu"), j + 1))) {
3940 for (
size_t i = 0; i < cont->m_aInstrumentPropertyList.GetCount();
3942 Inst = cont->m_aInstrumentPropertyList.Item(i);
3943 if (Inst->m_Listplace == (
int)j) {
3949 pConf->DeleteEntry(wxString::Format(_T(
"InstTitleFont%zu"), j + 1));
3951 wxString::Format(_T(
"InstTitleColor%zu"), j + 1));
3952 pConf->DeleteEntry(wxString::Format(_T(
"InstTitle%zu"), j + 1));
3954 wxString::Format(_T(
"InstDataShowUnit%zu"), i + 1));
3956 wxString::Format(_T(
"InstDataMargin%zu"), i + 1));
3958 wxString::Format(_T(
"InstDataAlignment%zu"), i + 1));
3960 wxString::Format(_T(
"InstDataFormat%zu"), i + 1));
3961 pConf->DeleteEntry(wxString::Format(_T(
"InstDataFont%zu"), j + 1));
3962 pConf->DeleteEntry(wxString::Format(_T(
"InstDataColor%zu"), j + 1));
3963 pConf->DeleteEntry(wxString::Format(_T(
"InstLabelFont%zu"), j + 1));
3965 wxString::Format(_T(
"InstLabelColor%zu"), j + 1));
3966 pConf->DeleteEntry(wxString::Format(_T(
"InstSmallFont%zu"), j + 1));
3968 wxString::Format(_T(
"InstSmallColor%zu"), j + 1));
3970 wxString::Format(_T(
"TitleBackColor%zu"), i + 1));
3971 pConf->DeleteEntry(wxString::Format(_T(
"DataBackColor%zu"), i + 1));
3972 pConf->DeleteEntry(wxString::Format(_T(
"ArrowFirst%zu"), i + 1));
3973 pConf->DeleteEntry(wxString::Format(_T(
"ArrowSecond%zu"), i + 1));
3977 for (
size_t i = 0; i < (cont->m_aInstrumentPropertyList.GetCount());
3979 Inst = cont->m_aInstrumentPropertyList.Item(i);
3980 if (Inst->m_Listplace == (
int)j) {
3982 wxString::Format(_T(
"InstTitleFont%zu"), j + 1),
3983 Inst->m_USTitleFont.GetChosenFont().GetNativeFontInfoDesc());
3985 wxString::Format(_T(
"InstTitleColor%zu"), j + 1),
3986 Inst->m_USTitleFont.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3988 wxString::Format(_T(
"InstDataFont%zu"), j + 1),
3989 Inst->m_USDataFont.GetChosenFont().GetNativeFontInfoDesc());
3991 wxString::Format(_T(
"InstDataColor%zu"), j + 1),
3992 Inst->m_USDataFont.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3994 wxString::Format(_T(
"InstLabelFont%zu"), j + 1),
3995 Inst->m_USLabelFont.GetChosenFont().GetNativeFontInfoDesc());
3997 wxString::Format(_T(
"InstLabelColor%zu"), j + 1),
3998 Inst->m_USLabelFont.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
4000 wxString::Format(_T(
"InstSmallFont%zu"), j + 1),
4001 Inst->m_USSmallFont.GetChosenFont().GetNativeFontInfoDesc());
4003 wxString::Format(_T(
"InstSmallColor%zu"), j + 1),
4004 Inst->m_USSmallFont.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
4006 wxString::Format(_T(
"TitleBackColor%zu"), j + 1),
4007 Inst->m_TitleBackgroundColour.GetAsString(wxC2S_HTML_SYNTAX));
4009 wxString::Format(_T(
"DataBackColor%zu"), j + 1),
4010 Inst->m_DataBackgroundColour.GetAsString(wxC2S_HTML_SYNTAX));
4012 wxString::Format(_T(
"ArrowFirst%zu"), j + 1),
4013 Inst->m_Arrow_First_Colour.GetAsString(wxC2S_HTML_SYNTAX));
4015 wxString::Format(_T(
"ArrowSecond%zu"), j + 1),
4016 Inst->m_Arrow_Second_Colour.GetAsString(wxC2S_HTML_SYNTAX));
4028void dashboard_pi::ApplyConfig(
void) {
4030 for (
size_t i = m_ArrayOfDashboardWindow.GetCount(); i > 0; i--) {
4032 int orient = (cont->m_sOrientation == _T(
"V") ? wxVERTICAL : wxHORIZONTAL);
4033 if (cont->m_bIsDeleted) {
4034 if (cont->m_pDashboardWindow) {
4035 m_pauimgr->DetachPane(cont->m_pDashboardWindow);
4036 cont->m_pDashboardWindow->Close();
4037 cont->m_pDashboardWindow->Destroy();
4038 cont->m_pDashboardWindow = NULL;
4040 m_ArrayOfDashboardWindow.Remove(cont);
4043 }
else if (!cont->m_pDashboardWindow) {
4047 cont->m_pDashboardWindow->SetInstrumentList(
4048 cont->m_aInstrumentList, &(cont->m_aInstrumentPropertyList));
4049 bool vertical = orient == wxVERTICAL;
4050 wxSize sz = cont->m_pDashboardWindow->GetMinSize();
4051 wxSize best = cont->m_conf_best_size;
4052 if (best.x < 100) best = sz;
4056 if (sz.x == 0) sz.IncTo(wxSize(160, 388));
4058 wxAuiPaneInfo p = wxAuiPaneInfo()
4059 .Name(cont->m_sName)
4060 .Caption(cont->m_sCaption)
4061 .CaptionVisible(
false)
4062 .TopDockable(!vertical)
4063 .BottomDockable(!vertical)
4064 .LeftDockable(vertical)
4065 .RightDockable(vertical)
4069 .FloatingPosition(100, 100)
4071 .Show(cont->m_bIsVisible)
4074 m_pauimgr->AddPane(cont->m_pDashboardWindow, p);
4081#ifdef __OCPN__ANDROID__
4082 wxAuiPaneInfo &pane = m_pauimgr->GetPane(cont->m_pDashboardWindow);
4083 pane.Dockable(
false);
4088 wxAuiPaneInfo &pane = m_pauimgr->GetPane(cont->m_pDashboardWindow);
4089 pane.Caption(cont->m_sCaption).Show(cont->m_bIsVisible);
4090 if (!cont->m_pDashboardWindow->isInstrumentListEqual(
4091 cont->m_aInstrumentList)) {
4092 cont->m_pDashboardWindow->SetInstrumentList(
4093 cont->m_aInstrumentList, &(cont->m_aInstrumentPropertyList));
4094 wxSize sz = cont->m_pDashboardWindow->GetMinSize();
4095 pane.MinSize(sz).BestSize(sz).FloatingSize(sz);
4097 if (cont->m_pDashboardWindow->GetSizerOrientation() != orient) {
4098 cont->m_pDashboardWindow->ChangePaneOrientation(orient,
false);
4102 m_pauimgr->Update();
4105 double sogFC = g_iDashSOGDamp ? 1.0 / (2.0 * g_iDashSOGDamp) : 0.0;
4106 double cogFC = g_iDashCOGDamp ? 1.0 / (2.0 * g_iDashCOGDamp) : 0.0;
4107 double awaFC = g_iDashAWADamp ? 1.0 / (2.0 * g_iDashAWADamp) : 0.0;
4108 double awsFC = g_iDashAWSDamp ? 1.0 / (2.0 * g_iDashAWSDamp) : 0.0;
4110 if (abs(sogFC - mSOGFilter.getFc()) > 1e-6) {
4111 mSOGFilter.setFC(sogFC);
4113 if (abs(cogFC - mCOGFilter.getFc()) > 1e-6) {
4114 mCOGFilter.setFC(cogFC);
4116 if (abs(awaFC - mAWAFilter.getFc()) > 1e-6) {
4117 mAWAFilter.setFC(awaFC);
4119 if (abs(awsFC - mAWSFilter.getFc()) > 1e-6) {
4120 mAWSFilter.setFC(awsFC);
4124void dashboard_pi::PopulateContextMenu(wxMenu *menu) {
4126 wxMenuItem *visItem = 0;
4127 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
4129 wxMenuItem *item = menu->AppendCheckItem(i + 1, cont->m_sCaption);
4130 item->Check(cont->m_bIsVisible);
4131 if (cont->m_bIsVisible) {
4136 if (nvis == 1 && visItem) visItem->Enable(
false);
4139void dashboard_pi::ShowDashboard(
size_t id,
bool visible) {
4140 if (
id < m_ArrayOfDashboardWindow.GetCount()) {
4142 m_pauimgr->GetPane(cont->m_pDashboardWindow).Show(visible);
4143 cont->m_bIsVisible = visible;
4144 cont->m_bPersVisible = visible;
4145 m_pauimgr->Update();
4153DashboardPreferencesDialog::DashboardPreferencesDialog(
4154 wxWindow *parent, wxWindowID
id, wxArrayOfDashboard config)
4155 : wxDialog(parent, id, _(
"Dashboard preferences"), wxDefaultPosition,
4156 wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
4162 int display_width, display_height;
4163 wxDisplaySize(&display_width, &display_height);
4166 wxFileName::GetPathSeparator() + _T(
"dashboard_pi") +
4167 wxFileName::GetPathSeparator() + _T(
"data") +
4168 wxFileName::GetPathSeparator();
4170 Connect(wxEVT_CLOSE_WINDOW,
4171 wxCloseEventHandler(DashboardPreferencesDialog::OnCloseDialog), NULL,
4175 m_Config = wxArrayOfDashboard(config);
4177 int border_size = 2;
4179 wxBoxSizer *itemBoxSizerMainPanel =
new wxBoxSizer(wxVERTICAL);
4180 SetSizer(itemBoxSizerMainPanel);
4182 wxWindow *dparent =
this;
4183 wxScrolledWindow *scrollWin =
new wxScrolledWindow(
4184 this, wxID_ANY, wxDefaultPosition, wxSize(-1, -1), wxVSCROLL | wxHSCROLL);
4186 scrollWin->SetScrollRate(1, 1);
4187 itemBoxSizerMainPanel->Add(scrollWin, 1, wxEXPAND | wxALL, 0);
4189 dparent = scrollWin;
4191 wxBoxSizer *itemBoxSizer2 =
new wxBoxSizer(wxVERTICAL);
4192 scrollWin->SetSizer(itemBoxSizer2);
4194 auto *DialogButtonSizer =
new wxStdDialogButtonSizer();
4195 DialogButtonSizer->AddButton(
new wxButton(
this, wxID_OK));
4196 DialogButtonSizer->AddButton(
new wxButton(
this, wxID_CANCEL));
4197 wxButton *help_btn =
new wxButton(
this, wxID_HELP);
4198 help_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [&](wxCommandEvent) {
4199 wxString datadir = GetPluginDataDir(
"manual_pi");
4200 Manual(
this, datadir.ToStdString()).Launch(
"Dashboard");
4202 DialogButtonSizer->AddButton(help_btn);
4203 DialogButtonSizer->Realize();
4205 itemBoxSizerMainPanel->Add(DialogButtonSizer, 0, wxALIGN_RIGHT | wxALL, 5);
4207 wxNotebook *itemNotebook =
new wxNotebook(
4208 dparent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP);
4209 itemBoxSizer2->Add(itemNotebook, 0, wxALL | wxEXPAND, border_size);
4211 wxPanel *itemPanelNotebook01 =
4212 new wxPanel(itemNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
4214 wxFlexGridSizer *itemFlexGridSizer01 =
new wxFlexGridSizer(2);
4215 itemFlexGridSizer01->AddGrowableCol(1);
4216 itemPanelNotebook01->SetSizer(itemFlexGridSizer01);
4217 itemNotebook->AddPage(itemPanelNotebook01, _(
"Dashboard"));
4219 wxBoxSizer *itemBoxSizer01 =
new wxBoxSizer(wxVERTICAL);
4220 itemFlexGridSizer01->Add(itemBoxSizer01, 1, wxEXPAND | wxTOP | wxLEFT,
4224 int imageRefSize = GetCharWidth() * 4;
4226 wxImageList *imglist1 =
new wxImageList(imageRefSize, imageRefSize,
true, 1);
4228 wxBitmap bmDashBoard;
4230 wxString filename = shareLocn + _T(
"Dashboard.svg");
4233 wxImage dash1 = wxBitmap(*_img_dashboard_pi).ConvertToImage();
4235 dash1.Scale(imageRefSize, imageRefSize, wxIMAGE_QUALITY_HIGH);
4236 bmDashBoard = wxBitmap(dash1s);
4239 imglist1->Add(bmDashBoard);
4241 m_pListCtrlDashboards =
4242 new wxListCtrl(itemPanelNotebook01, wxID_ANY, wxDefaultPosition,
4243 wxSize(imageRefSize * 3 / 2, 200),
4244 wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL);
4246 m_pListCtrlDashboards->AssignImageList(imglist1, wxIMAGE_LIST_SMALL);
4247 m_pListCtrlDashboards->InsertColumn(0, _T(
""));
4248 m_pListCtrlDashboards->Connect(
4249 wxEVT_COMMAND_LIST_ITEM_SELECTED,
4250 wxListEventHandler(DashboardPreferencesDialog::OnDashboardSelected), NULL,
4252 m_pListCtrlDashboards->Connect(
4253 wxEVT_COMMAND_LIST_ITEM_DESELECTED,
4254 wxListEventHandler(DashboardPreferencesDialog::OnDashboardSelected), NULL,
4256 itemBoxSizer01->Add(m_pListCtrlDashboards, 1, wxEXPAND, 0);
4258 wxBoxSizer *itemBoxSizer02 =
new wxBoxSizer(wxHORIZONTAL);
4259 itemBoxSizer01->Add(itemBoxSizer02);
4261 wxBitmap bmPlus, bmMinus;
4262 int bmSize = imageRefSize * 100 / 275;
4264#ifdef __OCPN__ANDROID__
4265 bmSize = imageRefSize / 2;
4272 wxImage plus1 = wxBitmap(*_img_plus).ConvertToImage();
4273 wxImage plus1s = plus1.Scale(bmSize, bmSize, wxIMAGE_QUALITY_HIGH);
4274 bmPlus = wxBitmap(plus1s);
4276 wxImage minus1 = wxBitmap(*_img_minus).ConvertToImage();
4277 wxImage minus1s = minus1.Scale(bmSize, bmSize, wxIMAGE_QUALITY_HIGH);
4278 bmMinus = wxBitmap(minus1s);
4281 m_pButtonAddDashboard =
new wxBitmapButton(
4282 itemPanelNotebook01, wxID_ANY, bmPlus, wxDefaultPosition, wxDefaultSize);
4283 itemBoxSizer02->Add(m_pButtonAddDashboard, 0, wxALIGN_CENTER, 2);
4284 m_pButtonAddDashboard->Connect(
4285 wxEVT_COMMAND_BUTTON_CLICKED,
4286 wxCommandEventHandler(DashboardPreferencesDialog::OnDashboardAdd), NULL,
4289 m_pButtonDeleteDashboard =
new wxBitmapButton(
4290 itemPanelNotebook01, wxID_ANY, bmMinus, wxDefaultPosition, wxDefaultSize);
4291 itemBoxSizer02->Add(m_pButtonDeleteDashboard, 0, wxALIGN_CENTER, 2);
4292 m_pButtonDeleteDashboard->Connect(
4293 wxEVT_COMMAND_BUTTON_CLICKED,
4294 wxCommandEventHandler(DashboardPreferencesDialog::OnDashboardDelete),
4298 new wxPanel(itemPanelNotebook01, wxID_ANY, wxDefaultPosition,
4299 wxDefaultSize, wxBORDER_SUNKEN);
4300 itemFlexGridSizer01->Add(m_pPanelDashboard, 1, wxEXPAND | wxTOP | wxRIGHT,
4303 wxBoxSizer *itemBoxSizer03 =
new wxBoxSizer(wxVERTICAL);
4304 m_pPanelDashboard->SetSizer(itemBoxSizer03);
4306 wxStaticBox *itemStaticBox02 =
4307 new wxStaticBox(m_pPanelDashboard, wxID_ANY, _(
"Dashboard"));
4308 wxStaticBoxSizer *itemStaticBoxSizer02 =
4309 new wxStaticBoxSizer(itemStaticBox02, wxHORIZONTAL);
4310 itemBoxSizer03->Add(itemStaticBoxSizer02, 0, wxEXPAND | wxALL, border_size);
4311 wxFlexGridSizer *itemFlexGridSizer =
new wxFlexGridSizer(2);
4312 itemFlexGridSizer->AddGrowableCol(1);
4313 itemStaticBoxSizer02->Add(itemFlexGridSizer, 1, wxEXPAND | wxALL, 0);
4315 m_pCheckBoxIsVisible =
4316 new wxCheckBox(m_pPanelDashboard, wxID_ANY, _(
"show this dashboard"),
4317 wxDefaultPosition, wxDefaultSize, 0);
4318 m_pCheckBoxIsVisible->SetMinSize(wxSize(25 * GetCharWidth(), -1));
4320 itemFlexGridSizer->Add(m_pCheckBoxIsVisible, 0, wxEXPAND | wxALL,
4322 wxStaticText *itemDummy01 =
4323 new wxStaticText(m_pPanelDashboard, wxID_ANY, _T(
""));
4324 itemFlexGridSizer->Add(itemDummy01, 0, wxEXPAND | wxALL, border_size);
4326 wxStaticText *itemStaticText01 =
4327 new wxStaticText(m_pPanelDashboard, wxID_ANY, _(
"Caption:"),
4328 wxDefaultPosition, wxDefaultSize, 0);
4329 itemFlexGridSizer->Add(itemStaticText01, 0, wxEXPAND | wxALL, border_size);
4330 m_pTextCtrlCaption =
new wxTextCtrl(m_pPanelDashboard, wxID_ANY, _T(
""),
4331 wxDefaultPosition, wxDefaultSize);
4332 m_pCheckBoxIsVisible->SetMinSize(wxSize(30 * GetCharWidth(), -1));
4333 itemFlexGridSizer->Add(m_pTextCtrlCaption, 0, wxALIGN_RIGHT | wxALL,
4336 wxStaticText *itemStaticText02 =
4337 new wxStaticText(m_pPanelDashboard, wxID_ANY, _(
"Orientation:"),
4338 wxDefaultPosition, wxDefaultSize, 0);
4339 itemFlexGridSizer->Add(itemStaticText02, 0, wxEXPAND | wxALL, border_size);
4340 m_pChoiceOrientation =
new wxChoice(m_pPanelDashboard, wxID_ANY,
4341 wxDefaultPosition, wxDefaultSize);
4342 m_pChoiceOrientation->SetMinSize(wxSize(15 * GetCharWidth(), -1));
4343 m_pChoiceOrientation->Append(_(
"Vertical"));
4344 m_pChoiceOrientation->Append(_(
"Horizontal"));
4345 itemFlexGridSizer->Add(m_pChoiceOrientation, 0, wxALIGN_RIGHT | wxALL,
4350 wxImageList *imglist =
4351 new wxImageList(instImageRefSize, instImageRefSize,
true, 2);
4353 wxBitmap bmDial, bmInst;
4358 instImageRefSize, instImageRefSize);
4360 wxImage dial1 = wxBitmap(*_img_dial).ConvertToImage();
4362 dial1.Scale(instImageRefSize, instImageRefSize, wxIMAGE_QUALITY_HIGH);
4363 bmDial = wxBitmap(dial1);
4365 wxImage inst1 = wxBitmap(*_img_instrument).ConvertToImage();
4367 inst1.Scale(instImageRefSize, instImageRefSize, wxIMAGE_QUALITY_HIGH);
4368 bmInst = wxBitmap(inst1s);
4371 imglist->Add(bmInst);
4372 imglist->Add(bmDial);
4374 wxStaticBox *itemStaticBox03 =
4375 new wxStaticBox(m_pPanelDashboard, wxID_ANY, _(
"Instruments"));
4376 wxStaticBoxSizer *itemStaticBoxSizer03 =
4377 new wxStaticBoxSizer(itemStaticBox03, wxHORIZONTAL);
4378 itemBoxSizer03->Add(itemStaticBoxSizer03, 1, wxEXPAND | wxALL, border_size);
4381 wxSize list_size = wxSize(-1, dsize.y * 35 / 100);
4384 int xsize = GetCharWidth() * 30;
4385 list_size = wxSize(xsize, dsize.y * 50 / 100);
4388 m_pListCtrlInstruments =
4389 new wxListCtrl(m_pPanelDashboard, wxID_ANY, wxDefaultPosition, list_size,
4390 wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL);
4392 itemStaticBoxSizer03->Add(m_pListCtrlInstruments, 1, wxEXPAND | wxALL,
4394 m_pListCtrlInstruments->AssignImageList(imglist, wxIMAGE_LIST_SMALL);
4395 m_pListCtrlInstruments->InsertColumn(0, _(
"Instruments"));
4396 m_pListCtrlInstruments->Connect(
4397 wxEVT_COMMAND_LIST_ITEM_SELECTED,
4398 wxListEventHandler(DashboardPreferencesDialog::OnInstrumentSelected),
4400 m_pListCtrlInstruments->Connect(
4401 wxEVT_COMMAND_LIST_ITEM_DESELECTED,
4402 wxListEventHandler(DashboardPreferencesDialog::OnInstrumentSelected),
4405 wxBoxSizer *itemBoxSizer04 =
new wxBoxSizer(wxVERTICAL);
4406 itemStaticBoxSizer03->Add(itemBoxSizer04, 0, wxALIGN_TOP | wxALL,
4408 m_pButtonAdd =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Add"),
4409 wxDefaultPosition, wxSize(-1, -1));
4410 itemBoxSizer04->Add(m_pButtonAdd, 0, wxEXPAND | wxALL, border_size);
4411 m_pButtonAdd->Connect(
4412 wxEVT_COMMAND_BUTTON_CLICKED,
4413 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentAdd), NULL,
4417 m_pButtonEdit =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Edit"),
4418 wxDefaultPosition, wxDefaultSize);
4419 itemBoxSizer04->Add(m_pButtonEdit, 0, wxEXPAND | wxALL, border_size);
4420 m_pButtonEdit->Connect(
4421 wxEVT_COMMAND_BUTTON_CLICKED,
4422 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentEdit), NULL,
4433 m_pButtonDelete =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Delete"),
4434 wxDefaultPosition, wxSize(-1, -1));
4435 itemBoxSizer04->Add(m_pButtonDelete, 0, wxEXPAND | wxALL, border_size);
4436 m_pButtonDelete->Connect(
4437 wxEVT_COMMAND_BUTTON_CLICKED,
4438 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentDelete),
4440 itemBoxSizer04->AddSpacer(10);
4441 m_pButtonUp =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Up"),
4442 wxDefaultPosition, wxDefaultSize);
4443 itemBoxSizer04->Add(m_pButtonUp, 0, wxEXPAND | wxALL, border_size);
4444 m_pButtonUp->Connect(
4445 wxEVT_COMMAND_BUTTON_CLICKED,
4446 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentUp), NULL,
4448 m_pButtonDown =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Down"),
4449 wxDefaultPosition, wxDefaultSize);
4450 itemBoxSizer04->Add(m_pButtonDown, 0, wxEXPAND | wxALL, border_size);
4451 m_pButtonDown->Connect(
4452 wxEVT_COMMAND_BUTTON_CLICKED,
4453 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentDown), NULL,
4456 wxPanel *itemPanelNotebook02 =
4457 new wxPanel(itemNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
4459 wxBoxSizer *itemBoxSizer05 =
new wxBoxSizer(wxVERTICAL);
4460 itemPanelNotebook02->SetSizer(itemBoxSizer05);
4461 itemNotebook->AddPage(itemPanelNotebook02, _(
"Appearance"));
4463 wxStaticBox *itemStaticBox01 =
4464 new wxStaticBox(itemPanelNotebook02, wxID_ANY, _(
"Fonts"));
4465 wxStaticBoxSizer *itemStaticBoxSizer01 =
4466 new wxStaticBoxSizer(itemStaticBox01, wxHORIZONTAL);
4467 itemBoxSizer05->Add(itemStaticBoxSizer01, 0, wxEXPAND | wxALL, border_size);
4468 wxFlexGridSizer *itemFlexGridSizer03 =
new wxFlexGridSizer(2);
4469 itemFlexGridSizer03->AddGrowableCol(1);
4470 itemStaticBoxSizer01->Add(itemFlexGridSizer03, 1, wxEXPAND | wxALL, 0);
4472 wxStaticText *itemStaticText04 =
4473 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Title:"),
4474 wxDefaultPosition, wxDefaultSize, 0);
4475 itemFlexGridSizer03->Add(itemStaticText04, 0, wxEXPAND | wxALL, border_size);
4477 m_pFontPickerTitle =
4478 new wxFontPickerCtrl(itemPanelNotebook02, wxID_ANY, g_USFontTitle,
4479 wxDefaultPosition, wxDefaultSize);
4480 itemFlexGridSizer03->Add(m_pFontPickerTitle, 0, wxALIGN_RIGHT | wxALL, 0);
4482 wxStaticText *itemStaticText05 =
4483 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Data:"),
4484 wxDefaultPosition, wxDefaultSize, 0);
4485 itemFlexGridSizer03->Add(itemStaticText05, 0, wxEXPAND | wxALL, border_size);
4487 new wxFontPickerCtrl(itemPanelNotebook02, wxID_ANY, g_USFontData,
4488 wxDefaultPosition, wxDefaultSize);
4489 itemFlexGridSizer03->Add(m_pFontPickerData, 0, wxALIGN_RIGHT | wxALL, 0);
4491 wxStaticText *itemStaticText06 =
4492 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Label:"),
4493 wxDefaultPosition, wxDefaultSize, 0);
4494 itemFlexGridSizer03->Add(itemStaticText06, 0, wxEXPAND | wxALL, border_size);
4495 m_pFontPickerLabel =
4496 new wxFontPickerCtrl(itemPanelNotebook02, wxID_ANY, g_USFontLabel,
4497 wxDefaultPosition, wxDefaultSize);
4498 itemFlexGridSizer03->Add(m_pFontPickerLabel, 0, wxALIGN_RIGHT | wxALL, 0);
4500 wxStaticText *itemStaticText07 =
4501 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Small:"),
4502 wxDefaultPosition, wxDefaultSize, 0);
4503 itemFlexGridSizer03->Add(itemStaticText07, 0, wxEXPAND | wxALL, border_size);
4504 m_pFontPickerSmall =
4505 new wxFontPickerCtrl(itemPanelNotebook02, wxID_ANY, g_USFontSmall,
4506 wxDefaultPosition, wxDefaultSize);
4507 itemFlexGridSizer03->Add(m_pFontPickerSmall, 0, wxALIGN_RIGHT | wxALL, 0);
4510 wxStaticText *itemStaticText80 =
4511 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Reset:"),
4512 wxDefaultPosition, wxDefaultSize, 0);
4513 itemFlexGridSizer03->Add(itemStaticText80, 0, wxEXPAND | wxALL, border_size);
4515 m_pButtondefaultFont =
new wxButton(itemPanelNotebook02, wxID_ANY,
4516 _(
"Set dashboard default fonts"),
4517 wxDefaultPosition, wxSize(-1, -1));
4518 itemFlexGridSizer03->Add(m_pButtondefaultFont, 0, wxALIGN_RIGHT | wxALL, 0);
4519 m_pButtondefaultFont->Connect(
4520 wxEVT_COMMAND_BUTTON_CLICKED,
4521 wxCommandEventHandler(DashboardPreferencesDialog::OnDashboarddefaultFont),
4524 wxStaticBox *itemStaticBox04 =
new wxStaticBox(itemPanelNotebook02, wxID_ANY,
4525 _(
"Units, Ranges, Formats"));
4526 wxStaticBoxSizer *itemStaticBoxSizer04 =
4527 new wxStaticBoxSizer(itemStaticBox04, wxHORIZONTAL);
4528 itemBoxSizer05->Add(itemStaticBoxSizer04, 0, wxEXPAND | wxALL, border_size);
4529 wxFlexGridSizer *itemFlexGridSizer04 =
new wxFlexGridSizer(2);
4530 itemFlexGridSizer04->AddGrowableCol(1);
4531 itemStaticBoxSizer04->Add(itemFlexGridSizer04, 1, wxEXPAND | wxALL, 0);
4532 wxStaticText *itemStaticText08 =
new wxStaticText(
4533 itemPanelNotebook02, wxID_ANY, _(
"Speedometer max value:"),
4534 wxDefaultPosition, wxDefaultSize, 0);
4535 itemFlexGridSizer04->Add(itemStaticText08, 0, wxEXPAND | wxALL, border_size);
4536 m_pSpinSpeedMax =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4537 wxDefaultPosition, wxDefaultSize,
4538 wxSP_ARROW_KEYS, 10, 100, g_iDashSpeedMax);
4539 itemFlexGridSizer04->Add(m_pSpinSpeedMax, 0, wxALIGN_RIGHT | wxALL, 0);
4541 wxStaticText *itemStaticText10 =
new wxStaticText(
4542 itemPanelNotebook02, wxID_ANY, _(
"Speed Over Ground Damping Factor:"),
4543 wxDefaultPosition, wxDefaultSize, 0);
4544 itemFlexGridSizer04->Add(itemStaticText10, 0, wxEXPAND | wxALL, border_size);
4545 m_pSpinSOGDamp =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4546 wxDefaultPosition, wxDefaultSize,
4547 wxSP_ARROW_KEYS, 0, 100, g_iDashSOGDamp);
4548 itemFlexGridSizer04->Add(m_pSpinSOGDamp, 0, wxALIGN_RIGHT | wxALL, 0);
4550 wxStaticText *itemStaticText11 =
4551 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"COG Damping Factor:"),
4552 wxDefaultPosition, wxDefaultSize, 0);
4553 itemFlexGridSizer04->Add(itemStaticText11, 0, wxEXPAND | wxALL, border_size);
4554 m_pSpinCOGDamp =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4555 wxDefaultPosition, wxDefaultSize,
4556 wxSP_ARROW_KEYS, 0, 100, g_iDashCOGDamp);
4557 itemFlexGridSizer04->Add(m_pSpinCOGDamp, 0, wxALIGN_RIGHT | wxALL, 0);
4559 wxStaticText *itemStaticText13 =
new wxStaticText(
4560 itemPanelNotebook02, wxID_ANY, _(
"Wind speed Damping Factor:"),
4561 wxDefaultPosition, wxDefaultSize, 0);
4562 itemFlexGridSizer04->Add(itemStaticText13, 0, wxEXPAND | wxALL, border_size);
4563 m_pSpinAWSDamp =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4564 wxDefaultPosition, wxDefaultSize,
4565 wxSP_ARROW_KEYS, 0, 100, g_iDashAWSDamp);
4566 itemFlexGridSizer04->Add(m_pSpinAWSDamp, 0, wxALIGN_RIGHT | wxALL, 0);
4568 wxStaticText *itemStaticText14 =
new wxStaticText(
4569 itemPanelNotebook02, wxID_ANY, _(
"Wind angle Damping Factor:"),
4570 wxDefaultPosition, wxDefaultSize, 0);
4571 itemFlexGridSizer04->Add(itemStaticText14, 0, wxEXPAND | wxALL, border_size);
4572 m_pSpinAWADamp =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4573 wxDefaultPosition, wxDefaultSize,
4574 wxSP_ARROW_KEYS, 0, 100, g_iDashAWADamp);
4575 itemFlexGridSizer04->Add(m_pSpinAWADamp, 0, wxALIGN_RIGHT | wxALL, 0);
4577 wxStaticText *itemStaticText12 =
new wxStaticText(
4578 itemPanelNotebook02, wxID_ANY, _(
"Local Time Offset From UTC:"),
4579 wxDefaultPosition, wxDefaultSize, 0);
4580 itemFlexGridSizer04->Add(itemStaticText12, 0, wxEXPAND | wxALL, border_size);
4581 wxString m_UTCOffsetChoices[] = {
4582 _T(
"-12:00" ), _T(
"-11:30" ), _T(
"-11:00" ), _T(
"-10:30" ),
4583 _T(
"-10:00" ), _T(
"-09:30" ), _T(
"-09:00" ), _T(
"-08:30" ),
4584 _T(
"-08:00" ), _T(
"-07:30" ), _T(
"-07:00" ), _T(
"-06:30" ),
4585 _T(
"-06:00" ), _T(
"-05:30" ), _T(
"-05:00" ), _T(
"-04:30" ),
4586 _T(
"-04:00" ), _T(
"-03:30" ), _T(
"-03:00" ), _T(
"-02:30" ),
4587 _T(
"-02:00" ), _T(
"-01:30" ), _T(
"-01:00" ), _T(
"-00:30" ),
4588 _T(
" 00:00" ), _T(
" 00:30" ), _T(
" 01:00" ), _T(
" 01:30" ),
4589 _T(
" 02:00" ), _T(
" 02:30" ), _T(
" 03:00" ), _T(
" 03:30" ),
4590 _T(
" 04:00" ), _T(
" 04:30" ), _T(
" 05:00" ), _T(
" 05:30" ),
4591 _T(
" 06:00" ), _T(
" 06:30" ), _T(
" 07:00" ), _T(
" 07:30" ),
4592 _T(
" 08:00" ), _T(
" 08:30" ), _T(
" 09:00" ), _T(
" 09:30" ),
4593 _T(
" 10:00" ), _T(
" 10:30" ), _T(
" 11:00" ), _T(
" 11:30" ),
4595 int m_UTCOffsetNChoices =
sizeof(m_UTCOffsetChoices) /
sizeof(wxString);
4596 m_pChoiceUTCOffset =
4597 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition,
4598 wxDefaultSize, m_UTCOffsetNChoices, m_UTCOffsetChoices, 0);
4599 m_pChoiceUTCOffset->SetSelection(g_iUTCOffset + 24);
4600 itemFlexGridSizer04->Add(m_pChoiceUTCOffset, 0, wxALIGN_RIGHT | wxALL, 0);
4602 wxStaticText *itemStaticText09 =
4603 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Boat speed units:"),
4604 wxDefaultPosition, wxDefaultSize, 0);
4605 itemFlexGridSizer04->Add(itemStaticText09, 0, wxEXPAND | wxALL, border_size);
4606 wxString m_SpeedUnitChoices[] = {_(
"Honor OpenCPN settings"), _(
"Kts"),
4607 _(
"mph"), _(
"km/h"), _(
"m/s")};
4608 int m_SpeedUnitNChoices =
sizeof(m_SpeedUnitChoices) /
sizeof(wxString);
4609 wxSize szSpeedUnit = wxDefaultSize;
4610 m_pChoiceSpeedUnit =
4611 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition,
4612 szSpeedUnit, m_SpeedUnitNChoices, m_SpeedUnitChoices, 0);
4613 for (
auto const &iUnit : m_SpeedUnitChoices) {
4614 szSpeedUnit.IncTo(m_pChoiceSpeedUnit->GetTextExtent(iUnit));
4616 m_pChoiceSpeedUnit->SetSize(szSpeedUnit);
4617 m_pChoiceSpeedUnit->SetSelection(g_iDashSpeedUnit + 1);
4618 itemFlexGridSizer04->Add(m_pChoiceSpeedUnit, 0, wxALIGN_RIGHT | wxALL, 0);
4620 wxStaticText *itemStaticTextDepthU =
4621 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Depth units:"),
4622 wxDefaultPosition, wxDefaultSize, 0);
4623 itemFlexGridSizer04->Add(itemStaticTextDepthU, 0, wxEXPAND | wxALL,
4625 wxString m_DepthUnitChoices[] = {_(
"Meters"), _(
"Feet"), _(
"Fathoms"),
4626 _(
"Inches"), _(
"Centimeters")};
4627 int m_DepthUnitNChoices =
sizeof(m_DepthUnitChoices) /
sizeof(wxString);
4628 wxSize szDepthUnit = wxDefaultSize;
4629 m_pChoiceDepthUnit =
4630 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition,
4631 szDepthUnit, m_DepthUnitNChoices, m_DepthUnitChoices, 0);
4632 for (
auto const &iUnit : m_DepthUnitChoices) {
4633 szDepthUnit.IncTo(m_pChoiceDepthUnit->GetTextExtent(iUnit));
4635 m_pChoiceDepthUnit->SetSize(szDepthUnit);
4636 m_pChoiceDepthUnit->SetSelection(g_iDashDepthUnit - 3);
4637 itemFlexGridSizer04->Add(m_pChoiceDepthUnit, 0, wxALIGN_RIGHT | wxALL, 0);
4638 wxString dMess = wxString::Format(_(
"Depth Offset (%s):"),
4639 m_DepthUnitChoices[g_iDashDepthUnit - 3]);
4640 wxStaticText *itemStaticDepthO =
4641 new wxStaticText(itemPanelNotebook02, wxID_ANY, dMess, wxDefaultPosition,
4644 switch (g_iDashDepthUnit - 3) {
4646 DepthOffset = g_dDashDBTOffset * 3.2808399;
4649 DepthOffset = g_dDashDBTOffset * 0.54680665;
4652 DepthOffset = g_dDashDBTOffset * 39.3700787;
4655 DepthOffset = g_dDashDBTOffset * 100;
4658 DepthOffset = g_dDashDBTOffset;
4660 itemFlexGridSizer04->Add(itemStaticDepthO, 0, wxEXPAND | wxALL, border_size);
4661 m_pSpinDBTOffset =
new wxSpinCtrlDouble(
4662 itemPanelNotebook02, wxID_ANY, wxEmptyString, wxDefaultPosition,
4663 wxDefaultSize, wxSP_ARROW_KEYS, -100, 100, DepthOffset, 0.1);
4664 itemFlexGridSizer04->Add(m_pSpinDBTOffset, 0, wxALIGN_RIGHT | wxALL, 0);
4666 wxStaticText *itemStaticText0b =
4667 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Distance units:"),
4668 wxDefaultPosition, wxDefaultSize, 0);
4669 itemFlexGridSizer04->Add(itemStaticText0b, 0, wxEXPAND | wxALL, border_size);
4670 wxString m_DistanceUnitChoices[] = {_(
"Honor OpenCPN settings"),
4671 _(
"Nautical miles"), _(
"Statute miles"),
4672 _(
"Kilometers"), _(
"Meters")};
4673 wxSize szDistanceUnit = wxDefaultSize;
4674 int m_DistanceUnitNChoices =
sizeof(m_DistanceUnitChoices) /
sizeof(wxString);
4675 m_pChoiceDistanceUnit =
new wxChoice(
4676 itemPanelNotebook02, wxID_ANY, wxDefaultPosition, szDistanceUnit,
4677 m_DistanceUnitNChoices, m_DistanceUnitChoices, 0);
4678 for (
auto const &iUnit : m_DistanceUnitChoices) {
4679 szDistanceUnit.IncTo(m_pChoiceDistanceUnit->GetTextExtent(iUnit));
4681 m_pChoiceDistanceUnit->SetSize(szDistanceUnit);
4682 m_pChoiceDistanceUnit->SetSelection(g_iDashDistanceUnit + 1);
4683 itemFlexGridSizer04->Add(m_pChoiceDistanceUnit, 0, wxALIGN_RIGHT | wxALL, 0);
4684 m_pChoiceDistanceUnit->Connect(
4685 wxEVT_COMMAND_CHOICE_SELECTED,
4686 wxCommandEventHandler(DashboardPreferencesDialog::OnDistanceUnitSelect),
4689 wxStaticText *itemStaticText0a =
4690 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Wind speed units:"),
4691 wxDefaultPosition, wxDefaultSize, 0);
4692 itemFlexGridSizer04->Add(itemStaticText0a, 0, wxEXPAND | wxALL, border_size);
4693 wxString m_WSpeedUnitChoices[] = {_(
"Kts"), _(
"mph"), _(
"km/h"), _(
"m/s")};
4694 int m_WSpeedUnitNChoices =
sizeof(m_WSpeedUnitChoices) /
sizeof(wxString);
4695 wxSize szWSpeedUnit = wxDefaultSize;
4696 m_pChoiceWindSpeedUnit =
4697 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition,
4698 szWSpeedUnit, m_WSpeedUnitNChoices, m_WSpeedUnitChoices, 0);
4699 for (
auto const &iUnit : m_WSpeedUnitChoices) {
4700 szWSpeedUnit.IncTo(m_pChoiceWindSpeedUnit->GetTextExtent(iUnit));
4702 m_pChoiceWindSpeedUnit->SetSize(szWSpeedUnit);
4703 m_pChoiceWindSpeedUnit->SetSelection(g_iDashWindSpeedUnit);
4704 itemFlexGridSizer04->Add(m_pChoiceWindSpeedUnit, 0, wxALIGN_RIGHT | wxALL, 0);
4706 wxStaticText *itemStaticText0c =
4707 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Temperature units:"),
4708 wxDefaultPosition, wxDefaultSize, 0);
4709 itemFlexGridSizer04->Add(itemStaticText0c, 0, wxEXPAND | wxALL, border_size);
4710 wxString m_TempUnitChoices[] = {_(
"Celsius"), _(
"Fahrenheit"), _(
"Kelvin")};
4711 int m_TempUnitNChoices =
sizeof(m_TempUnitChoices) /
sizeof(wxString);
4712 wxSize szTempUnit = wxDefaultSize;
4714 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition, szTempUnit,
4715 m_TempUnitNChoices, m_TempUnitChoices, 0);
4716 for (
auto const &iUnit : m_TempUnitChoices) {
4717 szTempUnit.IncTo(m_pChoiceTempUnit->GetTextExtent(iUnit));
4719 m_pChoiceTempUnit->SetSize(szTempUnit);
4720 m_pChoiceTempUnit->SetSelection(g_iDashTempUnit);
4721 itemFlexGridSizer04->Add(m_pChoiceTempUnit, 0, wxALIGN_RIGHT | wxALL, 0);
4725 wxStaticBox *itemStaticBox05 =
4726 new wxStaticBox(itemPanelNotebook02, wxID_ANY, _(
"Other selections"));
4727 wxStaticBoxSizer *itemStaticBoxSizer05 =
4728 new wxStaticBoxSizer(itemStaticBox05, wxHORIZONTAL);
4729 itemBoxSizer05->Add(itemStaticBoxSizer05, 0, wxEXPAND | wxALL, border_size);
4731 wxFlexGridSizer *itemFlexGridSizer05 =
new wxFlexGridSizer(3);
4732 itemFlexGridSizer05->AddGrowableCol(1);
4733 itemStaticBoxSizer05->Add(itemFlexGridSizer05, 1, wxEXPAND | wxALL, 0);
4735 m_pUseInternSumLog =
new wxCheckBox(itemPanelNotebook02, wxID_ANY,
4736 _(
"Use internal Sumlog.") +
" " +
4737 _(
"Enter new value if desired"));
4738 itemFlexGridSizer05->Add(m_pUseInternSumLog, 1, wxALIGN_LEFT, border_size);
4739 m_pUseInternSumLog->SetValue(g_bUseInternSumLog);
4742 new wxStaticText(itemPanelNotebook02, wxID_ANY,
4744 wxDefaultPosition, wxDefaultSize, 0);
4745 itemFlexGridSizer05->Add(m_SumLogUnit, 1, wxALIGN_RIGHT, 0);
4747 m_pSumLogValue =
new wxTextCtrl(itemPanelNotebook02, wxID_ANY,
"");
4748 itemFlexGridSizer05->Add(m_pSumLogValue, 1, wxALIGN_LEFT, 1);
4749 m_pSumLogValue->SetValue(wxString::Format(
4752 m_pUseTrueWinddata =
new wxCheckBox(itemPanelNotebook02, wxID_ANY,
4753 _(
"Use N2K & SignalK true wind data over "
4754 "ground.\n(Instead of through water)"));
4755 itemFlexGridSizer05->Add(m_pUseTrueWinddata, 1, wxALIGN_LEFT, border_size);
4756 m_pUseTrueWinddata->SetValue(g_bDBtrueWindGround);
4760 wxStaticBox *itemStaticBox05 =
4761 new wxStaticBox(itemPanelNotebook02, wxID_ANY, _(
"Other selections"));
4762 wxStaticBoxSizer *itemStaticBoxSizer05 =
4763 new wxStaticBoxSizer(itemStaticBox05, wxHORIZONTAL);
4764 itemBoxSizer05->Add(itemStaticBoxSizer05, 0, wxEXPAND | wxALL, border_size);
4766 wxFlexGridSizer *itemFlexGridSizer05 =
new wxFlexGridSizer(2);
4767 itemFlexGridSizer05->AddGrowableCol(1);
4768 itemStaticBoxSizer05->Add(itemFlexGridSizer05, 1, wxEXPAND | wxALL, 0);
4770 m_pUseInternSumLog =
new wxCheckBox(itemPanelNotebook02, wxID_ANY,
4771 _(
"Use internal Sumlog.") +
" ");
4772 itemFlexGridSizer05->Add(m_pUseInternSumLog, 0, wxALIGN_LEFT, border_size);
4773 m_pUseInternSumLog->SetValue(g_bUseInternSumLog);
4774 itemFlexGridSizer05->AddSpacer(0);
4777 new wxStaticText(itemPanelNotebook02, wxID_ANY,
4778 " " + _(
"Enter new value if desired") +
" ",
4779 wxDefaultPosition, wxDefaultSize, 0);
4780 itemFlexGridSizer05->Add(xtext, 1, wxALIGN_LEFT, 0);
4781 itemFlexGridSizer05->AddSpacer(0);
4783 m_SumLogUnit =
new wxStaticText(
4784 itemPanelNotebook02, wxID_ANY,
4786 wxDefaultPosition, wxDefaultSize, 0);
4787 itemFlexGridSizer05->Add(m_SumLogUnit, 1, wxALIGN_RIGHT, 0);
4789 m_pSumLogValue =
new wxTextCtrl(itemPanelNotebook02, wxID_ANY,
"");
4790 itemFlexGridSizer05->Add(m_pSumLogValue, 1, wxALIGN_LEFT, 1);
4791 m_pSumLogValue->SetValue(wxString::Format(
4794 m_pUseTrueWinddata =
new wxCheckBox(itemPanelNotebook02, wxID_ANY,
4795 _(
"Use N2K & SignalK true wind data over "
4796 "ground.\n(Instead of through water)"));
4797 itemFlexGridSizer05->Add(m_pUseTrueWinddata, 1, wxALIGN_LEFT, border_size);
4798 m_pUseTrueWinddata->SetValue(g_bDBtrueWindGround);
4799 itemFlexGridSizer05->AddSpacer(0);
4801 auto xtext1 =
new wxStaticText(itemPanelNotebook02, wxID_ANY,
" ",
4802 wxDefaultPosition, wxDefaultSize, 0);
4803 itemFlexGridSizer05->Add(xtext1, 1, wxALIGN_LEFT, 0);
4804 itemFlexGridSizer05->AddSpacer(0);
4806 auto xtext2 =
new wxStaticText(itemPanelNotebook02, wxID_ANY,
" ",
4807 wxDefaultPosition, wxDefaultSize, 0);
4808 itemFlexGridSizer05->Add(xtext2, 1, wxALIGN_LEFT, 0);
4809 itemFlexGridSizer05->AddSpacer(0);
4814 for (
size_t i = 0; i < m_Config.GetCount(); i++) {
4815 m_pListCtrlDashboards->InsertItem(i, 0);
4817 m_pListCtrlDashboards->SetItemData(i, i);
4819 m_pListCtrlDashboards->SetColumnWidth(0, wxLIST_AUTOSIZE);
4821 m_pListCtrlDashboards->SetItemState(0, wxLIST_STATE_SELECTED,
4822 wxLIST_STATE_SELECTED);
4825 UpdateDashboardButtonsState();
4826 UpdateButtonsState();
4833 SetMaxSize(wxSize(display_width, display_height));
4836 if (display_height < 600) {
4837 if (g_dashPrefWidth > 0 && g_dashPrefHeight > 0)
4838 SetSize(wxSize(g_dashPrefWidth, g_dashPrefHeight));
4840 SetSize(wxSize(canvas_size.x * 8 / 10, canvas_size.y * 8 / 10));
4842 if (g_dashPrefWidth > 0 && g_dashPrefHeight > 0)
4843 SetSize(wxSize(g_dashPrefWidth, g_dashPrefHeight));
4845 SetSize(wxSize(canvas_size.x * 3 / 4, canvas_size.y * 8 / 10));
4852void DashboardPreferencesDialog::RecalculateSize(
void) {
4853#ifdef __OCPN__ANDROID__
4855 esize.x = GetCharWidth() * 110;
4856 esize.y = GetCharHeight() * 40;
4859 esize.y = wxMin(esize.y, dsize.y - (3 * GetCharHeight()));
4860 esize.x = wxMin(esize.x, dsize.x - (3 * GetCharHeight()));
4867void DashboardPreferencesDialog::OnCloseDialog(wxCloseEvent &event) {
4868 g_dashPrefWidth = GetSize().x;
4869 g_dashPrefHeight = GetSize().y;
4870 SaveDashboardConfig();
4874void DashboardPreferencesDialog::SaveDashboardConfig() {
4875 g_iDashSpeedMax = m_pSpinSpeedMax->GetValue();
4876 g_iDashCOGDamp = m_pSpinCOGDamp->GetValue();
4877 g_iDashSOGDamp = m_pSpinSOGDamp->GetValue();
4878 g_iDashAWADamp = m_pSpinAWADamp->GetValue();
4879 g_iDashAWSDamp = m_pSpinAWSDamp->GetValue();
4881 g_bUseInternSumLog = m_pUseInternSumLog->IsChecked();
4883 m_pSumLogValue->GetValue().ToDouble(&ursDist);
4886 g_iUTCOffset = m_pChoiceUTCOffset->GetSelection() - 24;
4887 g_iDashSpeedUnit = m_pChoiceSpeedUnit->GetSelection() - 1;
4888 double DashDBTOffset = m_pSpinDBTOffset->GetValue();
4889 switch (g_iDashDepthUnit - 3) {
4891 g_dDashDBTOffset = DashDBTOffset / 3.2808399;
4894 g_dDashDBTOffset = DashDBTOffset / 0.54680665;
4897 g_dDashDBTOffset = DashDBTOffset / 39.3700787;
4900 g_dDashDBTOffset = DashDBTOffset / 100;
4903 g_dDashDBTOffset = DashDBTOffset;
4905 g_iDashDepthUnit = m_pChoiceDepthUnit->GetSelection() + 3;
4906 g_iDashDistanceUnit = m_pChoiceDistanceUnit->GetSelection() - 1;
4907 g_iDashWindSpeedUnit = m_pChoiceWindSpeedUnit->GetSelection();
4908 g_bDBtrueWindGround = m_pUseTrueWinddata->GetValue();
4909 g_iDashTempUnit = m_pChoiceTempUnit->GetSelection();
4912 cont->m_bIsVisible = m_pCheckBoxIsVisible->IsChecked();
4913 cont->m_sCaption = m_pTextCtrlCaption->GetValue();
4914 cont->m_sOrientation =
4915 m_pChoiceOrientation->GetSelection() == 0 ? _T(
"V") : _T(
"H");
4916 cont->m_aInstrumentList.Clear();
4917 for (
int i = 0; i < m_pListCtrlInstruments->GetItemCount(); i++)
4918 cont->m_aInstrumentList.Add((
int)m_pListCtrlInstruments->GetItemData(i));
4922void DashboardPreferencesDialog::OnDashboardSelected(wxListEvent &event) {
4924 SaveDashboardConfig();
4925 UpdateDashboardButtonsState();
4928void DashboardPreferencesDialog::UpdateDashboardButtonsState() {
4930 item = m_pListCtrlDashboards->GetNextItem(item, wxLIST_NEXT_ALL,
4931 wxLIST_STATE_SELECTED);
4932 bool enable = (item != -1);
4936 bool delete_enable = enable;
4938 int sel = m_pListCtrlDashboards->GetItemData(item);
4941 if (dash_sel == GetParent()) delete_enable =
false;
4943 m_pButtonDeleteDashboard->Enable(delete_enable);
4945 m_pPanelDashboard->Enable(enable);
4948 curSel = m_pListCtrlDashboards->GetItemData(item);
4950 m_pCheckBoxIsVisible->SetValue(cont->m_bIsVisible);
4951 m_pTextCtrlCaption->SetValue(cont->m_sCaption);
4952 m_pChoiceOrientation->SetSelection(cont->m_sOrientation == _T(
"V") ? 0 : 1);
4953 m_pListCtrlInstruments->DeleteAllItems();
4954 for (
size_t i = 0; i < cont->m_aInstrumentList.GetCount(); i++) {
4956 getListItemForInstrument(item, cont->m_aInstrumentList.Item(i));
4957 item.SetId(m_pListCtrlInstruments->GetItemCount());
4958 m_pListCtrlInstruments->InsertItem(item);
4961 m_pListCtrlInstruments->SetColumnWidth(0, wxLIST_AUTOSIZE);
4964 m_pCheckBoxIsVisible->SetValue(
false);
4965 m_pTextCtrlCaption->SetValue(_T(
""));
4966 m_pChoiceOrientation->SetSelection(0);
4967 m_pListCtrlInstruments->DeleteAllItems();
4972void DashboardPreferencesDialog::OnDashboarddefaultFont(wxCommandEvent &event) {
4973 m_pFontPickerTitle->SetSelectedFont(
4974 wxFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL));
4975 m_pFontPickerTitle->SetSelectedColour(wxColour(0, 0, 0));
4976 m_pFontPickerData->SetSelectedFont(
4977 wxFont(14, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
4978 m_pFontPickerData->SetSelectedColour(wxColour(0, 0, 0));
4979 m_pFontPickerLabel->SetSelectedFont(
4980 wxFont(8, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
4981 m_pFontPickerLabel->SetSelectedColour(wxColour(0, 0, 0));
4982 m_pFontPickerSmall->SetSelectedFont(
4983 wxFont(8, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
4984 m_pFontPickerSmall->SetSelectedColour(wxColour(0, 0, 0));
4985 double scaler = 1.0;
4988 scaler = wxMax(1.0, scaler);
4990 g_USFontTitle = *(m_pFontPickerTitle->GetFontData());
4991 g_FontTitle = *g_pUSFontTitle;
4992 g_FontTitle.SetChosenFont(g_pUSFontTitle->GetChosenFont().Scaled(scaler));
4993 g_FontTitle.SetColour(g_pUSFontTitle->GetColour());
4994 g_USFontTitle = *g_pUSFontTitle;
4996 g_USFontData = *(m_pFontPickerData->GetFontData());
4997 g_FontData = *g_pUSFontData;
4998 g_FontData.SetChosenFont(g_pUSFontData->GetChosenFont().Scaled(scaler));
4999 g_FontData.SetColour(g_pUSFontData->GetColour());
5000 g_USFontData = *g_pUSFontData;
5002 g_USFontLabel = *(m_pFontPickerLabel->GetFontData());
5003 g_FontLabel = *g_pUSFontLabel;
5004 g_FontLabel.SetChosenFont(g_pUSFontLabel->GetChosenFont().Scaled(scaler));
5005 g_FontLabel.SetColour(g_pUSFontLabel->GetColour());
5006 g_USFontLabel = *g_pUSFontLabel;
5008 g_USFontSmall = *(m_pFontPickerSmall->GetFontData());
5009 g_FontSmall = *g_pUSFontSmall;
5010 g_FontSmall.SetChosenFont(g_pUSFontSmall->GetChosenFont().Scaled(scaler));
5011 g_FontSmall.SetColour(g_pUSFontSmall->GetColour());
5012 g_USFontSmall = *g_pUSFontSmall;
5015void DashboardPreferencesDialog::OnDashboardAdd(wxCommandEvent &event) {
5016 int idx = m_pListCtrlDashboards->GetItemCount();
5017 m_pListCtrlDashboards->InsertItem(idx, 0);
5019 m_pListCtrlDashboards->SetItemData(idx, m_Config.GetCount());
5021 wxArrayOfInstrumentProperties Property;
5023 NULL, MakeName(), _(
"Dashboard"), _T(
"V"), ar, Property);
5024 dwc->m_bIsVisible =
true;
5028void DashboardPreferencesDialog::OnDashboardDelete(wxCommandEvent &event) {
5030 itemID = m_pListCtrlDashboards->GetNextItem(itemID, wxLIST_NEXT_ALL,
5031 wxLIST_STATE_SELECTED);
5033 int idx = m_pListCtrlDashboards->GetItemData(itemID);
5034 m_pListCtrlDashboards->DeleteItem(itemID);
5035 m_Config.Item(idx)->m_bIsDeleted =
true;
5036 UpdateDashboardButtonsState();
5039void DashboardPreferencesDialog::OnInstrumentSelected(wxListEvent &event) {
5040 UpdateButtonsState();
5043void DashboardPreferencesDialog::UpdateButtonsState() {
5045 item = m_pListCtrlInstruments->GetNextItem(item, wxLIST_NEXT_ALL,
5046 wxLIST_STATE_SELECTED);
5047 bool enable = (item != -1);
5049 m_pButtonDelete->Enable(enable);
5050 m_pButtonEdit->Enable(enable);
5051 m_pButtonUp->Enable(item > 0);
5052 m_pButtonDown->Enable(item != -1 &&
5053 item < m_pListCtrlInstruments->GetItemCount() - 1);
5056void DashboardPreferencesDialog::OnInstrumentAdd(wxCommandEvent &event) {
5059#ifdef __OCPN__ANDROID__
5064 esize.x = GetCharWidth() * 110;
5065 esize.y = GetCharHeight() * 40;
5068 esize.y = wxMin(esize.y, dsize.y - (3 * GetCharHeight()));
5069 esize.x = wxMin(esize.x, dsize.x - (3 * GetCharHeight()));
5070 pdlg.SetSize(esize);
5072 pdlg.CentreOnScreen();
5075 if (pdlg.GetReturnCode() == wxID_OK) {
5077 getListItemForInstrument(item, pdlg.GetInstrumentAdded());
5078 item.SetId(m_pListCtrlInstruments->GetItemCount());
5079 m_pListCtrlInstruments->InsertItem(item);
5080 m_pListCtrlInstruments->SetColumnWidth(0, wxLIST_AUTOSIZE);
5081 UpdateButtonsState();
5085void DashboardPreferencesDialog::OnInstrumentDelete(wxCommandEvent &event) {
5086 long itemIDWindow = -1;
5087 itemIDWindow = m_pListCtrlDashboards->GetNextItem(
5088 itemIDWindow, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
5090 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5091 wxLIST_STATE_SELECTED);
5093 m_Config.Item(m_pListCtrlDashboards->GetItemData(itemIDWindow));
5097 for (
unsigned int i = 0; i < (cont->m_aInstrumentPropertyList.GetCount());
5099 Inst = cont->m_aInstrumentPropertyList.Item(i);
5100 if (Inst->m_aInstrument ==
5101 (
int)m_pListCtrlInstruments->GetItemData(itemID) &&
5102 Inst->m_Listplace == itemID) {
5103 cont->m_aInstrumentPropertyList.Remove(Inst);
5107 if (Inst->m_Listplace > itemID) Inst->m_Listplace--;
5111 m_pListCtrlInstruments->DeleteItem(itemID);
5113 cont->m_pDashboardWindow->SetInstrumentList(
5114 cont->m_aInstrumentList, &(cont->m_aInstrumentPropertyList));
5117 UpdateButtonsState();
5120inline void GetFontData(
OCPNFontButton *FontButton, wxFontData &UnScaledFont,
5121 wxFontData &ScaledFont,
double scaler) {
5122 UnScaledFont = *(FontButton->GetFontData());
5123 ScaledFont = UnScaledFont;
5124 ScaledFont.SetChosenFont(UnScaledFont.GetChosenFont().Scaled(scaler));
5127void DashboardPreferencesDialog::OnInstrumentEdit(wxCommandEvent &event) {
5130 long itemIDWindow = -1;
5131 itemIDWindow = m_pListCtrlDashboards->GetNextItem(
5132 itemIDWindow, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
5134 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5135 wxLIST_STATE_SELECTED);
5141 m_Config.Item(m_pListCtrlDashboards->GetItemData(itemIDWindow));
5144 for (
unsigned int i = 0; i < (cont->m_aInstrumentPropertyList.GetCount());
5146 Inst = cont->m_aInstrumentPropertyList.Item(
5148 if (Inst->m_aInstrument == (
int)m_pListCtrlInstruments->GetItemData(
5151 if (Inst->m_Listplace == itemID)
break;
5158 cont->m_aInstrumentPropertyList.Add(Inst);
5162 bool DefaultFont =
false;
5163 if (Edit->ShowModal() == wxID_OK) {
5165 double scaler = 1.0;
5168 scaler = wxMax(1.0, scaler);
5169 if (Edit->m_fontPicker2->GetFont().Scaled(scaler) !=
5170 g_FontTitle.GetChosenFont() ||
5171 Edit->m_fontPicker2->GetSelectedColour() != g_FontTitle.GetColour())
5172 DefaultFont =
false;
5173 if (Edit->m_fontPicker4->GetFont().Scaled(scaler) !=
5174 g_FontData.GetChosenFont() ||
5175 Edit->m_fontPicker4->GetSelectedColour() != g_FontData.GetColour())
5176 DefaultFont =
false;
5177 if (Edit->m_fontPicker5->GetFont().Scaled(scaler) !=
5178 g_FontLabel.GetChosenFont() ||
5179 Edit->m_fontPicker5->GetSelectedColour() != g_FontLabel.GetColour())
5180 DefaultFont =
false;
5181 if (Edit->m_fontPicker6->GetFont().Scaled(scaler) !=
5182 g_FontSmall.GetChosenFont() ||
5183 Edit->m_fontPicker6->GetSelectedColour() != g_FontSmall.GetColour())
5184 DefaultFont =
false;
5186 GetGlobalColor(_T(
"DASHL"), &dummy);
5187 if (Edit->m_colourPicker1->GetColour() != dummy) DefaultFont =
false;
5188 GetGlobalColor(_T(
"DASHB"), &dummy);
5189 if (Edit->m_colourPicker2->GetColour() != dummy) DefaultFont =
false;
5190 GetGlobalColor(_T(
"DASHN"), &dummy);
5191 if (Edit->m_colourPicker3->GetColour() != dummy) DefaultFont =
false;
5192 GetGlobalColor(_T(
"BLUE3"), &dummy);
5193 if (Edit->m_colourPicker4->GetColour() != dummy) DefaultFont =
false;
5195 cont->m_aInstrumentPropertyList.Remove(Inst);
5197 GetFontData(Edit->m_fontPicker2, Inst->m_USTitleFont, Inst->m_TitleFont,
5199 GetFontData(Edit->m_fontPicker4, Inst->m_USDataFont, Inst->m_DataFont,
5201 GetFontData(Edit->m_fontPicker5, Inst->m_USLabelFont, Inst->m_LabelFont,
5203 GetFontData(Edit->m_fontPicker6, Inst->m_USSmallFont, Inst->m_SmallFont,
5205 Inst->m_DataBackgroundColour = Edit->m_colourPicker2->GetColour();
5206 Inst->m_TitleBackgroundColour = Edit->m_colourPicker1->GetColour();
5207 Inst->m_Arrow_First_Colour = Edit->m_colourPicker3->GetColour();
5208 Inst->m_Arrow_Second_Colour = Edit->m_colourPicker4->GetColour();
5212 if (cont->m_pDashboardWindow) {
5213 cont->m_pDashboardWindow->SetInstrumentList(
5214 cont->m_aInstrumentList, &(cont->m_aInstrumentPropertyList));
5216 if (DefaultFont)
delete Inst;
5219void DashboardPreferencesDialog::OnInstrumentUp(wxCommandEvent &event) {
5220 long itemIDWindow = -1;
5221 itemIDWindow = m_pListCtrlDashboards->GetNextItem(
5222 itemIDWindow, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
5224 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5225 wxLIST_STATE_SELECTED);
5228 item.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_IMAGE | wxLIST_MASK_DATA);
5229 m_pListCtrlInstruments->GetItem(item);
5230 item.SetId(itemID - 1);
5234 m_Config.Item(m_pListCtrlDashboards->GetItemData(itemIDWindow));
5237 for (
unsigned int i = 0; i < (cont->m_aInstrumentPropertyList.GetCount());
5239 Inst = cont->m_aInstrumentPropertyList.Item(i);
5240 if (Inst->m_Listplace == (itemID - 1)) Inst->m_Listplace = itemID;
5241 if (Inst->m_aInstrument ==
5242 (
int)m_pListCtrlInstruments->GetItemData(itemID) &&
5243 Inst->m_Listplace == itemID) {
5244 cont->m_aInstrumentPropertyList.Item(i)->m_Listplace = itemID - 1;
5248 m_pListCtrlInstruments->DeleteItem(itemID);
5249 m_pListCtrlInstruments->InsertItem(item);
5250 for (
int i = 0; i < m_pListCtrlInstruments->GetItemCount(); i++)
5251 m_pListCtrlInstruments->SetItemState(i, 0, wxLIST_STATE_SELECTED);
5253 m_pListCtrlInstruments->SetItemState(itemID - 1, wxLIST_STATE_SELECTED,
5254 wxLIST_STATE_SELECTED);
5256 UpdateButtonsState();
5259void DashboardPreferencesDialog::OnInstrumentDown(wxCommandEvent &event) {
5260 long itemIDWindow = -1;
5261 itemIDWindow = m_pListCtrlDashboards->GetNextItem(
5262 itemIDWindow, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
5264 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5265 wxLIST_STATE_SELECTED);
5269 item.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_IMAGE | wxLIST_MASK_DATA);
5270 m_pListCtrlInstruments->GetItem(item);
5271 item.SetId(itemID + 1);
5275 m_Config.Item(m_pListCtrlDashboards->GetItemData(itemIDWindow));
5278 for (
unsigned int i = 0; i < (cont->m_aInstrumentPropertyList.GetCount());
5280 Inst = cont->m_aInstrumentPropertyList.Item(i);
5281 if (Inst->m_Listplace == (itemID + 1) &&
5282 Inst->m_aInstrument !=
5283 (int)m_pListCtrlInstruments->GetItemData(itemID))
5284 Inst->m_Listplace = itemID;
5285 if (Inst->m_aInstrument ==
5286 (
int)m_pListCtrlInstruments->GetItemData(itemID) &&
5287 Inst->m_Listplace == itemID) {
5288 cont->m_aInstrumentPropertyList.Item(i)->m_Listplace = itemID + 1;
5293 m_pListCtrlInstruments->DeleteItem(itemID);
5294 m_pListCtrlInstruments->InsertItem(item);
5295 for (
int i = 0; i < m_pListCtrlInstruments->GetItemCount(); i++)
5296 m_pListCtrlInstruments->SetItemState(i, 0, wxLIST_STATE_SELECTED);
5298 m_pListCtrlInstruments->SetItemState(itemID + 1, wxLIST_STATE_SELECTED,
5299 wxLIST_STATE_SELECTED);
5301 UpdateButtonsState();
5304void DashboardPreferencesDialog::OnDistanceUnitSelect(wxCommandEvent &event) {
5306 g_iDashDistanceUnit = m_pChoiceDistanceUnit->GetSelection() - 1;
5308 m_pSumLogValue->SetValue(wxString::Format(
5318AddInstrumentDlg::AddInstrumentDlg(wxWindow *pparent, wxWindowID
id)
5319 : wxDialog(pparent, id, _(
"Add instrument"), wxDefaultPosition,
5320 wxDefaultSize, wxDEFAULT_DIALOG_STYLE) {
5321 wxBoxSizer *itemBoxSizer01 =
new wxBoxSizer(wxVERTICAL);
5322 SetSizer(itemBoxSizer01);
5323 wxStaticText *itemStaticText01 =
5324 new wxStaticText(
this, wxID_ANY, _(
"Select instrument to add:"),
5325 wxDefaultPosition, wxDefaultSize, 0);
5326 itemBoxSizer01->Add(itemStaticText01, 0, wxEXPAND | wxALL, 5);
5330 wxImageList *imglist =
5331 new wxImageList(instImageRefSize, instImageRefSize,
true, 2);
5333 wxImage inst1 = wxBitmap(*_img_instrument).ConvertToImage();
5335 inst1.Scale(instImageRefSize, instImageRefSize, wxIMAGE_QUALITY_HIGH);
5336 imglist->Add(wxBitmap(inst1s));
5338 wxImage dial1 = wxBitmap(*_img_dial).ConvertToImage();
5340 dial1.Scale(instImageRefSize, instImageRefSize, wxIMAGE_QUALITY_HIGH);
5341 imglist->Add(wxBitmap(dial1s));
5344 int vsize = dsize.y * 50 / 100;
5346#ifdef __OCPN__ANDROID__
5348 wxDisplaySize(&dw, &dh);
5349 vsize = dh * 50 / 100;
5352 m_pListCtrlInstruments =
new wxListCtrl(
5353 this, wxID_ANY, wxDefaultPosition, wxSize(-1, vsize ),
5354 wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING);
5355 itemBoxSizer01->Add(m_pListCtrlInstruments, 0, wxEXPAND | wxALL, 5);
5356 m_pListCtrlInstruments->AssignImageList(imglist, wxIMAGE_LIST_SMALL);
5357 m_pListCtrlInstruments->InsertColumn(0, _(
"Instruments"));
5360 m_pListCtrlInstruments->SetFont(*pF);
5362#ifdef __OCPN__ANDROID__
5363 m_pListCtrlInstruments->GetHandle()->setStyleSheet(qtStyleSheet);
5367 wxStdDialogButtonSizer *DialogButtonSizer =
5368 CreateStdDialogButtonSizer(wxOK | wxCANCEL);
5369 itemBoxSizer01->Add(DialogButtonSizer, 0, wxALIGN_RIGHT | wxALL, 5);
5372 for (
unsigned int i = ID_DBP_I_POS; i < ID_DBP_LAST_ENTRY;
5376 if (IsObsolete(i))
continue;
5377 getListItemForInstrument(item, i);
5379 m_pListCtrlInstruments->InsertItem(item);
5383 m_pListCtrlInstruments->SetColumnWidth(0, wxLIST_AUTOSIZE);
5384 m_pListCtrlInstruments->SetItemState(0, wxLIST_STATE_SELECTED,
5385 wxLIST_STATE_SELECTED);
5389unsigned int AddInstrumentDlg::GetInstrumentAdded() {
5391 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5392 wxLIST_STATE_SELECTED);
5394 return (
int)m_pListCtrlInstruments->GetItemData(itemID);
5404DashboardWindow::DashboardWindow(wxWindow *pparent, wxWindowID
id,
5407 : wxWindow(pparent, id, wxDefaultPosition, wxDefaultSize, 0) {
5413 m_Container = mycont;
5416 itemBoxSizer =
new wxBoxSizer(orient);
5417 SetSizer(itemBoxSizer);
5418 Connect(wxEVT_SIZE, wxSizeEventHandler(DashboardWindow::OnSize), NULL,
this);
5419 Connect(wxEVT_CONTEXT_MENU,
5420 wxContextMenuEventHandler(DashboardWindow::OnContextMenu), NULL,
5422 Connect(wxEVT_COMMAND_MENU_SELECTED,
5423 wxCommandEventHandler(DashboardWindow::OnContextMenuSelect), NULL,
5426#ifdef __OCPN__ANDROID__
5427 Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(DashboardWindow::OnMouseEvent));
5428 Connect(wxEVT_LEFT_UP, wxMouseEventHandler(DashboardWindow::OnMouseEvent));
5429 Connect(wxEVT_MOTION, wxMouseEventHandler(DashboardWindow::OnMouseEvent));
5431 GetHandle()->setAttribute(Qt::WA_AcceptTouchEvents);
5432 GetHandle()->grabGesture(Qt::PinchGesture);
5433 GetHandle()->grabGesture(Qt::PanGesture);
5435 Connect(wxEVT_QT_PINCHGESTURE,
5440 wxEVT_QT_PANGESTURE,
5441 (wxObjectEventFunction)(wxEventFunction)&DashboardWindow::OnEvtPanGesture,
5447 m_binResize =
false;
5451DashboardWindow::~DashboardWindow() {
5452 for (
size_t i = 0; i < m_ArrayOfInstrument.GetCount(); i++) {
5458#ifdef __OCPN__ANDROID__
5459void DashboardWindow::OnEvtPinchGesture(wxQT_PinchGestureEvent &event) {
5460 float zoom_gain = 0.3;
5462 float total_zoom_val;
5464 if (event.GetScaleFactor() > 1)
5465 zoom_val = ((
event.GetScaleFactor() - 1.0) * zoom_gain) + 1.0;
5467 zoom_val = 1.0 - ((1.0 -
event.GetScaleFactor()) * zoom_gain);
5469 if (event.GetTotalScaleFactor() > 1)
5470 total_zoom_val = ((event.GetTotalScaleFactor() - 1.0) * zoom_gain) + 1.0;
5472 total_zoom_val = 1.0 - ((1.0 -
event.GetTotalScaleFactor()) * zoom_gain);
5474 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5476 wxSize currentSize = wxSize(pane.floating_size.x, pane.floating_size.y);
5477 double aRatio = (double)currentSize.y / (
double)currentSize.x;
5480 wxPoint par_pos = wxPoint(pane.floating_pos.x, pane.floating_pos.y);
5482 switch (event.GetState()) {
5483 case GestureStarted:
5487 case GestureUpdated:
5488 currentSize.y *= zoom_val;
5489 currentSize.x *= zoom_val;
5491 if ((par_pos.y + currentSize.y) > par_size.y)
5492 currentSize.y = par_size.y - par_pos.y;
5494 if ((par_pos.x + currentSize.x) > par_size.x)
5495 currentSize.x = par_size.x - par_pos.x;
5498 currentSize.x = currentSize.y / aRatio;
5500 currentSize.x = wxMax(currentSize.x, 150);
5501 currentSize.y = wxMax(currentSize.y, 150);
5503 pane.FloatingSize(currentSize);
5504 m_pauimgr->Update();
5508 case GestureFinished: {
5509 if (itemBoxSizer->GetOrientation() == wxVERTICAL) {
5510 currentSize.y *= total_zoom_val;
5511 currentSize.x = currentSize.y / aRatio;
5513 currentSize.x *= total_zoom_val;
5514 currentSize.y = currentSize.x * aRatio;
5518 if ((par_pos.y + currentSize.y) > par_size.y)
5519 currentSize.y = par_size.y - par_pos.y;
5521 if ((par_pos.x + currentSize.x) > par_size.x)
5522 currentSize.x = par_size.x - par_pos.x;
5525 currentSize.x = wxMax(currentSize.x, 150);
5526 currentSize.y = wxMax(currentSize.y, 150);
5531 if (itemBoxSizer->GetOrientation() == wxVERTICAL) {
5533 for (
unsigned int i = 0; i < m_ArrayOfInstrument.size(); i++) {
5535 m_ArrayOfInstrument.Item(i)->m_pInstrument;
5537 inst->GetSize(itemBoxSizer->GetOrientation(), currentSize);
5541 currentSize.y = total_y;
5544 pane.FloatingSize(currentSize);
5547 for (
unsigned int i = 0; i < m_ArrayOfInstrument.size(); i++) {
5552 m_pauimgr->Update();
5555 m_binResize =
false;
5560 case GestureCanceled:
5562 m_binResize =
false;
5570void DashboardWindow::OnEvtPanGesture(wxQT_PanGestureEvent &event) {
5571 if (m_binPinch)
return;
5573 if (m_binResize)
return;
5575 int x =
event.GetOffset().x;
5576 int y =
event.GetOffset().y;
5578 int lx =
event.GetLastOffset().x;
5579 int ly =
event.GetLastOffset().y;
5584 switch (event.GetState()) {
5585 case GestureStarted:
5586 if (m_binPan)
break;
5591 case GestureUpdated:
5594 wxPoint par_pos_old = ClientToScreen(wxPoint(0, 0));
5596 wxPoint par_pos = par_pos_old;
5600 par_pos.x = wxMax(par_pos.x, 0);
5601 par_pos.y = wxMax(par_pos.y, 0);
5603 wxSize mySize = GetSize();
5605 if ((par_pos.y + mySize.y) > par_size.y)
5606 par_pos.y = par_size.y - mySize.y;
5608 if ((par_pos.x + mySize.x) > par_size.x)
5609 par_pos.x = par_size.x - mySize.x;
5611 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5612 pane.FloatingPosition(par_pos).Float();
5613 m_pauimgr->Update();
5617 case GestureFinished:
5624 case GestureCanceled:
5633void DashboardWindow::OnMouseEvent(wxMouseEvent &event) {
5634 if (m_binPinch)
return;
5637 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5638 wxSize currentSize = wxSize(pane.floating_size.x, pane.floating_size.y);
5639 double aRatio = (double)currentSize.y / (
double)currentSize.x;
5642 wxPoint par_pos = wxPoint(pane.floating_pos.x, pane.floating_pos.y);
5644 if (event.LeftDown()) {
5645 m_resizeStartPoint =
event.GetPosition();
5646 m_resizeStartSize = currentSize;
5647 m_binResize2 =
true;
5651 if (event.Dragging()) {
5652 wxPoint p =
event.GetPosition();
5654 wxSize dragSize = m_resizeStartSize;
5656 dragSize.y += p.y - m_resizeStartPoint.y;
5657 dragSize.x += p.x - m_resizeStartPoint.x;
5660 if ((par_pos.y + dragSize.y) > par_size.y)
5661 dragSize.y = par_size.y - par_pos.y;
5663 if ((par_pos.x + dragSize.x) > par_size.x)
5664 dragSize.x = par_size.x - par_pos.x;
5670 dragSize.x = wxMax(dragSize.x, 150);
5671 dragSize.y = wxMax(dragSize.y, 150);
5673 pane.FloatingSize(dragSize);
5674 m_pauimgr->Update();
5677 if (event.LeftUp()) {
5678 wxPoint p =
event.GetPosition();
5680 wxSize dragSize = m_resizeStartSize;
5682 dragSize.y += p.y - m_resizeStartPoint.y;
5683 dragSize.x += p.x - m_resizeStartPoint.x;
5686 if ((par_pos.y + dragSize.y) > par_size.y)
5687 dragSize.y = par_size.y - par_pos.y;
5689 if ((par_pos.x + dragSize.x) > par_size.x)
5690 dragSize.x = par_size.x - par_pos.x;
5693 dragSize.x = wxMax(dragSize.x, 150);
5694 dragSize.y = wxMax(dragSize.y, 150);
5701 pane.FloatingSize(dragSize);
5702 m_pauimgr->Update();
5704 m_binResize =
false;
5705 m_binResize2 =
false;
5712void DashboardWindow::OnSize(wxSizeEvent &event) {
5714 for (
unsigned int i = 0; i < m_ArrayOfInstrument.size(); i++) {
5717 inst->GetSize(itemBoxSizer->GetOrientation(), GetClientSize()));
5722 this->m_Container->m_best_size =
event.GetSize();
5725void DashboardWindow::OnContextMenu(wxContextMenuEvent &event) {
5726 wxMenu *contextMenu =
new wxMenu();
5733 new wxMenuItem(contextMenu, ID_DASH_PREFS, _(
"Preferences..."));
5734 item1->SetFont(*pf);
5735 contextMenu->Append(item1);
5738 new wxMenuItem(contextMenu, ID_DASH_RESIZE, _(
"Resize..."));
5739 item2->SetFont(*pf);
5740 contextMenu->Append(item2);
5744 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5745 if (pane.IsOk() && pane.IsDocked()) {
5746 contextMenu->Append(ID_DASH_UNDOCK, _(
"Undock"));
5748 wxMenuItem *btnVertical =
5749 contextMenu->AppendRadioItem(ID_DASH_VERTICAL, _(
"Vertical"));
5750 btnVertical->Check(itemBoxSizer->GetOrientation() == wxVERTICAL);
5751 wxMenuItem *btnHorizontal =
5752 contextMenu->AppendRadioItem(ID_DASH_HORIZONTAL, _(
"Horizontal"));
5753 btnHorizontal->Check(itemBoxSizer->GetOrientation() == wxHORIZONTAL);
5754 contextMenu->AppendSeparator();
5756 m_plugin->PopulateContextMenu(contextMenu);
5758 contextMenu->AppendSeparator();
5759 contextMenu->Append(ID_DASH_PREFS, _(
"Preferences..."));
5763 PopupMenu(contextMenu);
5767void DashboardWindow::OnContextMenuSelect(wxCommandEvent &event) {
5768 if (event.GetId() < ID_DASH_PREFS) {
5769 if (m_plugin->GetDashboardWindowShownCount() > 1 || event.IsChecked())
5770 m_plugin->ShowDashboard(event.GetId() - 1, event.IsChecked());
5772 m_plugin->ShowDashboard(event.GetId() - 1,
true);
5775 m_plugin->GetDashboardWindowShownCount() != 0);
5778 switch (event.GetId()) {
5779 case ID_DASH_PREFS: {
5781 wxPoint fp = m_pauimgr->GetPane(
this).floating_pos;
5785 ChangePaneOrientation(GetSizerOrientation(),
true, fp.x, fp.y);
5786 if (g_bUseInternSumLog) m_plugin->UpdateSumLog(
false);
5789 case ID_DASH_RESIZE: {
5800 case ID_DASH_VERTICAL: {
5801 ChangePaneOrientation(wxVERTICAL,
true);
5802 m_Container->m_sOrientation = _T(
"V");
5805 case ID_DASH_HORIZONTAL: {
5806 ChangePaneOrientation(wxHORIZONTAL,
true);
5807 m_Container->m_sOrientation = _T(
"H");
5810 case ID_DASH_UNDOCK: {
5811 ChangePaneOrientation(GetSizerOrientation(),
true);
5815 m_plugin->SaveConfig();
5822 wxColour col = g_BackgroundColor;
5824 if (!g_ForceBackgroundColor) GetGlobalColor(_T(
"DASHL"), &col);
5825 SetBackgroundColour(col);
5830void DashboardWindow::ChangePaneOrientation(
int orient,
bool updateAUImgr,
5832 m_pauimgr->DetachPane(
this);
5833 SetSizerOrientation(orient);
5834 bool vertical = orient == wxVERTICAL;
5836 wxSize sz = GetMinSize();
5838 m_Container->m_sName = MakeName();
5839 m_pauimgr->AddPane(
this, wxAuiPaneInfo()
5840 .Name(m_Container->m_sName)
5841 .Caption(m_Container->m_sCaption)
5842 .CaptionVisible(
true)
5843 .TopDockable(!vertical)
5844 .BottomDockable(!vertical)
5845 .LeftDockable(vertical)
5846 .RightDockable(vertical)
5850 .FloatingPosition(fpx, fpy)
5852 .Show(m_Container->m_bIsVisible));
5854#ifdef __OCPN__ANDROID__
5855 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5856 pane.Dockable(
false);
5859 if (updateAUImgr) m_pauimgr->Update();
5862void DashboardWindow::SetSizerOrientation(
int orient) {
5863 itemBoxSizer->SetOrientation(orient);
5865 wxWindowListNode *node = GetChildren().GetFirst();
5867 node->GetData()->SetMinSize(wxDefaultSize);
5868 node = node->GetNext();
5870 SetMinSize(wxDefaultSize);
5872 SetMinSize(itemBoxSizer->GetMinSize());
5875int DashboardWindow::GetSizerOrientation() {
5876 return itemBoxSizer->GetOrientation();
5879bool isArrayIntEqual(
const wxArrayInt &l1,
const wxArrayOfInstrument &l2) {
5880 if (l1.GetCount() != l2.GetCount())
return false;
5882 for (
size_t i = 0; i < l1.GetCount(); i++)
5883 if (l1.Item(i) != l2.Item(i)->m_ID)
return false;
5888bool DashboardWindow::isInstrumentListEqual(
const wxArrayInt &list) {
5889 return isArrayIntEqual(list, m_ArrayOfInstrument);
5892void DashboardWindow::SetInstrumentList(
5893 wxArrayInt list, wxArrayOfInstrumentProperties *InstrumentPropertyList) {
5907 m_ArrayOfInstrument.Clear();
5908 itemBoxSizer->Clear(
true);
5909 for (
size_t i = 0; i < list.GetCount(); i++) {
5910 int id = list.Item(i);
5912 for (
size_t j = 0; j < InstrumentPropertyList->GetCount(); j++) {
5913 if (InstrumentPropertyList->Item(j)->m_aInstrument ==
id &&
5914 InstrumentPropertyList->Item(j)->m_Listplace == (
int)i) {
5915 Properties = InstrumentPropertyList->Item(j);
5923 this, wxID_ANY, getInstrumentCaption(
id), Properties);
5927 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5928 OCPN_DBP_STC_SOG, _T(
"%5.1f"));
5932 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5933 OCPN_DBP_STC_SOG, 0, g_iDashSpeedMax);
5935 ->SetOptionLabel(g_iDashSpeedMax / 20 + 1, DIAL_LABEL_HORIZONTAL);
5939 ->SetOptionMarker(0.5, DIAL_MARKER_SIMPLE, 2);
5941 ->SetOptionExtraValue(OCPN_DBP_STC_STW,
"STW %.1f",
5942 DIAL_POSITION_BOTTOMMIDDLE);
5946 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5947 OCPN_DBP_STC_STW, 0, g_iDashSpeedMax);
5949 ->SetOptionLabel(g_iDashSpeedMax / 20 + 1, DIAL_LABEL_HORIZONTAL);
5953 ->SetOptionMarker(0.5, DIAL_MARKER_SIMPLE, 2);
5955 ->SetOptionExtraValue(OCPN_DBP_STC_SOG,
"SOG %.1f",
5956 DIAL_POSITION_BOTTOMMIDDLE);
5960 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5961 OCPN_DBP_STC_COG, _T(
"%03.0f"));
5965 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5966 OCPN_DBP_STC_MCOG, _T(
"%03.0f"));
5970 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5973 ->SetOptionMarker(5, DIAL_MARKER_SIMPLE, 2);
5975 ->SetOptionLabel(30, DIAL_LABEL_ROTATED);
5977 ->SetOptionExtraValue(OCPN_DBP_STC_SOG, _T(
"SOG\n%.2f"),
5978 DIAL_POSITION_BOTTOMLEFT);
5982 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5985 ->SetOptionMarker(5, DIAL_MARKER_SIMPLE, 2);
5987 ->SetOptionLabel(30, DIAL_LABEL_ROTATED);
5989 ->SetOptionExtraValue(OCPN_DBP_STC_STW, _T(
"STW\n%.1f"),
5990 DIAL_POSITION_BOTTOMLEFT);
5994 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5995 OCPN_DBP_STC_STW, _T(
"%.1f"));
6000 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6001 OCPN_DBP_STC_HDT, _T(
"%03.0f"));
6005 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6006 OCPN_DBP_STC_HDM, _T(
"%03.0f"));
6011 getInstrumentCaption(
id),
6012 Properties, OCPN_DBP_STC_AWA);
6014 ->SetOptionMainValue(_T(
"%.0f"), DIAL_POSITION_BOTTOMLEFT);
6016 ->SetOptionExtraValue(OCPN_DBP_STC_AWS, _T(
"%.1f"),
6017 DIAL_POSITION_INSIDE);
6021 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6022 OCPN_DBP_STC_AWS, _T(
"%.1f"));
6026 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6027 OCPN_DBP_STC_AWS, 0, 45);
6029 ->SetOptionLabel(5, DIAL_LABEL_HORIZONTAL);
6031 ->SetOptionMarker(1, DIAL_MARKER_SIMPLE, 5);
6033 ->SetOptionMainValue(_T(
"A %.1f"), DIAL_POSITION_BOTTOMLEFT);
6035 ->SetOptionExtraValue(OCPN_DBP_STC_TWS, _T(
"T %.1f"),
6036 DIAL_POSITION_BOTTOMRIGHT);
6040 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6043 ->SetOptionMainValue(_T(
"%.0f"), DIAL_POSITION_BOTTOMLEFT);
6045 ->SetOptionExtraValue(OCPN_DBP_STC_TWS, _T(
"%.1f"),
6046 DIAL_POSITION_INSIDE);
6048 case ID_DBP_D_AWA_TWA:
6050 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6054 ->SetOptionMainValue(_T(
"%.0f"), DIAL_POSITION_NONE);
6056 ->SetOptionExtraValue(OCPN_DBP_STC_TWS, _T(
"%.1f"),
6057 DIAL_POSITION_NONE);
6059 ->SetOptionExtraValue(OCPN_DBP_STC_AWS, _T(
"%.1f"),
6060 DIAL_POSITION_NONE);
6064 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6067 ->SetOptionMainValue(_T(
"%.0f"), DIAL_POSITION_BOTTOMLEFT);
6069 ->SetOptionExtraValue(OCPN_DBP_STC_TWS2, _T(
"%.1f"),
6070 DIAL_POSITION_INSIDE);
6074 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6075 OCPN_DBP_STC_ALTI, _T(
"%6.1f"));
6079 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6083 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6084 OCPN_DBP_STC_DPT, _T(
"%5.2f"));
6088 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6092 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6093 OCPN_DBP_STC_TMP, _T(
"%2.1f"));
6097 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6098 OCPN_DBP_STC_MDA, _T(
"%5.1f"));
6102 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6103 OCPN_DBP_STC_MDA, 938, 1088);
6105 ->SetOptionLabel(15, DIAL_LABEL_HORIZONTAL);
6107 ->SetOptionMarker(7.5, DIAL_MARKER_SIMPLE, 1);
6109 ->SetOptionMainValue(_T(
"%5.1f"), DIAL_POSITION_INSIDE);
6113 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6114 OCPN_DBP_STC_ATMP, _T(
"%2.1f"));
6118 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6119 OCPN_DBP_STC_VLW1, _T(
"%2.1f"));
6124 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6125 OCPN_DBP_STC_VLW2, _T(
"%2.1f"));
6130 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6131 OCPN_DBP_STC_TWA, _T(
"%5.0f"));
6135 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6136 OCPN_DBP_STC_TWD, _T(
"%3.0f"));
6140 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6141 OCPN_DBP_STC_TWS, _T(
"%2.1f"));
6145 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6146 OCPN_DBP_STC_AWA, _T(
"%3.0f"));
6150 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6151 OCPN_DBP_STC_VMGW, _T(
"%2.1f"));
6155 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6156 OCPN_DBP_STC_VMG, _T(
"%5.1f"));
6160 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6161 OCPN_DBP_STC_VMG, 0, g_iDashSpeedMax);
6163 ->SetOptionLabel(1, DIAL_LABEL_HORIZONTAL);
6165 ->SetOptionMarker(0.5, DIAL_MARKER_SIMPLE, 2);
6167 ->SetOptionExtraValue(OCPN_DBP_STC_SOG, _T(
"SOG\n%.1f"),
6168 DIAL_POSITION_BOTTOMLEFT);
6172 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6173 OCPN_DBP_STC_RSA, _T(
"%5.0f"));
6177 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6181 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6182 OCPN_DBP_STC_SAT, _T(
"%5.0f"));
6186 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6190 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6191 OCPN_DBP_STC_PLA, OCPN_DBP_STC_PLO);
6193 case ID_DBP_I_GPSUTC:
6195 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6199 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6203 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6207 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6211 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6215 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6217 case ID_DBP_I_PITCH:
6219 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6220 OCPN_DBP_STC_PITCH, _T(
"%2.1f"));
6224 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6225 OCPN_DBP_STC_HEEL, _T(
"%2.1f"));
6229 case ID_DBP_I_SUNLCL:
6231 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6232 _T(
"%02i:%02i:%02i LCL" ));
6234 case ID_DBP_I_GPSLCL:
6236 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6237 OCPN_DBP_STC_CLK, _T(
"%02i:%02i:%02i LCL" ));
6239 case ID_DBP_I_CPULCL:
6241 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6242 _T(
"%02i:%02i:%02i LCL" ));
6246 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6247 OCPN_DBP_STC_HUM,
"%3.0f");
6251 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6252 OCPN_DBP_STC_WCC, _T(
"%5.1f"));
6256 instrument->instrumentTypeId = id;
6258 id, instrument, instrument->GetCapacity()));
6259 itemBoxSizer->Add(instrument, 0, wxEXPAND, 0);
6260 if (itemBoxSizer->GetOrientation() == wxHORIZONTAL) {
6261 itemBoxSizer->AddSpacer(5);
6272 wxSize Hint = wxSize(DefaultWidth, DefaultWidth);
6274 for (
unsigned int i = 0; i < m_ArrayOfInstrument.size(); i++) {
6276 inst->SetMinSize(inst->GetSize(itemBoxSizer->GetOrientation(), Hint));
6277 Hint = inst->GetMinSize();
6282 SetMinSize(itemBoxSizer->GetMinSize());
6285void DashboardWindow::SendSentenceToAllInstruments(DASH_CAP st,
double value,
6287 for (
size_t i = 0; i < m_ArrayOfInstrument.GetCount(); i++) {
6288 if (m_ArrayOfInstrument.Item(i)->m_cap_flag.test(st))
6289 m_ArrayOfInstrument.Item(i)->m_pInstrument->SetData(st, value,
unit);
6293void DashboardWindow::SendSatInfoToAllInstruments(
int cnt,
int seq,
6296 for (
size_t i = 0; i < m_ArrayOfInstrument.GetCount(); i++) {
6297 if ((m_ArrayOfInstrument.Item(i)->m_cap_flag.test(OCPN_DBP_STC_GPS)) &&
6299 m_ArrayOfInstrument.Item(i)->m_pInstrument))
6301 ->SetSatInfo(cnt, seq, talk, sats);
6305void DashboardWindow::SendUtcTimeToAllInstruments(wxDateTime value) {
6306 for (
size_t i = 0; i < m_ArrayOfInstrument.GetCount(); i++) {
6307 if ((m_ArrayOfInstrument.Item(i)->m_cap_flag.test(OCPN_DBP_STC_CLK)) &&
6309 m_ArrayOfInstrument.Item(i)->m_pInstrument))
6317 ->SetUtcTime(value);
6333bool OCPNFontButton::Create(wxWindow *parent, wxWindowID
id,
6334 const wxFontData &initial,
const wxPoint &pos,
6335 const wxSize &size,
long style,
6336 const wxValidator &validator,
6337 const wxString &name) {
6338 wxString label = (style & wxFNTP_FONTDESC_AS_LABEL)
6344 if (!wxButton::Create(parent,
id, label, pos, size, style, validator, name)) {
6345 wxFAIL_MSG(wxT(
"OCPNFontButton creation failed"));
6350 Connect(GetId(), wxEVT_BUTTON,
6351 wxCommandEventHandler(OCPNFontButton::OnButtonClick), NULL,
this);
6355 initial.GetChosenFont().IsOk() ? initial.GetChosenFont() : *wxNORMAL_FONT;
6361void OCPNFontButton::OnButtonClick(wxCommandEvent &WXUNUSED(ev)) {
6363 m_data.SetInitialFont(m_selectedFont);
6368 int display_height = wxGetDisplaySize().y;
6369 if (display_height < 800) {
6373 if (dlg.ShowModal() == wxID_OK) {
6374 m_data = dlg.GetFontData();
6375 m_selectedFont = m_data.GetChosenFont();
6377 wxFontPickerEvent event(
this, GetId(), m_selectedFont);
6378 GetEventHandler()->ProcessEvent(event);
6383 wxFontDialog dlg(
this, m_data);
6385 if (dlg.ShowModal() == wxID_OK) {
6386 m_data = dlg.GetFontData();
6387 m_selectedFont = m_data.GetChosenFont();
6389 wxFontPickerEvent event(
this, GetId(), m_selectedFont);
6390 GetEventHandler()->ProcessEvent(event);
6397 wxFontDialog dlg(
this, m_data);
6403 wxSize proposed_size = GetParent()->GetSize();
6405 float font_size = pF->GetPointSize();
6407 if ((proposed_size.y / font_size) < n_lines) {
6408 float new_font_size = proposed_size.y / n_lines;
6409 wxFont *smallFont =
new wxFont(*pF);
6410 smallFont->SetPointSize(new_font_size);
6411 dlg.SetFont(*smallFont);
6414 dlg.SetSize(GetParent()->GetSize());
6418 if (dlg.ShowModal() == wxID_OK) {
6419 m_data = dlg.GetFontData();
6420 m_selectedFont = m_data.GetChosenFont();
6423 wxFontPickerEvent event(
this, GetId(), m_selectedFont);
6424 GetEventHandler()->ProcessEvent(event);
6431void OCPNFontButton::UpdateFont() {
6432 if (!m_selectedFont.IsOk())
return;
6437 if (HasFlag(wxFNTP_USEFONT_FOR_LABEL)) {
6439 wxButton::SetFont(m_selectedFont);
6440 wxButton::SetForegroundColour(GetSelectedColour());
6444 wxString::Format(wxT(
"%s, %d"), m_selectedFont.GetFaceName().c_str(),
6445 m_selectedFont.GetPointSize());
6447 if (HasFlag(wxFNTP_FONTDESC_AS_LABEL)) {
6451 auto minsize = GetTextExtent(label);
6454 GetParent()->Layout();
6461 wxWindowID
id,
const wxString &title,
const wxPoint &pos,
6462 const wxSize &size,
long style)
6463 : wxDialog(parent, id, title, pos, size, style) {
6464 this->SetSizeHints(wxDefaultSize, wxDefaultSize);
6466 wxBoxSizer *bSizer5;
6467 bSizer5 =
new wxBoxSizer(wxVERTICAL);
6469 wxFlexGridSizer *fgSizer2;
6470 fgSizer2 =
new wxFlexGridSizer(0, 2, 0, 0);
6471 fgSizer2->SetFlexibleDirection(wxBOTH);
6472 fgSizer2->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
6474 m_staticText1 =
new wxStaticText(
this, wxID_ANY, _(
"Title:"),
6475 wxDefaultPosition, wxDefaultSize, 0);
6476 m_staticText1->Wrap(-1);
6477 fgSizer2->Add(m_staticText1, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6479 m_fontPicker2 =
new wxFontPickerCtrl(
this, wxID_ANY, Properties.m_USTitleFont,
6480 wxDefaultPosition, wxDefaultSize);
6481 fgSizer2->Add(m_fontPicker2, 0, wxALL, 5);
6483 m_staticText5 =
new wxStaticText(
this, wxID_ANY, _(
"Title background color:"),
6484 wxDefaultPosition, wxDefaultSize, 0);
6485 m_staticText5->Wrap(-1);
6486 fgSizer2->Add(m_staticText5, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6488 m_colourPicker1 =
new wxColourPickerCtrl(
6489 this, wxID_ANY, Properties.m_TitleBackgroundColour, wxDefaultPosition,
6490 wxDefaultSize, wxCLRP_DEFAULT_STYLE);
6491 fgSizer2->Add(m_colourPicker1, 0, wxALL, 5);
6493 m_staticText2 =
new wxStaticText(
this, wxID_ANY, _(
"Data:"),
6494 wxDefaultPosition, wxDefaultSize, 0);
6495 m_staticText2->Wrap(-1);
6496 fgSizer2->Add(m_staticText2, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6498 m_fontPicker4 =
new wxFontPickerCtrl(
this, wxID_ANY, Properties.m_USDataFont,
6499 wxDefaultPosition, wxDefaultSize);
6500 fgSizer2->Add(m_fontPicker4, 0, wxALL, 5);
6502 m_staticText6 =
new wxStaticText(
this, wxID_ANY, _(
"Data background color:"),
6503 wxDefaultPosition, wxDefaultSize, 0);
6504 m_staticText6->Wrap(-1);
6505 fgSizer2->Add(m_staticText6, 0, wxALL, 5);
6507 m_colourPicker2 =
new wxColourPickerCtrl(
6508 this, wxID_ANY, Properties.m_DataBackgroundColour, wxDefaultPosition,
6509 wxDefaultSize, wxCLRP_DEFAULT_STYLE);
6510 fgSizer2->Add(m_colourPicker2, 0, wxALL, 5);
6512 m_staticText3 =
new wxStaticText(
this, wxID_ANY, _(
"Label:"),
6513 wxDefaultPosition, wxDefaultSize, 0);
6514 m_staticText3->Wrap(-1);
6515 fgSizer2->Add(m_staticText3, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6517 m_fontPicker5 =
new wxFontPickerCtrl(
this, wxID_ANY, Properties.m_USLabelFont,
6518 wxDefaultPosition, wxDefaultSize);
6519 fgSizer2->Add(m_fontPicker5, 0, wxALL, 5);
6521 m_staticText4 =
new wxStaticText(
this, wxID_ANY, _(
"Small:"),
6522 wxDefaultPosition, wxDefaultSize, 0);
6523 m_staticText4->Wrap(-1);
6524 fgSizer2->Add(m_staticText4, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6526 m_fontPicker6 =
new wxFontPickerCtrl(
this, wxID_ANY, Properties.m_USSmallFont,
6527 wxDefaultPosition, wxDefaultSize);
6528 fgSizer2->Add(m_fontPicker6, 0, wxALL, 5);
6530 m_staticText9 =
new wxStaticText(
this, wxID_ANY, _(
"Arrow 1 Color :"),
6531 wxDefaultPosition, wxDefaultSize, 0);
6532 m_staticText9->Wrap(-1);
6533 fgSizer2->Add(m_staticText9, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6535 m_colourPicker3 =
new wxColourPickerCtrl(
6536 this, wxID_ANY, Properties.m_Arrow_First_Colour, wxDefaultPosition,
6537 wxDefaultSize, wxCLRP_DEFAULT_STYLE);
6538 fgSizer2->Add(m_colourPicker3, 0, wxALL, 5);
6540 m_staticText10 =
new wxStaticText(
this, wxID_ANY, _(
"Arrow 2 Color :"),
6541 wxDefaultPosition, wxDefaultSize, 0);
6542 m_staticText10->Wrap(-1);
6543 fgSizer2->Add(m_staticText10, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6545 m_colourPicker4 =
new wxColourPickerCtrl(
6546 this, wxID_ANY, Properties.m_Arrow_Second_Colour, wxDefaultPosition,
6547 wxDefaultSize, wxCLRP_DEFAULT_STYLE);
6548 fgSizer2->Add(m_colourPicker4, 0, wxALL, 5);
6550 m_staticline1 =
new wxStaticLine(
this, wxID_ANY, wxDefaultPosition,
6551 wxDefaultSize, wxLI_HORIZONTAL);
6552 fgSizer2->Add(m_staticline1, 0, wxEXPAND | wxALL, 5);
6554 m_staticline2 =
new wxStaticLine(
this, wxID_ANY, wxDefaultPosition,
6555 wxDefaultSize, wxLI_HORIZONTAL);
6556 fgSizer2->Add(m_staticline2, 0, wxEXPAND | wxALL, 5);
6558 fgSizer2->Add(0, 5, 1, wxEXPAND, 5);
6560 fgSizer2->Add(0, 0, 1, wxEXPAND, 5);
6562 m_staticText7 =
new wxStaticText(
this, wxID_ANY, wxEmptyString,
6563 wxDefaultPosition, wxDefaultSize, 0);
6564 m_staticText7->Wrap(-1);
6565 fgSizer2->Add(m_staticText7, 0, wxALL, 5);
6567 m_button1 =
new wxButton(
this, wxID_ANY, _(
"Set default"), wxDefaultPosition,
6569 fgSizer2->Add(m_button1, 0, wxALL, 5);
6571 fgSizer2->Add(0, 5, 1, wxEXPAND, 5);
6573 fgSizer2->Add(5, 0, 1, wxEXPAND, 5);
6575 bSizer5->Add(fgSizer2, 1, wxALL | wxEXPAND, 5);
6577 m_sdbSizer3 =
new wxStdDialogButtonSizer();
6578 m_sdbSizer3OK =
new wxButton(
this, wxID_OK);
6579 m_sdbSizer3->AddButton(m_sdbSizer3OK);
6580 m_sdbSizer3Cancel =
new wxButton(
this, wxID_CANCEL);
6581 m_sdbSizer3->AddButton(m_sdbSizer3Cancel);
6582 m_sdbSizer3->Realize();
6584 bSizer5->Add(m_sdbSizer3, 0, 0, 1);
6586 bSizer5->Add(0, 10, 0, wxEXPAND, 5);
6588 this->SetSizer(bSizer5);
6592 this->Centre(wxBOTH);
6595 m_button1->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
6596 wxCommandEventHandler(EditDialog::OnSetdefault), NULL,
6600EditDialog::~EditDialog() {
6602 m_button1->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED,
6603 wxCommandEventHandler(EditDialog::OnSetdefault), NULL,
6607void EditDialog::OnSetdefault(wxCommandEvent &event) {
6608 m_fontPicker2->SetSelectedFont(g_USFontTitle.GetChosenFont());
6609 m_fontPicker2->SetSelectedColour(g_USFontTitle.GetColour());
6610 m_fontPicker4->SetSelectedFont(g_USFontData.GetChosenFont());
6611 m_fontPicker4->SetSelectedColour(g_USFontData.GetColour());
6612 m_fontPicker5->SetSelectedFont(g_USFontLabel.GetChosenFont());
6613 m_fontPicker5->SetSelectedColour(g_USFontLabel.GetColour());
6614 m_fontPicker6->SetSelectedFont(g_USFontSmall.GetChosenFont());
6615 m_fontPicker6->SetSelectedColour(g_USFontSmall.GetColour());
6617 GetGlobalColor(_T(
"DASHL"), &dummy);
6618 m_colourPicker1->SetColour(dummy);
6619 GetGlobalColor(_T(
"DASHB"), &dummy);
6620 m_colourPicker2->SetColour(dummy);
6621 GetGlobalColor(_T(
"DASHN"), &dummy);
6622 m_colourPicker3->SetColour(dummy);
6623 GetGlobalColor(_T(
"BLUE3"), &dummy);
6624 m_colourPicker4->SetColour(dummy);
6630void dashboard_pi::UpdateSumLog(
bool write) {
6632 g_dSumLogNM += d_tripNM;
6635 if (++confprint > 10) {
6636 wxFileConfig *logConf = (wxFileConfig *)m_pconfig;
6638 logConf->SetPath(
"/PlugIns/Dashboard");
6639 logConf->Write(
"SumLogNM", g_dSumLogNM);
6645 if (g_bUseInternSumLog) {
6646 SendSentenceToAllInstruments(
6655 SendSentenceToAllInstruments(
6659 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
Enumeration of color schemes.
#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.
wxString * GetpSharedDataLocation(void)
Gets shared application data location.
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.
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.
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.
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.
wxAuiManager * GetFrameAuiManager(void)
Gets main frame AUI manager.
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.
wxFileConfig * GetOCPNConfigObject(void)
Gets OpenCPN's configuration object.
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.