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(
"%08x-%04x-%04x-%02x%02x-%04x%08x", uuid.time_low, uuid.time_mid,
480 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 "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() +
"dashboard_pi" +
605 wxFileName::GetPathSeparator() +
"data" +
606 wxFileName::GetPathSeparator();
608 wxString normalIcon = shareLocn +
"Dashboard.svg";
609 wxString toggledIcon = shareLocn +
"Dashboard_toggled.svg";
610 wxString rolloverIcon = shareLocn +
"Dashboard_rollover.svg";
621 "", normalIcon, rolloverIcon, toggledIcon, wxITEM_CHECK, _(
"Dashboard"),
622 "", 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,
"\u00B0");
780 mHDx_Watchdog = gps_watchdog_timeout_ticks;
784 if (mHDT_Watchdog <= 0) {
786 SendSentenceToAllInstruments(OCPN_DBP_STC_HDT, NAN,
"\u00B0T");
787 mHDT_Watchdog = gps_watchdog_timeout_ticks;
791 if (mVar_Watchdog <= 0) {
794 SendSentenceToAllInstruments(OCPN_DBP_STC_HMV, NAN,
"\u00B0T");
795 mVar_Watchdog = gps_watchdog_timeout_ticks;
799 if (mSatsUsed_Wdog <= 0) {
802 SendSentenceToAllInstruments(OCPN_DBP_STC_SAT, NAN,
"");
803 mSatsUsed_Wdog = gps_watchdog_timeout_ticks;
806 if (m_PriN2kTalker < -1e6) m_PriN2kTalker = 0;
809 if (mSatStatus_Wdog <= 0) {
811 for (
int i = 0; i < 4; i++) {
812 sats[i].SatNumber = 0;
813 sats[i].SignalToNoiseRatio = 0;
815 SendSatInfoToAllInstruments(0, 1, wxEmptyString, sats);
816 SendSatInfoToAllInstruments(0, 2, wxEmptyString, sats);
817 SendSatInfoToAllInstruments(0, 3, wxEmptyString, sats);
819 mSatStatus_Wdog = gps_watchdog_timeout_ticks;
826 std::string satID = PriorityIDs[4].substr(0, PriorityIDs[4].find(
':'));
827 if (satID.find(
"nmea0183") != std::string::npos)
829 else if (satID.find(
"ignal") != std::string::npos)
831 else if (satID.find(
"N2k") != std::string::npos) {
832 prioN2kPGNsat = PriorityIDs[4];
837 if (mMWVA_Watchdog <= 0) {
838 SendSentenceToAllInstruments(OCPN_DBP_STC_AWA, NAN,
"-");
839 SendSentenceToAllInstruments(OCPN_DBP_STC_AWS, NAN,
"-");
841 mMWVA_Watchdog = gps_watchdog_timeout_ticks;
845 if (mMWVT_Watchdog <= 0) {
846 SendSentenceToAllInstruments(OCPN_DBP_STC_TWA, NAN,
"-");
847 SendSentenceToAllInstruments(OCPN_DBP_STC_TWS, NAN,
"-");
848 SendSentenceToAllInstruments(OCPN_DBP_STC_TWS2, NAN,
"-");
850 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
854 if (mDPT_DBT_Watchdog <= 0) {
856 SendSentenceToAllInstruments(OCPN_DBP_STC_DPT, NAN,
"-");
857 mDPT_DBT_Watchdog = gps_watchdog_timeout_ticks;
861 if (mSTW_Watchdog <= 0) {
863 SendSentenceToAllInstruments(OCPN_DBP_STC_STW, NAN,
"-");
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,
"-");
904 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
907 if (mMDA_Watchdog <= 0) {
908 SendSentenceToAllInstruments(OCPN_DBP_STC_MDA, NAN,
"-");
910 mMDA_Watchdog = gps_watchdog_timeout_ticks;
913 if (mPITCH_Watchdog <= 0) {
915 SendSentenceToAllInstruments(OCPN_DBP_STC_PITCH, NAN,
"-");
916 mPITCH_Watchdog = gps_watchdog_timeout_ticks;
919 if (mHEEL_Watchdog <= 0) {
921 SendSentenceToAllInstruments(OCPN_DBP_STC_HEEL, NAN,
"-");
922 mHEEL_Watchdog = gps_watchdog_timeout_ticks;
925 if (mALT_Watchdog <= 0) {
927 SendSentenceToAllInstruments(OCPN_DBP_STC_ALTI, NAN,
"-");
928 mALT_Watchdog = gps_watchdog_timeout_ticks;
932 if (mLOG_Watchdog <= 0) {
933 if (g_bUseInternSumLog) {
936 SendSentenceToAllInstruments(OCPN_DBP_STC_VLW2, NAN,
"-");
937 mLOG_Watchdog = no_nav_watchdog_timeout_ticks;
941 if (mTrLOG_Watchdog <= 0) {
942 SendSentenceToAllInstruments(OCPN_DBP_STC_VLW1, NAN,
"-");
943 mTrLOG_Watchdog = no_nav_watchdog_timeout_ticks;
946 if (mHUM_Watchdog <= 0) {
948 SendSentenceToAllInstruments(OCPN_DBP_STC_HUM, NAN,
"-");
949 mHUM_Watchdog = no_nav_watchdog_timeout_ticks;
952 if (mWCC_Watchdog <= 0) {
953 SendSentenceToAllInstruments(OCPN_DBP_STC_WCC, NAN,
"-");
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 ==
"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 ==
"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 ==
"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,
"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,
"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,
"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 ==
"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,
"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,
"SDMM");
1169 else if (m_NMEA0183.LastSentenceIDReceived ==
"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 ==
"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,
"\u00B0");
1213 if (mPriHeadingM >= 3) {
1214 if (!std::isnan(m_NMEA0183.Hdg.MagneticSensorHeadingDegrees)) {
1216 mHdm = m_NMEA0183.Hdg.MagneticSensorHeadingDegrees;
1217 SendSentenceToAllInstruments(OCPN_DBP_STC_HDM, mHdm,
"\u00B0");
1220 if (!std::isnan(m_NMEA0183.Hdg.MagneticSensorHeadingDegrees))
1221 mHDx_Watchdog = gps_watchdog_timeout_ticks;
1225 if (!std::isnan(m_NMEA0183.Hdg.MagneticSensorHeadingDegrees)) {
1226 if (!std::isnan(mVar) && (mPriHeadingT >= 7)) {
1228 double heading = mHdm + mVar;
1231 else if (heading >= 360.0)
1233 SendSentenceToAllInstruments(OCPN_DBP_STC_HDT, heading,
"\u00B0");
1234 mHDT_Watchdog = gps_watchdog_timeout_ticks;
1241 else if (m_NMEA0183.LastSentenceIDReceived ==
"HDM") {
1242 if (mPriHeadingM >= 4 || mPriHeadingT >= 5) {
1243 if (m_NMEA0183.Parse()) {
1244 if (mPriHeadingM >= 4) {
1245 if (!std::isnan(m_NMEA0183.Hdm.DegreesMagnetic)) {
1247 mHdm = m_NMEA0183.Hdm.DegreesMagnetic;
1248 SendSentenceToAllInstruments(OCPN_DBP_STC_HDM, mHdm,
"\u00B0M");
1249 mHDx_Watchdog = gps_watchdog_timeout_ticks;
1255 if (!std::isnan(m_NMEA0183.Hdm.DegreesMagnetic)) {
1256 if (!std::isnan(mVar) && (mPriHeadingT >= 5)) {
1258 double heading = mHdm + mVar;
1261 else if (heading >= 360.0)
1263 SendSentenceToAllInstruments(OCPN_DBP_STC_HDT, heading,
"\u00B0");
1264 mHDT_Watchdog = gps_watchdog_timeout_ticks;
1271 else if (m_NMEA0183.LastSentenceIDReceived ==
"HDT") {
1272 if (mPriHeadingT >= 3) {
1273 if (m_NMEA0183.Parse()) {
1274 if (!std::isnan(m_NMEA0183.Hdt.DegreesTrue)) {
1275 SendSentenceToAllInstruments(OCPN_DBP_STC_HDT,
1276 m_NMEA0183.Hdt.DegreesTrue,
"\u00B0T");
1278 mHDT_Watchdog = gps_watchdog_timeout_ticks;
1282 }
else if (m_NMEA0183.LastSentenceIDReceived ==
"MTA") {
1283 if (mPriATMP >= 3) {
1284 if (m_NMEA0183.Parse()) {
1286 SendSentenceToAllInstruments(
1290 mATMP_Watchdog = gps_watchdog_timeout_ticks;
1293 }
else if (m_NMEA0183.LastSentenceIDReceived ==
"MDA" &&
1294 (mPriMDA >= 5 || mPriATMP >= 5 || mPriHUM >= 4)) {
1296 if (m_NMEA0183.Parse()) {
1302 if (mPriMDA >= 5 && m_NMEA0183.Mda.Pressure > .8 &&
1303 m_NMEA0183.Mda.Pressure < 1.1) {
1304 SendSentenceToAllInstruments(OCPN_DBP_STC_MDA,
1305 m_NMEA0183.Mda.Pressure * 1000,
"hPa");
1307 mMDA_Watchdog = no_nav_watchdog_timeout_ticks;
1309 if (mPriATMP >= 5) {
1310 double airtemp = m_NMEA0183.Mda.AirTemp;
1311 if (!std::isnan(airtemp) && airtemp < 999.0) {
1312 SendSentenceToAllInstruments(
1315 mATMP_Watchdog = no_nav_watchdog_timeout_ticks;
1320 double humidity = m_NMEA0183.Mda.Humidity;
1321 if (!std::isnan(humidity)) {
1322 SendSentenceToAllInstruments(OCPN_DBP_STC_HUM, humidity,
"%");
1323 mHUM_Watchdog = no_nav_watchdog_timeout_ticks;
1329 }
else if (m_NMEA0183.LastSentenceIDReceived ==
"MTW") {
1331 if (m_NMEA0183.Parse()) {
1333 SendSentenceToAllInstruments(
1337 mWTP_Watchdog = no_nav_watchdog_timeout_ticks;
1341 }
else if (m_NMEA0183.LastSentenceIDReceived ==
"VLW") {
1342 if (m_NMEA0183.Parse()) {
1347 SendSentenceToAllInstruments(
1350 g_iDashDistanceUnit),
1352 mTrLOG_Watchdog = no_nav_watchdog_timeout_ticks;
1354 if (!g_bUseInternSumLog) {
1355 SendSentenceToAllInstruments(
1358 g_iDashDistanceUnit),
1360 mLOG_Watchdog = no_nav_watchdog_timeout_ticks;
1366 else if (m_NMEA0183.LastSentenceIDReceived ==
"MWD") {
1368 if (m_NMEA0183.Parse()) {
1371 if (!std::isnan(m_NMEA0183.Mwd.WindAngleTrue)) {
1373 SendSentenceToAllInstruments(
1374 OCPN_DBP_STC_TWD, m_NMEA0183.Mwd.WindAngleTrue,
"\u00B0");
1377 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
1378 }
else if (!std::isnan(m_NMEA0183.Mwd.WindAngleMagnetic)) {
1380 if (!std::isnan(mVar)) {
1381 double twd = m_NMEA0183.Mwd.WindAngleMagnetic;
1385 }
else if (twd < 0.) {
1388 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, twd,
"\u00B0");
1390 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
1393 SendSentenceToAllInstruments(
1396 g_iDashWindSpeedUnit),
1398 SendSentenceToAllInstruments(
1401 g_iDashWindSpeedUnit),
1403 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
1410 else if (m_NMEA0183.LastSentenceIDReceived ==
"MWV") {
1411 if (mPriAWA >= 4 || mPriTWA >= 5 || mPriWDN >= 5) {
1412 if (m_NMEA0183.Parse()) {
1413 if (m_NMEA0183.Mwv.IsDataValid == NTrue) {
1416 double m_wSpeedFactor = 1.0;
1417 if (m_NMEA0183.Mwv.WindSpeedUnits ==
"K")
1418 m_wSpeedFactor = 0.53995;
1419 if (m_NMEA0183.Mwv.WindSpeedUnits ==
"M")
1420 m_wSpeedFactor = 1.94384;
1422 if (m_NMEA0183.Mwv.Reference ==
"R")
1428 if (m_NMEA0183.Mwv.WindAngle > 180) {
1429 m_awaunit =
"\u00B0L";
1430 m_awaangle = 180.0 - (m_NMEA0183.Mwv.WindAngle - 180.0);
1432 m_awaunit =
"\u00B0R";
1433 m_awaangle = m_NMEA0183.Mwv.WindAngle;
1435 SendSentenceToAllInstruments(
1436 OCPN_DBP_STC_AWA, mAWAFilter.filter(m_awaangle), m_awaunit);
1437 SendSentenceToAllInstruments(
1440 mAWSFilter.filter(m_NMEA0183.Mwv.WindSpeed) *
1442 g_iDashWindSpeedUnit),
1444 mMWVA_Watchdog = gps_watchdog_timeout_ticks;
1452 CalculateAndUpdateTWDS(
1453 m_NMEA0183.Mwv.WindSpeed * m_wSpeedFactor,
1454 m_NMEA0183.Mwv.WindAngle);
1456 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
1457 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
1459 }
else if (m_NMEA0183.Mwv.Reference ==
1467 if (m_NMEA0183.Mwv.WindAngle > 180) {
1468 m_twaunit =
"\u00B0L";
1469 m_twaangle = 180.0 - (m_NMEA0183.Mwv.WindAngle - 180.0);
1471 m_twaunit =
"\u00B0R";
1472 m_twaangle = m_NMEA0183.Mwv.WindAngle;
1475 SendSentenceToAllInstruments(OCPN_DBP_STC_TWA, m_twaangle,
1483 if (g_dHDT < 361. && g_dHDT >= 0.0) {
1484 double g_dCalWdir = (m_NMEA0183.Mwv.WindAngle) + g_dHDT;
1485 if (g_dCalWdir > 360.) {
1487 }
else if (g_dCalWdir < 0.) {
1490 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, g_dCalWdir,
1493 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
1497 SendSentenceToAllInstruments(
1500 g_iDashWindSpeedUnit),
1502 SendSentenceToAllInstruments(
1505 g_iDashWindSpeedUnit),
1507 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
1515 else if (m_NMEA0183.LastSentenceIDReceived ==
"RMC") {
1516 if (mPriPosition >= 5 || mPriCOGSOG >= 3 || mPriVar >= 4 ||
1517 mPriDateTime >= 3) {
1518 if (m_NMEA0183.Parse()) {
1519 if (m_NMEA0183.Rmc.IsDataValid == NTrue) {
1520 if (mPriPosition >= 5) {
1523 float llt = m_NMEA0183.Rmc.Position.Latitude.Latitude;
1524 int lat_deg_int = (int)(llt / 100);
1525 float lat_deg = lat_deg_int;
1526 float lat_min = llt - (lat_deg * 100);
1527 lat = lat_deg + (lat_min / 60.);
1528 if (m_NMEA0183.Rmc.Position.Latitude.Northing == South)
1530 SendSentenceToAllInstruments(OCPN_DBP_STC_LAT, lat,
"SDMM");
1532 float lln = m_NMEA0183.Rmc.Position.Longitude.Longitude;
1533 int lon_deg_int = (int)(lln / 100);
1534 float lon_deg = lon_deg_int;
1535 float lon_min = lln - (lon_deg * 100);
1536 lon = lon_deg + (lon_min / 60.);
1537 if (m_NMEA0183.Rmc.Position.Longitude.Easting == West) lon = -lon;
1538 SendSentenceToAllInstruments(OCPN_DBP_STC_LON, lon,
"SDMM");
1541 if (mPriCOGSOG >= 3) {
1543 if (!std::isnan(m_NMEA0183.Rmc.SpeedOverGroundKnots)) {
1544 SendSentenceToAllInstruments(
1547 mSOGFilter.filter(m_NMEA0183.Rmc.SpeedOverGroundKnots),
1552 if (!std::isnan(m_NMEA0183.Rmc.TrackMadeGoodDegreesTrue)) {
1553 SendSentenceToAllInstruments(
1555 mCOGFilter.filter(m_NMEA0183.Rmc.TrackMadeGoodDegreesTrue),
1558 if (!std::isnan(m_NMEA0183.Rmc.TrackMadeGoodDegreesTrue) &&
1559 !std::isnan(m_NMEA0183.Rmc.MagneticVariation)) {
1560 double dMagneticCOG;
1561 if (m_NMEA0183.Rmc.MagneticVariationDirection == East) {
1563 mCOGFilter.get() - m_NMEA0183.Rmc.MagneticVariation;
1564 if (dMagneticCOG < 0.0) dMagneticCOG = 360.0 + dMagneticCOG;
1567 mCOGFilter.get() + m_NMEA0183.Rmc.MagneticVariation;
1568 if (dMagneticCOG > 360.0) dMagneticCOG = dMagneticCOG - 360.0;
1570 SendSentenceToAllInstruments(OCPN_DBP_STC_MCOG, dMagneticCOG,
1579 if ((!std::isnan(m_NMEA0183.Rmc.MagneticVariation)) &&
1580 0.0 != m_NMEA0183.Rmc.MagneticVariation) {
1582 if (m_NMEA0183.Rmc.MagneticVariationDirection == East)
1583 mVar = m_NMEA0183.Rmc.MagneticVariation;
1584 else if (m_NMEA0183.Rmc.MagneticVariationDirection == West)
1585 mVar = -m_NMEA0183.Rmc.MagneticVariation;
1586 mVar_Watchdog = gps_watchdog_timeout_ticks;
1588 SendSentenceToAllInstruments(OCPN_DBP_STC_HMV, mVar,
"\u00B0");
1592 if (mPriDateTime >= 3) {
1594 wxString dt = m_NMEA0183.Rmc.Date + m_NMEA0183.Rmc.UTCTime;
1595 mUTCDateTime.ParseFormat(dt.c_str(),
"%d%m%y%H%M%S");
1596 mUTC_Watchdog = gps_watchdog_timeout_ticks;
1603 else if (m_NMEA0183.LastSentenceIDReceived ==
"RSA") {
1605 if (m_NMEA0183.Parse()) {
1606 if (m_NMEA0183.Rsa.IsStarboardDataValid == NTrue) {
1607 SendSentenceToAllInstruments(OCPN_DBP_STC_RSA,
1608 m_NMEA0183.Rsa.Starboard,
"\u00B0");
1609 }
else if (m_NMEA0183.Rsa.IsPortDataValid == NTrue) {
1610 SendSentenceToAllInstruments(OCPN_DBP_STC_RSA, -m_NMEA0183.Rsa.Port,
1613 mRSA_Watchdog = gps_watchdog_timeout_ticks;
1619 else if (m_NMEA0183.LastSentenceIDReceived ==
"VHW") {
1620 if (mPriHeadingT >= 4 || mPriHeadingM >= 5 || mPriSTW >= 3) {
1621 if (m_NMEA0183.Parse()) {
1622 if (mPriHeadingT >= 4) {
1623 if (!std::isnan(m_NMEA0183.Vhw.DegreesTrue)) {
1625 SendSentenceToAllInstruments(
1626 OCPN_DBP_STC_HDT, m_NMEA0183.Vhw.DegreesTrue,
"\u00B0T");
1627 mHDT_Watchdog = gps_watchdog_timeout_ticks;
1630 if (mPriHeadingM >= 5) {
1631 if (!std::isnan(m_NMEA0183.Vhw.DegreesMagnetic)) {
1633 SendSentenceToAllInstruments(
1634 OCPN_DBP_STC_HDM, m_NMEA0183.Vhw.DegreesMagnetic,
"\u00B0M");
1635 mHDx_Watchdog = gps_watchdog_timeout_ticks;
1639 double stw_kn = NAN;
1640 if (!std::isnan(m_NMEA0183.Vhw.Knots))
1641 stw_kn = m_NMEA0183.Vhw.Knots;
1642 else if (!std::isnan(m_NMEA0183.Vhw.KilometersPerHour))
1643 stw_kn = m_NMEA0183.Vhw.KilometersPerHour * 0.53995;
1645 if (!std::isnan(stw_kn)) {
1646 SendSentenceToAllInstruments(
1649 mSTW_Watchdog = gps_watchdog_timeout_ticks;
1657 else if (m_NMEA0183.LastSentenceIDReceived ==
"VTG") {
1658 if (mPriCOGSOG >= 2) {
1659 if (m_NMEA0183.Parse()) {
1662 if (!std::isnan(m_NMEA0183.Vtg.SpeedKnots)) {
1663 SendSentenceToAllInstruments(
1670 if (!std::isnan(m_NMEA0183.Vtg.TrackDegreesTrue)) {
1671 SendSentenceToAllInstruments(
1673 mCOGFilter.filter(m_NMEA0183.Vtg.TrackDegreesTrue),
"\u00B0");
1686 else if (m_NMEA0183.LastSentenceIDReceived ==
"VWR") {
1688 if (m_NMEA0183.Parse()) {
1689 if (m_NMEA0183.Vwr.WindDirectionMagnitude < 200) {
1694 m_NMEA0183.Vwr.DirectionOfWind == Left ?
"\u00B0L" :
"\u00B0R";
1695 SendSentenceToAllInstruments(OCPN_DBP_STC_AWA,
1696 m_NMEA0183.Vwr.WindDirectionMagnitude,
1698 SendSentenceToAllInstruments(
1701 g_iDashWindSpeedUnit),
1703 mMWVA_Watchdog = gps_watchdog_timeout_ticks;
1715 double awa = m_NMEA0183.Vwr.WindDirectionMagnitude;
1716 if (m_NMEA0183.Vwr.DirectionOfWind == Left)
1717 awa = 360. - m_NMEA0183.Vwr.WindDirectionMagnitude;
1718 CalculateAndUpdateTWDS(m_NMEA0183.Vwr.WindSpeedKnots, awa);
1720 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
1721 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
1732 else if (m_NMEA0183.LastSentenceIDReceived ==
"VWT") {
1734 if (m_NMEA0183.Parse()) {
1735 if (m_NMEA0183.Vwt.WindDirectionMagnitude < 200) {
1739 m_NMEA0183.Vwt.DirectionOfWind == Left ?
"\u00B0L" :
"\u00B0R";
1740 SendSentenceToAllInstruments(OCPN_DBP_STC_TWA,
1741 m_NMEA0183.Vwt.WindDirectionMagnitude,
1743 SendSentenceToAllInstruments(
1746 g_iDashWindSpeedUnit),
1748 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
1758 else if (m_NMEA0183.LastSentenceIDReceived ==
1773 if (m_NMEA0183.Parse()) {
1776 for (
int i = 0; i < m_NMEA0183.Xdr.TransducerCnt; i++) {
1777 xdrdata = m_NMEA0183.Xdr.TransducerInfo[i].MeasurementData;
1779 if (m_NMEA0183.Xdr.TransducerInfo[i].TransducerType ==
"C") {
1780 if (m_NMEA0183.Xdr.TransducerInfo[i]
1781 .TransducerName.Upper()
1783 m_NMEA0183.Xdr.TransducerInfo[i].TransducerName ==
"Te" ||
1784 m_NMEA0183.Xdr.TransducerInfo[i].TransducerName ==
1786 m_NMEA0183.Xdr.TransducerInfo[i].TransducerName ==
1788 if (mPriATMP >= 4) {
1790 SendSentenceToAllInstruments(
1794 mATMP_Watchdog = no_nav_watchdog_timeout_ticks;
1798 if (m_NMEA0183.Xdr.TransducerInfo[i]
1799 .TransducerName.Upper()
1800 .Contains(
"WATER") ||
1801 m_NMEA0183.Xdr.TransducerInfo[i].TransducerName ==
"WTHI") {
1804 SendSentenceToAllInstruments(
1807 m_NMEA0183.Xdr.TransducerInfo[i].MeasurementData,
1810 mWTP_Watchdog = no_nav_watchdog_timeout_ticks;
1816 if (m_NMEA0183.Xdr.TransducerInfo[i].TransducerType ==
"P") {
1817 if (m_NMEA0183.Xdr.TransducerInfo[i]
1818 .TransducerName.Upper()
1819 .Contains(
"BARO") &&
1821 if (m_NMEA0183.Xdr.TransducerInfo[i].UnitOfMeasurement ==
"B") {
1823 SendSentenceToAllInstruments(OCPN_DBP_STC_MDA, xdrdata,
"hPa");
1825 mMDA_Watchdog = no_nav_watchdog_timeout_ticks;
1831 if (m_NMEA0183.Xdr.TransducerInfo[i].TransducerType ==
"A") {
1832 if (m_NMEA0183.Xdr.TransducerInfo[i].TransducerName.Contains(
1834 m_NMEA0183.Xdr.TransducerInfo[i]
1835 .TransducerName.Upper()
1836 .Contains(
"PITCH")) {
1837 if (mPriPitchRoll >= 3) {
1838 if (m_NMEA0183.Xdr.TransducerInfo[i].MeasurementData > 0) {
1839 xdrunit = L
"\u00B0\u2191" + _(
"Up");
1840 }
else if (m_NMEA0183.Xdr.TransducerInfo[i].MeasurementData <
1842 xdrunit = L
"\u00B0\u2193" + _(
"Down");
1847 SendSentenceToAllInstruments(OCPN_DBP_STC_PITCH, xdrdata,
1849 mPITCH_Watchdog = gps_watchdog_timeout_ticks;
1855 if (m_NMEA0183.Xdr.TransducerInfo[i]
1856 .TransducerName.Upper()
1857 .Contains(
"ROLL")) {
1858 if (mPriPitchRoll >= 3) {
1859 if (m_NMEA0183.Xdr.TransducerInfo[i].MeasurementData > 0) {
1860 xdrunit = L
"\u00B0\u003E" + _(
"Stbd");
1861 }
else if (m_NMEA0183.Xdr.TransducerInfo[i].MeasurementData <
1863 xdrunit = L
"\u00B0\u003C" + _(
"Port");
1868 SendSentenceToAllInstruments(OCPN_DBP_STC_HEEL, xdrdata,
1870 mHEEL_Watchdog = gps_watchdog_timeout_ticks;
1876 if (m_NMEA0183.Xdr.TransducerInfo[i]
1877 .TransducerName.Upper()
1878 .Contains(
"RUDDER")) {
1880 SendSentenceToAllInstruments(OCPN_DBP_STC_RSA, xdrdata,
1882 mRSA_Watchdog = gps_watchdog_timeout_ticks;
1889 if ((m_NMEA0183.Xdr.TransducerInfo[i].TransducerType ==
"D")) {
1890 bool good_depth =
false;
1891 if (m_NMEA0183.Xdr.TransducerInfo[i].TransducerName ==
"XDHI" &&
1895 }
else if (m_NMEA0183.Xdr.TransducerInfo[i].TransducerName ==
1902 else if (m_NMEA0183.Xdr.TransducerInfo[i].TransducerName ==
1904 m_NMEA0183.Xdr.TransducerInfo[i].TransducerName ==
1907 m_NMEA0183.Xdr.TransducerInfo[i].UnitOfMeasurement;
1908 if (
unit == wxEmptyString)
unit =
"m";
1910 SendSentenceToAllInstruments(OCPN_DBP_STC_WCC, xdrdata,
unit);
1911 mWCC_Watchdog = no_nav_watchdog_timeout_ticks;
1915 wxString
unit = m_NMEA0183.Xdr.TransducerInfo[i]
1916 .UnitOfMeasurement.MakeLower();
1920 if (!std::isnan(depth)) {
1921 depth += g_dDashDBTOffset;
1922 SendSentenceToAllInstruments(
1926 mDPT_DBT_Watchdog = gps_watchdog_timeout_ticks;
1932 if (m_NMEA0183.Xdr.TransducerInfo[i].TransducerType ==
"H") {
1934 if (m_NMEA0183.Xdr.TransducerInfo[i].UnitOfMeasurement ==
"P") {
1935 SendSentenceToAllInstruments(OCPN_DBP_STC_HUM, xdrdata,
"%");
1937 mHUM_Watchdog = no_nav_watchdog_timeout_ticks;
1943 }
else if (m_NMEA0183.LastSentenceIDReceived ==
"ZDA") {
1944 if (mPriDateTime >= 2) {
1945 if (m_NMEA0183.Parse()) {
1956 dt.Printf(
"%4d%02d%02d", m_NMEA0183.Zda.Year, m_NMEA0183.Zda.Month,
1957 m_NMEA0183.Zda.Day);
1958 dt.Append(m_NMEA0183.Zda.UTCTime);
1959 mUTCDateTime.ParseFormat(dt.c_str(),
"%Y%m%d%H%M%S");
1960 mUTC_Watchdog = gps_watchdog_timeout_ticks;
1966 else if (sentence.Mid(1, 5).IsSameAs(
"AIVDO")) {
1969 if (!std::isnan(gpd.
Lat))
1970 SendSentenceToAllInstruments(OCPN_DBP_STC_LAT, gpd.
Lat,
"SDMM");
1972 if (!std::isnan(gpd.
Lon))
1973 SendSentenceToAllInstruments(OCPN_DBP_STC_LON, gpd.
Lon,
"SDMM");
1975 SendSentenceToAllInstruments(
1979 SendSentenceToAllInstruments(OCPN_DBP_STC_COG, mCOGFilter.filter(gpd.
Cog),
1981 if (!std::isnan(gpd.
Hdt)) {
1982 SendSentenceToAllInstruments(OCPN_DBP_STC_HDT, gpd.
Hdt,
"\u00B0T");
1983 mHDT_Watchdog = gps_watchdog_timeout_ticks;
1994void dashboard_pi::CalculateAndUpdateTWDS(
double awsKnots,
double awaDegrees) {
1995 if (!std::isnan(g_dHDT)) {
1997 double awsx = awsKnots * cos(awaDegrees * PI / 180.);
1998 double awsy = awsKnots * sin(awaDegrees * PI / 180.);
2003 if ((!std::isnan(g_dSOG)) && (!std::isnan(g_dCOG))) {
2004 bsx = g_dSOG * cos((g_dCOG - g_dHDT) * PI / 180.);
2005 bsy = g_dSOG * sin((g_dCOG - g_dHDT) * PI / 180.);
2010 double twdx = awsx - bsx;
2011 double twdy = awsy - bsy;
2014 double tws = pow(((twdx * twdx) + (twdy * twdy)), 0.5);
2017 double twd = atan2(twdy, twdx) * 180. / PI;
2019 SendSentenceToAllInstruments(OCPN_DBP_STC_TWA, -twd,
"\u00B0L");
2021 SendSentenceToAllInstruments(OCPN_DBP_STC_TWA, twd,
"\u00B0R");
2024 double twdc = twd + g_dHDT;
2027 if (twdc < 0) twdc += 360.;
2028 if (twdc > 360.) twdc -= 360;
2032 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, twdc,
"\u00B0");
2034 SendSentenceToAllInstruments(OCPN_DBP_STC_TWS,
2037 SendSentenceToAllInstruments(OCPN_DBP_STC_TWS2,
2047void dashboard_pi::HandleN2K_127245(
ObservedEvt ev) {
2052 unsigned char source_id = v.at(7);
2054 sprintf(ss,
"%d", source_id);
2055 std::string ident = std::string(ss);
2057 source +=
":" + ident;
2062 if (source != prio127245)
return;
2065 prio127245 = source;
2068 double RudderPosition, AngleOrder;
2069 unsigned char Instance;
2070 tN2kRudderDirectionOrder RudderDirectionOrder;
2073 if (ParseN2kPGN127245(v, RudderPosition, Instance, RudderDirectionOrder,
2075 if (!N2kIsNA(RudderPosition)) {
2076 double m_rudangle = GEODESIC_RAD2DEG(RudderPosition);
2077 SendSentenceToAllInstruments(OCPN_DBP_STC_RSA, m_rudangle,
"\u00B0");
2078 mRSA_Watchdog = gps_watchdog_timeout_ticks;
2086void dashboard_pi::HandleN2K_127257(
ObservedEvt ev) {
2091 unsigned char source_id = v.at(7);
2093 sprintf(ss,
"%d", source_id);
2094 std::string ident = std::string(ss);
2096 source +=
":" + ident;
2098 if (mPriPitchRoll >= 1) {
2099 if (mPriPitchRoll == 1) {
2101 if (source != prio127257)
return;
2104 prio127257 = source;
2108 double Yaw, Pitch, Roll;
2111 if (ParseN2kPGN127257(v, SID, Yaw, Pitch, Roll)) {
2112 if (!N2kIsNA(Pitch)) {
2113 double m_pitch = GEODESIC_RAD2DEG(Pitch);
2114 wxString p_unit = L
"\u00B0\u2191" + _(
"Up");
2116 p_unit = L
"\u00B0\u2193" + _(
"Down");
2119 SendSentenceToAllInstruments(OCPN_DBP_STC_PITCH, m_pitch, p_unit);
2120 mPITCH_Watchdog = gps_watchdog_timeout_ticks;
2123 if (!N2kIsNA(Roll)) {
2124 double m_heel = GEODESIC_RAD2DEG(Roll);
2125 wxString h_unit = L
"\u00B0\u003E" + _(
"Stbd");
2127 h_unit = L
"\u00B0\u003C" + _(
"Port");
2130 SendSentenceToAllInstruments(OCPN_DBP_STC_HEEL, m_heel, h_unit);
2131 mHEEL_Watchdog = gps_watchdog_timeout_ticks;
2138void dashboard_pi::HandleN2K_128267(
ObservedEvt ev) {
2143 unsigned char source_id = v.at(7);
2145 sprintf(ss,
"%d", source_id);
2146 std::string ident = std::string(ss);
2148 source +=
":" + ident;
2150 if (mPriDepth >= 1) {
2151 if (mPriDepth == 1) {
2152 if (source != prio128267)
return;
2154 prio128267 = source;
2158 double DepthBelowTransducer, Offset, Range;
2161 if (ParseN2kPGN128267(v, SID, DepthBelowTransducer, Offset, Range)) {
2162 if (!N2kIsNA(DepthBelowTransducer)) {
2163 double depth = DepthBelowTransducer;
2165 if (!std::isnan(Offset) && !N2kIsNA(Offset))
2168 (depth += g_dDashDBTOffset);
2170 SendSentenceToAllInstruments(
2175 mDPT_DBT_Watchdog = gps_watchdog_timeout_ticks;
2181void dashboard_pi::HandleN2K_128275(
ObservedEvt ev) {
2184 uint16_t DaysSince1970;
2185 double SecondsSinceMidnight;
2186 uint32_t Log, TripLog;
2189 if (ParseN2kPGN128275(v, DaysSince1970, SecondsSinceMidnight, Log, TripLog)) {
2190 if (!N2kIsNA(Log) && !g_bUseInternSumLog) {
2191 double m_slog = METERS2NM((
double)Log);
2192 SendSentenceToAllInstruments(
2195 mLOG_Watchdog = no_nav_watchdog_timeout_ticks;
2198 if (!N2kIsNA(TripLog)) {
2199 double m_tlog = METERS2NM((
double)TripLog);
2200 SendSentenceToAllInstruments(
2203 mTrLOG_Watchdog = no_nav_watchdog_timeout_ticks;
2207void dashboard_pi::HandleN2K_128259(
ObservedEvt ev) {
2212 unsigned char source_id = v.at(7);
2214 sprintf(ss,
"%d", source_id);
2215 std::string ident = std::string(ss);
2217 source +=
":" + ident;
2221 if (source != prio128259)
return;
2223 prio128259 = source;
2227 double WaterReferenced, GroundReferenced;
2228 tN2kSpeedWaterReferenceType SWRT;
2231 if (ParseN2kPGN128259(v, SID, WaterReferenced, GroundReferenced, SWRT)) {
2232 if (!N2kIsNA(WaterReferenced)) {
2233 double stw_knots = MS2KNOTS(WaterReferenced);
2234 SendSentenceToAllInstruments(
2238 mSTW_Watchdog = gps_watchdog_timeout_ticks;
2244void dashboard_pi::HandleN2K_128777(
ObservedEvt ev) {
2249 unsigned char WindlassIdentifier;
2250 double RodeCounterValue;
2251 double WindlassLineSpeed;
2252 tN2kWindlassMotionStates WindlassMotionStatus;
2253 tN2kRodeTypeStates RodeTypeStatus;
2254 tN2kAnchorDockingStates AnchorDockingStatus;
2255 tN2kWindlassOperatingEvents WindlassOperatingEvents;
2257 if (ParseN2kPGN128777(v, SID, WindlassIdentifier, RodeCounterValue,
2258 WindlassLineSpeed, WindlassMotionStatus, RodeTypeStatus,
2259 AnchorDockingStatus, WindlassOperatingEvents)) {
2260 if (!N2kIsNA(RodeCounterValue)) {
2261 SendSentenceToAllInstruments(OCPN_DBP_STC_WCC, RodeCounterValue,
"m");
2262 mWCC_Watchdog = no_nav_watchdog_timeout_ticks;
2267wxString talker_N2k = wxEmptyString;
2268void dashboard_pi::HandleN2K_129029(
ObservedEvt ev) {
2272 unsigned char source_id = v.at(7);
2274 sprintf(ss,
"%d", source_id);
2275 std::string ident = std::string(ss);
2277 std::string prio_ID(prioN2kPGNsat.substr(prioN2kPGNsat.find(
':') + 1, 5));
2278 if (prio_ID.find(ident) == std::string::npos)
return;
2281 uint16_t DaysSince1970;
2282 double SecondsSinceMidnight;
2283 double Latitude, Longitude, Altitude;
2284 tN2kGNSStype GNSStype;
2285 tN2kGNSSmethod GNSSmethod;
2286 unsigned char nSatellites;
2287 double HDOP, PDOP, GeoidalSeparation;
2288 unsigned char nReferenceStations;
2289 tN2kGNSStype ReferenceStationType;
2290 uint16_t ReferenceSationID;
2291 double AgeOfCorrection;
2294 if (ParseN2kPGN129029(v, SID, DaysSince1970, SecondsSinceMidnight, Latitude,
2295 Longitude, Altitude, GNSStype, GNSSmethod, nSatellites,
2296 HDOP, PDOP, GeoidalSeparation, nReferenceStations,
2297 ReferenceStationType, ReferenceSationID,
2307 talker_N2k =
"GPSGLONAS";
2313 talker_N2k =
"GPSGLONAS";
2316 talker_N2k =
"Chayka";
2322 talker_N2k = wxEmptyString;
2324 if (!N2kIsNA(Altitude)) {
2326 SendSentenceToAllInstruments(OCPN_DBP_STC_ALTI, Altitude,
"m");
2328 mALT_Watchdog = gps_watchdog_timeout_ticks;
2334void dashboard_pi::HandleN2K_129540(
ObservedEvt ev) {
2339 unsigned char source_id = v.at(7);
2341 sprintf(ss,
"%d", source_id);
2342 std::string ident = std::string(ss);
2344 std::string prio_ID(prioN2kPGNsat.substr(prioN2kPGNsat.find(
':') + 1, 5));
2345 if (prio_ID.find(ident) == std::string::npos)
return;
2348 tN2kRangeResidualMode Mode;
2349 uint8_t NumberOfSVs;
2352 if (ParseN2kPGN129540(v, SID, Mode, NumberOfSVs)) {
2353 if (!N2kIsNA(NumberOfSVs) && mPriSatStatus == 1) {
2356 SAT_INFO N2K_SatInfo[4];
2359 double dElevRad = 0;
2360 double dAzimRad = 0;
2363 for (
int iMesNum = 0; iMesNum < 3; iMesNum++) {
2364 for (idx = 0; idx < 4; idx++) {
2365 tSatelliteInfo SatelliteInfo;
2366 index = idx + 4 * iMesNum;
2367 if (index >= NumberOfSVs - 1)
break;
2368 if (ParseN2kPGN129540(v, index, SatelliteInfo)) {
2369 iPRN = (int)SatelliteInfo.PRN;
2370 dElevRad = SatelliteInfo.Elevation;
2371 dAzimRad = SatelliteInfo.Azimuth;
2372 iSNR = N2kIsNA(SatelliteInfo.SNR) ? 0 : (int)SatelliteInfo.SNR;
2374 N2K_SatInfo[idx].SatNumber = iPRN;
2375 N2K_SatInfo[idx].ElevationDegrees = GEODESIC_RAD2DEG(dElevRad);
2376 N2K_SatInfo[idx].AzimuthDegreesTrue = GEODESIC_RAD2DEG(dAzimRad);
2377 N2K_SatInfo[idx].SignalToNoiseRatio = iSNR;
2382 SendSatInfoToAllInstruments(NumberOfSVs, iMesNum + 1, talker_N2k,
2385 mSatStatus_Wdog = gps_watchdog_timeout_ticks;
2393void dashboard_pi::HandleN2K_130306(
ObservedEvt ev) {
2401 double WindSpeed, WindAngle;
2402 tN2kWindReference WindReference;
2405 if (ParseN2kPGN130306(v, SID, WindSpeed, WindAngle, WindReference)) {
2406 if (!N2kIsNA(WindSpeed) && !N2kIsNA(WindAngle)) {
2407 double wind_angle_degr = GEODESIC_RAD2DEG(WindAngle);
2408 double wind_speed_kn = MS2KNOTS(WindSpeed);
2409 bool sendTWA =
false, sendTWS =
false;
2411 switch (WindReference) {
2414 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, wind_angle_degr,
2418 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
2424 if (!std::isnan(mVar)) {
2425 wind_angle_degr += mVar;
2426 if (wind_angle_degr > 360.) {
2427 wind_angle_degr -= 360;
2428 }
else if (wind_angle_degr < 0.) {
2429 wind_angle_degr += 360;
2432 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, wind_angle_degr,
2436 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
2441 double calc_angle = wind_angle_degr;
2443 wxString m_awaunit =
"\u00B0R";
2445 if (wind_angle_degr > 180.0) {
2446 wind_angle_degr = 360.0 - wind_angle_degr;
2447 m_awaunit =
"\u00B0L";
2449 SendSentenceToAllInstruments(OCPN_DBP_STC_AWA,
2450 mAWAFilter.filter(wind_angle_degr),
2453 SendSentenceToAllInstruments(
2456 g_iDashWindSpeedUnit),
2460 mMWVA_Watchdog = gps_watchdog_timeout_ticks;
2465 if (calc_angle > 180) calc_angle -= 360.0;
2466 CalculateAndUpdateTWDS(wind_speed_kn, calc_angle);
2469 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
2470 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
2475 if (mPriTWA >= 1 && g_bDBtrueWindGround) {
2482 if (mPriTWA >= 1 && !g_bDBtrueWindGround) {
2498 wxString m_twaunit =
"\u00B0R";
2500 if (wind_angle_degr > 180.0) {
2501 wind_angle_degr = 360.0 - wind_angle_degr;
2502 m_twaunit =
"\u00B0L";
2504 SendSentenceToAllInstruments(OCPN_DBP_STC_TWA, wind_angle_degr,
2510 SendSentenceToAllInstruments(
2514 SendSentenceToAllInstruments(
2518 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
2524void dashboard_pi::HandleN2K_130310(
ObservedEvt ev) {
2528 double WaterTemperature, OutsideAmbientAirTemperature, AtmosphericPressure;
2531 if (ParseN2kPGN130310(v, SID, WaterTemperature, OutsideAmbientAirTemperature,
2532 AtmosphericPressure)) {
2534 if (!N2kIsNA(WaterTemperature)) {
2535 double m_wtemp KELVIN2C(WaterTemperature);
2536 SendSentenceToAllInstruments(OCPN_DBP_STC_TMP,
2540 mWTP_Watchdog = no_nav_watchdog_timeout_ticks;
2544 if (mPriATMP >= 1) {
2545 if (!N2kIsNA(OutsideAmbientAirTemperature)) {
2546 double m_airtemp = KELVIN2C(OutsideAmbientAirTemperature);
2547 if (m_airtemp > -60 && m_airtemp < 100) {
2548 SendSentenceToAllInstruments(
2552 mATMP_Watchdog = no_nav_watchdog_timeout_ticks;
2557 if (!N2kIsNA(AtmosphericPressure) && mPriMDA >= 1) {
2558 double m_press = PA2HPA(AtmosphericPressure);
2559 SendSentenceToAllInstruments(OCPN_DBP_STC_MDA, m_press,
"hPa");
2561 mMDA_Watchdog = no_nav_watchdog_timeout_ticks;
2566void dashboard_pi::HandleN2K_130313(
ObservedEvt ev) {
2569 unsigned char SID, HumidityInstance;
2570 tN2kHumiditySource HumiditySource;
2571 double ActualHumidity, SetHumidity;
2573 if (ParseN2kPGN130313(v, SID, HumidityInstance, HumiditySource,
2574 ActualHumidity, SetHumidity)) {
2576 if (!N2kIsNA(ActualHumidity)) {
2577 SendSentenceToAllInstruments(OCPN_DBP_STC_HUM, ActualHumidity,
"%");
2579 mHUM_Watchdog = no_nav_watchdog_timeout_ticks;
2586void dashboard_pi::ParseSignalK(wxString &msg) {
2590 int errors = jsonReader.
Parse(msg, &root);
2598 if (root[
"self"].AsString().StartsWith(
"vessels."))
2599 m_self = (root[
"self"].
AsString());
2601 else if (root[
"self"].AsString().Length())
2602 m_self =
"vessels." + (root[
"self"].AsString());
2606 auto context = root[
"context"].
AsString();
2607 if (context != m_self) {
2614 for (
int i = 0; i < updates.
Size(); ++i) {
2615 handleSKUpdate(updates[i]);
2620void dashboard_pi::handleSKUpdate(
wxJSONValue &update) {
2621 wxString sfixtime =
"";
2624 sfixtime = update[
"timestamp"].
AsString();
2626 if (update.
HasMember(
"values") && update[
"values"].IsArray()) {
2627 wxString talker = wxEmptyString;
2629 if (update[
"source"].HasMember(
"talker")) {
2630 if (update[
"source"][
"talker"].IsString()) {
2631 talker = update[
"source"][
"talker"].
AsString();
2635 for (
int j = 0; j < update[
"values"].
Size(); ++j) {
2637 updateSKItem(item, talker, sfixtime);
2642void dashboard_pi::updateSKItem(
wxJSONValue &item, wxString &talker,
2643 wxString &sfixtime) {
2645 const wxString &update_path = item[
"path"].
AsString();
2649 static wxString talkerID = wxEmptyString;
2651 static double skAWA;
2653 if (update_path ==
"navigation.position") {
2654 if (mPriPosition >= 2) {
2655 if (value[
"latitude"].IsDouble() && value[
"longitude"].IsDouble()) {
2656 double lat = value[
"latitude"].
AsDouble();
2657 double lon = value[
"longitude"].AsDouble();
2658 SendSentenceToAllInstruments(OCPN_DBP_STC_LAT, lat,
"SDMM");
2659 SendSentenceToAllInstruments(OCPN_DBP_STC_LON, lon,
"SDMM");
2663 }
else if (update_path ==
"navigation.speedOverGround" &&
2664 2 == mPriPosition) {
2665 double sog_knot = GetJsonDouble(value);
2666 if (std::isnan(sog_knot))
return;
2668 SendSentenceToAllInstruments(
2672 }
else if (update_path ==
"navigation.courseOverGroundTrue" &&
2673 2 == mPriPosition) {
2674 double cog_rad = GetJsonDouble(value);
2675 if (std::isnan(cog_rad))
return;
2677 double cog_deg = GEODESIC_RAD2DEG(cog_rad);
2678 SendSentenceToAllInstruments(OCPN_DBP_STC_COG, mCOGFilter.filter(cog_deg),
2680 }
else if (update_path ==
"navigation.headingTrue") {
2681 if (mPriHeadingT >= 2) {
2682 double hdt = GetJsonDouble(value);
2683 if (std::isnan(hdt))
return;
2685 hdt = GEODESIC_RAD2DEG(hdt);
2686 SendSentenceToAllInstruments(OCPN_DBP_STC_HDT, hdt,
"\u00B0T");
2688 mHDT_Watchdog = gps_watchdog_timeout_ticks;
2690 }
else if (update_path ==
"navigation.headingMagnetic") {
2691 if (mPriHeadingM >= 2) {
2692 double hdm = GetJsonDouble(value);
2693 if (std::isnan(hdm))
return;
2695 hdm = GEODESIC_RAD2DEG(hdm);
2696 SendSentenceToAllInstruments(OCPN_DBP_STC_HDM, hdm,
"\u00B0M");
2698 mHDx_Watchdog = gps_watchdog_timeout_ticks;
2701 if (mPriHeadingT >= 6 && (!std::isnan(mVar))) {
2702 double heading = hdm + mVar;
2705 else if (heading >= 360.0)
2707 SendSentenceToAllInstruments(OCPN_DBP_STC_HDT, heading,
"\u00B0");
2709 mHDT_Watchdog = gps_watchdog_timeout_ticks;
2712 }
else if (update_path ==
"navigation.speedThroughWater") {
2714 double stw_knots = GetJsonDouble(value);
2715 if (std::isnan(stw_knots))
return;
2717 stw_knots = MS2KNOTS(stw_knots);
2718 SendSentenceToAllInstruments(
2722 mSTW_Watchdog = gps_watchdog_timeout_ticks;
2724 }
else if (update_path ==
"navigation.magneticVariation") {
2726 double dvar = GetJsonDouble(value);
2727 if (std::isnan(dvar))
return;
2729 dvar = GEODESIC_RAD2DEG(dvar);
2731 SendSentenceToAllInstruments(OCPN_DBP_STC_HMV, dvar,
"\u00B0");
2733 mVar_Watchdog = gps_watchdog_timeout_ticks;
2736 }
else if (update_path ==
"environment.wind.angleApparent") {
2738 double m_awaangle = GetJsonDouble(value);
2739 if (std::isnan(m_awaangle))
return;
2741 m_awaangle = GEODESIC_RAD2DEG(m_awaangle);
2743 wxString m_awaunit =
"\u00B0R";
2744 if (m_awaangle < 0) {
2745 m_awaunit =
"\u00B0L";
2748 SendSentenceToAllInstruments(OCPN_DBP_STC_AWA,
2749 mAWAFilter.filter(m_awaangle), m_awaunit);
2751 mMWVA_Watchdog = gps_watchdog_timeout_ticks;
2753 }
else if (update_path ==
"environment.wind.speedApparent") {
2755 double m_awaspeed_kn = GetJsonDouble(value);
2756 if (std::isnan(m_awaspeed_kn))
return;
2758 m_awaspeed_kn = MS2KNOTS(m_awaspeed_kn);
2759 SendSentenceToAllInstruments(
2762 g_iDashWindSpeedUnit),
2766 if (mPriTWA >= 6 && !std::isnan(skAWA)) {
2767 CalculateAndUpdateTWDS(m_awaspeed_kn, skAWA);
2769 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
2770 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
2773 }
else if ((update_path ==
"environment.wind.angleTrueWater" &&
2774 !g_bDBtrueWindGround) ||
2775 (update_path ==
"environment.wind.angleTrueGround" &&
2776 g_bDBtrueWindGround)) {
2778 double m_twaangle = GetJsonDouble(value);
2779 if (std::isnan(m_twaangle))
return;
2781 m_twaangle = GEODESIC_RAD2DEG(m_twaangle);
2782 double m_twaangle_raw = m_twaangle;
2783 wxString m_twaunit =
"\u00B0R";
2784 if (m_twaangle < 0) {
2785 m_twaunit =
"\u00B0L";
2788 SendSentenceToAllInstruments(OCPN_DBP_STC_TWA, m_twaangle, m_twaunit);
2790 mMWVT_Watchdog = gps_watchdog_timeout_ticks;
2797 if (g_dHDT < 361. && g_dHDT >= 0.0) {
2798 double g_dCalWdir = (m_twaangle_raw) + g_dHDT;
2799 if (g_dCalWdir > 360.) {
2801 }
else if (g_dCalWdir < 0.) {
2804 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, g_dCalWdir,
2807 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
2811 }
else if ((update_path ==
"environment.wind.speedTrue" &&
2812 !g_bDBtrueWindGround) ||
2813 (update_path ==
"environment.wind.speedOverGround" &&
2814 g_bDBtrueWindGround)) {
2816 double m_twaspeed_kn = GetJsonDouble(value);
2817 if (std::isnan(m_twaspeed_kn))
return;
2819 m_twaspeed_kn = MS2KNOTS(m_twaspeed_kn);
2820 SendSentenceToAllInstruments(
2824 SendSentenceToAllInstruments(
2829 }
else if (update_path ==
"environment.depth.belowSurface") {
2830 if (mPriDepth >= 3) {
2831 double depth = GetJsonDouble(value);
2832 if (std::isnan(depth))
return;
2835 depth += g_dDashDBTOffset;
2837 SendSentenceToAllInstruments(
2840 mDPT_DBT_Watchdog = gps_watchdog_timeout_ticks;
2842 }
else if (update_path ==
"environment.depth.belowTransducer") {
2843 if (mPriDepth >= 3) {
2844 double depth = GetJsonDouble(value);
2845 if (std::isnan(depth))
return;
2848 depth += g_dDashDBTOffset;
2850 SendSentenceToAllInstruments(
2853 mDPT_DBT_Watchdog = gps_watchdog_timeout_ticks;
2855 }
else if (update_path ==
"environment.water.temperature") {
2857 double m_wtemp = GetJsonDouble(value);
2858 if (std::isnan(m_wtemp))
return;
2860 m_wtemp = KELVIN2C(m_wtemp);
2861 if (m_wtemp > -60 && m_wtemp < 200 && !std::isnan(m_wtemp)) {
2862 SendSentenceToAllInstruments(
2866 mWTP_Watchdog = no_nav_watchdog_timeout_ticks;
2869 }
else if (update_path ==
2870 "navigation.courseRhumbline.nextPoint.velocityMadeGood") {
2871 double m_vmg_kn = GetJsonDouble(value);
2872 if (std::isnan(m_vmg_kn))
return;
2874 m_vmg_kn = MS2KNOTS(m_vmg_kn);
2875 SendSentenceToAllInstruments(
2878 mVMG_Watchdog = gps_watchdog_timeout_ticks;
2881 else if (update_path ==
"performance.velocityMadeGood") {
2882 double m_vmgw_kn = GetJsonDouble(value);
2883 if (std::isnan(m_vmgw_kn))
return;
2885 m_vmgw_kn = MS2KNOTS(m_vmgw_kn);
2886 SendSentenceToAllInstruments(
2889 mVMGW_Watchdog = gps_watchdog_timeout_ticks;
2892 else if (update_path ==
"steering.rudderAngle") {
2894 double m_rudangle = GetJsonDouble(value);
2895 if (std::isnan(m_rudangle))
return;
2897 m_rudangle = GEODESIC_RAD2DEG(m_rudangle);
2898 SendSentenceToAllInstruments(OCPN_DBP_STC_RSA, m_rudangle,
"\u00B0");
2899 mRSA_Watchdog = gps_watchdog_timeout_ticks;
2902 }
else if (update_path ==
2903 "navigation.gnss.satellites") {
2904 if (mPriSatUsed >= 2) {
2905 int usedSats = (value).AsInt();
2906 if (usedSats < 1)
return;
2907 SendSentenceToAllInstruments(OCPN_DBP_STC_SAT, usedSats, _T (
""));
2909 mSatsUsed_Wdog = gps_watchdog_timeout_ticks;
2911 }
else if (update_path ==
"navigation.gnss.type") {
2912 if (value.IsString() && value.AsString() != wxEmptyString) {
2913 talkerID = (value.AsString());
2914 talkerID.MakeUpper();
2915 m_PriN2kTalker = gps_watchdog_timeout_ticks;
2916 if ((talkerID.Contains(
"GPS")) && (talkerID.Contains(
"GLONASS")))
2917 talkerID =
"GPSGLONAS";
2918 else if (talkerID.Contains(
"GPS"))
2920 else if (talkerID.Contains(
"GLONASS"))
2922 else if (talkerID.Contains(
"GALILEO"))
2924 else if (talkerID.Contains(
"BEIDOU"))
2927 }
else if (update_path ==
2928 "navigation.gnss.satellitesInView") {
2930 if (mPriSatUsed >= 4) {
2931 if (value.HasMember(
"count") && value[
"count"].IsInt()) {
2932 double m_SK_SatsInView = (value[
"count"].AsInt());
2933 SendSentenceToAllInstruments(OCPN_DBP_STC_SAT, m_SK_SatsInView,
2936 mSatsUsed_Wdog = gps_watchdog_timeout_ticks;
2939 if (mPriSatStatus == 2) {
2940 if (value.HasMember(
"satellites") && value[
"satellites"].IsArray()) {
2943 if (value.HasMember(
"count") && value[
"count"].IsInt()) {
2944 iNumSats = (value[
"count"].AsInt());
2946 iNumSats = value[_T (
"satellites")].Size();
2948 SAT_INFO SK_SatInfo[4];
2949 for (
int idx = 0; idx < 4; idx++) {
2950 SK_SatInfo[idx].SatNumber = 0;
2951 SK_SatInfo[idx].ElevationDegrees = 0;
2952 SK_SatInfo[idx].AzimuthDegreesTrue = 0;
2953 SK_SatInfo[idx].SignalToNoiseRatio = 0;
2960 double dElevRad = 0;
2961 double dAzimRad = 0;
2964 for (
int iMesNum = 0; iMesNum < 3; iMesNum++) {
2965 for (idx = 0; idx < 4; idx++) {
2966 arr = idx + 4 * iMesNum;
2967 if (value[
"satellites"][arr][
"id"].IsInt())
2968 iID = value[
"satellites"][arr][
"id"].AsInt();
2969 if (value[
"satellites"][arr][
"elevation"].IsDouble())
2970 dElevRad = value[
"satellites"][arr][
"elevation"].AsDouble();
2971 if (value[
"satellites"][arr][
"azimuth"].IsDouble())
2972 dAzimRad = value[
"satellites"][arr][
"azimuth"].AsDouble();
2973 if (value[
"satellites"][arr][
"SNR"].IsInt())
2974 iSNR = value[
"satellites"][arr][
"SNR"].AsInt();
2977 SK_SatInfo[idx].SatNumber = iID;
2978 SK_SatInfo[idx].ElevationDegrees = GEODESIC_RAD2DEG(dElevRad);
2979 SK_SatInfo[idx].AzimuthDegreesTrue = GEODESIC_RAD2DEG(dAzimRad);
2980 SK_SatInfo[idx].SignalToNoiseRatio = iSNR;
2983 if (m_PriN2kTalker <= 0 && talker != wxEmptyString &&
2984 (talker.StartsWith(
"G") || talker.StartsWith(
"BD"))) {
2987 SendSatInfoToAllInstruments(iNumSats, iMesNum + 1, talkerID,
2990 mSatStatus_Wdog = gps_watchdog_timeout_ticks;
2998 }
else if (update_path ==
"navigation.gnss.antennaAltitude") {
3000 double m_alt = GetJsonDouble(value);
3001 if (std::isnan(m_alt))
return;
3003 SendSentenceToAllInstruments(OCPN_DBP_STC_ALTI, m_alt,
"m");
3005 mALT_Watchdog = gps_watchdog_timeout_ticks;
3008 }
else if (update_path ==
"navigation.datetime") {
3009 if (mPriDateTime >= 1) {
3011 wxString s_dt = (value.AsString());
3012 s_dt.Replace(
'-', wxEmptyString);
3013 s_dt.Replace(
':', wxEmptyString);
3014 wxString utc_dt = s_dt.BeforeFirst(
'T');
3015 utc_dt.Append(s_dt.AfterFirst(
'T').Left(6));
3016 mUTCDateTime.ParseFormat(utc_dt.c_str(),
"%Y%m%d%H%M%S");
3017 mUTC_Watchdog = gps_watchdog_timeout_ticks;
3019 }
else if (update_path ==
"environment.outside.temperature") {
3020 if (mPriATMP >= 2) {
3021 double m_airtemp = GetJsonDouble(value);
3022 if (std::isnan(m_airtemp))
return;
3024 m_airtemp = KELVIN2C(m_airtemp);
3025 if (m_airtemp > -60 && m_airtemp < 100) {
3026 SendSentenceToAllInstruments(
3030 mATMP_Watchdog = no_nav_watchdog_timeout_ticks;
3033 }
else if (update_path ==
"environment.outside.humidity" ||
3034 update_path ==
"environment.outside.relativeHumidity") {
3036 double m_hum = GetJsonDouble(value) * 100;
3037 if (std::isnan(m_hum))
return;
3038 SendSentenceToAllInstruments(OCPN_DBP_STC_HUM, m_hum,
"%");
3040 mHUM_Watchdog = no_nav_watchdog_timeout_ticks;
3042 }
else if (update_path ==
3043 "environment.wind.directionTrue") {
3045 double m_twdT = GetJsonDouble(value);
3046 if (std::isnan(m_twdT))
return;
3048 m_twdT = GEODESIC_RAD2DEG(m_twdT);
3049 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, m_twdT,
"\u00B0");
3051 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
3053 }
else if (update_path ==
"environment.wind.directionMagnetic") {
3056 double m_twdM = GetJsonDouble(value);
3057 if (std::isnan(m_twdM))
return;
3058 m_twdM = GEODESIC_RAD2DEG(m_twdM);
3060 if (!std::isnan(mVar)) {
3061 m_twdM = (m_twdM) + mVar;
3062 if (m_twdM > 360.) {
3064 }
else if (m_twdM < 0.) {
3068 SendSentenceToAllInstruments(OCPN_DBP_STC_TWD, m_twdM,
"\u00B0");
3070 mWDN_Watchdog = no_nav_watchdog_timeout_ticks;
3072 }
else if (update_path ==
"navigation.trip.log") {
3073 double m_tlog = GetJsonDouble(value);
3074 if (std::isnan(m_tlog))
return;
3076 m_tlog = METERS2NM(m_tlog);
3077 SendSentenceToAllInstruments(
3080 mTrLOG_Watchdog = no_nav_watchdog_timeout_ticks;
3081 }
else if (update_path ==
"navigation.log" && !g_bUseInternSumLog) {
3082 double m_slog = GetJsonDouble(value);
3083 if (std::isnan(m_slog))
return;
3085 m_slog = METERS2NM(m_slog);
3086 SendSentenceToAllInstruments(
3089 mLOG_Watchdog = no_nav_watchdog_timeout_ticks;
3090 }
else if (update_path ==
"environment.outside.pressure" &&
3092 double m_press = GetJsonDouble(value);
3093 if (std::isnan(m_press))
return;
3095 m_press = PA2HPA(m_press);
3096 SendSentenceToAllInstruments(OCPN_DBP_STC_MDA, m_press,
"hPa");
3098 mMDA_Watchdog = no_nav_watchdog_timeout_ticks;
3099 }
else if (update_path ==
"navigation.attitude") {
3100 if (mPriPitchRoll >= 2) {
3101 if (value[
"roll"].AsString() !=
"0") {
3102 double m_heel = GEODESIC_RAD2DEG(value[
"roll"].AsDouble());
3103 wxString h_unit = L
"\u00B0\u003E" + _(
"Stbd");
3105 h_unit = L
"\u00B0\u003C" + _(
"Port");
3108 SendSentenceToAllInstruments(OCPN_DBP_STC_HEEL, m_heel, h_unit);
3109 mHEEL_Watchdog = gps_watchdog_timeout_ticks;
3112 if (value[
"pitch"].AsString() !=
"0") {
3113 double m_pitch = GEODESIC_RAD2DEG(value[
"pitch"].AsDouble());
3114 wxString p_unit = L
"\u00B0\u2191" + _(
"Up");
3116 p_unit = L
"\u00B0\u2193" + _(
"Down");
3119 SendSentenceToAllInstruments(OCPN_DBP_STC_PITCH, m_pitch, p_unit);
3120 mPITCH_Watchdog = gps_watchdog_timeout_ticks;
3130 if (mPriPosition >= 1) {
3132 SendSentenceToAllInstruments(OCPN_DBP_STC_LAT, pfix.
Lat,
"SDMM");
3133 SendSentenceToAllInstruments(OCPN_DBP_STC_LON, pfix.
Lon,
"SDMM");
3135 if (mPriCOGSOG >= 1) {
3136 double dMagneticCOG;
3138 SendSentenceToAllInstruments(
3142 SendSentenceToAllInstruments(OCPN_DBP_STC_COG, mCOGFilter.filter(pfix.
Cog),
3146 double logSOG = mSOGFilter.filter(pfix.
Sog);
3148 d_tripNM += logSOG / 3600;
3150 if (++logCount > 60) {
3157 dMagneticCOG = mCOGFilter.get() - pfix.
Var;
3158 if (dMagneticCOG < 0.0) dMagneticCOG = 360.0 + dMagneticCOG;
3159 if (dMagneticCOG > 360.0) dMagneticCOG = dMagneticCOG - 360.0;
3160 SendSentenceToAllInstruments(OCPN_DBP_STC_MCOG, dMagneticCOG,
"\u00B0M");
3163 if (!std::isnan(pfix.
Var)) {
3166 mVar_Watchdog = gps_watchdog_timeout_ticks;
3168 SendSentenceToAllInstruments(OCPN_DBP_STC_HMV, pfix.
Var,
"\u00B0");
3171 if (mPriDateTime >= 6) {
3176 mUTCDateTime.Set(pfix.
FixTime);
3178 mUTCDateTime = wxInvalidDateTime;
3179 if (mUTCDateTime.IsValid()) {
3181 mUTCDateTime = mUTCDateTime.ToUTC();
3182 mUTC_Watchdog = gps_watchdog_timeout_ticks;
3185 if (mPriSatUsed >= 1) {
3186 mSatsInUse = pfix.
nSats;
3187 if (mSatsInUse > 0) {
3188 SendSentenceToAllInstruments(OCPN_DBP_STC_SAT, mSatsInUse,
"");
3190 mSatsUsed_Wdog = gps_watchdog_timeout_ticks;
3193 if (mPriHeadingT >= 1) {
3194 double hdt = pfix.
Hdt;
3195 if (std::isnan(hdt))
return;
3196 SendSentenceToAllInstruments(OCPN_DBP_STC_HDT, hdt,
"\u00B0T");
3198 mHDT_Watchdog = gps_watchdog_timeout_ticks;
3200 if (mPriHeadingM >= 1) {
3201 double hdm = pfix.
Hdm;
3202 if (std::isnan(hdm) && !std::isnan(pfix.
Hdt) && !std::isnan(pfix.
Var)) {
3203 hdm = pfix.
Hdt - pfix.
Var;
3206 else if (hdm >= 360.0)
3209 if (std::isnan(hdm))
return;
3210 SendSentenceToAllInstruments(OCPN_DBP_STC_HDM, hdm,
"\u00B0M");
3212 mHDx_Watchdog = gps_watchdog_timeout_ticks;
3217 SendSentenceToAllInstruments(OCPN_DBP_STC_PLA, lat,
"SDMM");
3218 SendSentenceToAllInstruments(OCPN_DBP_STC_PLO, lon,
"SDMM");
3221void dashboard_pi::SetPluginMessage(wxString &message_id,
3222 wxString &message_body) {
3223 if (message_id ==
"WMM_VARIATION_BOAT") {
3231 int numErrors = reader.
Parse(message_body, &root);
3232 if (numErrors > 0) {
3238 wxString decl = root[
"Decl"].
AsString();
3240 decl.ToDouble(&decl_val);
3245 mVar_Watchdog = gps_watchdog_timeout_ticks;
3246 SendSentenceToAllInstruments(OCPN_DBP_STC_HMV, mVar,
"\u00B0");
3248 }
else if (message_id ==
"OCPN_CORE_SIGNALK") {
3249 ParseSignalK(message_body);
3257 parent, wxID_ANY, m_ArrayOfDashboardWindow);
3259 dialog->RecalculateSize();
3261#ifdef __OCPN__ANDROID__
3262 dialog->GetHandle()->setStyleSheet(qtStyleSheet);
3265#ifdef __OCPN__ANDROID__
3269 int xmax = ccwin->GetSize().GetWidth();
3270 int ymax = ccwin->GetParent()
3273 dialog->SetSize(xmax, ymax);
3280 if (dialog->ShowModal() == wxID_OK) {
3281 double scaler = 1.0;
3284 scaler = wxMax(1.0, scaler);
3286 g_USFontTitle = *(dialog->m_pFontPickerTitle->GetFontData());
3287 g_FontTitle = *g_pUSFontTitle;
3288 g_FontTitle.SetChosenFont(g_pUSFontTitle->GetChosenFont().Scaled(scaler));
3289 g_FontTitle.SetColour(g_pUSFontTitle->GetColour());
3290 g_USFontTitle = *g_pUSFontTitle;
3292 g_USFontData = *(dialog->m_pFontPickerData->GetFontData());
3293 g_FontData = *g_pUSFontData;
3294 g_FontData.SetChosenFont(g_pUSFontData->GetChosenFont().Scaled(scaler));
3295 g_FontData.SetColour(g_pUSFontData->GetColour());
3296 g_USFontData = *g_pUSFontData;
3298 g_USFontLabel = *(dialog->m_pFontPickerLabel->GetFontData());
3299 g_FontLabel = *g_pUSFontLabel;
3300 g_FontLabel.SetChosenFont(g_pUSFontLabel->GetChosenFont().Scaled(scaler));
3301 g_FontLabel.SetColour(g_pUSFontLabel->GetColour());
3302 g_USFontLabel = *g_pUSFontLabel;
3304 g_USFontSmall = *(dialog->m_pFontPickerSmall->GetFontData());
3305 g_FontSmall = *g_pUSFontSmall;
3306 g_FontSmall.SetChosenFont(g_pUSFontSmall->GetChosenFont().Scaled(scaler));
3307 g_FontSmall.SetColour(g_pUSFontSmall->GetColour());
3308 g_USFontSmall = *g_pUSFontSmall;
3312 g_dashPrefWidth = dialog->GetSize().x;
3313 g_dashPrefHeight = dialog->GetSize().y;
3315 dialog->SaveDashboardConfig();
3316 m_ArrayOfDashboardWindow.Clear();
3317 m_ArrayOfDashboardWindow = dialog->m_Config;
3327 aktuellColorScheme = cs;
3328 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3330 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow;
3331 if (dashboard_window) dashboard_window->SetColorScheme(cs);
3335int dashboard_pi::GetDashboardWindowShownCount() {
3338 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3340 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow;
3341 if (dashboard_window) {
3342 wxAuiPaneInfo &pane = m_pauimgr->GetPane(dashboard_window);
3343 if (pane.IsOk() && pane.IsShown()) cnt++;
3349void dashboard_pi::OnPaneClose(wxAuiManagerEvent &event) {
3353 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3358 if (dashboard_window != d_w) {
3359 wxAuiPaneInfo &pane = m_pauimgr->GetPane(d_w);
3360 if (pane.IsOk() && pane.IsShown()) cnt++;
3362 cont->m_bIsVisible =
false;
3372 int cnt = GetDashboardWindowShownCount();
3374 bool b_anyviz =
false;
3375 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3377 if (cont->m_bIsVisible) {
3383 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3386 if (dashboard_window) {
3387 wxAuiPaneInfo &pane = m_pauimgr->GetPane(dashboard_window);
3389 bool b_reset_pos =
false;
3396 RECT frame_title_rect;
3397 frame_title_rect.left = pane.floating_pos.x;
3398 frame_title_rect.top = pane.floating_pos.y;
3399 frame_title_rect.right = pane.floating_pos.x + pane.floating_size.x;
3400 frame_title_rect.bottom = pane.floating_pos.y + 30;
3402 if (NULL == MonitorFromRect(&frame_title_rect, MONITOR_DEFAULTTONULL))
3408 wxRect window_title_rect;
3409 window_title_rect.x = pane.floating_pos.x;
3410 window_title_rect.y = pane.floating_pos.y;
3411 window_title_rect.width = pane.floating_size.x;
3412 window_title_rect.height = 30;
3414 wxRect ClientRect = wxGetClientDisplayRect();
3417 if (!ClientRect.Intersects(window_title_rect)) b_reset_pos =
true;
3421 if (b_reset_pos) pane.FloatingPosition(50, 50);
3425 pane.Show(cont->m_bIsVisible);
3427 cont->m_bIsVisible = cont->m_bPersVisible;
3428 pane.Show(cont->m_bIsVisible);
3435 if (pane.IsShown() && pane.IsDocked()) {
3436 pane.BestSize(cont->m_best_size);
3437 m_pauimgr->Update();
3448 if ((pane.dock_direction == wxAUI_DOCK_BOTTOM) && pane.IsDocked())
3455 GetDashboardWindowShownCount() != 0 );
3456 m_pauimgr->Update();
3466 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3468 wxAuiPaneInfo &pane = m_pauimgr->GetPane(cont->m_pDashboardWindow);
3470 cont->m_bIsVisible = (pane.IsOk() && pane.IsShown());
3474 if (pane.IsDocked()) {
3475 if ((cont->m_persist_size.x > 50) && (cont->m_persist_size.y > 50))
3476 cont->m_pDashboardWindow->SetSize(cont->m_persist_size);
3480 if (pane.IsShown()) {
3482 m_pauimgr->Update();
3484 m_pauimgr->Update();
3488 m_pauimgr->Update();
3496bool dashboard_pi::LoadConfig(
void) {
3497 wxFileConfig *pConf = (wxFileConfig *)m_pconfig;
3500 pConf->SetPath(
"/PlugIns/Dashboard");
3503 pConf->Read(
"Version", &version, wxEmptyString);
3512#ifdef __OCPN__ANDROID__
3513 TitleFont =
"Roboto,16,-1,5,50,0,0,0,0,0";
3514 DataFont =
"Roboto,16,-1,5,50,0,0,0,0,0";
3515 LabelFont =
"Roboto,16,-1,5,50,0,0,0,0,0";
3516 SmallFont =
"Roboto,14,-1,5,50,0,0,0,0,0";
3518 TitleFont = g_pFontTitle->GetChosenFont().GetNativeFontInfoDesc();
3519 DataFont = g_pFontData->GetChosenFont().GetNativeFontInfoDesc();
3520 LabelFont = g_pFontLabel->GetChosenFont().GetNativeFontInfoDesc();
3521 SmallFont = g_pFontSmall->GetChosenFont().GetNativeFontInfoDesc();
3524 double scaler = 1.0;
3526 wxFont *pDF = &DummyFont;
3530 scaler = wxMax(1.0, scaler);
3532 g_pFontTitle = &g_FontTitle;
3533 pConf->Read(
"FontTitle", &config, TitleFont);
3534 LoadFont(&pDF, config);
3535 wxFont DummyFontTitle = *pDF;
3536 pConf->Read(
"ColorTitle", &config,
"#000000");
3537 wxColour DummyColor(config);
3538 g_pUSFontTitle->SetChosenFont(DummyFontTitle);
3539 g_pUSFontTitle->SetColour(DummyColor);
3541 g_FontTitle = *g_pUSFontTitle;
3542 g_FontTitle.SetChosenFont(g_pUSFontTitle->GetChosenFont().Scaled(scaler));
3543 g_USFontTitle = *g_pUSFontTitle;
3545 g_pFontData = &g_FontData;
3546 pConf->Read(
"FontData", &config, DataFont);
3547 LoadFont(&pDF, config);
3548 wxFont DummyFontData = *pDF;
3549 pConf->Read(
"ColorData", &config,
"#000000");
3550 DummyColor.Set(config);
3551 g_pUSFontData->SetChosenFont(DummyFontData);
3552 g_pUSFontData->SetColour(DummyColor);
3553 g_FontData = *g_pUSFontData;
3554 g_FontData.SetChosenFont(g_pUSFontData->GetChosenFont().Scaled(scaler));
3555 g_USFontData = *g_pUSFontData;
3557 pConf->Read(
"ForceBackgroundColor", &g_ForceBackgroundColor, 0);
3558 pConf->Read(
"BackgroundColor", &config,
"DASHL");
3559 g_BackgroundColor.Set(config);
3562 pConf->Read(
"TitleAlignment", &alignment, (
int)wxALIGN_LEFT);
3563 g_TitleAlignment = (wxAlignment)alignment;
3564 if (g_TitleAlignment == wxALIGN_INVALID) g_TitleAlignment = wxALIGN_LEFT;
3565 pConf->Read(
"TitleMargin", &g_iTitleMargin, 5);
3566 pConf->Read(
"DataShowUnit", &g_bShowUnit,
true);
3567 pConf->Read(
"DataAlignment", &alignment, (
int)wxALIGN_LEFT);
3568 g_DataAlignment = (wxAlignment)alignment;
3569 if (g_DataAlignment == wxALIGN_INVALID) g_DataAlignment = wxALIGN_LEFT;
3570 pConf->Read(
"DataMargin", &g_iDataMargin, 10);
3571 pConf->Read(
"InstrumentSpacing", &g_iInstrumentSpacing, 0);
3572 pConf->Read(
"TitleVerticalOffset", &g_TitleVerticalOffset, 0.0);
3574 g_pFontLabel = &g_FontLabel;
3575 pConf->Read(
"FontLabel", &config, LabelFont);
3576 LoadFont(&pDF, config);
3577 wxFont DummyFontLabel = *pDF;
3578 pConf->Read(
"ColorLabel", &config,
"#000000");
3579 DummyColor.Set(config);
3580 g_pUSFontLabel->SetChosenFont(DummyFontLabel);
3581 g_pUSFontLabel->SetColour(DummyColor);
3582 g_FontLabel = *g_pUSFontLabel;
3583 g_FontLabel.SetChosenFont(g_pUSFontLabel->GetChosenFont().Scaled(scaler));
3584 g_USFontLabel = *g_pUSFontLabel;
3586 g_pFontSmall = &g_FontSmall;
3587 pConf->Read(
"FontSmall", &config, SmallFont);
3588 LoadFont(&pDF, config);
3589 wxFont DummyFontSmall = *pDF;
3590 pConf->Read(
"ColorSmall", &config,
"#000000");
3591 DummyColor.Set(config);
3592 g_pUSFontSmall->SetChosenFont(DummyFontSmall);
3593 g_pUSFontSmall->SetColour(DummyColor);
3594 g_FontSmall = *g_pUSFontSmall;
3595 g_FontSmall.SetChosenFont(g_pUSFontSmall->GetChosenFont().Scaled(scaler));
3596 g_USFontSmall = *g_pUSFontSmall;
3598 pConf->Read(
"SpeedometerMax", &g_iDashSpeedMax, 12);
3599 pConf->Read(
"COGDamp", &g_iDashCOGDamp, 0);
3600 pConf->Read(
"SpeedUnit", &g_iDashSpeedUnit, 0);
3601 pConf->Read(
"SOGDamp", &g_iDashSOGDamp, 0);
3602 pConf->Read(
"DepthUnit", &g_iDashDepthUnit, 3);
3603 g_iDashDepthUnit = wxMax(g_iDashDepthUnit, 3);
3604 pConf->Read(
"AWADamp", &g_iDashAWADamp, 0);
3605 pConf->Read(
"AWSDamp", &g_iDashAWSDamp, 0);
3607 pConf->Read(
"DepthOffset", &g_dDashDBTOffset, 0);
3609 pConf->Read(
"DistanceUnit", &g_iDashDistanceUnit, 0);
3610 pConf->Read(
"WindSpeedUnit", &g_iDashWindSpeedUnit, 0);
3611 pConf->Read(
"UseSignKtruewind", &g_bDBtrueWindGround, 0);
3612 pConf->Read(
"UseInternSumlog", &g_bUseInternSumLog, 0);
3613 pConf->Read(
"SumLogNM", &g_dSumLogNM, 0.0);
3614 pConf->Read(
"TemperatureUnit", &g_iDashTempUnit, 0);
3616 pConf->Read(
"UTCOffset", &g_iUTCOffset, 0);
3618 pConf->Read(
"PrefWidth", &g_dashPrefWidth, 0);
3619 pConf->Read(
"PrefHeight", &g_dashPrefHeight, 0);
3622 pConf->Read(
"DashboardCount", &d_cnt, -1);
3624 m_ArrayOfDashboardWindow.Clear();
3625 if (version.IsEmpty() && d_cnt == -1) {
3626 m_config_version = 1;
3629 pConf->Read(
"InstrumentCount", &i_cnt, -1);
3631 wxArrayOfInstrumentProperties Property;
3633 for (
int i = 0; i < i_cnt; i++) {
3635 pConf->Read(wxString::Format(
"Instrument%d", i + 1), &
id, -1);
3636 if (
id != -1) ar.Add(
id);
3640#ifndef __OCPN__ANDROID__
3641 ar.Add(ID_DBP_I_POS);
3642 ar.Add(ID_DBP_D_COG);
3643 ar.Add(ID_DBP_D_GPS);
3645 ar.Add(ID_DBP_I_POS);
3646 ar.Add(ID_DBP_D_COG);
3647 ar.Add(ID_DBP_I_SOG);
3653 NULL, MakeName(), _(
"Dashboard"),
"V", ar, Property);
3654 cont->m_bPersVisible =
true;
3655 m_ArrayOfDashboardWindow.Add(cont);
3659 m_config_version = 2;
3660 bool b_onePersisted =
false;
3662 wxSize persist_size;
3663 for (
int k = 0; k < d_cnt; k++) {
3665 wxString::Format(
"/PlugIns/Dashboard/Dashboard%d", k + 1));
3667 pConf->Read(
"Name", &name, MakeName());
3669 pConf->Read(
"Caption", &caption, _(
"Dashboard"));
3671 pConf->Read(
"Orientation", &orient,
"V");
3673 pConf->Read(
"InstrumentCount", &i_cnt, -1);
3675 pConf->Read(
"Persistence", &b_persist, 1);
3677 pConf->Read(
"BestSizeX", &val, DefaultWidth);
3679 pConf->Read(
"BestSizeY", &val, DefaultWidth);
3681 pConf->Read(
"PersistSizeX", &val, DefaultWidth);
3682 persist_size.x = val;
3683 pConf->Read(
"PersistSizeY", &val, DefaultWidth);
3684 persist_size.y = val;
3687 wxArrayOfInstrumentProperties Property;
3688 for (
int i = 0; i < i_cnt; i++) {
3690 pConf->Read(wxString::Format(
"Instrument%d", i + 1), &
id, -1);
3694 if (pConf->Exists(wxString::Format(
"InstTitleFont%d", i + 1))) {
3697 pConf->Read(wxString::Format(
"InstTitleFont%d", i + 1), &config,
3699 LoadFont(&pDF, config);
3700 wxFont DummyFontTitleA = *pDF;
3701 pConf->Read(wxString::Format(
"InstTitleColor%d", i + 1), &config,
3703 DummyColor.Set(config);
3704 instp->m_USTitleFont.SetChosenFont(DummyFontTitleA);
3705 instp->m_USTitleFont.SetColour(DummyColor);
3706 instp->m_TitleFont = instp->m_USTitleFont;
3707 instp->m_TitleFont.SetChosenFont(
3708 instp->m_USTitleFont.GetChosenFont().Scaled(scaler));
3710 pConf->Read(wxString::Format(
"InstDataShowUnit%d", i + 1),
3711 &instp->m_ShowUnit, -1);
3712 pConf->Read(wxString::Format(
"InstDataMargin%d", i + 1),
3713 &instp->m_DataMargin, -1);
3714 pConf->Read(wxString::Format(
"InstDataAlignment%d", i + 1),
3715 &alignment, (
int)wxALIGN_INVALID);
3716 instp->m_DataAlignment = (wxAlignment)alignment;
3717 pConf->Read(wxString::Format(
"InstInstrumentSpacing%d", i + 1),
3718 &instp->m_InstrumentSpacing, -1);
3719 pConf->Read(wxString::Format(
"InstDataFormat%d", i + 1),
3720 &instp->m_Format,
"");
3721 pConf->Read(wxString::Format(
"InstTitle%d", i + 1),
3722 &instp->m_Title,
"");
3724 pConf->Read(wxString::Format(
"InstDataFont%d", i + 1), &config,
3726 LoadFont(&pDF, config);
3727 wxFont DummyFontDataA = *pDF;
3728 pConf->Read(wxString::Format(
"InstDataColor%d", i + 1), &config,
3730 DummyColor.Set(config);
3731 instp->m_USDataFont.SetChosenFont(DummyFontDataA);
3732 instp->m_USDataFont.SetColour(DummyColor);
3733 instp->m_DataFont = instp->m_USDataFont;
3734 instp->m_DataFont.SetChosenFont(
3735 instp->m_USDataFont.GetChosenFont().Scaled(scaler));
3737 pConf->Read(wxString::Format(
"InstLabelFont%d", i + 1), &config,
3739 LoadFont(&pDF, config);
3740 wxFont DummyFontLabelA = *pDF;
3741 pConf->Read(wxString::Format(
"InstLabelColor%d", i + 1), &config,
3743 DummyColor.Set(config);
3744 instp->m_USLabelFont.SetChosenFont(DummyFontLabelA);
3745 instp->m_USLabelFont.SetColour(DummyColor);
3746 instp->m_LabelFont = instp->m_USLabelFont;
3747 instp->m_LabelFont.SetChosenFont(
3748 instp->m_USLabelFont.GetChosenFont().Scaled(scaler));
3750 pConf->Read(wxString::Format(
"InstSmallFont%d", i + 1), &config,
3752 LoadFont(&pDF, config);
3753 wxFont DummyFontSmallA = *pDF;
3754 pConf->Read(wxString::Format(
"InstSmallColor%d", i + 1), &config,
3756 DummyColor.Set(config);
3757 instp->m_USSmallFont.SetChosenFont(DummyFontSmallA);
3758 instp->m_USSmallFont.SetColour(DummyColor);
3759 instp->m_SmallFont = instp->m_USSmallFont;
3760 instp->m_SmallFont.SetChosenFont(
3761 instp->m_USSmallFont.GetChosenFont().Scaled(scaler));
3763 pConf->Read(wxString::Format(
"TitleBackColor%d", i + 1), &config,
3765 instp->m_TitleBackgroundColour.Set(config);
3767 pConf->Read(wxString::Format(
"DataBackColor%d", i + 1), &config,
3769 instp->m_DataBackgroundColour.Set(config);
3771 pConf->Read(wxString::Format(
"ArrowFirst%d", i + 1), &config,
3773 instp->m_Arrow_First_Colour.Set(config);
3775 pConf->Read(wxString::Format(
"ArrowSecond%d", i + 1), &config,
3777 instp->m_Arrow_Second_Colour.Set(config);
3779 Property.Add(instp);
3786 NULL, name, caption, orient, ar, Property);
3787 cont->m_bPersVisible = b_persist;
3788 cont->m_conf_best_size = best_size;
3789 cont->m_persist_size = persist_size;
3791 if (b_persist) b_onePersisted =
true;
3793 m_ArrayOfDashboardWindow.Add(cont);
3797 if (m_ArrayOfDashboardWindow.Count() && !b_onePersisted) {
3799 if (cont) cont->m_bPersVisible =
true;
3808void dashboard_pi::LoadFont(wxFont **target, wxString native_info) {
3809 if (!native_info.IsEmpty()) {
3810#ifdef __OCPN__ANDROID__
3811 wxFont *nf =
new wxFont(native_info);
3814 (*target)->SetNativeFontInfo(native_info);
3819bool dashboard_pi::SaveConfig(
void) {
3820 wxFileConfig *pConf = (wxFileConfig *)m_pconfig;
3823 pConf->SetPath(
"/PlugIns/Dashboard");
3824 pConf->Write(
"Version",
"2");
3825 pConf->Write(
"FontTitle",
3826 g_pUSFontTitle->GetChosenFont().GetNativeFontInfoDesc());
3827 pConf->Write(
"ColorTitle",
3828 g_pUSFontTitle->GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3829 pConf->Write(
"FontData",
3830 g_pUSFontData->GetChosenFont().GetNativeFontInfoDesc());
3831 pConf->Write(
"ColorData",
3832 g_pUSFontData->GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3833 pConf->Write(
"FontLabel",
3834 g_pUSFontLabel->GetChosenFont().GetNativeFontInfoDesc());
3835 pConf->Write(
"ColorLabel",
3836 g_pUSFontLabel->GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3837 pConf->Write(
"FontSmall",
3838 g_pUSFontSmall->GetChosenFont().GetNativeFontInfoDesc());
3839 pConf->Write(
"ColorSmall",
3840 g_pUSFontSmall->GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3841 pConf->Write(
"SpeedometerMax", g_iDashSpeedMax);
3842 pConf->Write(
"COGDamp", g_iDashCOGDamp);
3843 pConf->Write(
"SpeedUnit", g_iDashSpeedUnit);
3844 pConf->Write(
"SOGDamp", g_iDashSOGDamp);
3845 pConf->Write(
"AWSDamp", g_iDashAWSDamp);
3846 pConf->Write(
"AWADamp", g_iDashAWADamp);
3847 pConf->Write(
"DepthUnit", g_iDashDepthUnit);
3848 pConf->Write(
"DepthOffset", g_dDashDBTOffset);
3849 pConf->Write(
"DistanceUnit", g_iDashDistanceUnit);
3850 pConf->Write(
"WindSpeedUnit", g_iDashWindSpeedUnit);
3851 pConf->Write(
"UseInternSumlog", g_bUseInternSumLog);
3852 pConf->Write(
"SumLogNM", g_dSumLogNM);
3853 pConf->Write(
"UTCOffset", g_iUTCOffset);
3854 pConf->Write(
"UseSignKtruewind", g_bDBtrueWindGround);
3855 pConf->Write(
"TemperatureUnit", g_iDashTempUnit);
3856 pConf->Write(
"PrefWidth", g_dashPrefWidth);
3857 pConf->Write(
"PrefHeight", g_dashPrefHeight);
3859 pConf->Write(
"DashboardCount", (
int)m_ArrayOfDashboardWindow.GetCount());
3861 for (
size_t i = m_ArrayOfDashboardWindow.GetCount(); i < 20; i++) {
3863 wxString::Format(
"/PlugIns/Dashboard/Dashboard%zu", i + 1))) {
3865 wxString::Format(
"/PlugIns/Dashboard/Dashboard%zu", i + 1));
3868 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3871 wxString::Format(
"/PlugIns/Dashboard/Dashboard%zu", i + 1));
3872 pConf->Write(
"Name", cont->m_sName);
3873 pConf->Write(
"Caption", cont->m_sCaption);
3874 pConf->Write(
"Orientation", cont->m_sOrientation);
3875 pConf->Write(
"Persistence", cont->m_bPersVisible);
3876 pConf->Write(
"InstrumentCount", (
int)cont->m_aInstrumentList.GetCount());
3877 pConf->Write(
"BestSizeX", cont->m_best_size.x);
3878 pConf->Write(
"BestSizeY", cont->m_best_size.y);
3879 pConf->Write(
"PersistSizeX", cont->m_pDashboardWindow->GetSize().x);
3880 pConf->Write(
"PersistSizeY", cont->m_pDashboardWindow->GetSize().y);
3883 for (
size_t i = cont->m_aInstrumentList.GetCount(); i < 40; i++) {
3884 if (pConf->Exists(wxString::Format(
"Instrument%zu", i + 1))) {
3885 pConf->DeleteEntry(wxString::Format(
"Instrument%zu", i + 1));
3886 if (pConf->Exists(wxString::Format(
"InstTitleFont%zu", i + 1))) {
3887 pConf->DeleteEntry(wxString::Format(
"InstTitleFont%zu", i + 1));
3888 pConf->DeleteEntry(wxString::Format(
"InstTitleColor%zu", i + 1));
3889 pConf->DeleteEntry(wxString::Format(
"InstTitle%zu", i + 1));
3890 pConf->DeleteEntry(wxString::Format(
"InstDataShowUnit%zu", i + 1));
3891 pConf->DeleteEntry(wxString::Format(
"InstDataMargin%zu", i + 1));
3892 pConf->DeleteEntry(wxString::Format(
"InstDataAlignment%zu", i + 1));
3893 pConf->DeleteEntry(wxString::Format(
"InstDataFormat%zu", i + 1));
3894 pConf->DeleteEntry(wxString::Format(
"InstDataFont%zu", i + 1));
3895 pConf->DeleteEntry(wxString::Format(
"InstDataColor%zu", i + 1));
3896 pConf->DeleteEntry(wxString::Format(
"InstLabelFont%zu", i + 1));
3897 pConf->DeleteEntry(wxString::Format(
"InstLabelColor%zu", i + 1));
3898 pConf->DeleteEntry(wxString::Format(
"InstSmallFont%zu", i + 1));
3899 pConf->DeleteEntry(wxString::Format(
"InstSmallColor%zu", i + 1));
3900 pConf->DeleteEntry(wxString::Format(
"TitleBackColor%zu", i + 1));
3901 pConf->DeleteEntry(wxString::Format(
"DataBackColor%zu", i + 1));
3902 pConf->DeleteEntry(wxString::Format(
"ArrowFirst%zu", i + 1));
3903 pConf->DeleteEntry(wxString::Format(
"ArrowSecond%zu", i + 1));
3907 for (
size_t j = 0; j < cont->m_aInstrumentList.GetCount(); j++) {
3908 pConf->Write(wxString::Format(
"Instrument%zu", j + 1),
3909 cont->m_aInstrumentList.Item(j));
3912 if (pConf->Exists(wxString::Format(
"InstTitleFont%zu", j + 1))) {
3914 for (
size_t i = 0; i < cont->m_aInstrumentPropertyList.GetCount();
3916 Inst = cont->m_aInstrumentPropertyList.Item(i);
3917 if (Inst->m_Listplace == (
int)j) {
3923 pConf->DeleteEntry(wxString::Format(
"InstTitleFont%zu", j + 1));
3924 pConf->DeleteEntry(wxString::Format(
"InstTitleColor%zu", j + 1));
3925 pConf->DeleteEntry(wxString::Format(
"InstTitle%zu", j + 1));
3926 pConf->DeleteEntry(wxString::Format(
"InstDataShowUnit%zu", i + 1));
3927 pConf->DeleteEntry(wxString::Format(
"InstDataMargin%zu", i + 1));
3928 pConf->DeleteEntry(wxString::Format(
"InstDataAlignment%zu", i + 1));
3929 pConf->DeleteEntry(wxString::Format(
"InstDataFormat%zu", i + 1));
3930 pConf->DeleteEntry(wxString::Format(
"InstDataFont%zu", j + 1));
3931 pConf->DeleteEntry(wxString::Format(
"InstDataColor%zu", j + 1));
3932 pConf->DeleteEntry(wxString::Format(
"InstLabelFont%zu", j + 1));
3933 pConf->DeleteEntry(wxString::Format(
"InstLabelColor%zu", j + 1));
3934 pConf->DeleteEntry(wxString::Format(
"InstSmallFont%zu", j + 1));
3935 pConf->DeleteEntry(wxString::Format(
"InstSmallColor%zu", j + 1));
3936 pConf->DeleteEntry(wxString::Format(
"TitleBackColor%zu", i + 1));
3937 pConf->DeleteEntry(wxString::Format(
"DataBackColor%zu", i + 1));
3938 pConf->DeleteEntry(wxString::Format(
"ArrowFirst%zu", i + 1));
3939 pConf->DeleteEntry(wxString::Format(
"ArrowSecond%zu", i + 1));
3943 for (
size_t i = 0; i < (cont->m_aInstrumentPropertyList.GetCount());
3945 Inst = cont->m_aInstrumentPropertyList.Item(i);
3946 if (Inst->m_Listplace == (
int)j) {
3948 wxString::Format(
"InstTitleFont%zu", j + 1),
3949 Inst->m_USTitleFont.GetChosenFont().GetNativeFontInfoDesc());
3951 wxString::Format(
"InstTitleColor%zu", j + 1),
3952 Inst->m_USTitleFont.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3954 wxString::Format(
"InstDataFont%zu", j + 1),
3955 Inst->m_USDataFont.GetChosenFont().GetNativeFontInfoDesc());
3957 wxString::Format(
"InstDataColor%zu", j + 1),
3958 Inst->m_USDataFont.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3960 wxString::Format(
"InstLabelFont%zu", j + 1),
3961 Inst->m_USLabelFont.GetChosenFont().GetNativeFontInfoDesc());
3963 wxString::Format(
"InstLabelColor%zu", j + 1),
3964 Inst->m_USLabelFont.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3966 wxString::Format(
"InstSmallFont%zu", j + 1),
3967 Inst->m_USSmallFont.GetChosenFont().GetNativeFontInfoDesc());
3969 wxString::Format(
"InstSmallColor%zu", j + 1),
3970 Inst->m_USSmallFont.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3972 wxString::Format(
"TitleBackColor%zu", j + 1),
3973 Inst->m_TitleBackgroundColour.GetAsString(wxC2S_HTML_SYNTAX));
3975 wxString::Format(
"DataBackColor%zu", j + 1),
3976 Inst->m_DataBackgroundColour.GetAsString(wxC2S_HTML_SYNTAX));
3978 wxString::Format(
"ArrowFirst%zu", j + 1),
3979 Inst->m_Arrow_First_Colour.GetAsString(wxC2S_HTML_SYNTAX));
3981 wxString::Format(
"ArrowSecond%zu", j + 1),
3982 Inst->m_Arrow_Second_Colour.GetAsString(wxC2S_HTML_SYNTAX));
3994void dashboard_pi::ApplyConfig(
void) {
3996 for (
size_t i = m_ArrayOfDashboardWindow.GetCount(); i > 0; i--) {
3998 int orient = (cont->m_sOrientation ==
"V" ? wxVERTICAL : wxHORIZONTAL);
3999 if (cont->m_bIsDeleted) {
4000 if (cont->m_pDashboardWindow) {
4001 m_pauimgr->DetachPane(cont->m_pDashboardWindow);
4002 cont->m_pDashboardWindow->Close();
4003 cont->m_pDashboardWindow->Destroy();
4004 cont->m_pDashboardWindow = NULL;
4006 m_ArrayOfDashboardWindow.Remove(cont);
4009 }
else if (!cont->m_pDashboardWindow) {
4013 cont->m_pDashboardWindow->SetInstrumentList(
4014 cont->m_aInstrumentList, &(cont->m_aInstrumentPropertyList));
4015 bool vertical = orient == wxVERTICAL;
4016 wxSize sz = cont->m_pDashboardWindow->GetMinSize();
4017 wxSize best = cont->m_conf_best_size;
4018 if (best.x < 100) best = sz;
4022 if (sz.x == 0) sz.IncTo(wxSize(160, 388));
4024 wxAuiPaneInfo p = wxAuiPaneInfo()
4025 .Name(cont->m_sName)
4026 .Caption(cont->m_sCaption)
4027 .CaptionVisible(
false)
4028 .TopDockable(!vertical)
4029 .BottomDockable(!vertical)
4030 .LeftDockable(vertical)
4031 .RightDockable(vertical)
4035 .FloatingPosition(100, 100)
4037 .Show(cont->m_bIsVisible)
4040 m_pauimgr->AddPane(cont->m_pDashboardWindow, p);
4047#ifdef __OCPN__ANDROID__
4048 wxAuiPaneInfo &pane = m_pauimgr->GetPane(cont->m_pDashboardWindow);
4049 pane.Dockable(
false);
4054 wxAuiPaneInfo &pane = m_pauimgr->GetPane(cont->m_pDashboardWindow);
4055 pane.Caption(cont->m_sCaption).Show(cont->m_bIsVisible);
4056 if (!cont->m_pDashboardWindow->isInstrumentListEqual(
4057 cont->m_aInstrumentList)) {
4058 cont->m_pDashboardWindow->SetInstrumentList(
4059 cont->m_aInstrumentList, &(cont->m_aInstrumentPropertyList));
4060 wxSize sz = cont->m_pDashboardWindow->GetMinSize();
4061 pane.MinSize(sz).BestSize(sz).FloatingSize(sz);
4063 if (cont->m_pDashboardWindow->GetSizerOrientation() != orient) {
4064 cont->m_pDashboardWindow->ChangePaneOrientation(orient,
false);
4068 m_pauimgr->Update();
4071 double sogFC = g_iDashSOGDamp ? 1.0 / (2.0 * g_iDashSOGDamp) : 0.0;
4072 double cogFC = g_iDashCOGDamp ? 1.0 / (2.0 * g_iDashCOGDamp) : 0.0;
4073 double awaFC = g_iDashAWADamp ? 1.0 / (2.0 * g_iDashAWADamp) : 0.0;
4074 double awsFC = g_iDashAWSDamp ? 1.0 / (2.0 * g_iDashAWSDamp) : 0.0;
4076 if (abs(sogFC - mSOGFilter.getFc()) > 1e-6) {
4077 mSOGFilter.setFC(sogFC);
4079 if (abs(cogFC - mCOGFilter.getFc()) > 1e-6) {
4080 mCOGFilter.setFC(cogFC);
4082 if (abs(awaFC - mAWAFilter.getFc()) > 1e-6) {
4083 mAWAFilter.setFC(awaFC);
4085 if (abs(awsFC - mAWSFilter.getFc()) > 1e-6) {
4086 mAWSFilter.setFC(awsFC);
4090void dashboard_pi::PopulateContextMenu(wxMenu *menu) {
4092 wxMenuItem *visItem = 0;
4093 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
4095 wxMenuItem *item = menu->AppendCheckItem(i + 1, cont->m_sCaption);
4096 item->Check(cont->m_bIsVisible);
4097 if (cont->m_bIsVisible) {
4102 if (nvis == 1 && visItem) visItem->Enable(
false);
4105void dashboard_pi::ShowDashboard(
size_t id,
bool visible) {
4106 if (
id < m_ArrayOfDashboardWindow.GetCount()) {
4108 m_pauimgr->GetPane(cont->m_pDashboardWindow).Show(visible);
4109 cont->m_bIsVisible = visible;
4110 cont->m_bPersVisible = visible;
4111 m_pauimgr->Update();
4119DashboardPreferencesDialog::DashboardPreferencesDialog(
4120 wxWindow *parent, wxWindowID
id, wxArrayOfDashboard config)
4121 : wxDialog(parent, id, _(
"Dashboard preferences"), wxDefaultPosition,
4122 wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
4128 int display_width, display_height;
4129 wxDisplaySize(&display_width, &display_height);
4132 wxFileName::GetPathSeparator() +
"dashboard_pi" +
4133 wxFileName::GetPathSeparator() +
"data" +
4134 wxFileName::GetPathSeparator();
4136 Connect(wxEVT_CLOSE_WINDOW,
4137 wxCloseEventHandler(DashboardPreferencesDialog::OnCloseDialog), NULL,
4141 m_Config = wxArrayOfDashboard(config);
4143 int border_size = 2;
4145 wxBoxSizer *itemBoxSizerMainPanel =
new wxBoxSizer(wxVERTICAL);
4146 SetSizer(itemBoxSizerMainPanel);
4148 wxWindow *dparent =
this;
4149 wxScrolledWindow *scrollWin =
new wxScrolledWindow(
4150 this, wxID_ANY, wxDefaultPosition, wxSize(-1, -1), wxVSCROLL | wxHSCROLL);
4152 scrollWin->SetScrollRate(1, 1);
4153 itemBoxSizerMainPanel->Add(scrollWin, 1, wxEXPAND | wxALL, 0);
4155 dparent = scrollWin;
4157 wxBoxSizer *itemBoxSizer2 =
new wxBoxSizer(wxVERTICAL);
4158 scrollWin->SetSizer(itemBoxSizer2);
4160 auto *DialogButtonSizer =
new wxStdDialogButtonSizer();
4161 DialogButtonSizer->AddButton(
new wxButton(
this, wxID_OK));
4162 DialogButtonSizer->AddButton(
new wxButton(
this, wxID_CANCEL));
4163 wxButton *help_btn =
new wxButton(
this, wxID_HELP);
4164 help_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [&](wxCommandEvent) {
4166 Manual(
this, datadir.ToStdString()).Launch(
"Dashboard");
4168 DialogButtonSizer->AddButton(help_btn);
4169 DialogButtonSizer->Realize();
4171 itemBoxSizerMainPanel->Add(DialogButtonSizer, 0, wxALIGN_RIGHT | wxALL, 5);
4173 wxNotebook *itemNotebook =
new wxNotebook(
4174 dparent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP);
4175 itemBoxSizer2->Add(itemNotebook, 0, wxALL | wxEXPAND, border_size);
4177 wxPanel *itemPanelNotebook01 =
4178 new wxPanel(itemNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
4180 wxFlexGridSizer *itemFlexGridSizer01 =
new wxFlexGridSizer(2);
4181 itemFlexGridSizer01->AddGrowableCol(1);
4182 itemPanelNotebook01->SetSizer(itemFlexGridSizer01);
4183 itemNotebook->AddPage(itemPanelNotebook01, _(
"Dashboard"));
4185 wxBoxSizer *itemBoxSizer01 =
new wxBoxSizer(wxVERTICAL);
4186 itemFlexGridSizer01->Add(itemBoxSizer01, 1, wxEXPAND | wxTOP | wxLEFT,
4190 int imageRefSize = GetCharWidth() * 4;
4192 wxImageList *imglist1 =
new wxImageList(imageRefSize, imageRefSize,
true, 1);
4194 wxBitmap bmDashBoard;
4196 wxString filename = shareLocn +
"Dashboard.svg";
4199 wxImage dash1 = wxBitmap(*_img_dashboard_pi).ConvertToImage();
4201 dash1.Scale(imageRefSize, imageRefSize, wxIMAGE_QUALITY_HIGH);
4202 bmDashBoard = wxBitmap(dash1s);
4205 imglist1->Add(bmDashBoard);
4207 m_pListCtrlDashboards =
4208 new wxListCtrl(itemPanelNotebook01, wxID_ANY, wxDefaultPosition,
4209 wxSize(imageRefSize * 3 / 2, 200),
4210 wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL);
4212 m_pListCtrlDashboards->AssignImageList(imglist1, wxIMAGE_LIST_SMALL);
4213 m_pListCtrlDashboards->InsertColumn(0,
"");
4214 m_pListCtrlDashboards->Connect(
4215 wxEVT_COMMAND_LIST_ITEM_SELECTED,
4216 wxListEventHandler(DashboardPreferencesDialog::OnDashboardSelected), NULL,
4218 m_pListCtrlDashboards->Connect(
4219 wxEVT_COMMAND_LIST_ITEM_DESELECTED,
4220 wxListEventHandler(DashboardPreferencesDialog::OnDashboardSelected), NULL,
4222 itemBoxSizer01->Add(m_pListCtrlDashboards, 1, wxEXPAND, 0);
4224 wxBoxSizer *itemBoxSizer02 =
new wxBoxSizer(wxHORIZONTAL);
4225 itemBoxSizer01->Add(itemBoxSizer02);
4227 wxBitmap bmPlus, bmMinus;
4228 int bmSize = imageRefSize * 100 / 275;
4230#ifdef __OCPN__ANDROID__
4231 bmSize = imageRefSize / 2;
4238 wxImage plus1 = wxBitmap(*_img_plus).ConvertToImage();
4239 wxImage plus1s = plus1.Scale(bmSize, bmSize, wxIMAGE_QUALITY_HIGH);
4240 bmPlus = wxBitmap(plus1s);
4242 wxImage minus1 = wxBitmap(*_img_minus).ConvertToImage();
4243 wxImage minus1s = minus1.Scale(bmSize, bmSize, wxIMAGE_QUALITY_HIGH);
4244 bmMinus = wxBitmap(minus1s);
4247 m_pButtonAddDashboard =
new wxBitmapButton(
4248 itemPanelNotebook01, wxID_ANY, bmPlus, wxDefaultPosition, wxDefaultSize);
4249 itemBoxSizer02->Add(m_pButtonAddDashboard, 0, wxALIGN_CENTER, 2);
4250 m_pButtonAddDashboard->Connect(
4251 wxEVT_COMMAND_BUTTON_CLICKED,
4252 wxCommandEventHandler(DashboardPreferencesDialog::OnDashboardAdd), NULL,
4255 m_pButtonDeleteDashboard =
new wxBitmapButton(
4256 itemPanelNotebook01, wxID_ANY, bmMinus, wxDefaultPosition, wxDefaultSize);
4257 itemBoxSizer02->Add(m_pButtonDeleteDashboard, 0, wxALIGN_CENTER, 2);
4258 m_pButtonDeleteDashboard->Connect(
4259 wxEVT_COMMAND_BUTTON_CLICKED,
4260 wxCommandEventHandler(DashboardPreferencesDialog::OnDashboardDelete),
4264 new wxPanel(itemPanelNotebook01, wxID_ANY, wxDefaultPosition,
4265 wxDefaultSize, wxBORDER_SUNKEN);
4266 itemFlexGridSizer01->Add(m_pPanelDashboard, 1, wxEXPAND | wxTOP | wxRIGHT,
4269 wxBoxSizer *itemBoxSizer03 =
new wxBoxSizer(wxVERTICAL);
4270 m_pPanelDashboard->SetSizer(itemBoxSizer03);
4272 wxStaticBox *itemStaticBox02 =
4273 new wxStaticBox(m_pPanelDashboard, wxID_ANY, _(
"Dashboard"));
4274 wxStaticBoxSizer *itemStaticBoxSizer02 =
4275 new wxStaticBoxSizer(itemStaticBox02, wxHORIZONTAL);
4276 itemBoxSizer03->Add(itemStaticBoxSizer02, 0, wxEXPAND | wxALL, border_size);
4277 wxFlexGridSizer *itemFlexGridSizer =
new wxFlexGridSizer(2);
4278 itemFlexGridSizer->AddGrowableCol(1);
4279 itemStaticBoxSizer02->Add(itemFlexGridSizer, 1, wxEXPAND | wxALL, 0);
4281 m_pCheckBoxIsVisible =
4282 new wxCheckBox(m_pPanelDashboard, wxID_ANY, _(
"show this dashboard"),
4283 wxDefaultPosition, wxDefaultSize, 0);
4284 m_pCheckBoxIsVisible->SetMinSize(wxSize(25 * GetCharWidth(), -1));
4286 itemFlexGridSizer->Add(m_pCheckBoxIsVisible, 0, wxEXPAND | wxALL,
4288 wxStaticText *itemDummy01 =
new wxStaticText(m_pPanelDashboard, wxID_ANY,
"");
4289 itemFlexGridSizer->Add(itemDummy01, 0, wxEXPAND | wxALL, border_size);
4291 wxStaticText *itemStaticText01 =
4292 new wxStaticText(m_pPanelDashboard, wxID_ANY, _(
"Caption:"),
4293 wxDefaultPosition, wxDefaultSize, 0);
4294 itemFlexGridSizer->Add(itemStaticText01, 0, wxEXPAND | wxALL, border_size);
4295 m_pTextCtrlCaption =
new wxTextCtrl(m_pPanelDashboard, wxID_ANY,
"",
4296 wxDefaultPosition, wxDefaultSize);
4297 m_pCheckBoxIsVisible->SetMinSize(wxSize(30 * GetCharWidth(), -1));
4298 itemFlexGridSizer->Add(m_pTextCtrlCaption, 0, wxALIGN_RIGHT | wxALL,
4301 wxStaticText *itemStaticText02 =
4302 new wxStaticText(m_pPanelDashboard, wxID_ANY, _(
"Orientation:"),
4303 wxDefaultPosition, wxDefaultSize, 0);
4304 itemFlexGridSizer->Add(itemStaticText02, 0, wxEXPAND | wxALL, border_size);
4305 m_pChoiceOrientation =
new wxChoice(m_pPanelDashboard, wxID_ANY,
4306 wxDefaultPosition, wxDefaultSize);
4307 m_pChoiceOrientation->SetMinSize(wxSize(15 * GetCharWidth(), -1));
4308 m_pChoiceOrientation->Append(_(
"Vertical"));
4309 m_pChoiceOrientation->Append(_(
"Horizontal"));
4310 itemFlexGridSizer->Add(m_pChoiceOrientation, 0, wxALIGN_RIGHT | wxALL,
4315 wxImageList *imglist =
4316 new wxImageList(instImageRefSize, instImageRefSize,
true, 2);
4318 wxBitmap bmDial, bmInst;
4325 wxImage dial1 = wxBitmap(*_img_dial).ConvertToImage();
4327 dial1.Scale(instImageRefSize, instImageRefSize, wxIMAGE_QUALITY_HIGH);
4328 bmDial = wxBitmap(dial1);
4330 wxImage inst1 = wxBitmap(*_img_instrument).ConvertToImage();
4332 inst1.Scale(instImageRefSize, instImageRefSize, wxIMAGE_QUALITY_HIGH);
4333 bmInst = wxBitmap(inst1s);
4336 imglist->Add(bmInst);
4337 imglist->Add(bmDial);
4339 wxStaticBox *itemStaticBox03 =
4340 new wxStaticBox(m_pPanelDashboard, wxID_ANY, _(
"Instruments"));
4341 wxStaticBoxSizer *itemStaticBoxSizer03 =
4342 new wxStaticBoxSizer(itemStaticBox03, wxHORIZONTAL);
4343 itemBoxSizer03->Add(itemStaticBoxSizer03, 1, wxEXPAND | wxALL, border_size);
4346 wxSize list_size = wxSize(-1, dsize.y * 35 / 100);
4349 int xsize = GetCharWidth() * 30;
4350 list_size = wxSize(xsize, dsize.y * 50 / 100);
4353 m_pListCtrlInstruments =
4354 new wxListCtrl(m_pPanelDashboard, wxID_ANY, wxDefaultPosition, list_size,
4355 wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL);
4357 itemStaticBoxSizer03->Add(m_pListCtrlInstruments, 1, wxEXPAND | wxALL,
4359 m_pListCtrlInstruments->AssignImageList(imglist, wxIMAGE_LIST_SMALL);
4360 m_pListCtrlInstruments->InsertColumn(0, _(
"Instruments"));
4361 m_pListCtrlInstruments->Connect(
4362 wxEVT_COMMAND_LIST_ITEM_SELECTED,
4363 wxListEventHandler(DashboardPreferencesDialog::OnInstrumentSelected),
4365 m_pListCtrlInstruments->Connect(
4366 wxEVT_COMMAND_LIST_ITEM_DESELECTED,
4367 wxListEventHandler(DashboardPreferencesDialog::OnInstrumentSelected),
4370 wxBoxSizer *itemBoxSizer04 =
new wxBoxSizer(wxVERTICAL);
4371 itemStaticBoxSizer03->Add(itemBoxSizer04, 0, wxALIGN_TOP | wxALL,
4373 m_pButtonAdd =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Add"),
4374 wxDefaultPosition, wxSize(-1, -1));
4375 itemBoxSizer04->Add(m_pButtonAdd, 0, wxEXPAND | wxALL, border_size);
4376 m_pButtonAdd->Connect(
4377 wxEVT_COMMAND_BUTTON_CLICKED,
4378 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentAdd), NULL,
4382 m_pButtonEdit =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Edit"),
4383 wxDefaultPosition, wxDefaultSize);
4384 itemBoxSizer04->Add(m_pButtonEdit, 0, wxEXPAND | wxALL, border_size);
4385 m_pButtonEdit->Connect(
4386 wxEVT_COMMAND_BUTTON_CLICKED,
4387 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentEdit), NULL,
4398 m_pButtonDelete =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Delete"),
4399 wxDefaultPosition, wxSize(-1, -1));
4400 itemBoxSizer04->Add(m_pButtonDelete, 0, wxEXPAND | wxALL, border_size);
4401 m_pButtonDelete->Connect(
4402 wxEVT_COMMAND_BUTTON_CLICKED,
4403 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentDelete),
4405 itemBoxSizer04->AddSpacer(10);
4406 m_pButtonUp =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Up"),
4407 wxDefaultPosition, wxDefaultSize);
4408 itemBoxSizer04->Add(m_pButtonUp, 0, wxEXPAND | wxALL, border_size);
4409 m_pButtonUp->Connect(
4410 wxEVT_COMMAND_BUTTON_CLICKED,
4411 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentUp), NULL,
4413 m_pButtonDown =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Down"),
4414 wxDefaultPosition, wxDefaultSize);
4415 itemBoxSizer04->Add(m_pButtonDown, 0, wxEXPAND | wxALL, border_size);
4416 m_pButtonDown->Connect(
4417 wxEVT_COMMAND_BUTTON_CLICKED,
4418 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentDown), NULL,
4421 wxPanel *itemPanelNotebook02 =
4422 new wxPanel(itemNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
4424 wxBoxSizer *itemBoxSizer05 =
new wxBoxSizer(wxVERTICAL);
4425 itemPanelNotebook02->SetSizer(itemBoxSizer05);
4426 itemNotebook->AddPage(itemPanelNotebook02, _(
"Appearance"));
4428 wxStaticBox *itemStaticBox01 =
4429 new wxStaticBox(itemPanelNotebook02, wxID_ANY, _(
"Fonts"));
4430 wxStaticBoxSizer *itemStaticBoxSizer01 =
4431 new wxStaticBoxSizer(itemStaticBox01, wxHORIZONTAL);
4432 itemBoxSizer05->Add(itemStaticBoxSizer01, 0, wxEXPAND | wxALL, border_size);
4433 wxFlexGridSizer *itemFlexGridSizer03 =
new wxFlexGridSizer(2);
4434 itemFlexGridSizer03->AddGrowableCol(1);
4435 itemStaticBoxSizer01->Add(itemFlexGridSizer03, 1, wxEXPAND | wxALL, 0);
4437 wxStaticText *itemStaticText04 =
4438 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Title:"),
4439 wxDefaultPosition, wxDefaultSize, 0);
4440 itemFlexGridSizer03->Add(itemStaticText04, 0, wxEXPAND | wxALL, border_size);
4442 m_pFontPickerTitle =
4443 new wxFontPickerCtrl(itemPanelNotebook02, wxID_ANY, g_USFontTitle,
4444 wxDefaultPosition, wxDefaultSize);
4445 itemFlexGridSizer03->Add(m_pFontPickerTitle, 0, wxALIGN_RIGHT | wxALL, 0);
4447 wxStaticText *itemStaticText05 =
4448 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Data:"),
4449 wxDefaultPosition, wxDefaultSize, 0);
4450 itemFlexGridSizer03->Add(itemStaticText05, 0, wxEXPAND | wxALL, border_size);
4452 new wxFontPickerCtrl(itemPanelNotebook02, wxID_ANY, g_USFontData,
4453 wxDefaultPosition, wxDefaultSize);
4454 itemFlexGridSizer03->Add(m_pFontPickerData, 0, wxALIGN_RIGHT | wxALL, 0);
4456 wxStaticText *itemStaticText06 =
4457 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Label:"),
4458 wxDefaultPosition, wxDefaultSize, 0);
4459 itemFlexGridSizer03->Add(itemStaticText06, 0, wxEXPAND | wxALL, border_size);
4460 m_pFontPickerLabel =
4461 new wxFontPickerCtrl(itemPanelNotebook02, wxID_ANY, g_USFontLabel,
4462 wxDefaultPosition, wxDefaultSize);
4463 itemFlexGridSizer03->Add(m_pFontPickerLabel, 0, wxALIGN_RIGHT | wxALL, 0);
4465 wxStaticText *itemStaticText07 =
4466 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Small:"),
4467 wxDefaultPosition, wxDefaultSize, 0);
4468 itemFlexGridSizer03->Add(itemStaticText07, 0, wxEXPAND | wxALL, border_size);
4469 m_pFontPickerSmall =
4470 new wxFontPickerCtrl(itemPanelNotebook02, wxID_ANY, g_USFontSmall,
4471 wxDefaultPosition, wxDefaultSize);
4472 itemFlexGridSizer03->Add(m_pFontPickerSmall, 0, wxALIGN_RIGHT | wxALL, 0);
4475 wxStaticText *itemStaticText80 =
4476 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Reset:"),
4477 wxDefaultPosition, wxDefaultSize, 0);
4478 itemFlexGridSizer03->Add(itemStaticText80, 0, wxEXPAND | wxALL, border_size);
4480 m_pButtondefaultFont =
new wxButton(itemPanelNotebook02, wxID_ANY,
4481 _(
"Set dashboard default fonts"),
4482 wxDefaultPosition, wxSize(-1, -1));
4483 itemFlexGridSizer03->Add(m_pButtondefaultFont, 0, wxALIGN_RIGHT | wxALL, 0);
4484 m_pButtondefaultFont->Connect(
4485 wxEVT_COMMAND_BUTTON_CLICKED,
4486 wxCommandEventHandler(DashboardPreferencesDialog::OnDashboarddefaultFont),
4489 wxStaticBox *itemStaticBox04 =
new wxStaticBox(itemPanelNotebook02, wxID_ANY,
4490 _(
"Units, Ranges, Formats"));
4491 wxStaticBoxSizer *itemStaticBoxSizer04 =
4492 new wxStaticBoxSizer(itemStaticBox04, wxHORIZONTAL);
4493 itemBoxSizer05->Add(itemStaticBoxSizer04, 0, wxEXPAND | wxALL, border_size);
4494 wxFlexGridSizer *itemFlexGridSizer04 =
new wxFlexGridSizer(2);
4495 itemFlexGridSizer04->AddGrowableCol(1);
4496 itemStaticBoxSizer04->Add(itemFlexGridSizer04, 1, wxEXPAND | wxALL, 0);
4497 wxStaticText *itemStaticText08 =
new wxStaticText(
4498 itemPanelNotebook02, wxID_ANY, _(
"Speedometer max value:"),
4499 wxDefaultPosition, wxDefaultSize, 0);
4500 itemFlexGridSizer04->Add(itemStaticText08, 0, wxEXPAND | wxALL, border_size);
4501 m_pSpinSpeedMax =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4502 wxDefaultPosition, wxDefaultSize,
4503 wxSP_ARROW_KEYS, 10, 100, g_iDashSpeedMax);
4504 itemFlexGridSizer04->Add(m_pSpinSpeedMax, 0, wxALIGN_RIGHT | wxALL, 0);
4506 wxStaticText *itemStaticText10 =
new wxStaticText(
4507 itemPanelNotebook02, wxID_ANY, _(
"Speed Over Ground Damping Factor:"),
4508 wxDefaultPosition, wxDefaultSize, 0);
4509 itemFlexGridSizer04->Add(itemStaticText10, 0, wxEXPAND | wxALL, border_size);
4510 m_pSpinSOGDamp =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4511 wxDefaultPosition, wxDefaultSize,
4512 wxSP_ARROW_KEYS, 0, 100, g_iDashSOGDamp);
4513 itemFlexGridSizer04->Add(m_pSpinSOGDamp, 0, wxALIGN_RIGHT | wxALL, 0);
4515 wxStaticText *itemStaticText11 =
4516 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"COG Damping Factor:"),
4517 wxDefaultPosition, wxDefaultSize, 0);
4518 itemFlexGridSizer04->Add(itemStaticText11, 0, wxEXPAND | wxALL, border_size);
4519 m_pSpinCOGDamp =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4520 wxDefaultPosition, wxDefaultSize,
4521 wxSP_ARROW_KEYS, 0, 100, g_iDashCOGDamp);
4522 itemFlexGridSizer04->Add(m_pSpinCOGDamp, 0, wxALIGN_RIGHT | wxALL, 0);
4524 wxStaticText *itemStaticText13 =
new wxStaticText(
4525 itemPanelNotebook02, wxID_ANY, _(
"Wind speed Damping Factor:"),
4526 wxDefaultPosition, wxDefaultSize, 0);
4527 itemFlexGridSizer04->Add(itemStaticText13, 0, wxEXPAND | wxALL, border_size);
4528 m_pSpinAWSDamp =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4529 wxDefaultPosition, wxDefaultSize,
4530 wxSP_ARROW_KEYS, 0, 100, g_iDashAWSDamp);
4531 itemFlexGridSizer04->Add(m_pSpinAWSDamp, 0, wxALIGN_RIGHT | wxALL, 0);
4533 wxStaticText *itemStaticText14 =
new wxStaticText(
4534 itemPanelNotebook02, wxID_ANY, _(
"Wind angle Damping Factor:"),
4535 wxDefaultPosition, wxDefaultSize, 0);
4536 itemFlexGridSizer04->Add(itemStaticText14, 0, wxEXPAND | wxALL, border_size);
4537 m_pSpinAWADamp =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4538 wxDefaultPosition, wxDefaultSize,
4539 wxSP_ARROW_KEYS, 0, 100, g_iDashAWADamp);
4540 itemFlexGridSizer04->Add(m_pSpinAWADamp, 0, wxALIGN_RIGHT | wxALL, 0);
4542 wxStaticText *itemStaticText12 =
new wxStaticText(
4543 itemPanelNotebook02, wxID_ANY, _(
"Local Time Offset From UTC:"),
4544 wxDefaultPosition, wxDefaultSize, 0);
4545 itemFlexGridSizer04->Add(itemStaticText12, 0, wxEXPAND | wxALL, border_size);
4546 wxString m_UTCOffsetChoices[] = {
4547 "-12:00",
"-11:30",
"-11:00",
"-10:30",
"-10:00",
"-09:30",
"-09:00",
4548 "-08:30",
"-08:00",
"-07:30",
"-07:00",
"-06:30",
"-06:00",
"-05:30",
4549 "-05:00",
"-04:30",
"-04:00",
"-03:30",
"-03:00",
"-02:30",
"-02:00",
4550 "-01:30",
"-01:00",
"-00:30",
" 00:00",
" 00:30",
" 01:00",
" 01:30",
4551 " 02:00",
" 02:30",
" 03:00",
" 03:30",
" 04:00",
" 04:30",
" 05:00",
4552 " 05:30",
" 06:00",
" 06:30",
" 07:00",
" 07:30",
" 08:00",
" 08:30",
4553 " 09:00",
" 09:30",
" 10:00",
" 10:30",
" 11:00",
" 11:30",
" 12:00"};
4554 int m_UTCOffsetNChoices =
sizeof(m_UTCOffsetChoices) /
sizeof(wxString);
4555 m_pChoiceUTCOffset =
4556 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition,
4557 wxDefaultSize, m_UTCOffsetNChoices, m_UTCOffsetChoices, 0);
4558 m_pChoiceUTCOffset->SetSelection(g_iUTCOffset + 24);
4559 itemFlexGridSizer04->Add(m_pChoiceUTCOffset, 0, wxALIGN_RIGHT | wxALL, 0);
4561 wxStaticText *itemStaticText09 =
4562 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Boat speed units:"),
4563 wxDefaultPosition, wxDefaultSize, 0);
4564 itemFlexGridSizer04->Add(itemStaticText09, 0, wxEXPAND | wxALL, border_size);
4565 wxString m_SpeedUnitChoices[] = {_(
"Honor OpenCPN settings"), _(
"Kts"),
4566 _(
"mph"), _(
"km/h"), _(
"m/s")};
4567 int m_SpeedUnitNChoices =
sizeof(m_SpeedUnitChoices) /
sizeof(wxString);
4568 wxSize szSpeedUnit = wxDefaultSize;
4569 m_pChoiceSpeedUnit =
4570 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition,
4571 szSpeedUnit, m_SpeedUnitNChoices, m_SpeedUnitChoices, 0);
4572 for (
auto const &iUnit : m_SpeedUnitChoices) {
4573 szSpeedUnit.IncTo(m_pChoiceSpeedUnit->GetTextExtent(iUnit));
4575 m_pChoiceSpeedUnit->SetSize(szSpeedUnit);
4576 m_pChoiceSpeedUnit->SetSelection(g_iDashSpeedUnit + 1);
4577 itemFlexGridSizer04->Add(m_pChoiceSpeedUnit, 0, wxALIGN_RIGHT | wxALL, 0);
4579 wxStaticText *itemStaticTextDepthU =
4580 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Depth units:"),
4581 wxDefaultPosition, wxDefaultSize, 0);
4582 itemFlexGridSizer04->Add(itemStaticTextDepthU, 0, wxEXPAND | wxALL,
4584 wxString m_DepthUnitChoices[] = {_(
"Meters"), _(
"Feet"), _(
"Fathoms"),
4585 _(
"Inches"), _(
"Centimeters")};
4586 int m_DepthUnitNChoices =
sizeof(m_DepthUnitChoices) /
sizeof(wxString);
4587 wxSize szDepthUnit = wxDefaultSize;
4588 m_pChoiceDepthUnit =
4589 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition,
4590 szDepthUnit, m_DepthUnitNChoices, m_DepthUnitChoices, 0);
4591 for (
auto const &iUnit : m_DepthUnitChoices) {
4592 szDepthUnit.IncTo(m_pChoiceDepthUnit->GetTextExtent(iUnit));
4594 m_pChoiceDepthUnit->SetSize(szDepthUnit);
4595 m_pChoiceDepthUnit->SetSelection(g_iDashDepthUnit - 3);
4596 itemFlexGridSizer04->Add(m_pChoiceDepthUnit, 0, wxALIGN_RIGHT | wxALL, 0);
4597 wxString dMess = wxString::Format(_(
"Depth Offset (%s):"),
4598 m_DepthUnitChoices[g_iDashDepthUnit - 3]);
4599 wxStaticText *itemStaticDepthO =
4600 new wxStaticText(itemPanelNotebook02, wxID_ANY, dMess, wxDefaultPosition,
4603 switch (g_iDashDepthUnit - 3) {
4605 DepthOffset = g_dDashDBTOffset * 3.2808399;
4608 DepthOffset = g_dDashDBTOffset * 0.54680665;
4611 DepthOffset = g_dDashDBTOffset * 39.3700787;
4614 DepthOffset = g_dDashDBTOffset * 100;
4617 DepthOffset = g_dDashDBTOffset;
4619 itemFlexGridSizer04->Add(itemStaticDepthO, 0, wxEXPAND | wxALL, border_size);
4620 m_pSpinDBTOffset =
new wxSpinCtrlDouble(
4621 itemPanelNotebook02, wxID_ANY, wxEmptyString, wxDefaultPosition,
4622 wxDefaultSize, wxSP_ARROW_KEYS, -100, 100, DepthOffset, 0.1);
4623 itemFlexGridSizer04->Add(m_pSpinDBTOffset, 0, wxALIGN_RIGHT | wxALL, 0);
4625 wxStaticText *itemStaticText0b =
4626 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Distance units:"),
4627 wxDefaultPosition, wxDefaultSize, 0);
4628 itemFlexGridSizer04->Add(itemStaticText0b, 0, wxEXPAND | wxALL, border_size);
4629 wxString m_DistanceUnitChoices[] = {_(
"Honor OpenCPN settings"),
4630 _(
"Nautical miles"), _(
"Statute miles"),
4631 _(
"Kilometers"), _(
"Meters")};
4632 wxSize szDistanceUnit = wxDefaultSize;
4633 int m_DistanceUnitNChoices =
sizeof(m_DistanceUnitChoices) /
sizeof(wxString);
4634 m_pChoiceDistanceUnit =
new wxChoice(
4635 itemPanelNotebook02, wxID_ANY, wxDefaultPosition, szDistanceUnit,
4636 m_DistanceUnitNChoices, m_DistanceUnitChoices, 0);
4637 for (
auto const &iUnit : m_DistanceUnitChoices) {
4638 szDistanceUnit.IncTo(m_pChoiceDistanceUnit->GetTextExtent(iUnit));
4640 m_pChoiceDistanceUnit->SetSize(szDistanceUnit);
4641 m_pChoiceDistanceUnit->SetSelection(g_iDashDistanceUnit + 1);
4642 itemFlexGridSizer04->Add(m_pChoiceDistanceUnit, 0, wxALIGN_RIGHT | wxALL, 0);
4643 m_pChoiceDistanceUnit->Connect(
4644 wxEVT_COMMAND_CHOICE_SELECTED,
4645 wxCommandEventHandler(DashboardPreferencesDialog::OnDistanceUnitSelect),
4648 wxStaticText *itemStaticText0a =
4649 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Wind speed units:"),
4650 wxDefaultPosition, wxDefaultSize, 0);
4651 itemFlexGridSizer04->Add(itemStaticText0a, 0, wxEXPAND | wxALL, border_size);
4652 wxString m_WSpeedUnitChoices[] = {_(
"Kts"), _(
"mph"), _(
"km/h"), _(
"m/s")};
4653 int m_WSpeedUnitNChoices =
sizeof(m_WSpeedUnitChoices) /
sizeof(wxString);
4654 wxSize szWSpeedUnit = wxDefaultSize;
4655 m_pChoiceWindSpeedUnit =
4656 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition,
4657 szWSpeedUnit, m_WSpeedUnitNChoices, m_WSpeedUnitChoices, 0);
4658 for (
auto const &iUnit : m_WSpeedUnitChoices) {
4659 szWSpeedUnit.IncTo(m_pChoiceWindSpeedUnit->GetTextExtent(iUnit));
4661 m_pChoiceWindSpeedUnit->SetSize(szWSpeedUnit);
4662 m_pChoiceWindSpeedUnit->SetSelection(g_iDashWindSpeedUnit);
4663 itemFlexGridSizer04->Add(m_pChoiceWindSpeedUnit, 0, wxALIGN_RIGHT | wxALL, 0);
4665 wxStaticText *itemStaticText0c =
4666 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Temperature units:"),
4667 wxDefaultPosition, wxDefaultSize, 0);
4668 itemFlexGridSizer04->Add(itemStaticText0c, 0, wxEXPAND | wxALL, border_size);
4669 wxString m_TempUnitChoices[] = {_(
"Celsius"), _(
"Fahrenheit"), _(
"Kelvin")};
4670 int m_TempUnitNChoices =
sizeof(m_TempUnitChoices) /
sizeof(wxString);
4671 wxSize szTempUnit = wxDefaultSize;
4673 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition, szTempUnit,
4674 m_TempUnitNChoices, m_TempUnitChoices, 0);
4675 for (
auto const &iUnit : m_TempUnitChoices) {
4676 szTempUnit.IncTo(m_pChoiceTempUnit->GetTextExtent(iUnit));
4678 m_pChoiceTempUnit->SetSize(szTempUnit);
4679 m_pChoiceTempUnit->SetSelection(g_iDashTempUnit);
4680 itemFlexGridSizer04->Add(m_pChoiceTempUnit, 0, wxALIGN_RIGHT | wxALL, 0);
4684 wxStaticBox *itemStaticBox05 =
4685 new wxStaticBox(itemPanelNotebook02, wxID_ANY, _(
"Other selections"));
4686 wxStaticBoxSizer *itemStaticBoxSizer05 =
4687 new wxStaticBoxSizer(itemStaticBox05, wxHORIZONTAL);
4688 itemBoxSizer05->Add(itemStaticBoxSizer05, 0, wxEXPAND | wxALL, border_size);
4690 wxFlexGridSizer *itemFlexGridSizer05 =
new wxFlexGridSizer(3);
4691 itemFlexGridSizer05->AddGrowableCol(1);
4692 itemStaticBoxSizer05->Add(itemFlexGridSizer05, 1, wxEXPAND | wxALL, 0);
4694 m_pUseInternSumLog =
new wxCheckBox(itemPanelNotebook02, wxID_ANY,
4695 _(
"Use internal Sumlog.") +
" " +
4696 _(
"Enter new value if desired"));
4697 itemFlexGridSizer05->Add(m_pUseInternSumLog, 1, wxALIGN_LEFT, border_size);
4698 m_pUseInternSumLog->SetValue(g_bUseInternSumLog);
4701 new wxStaticText(itemPanelNotebook02, wxID_ANY,
4703 wxDefaultPosition, wxDefaultSize, 0);
4704 itemFlexGridSizer05->Add(m_SumLogUnit, 1, wxALIGN_RIGHT, 0);
4706 m_pSumLogValue =
new wxTextCtrl(itemPanelNotebook02, wxID_ANY,
"");
4707 itemFlexGridSizer05->Add(m_pSumLogValue, 1, wxALIGN_LEFT, 1);
4708 m_pSumLogValue->SetValue(wxString::Format(
4711 m_pUseTrueWinddata =
new wxCheckBox(itemPanelNotebook02, wxID_ANY,
4712 _(
"Use N2K & SignalK true wind data over "
4713 "ground.\n(Instead of through water)"));
4714 itemFlexGridSizer05->Add(m_pUseTrueWinddata, 1, wxALIGN_LEFT, border_size);
4715 m_pUseTrueWinddata->SetValue(g_bDBtrueWindGround);
4719 wxStaticBox *itemStaticBox05 =
4720 new wxStaticBox(itemPanelNotebook02, wxID_ANY, _(
"Other selections"));
4721 wxStaticBoxSizer *itemStaticBoxSizer05 =
4722 new wxStaticBoxSizer(itemStaticBox05, wxHORIZONTAL);
4723 itemBoxSizer05->Add(itemStaticBoxSizer05, 0, wxEXPAND | wxALL, border_size);
4725 wxFlexGridSizer *itemFlexGridSizer05 =
new wxFlexGridSizer(2);
4726 itemFlexGridSizer05->AddGrowableCol(1);
4727 itemStaticBoxSizer05->Add(itemFlexGridSizer05, 1, wxEXPAND | wxALL, 0);
4729 m_pUseInternSumLog =
new wxCheckBox(itemPanelNotebook02, wxID_ANY,
4730 _(
"Use internal Sumlog.") +
" ");
4731 itemFlexGridSizer05->Add(m_pUseInternSumLog, 0, wxALIGN_LEFT, border_size);
4732 m_pUseInternSumLog->SetValue(g_bUseInternSumLog);
4733 itemFlexGridSizer05->AddSpacer(0);
4736 new wxStaticText(itemPanelNotebook02, wxID_ANY,
4737 " " + _(
"Enter new value if desired") +
" ",
4738 wxDefaultPosition, wxDefaultSize, 0);
4739 itemFlexGridSizer05->Add(xtext, 1, wxALIGN_LEFT, 0);
4740 itemFlexGridSizer05->AddSpacer(0);
4742 m_SumLogUnit =
new wxStaticText(
4743 itemPanelNotebook02, wxID_ANY,
4745 wxDefaultPosition, wxDefaultSize, 0);
4746 itemFlexGridSizer05->Add(m_SumLogUnit, 1, wxALIGN_RIGHT, 0);
4748 m_pSumLogValue =
new wxTextCtrl(itemPanelNotebook02, wxID_ANY,
"");
4749 itemFlexGridSizer05->Add(m_pSumLogValue, 1, wxALIGN_LEFT, 1);
4750 m_pSumLogValue->SetValue(wxString::Format(
4753 m_pUseTrueWinddata =
new wxCheckBox(itemPanelNotebook02, wxID_ANY,
4754 _(
"Use N2K & SignalK true wind data over "
4755 "ground.\n(Instead of through water)"));
4756 itemFlexGridSizer05->Add(m_pUseTrueWinddata, 1, wxALIGN_LEFT, border_size);
4757 m_pUseTrueWinddata->SetValue(g_bDBtrueWindGround);
4758 itemFlexGridSizer05->AddSpacer(0);
4760 auto xtext1 =
new wxStaticText(itemPanelNotebook02, wxID_ANY,
" ",
4761 wxDefaultPosition, wxDefaultSize, 0);
4762 itemFlexGridSizer05->Add(xtext1, 1, wxALIGN_LEFT, 0);
4763 itemFlexGridSizer05->AddSpacer(0);
4765 auto xtext2 =
new wxStaticText(itemPanelNotebook02, wxID_ANY,
" ",
4766 wxDefaultPosition, wxDefaultSize, 0);
4767 itemFlexGridSizer05->Add(xtext2, 1, wxALIGN_LEFT, 0);
4768 itemFlexGridSizer05->AddSpacer(0);
4773 for (
size_t i = 0; i < m_Config.GetCount(); i++) {
4774 m_pListCtrlDashboards->InsertItem(i, 0);
4776 m_pListCtrlDashboards->SetItemData(i, i);
4778 m_pListCtrlDashboards->SetColumnWidth(0, wxLIST_AUTOSIZE);
4780 m_pListCtrlDashboards->SetItemState(0, wxLIST_STATE_SELECTED,
4781 wxLIST_STATE_SELECTED);
4784 UpdateDashboardButtonsState();
4785 UpdateButtonsState();
4792 SetMaxSize(wxSize(display_width, display_height));
4795 if (display_height < 600) {
4796 if (g_dashPrefWidth > 0 && g_dashPrefHeight > 0)
4797 SetSize(wxSize(g_dashPrefWidth, g_dashPrefHeight));
4799 SetSize(wxSize(canvas_size.x * 8 / 10, canvas_size.y * 8 / 10));
4801 if (g_dashPrefWidth > 0 && g_dashPrefHeight > 0)
4802 SetSize(wxSize(g_dashPrefWidth, g_dashPrefHeight));
4804 SetSize(wxSize(canvas_size.x * 3 / 4, canvas_size.y * 8 / 10));
4811void DashboardPreferencesDialog::RecalculateSize(
void) {
4812#ifdef __OCPN__ANDROID__
4814 esize.x = GetCharWidth() * 110;
4815 esize.y = GetCharHeight() * 40;
4818 esize.y = wxMin(esize.y, dsize.y - (3 * GetCharHeight()));
4819 esize.x = wxMin(esize.x, dsize.x - (3 * GetCharHeight()));
4826void DashboardPreferencesDialog::OnCloseDialog(wxCloseEvent &event) {
4827 g_dashPrefWidth = GetSize().x;
4828 g_dashPrefHeight = GetSize().y;
4829 SaveDashboardConfig();
4833void DashboardPreferencesDialog::SaveDashboardConfig() {
4834 g_iDashSpeedMax = m_pSpinSpeedMax->GetValue();
4835 g_iDashCOGDamp = m_pSpinCOGDamp->GetValue();
4836 g_iDashSOGDamp = m_pSpinSOGDamp->GetValue();
4837 g_iDashAWADamp = m_pSpinAWADamp->GetValue();
4838 g_iDashAWSDamp = m_pSpinAWSDamp->GetValue();
4840 g_bUseInternSumLog = m_pUseInternSumLog->IsChecked();
4842 m_pSumLogValue->GetValue().ToDouble(&ursDist);
4845 g_iUTCOffset = m_pChoiceUTCOffset->GetSelection() - 24;
4846 g_iDashSpeedUnit = m_pChoiceSpeedUnit->GetSelection() - 1;
4847 double DashDBTOffset = m_pSpinDBTOffset->GetValue();
4848 switch (g_iDashDepthUnit - 3) {
4850 g_dDashDBTOffset = DashDBTOffset / 3.2808399;
4853 g_dDashDBTOffset = DashDBTOffset / 0.54680665;
4856 g_dDashDBTOffset = DashDBTOffset / 39.3700787;
4859 g_dDashDBTOffset = DashDBTOffset / 100;
4862 g_dDashDBTOffset = DashDBTOffset;
4864 g_iDashDepthUnit = m_pChoiceDepthUnit->GetSelection() + 3;
4865 g_iDashDistanceUnit = m_pChoiceDistanceUnit->GetSelection() - 1;
4866 g_iDashWindSpeedUnit = m_pChoiceWindSpeedUnit->GetSelection();
4867 g_bDBtrueWindGround = m_pUseTrueWinddata->GetValue();
4868 g_iDashTempUnit = m_pChoiceTempUnit->GetSelection();
4871 cont->m_bIsVisible = m_pCheckBoxIsVisible->IsChecked();
4872 cont->m_sCaption = m_pTextCtrlCaption->GetValue();
4873 cont->m_sOrientation =
4874 m_pChoiceOrientation->GetSelection() == 0 ?
"V" :
"H";
4875 cont->m_aInstrumentList.Clear();
4876 for (
int i = 0; i < m_pListCtrlInstruments->GetItemCount(); i++)
4877 cont->m_aInstrumentList.Add((
int)m_pListCtrlInstruments->GetItemData(i));
4881void DashboardPreferencesDialog::OnDashboardSelected(wxListEvent &event) {
4883 SaveDashboardConfig();
4884 UpdateDashboardButtonsState();
4887void DashboardPreferencesDialog::UpdateDashboardButtonsState() {
4889 item = m_pListCtrlDashboards->GetNextItem(item, wxLIST_NEXT_ALL,
4890 wxLIST_STATE_SELECTED);
4891 bool enable = (item != -1);
4895 bool delete_enable = enable;
4897 int sel = m_pListCtrlDashboards->GetItemData(item);
4900 if (dash_sel == GetParent()) delete_enable =
false;
4902 m_pButtonDeleteDashboard->Enable(delete_enable);
4904 m_pPanelDashboard->Enable(enable);
4907 curSel = m_pListCtrlDashboards->GetItemData(item);
4909 m_pCheckBoxIsVisible->SetValue(cont->m_bIsVisible);
4910 m_pTextCtrlCaption->SetValue(cont->m_sCaption);
4911 m_pChoiceOrientation->SetSelection(cont->m_sOrientation ==
"V" ? 0 : 1);
4912 m_pListCtrlInstruments->DeleteAllItems();
4913 for (
size_t i = 0; i < cont->m_aInstrumentList.GetCount(); i++) {
4915 getListItemForInstrument(item, cont->m_aInstrumentList.Item(i));
4916 item.SetId(m_pListCtrlInstruments->GetItemCount());
4917 m_pListCtrlInstruments->InsertItem(item);
4920 m_pListCtrlInstruments->SetColumnWidth(0, wxLIST_AUTOSIZE);
4923 m_pCheckBoxIsVisible->SetValue(
false);
4924 m_pTextCtrlCaption->SetValue(
"");
4925 m_pChoiceOrientation->SetSelection(0);
4926 m_pListCtrlInstruments->DeleteAllItems();
4931void DashboardPreferencesDialog::OnDashboarddefaultFont(wxCommandEvent &event) {
4932 m_pFontPickerTitle->SetSelectedFont(
4933 wxFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL));
4934 m_pFontPickerTitle->SetSelectedColour(wxColour(0, 0, 0));
4935 m_pFontPickerData->SetSelectedFont(
4936 wxFont(14, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
4937 m_pFontPickerData->SetSelectedColour(wxColour(0, 0, 0));
4938 m_pFontPickerLabel->SetSelectedFont(
4939 wxFont(8, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
4940 m_pFontPickerLabel->SetSelectedColour(wxColour(0, 0, 0));
4941 m_pFontPickerSmall->SetSelectedFont(
4942 wxFont(8, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
4943 m_pFontPickerSmall->SetSelectedColour(wxColour(0, 0, 0));
4944 double scaler = 1.0;
4947 scaler = wxMax(1.0, scaler);
4949 g_USFontTitle = *(m_pFontPickerTitle->GetFontData());
4950 g_FontTitle = *g_pUSFontTitle;
4951 g_FontTitle.SetChosenFont(g_pUSFontTitle->GetChosenFont().Scaled(scaler));
4952 g_FontTitle.SetColour(g_pUSFontTitle->GetColour());
4953 g_USFontTitle = *g_pUSFontTitle;
4955 g_USFontData = *(m_pFontPickerData->GetFontData());
4956 g_FontData = *g_pUSFontData;
4957 g_FontData.SetChosenFont(g_pUSFontData->GetChosenFont().Scaled(scaler));
4958 g_FontData.SetColour(g_pUSFontData->GetColour());
4959 g_USFontData = *g_pUSFontData;
4961 g_USFontLabel = *(m_pFontPickerLabel->GetFontData());
4962 g_FontLabel = *g_pUSFontLabel;
4963 g_FontLabel.SetChosenFont(g_pUSFontLabel->GetChosenFont().Scaled(scaler));
4964 g_FontLabel.SetColour(g_pUSFontLabel->GetColour());
4965 g_USFontLabel = *g_pUSFontLabel;
4967 g_USFontSmall = *(m_pFontPickerSmall->GetFontData());
4968 g_FontSmall = *g_pUSFontSmall;
4969 g_FontSmall.SetChosenFont(g_pUSFontSmall->GetChosenFont().Scaled(scaler));
4970 g_FontSmall.SetColour(g_pUSFontSmall->GetColour());
4971 g_USFontSmall = *g_pUSFontSmall;
4974void DashboardPreferencesDialog::OnDashboardAdd(wxCommandEvent &event) {
4975 int idx = m_pListCtrlDashboards->GetItemCount();
4976 m_pListCtrlDashboards->InsertItem(idx, 0);
4978 m_pListCtrlDashboards->SetItemData(idx, m_Config.GetCount());
4980 wxArrayOfInstrumentProperties Property;
4982 NULL, MakeName(), _(
"Dashboard"),
"V", ar, Property);
4983 dwc->m_bIsVisible =
true;
4987void DashboardPreferencesDialog::OnDashboardDelete(wxCommandEvent &event) {
4989 itemID = m_pListCtrlDashboards->GetNextItem(itemID, wxLIST_NEXT_ALL,
4990 wxLIST_STATE_SELECTED);
4992 int idx = m_pListCtrlDashboards->GetItemData(itemID);
4993 m_pListCtrlDashboards->DeleteItem(itemID);
4994 m_Config.Item(idx)->m_bIsDeleted =
true;
4995 UpdateDashboardButtonsState();
4998void DashboardPreferencesDialog::OnInstrumentSelected(wxListEvent &event) {
4999 UpdateButtonsState();
5002void DashboardPreferencesDialog::UpdateButtonsState() {
5004 item = m_pListCtrlInstruments->GetNextItem(item, wxLIST_NEXT_ALL,
5005 wxLIST_STATE_SELECTED);
5006 bool enable = (item != -1);
5008 m_pButtonDelete->Enable(enable);
5009 m_pButtonEdit->Enable(enable);
5010 m_pButtonUp->Enable(item > 0);
5011 m_pButtonDown->Enable(item != -1 &&
5012 item < m_pListCtrlInstruments->GetItemCount() - 1);
5015void DashboardPreferencesDialog::OnInstrumentAdd(wxCommandEvent &event) {
5018#ifdef __OCPN__ANDROID__
5023 esize.x = GetCharWidth() * 110;
5024 esize.y = GetCharHeight() * 40;
5027 esize.y = wxMin(esize.y, dsize.y - (3 * GetCharHeight()));
5028 esize.x = wxMin(esize.x, dsize.x - (3 * GetCharHeight()));
5029 pdlg.SetSize(esize);
5031 pdlg.CentreOnScreen();
5034 if (pdlg.GetReturnCode() == wxID_OK) {
5036 getListItemForInstrument(item, pdlg.GetInstrumentAdded());
5037 item.SetId(m_pListCtrlInstruments->GetItemCount());
5038 m_pListCtrlInstruments->InsertItem(item);
5039 m_pListCtrlInstruments->SetColumnWidth(0, wxLIST_AUTOSIZE);
5040 UpdateButtonsState();
5044void DashboardPreferencesDialog::OnInstrumentDelete(wxCommandEvent &event) {
5045 long itemIDWindow = -1;
5046 itemIDWindow = m_pListCtrlDashboards->GetNextItem(
5047 itemIDWindow, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
5049 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5050 wxLIST_STATE_SELECTED);
5052 m_Config.Item(m_pListCtrlDashboards->GetItemData(itemIDWindow));
5056 for (
unsigned int i = 0; i < (cont->m_aInstrumentPropertyList.GetCount());
5058 Inst = cont->m_aInstrumentPropertyList.Item(i);
5059 if (Inst->m_aInstrument ==
5060 (
int)m_pListCtrlInstruments->GetItemData(itemID) &&
5061 Inst->m_Listplace == itemID) {
5062 cont->m_aInstrumentPropertyList.Remove(Inst);
5066 if (Inst->m_Listplace > itemID) Inst->m_Listplace--;
5070 m_pListCtrlInstruments->DeleteItem(itemID);
5072 cont->m_pDashboardWindow->SetInstrumentList(
5073 cont->m_aInstrumentList, &(cont->m_aInstrumentPropertyList));
5076 UpdateButtonsState();
5079inline void GetFontData(
OCPNFontButton *FontButton, wxFontData &UnScaledFont,
5080 wxFontData &ScaledFont,
double scaler) {
5081 UnScaledFont = *(FontButton->GetFontData());
5082 ScaledFont = UnScaledFont;
5083 ScaledFont.SetChosenFont(UnScaledFont.GetChosenFont().Scaled(scaler));
5086void DashboardPreferencesDialog::OnInstrumentEdit(wxCommandEvent &event) {
5089 long itemIDWindow = -1;
5090 itemIDWindow = m_pListCtrlDashboards->GetNextItem(
5091 itemIDWindow, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
5093 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5094 wxLIST_STATE_SELECTED);
5100 m_Config.Item(m_pListCtrlDashboards->GetItemData(itemIDWindow));
5103 for (
unsigned int i = 0; i < (cont->m_aInstrumentPropertyList.GetCount());
5105 Inst = cont->m_aInstrumentPropertyList.Item(
5107 if (Inst->m_aInstrument == (
int)m_pListCtrlInstruments->GetItemData(
5110 if (Inst->m_Listplace == itemID)
break;
5117 cont->m_aInstrumentPropertyList.Add(Inst);
5121 bool DefaultFont =
false;
5122 if (Edit->ShowModal() == wxID_OK) {
5124 double scaler = 1.0;
5127 scaler = wxMax(1.0, scaler);
5128 if (Edit->m_fontPicker2->GetFont().Scaled(scaler) !=
5129 g_FontTitle.GetChosenFont() ||
5130 Edit->m_fontPicker2->GetSelectedColour() != g_FontTitle.GetColour())
5131 DefaultFont =
false;
5132 if (Edit->m_fontPicker4->GetFont().Scaled(scaler) !=
5133 g_FontData.GetChosenFont() ||
5134 Edit->m_fontPicker4->GetSelectedColour() != g_FontData.GetColour())
5135 DefaultFont =
false;
5136 if (Edit->m_fontPicker5->GetFont().Scaled(scaler) !=
5137 g_FontLabel.GetChosenFont() ||
5138 Edit->m_fontPicker5->GetSelectedColour() != g_FontLabel.GetColour())
5139 DefaultFont =
false;
5140 if (Edit->m_fontPicker6->GetFont().Scaled(scaler) !=
5141 g_FontSmall.GetChosenFont() ||
5142 Edit->m_fontPicker6->GetSelectedColour() != g_FontSmall.GetColour())
5143 DefaultFont =
false;
5145 GetGlobalColor(
"DASHL", &dummy);
5146 if (Edit->m_colourPicker1->GetColour() != dummy) DefaultFont =
false;
5147 GetGlobalColor(
"DASHB", &dummy);
5148 if (Edit->m_colourPicker2->GetColour() != dummy) DefaultFont =
false;
5149 GetGlobalColor(
"DASHN", &dummy);
5150 if (Edit->m_colourPicker3->GetColour() != dummy) DefaultFont =
false;
5151 GetGlobalColor(
"BLUE3", &dummy);
5152 if (Edit->m_colourPicker4->GetColour() != dummy) DefaultFont =
false;
5154 cont->m_aInstrumentPropertyList.Remove(Inst);
5156 GetFontData(Edit->m_fontPicker2, Inst->m_USTitleFont, Inst->m_TitleFont,
5158 GetFontData(Edit->m_fontPicker4, Inst->m_USDataFont, Inst->m_DataFont,
5160 GetFontData(Edit->m_fontPicker5, Inst->m_USLabelFont, Inst->m_LabelFont,
5162 GetFontData(Edit->m_fontPicker6, Inst->m_USSmallFont, Inst->m_SmallFont,
5164 Inst->m_DataBackgroundColour = Edit->m_colourPicker2->GetColour();
5165 Inst->m_TitleBackgroundColour = Edit->m_colourPicker1->GetColour();
5166 Inst->m_Arrow_First_Colour = Edit->m_colourPicker3->GetColour();
5167 Inst->m_Arrow_Second_Colour = Edit->m_colourPicker4->GetColour();
5171 if (cont->m_pDashboardWindow) {
5172 cont->m_pDashboardWindow->SetInstrumentList(
5173 cont->m_aInstrumentList, &(cont->m_aInstrumentPropertyList));
5175 if (DefaultFont)
delete Inst;
5178void DashboardPreferencesDialog::OnInstrumentUp(wxCommandEvent &event) {
5179 long itemIDWindow = -1;
5180 itemIDWindow = m_pListCtrlDashboards->GetNextItem(
5181 itemIDWindow, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
5183 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5184 wxLIST_STATE_SELECTED);
5187 item.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_IMAGE | wxLIST_MASK_DATA);
5188 m_pListCtrlInstruments->GetItem(item);
5189 item.SetId(itemID - 1);
5193 m_Config.Item(m_pListCtrlDashboards->GetItemData(itemIDWindow));
5196 for (
unsigned int i = 0; i < (cont->m_aInstrumentPropertyList.GetCount());
5198 Inst = cont->m_aInstrumentPropertyList.Item(i);
5199 if (Inst->m_Listplace == (itemID - 1)) Inst->m_Listplace = itemID;
5200 if (Inst->m_aInstrument ==
5201 (
int)m_pListCtrlInstruments->GetItemData(itemID) &&
5202 Inst->m_Listplace == itemID) {
5203 cont->m_aInstrumentPropertyList.Item(i)->m_Listplace = itemID - 1;
5207 m_pListCtrlInstruments->DeleteItem(itemID);
5208 m_pListCtrlInstruments->InsertItem(item);
5209 for (
int i = 0; i < m_pListCtrlInstruments->GetItemCount(); i++)
5210 m_pListCtrlInstruments->SetItemState(i, 0, wxLIST_STATE_SELECTED);
5212 m_pListCtrlInstruments->SetItemState(itemID - 1, wxLIST_STATE_SELECTED,
5213 wxLIST_STATE_SELECTED);
5215 UpdateButtonsState();
5218void DashboardPreferencesDialog::OnInstrumentDown(wxCommandEvent &event) {
5219 long itemIDWindow = -1;
5220 itemIDWindow = m_pListCtrlDashboards->GetNextItem(
5221 itemIDWindow, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
5223 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5224 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) &&
5241 Inst->m_aInstrument !=
5242 (int)m_pListCtrlInstruments->GetItemData(itemID))
5243 Inst->m_Listplace = itemID;
5244 if (Inst->m_aInstrument ==
5245 (
int)m_pListCtrlInstruments->GetItemData(itemID) &&
5246 Inst->m_Listplace == itemID) {
5247 cont->m_aInstrumentPropertyList.Item(i)->m_Listplace = itemID + 1;
5252 m_pListCtrlInstruments->DeleteItem(itemID);
5253 m_pListCtrlInstruments->InsertItem(item);
5254 for (
int i = 0; i < m_pListCtrlInstruments->GetItemCount(); i++)
5255 m_pListCtrlInstruments->SetItemState(i, 0, wxLIST_STATE_SELECTED);
5257 m_pListCtrlInstruments->SetItemState(itemID + 1, wxLIST_STATE_SELECTED,
5258 wxLIST_STATE_SELECTED);
5260 UpdateButtonsState();
5263void DashboardPreferencesDialog::OnDistanceUnitSelect(wxCommandEvent &event) {
5265 g_iDashDistanceUnit = m_pChoiceDistanceUnit->GetSelection() - 1;
5267 m_pSumLogValue->SetValue(wxString::Format(
5277AddInstrumentDlg::AddInstrumentDlg(wxWindow *pparent, wxWindowID
id)
5278 : wxDialog(pparent, id, _(
"Add instrument"), wxDefaultPosition,
5279 wxDefaultSize, wxDEFAULT_DIALOG_STYLE) {
5280 wxBoxSizer *itemBoxSizer01 =
new wxBoxSizer(wxVERTICAL);
5281 SetSizer(itemBoxSizer01);
5282 wxStaticText *itemStaticText01 =
5283 new wxStaticText(
this, wxID_ANY, _(
"Select instrument to add:"),
5284 wxDefaultPosition, wxDefaultSize, 0);
5285 itemBoxSizer01->Add(itemStaticText01, 0, wxEXPAND | wxALL, 5);
5289 wxImageList *imglist =
5290 new wxImageList(instImageRefSize, instImageRefSize,
true, 2);
5292 wxImage inst1 = wxBitmap(*_img_instrument).ConvertToImage();
5294 inst1.Scale(instImageRefSize, instImageRefSize, wxIMAGE_QUALITY_HIGH);
5295 imglist->Add(wxBitmap(inst1s));
5297 wxImage dial1 = wxBitmap(*_img_dial).ConvertToImage();
5299 dial1.Scale(instImageRefSize, instImageRefSize, wxIMAGE_QUALITY_HIGH);
5300 imglist->Add(wxBitmap(dial1s));
5303 int vsize = dsize.y * 50 / 100;
5305#ifdef __OCPN__ANDROID__
5307 wxDisplaySize(&dw, &dh);
5308 vsize = dh * 50 / 100;
5311 m_pListCtrlInstruments =
new wxListCtrl(
5312 this, wxID_ANY, wxDefaultPosition, wxSize(-1, vsize ),
5313 wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING);
5314 itemBoxSizer01->Add(m_pListCtrlInstruments, 0, wxEXPAND | wxALL, 5);
5315 m_pListCtrlInstruments->AssignImageList(imglist, wxIMAGE_LIST_SMALL);
5316 m_pListCtrlInstruments->InsertColumn(0, _(
"Instruments"));
5319 m_pListCtrlInstruments->SetFont(*pF);
5321#ifdef __OCPN__ANDROID__
5322 m_pListCtrlInstruments->GetHandle()->setStyleSheet(qtStyleSheet);
5326 wxStdDialogButtonSizer *DialogButtonSizer =
5327 CreateStdDialogButtonSizer(wxOK | wxCANCEL);
5328 itemBoxSizer01->Add(DialogButtonSizer, 0, wxALIGN_RIGHT | wxALL, 5);
5331 for (
unsigned int i = ID_DBP_I_POS; i < ID_DBP_LAST_ENTRY;
5335 if (IsObsolete(i))
continue;
5336 getListItemForInstrument(item, i);
5338 m_pListCtrlInstruments->InsertItem(item);
5342 m_pListCtrlInstruments->SetColumnWidth(0, wxLIST_AUTOSIZE);
5343 m_pListCtrlInstruments->SetItemState(0, wxLIST_STATE_SELECTED,
5344 wxLIST_STATE_SELECTED);
5348unsigned int AddInstrumentDlg::GetInstrumentAdded() {
5350 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5351 wxLIST_STATE_SELECTED);
5353 return (
int)m_pListCtrlInstruments->GetItemData(itemID);
5363DashboardWindow::DashboardWindow(wxWindow *pparent, wxWindowID
id,
5366 : wxWindow(pparent, id, wxDefaultPosition, wxDefaultSize, 0) {
5372 m_Container = mycont;
5375 itemBoxSizer =
new wxBoxSizer(orient);
5376 SetSizer(itemBoxSizer);
5377 Connect(wxEVT_SIZE, wxSizeEventHandler(DashboardWindow::OnSize), NULL,
this);
5378 Connect(wxEVT_CONTEXT_MENU,
5379 wxContextMenuEventHandler(DashboardWindow::OnContextMenu), NULL,
5381 Connect(wxEVT_COMMAND_MENU_SELECTED,
5382 wxCommandEventHandler(DashboardWindow::OnContextMenuSelect), NULL,
5385#ifdef __OCPN__ANDROID__
5386 Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(DashboardWindow::OnMouseEvent));
5387 Connect(wxEVT_LEFT_UP, wxMouseEventHandler(DashboardWindow::OnMouseEvent));
5388 Connect(wxEVT_MOTION, wxMouseEventHandler(DashboardWindow::OnMouseEvent));
5390 GetHandle()->setAttribute(Qt::WA_AcceptTouchEvents);
5391 GetHandle()->grabGesture(Qt::PinchGesture);
5392 GetHandle()->grabGesture(Qt::PanGesture);
5394 Connect(wxEVT_QT_PINCHGESTURE,
5399 wxEVT_QT_PANGESTURE,
5400 (wxObjectEventFunction)(wxEventFunction)&DashboardWindow::OnEvtPanGesture,
5406 m_binResize =
false;
5410DashboardWindow::~DashboardWindow() {
5411 for (
size_t i = 0; i < m_ArrayOfInstrument.GetCount(); i++) {
5417#ifdef __OCPN__ANDROID__
5418void DashboardWindow::OnEvtPinchGesture(wxQT_PinchGestureEvent &event) {
5419 float zoom_gain = 0.3;
5421 float total_zoom_val;
5423 if (event.GetScaleFactor() > 1)
5424 zoom_val = ((
event.GetScaleFactor() - 1.0) * zoom_gain) + 1.0;
5426 zoom_val = 1.0 - ((1.0 -
event.GetScaleFactor()) * zoom_gain);
5428 if (event.GetTotalScaleFactor() > 1)
5429 total_zoom_val = ((event.GetTotalScaleFactor() - 1.0) * zoom_gain) + 1.0;
5431 total_zoom_val = 1.0 - ((1.0 -
event.GetTotalScaleFactor()) * zoom_gain);
5433 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5435 wxSize currentSize = wxSize(pane.floating_size.x, pane.floating_size.y);
5436 double aRatio = (double)currentSize.y / (
double)currentSize.x;
5439 wxPoint par_pos = wxPoint(pane.floating_pos.x, pane.floating_pos.y);
5441 switch (event.GetState()) {
5442 case GestureStarted:
5446 case GestureUpdated:
5447 currentSize.y *= zoom_val;
5448 currentSize.x *= zoom_val;
5450 if ((par_pos.y + currentSize.y) > par_size.y)
5451 currentSize.y = par_size.y - par_pos.y;
5453 if ((par_pos.x + currentSize.x) > par_size.x)
5454 currentSize.x = par_size.x - par_pos.x;
5457 currentSize.x = currentSize.y / aRatio;
5459 currentSize.x = wxMax(currentSize.x, 150);
5460 currentSize.y = wxMax(currentSize.y, 150);
5462 pane.FloatingSize(currentSize);
5463 m_pauimgr->Update();
5467 case GestureFinished: {
5468 if (itemBoxSizer->GetOrientation() == wxVERTICAL) {
5469 currentSize.y *= total_zoom_val;
5470 currentSize.x = currentSize.y / aRatio;
5472 currentSize.x *= total_zoom_val;
5473 currentSize.y = currentSize.x * aRatio;
5477 if ((par_pos.y + currentSize.y) > par_size.y)
5478 currentSize.y = par_size.y - par_pos.y;
5480 if ((par_pos.x + currentSize.x) > par_size.x)
5481 currentSize.x = par_size.x - par_pos.x;
5484 currentSize.x = wxMax(currentSize.x, 150);
5485 currentSize.y = wxMax(currentSize.y, 150);
5490 if (itemBoxSizer->GetOrientation() == wxVERTICAL) {
5492 for (
unsigned int i = 0; i < m_ArrayOfInstrument.size(); i++) {
5494 m_ArrayOfInstrument.Item(i)->m_pInstrument;
5496 inst->GetSize(itemBoxSizer->GetOrientation(), currentSize);
5500 currentSize.y = total_y;
5503 pane.FloatingSize(currentSize);
5506 for (
unsigned int i = 0; i < m_ArrayOfInstrument.size(); i++) {
5511 m_pauimgr->Update();
5514 m_binResize =
false;
5519 case GestureCanceled:
5521 m_binResize =
false;
5529void DashboardWindow::OnEvtPanGesture(wxQT_PanGestureEvent &event) {
5530 if (m_binPinch)
return;
5532 if (m_binResize)
return;
5534 int x =
event.GetOffset().x;
5535 int y =
event.GetOffset().y;
5537 int lx =
event.GetLastOffset().x;
5538 int ly =
event.GetLastOffset().y;
5543 switch (event.GetState()) {
5544 case GestureStarted:
5545 if (m_binPan)
break;
5550 case GestureUpdated:
5553 wxPoint par_pos_old = ClientToScreen(wxPoint(0, 0));
5555 wxPoint par_pos = par_pos_old;
5559 par_pos.x = wxMax(par_pos.x, 0);
5560 par_pos.y = wxMax(par_pos.y, 0);
5562 wxSize mySize = GetSize();
5564 if ((par_pos.y + mySize.y) > par_size.y)
5565 par_pos.y = par_size.y - mySize.y;
5567 if ((par_pos.x + mySize.x) > par_size.x)
5568 par_pos.x = par_size.x - mySize.x;
5570 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5571 pane.FloatingPosition(par_pos).Float();
5572 m_pauimgr->Update();
5576 case GestureFinished:
5583 case GestureCanceled:
5592void DashboardWindow::OnMouseEvent(wxMouseEvent &event) {
5593 if (m_binPinch)
return;
5596 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5597 wxSize currentSize = wxSize(pane.floating_size.x, pane.floating_size.y);
5598 double aRatio = (double)currentSize.y / (
double)currentSize.x;
5601 wxPoint par_pos = wxPoint(pane.floating_pos.x, pane.floating_pos.y);
5603 if (event.LeftDown()) {
5604 m_resizeStartPoint =
event.GetPosition();
5605 m_resizeStartSize = currentSize;
5606 m_binResize2 =
true;
5610 if (event.Dragging()) {
5611 wxPoint p =
event.GetPosition();
5613 wxSize dragSize = m_resizeStartSize;
5615 dragSize.y += p.y - m_resizeStartPoint.y;
5616 dragSize.x += p.x - m_resizeStartPoint.x;
5619 if ((par_pos.y + dragSize.y) > par_size.y)
5620 dragSize.y = par_size.y - par_pos.y;
5622 if ((par_pos.x + dragSize.x) > par_size.x)
5623 dragSize.x = par_size.x - par_pos.x;
5629 dragSize.x = wxMax(dragSize.x, 150);
5630 dragSize.y = wxMax(dragSize.y, 150);
5632 pane.FloatingSize(dragSize);
5633 m_pauimgr->Update();
5636 if (event.LeftUp()) {
5637 wxPoint p =
event.GetPosition();
5639 wxSize dragSize = m_resizeStartSize;
5641 dragSize.y += p.y - m_resizeStartPoint.y;
5642 dragSize.x += p.x - m_resizeStartPoint.x;
5645 if ((par_pos.y + dragSize.y) > par_size.y)
5646 dragSize.y = par_size.y - par_pos.y;
5648 if ((par_pos.x + dragSize.x) > par_size.x)
5649 dragSize.x = par_size.x - par_pos.x;
5652 dragSize.x = wxMax(dragSize.x, 150);
5653 dragSize.y = wxMax(dragSize.y, 150);
5660 pane.FloatingSize(dragSize);
5661 m_pauimgr->Update();
5663 m_binResize =
false;
5664 m_binResize2 =
false;
5671void DashboardWindow::OnSize(wxSizeEvent &event) {
5673 for (
unsigned int i = 0; i < m_ArrayOfInstrument.size(); i++) {
5676 inst->GetSize(itemBoxSizer->GetOrientation(), GetClientSize()));
5681 this->m_Container->m_best_size =
event.GetSize();
5684void DashboardWindow::OnContextMenu(wxContextMenuEvent &event) {
5685 wxMenu *contextMenu =
new wxMenu();
5692 new wxMenuItem(contextMenu, ID_DASH_PREFS, _(
"Preferences..."));
5693 item1->SetFont(*pf);
5694 contextMenu->Append(item1);
5697 new wxMenuItem(contextMenu, ID_DASH_RESIZE, _(
"Resize..."));
5698 item2->SetFont(*pf);
5699 contextMenu->Append(item2);
5703 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5704 if (pane.IsOk() && pane.IsDocked()) {
5705 contextMenu->Append(ID_DASH_UNDOCK, _(
"Undock"));
5707 wxMenuItem *btnVertical =
5708 contextMenu->AppendRadioItem(ID_DASH_VERTICAL, _(
"Vertical"));
5709 btnVertical->Check(itemBoxSizer->GetOrientation() == wxVERTICAL);
5710 wxMenuItem *btnHorizontal =
5711 contextMenu->AppendRadioItem(ID_DASH_HORIZONTAL, _(
"Horizontal"));
5712 btnHorizontal->Check(itemBoxSizer->GetOrientation() == wxHORIZONTAL);
5713 contextMenu->AppendSeparator();
5715 m_plugin->PopulateContextMenu(contextMenu);
5717 contextMenu->AppendSeparator();
5718 contextMenu->Append(ID_DASH_PREFS, _(
"Preferences..."));
5722 PopupMenu(contextMenu);
5726void DashboardWindow::OnContextMenuSelect(wxCommandEvent &event) {
5727 if (event.GetId() < ID_DASH_PREFS) {
5728 if (m_plugin->GetDashboardWindowShownCount() > 1 || event.IsChecked())
5729 m_plugin->ShowDashboard(event.GetId() - 1, event.IsChecked());
5731 m_plugin->ShowDashboard(event.GetId() - 1,
true);
5734 m_plugin->GetDashboardWindowShownCount() != 0);
5737 switch (event.GetId()) {
5738 case ID_DASH_PREFS: {
5739 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5741 wxPoint fp = pane.floating_pos;
5749 if (!pane.IsDocked())
5750 ChangePaneOrientation(GetSizerOrientation(),
true, fp.x, fp.y);
5752 if (g_bUseInternSumLog) m_plugin->UpdateSumLog(
false);
5755 case ID_DASH_RESIZE: {
5766 case ID_DASH_VERTICAL: {
5767 ChangePaneOrientation(wxVERTICAL,
true);
5768 m_Container->m_sOrientation =
"V";
5771 case ID_DASH_HORIZONTAL: {
5772 ChangePaneOrientation(wxHORIZONTAL,
true);
5773 m_Container->m_sOrientation =
"H";
5776 case ID_DASH_UNDOCK: {
5777 ChangePaneOrientation(GetSizerOrientation(),
true);
5781 m_plugin->SaveConfig();
5788 wxColour col = g_BackgroundColor;
5790 if (!g_ForceBackgroundColor) GetGlobalColor(
"DASHL", &col);
5791 SetBackgroundColour(col);
5796void DashboardWindow::ChangePaneOrientation(
int orient,
bool updateAUImgr,
5798 m_pauimgr->DetachPane(
this);
5799 SetSizerOrientation(orient);
5800 bool vertical = orient == wxVERTICAL;
5802 wxSize sz = GetMinSize();
5804 m_Container->m_sName = MakeName();
5805 m_pauimgr->AddPane(
this, wxAuiPaneInfo()
5806 .Name(m_Container->m_sName)
5807 .Caption(m_Container->m_sCaption)
5808 .CaptionVisible(
true)
5809 .TopDockable(!vertical)
5810 .BottomDockable(!vertical)
5811 .LeftDockable(vertical)
5812 .RightDockable(vertical)
5816 .FloatingPosition(fpx, fpy)
5818 .Show(m_Container->m_bIsVisible));
5820#ifdef __OCPN__ANDROID__
5821 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5822 pane.Dockable(
false);
5825 if (updateAUImgr) m_pauimgr->Update();
5828void DashboardWindow::SetSizerOrientation(
int orient) {
5829 itemBoxSizer->SetOrientation(orient);
5831 wxWindowListNode *node = GetChildren().GetFirst();
5833 node->GetData()->SetMinSize(wxDefaultSize);
5834 node = node->GetNext();
5836 SetMinSize(wxDefaultSize);
5838 SetMinSize(itemBoxSizer->GetMinSize());
5841int DashboardWindow::GetSizerOrientation() {
5842 return itemBoxSizer->GetOrientation();
5845bool isArrayIntEqual(
const wxArrayInt &l1,
const wxArrayOfInstrument &l2) {
5846 if (l1.GetCount() != l2.GetCount())
return false;
5848 for (
size_t i = 0; i < l1.GetCount(); i++)
5849 if (l1.Item(i) != l2.Item(i)->m_ID)
return false;
5854bool DashboardWindow::isInstrumentListEqual(
const wxArrayInt &list) {
5855 return isArrayIntEqual(list, m_ArrayOfInstrument);
5858void DashboardWindow::SetInstrumentList(
5859 wxArrayInt list, wxArrayOfInstrumentProperties *InstrumentPropertyList) {
5873 m_ArrayOfInstrument.Clear();
5874 itemBoxSizer->Clear(
true);
5875 for (
size_t i = 0; i < list.GetCount(); i++) {
5876 int id = list.Item(i);
5878 for (
size_t j = 0; j < InstrumentPropertyList->GetCount(); j++) {
5879 if (InstrumentPropertyList->Item(j)->m_aInstrument ==
id &&
5880 InstrumentPropertyList->Item(j)->m_Listplace == (
int)i) {
5881 Properties = InstrumentPropertyList->Item(j);
5889 this, wxID_ANY, getInstrumentCaption(
id), Properties);
5893 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5894 OCPN_DBP_STC_SOG,
"%5.1f");
5898 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5899 OCPN_DBP_STC_SOG, 0, g_iDashSpeedMax);
5901 ->SetOptionLabel(g_iDashSpeedMax / 20 + 1, DIAL_LABEL_HORIZONTAL);
5905 ->SetOptionMarker(0.5, DIAL_MARKER_SIMPLE, 2);
5907 ->SetOptionExtraValue(OCPN_DBP_STC_STW,
"STW %.1f",
5908 DIAL_POSITION_BOTTOMMIDDLE);
5912 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5913 OCPN_DBP_STC_STW, 0, g_iDashSpeedMax);
5915 ->SetOptionLabel(g_iDashSpeedMax / 20 + 1, DIAL_LABEL_HORIZONTAL);
5919 ->SetOptionMarker(0.5, DIAL_MARKER_SIMPLE, 2);
5921 ->SetOptionExtraValue(OCPN_DBP_STC_SOG,
"SOG %.1f",
5922 DIAL_POSITION_BOTTOMMIDDLE);
5926 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5927 OCPN_DBP_STC_COG,
"%03.0f");
5931 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5932 OCPN_DBP_STC_MCOG,
"%03.0f");
5936 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5939 ->SetOptionMarker(5, DIAL_MARKER_SIMPLE, 2);
5941 ->SetOptionLabel(30, DIAL_LABEL_ROTATED);
5943 ->SetOptionExtraValue(OCPN_DBP_STC_SOG,
"SOG\n%.2f",
5944 DIAL_POSITION_BOTTOMLEFT);
5948 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5951 ->SetOptionMarker(5, DIAL_MARKER_SIMPLE, 2);
5953 ->SetOptionLabel(30, DIAL_LABEL_ROTATED);
5955 ->SetOptionExtraValue(OCPN_DBP_STC_STW,
"STW\n%.1f",
5956 DIAL_POSITION_BOTTOMLEFT);
5960 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5961 OCPN_DBP_STC_STW,
"%.1f");
5966 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5967 OCPN_DBP_STC_HDT,
"%03.0f");
5971 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5972 OCPN_DBP_STC_HDM,
"%03.0f");
5977 getInstrumentCaption(
id),
5978 Properties, OCPN_DBP_STC_AWA);
5980 ->SetOptionMainValue(
"%.0f", DIAL_POSITION_BOTTOMLEFT);
5982 ->SetOptionExtraValue(OCPN_DBP_STC_AWS,
"%.1f",
5983 DIAL_POSITION_INSIDE);
5987 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5988 OCPN_DBP_STC_AWS,
"%.1f");
5992 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5993 OCPN_DBP_STC_AWS, 0, 45);
5995 ->SetOptionLabel(5, DIAL_LABEL_HORIZONTAL);
5997 ->SetOptionMarker(1, DIAL_MARKER_SIMPLE, 5);
5999 ->SetOptionMainValue(
"A %.1f", DIAL_POSITION_BOTTOMLEFT);
6001 ->SetOptionExtraValue(OCPN_DBP_STC_TWS,
"T %.1f",
6002 DIAL_POSITION_BOTTOMRIGHT);
6006 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6009 ->SetOptionMainValue(
"%.0f", DIAL_POSITION_BOTTOMLEFT);
6011 ->SetOptionExtraValue(OCPN_DBP_STC_TWS,
"%.1f",
6012 DIAL_POSITION_INSIDE);
6014 case ID_DBP_D_AWA_TWA:
6016 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6020 ->SetOptionMainValue(
"%.0f", DIAL_POSITION_NONE);
6022 ->SetOptionExtraValue(OCPN_DBP_STC_TWS,
"%.1f", DIAL_POSITION_NONE);
6024 ->SetOptionExtraValue(OCPN_DBP_STC_AWS,
"%.1f", DIAL_POSITION_NONE);
6028 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6031 ->SetOptionMainValue(
"%.0f", DIAL_POSITION_BOTTOMLEFT);
6033 ->SetOptionExtraValue(OCPN_DBP_STC_TWS2,
"%.1f",
6034 DIAL_POSITION_INSIDE);
6038 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6039 OCPN_DBP_STC_ALTI,
"%6.1f");
6043 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6047 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6048 OCPN_DBP_STC_DPT,
"%5.2f");
6052 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6056 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6057 OCPN_DBP_STC_TMP,
"%2.1f");
6061 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6062 OCPN_DBP_STC_MDA,
"%5.1f");
6066 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6067 OCPN_DBP_STC_MDA, 938, 1088);
6069 ->SetOptionLabel(15, DIAL_LABEL_HORIZONTAL);
6071 ->SetOptionMarker(7.5, DIAL_MARKER_SIMPLE, 1);
6073 ->SetOptionMainValue(
"%5.1f", DIAL_POSITION_INSIDE);
6077 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6078 OCPN_DBP_STC_ATMP,
"%2.1f");
6082 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6083 OCPN_DBP_STC_VLW1,
"%2.1f");
6088 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6089 OCPN_DBP_STC_VLW2,
"%2.1f");
6094 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6095 OCPN_DBP_STC_TWA,
"%5.0f");
6099 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6100 OCPN_DBP_STC_TWD,
"%3.0f");
6104 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6105 OCPN_DBP_STC_TWS,
"%2.1f");
6109 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6110 OCPN_DBP_STC_AWA,
"%3.0f");
6114 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6115 OCPN_DBP_STC_VMGW,
"%2.1f");
6119 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6120 OCPN_DBP_STC_VMG,
"%5.1f");
6124 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6125 OCPN_DBP_STC_VMG, 0, g_iDashSpeedMax);
6127 ->SetOptionLabel(1, DIAL_LABEL_HORIZONTAL);
6129 ->SetOptionMarker(0.5, DIAL_MARKER_SIMPLE, 2);
6131 ->SetOptionExtraValue(OCPN_DBP_STC_SOG,
"SOG\n%.1f",
6132 DIAL_POSITION_BOTTOMLEFT);
6136 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6137 OCPN_DBP_STC_RSA,
"%5.0f");
6141 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6145 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6146 OCPN_DBP_STC_SAT,
"%5.0f");
6150 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6154 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6155 OCPN_DBP_STC_PLA, OCPN_DBP_STC_PLO);
6157 case ID_DBP_I_GPSUTC:
6159 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6163 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6167 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6171 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6175 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6179 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6181 case ID_DBP_I_PITCH:
6183 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6184 OCPN_DBP_STC_PITCH,
"%2.1f");
6188 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6189 OCPN_DBP_STC_HEEL,
"%2.1f");
6193 case ID_DBP_I_SUNLCL:
6195 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6196 "%02i:%02i:%02i LCL");
6198 case ID_DBP_I_GPSLCL:
6200 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6201 OCPN_DBP_STC_CLK,
"%02i:%02i:%02i LCL");
6203 case ID_DBP_I_CPULCL:
6205 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6206 "%02i:%02i:%02i LCL");
6210 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6211 OCPN_DBP_STC_HUM,
"%3.0f");
6215 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6216 OCPN_DBP_STC_WCC,
"%5.1f");
6220 instrument->instrumentTypeId = id;
6222 id, instrument, instrument->GetCapacity()));
6223 itemBoxSizer->Add(instrument, 0, wxEXPAND, 0);
6224 if (itemBoxSizer->GetOrientation() == wxHORIZONTAL) {
6225 itemBoxSizer->AddSpacer(5);
6236 wxSize Hint = wxSize(DefaultWidth, DefaultWidth);
6238 for (
unsigned int i = 0; i < m_ArrayOfInstrument.size(); i++) {
6240 inst->SetMinSize(inst->GetSize(itemBoxSizer->GetOrientation(), Hint));
6241 Hint = inst->GetMinSize();
6246 SetMinSize(itemBoxSizer->GetMinSize());
6249void DashboardWindow::SendSentenceToAllInstruments(DASH_CAP st,
double value,
6251 for (
size_t i = 0; i < m_ArrayOfInstrument.GetCount(); i++) {
6252 if (m_ArrayOfInstrument.Item(i)->m_cap_flag.test(st))
6253 m_ArrayOfInstrument.Item(i)->m_pInstrument->SetData(st, value,
unit);
6257void DashboardWindow::SendSatInfoToAllInstruments(
int cnt,
int seq,
6260 for (
size_t i = 0; i < m_ArrayOfInstrument.GetCount(); i++) {
6261 if ((m_ArrayOfInstrument.Item(i)->m_cap_flag.test(OCPN_DBP_STC_GPS)) &&
6263 m_ArrayOfInstrument.Item(i)->m_pInstrument))
6265 ->SetSatInfo(cnt, seq, talk, sats);
6269void DashboardWindow::SendUtcTimeToAllInstruments(wxDateTime value) {
6270 for (
size_t i = 0; i < m_ArrayOfInstrument.GetCount(); i++) {
6271 if ((m_ArrayOfInstrument.Item(i)->m_cap_flag.test(OCPN_DBP_STC_CLK)) &&
6273 m_ArrayOfInstrument.Item(i)->m_pInstrument))
6281 ->SetUtcTime(value);
6297bool OCPNFontButton::Create(wxWindow *parent, wxWindowID
id,
6298 const wxFontData &initial,
const wxPoint &pos,
6299 const wxSize &size,
long style,
6300 const wxValidator &validator,
6301 const wxString &name) {
6302 wxString label = (style & wxFNTP_FONTDESC_AS_LABEL)
6308 if (!wxButton::Create(parent,
id, label, pos, size, style, validator, name)) {
6309 wxFAIL_MSG(
"OCPNFontButton creation failed");
6314 Connect(GetId(), wxEVT_BUTTON,
6315 wxCommandEventHandler(OCPNFontButton::OnButtonClick), NULL,
this);
6319 initial.GetChosenFont().IsOk() ? initial.GetChosenFont() : *wxNORMAL_FONT;
6325void OCPNFontButton::OnButtonClick(wxCommandEvent &WXUNUSED(ev)) {
6327 m_data.SetInitialFont(m_selectedFont);
6332 int display_height = wxGetDisplaySize().y;
6333 if (display_height < 800) {
6337 if (dlg.ShowModal() == wxID_OK) {
6338 m_data = dlg.GetFontData();
6339 m_selectedFont = m_data.GetChosenFont();
6341 wxFontPickerEvent event(
this, GetId(), m_selectedFont);
6342 GetEventHandler()->ProcessEvent(event);
6347 wxFontDialog dlg(
this, m_data);
6349 if (dlg.ShowModal() == wxID_OK) {
6350 m_data = dlg.GetFontData();
6351 m_selectedFont = m_data.GetChosenFont();
6353 wxFontPickerEvent event(
this, GetId(), m_selectedFont);
6354 GetEventHandler()->ProcessEvent(event);
6361 wxFontDialog dlg(
this, m_data);
6367 wxSize proposed_size = GetParent()->GetSize();
6369 float font_size = pF->GetPointSize();
6371 if ((proposed_size.y / font_size) < n_lines) {
6372 float new_font_size = proposed_size.y / n_lines;
6373 wxFont *smallFont =
new wxFont(*pF);
6374 smallFont->SetPointSize(new_font_size);
6375 dlg.SetFont(*smallFont);
6378 dlg.SetSize(GetParent()->GetSize());
6382 if (dlg.ShowModal() == wxID_OK) {
6383 m_data = dlg.GetFontData();
6384 m_selectedFont = m_data.GetChosenFont();
6387 wxFontPickerEvent event(
this, GetId(), m_selectedFont);
6388 GetEventHandler()->ProcessEvent(event);
6395void OCPNFontButton::UpdateFont() {
6396 if (!m_selectedFont.IsOk())
return;
6401 if (HasFlag(wxFNTP_USEFONT_FOR_LABEL)) {
6403 wxButton::SetFont(m_selectedFont);
6404 wxButton::SetForegroundColour(GetSelectedColour());
6408 wxString::Format(
"%s, %d", m_selectedFont.GetFaceName().c_str(),
6409 m_selectedFont.GetPointSize());
6411 if (HasFlag(wxFNTP_FONTDESC_AS_LABEL)) {
6415 auto minsize = GetTextExtent(label);
6418 GetParent()->Layout();
6425 wxWindowID
id,
const wxString &title,
const wxPoint &pos,
6426 const wxSize &size,
long style)
6427 : wxDialog(parent, id, title, pos, size, style) {
6428 this->SetSizeHints(wxDefaultSize, wxDefaultSize);
6430 wxBoxSizer *bSizer5;
6431 bSizer5 =
new wxBoxSizer(wxVERTICAL);
6433 wxFlexGridSizer *fgSizer2;
6434 fgSizer2 =
new wxFlexGridSizer(0, 2, 0, 0);
6435 fgSizer2->SetFlexibleDirection(wxBOTH);
6436 fgSizer2->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
6438 m_staticText1 =
new wxStaticText(
this, wxID_ANY, _(
"Title:"),
6439 wxDefaultPosition, wxDefaultSize, 0);
6440 m_staticText1->Wrap(-1);
6441 fgSizer2->Add(m_staticText1, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6443 m_fontPicker2 =
new wxFontPickerCtrl(
this, wxID_ANY, Properties.m_USTitleFont,
6444 wxDefaultPosition, wxDefaultSize);
6445 fgSizer2->Add(m_fontPicker2, 0, wxALL, 5);
6447 m_staticText5 =
new wxStaticText(
this, wxID_ANY, _(
"Title background color:"),
6448 wxDefaultPosition, wxDefaultSize, 0);
6449 m_staticText5->Wrap(-1);
6450 fgSizer2->Add(m_staticText5, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6452 m_colourPicker1 =
new wxColourPickerCtrl(
6453 this, wxID_ANY, Properties.m_TitleBackgroundColour, wxDefaultPosition,
6454 wxDefaultSize, wxCLRP_DEFAULT_STYLE);
6455 fgSizer2->Add(m_colourPicker1, 0, wxALL, 5);
6457 m_staticText2 =
new wxStaticText(
this, wxID_ANY, _(
"Data:"),
6458 wxDefaultPosition, wxDefaultSize, 0);
6459 m_staticText2->Wrap(-1);
6460 fgSizer2->Add(m_staticText2, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6462 m_fontPicker4 =
new wxFontPickerCtrl(
this, wxID_ANY, Properties.m_USDataFont,
6463 wxDefaultPosition, wxDefaultSize);
6464 fgSizer2->Add(m_fontPicker4, 0, wxALL, 5);
6466 m_staticText6 =
new wxStaticText(
this, wxID_ANY, _(
"Data background color:"),
6467 wxDefaultPosition, wxDefaultSize, 0);
6468 m_staticText6->Wrap(-1);
6469 fgSizer2->Add(m_staticText6, 0, wxALL, 5);
6471 m_colourPicker2 =
new wxColourPickerCtrl(
6472 this, wxID_ANY, Properties.m_DataBackgroundColour, wxDefaultPosition,
6473 wxDefaultSize, wxCLRP_DEFAULT_STYLE);
6474 fgSizer2->Add(m_colourPicker2, 0, wxALL, 5);
6476 m_staticText3 =
new wxStaticText(
this, wxID_ANY, _(
"Label:"),
6477 wxDefaultPosition, wxDefaultSize, 0);
6478 m_staticText3->Wrap(-1);
6479 fgSizer2->Add(m_staticText3, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6481 m_fontPicker5 =
new wxFontPickerCtrl(
this, wxID_ANY, Properties.m_USLabelFont,
6482 wxDefaultPosition, wxDefaultSize);
6483 fgSizer2->Add(m_fontPicker5, 0, wxALL, 5);
6485 m_staticText4 =
new wxStaticText(
this, wxID_ANY, _(
"Small:"),
6486 wxDefaultPosition, wxDefaultSize, 0);
6487 m_staticText4->Wrap(-1);
6488 fgSizer2->Add(m_staticText4, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6490 m_fontPicker6 =
new wxFontPickerCtrl(
this, wxID_ANY, Properties.m_USSmallFont,
6491 wxDefaultPosition, wxDefaultSize);
6492 fgSizer2->Add(m_fontPicker6, 0, wxALL, 5);
6494 m_staticText9 =
new wxStaticText(
this, wxID_ANY, _(
"Arrow 1 Color :"),
6495 wxDefaultPosition, wxDefaultSize, 0);
6496 m_staticText9->Wrap(-1);
6497 fgSizer2->Add(m_staticText9, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6499 m_colourPicker3 =
new wxColourPickerCtrl(
6500 this, wxID_ANY, Properties.m_Arrow_First_Colour, wxDefaultPosition,
6501 wxDefaultSize, wxCLRP_DEFAULT_STYLE);
6502 fgSizer2->Add(m_colourPicker3, 0, wxALL, 5);
6504 m_staticText10 =
new wxStaticText(
this, wxID_ANY, _(
"Arrow 2 Color :"),
6505 wxDefaultPosition, wxDefaultSize, 0);
6506 m_staticText10->Wrap(-1);
6507 fgSizer2->Add(m_staticText10, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6509 m_colourPicker4 =
new wxColourPickerCtrl(
6510 this, wxID_ANY, Properties.m_Arrow_Second_Colour, wxDefaultPosition,
6511 wxDefaultSize, wxCLRP_DEFAULT_STYLE);
6512 fgSizer2->Add(m_colourPicker4, 0, wxALL, 5);
6514 m_staticline1 =
new wxStaticLine(
this, wxID_ANY, wxDefaultPosition,
6515 wxDefaultSize, wxLI_HORIZONTAL);
6516 fgSizer2->Add(m_staticline1, 0, wxEXPAND | wxALL, 5);
6518 m_staticline2 =
new wxStaticLine(
this, wxID_ANY, wxDefaultPosition,
6519 wxDefaultSize, wxLI_HORIZONTAL);
6520 fgSizer2->Add(m_staticline2, 0, wxEXPAND | wxALL, 5);
6522 fgSizer2->Add(0, 5, 1, wxEXPAND, 5);
6524 fgSizer2->Add(0, 0, 1, wxEXPAND, 5);
6526 m_staticText7 =
new wxStaticText(
this, wxID_ANY, wxEmptyString,
6527 wxDefaultPosition, wxDefaultSize, 0);
6528 m_staticText7->Wrap(-1);
6529 fgSizer2->Add(m_staticText7, 0, wxALL, 5);
6531 m_button1 =
new wxButton(
this, wxID_ANY, _(
"Set default"), wxDefaultPosition,
6533 fgSizer2->Add(m_button1, 0, wxALL, 5);
6535 fgSizer2->Add(0, 5, 1, wxEXPAND, 5);
6537 fgSizer2->Add(5, 0, 1, wxEXPAND, 5);
6539 bSizer5->Add(fgSizer2, 1, wxALL | wxEXPAND, 5);
6541 m_sdbSizer3 =
new wxStdDialogButtonSizer();
6542 m_sdbSizer3OK =
new wxButton(
this, wxID_OK);
6543 m_sdbSizer3->AddButton(m_sdbSizer3OK);
6544 m_sdbSizer3Cancel =
new wxButton(
this, wxID_CANCEL);
6545 m_sdbSizer3->AddButton(m_sdbSizer3Cancel);
6546 m_sdbSizer3->Realize();
6548 bSizer5->Add(m_sdbSizer3, 0, 0, 1);
6550 bSizer5->Add(0, 10, 0, wxEXPAND, 5);
6552 this->SetSizer(bSizer5);
6556 this->Centre(wxBOTH);
6559 m_button1->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
6560 wxCommandEventHandler(EditDialog::OnSetdefault), NULL,
6564EditDialog::~EditDialog() {
6566 m_button1->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED,
6567 wxCommandEventHandler(EditDialog::OnSetdefault), NULL,
6571void EditDialog::OnSetdefault(wxCommandEvent &event) {
6572 m_fontPicker2->SetSelectedFont(g_USFontTitle.GetChosenFont());
6573 m_fontPicker2->SetSelectedColour(g_USFontTitle.GetColour());
6574 m_fontPicker4->SetSelectedFont(g_USFontData.GetChosenFont());
6575 m_fontPicker4->SetSelectedColour(g_USFontData.GetColour());
6576 m_fontPicker5->SetSelectedFont(g_USFontLabel.GetChosenFont());
6577 m_fontPicker5->SetSelectedColour(g_USFontLabel.GetColour());
6578 m_fontPicker6->SetSelectedFont(g_USFontSmall.GetChosenFont());
6579 m_fontPicker6->SetSelectedColour(g_USFontSmall.GetColour());
6581 GetGlobalColor(
"DASHL", &dummy);
6582 m_colourPicker1->SetColour(dummy);
6583 GetGlobalColor(
"DASHB", &dummy);
6584 m_colourPicker2->SetColour(dummy);
6585 GetGlobalColor(
"DASHN", &dummy);
6586 m_colourPicker3->SetColour(dummy);
6587 GetGlobalColor(
"BLUE3", &dummy);
6588 m_colourPicker4->SetColour(dummy);
6594void dashboard_pi::UpdateSumLog(
bool write) {
6596 g_dSumLogNM += d_tripNM;
6599 if (++confprint > 10) {
6600 wxFileConfig *logConf = (wxFileConfig *)m_pconfig;
6602 logConf->SetPath(
"/PlugIns/Dashboard");
6603 logConf->Write(
"SumLogNM", g_dSumLogNM);
6609 if (g_bUseInternSumLog) {
6610 SendSentenceToAllInstruments(
6619 SendSentenceToAllInstruments(
6623 mLOG_Watchdog = no_nav_watchdog_timeout_ticks;
A dashboard instrument that displays the current computer time.
A dashboard instrument that displays the GNSS clock time, if available.
A dashboard instrument that displays current moon phase information.
A dashboard instrument that displays sunrise and sunset times.
Custom event class for OpenCPN's notification system.
Extended position fix information.
int nSats
Number of satellites used in the fix.
double Var
Magnetic variation in degrees, typically from RMC message.
double Cog
Course over ground in degrees [0-360).
double Lat
Latitude in decimal degrees.
double Hdm
Heading magnetic in degrees [0-360).
time_t FixTime
UTC time of fix.
double Lon
Longitude in decimal degrees.
double Sog
Speed over ground in knots.
double Hdt
Heading true in degrees [0-360).
void SetCursorLatLon(double lat, double lon)
Receives cursor lat/lon position updates.
void ShowPreferencesDialog(wxWindow *parent)
Shows the plugin preferences dialog.
void OnToolbarToolCallback(int id)
Handles toolbar tool clicks.
void SetColorScheme(PI_ColorScheme cs)
Updates plugin color scheme.
void SetPositionFixEx(PlugIn_Position_Fix_Ex &pfix)
Updates plugin with extended position fix data at regular intervals.
int GetToolbarToolCount(void)
Returns the number of toolbar tools this plugin provides.
wxString GetCommonName()
Get the plugin's common (short) name.
wxString GetShortDescription()
Get a brief description of the plugin.
void UpdateAuiStatus(void)
Updates AUI manager status.
int GetAPIVersionMinor()
Returns the minor version number of the plugin API that this plugin supports.
wxBitmap * GetPlugInBitmap()
Get the plugin's icon bitmap.
void SetNMEASentence(wxString &sentence)
Receive all NMEA 0183 sentences from OpenCPN.
int GetAPIVersionMajor()
Returns the major version number of the plugin API that this plugin supports.
wxString GetLongDescription()
Get detailed plugin information.
int GetPlugInVersionMinor()
Returns the minor version number of the plugin itself.
bool DeInit(void)
Clean up plugin resources.
int Init(void)
Initialize the plugin and declare its capabilities.
int GetPlugInVersionMajor()
Returns the major version number of the plugin itself.
Base class for OpenCPN plugins.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
bool IsArray() const
Return TRUE if the type of the value stored is an array type.
int Size() const
Return the size of the array or map stored in this value.
bool HasMember(unsigned index) const
Return TRUE if the object contains an element at the specified index.
double AsDouble() const
Return the stored value as a double.
bool IsString() const
Return TRUE if the type of the value stored is a wxString object.
wxString AsString() const
Return the stored value as a wxWidget's string.
#define WANTS_NMEA_EVENTS
Receive decoded NMEA events with parsed data.
PI_ColorScheme
Color schemes for different lighting conditions.
#define USES_AUI_MANAGER
Plugin uses wxAuiManager for window management.
#define WANTS_NMEA_SENTENCES
Receive raw NMEA 0183 sentences from all active ports.
#define WANTS_PREFERENCES
Plugin will add page(s) to global preferences dialog.
#define WANTS_CONFIG
Plugin requires persistent configuration storage.
#define WANTS_PLUGIN_MESSAGING
Enable message passing between plugins.
#define INSTALLS_TOOLBAR_TOOL
Plugin will add one or more toolbar buttons.
#define WANTS_CURSOR_LATLON
Receive updates when cursor moves over chart.
#define WANTS_TOOLBAR_CALLBACK
Receive notification when user left-clicks plugin's toolbar buttons.
double toUsrTemp_Plugin(double cel_temp, int unit)
Converts Celsius to user's preferred temperature unit.
wxWindow * GetOCPNCanvasWindow()
Gets OpenCPN's main canvas window.
wxFont * OCPNGetFont(wxString TextElement, int default_size)
Gets a font for UI elements.
wxString getUsrDistanceUnit_Plugin(int unit)
Gets display string for user's preferred distance unit.
wxFileConfig * GetOCPNConfigObject()
Gets OpenCPN's configuration object.
wxBitmap GetBitmapFromSVGFile(wxString filename, unsigned int width, unsigned int height)
Creates bitmap from SVG file.
double toUsrDistance_Plugin(double nm_distance, int unit)
Converts nautical miles to user's preferred distance unit.
int InsertPlugInToolSVG(wxString label, wxString SVGfile, wxString SVGfileRollover, wxString SVGfileToggled, wxItemKind kind, wxString shortHelp, wxString longHelp, wxObject *clientData, int position, int tool_sel, opencpn_plugin *pplugin)
Adds a tool using SVG graphics.
wxString getUsrSpeedUnit_Plugin(int unit)
Gets display string for user's preferred speed unit.
wxString * GetpSharedDataLocation()
Gets shared application data location.
void DimeWindow(wxWindow *win)
Applies system color scheme to window.
double GetOCPNGUIToolScaleFactor_PlugIn()
Gets current global GUI scaling factor.
wxString getUsrTempUnit_Plugin(int unit)
Gets display string for user's preferred temperature unit.
wxString GetActiveStyleName()
Gets name of currently active style sheet.
bool DecodeSingleVDOMessage(const wxString &str, PlugIn_Position_Fix_Ex *pos, wxString *accumulator)
Decodes a single VDO (Own Ship AIS) message.
wxAuiManager * GetFrameAuiManager()
Gets main frame AUI manager.
double toUsrSpeed_Plugin(double kts_speed, int unit)
Converts knots to user's preferred speed unit.
std::vector< std::string > GetActivePriorityIdentifiers()
Gets list of active priority identifiers.
void SetToolbarItemState(int item, bool toggle)
Sets toolbar item toggle state.
double OCPN_GetWinDIPScaleFactor()
Gets Windows-specific DPI scaling factor.
bool AddLocaleCatalog(wxString catalog)
Adds a locale catalog for translations.
double fromUsrDistance_Plugin(double usr_distance, int unit)
Converts from user's preferred distance unit to nautical miles.
shared_ptr< ObservableListener > GetListener(NMEA2000Id id, wxEventType et, wxEvtHandler *eh)
Gets listener for NMEA 2000 messages.
std::string GetN2000Source(NMEA2000Id id, ObservedEvt ev)
Return source identifier (iface) of a received n2000 message of type id in ev.
vector< uint8_t > GetN2000Payload(NMEA2000Id id, ObservedEvt ev)
Return N2K payload for a received n2000 message of type id in ev.
Identifier for NMEA 2000 message types.