36#include <wx/filename.h>
37#include <wx/fontdlg.h>
41#include "manual/manual.h"
52#include "jsonreader.h"
53#include "jsonwriter.h"
56wxFontData *g_pFontTitle;
57wxFontData *g_pFontData;
58wxFontData *g_pFontLabel;
59wxFontData *g_pFontSmall;
61wxFontData g_FontTitle;
63wxFontData g_FontLabel;
64wxFontData g_FontSmall;
66wxFontData *g_pUSFontTitle;
67wxFontData *g_pUSFontData;
68wxFontData *g_pUSFontLabel;
69wxFontData *g_pUSFontSmall;
71wxFontData g_USFontTitle;
72wxFontData g_USFontData;
73wxFontData g_USFontLabel;
74wxFontData g_USFontSmall;
83int g_iDashDistanceUnit;
84int g_iDashWindSpeedUnit;
86double g_dDashDBTOffset;
87bool g_bUseInternSumLog;
90int logCount, confprint;
91bool g_bDBtrueWindGround;
95int g_dashPrefWidth, g_dashPrefHeight;
97wxColor g_BackgroundColor;
98bool g_ForceBackgroundColor;
99wxAlignment g_TitleAlignment;
100double g_TitleVerticalOffset;
103wxAlignment g_DataAlignment;
105int g_iInstrumentSpacing;
109static const long long lNaN = 0xfff8000000000000;
110#define NAN (*(double *)&lNaN)
123extern "C" DECL_EXP
void destroy_pi(
opencpn_plugin *p) {
delete p; }
127QString qtStyleSheet =
128 "QScrollBar:horizontal {\
129border: 0px solid grey;\
130background-color: rgb(240, 240, 240);\
132margin: 0px 1px 0 1px;\
134QScrollBar::handle:horizontal {\
135background-color: rgb(200, 200, 200);\
139QScrollBar::add-line:horizontal {\
140border: 0px solid grey;\
143subcontrol-position: right;\
144subcontrol-origin: margin;\
146QScrollBar::sub-line:horizontal {\
147border: 0px solid grey;\
150subcontrol-position: left;\
151subcontrol-origin: margin;\
153QScrollBar:vertical {\
154border: 0px solid grey;\
155background-color: rgb(240, 240, 240);\
157margin: 1px 0px 1px 0px;\
159QScrollBar::handle:vertical {\
160background-color: rgb(200, 200, 200);\
164QScrollBar::add-line:vertical {\
165border: 0px solid grey;\
168subcontrol-position: top;\
169subcontrol-origin: margin;\
171QScrollBar::sub-line:vertical {\
172border: 0px solid grey;\
175subcontrol-position: bottom;\
176subcontrol-origin: margin;\
181QCheckBox::indicator {\
190#include <QtWidgets/QScroller>
262bool IsObsolete(
int id) {
return id == ID_DBP_D_AWA; }
264wxString getInstrumentCaption(
unsigned int id) {
267 return _(
"Position");
271 return _(
"Speed SOG");
273 return _(
"Speed STW");
279 return _(
"GNSS Compass");
281 return _(
"True Compass");
285 return _(
"True HDG");
290 return _(
"App. Wind Angle & Speed");
291 case ID_DBP_D_AWA_TWA:
292 return _(
"App & True Wind Angle");
295 return _(
"App. Wind Speed");
297 return _(
"True Wind Angle & Speed");
299 return _(
"Altitude");
301 return _(
"Altitude Trace");
307 return _(
"Barometric pressure");
309 return _(
"Water Temp.");
311 return _(
"Air Temp.");
313 return _(
"App. Wind Angle");
315 return _(
"True Wind Angle");
317 return _(
"True Wind Direction");
319 return _(
"True Wind Speed");
321 return _(
"True Wind Dir. & Speed");
326 return _(
"VMG Wind");
329 return _(
"Rudder Angle");
331 return _(
"GNSS in use");
333 return _(
"GNSS Status");
336 case ID_DBP_I_GPSUTC:
337 return _(
"GNSS Clock");
339 return _(
"Sunrise/Sunset");
341 return _(
"Moon phase");
343 return _(
"Wind history");
345 return _(
"Barometric history");
347 return _(
"Trip Log");
351 return _(
"From Ownship");
357 return _(
"Local GNSS Clock");
359 return _(
"Local CPU Clock");
361 return _(
"Local Sunrise/Sunset");
363 return _(
"Humidity");
365 return _(
"Windlass");
371void getListItemForInstrument(wxListItem &item,
unsigned int id) {
373 item.SetText(getInstrumentCaption(
id));
396 case ID_DBP_I_GPSUTC:
418 case ID_DBP_D_AWA_TWA:
433 assert(
false &&
"Illegal instrument ID");
438int GetRandomNumber(
int range_min,
int range_max) {
439 long u = (long)wxRound(
440 ((
double)rand() / ((
double)(RAND_MAX) + 1) * (range_max - range_min)) +
451 int time_hi_and_version;
452 int clock_seq_hi_and_rsv;
458 uuid.time_low = GetRandomNumber(
461 uuid.time_mid = GetRandomNumber(0, 65535);
462 uuid.time_hi_and_version = GetRandomNumber(0, 65535);
463 uuid.clock_seq_hi_and_rsv = GetRandomNumber(0, 255);
464 uuid.clock_seq_low = GetRandomNumber(0, 255);
465 uuid.node_hi = GetRandomNumber(0, 65535);
466 uuid.node_low = GetRandomNumber(0, 2147483647);
470 uuid.clock_seq_hi_and_rsv = (uuid.clock_seq_hi_and_rsv & 0x3F) | 0x80;
474 uuid.time_hi_and_version = (uuid.time_hi_and_version & 0x0fff) | 0x4000;
476 str.Printf(
"%08x-%04x-%04x-%02x%02x-%04x%08x", uuid.time_low, uuid.time_mid,
477 uuid.time_hi_and_version, uuid.clock_seq_hi_and_rsv,
478 uuid.clock_seq_low, uuid.node_hi, uuid.node_low);
483wxString MakeName() {
return "DASH_" + GetUUID(); }
491dashboard_pi::dashboard_pi(
void *ppimgr)
496 m_cog_filter.SetType(IIRFILTER_TYPE_DEG);
497 m_awa_filter.SetType(IIRFILTER_TYPE_DEG);
498 m_aws_filter.SetType(IIRFILTER_TYPE_LINEAR);
501dashboard_pi::~dashboard_pi() {
502 delete _img_dashboard_pi;
503 delete _img_dashboard;
505 delete _img_instrument;
516 m_pri_heading_t = 99;
517 m_pri_heading_m = 99;
519 m_pri_date_time = 99;
528 m_pri_sat_status = 99;
533 m_pri_pitch_roll = 99;
535 m_config_version = -1;
538 m_sats_used_wdog = 2;
539 m_sat_status_wdog = 2;
540 m_pri_n2_k_talker = 2;
544 m_dpt_dbt_watchdog = 2;
554 m_pitch_watchdog = 2;
558 m_tr_log_watchdog = 2;
562 g_pFontTitle =
new wxFontData();
563 g_pFontTitle->SetChosenFont(
564 wxFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL));
566 g_pFontData =
new wxFontData();
567 g_pFontData->SetChosenFont(
568 wxFont(14, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
570 g_pFontLabel =
new wxFontData();
571 g_pFontLabel->SetChosenFont(
572 wxFont(8, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
574 g_pFontSmall =
new wxFontData();
575 g_pFontSmall->SetChosenFont(
576 wxFont(8, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
578 g_pUSFontTitle = &g_USFontTitle;
579 g_pUSFontData = &g_USFontData;
580 g_pUSFontLabel = &g_USFontLabel;
581 g_pUSFontSmall = &g_USFontSmall;
584 m_pauimgr->Connect(wxEVT_AUI_PANE_CLOSE,
585 wxAuiManagerEventHandler(dashboard_pi::OnPaneClose),
601 wxFileName::GetPathSeparator() +
"dashboard_pi" +
602 wxFileName::GetPathSeparator() +
"data" +
603 wxFileName::GetPathSeparator();
605 wxString normalIcon = shareLocn +
"Dashboard.svg";
606 wxString toggledIcon = shareLocn +
"Dashboard_toggled.svg";
607 wxString rolloverIcon = shareLocn +
"Dashboard_rollover.svg";
618 "", normalIcon, rolloverIcon, toggledIcon, wxITEM_CHECK, _(
"Dashboard"),
619 "",
nullptr, DASHBOARD_TOOL_POSITION, 0,
this);
624 if (m_config_version == 1) {
629 logCount = confprint = 0;
631 if (g_bUseInternSumLog) UpdateSumLog(
false);
639 listener_127245 =
GetListener(id_127245, EVT_N2K_127245,
this);
640 Bind(EVT_N2K_127245, [&](
ObservedEvt &ev) { HandleN2K_127245(ev); });
645 listener_127257 =
GetListener(id_127257, EVT_N2K_127257,
this);
646 Bind(EVT_N2K_127257, [&](
ObservedEvt &ev) { HandleN2K_127257(ev); });
651 listener_128259 =
GetListener(id_128259, EVT_N2K_128259,
this);
652 Bind(EVT_N2K_128259, [&](
ObservedEvt &ev) { HandleN2K_128259(ev); });
657 listener_128267 =
GetListener(id_128267, EVT_N2K_128267,
this);
658 Bind(EVT_N2K_128267, [&](
ObservedEvt &ev) { HandleN2K_128267(ev); });
663 listener_128275 =
GetListener(id_128275, EVT_N2K_128275,
this);
664 Bind(EVT_N2K_128275, [&](
ObservedEvt &ev) { HandleN2K_128275(ev); });
669 listener_128777 =
GetListener(id_128777, EVT_N2K_128777,
this);
670 Bind(EVT_N2K_128777, [&](
ObservedEvt &ev) { HandleN2K_128777(ev); });
675 listener_129029 =
GetListener(id_129029, EVT_N2K_129029,
this);
676 Bind(EVT_N2K_129029, [&](
ObservedEvt &ev) { HandleN2K_129029(ev); });
681 listener_129540 =
GetListener(id_129540, EVT_N2K_129540,
this);
682 Bind(EVT_N2K_129540, [&](
ObservedEvt &ev) { HandleN2K_129540(ev); });
687 listener_130306 =
GetListener(id_130306, EVT_N2K_130306,
this);
688 Bind(EVT_N2K_130306, [&](
ObservedEvt &ev) { HandleN2K_130306(ev); });
693 listener_130310 =
GetListener(id_130310, EVT_N2K_130310,
this);
694 Bind(EVT_N2K_130310, [&](
ObservedEvt &ev) { HandleN2K_130310(ev); });
699 listener_130313 =
GetListener(id_130313, EVT_N2K_130313,
this);
700 Bind(EVT_N2K_130313, [&](
ObservedEvt &ev) { HandleN2K_130313(ev); });
702 Start(1000, wxTIMER_CONTINUOUS);
714 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
716 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow;
717 if (dashboard_window) {
718 m_pauimgr->DetachPane(dashboard_window);
719 dashboard_window->Close();
720 dashboard_window->Destroy();
721 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow =
nullptr;
725 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
740 if (value.IsDouble()) {
741 d_ret = value.AsDouble();
743 }
else if (value.IsLong()) {
744 long i_ret = value.AsLong();
745 d_ret =
static_cast<double>(i_ret);
751void dashboard_pi::Notify() {
752 SendUtcTimeToAllInstruments(m_utc_date_time);
753 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
755 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow;
756 if (dashboard_window) {
757 dashboard_window->Refresh();
759 wxWindowList list = dashboard_window->GetChildren();
760 wxWindowListNode *node = list.GetFirst();
761 for (
size_t i = 0; i < list.GetCount(); i++) {
762 wxWindow *win = node->GetData();
765 node = node->GetNext();
773 if (m_h_dx_watchdog <= 0) {
775 m_pri_heading_m = 99;
777 m_h_dx_watchdog = gps_watchdog_timeout_ticks;
781 if (m_hdt_watchdog <= 0) {
782 m_pri_heading_t = 99;
784 m_hdt_watchdog = gps_watchdog_timeout_ticks;
788 if (m_var_watchdog <= 0) {
792 m_var_watchdog = gps_watchdog_timeout_ticks;
796 if (m_sats_used_wdog <= 0) {
800 m_sats_used_wdog = gps_watchdog_timeout_ticks;
803 if (m_pri_n2_k_talker < -1e6) m_pri_n2_k_talker = 0;
806 if (m_sat_status_wdog <= 0) {
808 for (
int i = 0; i < 4; i++) {
809 sats[i].SatNumber = 0;
810 sats[i].SignalToNoiseRatio = 0;
812 SendSatInfoToAllInstruments(0, 1, wxEmptyString, sats);
813 SendSatInfoToAllInstruments(0, 2, wxEmptyString, sats);
814 SendSatInfoToAllInstruments(0, 3, wxEmptyString, sats);
815 m_pri_sat_status = 99;
816 m_sat_status_wdog = gps_watchdog_timeout_ticks;
823 std::string satID = PriorityIDs[4].substr(0, PriorityIDs[4].find(
':'));
824 if (satID.find(
"nmea0183") != std::string::npos)
825 m_pri_sat_status = 3;
826 else if (satID.find(
"ignal") != std::string::npos)
827 m_pri_sat_status = 2;
828 else if (satID.find(
"N2k") != std::string::npos) {
829 prioN2kPGNsat = PriorityIDs[4];
830 m_pri_sat_status = 1;
834 if (m_mwva_watchdog <= 0) {
838 m_mwva_watchdog = gps_watchdog_timeout_ticks;
842 if (m_mwvt_watchdog <= 0) {
847 m_mwvt_watchdog = gps_watchdog_timeout_ticks;
850 m_dpt_dbt_watchdog--;
851 if (m_dpt_dbt_watchdog <= 0) {
854 m_dpt_dbt_watchdog = gps_watchdog_timeout_ticks;
858 if (m_stw_watchdog <= 0) {
861 m_stw_watchdog = gps_watchdog_timeout_ticks;
865 if (m_wtp_watchdog <= 0) {
868 m_wtp_watchdog = no_nav_watchdog_timeout_ticks;
871 if (m_rsa_watchdog <= 0) {
874 m_rsa_watchdog = gps_watchdog_timeout_ticks;
877 if (m_vmg_watchdog <= 0) {
879 m_vmg_watchdog = gps_watchdog_timeout_ticks;
882 if (m_vmgw_watchdog <= 0) {
884 m_vmgw_watchdog = gps_watchdog_timeout_ticks;
887 if (m_utc_watchdog <= 0) {
888 m_pri_date_time = 99;
889 m_utc_watchdog = gps_watchdog_timeout_ticks;
892 if (m_atmp_watchdog <= 0) {
895 m_atmp_watchdog = gps_watchdog_timeout_ticks;
898 if (m_wdn_watchdog <= 0) {
901 m_wdn_watchdog = no_nav_watchdog_timeout_ticks;
904 if (m_mda_watchdog <= 0) {
907 m_mda_watchdog = gps_watchdog_timeout_ticks;
910 if (m_pitch_watchdog <= 0) {
911 m_pri_pitch_roll = 99;
913 m_pitch_watchdog = gps_watchdog_timeout_ticks;
916 if (m_heel_watchdog <= 0) {
917 m_pri_pitch_roll = 99;
919 m_heel_watchdog = gps_watchdog_timeout_ticks;
922 if (m_alt_watchdog <= 0) {
925 m_alt_watchdog = gps_watchdog_timeout_ticks;
929 if (m_log_watchdog <= 0) {
930 if (g_bUseInternSumLog) {
934 m_log_watchdog = no_nav_watchdog_timeout_ticks;
938 if (m_tr_log_watchdog <= 0) {
940 m_tr_log_watchdog = no_nav_watchdog_timeout_ticks;
943 if (m_hum_watchdog <= 0) {
946 m_hum_watchdog = no_nav_watchdog_timeout_ticks;
949 if (m_wcc_watchdog <= 0) {
951 m_wcc_watchdog = no_nav_watchdog_timeout_ticks;
968 return _(
"Dashboard PlugIn for OpenCPN");
973 "Dashboard PlugIn for OpenCPN\n\
974Provides navigation instrument display from NMEA source.");
977void dashboard_pi::SendSentenceToAllInstruments(
DASH_CAP st,
double value,
978 const wxString &
unit) {
979 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
981 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow;
982 if (dashboard_window)
983 dashboard_window->SendSentenceToAllInstruments(st, value,
unit);
996void dashboard_pi::SendUtcTimeToAllInstruments(wxDateTime value) {
997 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
999 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow;
1000 if (dashboard_window) dashboard_window->SendUtcTimeToAllInstruments(value);
1004void dashboard_pi::SendSatInfoToAllInstruments(
int cnt,
int seq,
1005 const wxString &talk,
1007 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
1009 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow;
1010 if (dashboard_window)
1011 dashboard_window->SendSatInfoToAllInstruments(cnt, seq, talk, sats);
1017 m_nmea0183 << sentence;
1019 if (m_nmea0183.PreParse()) {
1020 if (m_nmea0183.LastSentenceIDReceived ==
"DBT") {
1021 if (m_pri_depth >= 5) {
1022 if (m_nmea0183.Parse()) {
1029 if (!std::isnan(m_nmea0183.Dbt.DepthMeters))
1030 depth = m_nmea0183.Dbt.DepthMeters;
1031 else if (!std::isnan(m_nmea0183.Dbt.DepthFeet))
1032 depth = m_nmea0183.Dbt.DepthFeet * 0.3048;
1033 else if (!std::isnan(m_nmea0183.Dbt.DepthFathoms))
1034 depth = m_nmea0183.Dbt.DepthFathoms * 1.82880;
1035 if (!std::isnan(depth)) depth += g_dDashDBTOffset;
1036 if (!std::isnan(depth)) {
1037 SendSentenceToAllInstruments(
1042 m_dpt_dbt_watchdog = gps_watchdog_timeout_ticks;
1048 else if (m_nmea0183.LastSentenceIDReceived ==
"DPT") {
1049 if (m_pri_depth >= 4) {
1050 if (m_nmea0183.Parse()) {
1055 double depth = m_nmea0183.Dpt.DepthMeters;
1056 if (!std::isnan(m_nmea0183.Dpt.OffsetFromTransducerMeters)) {
1057 depth += m_nmea0183.Dpt.OffsetFromTransducerMeters;
1059 depth += g_dDashDBTOffset;
1060 if (!std::isnan(depth)) {
1061 SendSentenceToAllInstruments(
1066 m_dpt_dbt_watchdog = gps_watchdog_timeout_ticks;
1072 else if (m_nmea0183.LastSentenceIDReceived ==
"GGA") {
1074 printf(
"GGA mPriPosition=%d mPriSatUsed=%d \tnSat=%d alt=%3.2f\n",
1075 m_pri_position, m_pri_sat_used,
1076 m_nmea0183.Gga.NumberOfSatellitesInUse,
1077 m_nmea0183.Gga.AntennaAltitudeMeters);
1078 if (m_pri_alt >= 3 && (m_pri_position >= 1 || m_pri_sat_used >= 1)) {
1079 if (m_nmea0183.Parse()) {
1080 if (m_nmea0183.Gga.GPSQuality > 0 &&
1081 m_nmea0183.Gga.NumberOfSatellitesInUse >= 5) {
1084 double alt = m_nmea0183.Gga.AntennaAltitudeMeters;
1087 m_alt_watchdog = gps_watchdog_timeout_ticks;
1091 if (m_pri_position >= 4 || m_pri_sat_used >= 3) {
1092 if (m_nmea0183.Parse()) {
1093 if (m_nmea0183.Gga.GPSQuality > 0) {
1094 if (m_pri_position >= 4) {
1098 static_cast<float>(m_nmea0183.Gga.Position.Latitude.Latitude);
1099 int lat_deg_int = (int)(llt / 100);
1100 auto lat_deg =
static_cast<float>(lat_deg_int);
1101 float lat_min = llt - (lat_deg * 100);
1102 lat = lat_deg + (lat_min / 60.);
1103 if (m_nmea0183.Gga.Position.Latitude.Northing == South)
1107 auto lln =
static_cast<float>(
1108 m_nmea0183.Gga.Position.Longitude.Longitude);
1109 int lon_deg_int = (int)(lln / 100);
1110 auto lon_deg =
static_cast<float>(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;
1116 if (m_pri_sat_used >= 3) {
1117 m_sats_in_use = m_nmea0183.Gga.NumberOfSatellitesInUse;
1121 m_sats_used_wdog = gps_watchdog_timeout_ticks;
1135 else if (m_nmea0183.LastSentenceIDReceived ==
"GLL") {
1136 if (m_pri_position >= 3) {
1137 if (m_nmea0183.Parse()) {
1138 if (m_nmea0183.Gll.IsDataValid == NTrue) {
1141 static_cast<float>(m_nmea0183.Gll.Position.Latitude.Latitude);
1142 int lat_deg_int = (int)(llt / 100);
1143 auto lat_deg =
static_cast<float>(lat_deg_int);
1144 float lat_min = llt - (lat_deg * 100);
1145 lat = lat_deg + (lat_min / 60.);
1146 if (m_nmea0183.Gll.Position.Latitude.Northing == South) lat = -lat;
1150 static_cast<float>(m_nmea0183.Gll.Position.Longitude.Longitude);
1151 int lon_deg_int = (int)(lln / 100);
1152 auto lon_deg =
static_cast<float>(lon_deg_int);
1153 float lon_min = lln - (lon_deg * 100);
1154 lon = lon_deg + (lon_min / 60.);
1155 if (m_nmea0183.Gll.Position.Longitude.Easting == West) lon = -lon;
1171 else if (m_nmea0183.LastSentenceIDReceived ==
"GSV") {
1172 if (m_pri_sat_status >= 3 || m_pri_sat_used >= 5) {
1173 if (m_nmea0183.Parse()) {
1174 if (m_nmea0183.Gsv.MessageNumber == 1) {
1177 m_sats_in_view = m_nmea0183.Gsv.SatsInView;
1179 if (m_pri_sat_used >= 5) {
1181 m_nmea0183.Gsv.SatsInView, _T (
""));
1183 m_sats_used_wdog = gps_watchdog_timeout_ticks;
1187 if (m_pri_sat_status >= 3) {
1188 SendSatInfoToAllInstruments(
1189 m_sats_in_view, m_nmea0183.Gsv.MessageNumber,
1190 m_nmea0183.TalkerID, m_nmea0183.Gsv.SatInfo);
1191 m_pri_sat_status = 3;
1192 m_sat_status_wdog = gps_watchdog_timeout_ticks;
1198 else if (m_nmea0183.LastSentenceIDReceived ==
"HDG") {
1199 if (m_pri_var >= 3 || m_pri_heading_m >= 3 || m_pri_heading_t >= 7) {
1200 if (m_nmea0183.Parse()) {
1201 if (m_pri_var >= 3) {
1205 if ((!std::isnan(m_nmea0183.Hdg.MagneticVariationDegrees)) &&
1206 0.0 != m_nmea0183.Hdg.MagneticVariationDegrees) {
1208 if (m_nmea0183.Hdg.MagneticVariationDirection == East)
1209 m_var = m_nmea0183.Hdg.MagneticVariationDegrees;
1210 else if (m_nmea0183.Hdg.MagneticVariationDirection == West)
1211 m_var = -m_nmea0183.Hdg.MagneticVariationDegrees;
1215 if (m_pri_heading_m >= 3) {
1216 if (!std::isnan(m_nmea0183.Hdg.MagneticSensorHeadingDegrees)) {
1217 m_pri_heading_m = 3;
1218 m_hdm = m_nmea0183.Hdg.MagneticSensorHeadingDegrees;
1222 if (!std::isnan(m_nmea0183.Hdg.MagneticSensorHeadingDegrees))
1223 m_h_dx_watchdog = gps_watchdog_timeout_ticks;
1227 if (!std::isnan(m_nmea0183.Hdg.MagneticSensorHeadingDegrees)) {
1228 if (!std::isnan(m_var) && (m_pri_heading_t >= 7)) {
1229 m_pri_heading_t = 7;
1230 double heading = m_hdm + m_var;
1233 else if (heading >= 360.0)
1236 m_hdt_watchdog = gps_watchdog_timeout_ticks;
1243 else if (m_nmea0183.LastSentenceIDReceived ==
"HDM") {
1244 if (m_pri_heading_m >= 4 || m_pri_heading_t >= 5) {
1245 if (m_nmea0183.Parse()) {
1246 if (m_pri_heading_m >= 4) {
1247 if (!std::isnan(m_nmea0183.Hdm.DegreesMagnetic)) {
1248 m_pri_heading_m = 4;
1249 m_hdm = m_nmea0183.Hdm.DegreesMagnetic;
1251 m_h_dx_watchdog = gps_watchdog_timeout_ticks;
1257 if (!std::isnan(m_nmea0183.Hdm.DegreesMagnetic)) {
1258 if (!std::isnan(m_var) && (m_pri_heading_t >= 5)) {
1259 m_pri_heading_t = 5;
1260 double heading = m_hdm + m_var;
1263 else if (heading >= 360.0)
1266 m_hdt_watchdog = gps_watchdog_timeout_ticks;
1273 else if (m_nmea0183.LastSentenceIDReceived ==
"HDT") {
1274 if (m_pri_heading_t >= 3) {
1275 if (m_nmea0183.Parse()) {
1276 if (!std::isnan(m_nmea0183.Hdt.DegreesTrue)) {
1278 m_nmea0183.Hdt.DegreesTrue,
"\u00B0T");
1279 m_pri_heading_t = 3;
1280 m_hdt_watchdog = gps_watchdog_timeout_ticks;
1284 }
else if (m_nmea0183.LastSentenceIDReceived ==
"MTA") {
1285 if (m_pri_atmp >= 3) {
1286 if (m_nmea0183.Parse()) {
1288 SendSentenceToAllInstruments(
1292 m_atmp_watchdog = gps_watchdog_timeout_ticks;
1295 }
else if (m_nmea0183.LastSentenceIDReceived ==
"MDA" &&
1296 (m_pri_mda >= 5 || m_pri_atmp >= 5 || m_pri_hum >= 4)) {
1298 if (m_nmea0183.Parse()) {
1304 if (m_pri_mda >= 5 && m_nmea0183.Mda.Pressure > .8 &&
1305 m_nmea0183.Mda.Pressure < 1.1) {
1307 m_nmea0183.Mda.Pressure * 1000,
"hPa");
1309 m_mda_watchdog = no_nav_watchdog_timeout_ticks;
1311 if (m_pri_atmp >= 5) {
1312 double airtemp = m_nmea0183.Mda.AirTemp;
1313 if (!std::isnan(airtemp) && airtemp < 999.0) {
1314 SendSentenceToAllInstruments(
1317 m_atmp_watchdog = no_nav_watchdog_timeout_ticks;
1321 if (m_pri_hum >= 4) {
1322 double humidity = m_nmea0183.Mda.Humidity;
1323 if (!std::isnan(humidity)) {
1325 m_hum_watchdog = no_nav_watchdog_timeout_ticks;
1331 }
else if (m_nmea0183.LastSentenceIDReceived ==
"MTW") {
1332 if (m_pri_wtp >= 4) {
1333 if (m_nmea0183.Parse()) {
1335 SendSentenceToAllInstruments(
1339 m_wtp_watchdog = no_nav_watchdog_timeout_ticks;
1343 }
else if (m_nmea0183.LastSentenceIDReceived ==
"VLW") {
1344 if (m_nmea0183.Parse()) {
1349 SendSentenceToAllInstruments(
1352 g_iDashDistanceUnit),
1354 m_tr_log_watchdog = no_nav_watchdog_timeout_ticks;
1356 if (!g_bUseInternSumLog) {
1357 SendSentenceToAllInstruments(
1360 g_iDashDistanceUnit),
1362 m_log_watchdog = no_nav_watchdog_timeout_ticks;
1368 else if (m_nmea0183.LastSentenceIDReceived ==
"MWD") {
1369 if (m_pri_wdn >= 6) {
1370 if (m_nmea0183.Parse()) {
1373 if (!std::isnan(m_nmea0183.Mwd.WindAngleTrue)) {
1375 SendSentenceToAllInstruments(
1379 m_wdn_watchdog = no_nav_watchdog_timeout_ticks;
1380 }
else if (!std::isnan(m_nmea0183.Mwd.WindAngleMagnetic)) {
1382 if (!std::isnan(m_var)) {
1383 double twd = m_nmea0183.Mwd.WindAngleMagnetic;
1387 }
else if (twd < 0.) {
1392 m_wdn_watchdog = no_nav_watchdog_timeout_ticks;
1395 SendSentenceToAllInstruments(
1398 g_iDashWindSpeedUnit),
1400 SendSentenceToAllInstruments(
1403 g_iDashWindSpeedUnit),
1405 m_mwvt_watchdog = gps_watchdog_timeout_ticks;
1412 else if (m_nmea0183.LastSentenceIDReceived ==
"MWV") {
1413 if (m_pri_awa >= 4 || m_pri_twa >= 5 || m_pri_wdn >= 5) {
1414 if (m_nmea0183.Parse()) {
1415 if (m_nmea0183.Mwv.IsDataValid == NTrue) {
1418 double m_wSpeedFactor = 1.0;
1419 if (m_nmea0183.Mwv.WindSpeedUnits ==
"K")
1420 m_wSpeedFactor = 0.53995;
1421 if (m_nmea0183.Mwv.WindSpeedUnits ==
"M")
1422 m_wSpeedFactor = 1.94384;
1424 if (m_nmea0183.Mwv.Reference ==
"R")
1426 if (m_pri_awa >= 4) {
1430 if (m_nmea0183.Mwv.WindAngle > 180) {
1431 m_awaunit =
"\u00B0L";
1432 m_awaangle = 180.0 - (m_nmea0183.Mwv.WindAngle - 180.0);
1434 m_awaunit =
"\u00B0R";
1435 m_awaangle = m_nmea0183.Mwv.WindAngle;
1438 m_awa_filter.Filter(m_awaangle),
1440 SendSentenceToAllInstruments(
1443 m_aws_filter.Filter(m_nmea0183.Mwv.WindSpeed) *
1445 g_iDashWindSpeedUnit),
1447 m_mwva_watchdog = gps_watchdog_timeout_ticks;
1454 if (m_pri_wdn >= 8) {
1455 CalculateAndUpdateTWDS(
1456 m_nmea0183.Mwv.WindSpeed * m_wSpeedFactor,
1457 m_nmea0183.Mwv.WindAngle);
1459 m_wdn_watchdog = no_nav_watchdog_timeout_ticks;
1460 m_mwvt_watchdog = gps_watchdog_timeout_ticks;
1462 }
else if (m_nmea0183.Mwv.Reference ==
1465 if (m_pri_twa >= 5) {
1469 if (m_nmea0183.Mwv.WindAngle > 180) {
1470 m_twaunit =
"\u00B0L";
1471 m_twaangle = 180.0 - (m_nmea0183.Mwv.WindAngle - 180.0);
1473 m_twaunit =
"\u00B0R";
1474 m_twaangle = m_nmea0183.Mwv.WindAngle;
1479 if (m_pri_wdn >= 7) {
1484 if (g_dHDT < 361. && g_dHDT >= 0.0) {
1485 double g_dCalWdir = (m_nmea0183.Mwv.WindAngle) + g_dHDT;
1486 if (g_dCalWdir > 360.) {
1488 }
else if (g_dCalWdir < 0.) {
1494 m_wdn_watchdog = no_nav_watchdog_timeout_ticks;
1498 SendSentenceToAllInstruments(
1501 g_iDashWindSpeedUnit),
1503 SendSentenceToAllInstruments(
1506 g_iDashWindSpeedUnit),
1508 m_mwvt_watchdog = gps_watchdog_timeout_ticks;
1516 else if (m_nmea0183.LastSentenceIDReceived ==
"RMC") {
1517 if (m_pri_position >= 5 || m_pri_cogsog >= 3 || m_pri_var >= 4 ||
1518 m_pri_date_time >= 3) {
1519 if (m_nmea0183.Parse()) {
1520 if (m_nmea0183.Rmc.IsDataValid == NTrue) {
1521 if (m_pri_position >= 5) {
1525 static_cast<float>(m_nmea0183.Rmc.Position.Latitude.Latitude);
1526 int lat_deg_int = (int)(llt / 100);
1527 auto lat_deg =
static_cast<float>(lat_deg_int);
1528 float lat_min = llt - (lat_deg * 100);
1529 lat = lat_deg + (lat_min / 60.);
1530 if (m_nmea0183.Rmc.Position.Latitude.Northing == South)
1534 auto lln =
static_cast<float>(
1535 m_nmea0183.Rmc.Position.Longitude.Longitude);
1536 int lon_deg_int = (int)(lln / 100);
1537 auto lon_deg =
static_cast<float>(lon_deg_int);
1538 float lon_min = lln - (lon_deg * 100);
1539 lon = lon_deg + (lon_min / 60.);
1540 if (m_nmea0183.Rmc.Position.Longitude.Easting == West) lon = -lon;
1544 if (m_pri_cogsog >= 3) {
1546 if (!std::isnan(m_nmea0183.Rmc.SpeedOverGroundKnots)) {
1547 SendSentenceToAllInstruments(
1550 m_nmea0183.Rmc.SpeedOverGroundKnots),
1555 if (!std::isnan(m_nmea0183.Rmc.TrackMadeGoodDegreesTrue)) {
1556 SendSentenceToAllInstruments(
1558 m_cog_filter.Filter(
1559 m_nmea0183.Rmc.TrackMadeGoodDegreesTrue),
1562 if (!std::isnan(m_nmea0183.Rmc.TrackMadeGoodDegreesTrue) &&
1563 !std::isnan(m_nmea0183.Rmc.MagneticVariation)) {
1564 double dMagneticCOG;
1565 if (m_nmea0183.Rmc.MagneticVariationDirection == East) {
1567 m_cog_filter.get() - m_nmea0183.Rmc.MagneticVariation;
1568 if (dMagneticCOG < 0.0) dMagneticCOG = 360.0 + dMagneticCOG;
1571 m_cog_filter.get() + m_nmea0183.Rmc.MagneticVariation;
1572 if (dMagneticCOG > 360.0) dMagneticCOG = dMagneticCOG - 360.0;
1579 if (m_pri_var >= 4) {
1583 if ((!std::isnan(m_nmea0183.Rmc.MagneticVariation)) &&
1584 0.0 != m_nmea0183.Rmc.MagneticVariation) {
1586 if (m_nmea0183.Rmc.MagneticVariationDirection == East)
1587 m_var = m_nmea0183.Rmc.MagneticVariation;
1588 else if (m_nmea0183.Rmc.MagneticVariationDirection == West)
1589 m_var = -m_nmea0183.Rmc.MagneticVariation;
1590 m_var_watchdog = gps_watchdog_timeout_ticks;
1596 if (m_pri_date_time >= 3) {
1597 m_pri_date_time = 3;
1598 wxString dt = m_nmea0183.Rmc.Date + m_nmea0183.Rmc.UTCTime;
1599 m_utc_date_time.ParseFormat(dt.c_str(),
"%d%m%y%H%M%S");
1600 m_utc_watchdog = gps_watchdog_timeout_ticks;
1607 else if (m_nmea0183.LastSentenceIDReceived ==
"RSA") {
1608 if (m_pri_rsa >= 3) {
1609 if (m_nmea0183.Parse()) {
1610 if (m_nmea0183.Rsa.IsStarboardDataValid == NTrue) {
1612 m_nmea0183.Rsa.Starboard,
"\u00B0");
1613 }
else if (m_nmea0183.Rsa.IsPortDataValid == NTrue) {
1617 m_rsa_watchdog = gps_watchdog_timeout_ticks;
1623 else if (m_nmea0183.LastSentenceIDReceived ==
"VHW") {
1624 if (m_pri_heading_t >= 4 || m_pri_heading_m >= 5 || m_pri_stw >= 3) {
1625 if (m_nmea0183.Parse()) {
1626 if (m_pri_heading_t >= 4) {
1627 if (!std::isnan(m_nmea0183.Vhw.DegreesTrue)) {
1628 m_pri_heading_t = 4;
1629 SendSentenceToAllInstruments(
1631 m_hdt_watchdog = gps_watchdog_timeout_ticks;
1634 if (m_pri_heading_m >= 5) {
1635 if (!std::isnan(m_nmea0183.Vhw.DegreesMagnetic)) {
1636 m_pri_heading_m = 5;
1637 SendSentenceToAllInstruments(
1639 m_h_dx_watchdog = gps_watchdog_timeout_ticks;
1642 if (m_pri_stw >= 3) {
1643 double stw_kn = NAN;
1644 if (!std::isnan(m_nmea0183.Vhw.Knots))
1645 stw_kn = m_nmea0183.Vhw.Knots;
1646 else if (!std::isnan(m_nmea0183.Vhw.KilometersPerHour))
1647 stw_kn = m_nmea0183.Vhw.KilometersPerHour * 0.53995;
1649 if (!std::isnan(stw_kn)) {
1650 SendSentenceToAllInstruments(
1653 m_stw_watchdog = gps_watchdog_timeout_ticks;
1661 else if (m_nmea0183.LastSentenceIDReceived ==
"VTG") {
1662 if (m_pri_cogsog >= 2) {
1663 if (m_nmea0183.Parse()) {
1666 if (!std::isnan(m_nmea0183.Vtg.SpeedKnots)) {
1667 SendSentenceToAllInstruments(
1670 m_sog_filter.Filter(m_nmea0183.Vtg.SpeedKnots),
1675 if (!std::isnan(m_nmea0183.Vtg.TrackDegreesTrue)) {
1676 SendSentenceToAllInstruments(
1678 m_cog_filter.Filter(m_nmea0183.Vtg.TrackDegreesTrue),
"\u00B0");
1691 else if (m_nmea0183.LastSentenceIDReceived ==
"VWR") {
1692 if (m_pri_awa >= 3) {
1693 if (m_nmea0183.Parse()) {
1694 if (m_nmea0183.Vwr.WindDirectionMagnitude < 200) {
1699 m_nmea0183.Vwr.DirectionOfWind == Left ?
"\u00B0L" :
"\u00B0R";
1701 m_nmea0183.Vwr.WindDirectionMagnitude,
1703 SendSentenceToAllInstruments(
1706 g_iDashWindSpeedUnit),
1708 m_mwva_watchdog = gps_watchdog_timeout_ticks;
1719 if (m_pri_wdn >= 9) {
1720 double awa = m_nmea0183.Vwr.WindDirectionMagnitude;
1721 if (m_nmea0183.Vwr.DirectionOfWind == Left)
1722 awa = 360. - m_nmea0183.Vwr.WindDirectionMagnitude;
1723 CalculateAndUpdateTWDS(m_nmea0183.Vwr.WindSpeedKnots, awa);
1725 m_mwvt_watchdog = gps_watchdog_timeout_ticks;
1726 m_wdn_watchdog = no_nav_watchdog_timeout_ticks;
1737 else if (m_nmea0183.LastSentenceIDReceived ==
"VWT") {
1738 if (m_pri_twa >= 4) {
1739 if (m_nmea0183.Parse()) {
1740 if (m_nmea0183.Vwt.WindDirectionMagnitude < 200) {
1744 m_nmea0183.Vwt.DirectionOfWind == Left ?
"\u00B0L" :
"\u00B0R";
1746 m_nmea0183.Vwt.WindDirectionMagnitude,
1748 SendSentenceToAllInstruments(
1751 g_iDashWindSpeedUnit),
1753 m_mwvt_watchdog = gps_watchdog_timeout_ticks;
1763 else if (m_nmea0183.LastSentenceIDReceived ==
1778 if (m_nmea0183.Parse()) {
1781 for (
int i = 0; i < m_nmea0183.Xdr.TransducerCnt; i++) {
1782 xdrdata = m_nmea0183.Xdr.TransducerInfo[i].MeasurementData;
1784 if (m_nmea0183.Xdr.TransducerInfo[i].TransducerType ==
"C") {
1785 if (m_nmea0183.Xdr.TransducerInfo[i]
1786 .TransducerName.Upper()
1788 m_nmea0183.Xdr.TransducerInfo[i].TransducerName ==
"Te" ||
1789 m_nmea0183.Xdr.TransducerInfo[i].TransducerName ==
1791 m_nmea0183.Xdr.TransducerInfo[i].TransducerName ==
1793 if (m_pri_atmp >= 4) {
1795 SendSentenceToAllInstruments(
1799 m_atmp_watchdog = no_nav_watchdog_timeout_ticks;
1803 if (m_nmea0183.Xdr.TransducerInfo[i]
1804 .TransducerName.Upper()
1805 .Contains(
"WATER") ||
1806 m_nmea0183.Xdr.TransducerInfo[i].TransducerName ==
"WTHI") {
1807 if (m_pri_wtp >= 3) {
1809 SendSentenceToAllInstruments(
1812 m_nmea0183.Xdr.TransducerInfo[i].MeasurementData,
1815 m_wtp_watchdog = no_nav_watchdog_timeout_ticks;
1821 if (m_nmea0183.Xdr.TransducerInfo[i].TransducerType ==
"P") {
1822 if (m_nmea0183.Xdr.TransducerInfo[i]
1823 .TransducerName.Upper()
1824 .Contains(
"BARO") &&
1826 if (m_nmea0183.Xdr.TransducerInfo[i].UnitOfMeasurement ==
"B") {
1830 m_mda_watchdog = no_nav_watchdog_timeout_ticks;
1836 if (m_nmea0183.Xdr.TransducerInfo[i].TransducerType ==
"A") {
1837 if (m_nmea0183.Xdr.TransducerInfo[i].TransducerName.Contains(
1839 m_nmea0183.Xdr.TransducerInfo[i]
1840 .TransducerName.Upper()
1841 .Contains(
"PITCH")) {
1842 if (m_pri_pitch_roll >= 3) {
1843 if (m_nmea0183.Xdr.TransducerInfo[i].MeasurementData > 0) {
1844 xdrunit = L
"\u00B0\u2191" + _(
"Up");
1845 }
else if (m_nmea0183.Xdr.TransducerInfo[i].MeasurementData <
1847 xdrunit = L
"\u00B0\u2193" + _(
"Down");
1854 m_pitch_watchdog = gps_watchdog_timeout_ticks;
1855 m_pri_pitch_roll = 3;
1860 if (m_nmea0183.Xdr.TransducerInfo[i]
1861 .TransducerName.Upper()
1862 .Contains(
"ROLL")) {
1863 if (m_pri_pitch_roll >= 3) {
1864 if (m_nmea0183.Xdr.TransducerInfo[i].MeasurementData > 0) {
1865 xdrunit = L
"\u00B0\u003E" + _(
"Stbd");
1866 }
else if (m_nmea0183.Xdr.TransducerInfo[i].MeasurementData <
1868 xdrunit = L
"\u00B0\u003C" + _(
"Port");
1875 m_heel_watchdog = gps_watchdog_timeout_ticks;
1876 m_pri_pitch_roll = 3;
1881 if (m_nmea0183.Xdr.TransducerInfo[i]
1882 .TransducerName.Upper()
1883 .Contains(
"RUDDER")) {
1884 if (m_pri_rsa > 4) {
1887 m_rsa_watchdog = gps_watchdog_timeout_ticks;
1894 if ((m_nmea0183.Xdr.TransducerInfo[i].TransducerType ==
"D")) {
1895 bool good_depth =
false;
1896 if (m_nmea0183.Xdr.TransducerInfo[i].TransducerName ==
"XDHI" &&
1900 }
else if (m_nmea0183.Xdr.TransducerInfo[i].TransducerName ==
1907 else if (m_nmea0183.Xdr.TransducerInfo[i].TransducerName ==
1909 m_nmea0183.Xdr.TransducerInfo[i].TransducerName ==
1912 m_nmea0183.Xdr.TransducerInfo[i].UnitOfMeasurement;
1913 if (
unit == wxEmptyString)
unit =
"m";
1916 m_wcc_watchdog = no_nav_watchdog_timeout_ticks;
1920 wxString
unit = m_nmea0183.Xdr.TransducerInfo[i]
1921 .UnitOfMeasurement.MakeLower();
1925 if (!std::isnan(depth)) {
1926 depth += g_dDashDBTOffset;
1927 SendSentenceToAllInstruments(
1931 m_dpt_dbt_watchdog = gps_watchdog_timeout_ticks;
1937 if (m_nmea0183.Xdr.TransducerInfo[i].TransducerType ==
"H") {
1938 if (m_pri_hum >= 3) {
1939 if (m_nmea0183.Xdr.TransducerInfo[i].UnitOfMeasurement ==
"P") {
1942 m_hum_watchdog = no_nav_watchdog_timeout_ticks;
1948 }
else if (m_nmea0183.LastSentenceIDReceived ==
"ZDA") {
1949 if (m_pri_date_time >= 2) {
1950 if (m_nmea0183.Parse()) {
1951 m_pri_date_time = 2;
1961 dt.Printf(
"%4d%02d%02d", m_nmea0183.Zda.Year, m_nmea0183.Zda.Month,
1962 m_nmea0183.Zda.Day);
1963 dt.Append(m_nmea0183.Zda.UTCTime);
1964 m_utc_date_time.ParseFormat(dt.c_str(),
"%Y%m%d%H%M%S");
1965 m_utc_watchdog = gps_watchdog_timeout_ticks;
1971 else if (sentence.Mid(1, 5).IsSameAs(
"AIVDO")) {
1974 if (!std::isnan(gpd.
Lat))
1977 if (!std::isnan(gpd.
Lon))
1980 SendSentenceToAllInstruments(
1985 m_cog_filter.Filter(gpd.
Cog),
"\u00B0");
1986 if (!std::isnan(gpd.
Hdt)) {
1988 m_hdt_watchdog = gps_watchdog_timeout_ticks;
1999void dashboard_pi::CalculateAndUpdateTWDS(
double awsKnots,
double awaDegrees) {
2000 if (!std::isnan(g_dHDT)) {
2002 double awsx = awsKnots * cos(awaDegrees * PI / 180.);
2003 double awsy = awsKnots * sin(awaDegrees * PI / 180.);
2008 if ((!std::isnan(g_dSOG)) && (!std::isnan(g_dCOG))) {
2009 bsx = g_dSOG * cos((g_dCOG - g_dHDT) * PI / 180.);
2010 bsy = g_dSOG * sin((g_dCOG - g_dHDT) * PI / 180.);
2015 double twdx = awsx - bsx;
2016 double twdy = awsy - bsy;
2019 double tws = pow(((twdx * twdx) + (twdy * twdy)), 0.5);
2022 double twd = atan2(twdy, twdx) * 180. / PI;
2029 double twdc = twd + g_dHDT;
2032 if (twdc < 0) twdc += 360.;
2033 if (twdc > 360.) twdc -= 360;
2052void dashboard_pi::HandleN2K_127245(
ObservedEvt &ev) {
2057 unsigned char source_id = v.at(7);
2059 sprintf(ss,
"%d", source_id);
2060 std::string ident = std::string(ss);
2062 source +=
":" + ident;
2064 if (m_pri_rsa >= 1) {
2065 if (m_pri_rsa == 1) {
2067 if (source != prio127245)
return;
2070 prio127245 = source;
2073 double RudderPosition, AngleOrder;
2074 unsigned char Instance;
2075 tN2kRudderDirectionOrder RudderDirectionOrder;
2078 if (ParseN2kPGN127245(v, RudderPosition, Instance, RudderDirectionOrder,
2080 if (!N2kIsNA(RudderPosition)) {
2081 double m_rudangle = GEODESIC_RAD2DEG(RudderPosition);
2083 m_rsa_watchdog = gps_watchdog_timeout_ticks;
2091void dashboard_pi::HandleN2K_127257(
ObservedEvt &ev) {
2096 unsigned char source_id = v.at(7);
2098 sprintf(ss,
"%d", source_id);
2099 std::string ident = std::string(ss);
2101 source +=
":" + ident;
2103 if (m_pri_pitch_roll >= 1) {
2104 if (m_pri_pitch_roll == 1) {
2106 if (source != prio127257)
return;
2109 prio127257 = source;
2113 double Yaw, Pitch, Roll;
2116 if (ParseN2kPGN127257(v, SID, Yaw, Pitch, Roll)) {
2117 if (!N2kIsNA(Pitch)) {
2118 double m_pitch = GEODESIC_RAD2DEG(Pitch);
2119 wxString p_unit = L
"\u00B0\u2191" + _(
"Up");
2121 p_unit = L
"\u00B0\u2193" + _(
"Down");
2125 m_pitch_watchdog = gps_watchdog_timeout_ticks;
2126 m_pri_pitch_roll = 1;
2128 if (!N2kIsNA(Roll)) {
2129 double m_heel = GEODESIC_RAD2DEG(Roll);
2130 wxString h_unit = L
"\u00B0\u003E" + _(
"Stbd");
2132 h_unit = L
"\u00B0\u003C" + _(
"Port");
2136 m_heel_watchdog = gps_watchdog_timeout_ticks;
2137 m_pri_pitch_roll = 1;
2143void dashboard_pi::HandleN2K_128267(
ObservedEvt &ev) {
2148 unsigned char source_id = v.at(7);
2150 sprintf(ss,
"%d", source_id);
2151 std::string ident = std::string(ss);
2153 source +=
":" + ident;
2155 if (m_pri_depth >= 1) {
2156 if (m_pri_depth == 1) {
2157 if (source != prio128267)
return;
2159 prio128267 = source;
2163 double DepthBelowTransducer, Offset, Range;
2166 if (ParseN2kPGN128267(v, SID, DepthBelowTransducer, Offset, Range)) {
2167 if (!N2kIsNA(DepthBelowTransducer)) {
2168 double depth = DepthBelowTransducer;
2170 if (!std::isnan(Offset) && !N2kIsNA(Offset))
2173 (depth += g_dDashDBTOffset);
2175 SendSentenceToAllInstruments(
2180 m_dpt_dbt_watchdog = gps_watchdog_timeout_ticks;
2186void dashboard_pi::HandleN2K_128275(
ObservedEvt &ev) {
2189 uint16_t DaysSince1970;
2190 double SecondsSinceMidnight;
2191 uint32_t Log, TripLog;
2194 if (ParseN2kPGN128275(v, DaysSince1970, SecondsSinceMidnight, Log, TripLog)) {
2195 if (!N2kIsNA(Log) && !g_bUseInternSumLog) {
2196 double m_slog = METERS2NM((
double)Log);
2197 SendSentenceToAllInstruments(
2200 m_log_watchdog = no_nav_watchdog_timeout_ticks;
2203 if (!N2kIsNA(TripLog)) {
2204 double m_tlog = METERS2NM((
double)TripLog);
2205 SendSentenceToAllInstruments(
2208 m_tr_log_watchdog = no_nav_watchdog_timeout_ticks;
2212void dashboard_pi::HandleN2K_128259(
ObservedEvt &ev) {
2217 unsigned char source_id = v.at(7);
2219 sprintf(ss,
"%d", source_id);
2220 std::string ident = std::string(ss);
2222 source +=
":" + ident;
2224 if (m_pri_stw >= 1) {
2225 if (m_pri_stw == 1) {
2226 if (source != prio128259)
return;
2228 prio128259 = source;
2232 double WaterReferenced, GroundReferenced;
2233 tN2kSpeedWaterReferenceType SWRT;
2236 if (ParseN2kPGN128259(v, SID, WaterReferenced, GroundReferenced, SWRT)) {
2237 if (!N2kIsNA(WaterReferenced)) {
2238 double stw_knots = MS2KNOTS(WaterReferenced);
2239 SendSentenceToAllInstruments(
2243 m_stw_watchdog = gps_watchdog_timeout_ticks;
2249void dashboard_pi::HandleN2K_128777(
ObservedEvt &ev) {
2254 unsigned char WindlassIdentifier;
2255 double RodeCounterValue;
2256 double WindlassLineSpeed;
2257 tN2kWindlassMotionStates WindlassMotionStatus;
2258 tN2kRodeTypeStates RodeTypeStatus;
2259 tN2kAnchorDockingStates AnchorDockingStatus;
2260 tN2kWindlassOperatingEvents WindlassOperatingEvents;
2262 if (ParseN2kPGN128777(v, SID, WindlassIdentifier, RodeCounterValue,
2263 WindlassLineSpeed, WindlassMotionStatus, RodeTypeStatus,
2264 AnchorDockingStatus, WindlassOperatingEvents)) {
2265 if (!N2kIsNA(RodeCounterValue)) {
2267 m_wcc_watchdog = no_nav_watchdog_timeout_ticks;
2272wxString talker_N2k = wxEmptyString;
2273void dashboard_pi::HandleN2K_129029(
ObservedEvt &ev) {
2277 unsigned char source_id = v.at(7);
2279 sprintf(ss,
"%d", source_id);
2280 std::string ident = std::string(ss);
2282 std::string prio_ID(prioN2kPGNsat.substr(prioN2kPGNsat.find(
':') + 1, 5));
2283 if (prio_ID.find(ident) == std::string::npos)
return;
2286 uint16_t DaysSince1970;
2287 double SecondsSinceMidnight;
2288 double Latitude, Longitude, Altitude;
2289 tN2kGNSStype GNSStype;
2290 tN2kGNSSmethod GNSSmethod;
2291 unsigned char nSatellites;
2292 double HDOP, PDOP, GeoidalSeparation;
2293 unsigned char nReferenceStations;
2294 tN2kGNSStype ReferenceStationType;
2295 uint16_t ReferenceSationID;
2296 double AgeOfCorrection;
2299 if (ParseN2kPGN129029(v, SID, DaysSince1970, SecondsSinceMidnight, Latitude,
2300 Longitude, Altitude, GNSStype, GNSSmethod, nSatellites,
2301 HDOP, PDOP, GeoidalSeparation, nReferenceStations,
2302 ReferenceStationType, ReferenceSationID,
2312 talker_N2k =
"GPSGLONAS";
2318 talker_N2k =
"GPSGLONAS";
2321 talker_N2k =
"Chayka";
2327 talker_N2k = wxEmptyString;
2329 if (!N2kIsNA(Altitude)) {
2330 if (m_pri_alt >= 1) {
2333 m_alt_watchdog = gps_watchdog_timeout_ticks;
2339void dashboard_pi::HandleN2K_129540(
ObservedEvt &ev) {
2344 unsigned char source_id = v.at(7);
2346 sprintf(ss,
"%d", source_id);
2347 std::string ident = std::string(ss);
2349 std::string prio_ID(prioN2kPGNsat.substr(prioN2kPGNsat.find(
':') + 1, 5));
2350 if (prio_ID.find(ident) == std::string::npos)
return;
2353 tN2kRangeResidualMode Mode;
2354 uint8_t NumberOfSVs;
2357 if (ParseN2kPGN129540(v, SID, Mode, NumberOfSVs)) {
2358 if (!N2kIsNA(NumberOfSVs) && m_pri_sat_status == 1) {
2361 SAT_INFO N2K_SatInfo[4];
2364 double dElevRad = 0;
2365 double dAzimRad = 0;
2368 for (
int iMesNum = 0; iMesNum < 3; iMesNum++) {
2369 for (idx = 0; idx < 4; idx++) {
2370 tSatelliteInfo SatelliteInfo;
2371 index = idx + 4 * iMesNum;
2372 if (index >= NumberOfSVs - 1)
break;
2373 if (ParseN2kPGN129540(v, index, SatelliteInfo)) {
2374 iPRN = (int)SatelliteInfo.PRN;
2375 dElevRad = SatelliteInfo.Elevation;
2376 dAzimRad = SatelliteInfo.Azimuth;
2377 iSNR = N2kIsNA(SatelliteInfo.SNR) ? 0 : (int)SatelliteInfo.SNR;
2379 N2K_SatInfo[idx].SatNumber = iPRN;
2380 N2K_SatInfo[idx].ElevationDegrees = GEODESIC_RAD2DEG(dElevRad);
2381 N2K_SatInfo[idx].AzimuthDegreesTrue = GEODESIC_RAD2DEG(dAzimRad);
2382 N2K_SatInfo[idx].SignalToNoiseRatio = iSNR;
2387 SendSatInfoToAllInstruments(NumberOfSVs, iMesNum + 1, talker_N2k,
2390 m_sat_status_wdog = gps_watchdog_timeout_ticks;
2398void dashboard_pi::HandleN2K_130306(
ObservedEvt &ev) {
2406 double WindSpeed, WindAngle;
2407 tN2kWindReference WindReference;
2410 if (ParseN2kPGN130306(v, SID, WindSpeed, WindAngle, WindReference)) {
2411 if (!N2kIsNA(WindSpeed) && !N2kIsNA(WindAngle)) {
2412 double wind_angle_degr = GEODESIC_RAD2DEG(WindAngle);
2413 double wind_speed_kn = MS2KNOTS(WindSpeed);
2414 bool sendTWA =
false, sendTWS =
false;
2416 switch (WindReference) {
2418 if (m_pri_wdn >= 1) {
2423 m_wdn_watchdog = no_nav_watchdog_timeout_ticks;
2427 if (m_pri_wdn >= 1) {
2429 if (!std::isnan(m_var)) {
2430 wind_angle_degr += m_var;
2431 if (wind_angle_degr > 360.) {
2432 wind_angle_degr -= 360;
2433 }
else if (wind_angle_degr < 0.) {
2434 wind_angle_degr += 360;
2441 m_wdn_watchdog = no_nav_watchdog_timeout_ticks;
2445 if (m_pri_awa >= 1) {
2446 double calc_angle = wind_angle_degr;
2448 wxString m_awaunit =
"\u00B0R";
2450 if (wind_angle_degr > 180.0) {
2451 wind_angle_degr = 360.0 - wind_angle_degr;
2452 m_awaunit =
"\u00B0L";
2455 m_awa_filter.Filter(wind_angle_degr),
2458 SendSentenceToAllInstruments(
2461 g_iDashWindSpeedUnit),
2465 m_mwva_watchdog = gps_watchdog_timeout_ticks;
2468 if (m_pri_twa != 1) {
2470 if (calc_angle > 180) calc_angle -= 360.0;
2471 CalculateAndUpdateTWDS(wind_speed_kn, calc_angle);
2474 m_mwvt_watchdog = gps_watchdog_timeout_ticks;
2475 m_wdn_watchdog = no_nav_watchdog_timeout_ticks;
2480 if (m_pri_twa >= 1 && g_bDBtrueWindGround) {
2487 if (m_pri_twa >= 1 && !g_bDBtrueWindGround) {
2501 wxString m_twaunit =
"\u00B0R";
2503 if (wind_angle_degr > 180.0) {
2504 wind_angle_degr = 360.0 - wind_angle_degr;
2505 m_twaunit =
"\u00B0L";
2513 SendSentenceToAllInstruments(
2517 SendSentenceToAllInstruments(
2521 m_mwvt_watchdog = gps_watchdog_timeout_ticks;
2527void dashboard_pi::HandleN2K_130310(
ObservedEvt &ev) {
2531 double WaterTemperature, OutsideAmbientAirTemperature, AtmosphericPressure;
2534 if (ParseN2kPGN130310(v, SID, WaterTemperature, OutsideAmbientAirTemperature,
2535 AtmosphericPressure)) {
2536 if (m_pri_wtp >= 1) {
2537 if (!N2kIsNA(WaterTemperature)) {
2538 double m_wtemp KELVIN2C(WaterTemperature);
2543 m_wtp_watchdog = no_nav_watchdog_timeout_ticks;
2547 if (m_pri_atmp >= 1) {
2548 if (!N2kIsNA(OutsideAmbientAirTemperature)) {
2549 double m_airtemp = KELVIN2C(OutsideAmbientAirTemperature);
2550 if (m_airtemp > -60 && m_airtemp < 100) {
2551 SendSentenceToAllInstruments(
2555 m_atmp_watchdog = no_nav_watchdog_timeout_ticks;
2560 if (!N2kIsNA(AtmosphericPressure) && m_pri_mda >= 1) {
2561 double m_press = PA2HPA(AtmosphericPressure);
2564 m_mda_watchdog = no_nav_watchdog_timeout_ticks;
2569void dashboard_pi::HandleN2K_130313(
ObservedEvt &ev) {
2572 unsigned char SID, HumidityInstance;
2573 tN2kHumiditySource HumiditySource;
2574 double ActualHumidity, SetHumidity;
2576 if (ParseN2kPGN130313(v, SID, HumidityInstance, HumiditySource,
2577 ActualHumidity, SetHumidity)) {
2578 if (m_pri_hum >= 1) {
2579 if (!N2kIsNA(ActualHumidity)) {
2582 m_hum_watchdog = no_nav_watchdog_timeout_ticks;
2589void dashboard_pi::ParseSignalK(wxString &msg) {
2598 jsonReader.
Parse(msg, &root);
2600 if (root[
"self"].AsString().StartsWith(
"vessels."))
2601 m_self = (root[
"self"].
AsString());
2603 else if (root[
"self"].AsString().Length())
2604 m_self =
"vessels." + (root[
"self"].AsString());
2608 auto context = root[
"context"].
AsString();
2609 if (context != m_self) {
2616 for (
int i = 0; i < updates.
Size(); ++i) {
2617 handleSKUpdate(updates[i]);
2622void dashboard_pi::handleSKUpdate(
wxJSONValue &update) {
2623 wxString sfixtime =
"";
2626 sfixtime = update[
"timestamp"].
AsString();
2628 if (update.
HasMember(
"values") && update[
"values"].IsArray()) {
2629 wxString talker = wxEmptyString;
2631 if (update[
"source"].HasMember(
"talker")) {
2632 if (update[
"source"][
"talker"].IsString()) {
2633 talker = update[
"source"][
"talker"].
AsString();
2637 for (
int j = 0; j < update[
"values"].
Size(); ++j) {
2639 updateSKItem(item, talker, sfixtime);
2644void dashboard_pi::updateSKItem(
wxJSONValue &item, wxString &talker,
2645 wxString &sfixtime) {
2647 const wxString &update_path = item[
"path"].
AsString();
2651 static wxString talkerID = wxEmptyString;
2653 static double skAWA;
2655 if (update_path ==
"navigation.position") {
2656 if (m_pri_position >= 2) {
2657 if (value[
"latitude"].IsDouble() && value[
"longitude"].IsDouble()) {
2658 double lat = value[
"latitude"].
AsDouble();
2659 double lon = value[
"longitude"].AsDouble();
2665 }
else if (update_path ==
"navigation.speedOverGround" &&
2666 2 == m_pri_position) {
2667 double sog_knot = GetJsonDouble(value);
2668 if (std::isnan(sog_knot))
return;
2670 SendSentenceToAllInstruments(
2674 }
else if (update_path ==
"navigation.courseOverGroundTrue" &&
2675 2 == m_pri_position) {
2676 double cog_rad = GetJsonDouble(value);
2677 if (std::isnan(cog_rad))
return;
2679 double cog_deg = GEODESIC_RAD2DEG(cog_rad);
2681 m_cog_filter.Filter(cog_deg),
"\u00B0");
2682 }
else if (update_path ==
"navigation.headingTrue") {
2683 if (m_pri_heading_t >= 2) {
2684 double hdt = GetJsonDouble(value);
2685 if (std::isnan(hdt))
return;
2687 hdt = GEODESIC_RAD2DEG(hdt);
2689 m_pri_heading_t = 2;
2690 m_hdt_watchdog = gps_watchdog_timeout_ticks;
2692 }
else if (update_path ==
"navigation.headingMagnetic") {
2693 if (m_pri_heading_m >= 2) {
2694 double hdm = GetJsonDouble(value);
2695 if (std::isnan(hdm))
return;
2697 hdm = GEODESIC_RAD2DEG(hdm);
2699 m_pri_heading_m = 2;
2700 m_h_dx_watchdog = gps_watchdog_timeout_ticks;
2703 if (m_pri_heading_t >= 6 && (!std::isnan(m_var))) {
2704 double heading = hdm + m_var;
2707 else if (heading >= 360.0)
2710 m_pri_heading_t = 6;
2711 m_hdt_watchdog = gps_watchdog_timeout_ticks;
2714 }
else if (update_path ==
"navigation.speedThroughWater") {
2715 if (m_pri_stw >= 2) {
2716 double stw_knots = GetJsonDouble(value);
2717 if (std::isnan(stw_knots))
return;
2719 stw_knots = MS2KNOTS(stw_knots);
2720 SendSentenceToAllInstruments(
2724 m_stw_watchdog = gps_watchdog_timeout_ticks;
2726 }
else if (update_path ==
"navigation.magneticVariation") {
2727 if (m_pri_var >= 2) {
2728 double dvar = GetJsonDouble(value);
2729 if (std::isnan(dvar))
return;
2731 dvar = GEODESIC_RAD2DEG(dvar);
2735 m_var_watchdog = gps_watchdog_timeout_ticks;
2738 }
else if (update_path ==
"environment.wind.angleApparent") {
2739 if (m_pri_awa >= 2) {
2740 double m_awaangle = GetJsonDouble(value);
2741 if (std::isnan(m_awaangle))
return;
2743 m_awaangle = GEODESIC_RAD2DEG(m_awaangle);
2745 wxString m_awaunit =
"\u00B0R";
2746 if (m_awaangle < 0) {
2747 m_awaunit =
"\u00B0L";
2750 SendSentenceToAllInstruments(
2754 m_mwva_watchdog = gps_watchdog_timeout_ticks;
2756 }
else if (update_path ==
"environment.wind.speedApparent") {
2757 if (m_pri_awa >= 2) {
2758 double m_awaspeed_kn = GetJsonDouble(value);
2759 if (std::isnan(m_awaspeed_kn))
return;
2761 m_awaspeed_kn = MS2KNOTS(m_awaspeed_kn);
2762 SendSentenceToAllInstruments(
2765 g_iDashWindSpeedUnit),
2769 if (m_pri_twa >= 6 && !std::isnan(skAWA)) {
2770 CalculateAndUpdateTWDS(m_awaspeed_kn, skAWA);
2772 m_mwvt_watchdog = gps_watchdog_timeout_ticks;
2773 m_wdn_watchdog = no_nav_watchdog_timeout_ticks;
2776 }
else if ((update_path ==
"environment.wind.angleTrueWater" &&
2777 !g_bDBtrueWindGround) ||
2778 (update_path ==
"environment.wind.angleTrueGround" &&
2779 g_bDBtrueWindGround)) {
2780 if (m_pri_twa >= 3) {
2781 double m_twaangle = GetJsonDouble(value);
2782 if (std::isnan(m_twaangle))
return;
2784 m_twaangle = GEODESIC_RAD2DEG(m_twaangle);
2785 double m_twaangle_raw = m_twaangle;
2786 wxString m_twaunit =
"\u00B0R";
2787 if (m_twaangle < 0) {
2788 m_twaunit =
"\u00B0L";
2794 m_mwvt_watchdog = gps_watchdog_timeout_ticks;
2796 if (m_pri_wdn >= 5) {
2801 if (g_dHDT < 361. && g_dHDT >= 0.0) {
2802 double g_dCalWdir = (m_twaangle_raw) + g_dHDT;
2803 if (g_dCalWdir > 360.) {
2805 }
else if (g_dCalWdir < 0.) {
2811 m_wdn_watchdog = no_nav_watchdog_timeout_ticks;
2815 }
else if ((update_path ==
"environment.wind.speedTrue" &&
2816 !g_bDBtrueWindGround) ||
2817 (update_path ==
"environment.wind.speedOverGround" &&
2818 g_bDBtrueWindGround)) {
2819 if (m_pri_twa >= 3) {
2820 double m_twaspeed_kn = GetJsonDouble(value);
2821 if (std::isnan(m_twaspeed_kn))
return;
2823 m_twaspeed_kn = MS2KNOTS(m_twaspeed_kn);
2824 SendSentenceToAllInstruments(
2828 SendSentenceToAllInstruments(
2833 }
else if (update_path ==
"environment.depth.belowSurface") {
2834 if (m_pri_depth >= 3) {
2835 double depth = GetJsonDouble(value);
2836 if (std::isnan(depth))
return;
2839 depth += g_dDashDBTOffset;
2841 SendSentenceToAllInstruments(
2844 m_dpt_dbt_watchdog = gps_watchdog_timeout_ticks;
2846 }
else if (update_path ==
"environment.depth.belowTransducer") {
2847 if (m_pri_depth >= 3) {
2848 double depth = GetJsonDouble(value);
2849 if (std::isnan(depth))
return;
2852 depth += g_dDashDBTOffset;
2854 SendSentenceToAllInstruments(
2857 m_dpt_dbt_watchdog = gps_watchdog_timeout_ticks;
2859 }
else if (update_path ==
"environment.water.temperature") {
2860 if (m_pri_wtp >= 2) {
2861 double m_wtemp = GetJsonDouble(value);
2862 if (std::isnan(m_wtemp))
return;
2864 m_wtemp = KELVIN2C(m_wtemp);
2865 if (m_wtemp > -60 && m_wtemp < 200 && !std::isnan(m_wtemp)) {
2866 SendSentenceToAllInstruments(
2870 m_wtp_watchdog = no_nav_watchdog_timeout_ticks;
2873 }
else if (update_path ==
2874 "navigation.courseRhumbline.nextPoint.velocityMadeGood") {
2875 double m_vmg_kn = GetJsonDouble(value);
2876 if (std::isnan(m_vmg_kn))
return;
2878 m_vmg_kn = MS2KNOTS(m_vmg_kn);
2879 SendSentenceToAllInstruments(
2882 m_vmg_watchdog = gps_watchdog_timeout_ticks;
2885 else if (update_path ==
"performance.velocityMadeGood") {
2886 double m_vmgw_kn = GetJsonDouble(value);
2887 if (std::isnan(m_vmgw_kn))
return;
2889 m_vmgw_kn = MS2KNOTS(m_vmgw_kn);
2890 SendSentenceToAllInstruments(
2893 m_vmgw_watchdog = gps_watchdog_timeout_ticks;
2896 else if (update_path ==
"steering.rudderAngle") {
2897 if (m_pri_rsa >= 2) {
2898 double m_rudangle = GetJsonDouble(value);
2899 if (std::isnan(m_rudangle))
return;
2901 m_rudangle = GEODESIC_RAD2DEG(m_rudangle);
2903 m_rsa_watchdog = gps_watchdog_timeout_ticks;
2906 }
else if (update_path ==
2907 "navigation.gnss.satellites") {
2908 if (m_pri_sat_used >= 2) {
2909 int usedSats = (value).AsInt();
2910 if (usedSats < 1)
return;
2913 m_sats_used_wdog = gps_watchdog_timeout_ticks;
2915 }
else if (update_path ==
"navigation.gnss.type") {
2916 if (value.IsString() && value.AsString() != wxEmptyString) {
2917 talkerID = (value.AsString());
2918 talkerID.MakeUpper();
2919 m_pri_n2_k_talker = gps_watchdog_timeout_ticks;
2920 if ((talkerID.Contains(
"GPS")) && (talkerID.Contains(
"GLONASS")))
2921 talkerID =
"GPSGLONAS";
2922 else if (talkerID.Contains(
"GPS"))
2924 else if (talkerID.Contains(
"GLONASS"))
2926 else if (talkerID.Contains(
"GALILEO"))
2928 else if (talkerID.Contains(
"BEIDOU"))
2931 }
else if (update_path ==
2932 "navigation.gnss.satellitesInView") {
2934 if (m_pri_sat_used >= 4) {
2935 if (value.HasMember(
"count") && value[
"count"].IsInt()) {
2936 double m_SK_SatsInView = (value[
"count"].AsInt());
2940 m_sats_used_wdog = gps_watchdog_timeout_ticks;
2943 if (m_pri_sat_status == 2) {
2944 if (value.HasMember(
"satellites") && value[
"satellites"].IsArray()) {
2947 if (value.HasMember(
"count") && value[
"count"].IsInt()) {
2948 iNumSats = (value[
"count"].AsInt());
2950 iNumSats = value[_T (
"satellites")].Size();
2952 SAT_INFO SK_SatInfo[4];
2953 for (
int idx = 0; idx < 4; idx++) {
2954 SK_SatInfo[idx].SatNumber = 0;
2955 SK_SatInfo[idx].ElevationDegrees = 0;
2956 SK_SatInfo[idx].AzimuthDegreesTrue = 0;
2957 SK_SatInfo[idx].SignalToNoiseRatio = 0;
2964 double dElevRad = 0;
2965 double dAzimRad = 0;
2968 for (
int iMesNum = 0; iMesNum < 3; iMesNum++) {
2969 for (idx = 0; idx < 4; idx++) {
2970 arr = idx + 4 * iMesNum;
2971 if (value[
"satellites"][arr][
"id"].IsInt())
2972 iID = value[
"satellites"][arr][
"id"].AsInt();
2973 if (value[
"satellites"][arr][
"elevation"].IsDouble())
2974 dElevRad = value[
"satellites"][arr][
"elevation"].AsDouble();
2975 if (value[
"satellites"][arr][
"azimuth"].IsDouble())
2976 dAzimRad = value[
"satellites"][arr][
"azimuth"].AsDouble();
2977 if (value[
"satellites"][arr][
"SNR"].IsInt())
2978 iSNR = value[
"satellites"][arr][
"SNR"].AsInt();
2981 SK_SatInfo[idx].SatNumber = iID;
2982 SK_SatInfo[idx].ElevationDegrees = GEODESIC_RAD2DEG(dElevRad);
2983 SK_SatInfo[idx].AzimuthDegreesTrue = GEODESIC_RAD2DEG(dAzimRad);
2984 SK_SatInfo[idx].SignalToNoiseRatio = iSNR;
2987 if (m_pri_n2_k_talker <= 0 && talker != wxEmptyString &&
2988 (talker.StartsWith(
"G") || talker.StartsWith(
"BD"))) {
2991 SendSatInfoToAllInstruments(iNumSats, iMesNum + 1, talkerID,
2994 m_sat_status_wdog = gps_watchdog_timeout_ticks;
3002 }
else if (update_path ==
"navigation.gnss.antennaAltitude") {
3003 if (m_pri_alt >= 2) {
3004 double m_alt = GetJsonDouble(value);
3005 if (std::isnan(m_alt))
return;
3009 m_alt_watchdog = gps_watchdog_timeout_ticks;
3012 }
else if (update_path ==
"navigation.datetime") {
3013 if (m_pri_date_time >= 1) {
3014 m_pri_date_time = 1;
3015 wxString s_dt = (value.AsString());
3016 s_dt.Replace(
'-', wxEmptyString);
3017 s_dt.Replace(
':', wxEmptyString);
3018 wxString utc_dt = s_dt.BeforeFirst(
'T');
3019 utc_dt.Append(s_dt.AfterFirst(
'T').Left(6));
3020 m_utc_date_time.ParseFormat(utc_dt.c_str(),
"%Y%m%d%H%M%S");
3021 m_utc_watchdog = gps_watchdog_timeout_ticks;
3023 }
else if (update_path ==
"environment.outside.temperature") {
3024 if (m_pri_atmp >= 2) {
3025 double m_airtemp = GetJsonDouble(value);
3026 if (std::isnan(m_airtemp))
return;
3028 m_airtemp = KELVIN2C(m_airtemp);
3029 if (m_airtemp > -60 && m_airtemp < 100) {
3030 SendSentenceToAllInstruments(
3034 m_atmp_watchdog = no_nav_watchdog_timeout_ticks;
3037 }
else if (update_path ==
"environment.outside.humidity" ||
3038 update_path ==
"environment.outside.relativeHumidity") {
3039 if (m_pri_hum >= 2) {
3040 double m_hum = GetJsonDouble(value) * 100;
3041 if (std::isnan(m_hum))
return;
3044 m_hum_watchdog = no_nav_watchdog_timeout_ticks;
3046 }
else if (update_path ==
3047 "environment.wind.directionTrue") {
3048 if (m_pri_wdn >= 3) {
3049 double m_twdT = GetJsonDouble(value);
3050 if (std::isnan(m_twdT))
return;
3052 m_twdT = GEODESIC_RAD2DEG(m_twdT);
3055 m_wdn_watchdog = no_nav_watchdog_timeout_ticks;
3057 }
else if (update_path ==
"environment.wind.directionMagnetic") {
3059 if (m_pri_wdn >= 4) {
3060 double m_twdM = GetJsonDouble(value);
3061 if (std::isnan(m_twdM))
return;
3062 m_twdM = GEODESIC_RAD2DEG(m_twdM);
3064 if (!std::isnan(m_var)) {
3065 m_twdM = (m_twdM) + m_var;
3066 if (m_twdM > 360.) {
3068 }
else if (m_twdM < 0.) {
3074 m_wdn_watchdog = no_nav_watchdog_timeout_ticks;
3076 }
else if (update_path ==
"navigation.trip.log") {
3077 double m_tlog = GetJsonDouble(value);
3078 if (std::isnan(m_tlog))
return;
3080 m_tlog = METERS2NM(m_tlog);
3081 SendSentenceToAllInstruments(
3084 m_tr_log_watchdog = no_nav_watchdog_timeout_ticks;
3085 }
else if (update_path ==
"navigation.log" && !g_bUseInternSumLog) {
3086 double m_slog = GetJsonDouble(value);
3087 if (std::isnan(m_slog))
return;
3089 m_slog = METERS2NM(m_slog);
3090 SendSentenceToAllInstruments(
3093 m_log_watchdog = no_nav_watchdog_timeout_ticks;
3094 }
else if (update_path ==
"environment.outside.pressure" &&
3096 double m_press = GetJsonDouble(value);
3097 if (std::isnan(m_press))
return;
3099 m_press = PA2HPA(m_press);
3102 m_mda_watchdog = no_nav_watchdog_timeout_ticks;
3103 }
else if (update_path ==
"navigation.attitude") {
3104 if (m_pri_pitch_roll >= 2) {
3105 if (value[
"roll"].AsString() !=
"0") {
3106 double m_heel = GEODESIC_RAD2DEG(value[
"roll"].AsDouble());
3107 wxString h_unit = L
"\u00B0\u003E" + _(
"Stbd");
3109 h_unit = L
"\u00B0\u003C" + _(
"Port");
3113 m_heel_watchdog = gps_watchdog_timeout_ticks;
3114 m_pri_pitch_roll = 2;
3116 if (value[
"pitch"].AsString() !=
"0") {
3117 double m_pitch = GEODESIC_RAD2DEG(value[
"pitch"].AsDouble());
3118 wxString p_unit = L
"\u00B0\u2191" + _(
"Up");
3120 p_unit = L
"\u00B0\u2193" + _(
"Down");
3124 m_pitch_watchdog = gps_watchdog_timeout_ticks;
3125 m_pri_pitch_roll = 2;
3134 if (m_pri_position >= 1) {
3139 if (m_pri_cogsog >= 1) {
3140 double dMagneticCOG;
3142 SendSentenceToAllInstruments(
3147 m_cog_filter.Filter(pfix.
Cog),
"\u00B0");
3150 double logSOG = m_sog_filter.Filter(pfix.
Sog);
3152 d_tripNM += logSOG / 3600;
3154 if (++logCount > 60) {
3161 dMagneticCOG = m_cog_filter.get() - pfix.
Var;
3162 if (dMagneticCOG < 0.0) dMagneticCOG = 360.0 + dMagneticCOG;
3163 if (dMagneticCOG > 360.0) dMagneticCOG = dMagneticCOG - 360.0;
3166 if (m_pri_var >= 1) {
3167 if (!std::isnan(pfix.
Var)) {
3170 m_var_watchdog = gps_watchdog_timeout_ticks;
3175 if (m_pri_date_time >= 6) {
3180 m_utc_date_time.Set(pfix.
FixTime);
3182 m_utc_date_time = wxInvalidDateTime;
3183 if (m_utc_date_time.IsValid()) {
3184 m_pri_date_time = 6;
3185 m_utc_date_time = m_utc_date_time.ToUTC();
3186 m_utc_watchdog = gps_watchdog_timeout_ticks;
3189 if (m_pri_sat_used >= 1) {
3190 m_sats_in_use = pfix.
nSats;
3191 if (m_sats_in_use > 0) {
3194 m_sats_used_wdog = gps_watchdog_timeout_ticks;
3197 if (m_pri_heading_t >= 1) {
3198 double hdt = pfix.
Hdt;
3199 if (std::isnan(hdt))
return;
3201 m_pri_heading_t = 1;
3202 m_hdt_watchdog = gps_watchdog_timeout_ticks;
3204 if (m_pri_heading_m >= 1) {
3205 double hdm = pfix.
Hdm;
3206 if (std::isnan(hdm) && !std::isnan(pfix.
Hdt) && !std::isnan(pfix.
Var)) {
3207 hdm = pfix.
Hdt - pfix.
Var;
3210 else if (hdm >= 360.0)
3213 if (std::isnan(hdm))
return;
3215 m_pri_heading_m = 1;
3216 m_h_dx_watchdog = gps_watchdog_timeout_ticks;
3225void dashboard_pi::SetPluginMessage(wxString &message_id,
3226 wxString &message_body) {
3227 if (message_id ==
"WMM_VARIATION_BOAT") {
3235 int numErrors = reader.
Parse(message_body, &root);
3236 if (numErrors > 0) {
3242 wxString decl = root[
"Decl"].
AsString();
3244 decl.ToDouble(&decl_val);
3246 if (m_pri_var >= 5) {
3249 m_var_watchdog = gps_watchdog_timeout_ticks;
3252 }
else if (message_id ==
"OCPN_CORE_SIGNALK") {
3253 ParseSignalK(message_body);
3261 parent, wxID_ANY, m_ArrayOfDashboardWindow);
3263 dialog->RecalculateSize();
3266 dialog->GetHandle()->setStyleSheet(qtStyleSheet);
3273 int xmax = ccwin->GetSize().GetWidth();
3274 int ymax = ccwin->GetParent()
3277 dialog->SetSize(xmax, ymax);
3284 if (dialog->ShowModal() == wxID_OK) {
3285 double scaler = 1.0;
3288 scaler = wxMax(1.0, scaler);
3290 g_USFontTitle = *(dialog->m_font_picker_title->GetFontData());
3291 g_FontTitle = *g_pUSFontTitle;
3292 g_FontTitle.SetChosenFont(g_pUSFontTitle->GetChosenFont().Scaled(scaler));
3293 g_FontTitle.SetColour(g_pUSFontTitle->GetColour());
3294 g_USFontTitle = *g_pUSFontTitle;
3296 g_USFontData = *(dialog->m_font_picker_data->GetFontData());
3297 g_FontData = *g_pUSFontData;
3298 g_FontData.SetChosenFont(g_pUSFontData->GetChosenFont().Scaled(scaler));
3299 g_FontData.SetColour(g_pUSFontData->GetColour());
3300 g_USFontData = *g_pUSFontData;
3302 g_USFontLabel = *(dialog->m_font_picker_label->GetFontData());
3303 g_FontLabel = *g_pUSFontLabel;
3304 g_FontLabel.SetChosenFont(g_pUSFontLabel->GetChosenFont().Scaled(scaler));
3305 g_FontLabel.SetColour(g_pUSFontLabel->GetColour());
3306 g_USFontLabel = *g_pUSFontLabel;
3308 g_USFontSmall = *(dialog->m_font_picker_small->GetFontData());
3309 g_FontSmall = *g_pUSFontSmall;
3310 g_FontSmall.SetChosenFont(g_pUSFontSmall->GetChosenFont().Scaled(scaler));
3311 g_FontSmall.SetColour(g_pUSFontSmall->GetColour());
3312 g_USFontSmall = *g_pUSFontSmall;
3316 g_dashPrefWidth = dialog->GetSize().x;
3317 g_dashPrefHeight = dialog->GetSize().y;
3319 dialog->SaveDashboardConfig();
3320 m_ArrayOfDashboardWindow.Clear();
3321 m_ArrayOfDashboardWindow = dialog->m_config;
3331 aktuellColorScheme = cs;
3332 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3334 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow;
3335 if (dashboard_window) dashboard_window->SetColorScheme(cs);
3339int dashboard_pi::GetDashboardWindowShownCount() {
3342 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3344 m_ArrayOfDashboardWindow.Item(i)->m_pDashboardWindow;
3345 if (dashboard_window) {
3346 wxAuiPaneInfo &pane = m_pauimgr->GetPane(dashboard_window);
3347 if (pane.IsOk() && pane.IsShown()) cnt++;
3353void dashboard_pi::OnPaneClose(wxAuiManagerEvent &event) {
3357 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3362 if (dashboard_window != d_w) {
3363 wxAuiPaneInfo &pane = m_pauimgr->GetPane(d_w);
3364 if (pane.IsOk() && pane.IsShown()) cnt++;
3366 cont->m_bIsVisible =
false;
3376 int cnt = GetDashboardWindowShownCount();
3378 bool b_anyviz =
false;
3379 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3381 if (cont->m_bIsVisible) {
3387 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3390 if (dashboard_window) {
3391 wxAuiPaneInfo &pane = m_pauimgr->GetPane(dashboard_window);
3393 bool b_reset_pos =
false;
3400 RECT frame_title_rect;
3401 frame_title_rect.left = pane.floating_pos.x;
3402 frame_title_rect.top = pane.floating_pos.y;
3403 frame_title_rect.right = pane.floating_pos.x + pane.floating_size.x;
3404 frame_title_rect.bottom = pane.floating_pos.y + 30;
3406 if (NULL == MonitorFromRect(&frame_title_rect, MONITOR_DEFAULTTONULL))
3412 wxRect window_title_rect;
3413 window_title_rect.x = pane.floating_pos.x;
3414 window_title_rect.y = pane.floating_pos.y;
3415 window_title_rect.width = pane.floating_size.x;
3416 window_title_rect.height = 30;
3418 wxRect ClientRect = wxGetClientDisplayRect();
3421 if (!ClientRect.Intersects(window_title_rect)) b_reset_pos =
true;
3425 if (b_reset_pos) pane.FloatingPosition(50, 50);
3429 pane.Show(cont->m_bIsVisible);
3431 cont->m_bIsVisible = cont->m_bPersVisible;
3432 pane.Show(cont->m_bIsVisible);
3439 if (pane.IsShown() && pane.IsDocked()) {
3440 pane.BestSize(cont->m_best_size);
3441 m_pauimgr->Update();
3452 if ((pane.dock_direction == wxAUI_DOCK_BOTTOM) && pane.IsDocked())
3459 GetDashboardWindowShownCount() != 0 );
3460 m_pauimgr->Update();
3470 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3472 wxAuiPaneInfo &pane = m_pauimgr->GetPane(cont->m_pDashboardWindow);
3474 cont->m_bIsVisible = (pane.IsOk() && pane.IsShown());
3478 if (pane.IsDocked()) {
3479 if ((cont->m_persist_size.x > 50) && (cont->m_persist_size.y > 50))
3480 cont->m_pDashboardWindow->SetSize(cont->m_persist_size);
3484 if (pane.IsShown()) {
3486 m_pauimgr->Update();
3488 m_pauimgr->Update();
3492 m_pauimgr->Update();
3500bool dashboard_pi::LoadConfig() {
3501 auto *pConf = (wxFileConfig *)m_pconfig;
3504 pConf->SetPath(
"/PlugIns/Dashboard");
3507 pConf->Read(
"Version", &version, wxEmptyString);
3517 TitleFont =
"Roboto,16,-1,5,50,0,0,0,0,0";
3518 DataFont =
"Roboto,16,-1,5,50,0,0,0,0,0";
3519 LabelFont =
"Roboto,16,-1,5,50,0,0,0,0,0";
3520 SmallFont =
"Roboto,14,-1,5,50,0,0,0,0,0";
3522 TitleFont = g_pFontTitle->GetChosenFont().GetNativeFontInfoDesc();
3523 DataFont = g_pFontData->GetChosenFont().GetNativeFontInfoDesc();
3524 LabelFont = g_pFontLabel->GetChosenFont().GetNativeFontInfoDesc();
3525 SmallFont = g_pFontSmall->GetChosenFont().GetNativeFontInfoDesc();
3528 double scaler = 1.0;
3530 wxFont *pDF = &DummyFont;
3534 scaler = wxMax(1.0, scaler);
3536 g_pFontTitle = &g_FontTitle;
3537 pConf->Read(
"FontTitle", &config, TitleFont);
3538 LoadFont(&pDF, config);
3539 wxFont DummyFontTitle = *pDF;
3540 pConf->Read(
"ColorTitle", &config,
"#000000");
3541 wxColour DummyColor(config);
3542 g_pUSFontTitle->SetChosenFont(DummyFontTitle);
3543 g_pUSFontTitle->SetColour(DummyColor);
3545 g_FontTitle = *g_pUSFontTitle;
3546 g_FontTitle.SetChosenFont(g_pUSFontTitle->GetChosenFont().Scaled(scaler));
3547 g_USFontTitle = *g_pUSFontTitle;
3549 g_pFontData = &g_FontData;
3550 pConf->Read(
"FontData", &config, DataFont);
3551 LoadFont(&pDF, config);
3552 wxFont DummyFontData = *pDF;
3553 pConf->Read(
"ColorData", &config,
"#000000");
3554 DummyColor.Set(config);
3555 g_pUSFontData->SetChosenFont(DummyFontData);
3556 g_pUSFontData->SetColour(DummyColor);
3557 g_FontData = *g_pUSFontData;
3558 g_FontData.SetChosenFont(g_pUSFontData->GetChosenFont().Scaled(scaler));
3559 g_USFontData = *g_pUSFontData;
3561 pConf->Read(
"ForceBackgroundColor", &g_ForceBackgroundColor,
false);
3562 pConf->Read(
"BackgroundColor", &config,
"DASHL");
3563 g_BackgroundColor.Set(config);
3566 pConf->Read(
"TitleAlignment", &alignment, (
int)wxALIGN_LEFT);
3567 g_TitleAlignment = (wxAlignment)alignment;
3568 if (g_TitleAlignment == wxALIGN_INVALID) g_TitleAlignment = wxALIGN_LEFT;
3569 pConf->Read(
"TitleMargin", &g_iTitleMargin, 5);
3570 pConf->Read(
"DataShowUnit", &g_bShowUnit,
true);
3571 pConf->Read(
"DataAlignment", &alignment, (
int)wxALIGN_LEFT);
3572 g_DataAlignment = (wxAlignment)alignment;
3573 if (g_DataAlignment == wxALIGN_INVALID) g_DataAlignment = wxALIGN_LEFT;
3574 pConf->Read(
"DataMargin", &g_iDataMargin, 10);
3575 pConf->Read(
"InstrumentSpacing", &g_iInstrumentSpacing, 0);
3576 pConf->Read(
"TitleVerticalOffset", &g_TitleVerticalOffset, 0.0);
3578 g_pFontLabel = &g_FontLabel;
3579 pConf->Read(
"FontLabel", &config, LabelFont);
3580 LoadFont(&pDF, config);
3581 wxFont DummyFontLabel = *pDF;
3582 pConf->Read(
"ColorLabel", &config,
"#000000");
3583 DummyColor.Set(config);
3584 g_pUSFontLabel->SetChosenFont(DummyFontLabel);
3585 g_pUSFontLabel->SetColour(DummyColor);
3586 g_FontLabel = *g_pUSFontLabel;
3587 g_FontLabel.SetChosenFont(g_pUSFontLabel->GetChosenFont().Scaled(scaler));
3588 g_USFontLabel = *g_pUSFontLabel;
3590 g_pFontSmall = &g_FontSmall;
3591 pConf->Read(
"FontSmall", &config, SmallFont);
3592 LoadFont(&pDF, config);
3593 wxFont DummyFontSmall = *pDF;
3594 pConf->Read(
"ColorSmall", &config,
"#000000");
3595 DummyColor.Set(config);
3596 g_pUSFontSmall->SetChosenFont(DummyFontSmall);
3597 g_pUSFontSmall->SetColour(DummyColor);
3598 g_FontSmall = *g_pUSFontSmall;
3599 g_FontSmall.SetChosenFont(g_pUSFontSmall->GetChosenFont().Scaled(scaler));
3600 g_USFontSmall = *g_pUSFontSmall;
3602 pConf->Read(
"SpeedometerMax", &g_iDashSpeedMax, 12);
3603 pConf->Read(
"COGDamp", &g_iDashCOGDamp, 0);
3604 pConf->Read(
"SpeedUnit", &g_iDashSpeedUnit, 0);
3605 pConf->Read(
"SOGDamp", &g_iDashSOGDamp, 0);
3606 pConf->Read(
"DepthUnit", &g_iDashDepthUnit, 3);
3607 g_iDashDepthUnit = wxMax(g_iDashDepthUnit, 3);
3608 pConf->Read(
"AWADamp", &g_iDashAWADamp, 0);
3609 pConf->Read(
"AWSDamp", &g_iDashAWSDamp, 0);
3611 pConf->Read(
"DepthOffset", &g_dDashDBTOffset, 0);
3613 pConf->Read(
"DistanceUnit", &g_iDashDistanceUnit, 0);
3614 pConf->Read(
"WindSpeedUnit", &g_iDashWindSpeedUnit, 0);
3615 pConf->Read(
"UseSignKtruewind", &g_bDBtrueWindGround,
false);
3616 pConf->Read(
"UseInternSumlog", &g_bUseInternSumLog,
false);
3617 pConf->Read(
"SumLogNM", &g_dSumLogNM, 0.0);
3618 pConf->Read(
"TemperatureUnit", &g_iDashTempUnit, 0);
3620 pConf->Read(
"UTCOffset", &g_iUTCOffset, 0);
3622 pConf->Read(
"PrefWidth", &g_dashPrefWidth, 0);
3623 pConf->Read(
"PrefHeight", &g_dashPrefHeight, 0);
3626 pConf->Read(
"DashboardCount", &d_cnt, -1);
3628 m_ArrayOfDashboardWindow.Clear();
3629 if (version.IsEmpty() && d_cnt == -1) {
3630 m_config_version = 1;
3633 pConf->Read(
"InstrumentCount", &i_cnt, -1);
3635 wxArrayOfInstrumentProperties Property;
3637 for (
int i = 0; i < i_cnt; i++) {
3639 pConf->Read(wxString::Format(
"Instrument%d", i + 1), &
id, -1);
3640 if (
id != -1) ar.Add(
id);
3645 ar.Add(ID_DBP_I_POS);
3646 ar.Add(ID_DBP_D_COG);
3647 ar.Add(ID_DBP_D_GPS);
3649 ar.Add(ID_DBP_I_POS);
3650 ar.Add(ID_DBP_D_COG);
3651 ar.Add(ID_DBP_I_SOG);
3657 nullptr, MakeName(), _(
"Dashboard"),
"V", ar, Property);
3658 cont->m_bPersVisible =
true;
3659 m_ArrayOfDashboardWindow.Add(cont);
3663 m_config_version = 2;
3664 bool b_onePersisted =
false;
3666 wxSize persist_size;
3667 for (
int k = 0; k < d_cnt; k++) {
3669 wxString::Format(
"/PlugIns/Dashboard/Dashboard%d", k + 1));
3671 pConf->Read(
"Name", &name, MakeName());
3673 pConf->Read(
"Caption", &caption, _(
"Dashboard"));
3675 pConf->Read(
"Orientation", &orient,
"V");
3677 pConf->Read(
"InstrumentCount", &i_cnt, -1);
3679 pConf->Read(
"Persistence", &b_persist,
true);
3681 pConf->Read(
"BestSizeX", &val, DefaultWidth);
3683 pConf->Read(
"BestSizeY", &val, DefaultWidth);
3685 pConf->Read(
"PersistSizeX", &val, DefaultWidth);
3686 persist_size.x = val;
3687 pConf->Read(
"PersistSizeY", &val, DefaultWidth);
3688 persist_size.y = val;
3691 wxArrayOfInstrumentProperties Property;
3692 for (
int i = 0; i < i_cnt; i++) {
3694 pConf->Read(wxString::Format(
"Instrument%d", i + 1), &
id, -1);
3698 if (pConf->Exists(wxString::Format(
"InstTitleFont%d", i + 1))) {
3701 pConf->Read(wxString::Format(
"InstTitleFont%d", i + 1), &config,
3703 LoadFont(&pDF, config);
3704 wxFont DummyFontTitleA = *pDF;
3705 pConf->Read(wxString::Format(
"InstTitleColor%d", i + 1), &config,
3707 DummyColor.Set(config);
3708 instp->m_USTitleFont.SetChosenFont(DummyFontTitleA);
3709 instp->m_USTitleFont.SetColour(DummyColor);
3710 instp->m_TitleFont = instp->m_USTitleFont;
3711 instp->m_TitleFont.SetChosenFont(
3712 instp->m_USTitleFont.GetChosenFont().Scaled(scaler));
3714 pConf->Read(wxString::Format(
"InstDataShowUnit%d", i + 1),
3715 &instp->m_ShowUnit, -1);
3716 pConf->Read(wxString::Format(
"InstDataMargin%d", i + 1),
3717 &instp->m_DataMargin, -1);
3718 pConf->Read(wxString::Format(
"InstDataAlignment%d", i + 1),
3719 &alignment, (
int)wxALIGN_INVALID);
3720 instp->m_DataAlignment = (wxAlignment)alignment;
3721 pConf->Read(wxString::Format(
"InstInstrumentSpacing%d", i + 1),
3722 &instp->m_InstrumentSpacing, -1);
3723 pConf->Read(wxString::Format(
"InstDataFormat%d", i + 1),
3724 &instp->m_Format,
"");
3725 pConf->Read(wxString::Format(
"InstTitle%d", i + 1),
3726 &instp->m_Title,
"");
3728 pConf->Read(wxString::Format(
"InstDataFont%d", i + 1), &config,
3730 LoadFont(&pDF, config);
3731 wxFont DummyFontDataA = *pDF;
3732 pConf->Read(wxString::Format(
"InstDataColor%d", i + 1), &config,
3734 DummyColor.Set(config);
3735 instp->m_USDataFont.SetChosenFont(DummyFontDataA);
3736 instp->m_USDataFont.SetColour(DummyColor);
3737 instp->m_DataFont = instp->m_USDataFont;
3738 instp->m_DataFont.SetChosenFont(
3739 instp->m_USDataFont.GetChosenFont().Scaled(scaler));
3741 pConf->Read(wxString::Format(
"InstLabelFont%d", i + 1), &config,
3743 LoadFont(&pDF, config);
3744 wxFont DummyFontLabelA = *pDF;
3745 pConf->Read(wxString::Format(
"InstLabelColor%d", i + 1), &config,
3747 DummyColor.Set(config);
3748 instp->m_USLabelFont.SetChosenFont(DummyFontLabelA);
3749 instp->m_USLabelFont.SetColour(DummyColor);
3750 instp->m_LabelFont = instp->m_USLabelFont;
3751 instp->m_LabelFont.SetChosenFont(
3752 instp->m_USLabelFont.GetChosenFont().Scaled(scaler));
3754 pConf->Read(wxString::Format(
"InstSmallFont%d", i + 1), &config,
3756 LoadFont(&pDF, config);
3757 wxFont DummyFontSmallA = *pDF;
3758 pConf->Read(wxString::Format(
"InstSmallColor%d", i + 1), &config,
3760 DummyColor.Set(config);
3761 instp->m_USSmallFont.SetChosenFont(DummyFontSmallA);
3762 instp->m_USSmallFont.SetColour(DummyColor);
3763 instp->m_SmallFont = instp->m_USSmallFont;
3764 instp->m_SmallFont.SetChosenFont(
3765 instp->m_USSmallFont.GetChosenFont().Scaled(scaler));
3767 pConf->Read(wxString::Format(
"TitleBackColor%d", i + 1), &config,
3769 instp->m_TitleBackgroundColour.Set(config);
3771 pConf->Read(wxString::Format(
"DataBackColor%d", i + 1), &config,
3773 instp->m_DataBackgroundColour.Set(config);
3775 pConf->Read(wxString::Format(
"ArrowFirst%d", i + 1), &config,
3777 instp->m_Arrow_First_Colour.Set(config);
3779 pConf->Read(wxString::Format(
"ArrowSecond%d", i + 1), &config,
3781 instp->m_Arrow_Second_Colour.Set(config);
3783 Property.Add(instp);
3790 orient, ar, Property);
3791 cont->m_bPersVisible = b_persist;
3792 cont->m_conf_best_size = best_size;
3793 cont->m_persist_size = persist_size;
3795 if (b_persist) b_onePersisted =
true;
3797 m_ArrayOfDashboardWindow.Add(cont);
3801 if (m_ArrayOfDashboardWindow.Count() && !b_onePersisted) {
3803 if (cont) cont->m_bPersVisible =
true;
3812void dashboard_pi::LoadFont(wxFont **target,
const wxString &native_info) {
3813 if (!native_info.IsEmpty()) {
3815 wxFont *nf =
new wxFont(native_info);
3818 (*target)->SetNativeFontInfo(native_info);
3823bool dashboard_pi::SaveConfig() {
3824 auto *pConf = (wxFileConfig *)m_pconfig;
3827 pConf->SetPath(
"/PlugIns/Dashboard");
3828 pConf->Write(
"Version",
"2");
3829 pConf->Write(
"FontTitle",
3830 g_pUSFontTitle->GetChosenFont().GetNativeFontInfoDesc());
3831 pConf->Write(
"ColorTitle",
3832 g_pUSFontTitle->GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3833 pConf->Write(
"FontData",
3834 g_pUSFontData->GetChosenFont().GetNativeFontInfoDesc());
3835 pConf->Write(
"ColorData",
3836 g_pUSFontData->GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3837 pConf->Write(
"FontLabel",
3838 g_pUSFontLabel->GetChosenFont().GetNativeFontInfoDesc());
3839 pConf->Write(
"ColorLabel",
3840 g_pUSFontLabel->GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3841 pConf->Write(
"FontSmall",
3842 g_pUSFontSmall->GetChosenFont().GetNativeFontInfoDesc());
3843 pConf->Write(
"ColorSmall",
3844 g_pUSFontSmall->GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3845 pConf->Write(
"SpeedometerMax", g_iDashSpeedMax);
3846 pConf->Write(
"COGDamp", g_iDashCOGDamp);
3847 pConf->Write(
"SpeedUnit", g_iDashSpeedUnit);
3848 pConf->Write(
"SOGDamp", g_iDashSOGDamp);
3849 pConf->Write(
"AWSDamp", g_iDashAWSDamp);
3850 pConf->Write(
"AWADamp", g_iDashAWADamp);
3851 pConf->Write(
"DepthUnit", g_iDashDepthUnit);
3852 pConf->Write(
"DepthOffset", g_dDashDBTOffset);
3853 pConf->Write(
"DistanceUnit", g_iDashDistanceUnit);
3854 pConf->Write(
"WindSpeedUnit", g_iDashWindSpeedUnit);
3855 pConf->Write(
"UseInternSumlog", g_bUseInternSumLog);
3856 pConf->Write(
"SumLogNM", g_dSumLogNM);
3857 pConf->Write(
"UTCOffset", g_iUTCOffset);
3858 pConf->Write(
"UseSignKtruewind", g_bDBtrueWindGround);
3859 pConf->Write(
"TemperatureUnit", g_iDashTempUnit);
3860 pConf->Write(
"PrefWidth", g_dashPrefWidth);
3861 pConf->Write(
"PrefHeight", g_dashPrefHeight);
3863 pConf->Write(
"DashboardCount", (
int)m_ArrayOfDashboardWindow.GetCount());
3865 for (
size_t i = m_ArrayOfDashboardWindow.GetCount(); i < 20; i++) {
3867 wxString::Format(
"/PlugIns/Dashboard/Dashboard%zu", i + 1))) {
3869 wxString::Format(
"/PlugIns/Dashboard/Dashboard%zu", i + 1));
3872 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
3875 wxString::Format(
"/PlugIns/Dashboard/Dashboard%zu", i + 1));
3876 pConf->Write(
"Name", cont->m_sName);
3877 pConf->Write(
"Caption", cont->m_sCaption);
3878 pConf->Write(
"Orientation", cont->m_sOrientation);
3879 pConf->Write(
"Persistence", cont->m_bPersVisible);
3880 pConf->Write(
"InstrumentCount", (
int)cont->m_aInstrumentList.GetCount());
3881 pConf->Write(
"BestSizeX", cont->m_best_size.x);
3882 pConf->Write(
"BestSizeY", cont->m_best_size.y);
3883 pConf->Write(
"PersistSizeX", cont->m_pDashboardWindow->GetSize().x);
3884 pConf->Write(
"PersistSizeY", cont->m_pDashboardWindow->GetSize().y);
3887 for (
size_t ii = cont->m_aInstrumentList.GetCount(); ii < 40; ii++) {
3888 if (pConf->Exists(wxString::Format(
"Instrument%zu", ii + 1))) {
3889 pConf->DeleteEntry(wxString::Format(
"Instrument%zu", ii + 1));
3890 if (pConf->Exists(wxString::Format(
"InstTitleFont%zu", ii + 1))) {
3891 pConf->DeleteEntry(wxString::Format(
"InstTitleFont%zu", ii + 1));
3892 pConf->DeleteEntry(wxString::Format(
"InstTitleColor%zu", ii + 1));
3893 pConf->DeleteEntry(wxString::Format(
"InstTitle%zu", ii + 1));
3894 pConf->DeleteEntry(wxString::Format(
"InstDataShowUnit%zu", ii + 1));
3895 pConf->DeleteEntry(wxString::Format(
"InstDataMargin%zu", ii + 1));
3897 wxString::Format(
"InstDataAlignment%zu", ii + 1));
3898 pConf->DeleteEntry(wxString::Format(
"InstDataFormat%zu", ii + 1));
3899 pConf->DeleteEntry(wxString::Format(
"InstDataFont%zu", ii + 1));
3900 pConf->DeleteEntry(wxString::Format(
"InstDataColor%zu", ii + 1));
3901 pConf->DeleteEntry(wxString::Format(
"InstLabelFont%zu", ii + 1));
3902 pConf->DeleteEntry(wxString::Format(
"InstLabelColor%zu", ii + 1));
3903 pConf->DeleteEntry(wxString::Format(
"InstSmallFont%zu", ii + 1));
3904 pConf->DeleteEntry(wxString::Format(
"InstSmallColor%zu", ii + 1));
3905 pConf->DeleteEntry(wxString::Format(
"TitleBackColor%zu", ii + 1));
3906 pConf->DeleteEntry(wxString::Format(
"DataBackColor%zu", ii + 1));
3907 pConf->DeleteEntry(wxString::Format(
"ArrowFirst%zu", ii + 1));
3908 pConf->DeleteEntry(wxString::Format(
"ArrowSecond%zu", ii + 1));
3912 for (
size_t j = 0; j < cont->m_aInstrumentList.GetCount(); j++) {
3913 pConf->Write(wxString::Format(
"Instrument%zu", j + 1),
3914 cont->m_aInstrumentList.Item(j));
3917 if (pConf->Exists(wxString::Format(
"InstTitleFont%zu", j + 1))) {
3919 for (
size_t ii = 0; ii < cont->m_aInstrumentPropertyList.GetCount();
3921 Inst = cont->m_aInstrumentPropertyList.Item(ii);
3922 if (Inst->m_Listplace == (
int)j) {
3928 pConf->DeleteEntry(wxString::Format(
"InstTitleFont%zu", j + 1));
3929 pConf->DeleteEntry(wxString::Format(
"InstTitleColor%zu", j + 1));
3930 pConf->DeleteEntry(wxString::Format(
"InstTitle%zu", j + 1));
3931 pConf->DeleteEntry(wxString::Format(
"InstDataShowUnit%zu", i + 1));
3932 pConf->DeleteEntry(wxString::Format(
"InstDataMargin%zu", i + 1));
3933 pConf->DeleteEntry(wxString::Format(
"InstDataAlignment%zu", i + 1));
3934 pConf->DeleteEntry(wxString::Format(
"InstDataFormat%zu", i + 1));
3935 pConf->DeleteEntry(wxString::Format(
"InstDataFont%zu", j + 1));
3936 pConf->DeleteEntry(wxString::Format(
"InstDataColor%zu", j + 1));
3937 pConf->DeleteEntry(wxString::Format(
"InstLabelFont%zu", j + 1));
3938 pConf->DeleteEntry(wxString::Format(
"InstLabelColor%zu", j + 1));
3939 pConf->DeleteEntry(wxString::Format(
"InstSmallFont%zu", j + 1));
3940 pConf->DeleteEntry(wxString::Format(
"InstSmallColor%zu", j + 1));
3941 pConf->DeleteEntry(wxString::Format(
"TitleBackColor%zu", i + 1));
3942 pConf->DeleteEntry(wxString::Format(
"DataBackColor%zu", i + 1));
3943 pConf->DeleteEntry(wxString::Format(
"ArrowFirst%zu", i + 1));
3944 pConf->DeleteEntry(wxString::Format(
"ArrowSecond%zu", i + 1));
3948 for (
size_t ii = 0; ii < (cont->m_aInstrumentPropertyList.GetCount());
3950 Inst = cont->m_aInstrumentPropertyList.Item(ii);
3951 if (Inst->m_Listplace == (
int)j) {
3953 wxString::Format(
"InstTitleFont%zu", j + 1),
3954 Inst->m_USTitleFont.GetChosenFont().GetNativeFontInfoDesc());
3956 wxString::Format(
"InstTitleColor%zu", j + 1),
3957 Inst->m_USTitleFont.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3959 wxString::Format(
"InstDataFont%zu", j + 1),
3960 Inst->m_USDataFont.GetChosenFont().GetNativeFontInfoDesc());
3962 wxString::Format(
"InstDataColor%zu", j + 1),
3963 Inst->m_USDataFont.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3965 wxString::Format(
"InstLabelFont%zu", j + 1),
3966 Inst->m_USLabelFont.GetChosenFont().GetNativeFontInfoDesc());
3968 wxString::Format(
"InstLabelColor%zu", j + 1),
3969 Inst->m_USLabelFont.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3971 wxString::Format(
"InstSmallFont%zu", j + 1),
3972 Inst->m_USSmallFont.GetChosenFont().GetNativeFontInfoDesc());
3974 wxString::Format(
"InstSmallColor%zu", j + 1),
3975 Inst->m_USSmallFont.GetColour().GetAsString(wxC2S_HTML_SYNTAX));
3977 wxString::Format(
"TitleBackColor%zu", j + 1),
3978 Inst->m_TitleBackgroundColour.GetAsString(wxC2S_HTML_SYNTAX));
3980 wxString::Format(
"DataBackColor%zu", j + 1),
3981 Inst->m_DataBackgroundColour.GetAsString(wxC2S_HTML_SYNTAX));
3983 wxString::Format(
"ArrowFirst%zu", j + 1),
3984 Inst->m_Arrow_First_Colour.GetAsString(wxC2S_HTML_SYNTAX));
3986 wxString::Format(
"ArrowSecond%zu", j + 1),
3987 Inst->m_Arrow_Second_Colour.GetAsString(wxC2S_HTML_SYNTAX));
3999void dashboard_pi::ApplyConfig() {
4001 for (
size_t i = m_ArrayOfDashboardWindow.GetCount(); i > 0; i--) {
4003 int orient = (cont->m_sOrientation ==
"V" ? wxVERTICAL : wxHORIZONTAL);
4004 if (cont->m_bIsDeleted) {
4005 if (cont->m_pDashboardWindow) {
4006 m_pauimgr->DetachPane(cont->m_pDashboardWindow);
4007 cont->m_pDashboardWindow->Close();
4008 cont->m_pDashboardWindow->Destroy();
4009 cont->m_pDashboardWindow =
nullptr;
4011 m_ArrayOfDashboardWindow.Remove(cont);
4014 }
else if (!cont->m_pDashboardWindow) {
4018 cont->m_pDashboardWindow->SetInstrumentList(
4019 cont->m_aInstrumentList, &(cont->m_aInstrumentPropertyList));
4020 bool vertical = orient == wxVERTICAL;
4021 wxSize sz = cont->m_pDashboardWindow->GetMinSize();
4022 wxSize best = cont->m_conf_best_size;
4023 if (best.x < 100) best = sz;
4027 if (sz.x == 0) sz.IncTo(wxSize(160, 388));
4029 wxAuiPaneInfo p = wxAuiPaneInfo()
4030 .Name(cont->m_sName)
4031 .Caption(cont->m_sCaption)
4032 .CaptionVisible(
false)
4033 .TopDockable(!vertical)
4034 .BottomDockable(!vertical)
4035 .LeftDockable(vertical)
4036 .RightDockable(vertical)
4040 .FloatingPosition(100, 100)
4042 .Show(cont->m_bIsVisible)
4045 m_pauimgr->AddPane(cont->m_pDashboardWindow, p);
4053 wxAuiPaneInfo &pane = m_pauimgr->GetPane(cont->m_pDashboardWindow);
4054 pane.Dockable(
false);
4059 wxAuiPaneInfo &pane = m_pauimgr->GetPane(cont->m_pDashboardWindow);
4060 pane.Caption(cont->m_sCaption).Show(cont->m_bIsVisible);
4061 if (!cont->m_pDashboardWindow->isInstrumentListEqual(
4062 cont->m_aInstrumentList)) {
4063 cont->m_pDashboardWindow->SetInstrumentList(
4064 cont->m_aInstrumentList, &(cont->m_aInstrumentPropertyList));
4065 wxSize sz = cont->m_pDashboardWindow->GetMinSize();
4066 pane.MinSize(sz).BestSize(sz).FloatingSize(sz);
4068 if (cont->m_pDashboardWindow->GetSizerOrientation() != orient) {
4069 cont->m_pDashboardWindow->ChangePaneOrientation(orient,
false);
4073 m_pauimgr->Update();
4076 double sogFC = g_iDashSOGDamp ? 1.0 / (2.0 * g_iDashSOGDamp) : 0.0;
4077 double cogFC = g_iDashCOGDamp ? 1.0 / (2.0 * g_iDashCOGDamp) : 0.0;
4078 double awaFC = g_iDashAWADamp ? 1.0 / (2.0 * g_iDashAWADamp) : 0.0;
4079 double awsFC = g_iDashAWSDamp ? 1.0 / (2.0 * g_iDashAWSDamp) : 0.0;
4081 if (abs(sogFC - m_sog_filter.GetFc()) > 1e-6) {
4082 m_sog_filter.SetFc(sogFC);
4084 if (abs(cogFC - m_cog_filter.GetFc()) > 1e-6) {
4085 m_cog_filter.SetFc(cogFC);
4087 if (abs(awaFC - m_awa_filter.GetFc()) > 1e-6) {
4088 m_awa_filter.SetFc(awaFC);
4090 if (abs(awsFC - m_aws_filter.GetFc()) > 1e-6) {
4091 m_aws_filter.SetFc(awsFC);
4095void dashboard_pi::PopulateContextMenu(wxMenu *menu) {
4097 wxMenuItem *visItem =
nullptr;
4098 for (
size_t i = 0; i < m_ArrayOfDashboardWindow.GetCount(); i++) {
4100 wxMenuItem *item = menu->AppendCheckItem(i + 1, cont->m_sCaption);
4101 item->Check(cont->m_bIsVisible);
4102 if (cont->m_bIsVisible) {
4107 if (nvis == 1 && visItem) visItem->Enable(
false);
4110void dashboard_pi::ShowDashboard(
size_t id,
bool visible) {
4111 if (
id < m_ArrayOfDashboardWindow.GetCount()) {
4113 m_pauimgr->GetPane(cont->m_pDashboardWindow).Show(visible);
4114 cont->m_bIsVisible = visible;
4115 cont->m_bPersVisible = visible;
4116 m_pauimgr->Update();
4124DashboardPreferencesDialog::DashboardPreferencesDialog(
4125 wxWindow *parent, wxWindowID
id, wxArrayOfDashboard config)
4126 : wxDialog(parent, id, _(
"Dashboard preferences"), wxDefaultPosition,
4127 wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
4133 int display_width, display_height;
4134 wxDisplaySize(&display_width, &display_height);
4137 wxFileName::GetPathSeparator() +
"dashboard_pi" +
4138 wxFileName::GetPathSeparator() +
"data" +
4139 wxFileName::GetPathSeparator();
4141 Connect(wxEVT_CLOSE_WINDOW,
4142 wxCloseEventHandler(DashboardPreferencesDialog::OnCloseDialog),
4146 m_config = wxArrayOfDashboard(config);
4148 int border_size = 2;
4150 auto *itemBoxSizerMainPanel =
new wxBoxSizer(wxVERTICAL);
4151 SetSizer(itemBoxSizerMainPanel);
4153 wxWindow *dparent =
this;
4154 auto *scrollWin =
new wxScrolledWindow(
this, wxID_ANY, wxDefaultPosition,
4155 wxSize(-1, -1), wxVSCROLL | wxHSCROLL);
4157 scrollWin->SetScrollRate(1, 1);
4158 itemBoxSizerMainPanel->Add(scrollWin, 1, wxEXPAND | wxALL, 0);
4160 dparent = scrollWin;
4162 auto *itemBoxSizer2 =
new wxBoxSizer(wxVERTICAL);
4163 scrollWin->SetSizer(itemBoxSizer2);
4165 auto *DialogButtonSizer =
new wxStdDialogButtonSizer();
4166 DialogButtonSizer->AddButton(
new wxButton(
this, wxID_OK));
4167 DialogButtonSizer->AddButton(
new wxButton(
this, wxID_CANCEL));
4168 auto *help_btn =
new wxButton(
this, wxID_HELP);
4169 help_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [&](wxCommandEvent &) {
4171 Manual(
this, datadir.ToStdString()).Launch(
"Dashboard");
4173 DialogButtonSizer->AddButton(help_btn);
4174 DialogButtonSizer->Realize();
4176 itemBoxSizerMainPanel->Add(DialogButtonSizer, 0, wxALIGN_RIGHT | wxALL, 5);
4178 auto *itemNotebook =
new wxNotebook(dparent, wxID_ANY, wxDefaultPosition,
4179 wxDefaultSize, wxNB_TOP);
4180 itemBoxSizer2->Add(itemNotebook, 0, wxALL | wxEXPAND, border_size);
4182 auto *itemPanelNotebook01 =
4183 new wxPanel(itemNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
4185 auto *itemFlexGridSizer01 =
new wxFlexGridSizer(2);
4186 itemFlexGridSizer01->AddGrowableCol(1);
4187 itemPanelNotebook01->SetSizer(itemFlexGridSizer01);
4188 itemNotebook->AddPage(itemPanelNotebook01, _(
"Dashboard"));
4190 auto *itemBoxSizer01 =
new wxBoxSizer(wxVERTICAL);
4191 itemFlexGridSizer01->Add(itemBoxSizer01, 1, wxEXPAND | wxTOP | wxLEFT,
4195 int imageRefSize = wxWindow::GetCharWidth() * 4;
4197 auto *imglist1 =
new wxImageList(imageRefSize, imageRefSize,
true, 1);
4199 wxBitmap bmDashBoard;
4201 wxString filename = shareLocn +
"Dashboard.svg";
4204 wxImage dash1 = wxBitmap(*_img_dashboard_pi).ConvertToImage();
4206 dash1.Scale(imageRefSize, imageRefSize, wxIMAGE_QUALITY_HIGH);
4207 bmDashBoard = wxBitmap(dash1s);
4210 imglist1->Add(bmDashBoard);
4212 m_pListCtrlDashboards =
4213 new wxListCtrl(itemPanelNotebook01, wxID_ANY, wxDefaultPosition,
4214 wxSize(imageRefSize * 3 / 2, 200),
4215 wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL);
4217 m_pListCtrlDashboards->AssignImageList(imglist1, wxIMAGE_LIST_SMALL);
4218 m_pListCtrlDashboards->InsertColumn(0,
"");
4219 m_pListCtrlDashboards->Connect(
4220 wxEVT_COMMAND_LIST_ITEM_SELECTED,
4221 wxListEventHandler(DashboardPreferencesDialog::OnDashboardSelected),
4223 m_pListCtrlDashboards->Connect(
4224 wxEVT_COMMAND_LIST_ITEM_DESELECTED,
4225 wxListEventHandler(DashboardPreferencesDialog::OnDashboardSelected),
4227 itemBoxSizer01->Add(m_pListCtrlDashboards, 1, wxEXPAND, 0);
4229 auto *itemBoxSizer02 =
new wxBoxSizer(wxHORIZONTAL);
4230 itemBoxSizer01->Add(itemBoxSizer02);
4232 wxBitmap bmPlus, bmMinus;
4233 int bmSize = imageRefSize * 100 / 275;
4236 bmSize = imageRefSize / 2;
4243 wxImage plus1 = wxBitmap(*_img_plus).ConvertToImage();
4244 wxImage plus1s = plus1.Scale(bmSize, bmSize, wxIMAGE_QUALITY_HIGH);
4245 bmPlus = wxBitmap(plus1s);
4247 wxImage minus1 = wxBitmap(*_img_minus).ConvertToImage();
4248 wxImage minus1s = minus1.Scale(bmSize, bmSize, wxIMAGE_QUALITY_HIGH);
4249 bmMinus = wxBitmap(minus1s);
4252 m_pButtonAddDashboard =
new wxBitmapButton(
4253 itemPanelNotebook01, wxID_ANY, bmPlus, wxDefaultPosition, wxDefaultSize);
4254 itemBoxSizer02->Add(m_pButtonAddDashboard, 0, wxALIGN_CENTER, 2);
4255 m_pButtonAddDashboard->Connect(
4256 wxEVT_COMMAND_BUTTON_CLICKED,
4257 wxCommandEventHandler(DashboardPreferencesDialog::OnDashboardAdd),
4260 m_pButtonDeleteDashboard =
new wxBitmapButton(
4261 itemPanelNotebook01, wxID_ANY, bmMinus, wxDefaultPosition, wxDefaultSize);
4262 itemBoxSizer02->Add(m_pButtonDeleteDashboard, 0, wxALIGN_CENTER, 2);
4263 m_pButtonDeleteDashboard->Connect(
4264 wxEVT_COMMAND_BUTTON_CLICKED,
4265 wxCommandEventHandler(DashboardPreferencesDialog::OnDashboardDelete),
4269 new wxPanel(itemPanelNotebook01, wxID_ANY, wxDefaultPosition,
4270 wxDefaultSize, wxBORDER_SUNKEN);
4271 itemFlexGridSizer01->Add(m_pPanelDashboard, 1, wxEXPAND | wxTOP | wxRIGHT,
4274 auto *itemBoxSizer03 =
new wxBoxSizer(wxVERTICAL);
4275 m_pPanelDashboard->SetSizer(itemBoxSizer03);
4277 auto *itemStaticBox02 =
4278 new wxStaticBox(m_pPanelDashboard, wxID_ANY, _(
"Dashboard"));
4279 auto *itemStaticBoxSizer02 =
4280 new wxStaticBoxSizer(itemStaticBox02, wxHORIZONTAL);
4281 itemBoxSizer03->Add(itemStaticBoxSizer02, 0, wxEXPAND | wxALL, border_size);
4282 auto *itemFlexGridSizer =
new wxFlexGridSizer(2);
4283 itemFlexGridSizer->AddGrowableCol(1);
4284 itemStaticBoxSizer02->Add(itemFlexGridSizer, 1, wxEXPAND | wxALL, 0);
4286 m_pCheckBoxIsVisible =
4287 new wxCheckBox(m_pPanelDashboard, wxID_ANY, _(
"show this dashboard"),
4288 wxDefaultPosition, wxDefaultSize, 0);
4289 m_pCheckBoxIsVisible->SetMinSize(wxSize(25 * wxWindow::GetCharWidth(), -1));
4291 itemFlexGridSizer->Add(m_pCheckBoxIsVisible, 0, wxEXPAND | wxALL,
4293 auto *itemDummy01 =
new wxStaticText(m_pPanelDashboard, wxID_ANY,
"");
4294 itemFlexGridSizer->Add(itemDummy01, 0, wxEXPAND | wxALL, border_size);
4296 auto *itemStaticText01 =
4297 new wxStaticText(m_pPanelDashboard, wxID_ANY, _(
"Caption:"),
4298 wxDefaultPosition, wxDefaultSize, 0);
4299 itemFlexGridSizer->Add(itemStaticText01, 0, wxEXPAND | wxALL, border_size);
4300 m_pTextCtrlCaption =
new wxTextCtrl(m_pPanelDashboard, wxID_ANY,
"",
4301 wxDefaultPosition, wxDefaultSize);
4302 m_pCheckBoxIsVisible->SetMinSize(wxSize(30 * wxWindow::GetCharWidth(), -1));
4303 itemFlexGridSizer->Add(m_pTextCtrlCaption, 0, wxALIGN_RIGHT | wxALL,
4306 auto *itemStaticText02 =
4307 new wxStaticText(m_pPanelDashboard, wxID_ANY, _(
"Orientation:"),
4308 wxDefaultPosition, wxDefaultSize, 0);
4309 itemFlexGridSizer->Add(itemStaticText02, 0, wxEXPAND | wxALL, border_size);
4310 m_pChoiceOrientation =
new wxChoice(m_pPanelDashboard, wxID_ANY,
4311 wxDefaultPosition, wxDefaultSize);
4312 m_pChoiceOrientation->SetMinSize(wxSize(15 * wxWindow::GetCharWidth(), -1));
4313 m_pChoiceOrientation->Append(_(
"Vertical"));
4314 m_pChoiceOrientation->Append(_(
"Horizontal"));
4315 itemFlexGridSizer->Add(m_pChoiceOrientation, 0, wxALIGN_RIGHT | wxALL,
4320 auto *imglist =
new wxImageList(instImageRefSize, instImageRefSize,
true, 2);
4322 wxBitmap bmDial, bmInst;
4329 wxImage dial1 = wxBitmap(*_img_dial).ConvertToImage();
4331 dial1.Scale(instImageRefSize, instImageRefSize, wxIMAGE_QUALITY_HIGH);
4332 bmDial = wxBitmap(dial1);
4334 wxImage inst1 = wxBitmap(*_img_instrument).ConvertToImage();
4336 inst1.Scale(instImageRefSize, instImageRefSize, wxIMAGE_QUALITY_HIGH);
4337 bmInst = wxBitmap(inst1s);
4340 imglist->Add(bmInst);
4341 imglist->Add(bmDial);
4343 auto *itemStaticBox03 =
4344 new wxStaticBox(m_pPanelDashboard, wxID_ANY, _(
"Instruments"));
4345 auto *itemStaticBoxSizer03 =
4346 new wxStaticBoxSizer(itemStaticBox03, wxHORIZONTAL);
4347 itemBoxSizer03->Add(itemStaticBoxSizer03, 1, wxEXPAND | wxALL, border_size);
4350 wxSize list_size = wxSize(-1, dsize.y * 35 / 100);
4353 int xsize = GetCharWidth() * 30;
4354 list_size = wxSize(xsize, dsize.y * 50 / 100);
4357 m_pListCtrlInstruments =
4358 new wxListCtrl(m_pPanelDashboard, wxID_ANY, wxDefaultPosition, list_size,
4359 wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL);
4361 itemStaticBoxSizer03->Add(m_pListCtrlInstruments, 1, wxEXPAND | wxALL,
4363 m_pListCtrlInstruments->AssignImageList(imglist, wxIMAGE_LIST_SMALL);
4364 m_pListCtrlInstruments->InsertColumn(0, _(
"Instruments"));
4365 m_pListCtrlInstruments->Connect(
4366 wxEVT_COMMAND_LIST_ITEM_SELECTED,
4367 wxListEventHandler(DashboardPreferencesDialog::OnInstrumentSelected),
4369 m_pListCtrlInstruments->Connect(
4370 wxEVT_COMMAND_LIST_ITEM_DESELECTED,
4371 wxListEventHandler(DashboardPreferencesDialog::OnInstrumentSelected),
4374 auto *itemBoxSizer04 =
new wxBoxSizer(wxVERTICAL);
4375 itemStaticBoxSizer03->Add(itemBoxSizer04, 0, wxALIGN_TOP | wxALL,
4377 m_pButtonAdd =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Add..."),
4378 wxDefaultPosition, wxSize(-1, -1));
4379 itemBoxSizer04->Add(m_pButtonAdd, 0, wxEXPAND | wxALL, border_size);
4380 m_pButtonAdd->Connect(
4381 wxEVT_COMMAND_BUTTON_CLICKED,
4382 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentAdd),
4386 m_pButtonEdit =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Edit..."),
4387 wxDefaultPosition, wxDefaultSize);
4388 itemBoxSizer04->Add(m_pButtonEdit, 0, wxEXPAND | wxALL, border_size);
4389 m_pButtonEdit->Connect(
4390 wxEVT_COMMAND_BUTTON_CLICKED,
4391 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentEdit),
4402 m_pButtonDelete =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Delete"),
4403 wxDefaultPosition, wxSize(-1, -1));
4404 itemBoxSizer04->Add(m_pButtonDelete, 0, wxEXPAND | wxALL, border_size);
4405 m_pButtonDelete->Connect(
4406 wxEVT_COMMAND_BUTTON_CLICKED,
4407 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentDelete),
4409 itemBoxSizer04->AddSpacer(10);
4410 m_pButtonUp =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Up"),
4411 wxDefaultPosition, wxDefaultSize);
4412 itemBoxSizer04->Add(m_pButtonUp, 0, wxEXPAND | wxALL, border_size);
4413 m_pButtonUp->Connect(
4414 wxEVT_COMMAND_BUTTON_CLICKED,
4415 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentUp),
4417 m_pButtonDown =
new wxButton(m_pPanelDashboard, wxID_ANY, _(
"Down"),
4418 wxDefaultPosition, wxDefaultSize);
4419 itemBoxSizer04->Add(m_pButtonDown, 0, wxEXPAND | wxALL, border_size);
4420 m_pButtonDown->Connect(
4421 wxEVT_COMMAND_BUTTON_CLICKED,
4422 wxCommandEventHandler(DashboardPreferencesDialog::OnInstrumentDown),
4425 auto *itemPanelNotebook02 =
4426 new wxPanel(itemNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
4428 auto *itemBoxSizer05 =
new wxBoxSizer(wxVERTICAL);
4429 itemPanelNotebook02->SetSizer(itemBoxSizer05);
4430 itemNotebook->AddPage(itemPanelNotebook02, _(
"Appearance"));
4432 auto *itemStaticBox01 =
4433 new wxStaticBox(itemPanelNotebook02, wxID_ANY, _(
"Fonts"));
4434 auto *itemStaticBoxSizer01 =
4435 new wxStaticBoxSizer(itemStaticBox01, wxHORIZONTAL);
4436 itemBoxSizer05->Add(itemStaticBoxSizer01, 0, wxEXPAND | wxALL, border_size);
4437 auto *itemFlexGridSizer03 =
new wxFlexGridSizer(2);
4438 itemFlexGridSizer03->AddGrowableCol(1);
4439 itemStaticBoxSizer01->Add(itemFlexGridSizer03, 1, wxEXPAND | wxALL, 0);
4441 auto *itemStaticText04 =
4442 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Title:"),
4443 wxDefaultPosition, wxDefaultSize, 0);
4444 itemFlexGridSizer03->Add(itemStaticText04, 0, wxEXPAND | wxALL, border_size);
4446 m_font_picker_title =
4447 new wxFontPickerCtrl(itemPanelNotebook02, wxID_ANY, g_USFontTitle,
4448 wxDefaultPosition, wxDefaultSize);
4449 itemFlexGridSizer03->Add(m_font_picker_title, 0, wxALIGN_RIGHT | wxALL, 0);
4451 auto *itemStaticText05 =
4452 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Data:"),
4453 wxDefaultPosition, wxDefaultSize, 0);
4454 itemFlexGridSizer03->Add(itemStaticText05, 0, wxEXPAND | wxALL, border_size);
4455 m_font_picker_data =
4456 new wxFontPickerCtrl(itemPanelNotebook02, wxID_ANY, g_USFontData,
4457 wxDefaultPosition, wxDefaultSize);
4458 itemFlexGridSizer03->Add(m_font_picker_data, 0, wxALIGN_RIGHT | wxALL, 0);
4460 auto *itemStaticText06 =
4461 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Label:"),
4462 wxDefaultPosition, wxDefaultSize, 0);
4463 itemFlexGridSizer03->Add(itemStaticText06, 0, wxEXPAND | wxALL, border_size);
4464 m_font_picker_label =
4465 new wxFontPickerCtrl(itemPanelNotebook02, wxID_ANY, g_USFontLabel,
4466 wxDefaultPosition, wxDefaultSize);
4467 itemFlexGridSizer03->Add(m_font_picker_label, 0, wxALIGN_RIGHT | wxALL, 0);
4469 auto *itemStaticText07 =
4470 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Small:"),
4471 wxDefaultPosition, wxDefaultSize, 0);
4472 itemFlexGridSizer03->Add(itemStaticText07, 0, wxEXPAND | wxALL, border_size);
4473 m_font_picker_small =
4474 new wxFontPickerCtrl(itemPanelNotebook02, wxID_ANY, g_USFontSmall,
4475 wxDefaultPosition, wxDefaultSize);
4476 itemFlexGridSizer03->Add(m_font_picker_small, 0, wxALIGN_RIGHT | wxALL, 0);
4479 auto *itemStaticText80 =
4480 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Reset:"),
4481 wxDefaultPosition, wxDefaultSize, 0);
4482 itemFlexGridSizer03->Add(itemStaticText80, 0, wxEXPAND | wxALL, border_size);
4484 m_pButtondefaultFont =
new wxButton(itemPanelNotebook02, wxID_ANY,
4485 _(
"Set dashboard default fonts"),
4486 wxDefaultPosition, wxSize(-1, -1));
4487 itemFlexGridSizer03->Add(m_pButtondefaultFont, 0, wxALIGN_RIGHT | wxALL, 0);
4488 m_pButtondefaultFont->Connect(
4489 wxEVT_COMMAND_BUTTON_CLICKED,
4490 wxCommandEventHandler(DashboardPreferencesDialog::OnDashboarddefaultFont),
4493 auto *itemStaticBox04 =
new wxStaticBox(itemPanelNotebook02, wxID_ANY,
4494 _(
"Units, Ranges, Formats"));
4495 auto *itemStaticBoxSizer04 =
4496 new wxStaticBoxSizer(itemStaticBox04, wxHORIZONTAL);
4497 itemBoxSizer05->Add(itemStaticBoxSizer04, 0, wxEXPAND | wxALL, border_size);
4498 auto *itemFlexGridSizer04 =
new wxFlexGridSizer(2);
4499 itemFlexGridSizer04->AddGrowableCol(1);
4500 itemStaticBoxSizer04->Add(itemFlexGridSizer04, 1, wxEXPAND | wxALL, 0);
4501 auto *itemStaticText08 =
new wxStaticText(
4502 itemPanelNotebook02, wxID_ANY, _(
"Speedometer max value:"),
4503 wxDefaultPosition, wxDefaultSize, 0);
4504 itemFlexGridSizer04->Add(itemStaticText08, 0, wxEXPAND | wxALL, border_size);
4505 m_spin_speed_max =
new wxSpinCtrl(
4506 itemPanelNotebook02, wxID_ANY, wxEmptyString, wxDefaultPosition,
4507 wxDefaultSize, wxSP_ARROW_KEYS, 10, 100, g_iDashSpeedMax);
4508 itemFlexGridSizer04->Add(m_spin_speed_max, 0, wxALIGN_RIGHT | wxALL, 0);
4510 auto *itemStaticText10 =
new wxStaticText(
4511 itemPanelNotebook02, wxID_ANY, _(
"Speed Over Ground Damping Factor:"),
4512 wxDefaultPosition, wxDefaultSize, 0);
4513 itemFlexGridSizer04->Add(itemStaticText10, 0, wxEXPAND | wxALL, border_size);
4514 m_spin_sog_damp =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4515 wxDefaultPosition, wxDefaultSize,
4516 wxSP_ARROW_KEYS, 0, 100, g_iDashSOGDamp);
4517 itemFlexGridSizer04->Add(m_spin_sog_damp, 0, wxALIGN_RIGHT | wxALL, 0);
4519 auto *itemStaticText11 =
4520 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"COG Damping Factor:"),
4521 wxDefaultPosition, wxDefaultSize, 0);
4522 itemFlexGridSizer04->Add(itemStaticText11, 0, wxEXPAND | wxALL, border_size);
4523 m_spin_cog_damp =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4524 wxDefaultPosition, wxDefaultSize,
4525 wxSP_ARROW_KEYS, 0, 100, g_iDashCOGDamp);
4526 itemFlexGridSizer04->Add(m_spin_cog_damp, 0, wxALIGN_RIGHT | wxALL, 0);
4528 auto *itemStaticText13 =
new wxStaticText(
4529 itemPanelNotebook02, wxID_ANY, _(
"Wind speed Damping Factor:"),
4530 wxDefaultPosition, wxDefaultSize, 0);
4531 itemFlexGridSizer04->Add(itemStaticText13, 0, wxEXPAND | wxALL, border_size);
4532 m_spin_aws_damp =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4533 wxDefaultPosition, wxDefaultSize,
4534 wxSP_ARROW_KEYS, 0, 100, g_iDashAWSDamp);
4535 itemFlexGridSizer04->Add(m_spin_aws_damp, 0, wxALIGN_RIGHT | wxALL, 0);
4537 auto *itemStaticText14 =
new wxStaticText(
4538 itemPanelNotebook02, wxID_ANY, _(
"Wind angle Damping Factor:"),
4539 wxDefaultPosition, wxDefaultSize, 0);
4540 itemFlexGridSizer04->Add(itemStaticText14, 0, wxEXPAND | wxALL, border_size);
4541 m_spin_awa_damp =
new wxSpinCtrl(itemPanelNotebook02, wxID_ANY, wxEmptyString,
4542 wxDefaultPosition, wxDefaultSize,
4543 wxSP_ARROW_KEYS, 0, 100, g_iDashAWADamp);
4544 itemFlexGridSizer04->Add(m_spin_awa_damp, 0, wxALIGN_RIGHT | wxALL, 0);
4546 auto *itemStaticText12 =
new wxStaticText(
4547 itemPanelNotebook02, wxID_ANY, _(
"Local Time Offset From UTC:"),
4548 wxDefaultPosition, wxDefaultSize, 0);
4549 itemFlexGridSizer04->Add(itemStaticText12, 0, wxEXPAND | wxALL, border_size);
4550 wxString m_UTCOffsetChoices[] = {
4551 "-12:00",
"-11:30",
"-11:00",
"-10:30",
"-10:00",
"-09:30",
"-09:00",
4552 "-08:30",
"-08:00",
"-07:30",
"-07:00",
"-06:30",
"-06:00",
"-05:30",
4553 "-05:00",
"-04:30",
"-04:00",
"-03:30",
"-03:00",
"-02:30",
"-02:00",
4554 "-01:30",
"-01:00",
"-00:30",
" 00:00",
" 00:30",
" 01:00",
" 01:30",
4555 " 02:00",
" 02:30",
" 03:00",
" 03:30",
" 04:00",
" 04:30",
" 05:00",
4556 " 05:30",
" 06:00",
" 06:30",
" 07:00",
" 07:30",
" 08:00",
" 08:30",
4557 " 09:00",
" 09:30",
" 10:00",
" 10:30",
" 11:00",
" 11:30",
" 12:00"};
4558 int m_UTCOffsetNChoices =
sizeof(m_UTCOffsetChoices) /
sizeof(wxString);
4559 m_choice_utc_offset =
4560 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition,
4561 wxDefaultSize, m_UTCOffsetNChoices, m_UTCOffsetChoices, 0);
4562 m_choice_utc_offset->SetSelection(g_iUTCOffset + 24);
4563 itemFlexGridSizer04->Add(m_choice_utc_offset, 0, wxALIGN_RIGHT | wxALL, 0);
4565 auto *itemStaticText09 =
4566 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Boat speed units:"),
4567 wxDefaultPosition, wxDefaultSize, 0);
4568 itemFlexGridSizer04->Add(itemStaticText09, 0, wxEXPAND | wxALL, border_size);
4569 wxString m_SpeedUnitChoices[] = {_(
"Honor OpenCPN settings"), _(
"Kts"),
4570 _(
"mph"), _(
"km/h"), _(
"m/s")};
4571 int m_SpeedUnitNChoices =
sizeof(m_SpeedUnitChoices) /
sizeof(wxString);
4572 wxSize szSpeedUnit = wxDefaultSize;
4573 m_choice_speed_unit =
4574 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition,
4575 szSpeedUnit, m_SpeedUnitNChoices, m_SpeedUnitChoices, 0);
4576 for (
auto const &iUnit : m_SpeedUnitChoices) {
4577 szSpeedUnit.IncTo(m_choice_speed_unit->GetTextExtent(iUnit));
4579 m_choice_speed_unit->SetSize(szSpeedUnit);
4580 m_choice_speed_unit->SetSelection(g_iDashSpeedUnit + 1);
4581 itemFlexGridSizer04->Add(m_choice_speed_unit, 0, wxALIGN_RIGHT | wxALL, 0);
4583 auto *itemStaticTextDepthU =
4584 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Depth units:"),
4585 wxDefaultPosition, wxDefaultSize, 0);
4586 itemFlexGridSizer04->Add(itemStaticTextDepthU, 0, wxEXPAND | wxALL,
4588 wxString m_DepthUnitChoices[] = {_(
"Meters"), _(
"Feet"), _(
"Fathoms"),
4589 _(
"Inches"), _(
"Centimeters")};
4590 int m_DepthUnitNChoices =
sizeof(m_DepthUnitChoices) /
sizeof(wxString);
4591 wxSize szDepthUnit = wxDefaultSize;
4592 m_choice_depth_unit =
4593 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition,
4594 szDepthUnit, m_DepthUnitNChoices, m_DepthUnitChoices, 0);
4595 for (
auto const &iUnit : m_DepthUnitChoices) {
4596 szDepthUnit.IncTo(m_choice_depth_unit->GetTextExtent(iUnit));
4598 m_choice_depth_unit->SetSize(szDepthUnit);
4599 m_choice_depth_unit->SetSelection(g_iDashDepthUnit - 3);
4600 itemFlexGridSizer04->Add(m_choice_depth_unit, 0, wxALIGN_RIGHT | wxALL, 0);
4601 wxString dMess = wxString::Format(_(
"Depth Offset (%s):"),
4602 m_DepthUnitChoices[g_iDashDepthUnit - 3]);
4603 auto *itemStaticDepthO =
4604 new wxStaticText(itemPanelNotebook02, wxID_ANY, dMess, wxDefaultPosition,
4607 switch (g_iDashDepthUnit - 3) {
4609 DepthOffset = g_dDashDBTOffset * 3.2808399;
4612 DepthOffset = g_dDashDBTOffset * 0.54680665;
4615 DepthOffset = g_dDashDBTOffset * 39.3700787;
4618 DepthOffset = g_dDashDBTOffset * 100;
4621 DepthOffset = g_dDashDBTOffset;
4623 itemFlexGridSizer04->Add(itemStaticDepthO, 0, wxEXPAND | wxALL, border_size);
4624 m_spin_dbt_offset =
new wxSpinCtrlDouble(
4625 itemPanelNotebook02, wxID_ANY, wxEmptyString, wxDefaultPosition,
4626 wxDefaultSize, wxSP_ARROW_KEYS, -100, 100, DepthOffset, 0.1);
4627 itemFlexGridSizer04->Add(m_spin_dbt_offset, 0, wxALIGN_RIGHT | wxALL, 0);
4629 auto *itemStaticText0b =
4630 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Distance units:"),
4631 wxDefaultPosition, wxDefaultSize, 0);
4632 itemFlexGridSizer04->Add(itemStaticText0b, 0, wxEXPAND | wxALL, border_size);
4633 wxString m_DistanceUnitChoices[] = {_(
"Honor OpenCPN settings"),
4634 _(
"Nautical miles"), _(
"Statute miles"),
4635 _(
"Kilometers"), _(
"Meters")};
4636 wxSize szDistanceUnit = wxDefaultSize;
4637 int m_DistanceUnitNChoices =
sizeof(m_DistanceUnitChoices) /
sizeof(wxString);
4638 m_choice_distance_unit =
new wxChoice(
4639 itemPanelNotebook02, wxID_ANY, wxDefaultPosition, szDistanceUnit,
4640 m_DistanceUnitNChoices, m_DistanceUnitChoices, 0);
4641 for (
auto const &iUnit : m_DistanceUnitChoices) {
4642 szDistanceUnit.IncTo(m_choice_distance_unit->GetTextExtent(iUnit));
4644 m_choice_distance_unit->SetSize(szDistanceUnit);
4645 m_choice_distance_unit->SetSelection(g_iDashDistanceUnit + 1);
4646 itemFlexGridSizer04->Add(m_choice_distance_unit, 0, wxALIGN_RIGHT | wxALL, 0);
4647 m_choice_distance_unit->Connect(
4648 wxEVT_COMMAND_CHOICE_SELECTED,
4649 wxCommandEventHandler(DashboardPreferencesDialog::OnDistanceUnitSelect),
4652 auto *itemStaticText0a =
4653 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Wind speed units:"),
4654 wxDefaultPosition, wxDefaultSize, 0);
4655 itemFlexGridSizer04->Add(itemStaticText0a, 0, wxEXPAND | wxALL, border_size);
4656 wxString m_WSpeedUnitChoices[] = {_(
"Kts"), _(
"mph"), _(
"km/h"), _(
"m/s")};
4657 int m_WSpeedUnitNChoices =
sizeof(m_WSpeedUnitChoices) /
sizeof(wxString);
4658 wxSize szWSpeedUnit = wxDefaultSize;
4659 m_choice_wind_speed_unit =
4660 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition,
4661 szWSpeedUnit, m_WSpeedUnitNChoices, m_WSpeedUnitChoices, 0);
4662 for (
auto const &iUnit : m_WSpeedUnitChoices) {
4663 szWSpeedUnit.IncTo(m_choice_wind_speed_unit->GetTextExtent(iUnit));
4665 m_choice_wind_speed_unit->SetSize(szWSpeedUnit);
4666 m_choice_wind_speed_unit->SetSelection(g_iDashWindSpeedUnit);
4667 itemFlexGridSizer04->Add(m_choice_wind_speed_unit, 0, wxALIGN_RIGHT | wxALL,
4670 auto *itemStaticText0c =
4671 new wxStaticText(itemPanelNotebook02, wxID_ANY, _(
"Temperature units:"),
4672 wxDefaultPosition, wxDefaultSize, 0);
4673 itemFlexGridSizer04->Add(itemStaticText0c, 0, wxEXPAND | wxALL, border_size);
4674 wxString m_TempUnitChoices[] = {_(
"Celsius"), _(
"Fahrenheit"), _(
"Kelvin")};
4675 int m_TempUnitNChoices =
sizeof(m_TempUnitChoices) /
sizeof(wxString);
4676 wxSize szTempUnit = wxDefaultSize;
4677 m_choice_temp_unit =
4678 new wxChoice(itemPanelNotebook02, wxID_ANY, wxDefaultPosition, szTempUnit,
4679 m_TempUnitNChoices, m_TempUnitChoices, 0);
4680 for (
auto const &iUnit : m_TempUnitChoices) {
4681 szTempUnit.IncTo(m_choice_temp_unit->GetTextExtent(iUnit));
4683 m_choice_temp_unit->SetSize(szTempUnit);
4684 m_choice_temp_unit->SetSelection(g_iDashTempUnit);
4685 itemFlexGridSizer04->Add(m_choice_temp_unit, 0, wxALIGN_RIGHT | wxALL, 0);
4689 auto *itemStaticBox05 =
4690 new wxStaticBox(itemPanelNotebook02, wxID_ANY, _(
"Other selections"));
4691 auto *itemStaticBoxSizer05 =
4692 new wxStaticBoxSizer(itemStaticBox05, wxHORIZONTAL);
4693 itemBoxSizer05->Add(itemStaticBoxSizer05, 0, wxEXPAND | wxALL, border_size);
4695 auto *itemFlexGridSizer05 =
new wxFlexGridSizer(3);
4696 itemFlexGridSizer05->AddGrowableCol(1);
4697 itemStaticBoxSizer05->Add(itemFlexGridSizer05, 1, wxEXPAND | wxALL, 0);
4699 m_use_intern_sum_log =
4700 new wxCheckBox(itemPanelNotebook02, wxID_ANY,
4701 _(
"Use internal Sumlog.") +
" " +
4702 _(
"Enter new value if desired"));
4703 itemFlexGridSizer05->Add(m_use_intern_sum_log, 1, wxALIGN_LEFT, border_size);
4704 m_use_intern_sum_log->SetValue(g_bUseInternSumLog);
4707 new wxStaticText(itemPanelNotebook02, wxID_ANY,
4709 wxDefaultPosition, wxDefaultSize, 0);
4710 itemFlexGridSizer05->Add(m_sum_log_unit, 1, wxALIGN_RIGHT, 0);
4712 m_sum_log_value =
new wxTextCtrl(itemPanelNotebook02, wxID_ANY,
"");
4713 itemFlexGridSizer05->Add(m_sum_log_value, 1, wxALIGN_LEFT, 1);
4714 m_sum_log_value->SetValue(wxString::Format(
4717 m_use_true_winddata =
4718 new wxCheckBox(itemPanelNotebook02, wxID_ANY,
4719 _(
"Use N2K & SignalK true wind data over "
4720 "ground.\n(Instead of through water)"));
4721 itemFlexGridSizer05->Add(m_use_true_winddata, 1, wxALIGN_LEFT, border_size);
4722 m_use_true_winddata->SetValue(g_bDBtrueWindGround);
4726 auto *itemStaticBox05 =
4727 new wxStaticBox(itemPanelNotebook02, wxID_ANY, _(
"Other selections"));
4728 auto *itemStaticBoxSizer05 =
4729 new wxStaticBoxSizer(itemStaticBox05, wxHORIZONTAL);
4730 itemBoxSizer05->Add(itemStaticBoxSizer05, 0, wxEXPAND | wxALL, border_size);
4732 auto *itemFlexGridSizer05 =
new wxFlexGridSizer(2);
4733 itemFlexGridSizer05->AddGrowableCol(1);
4734 itemStaticBoxSizer05->Add(itemFlexGridSizer05, 1, wxEXPAND | wxALL, 0);
4736 m_use_intern_sum_log =
new wxCheckBox(itemPanelNotebook02, wxID_ANY,
4737 _(
"Use internal Sumlog.") +
" ");
4738 itemFlexGridSizer05->Add(m_use_intern_sum_log, 0, wxALIGN_LEFT, border_size);
4739 m_use_intern_sum_log->SetValue(g_bUseInternSumLog);
4740 itemFlexGridSizer05->AddSpacer(0);
4743 new wxStaticText(itemPanelNotebook02, wxID_ANY,
4744 " " + _(
"Enter new value if desired") +
" ",
4745 wxDefaultPosition, wxDefaultSize, 0);
4746 itemFlexGridSizer05->Add(xtext, 1, wxALIGN_LEFT, 0);
4747 itemFlexGridSizer05->AddSpacer(0);
4749 m_sum_log_unit =
new wxStaticText(
4750 itemPanelNotebook02, wxID_ANY,
4752 wxDefaultPosition, wxDefaultSize, 0);
4753 itemFlexGridSizer05->Add(m_sum_log_unit, 1, wxALIGN_RIGHT, 0);
4755 m_sum_log_value =
new wxTextCtrl(itemPanelNotebook02, wxID_ANY,
"");
4756 itemFlexGridSizer05->Add(m_sum_log_value, 1, wxALIGN_LEFT, 1);
4757 m_sum_log_value->SetValue(wxString::Format(
4760 m_use_true_winddata =
4761 new wxCheckBox(itemPanelNotebook02, wxID_ANY,
4762 _(
"Use N2K & SignalK true wind data over "
4763 "ground.\n(Instead of through water)"));
4764 itemFlexGridSizer05->Add(m_use_true_winddata, 1, wxALIGN_LEFT, border_size);
4765 m_use_true_winddata->SetValue(g_bDBtrueWindGround);
4766 itemFlexGridSizer05->AddSpacer(0);
4768 auto xtext1 =
new wxStaticText(itemPanelNotebook02, wxID_ANY,
" ",
4769 wxDefaultPosition, wxDefaultSize, 0);
4770 itemFlexGridSizer05->Add(xtext1, 1, wxALIGN_LEFT, 0);
4771 itemFlexGridSizer05->AddSpacer(0);
4773 auto xtext2 =
new wxStaticText(itemPanelNotebook02, wxID_ANY,
" ",
4774 wxDefaultPosition, wxDefaultSize, 0);
4775 itemFlexGridSizer05->Add(xtext2, 1, wxALIGN_LEFT, 0);
4776 itemFlexGridSizer05->AddSpacer(0);
4781 for (
size_t i = 0; i < m_config.GetCount(); i++) {
4782 m_pListCtrlDashboards->InsertItem(i, 0);
4784 m_pListCtrlDashboards->SetItemData(i, i);
4786 m_pListCtrlDashboards->SetColumnWidth(0, wxLIST_AUTOSIZE);
4788 m_pListCtrlDashboards->SetItemState(0, wxLIST_STATE_SELECTED,
4789 wxLIST_STATE_SELECTED);
4792 UpdateDashboardButtonsState();
4793 UpdateButtonsState();
4800 SetMaxSize(wxSize(display_width, display_height));
4803 if (display_height < 600) {
4804 if (g_dashPrefWidth > 0 && g_dashPrefHeight > 0)
4805 SetSize(wxSize(g_dashPrefWidth, g_dashPrefHeight));
4807 SetSize(wxSize(canvas_size.x * 8 / 10, canvas_size.y * 8 / 10));
4809 if (g_dashPrefWidth > 0 && g_dashPrefHeight > 0)
4810 SetSize(wxSize(g_dashPrefWidth, g_dashPrefHeight));
4812 SetSize(wxSize(canvas_size.x * 3 / 4, canvas_size.y * 8 / 10));
4819void DashboardPreferencesDialog::RecalculateSize() {
4822 esize.x = GetCharWidth() * 110;
4823 esize.y = GetCharHeight() * 40;
4826 esize.y = wxMin(esize.y, dsize.y - (3 * GetCharHeight()));
4827 esize.x = wxMin(esize.x, dsize.x - (3 * GetCharHeight()));
4834void DashboardPreferencesDialog::OnCloseDialog(wxCloseEvent &event) {
4835 g_dashPrefWidth = GetSize().x;
4836 g_dashPrefHeight = GetSize().y;
4837 SaveDashboardConfig();
4841void DashboardPreferencesDialog::SaveDashboardConfig() {
4842 g_iDashSpeedMax = m_spin_speed_max->GetValue();
4843 g_iDashCOGDamp = m_spin_cog_damp->GetValue();
4844 g_iDashSOGDamp = m_spin_sog_damp->GetValue();
4845 g_iDashAWADamp = m_spin_awa_damp->GetValue();
4846 g_iDashAWSDamp = m_spin_aws_damp->GetValue();
4848 g_bUseInternSumLog = m_use_intern_sum_log->IsChecked();
4850 m_sum_log_value->GetValue().ToDouble(&ursDist);
4853 g_iUTCOffset = m_choice_utc_offset->GetSelection() - 24;
4854 g_iDashSpeedUnit = m_choice_speed_unit->GetSelection() - 1;
4855 double DashDBTOffset = m_spin_dbt_offset->GetValue();
4856 switch (g_iDashDepthUnit - 3) {
4858 g_dDashDBTOffset = DashDBTOffset / 3.2808399;
4861 g_dDashDBTOffset = DashDBTOffset / 0.54680665;
4864 g_dDashDBTOffset = DashDBTOffset / 39.3700787;
4867 g_dDashDBTOffset = DashDBTOffset / 100;
4870 g_dDashDBTOffset = DashDBTOffset;
4872 g_iDashDepthUnit = m_choice_depth_unit->GetSelection() + 3;
4873 g_iDashDistanceUnit = m_choice_distance_unit->GetSelection() - 1;
4874 g_iDashWindSpeedUnit = m_choice_wind_speed_unit->GetSelection();
4875 g_bDBtrueWindGround = m_use_true_winddata->GetValue();
4876 g_iDashTempUnit = m_choice_temp_unit->GetSelection();
4879 cont->m_bIsVisible = m_pCheckBoxIsVisible->IsChecked();
4880 cont->m_sCaption = m_pTextCtrlCaption->GetValue();
4881 cont->m_sOrientation =
4882 m_pChoiceOrientation->GetSelection() == 0 ?
"V" :
"H";
4883 cont->m_aInstrumentList.Clear();
4884 for (
int i = 0; i < m_pListCtrlInstruments->GetItemCount(); i++)
4885 cont->m_aInstrumentList.Add((
int)m_pListCtrlInstruments->GetItemData(i));
4889void DashboardPreferencesDialog::OnDashboardSelected(wxListEvent &event) {
4891 SaveDashboardConfig();
4892 UpdateDashboardButtonsState();
4895void DashboardPreferencesDialog::UpdateDashboardButtonsState() {
4897 item = m_pListCtrlDashboards->GetNextItem(item, wxLIST_NEXT_ALL,
4898 wxLIST_STATE_SELECTED);
4899 bool enable = (item != -1);
4903 bool delete_enable = enable;
4905 int sel = m_pListCtrlDashboards->GetItemData(item);
4908 if (dash_sel == GetParent()) delete_enable =
false;
4910 m_pButtonDeleteDashboard->Enable(delete_enable);
4912 m_pPanelDashboard->Enable(enable);
4915 curSel = m_pListCtrlDashboards->GetItemData(item);
4917 m_pCheckBoxIsVisible->SetValue(cont->m_bIsVisible);
4918 m_pTextCtrlCaption->SetValue(cont->m_sCaption);
4919 m_pChoiceOrientation->SetSelection(cont->m_sOrientation ==
"V" ? 0 : 1);
4920 m_pListCtrlInstruments->DeleteAllItems();
4921 for (
size_t i = 0; i < cont->m_aInstrumentList.GetCount(); i++) {
4923 getListItemForInstrument(item_, cont->m_aInstrumentList.Item(i));
4924 item_.SetId(m_pListCtrlInstruments->GetItemCount());
4925 m_pListCtrlInstruments->InsertItem(item_);
4928 m_pListCtrlInstruments->SetColumnWidth(0, wxLIST_AUTOSIZE);
4931 m_pCheckBoxIsVisible->SetValue(
false);
4932 m_pTextCtrlCaption->SetValue(
"");
4933 m_pChoiceOrientation->SetSelection(0);
4934 m_pListCtrlInstruments->DeleteAllItems();
4939void DashboardPreferencesDialog::OnDashboarddefaultFont(wxCommandEvent &event) {
4940 m_font_picker_title->SetSelectedFont(
4941 wxFont(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_ITALIC, wxFONTWEIGHT_NORMAL));
4942 m_font_picker_title->SetSelectedColour(wxColour(0, 0, 0));
4943 m_font_picker_data->SetSelectedFont(
4944 wxFont(14, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
4945 m_font_picker_data->SetSelectedColour(wxColour(0, 0, 0));
4946 m_font_picker_label->SetSelectedFont(
4947 wxFont(8, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
4948 m_font_picker_label->SetSelectedColour(wxColour(0, 0, 0));
4949 m_font_picker_small->SetSelectedFont(
4950 wxFont(8, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
4951 m_font_picker_small->SetSelectedColour(wxColour(0, 0, 0));
4952 double scaler = 1.0;
4955 scaler = wxMax(1.0, scaler);
4957 g_USFontTitle = *(m_font_picker_title->GetFontData());
4958 g_FontTitle = *g_pUSFontTitle;
4959 g_FontTitle.SetChosenFont(g_pUSFontTitle->GetChosenFont().Scaled(scaler));
4960 g_FontTitle.SetColour(g_pUSFontTitle->GetColour());
4961 g_USFontTitle = *g_pUSFontTitle;
4963 g_USFontData = *(m_font_picker_data->GetFontData());
4964 g_FontData = *g_pUSFontData;
4965 g_FontData.SetChosenFont(g_pUSFontData->GetChosenFont().Scaled(scaler));
4966 g_FontData.SetColour(g_pUSFontData->GetColour());
4967 g_USFontData = *g_pUSFontData;
4969 g_USFontLabel = *(m_font_picker_label->GetFontData());
4970 g_FontLabel = *g_pUSFontLabel;
4971 g_FontLabel.SetChosenFont(g_pUSFontLabel->GetChosenFont().Scaled(scaler));
4972 g_FontLabel.SetColour(g_pUSFontLabel->GetColour());
4973 g_USFontLabel = *g_pUSFontLabel;
4975 g_USFontSmall = *(m_font_picker_small->GetFontData());
4976 g_FontSmall = *g_pUSFontSmall;
4977 g_FontSmall.SetChosenFont(g_pUSFontSmall->GetChosenFont().Scaled(scaler));
4978 g_FontSmall.SetColour(g_pUSFontSmall->GetColour());
4979 g_USFontSmall = *g_pUSFontSmall;
4982void DashboardPreferencesDialog::OnDashboardAdd(wxCommandEvent &event) {
4983 int idx = m_pListCtrlDashboards->GetItemCount();
4984 m_pListCtrlDashboards->InsertItem(idx, 0);
4986 m_pListCtrlDashboards->SetItemData(idx, m_config.GetCount());
4988 wxArrayOfInstrumentProperties Property;
4991 dwc->m_bIsVisible =
true;
4995void DashboardPreferencesDialog::OnDashboardDelete(wxCommandEvent &event) {
4997 itemID = m_pListCtrlDashboards->GetNextItem(itemID, wxLIST_NEXT_ALL,
4998 wxLIST_STATE_SELECTED);
5000 int idx = m_pListCtrlDashboards->GetItemData(itemID);
5001 m_pListCtrlDashboards->DeleteItem(itemID);
5002 m_config.Item(idx)->m_bIsDeleted =
true;
5003 UpdateDashboardButtonsState();
5006void DashboardPreferencesDialog::OnInstrumentSelected(wxListEvent &event) {
5007 UpdateButtonsState();
5010void DashboardPreferencesDialog::UpdateButtonsState() {
5012 item = m_pListCtrlInstruments->GetNextItem(item, wxLIST_NEXT_ALL,
5013 wxLIST_STATE_SELECTED);
5014 bool enable = (item != -1);
5016 m_pButtonDelete->Enable(enable);
5017 m_pButtonEdit->Enable(enable);
5018 m_pButtonUp->Enable(item > 0);
5019 m_pButtonDown->Enable(item != -1 &&
5020 item < m_pListCtrlInstruments->GetItemCount() - 1);
5023void DashboardPreferencesDialog::OnInstrumentAdd(wxCommandEvent &event) {
5031 esize.x = GetCharWidth() * 110;
5032 esize.y = GetCharHeight() * 40;
5035 esize.y = wxMin(esize.y, dsize.y - (3 * GetCharHeight()));
5036 esize.x = wxMin(esize.x, dsize.x - (3 * GetCharHeight()));
5037 pdlg.SetSize(esize);
5039 pdlg.CentreOnScreen();
5042 if (pdlg.GetReturnCode() == wxID_OK) {
5044 getListItemForInstrument(item, pdlg.GetInstrumentAdded());
5045 item.SetId(m_pListCtrlInstruments->GetItemCount());
5046 m_pListCtrlInstruments->InsertItem(item);
5047 m_pListCtrlInstruments->SetColumnWidth(0, wxLIST_AUTOSIZE);
5048 UpdateButtonsState();
5052void DashboardPreferencesDialog::OnInstrumentDelete(wxCommandEvent &event) {
5053 long itemIDWindow = -1;
5054 itemIDWindow = m_pListCtrlDashboards->GetNextItem(
5055 itemIDWindow, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
5057 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5058 wxLIST_STATE_SELECTED);
5060 m_config.Item(m_pListCtrlDashboards->GetItemData(itemIDWindow));
5064 for (
unsigned int i = 0; i < (cont->m_aInstrumentPropertyList.GetCount());
5066 Inst = cont->m_aInstrumentPropertyList.Item(i);
5067 if (Inst->m_aInstrument ==
5068 (
int)m_pListCtrlInstruments->GetItemData(itemID) &&
5069 Inst->m_Listplace == itemID) {
5070 cont->m_aInstrumentPropertyList.Remove(Inst);
5074 if (Inst->m_Listplace > itemID) Inst->m_Listplace--;
5078 m_pListCtrlInstruments->DeleteItem(itemID);
5080 cont->m_pDashboardWindow->SetInstrumentList(
5081 cont->m_aInstrumentList, &(cont->m_aInstrumentPropertyList));
5084 UpdateButtonsState();
5087inline void GetFontData(
OCPNFontButton *FontButton, wxFontData &UnScaledFont,
5088 wxFontData &ScaledFont,
double scaler) {
5089 UnScaledFont = *(FontButton->GetFontData());
5090 ScaledFont = UnScaledFont;
5091 ScaledFont.SetChosenFont(UnScaledFont.GetChosenFont().Scaled(scaler));
5094void DashboardPreferencesDialog::OnInstrumentEdit(wxCommandEvent &event) {
5097 long itemIDWindow = -1;
5098 itemIDWindow = m_pListCtrlDashboards->GetNextItem(
5099 itemIDWindow, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
5101 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5102 wxLIST_STATE_SELECTED);
5108 m_config.Item(m_pListCtrlDashboards->GetItemData(itemIDWindow));
5111 for (
unsigned int i = 0; i < (cont->m_aInstrumentPropertyList.GetCount());
5113 Inst = cont->m_aInstrumentPropertyList.Item(
5115 if (Inst->m_aInstrument == (
int)m_pListCtrlInstruments->GetItemData(
5118 if (Inst->m_Listplace == itemID)
break;
5125 cont->m_aInstrumentPropertyList.Add(Inst);
5127 auto *Edit =
new EditDialog(
this, *Inst, wxID_ANY);
5129 bool DefaultFont =
false;
5130 if (Edit->ShowModal() == wxID_OK) {
5132 double scaler = 1.0;
5135 scaler = wxMax(1.0, scaler);
5136 if (Edit->m_fontPicker2->GetFont().Scaled(scaler) !=
5137 g_FontTitle.GetChosenFont() ||
5138 Edit->m_fontPicker2->GetSelectedColour() != g_FontTitle.GetColour())
5139 DefaultFont =
false;
5140 if (Edit->m_fontPicker4->GetFont().Scaled(scaler) !=
5141 g_FontData.GetChosenFont() ||
5142 Edit->m_fontPicker4->GetSelectedColour() != g_FontData.GetColour())
5143 DefaultFont =
false;
5144 if (Edit->m_fontPicker5->GetFont().Scaled(scaler) !=
5145 g_FontLabel.GetChosenFont() ||
5146 Edit->m_fontPicker5->GetSelectedColour() != g_FontLabel.GetColour())
5147 DefaultFont =
false;
5148 if (Edit->m_fontPicker6->GetFont().Scaled(scaler) !=
5149 g_FontSmall.GetChosenFont() ||
5150 Edit->m_fontPicker6->GetSelectedColour() != g_FontSmall.GetColour())
5151 DefaultFont =
false;
5153 GetGlobalColor(
"DASHL", &dummy);
5154 if (Edit->m_colourPicker1->GetColour() != dummy) DefaultFont =
false;
5155 GetGlobalColor(
"DASHB", &dummy);
5156 if (Edit->m_colourPicker2->GetColour() != dummy) DefaultFont =
false;
5157 GetGlobalColor(
"DASHN", &dummy);
5158 if (Edit->m_colourPicker3->GetColour() != dummy) DefaultFont =
false;
5159 GetGlobalColor(
"BLUE3", &dummy);
5160 if (Edit->m_colourPicker4->GetColour() != dummy) DefaultFont =
false;
5162 cont->m_aInstrumentPropertyList.Remove(Inst);
5164 GetFontData(Edit->m_fontPicker2, Inst->m_USTitleFont, Inst->m_TitleFont,
5166 GetFontData(Edit->m_fontPicker4, Inst->m_USDataFont, Inst->m_DataFont,
5168 GetFontData(Edit->m_fontPicker5, Inst->m_USLabelFont, Inst->m_LabelFont,
5170 GetFontData(Edit->m_fontPicker6, Inst->m_USSmallFont, Inst->m_SmallFont,
5172 Inst->m_DataBackgroundColour = Edit->m_colourPicker2->GetColour();
5173 Inst->m_TitleBackgroundColour = Edit->m_colourPicker1->GetColour();
5174 Inst->m_Arrow_First_Colour = Edit->m_colourPicker3->GetColour();
5175 Inst->m_Arrow_Second_Colour = Edit->m_colourPicker4->GetColour();
5179 if (cont->m_pDashboardWindow) {
5180 cont->m_pDashboardWindow->SetInstrumentList(
5181 cont->m_aInstrumentList, &(cont->m_aInstrumentPropertyList));
5183 if (DefaultFont)
delete Inst;
5186void DashboardPreferencesDialog::OnInstrumentUp(wxCommandEvent &event) {
5187 long itemIDWindow = -1;
5188 itemIDWindow = m_pListCtrlDashboards->GetNextItem(
5189 itemIDWindow, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
5191 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5192 wxLIST_STATE_SELECTED);
5195 item.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_IMAGE | wxLIST_MASK_DATA);
5196 m_pListCtrlInstruments->GetItem(item);
5197 item.SetId(itemID - 1);
5201 m_config.Item(m_pListCtrlDashboards->GetItemData(itemIDWindow));
5204 for (
unsigned int i = 0; i < (cont->m_aInstrumentPropertyList.GetCount());
5206 Inst = cont->m_aInstrumentPropertyList.Item(i);
5207 if (Inst->m_Listplace == (itemID - 1)) Inst->m_Listplace = itemID;
5208 if (Inst->m_aInstrument ==
5209 (
int)m_pListCtrlInstruments->GetItemData(itemID) &&
5210 Inst->m_Listplace == itemID) {
5211 cont->m_aInstrumentPropertyList.Item(i)->m_Listplace = itemID - 1;
5215 m_pListCtrlInstruments->DeleteItem(itemID);
5216 m_pListCtrlInstruments->InsertItem(item);
5217 for (
int i = 0; i < m_pListCtrlInstruments->GetItemCount(); i++)
5218 m_pListCtrlInstruments->SetItemState(i, 0, wxLIST_STATE_SELECTED);
5220 m_pListCtrlInstruments->SetItemState(itemID - 1, wxLIST_STATE_SELECTED,
5221 wxLIST_STATE_SELECTED);
5223 UpdateButtonsState();
5226void DashboardPreferencesDialog::OnInstrumentDown(wxCommandEvent &event) {
5227 long itemIDWindow = -1;
5228 itemIDWindow = m_pListCtrlDashboards->GetNextItem(
5229 itemIDWindow, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
5231 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5232 wxLIST_STATE_SELECTED);
5236 item.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_IMAGE | wxLIST_MASK_DATA);
5237 m_pListCtrlInstruments->GetItem(item);
5238 item.SetId(itemID + 1);
5242 m_config.Item(m_pListCtrlDashboards->GetItemData(itemIDWindow));
5245 for (
unsigned int i = 0; i < (cont->m_aInstrumentPropertyList.GetCount());
5247 Inst = cont->m_aInstrumentPropertyList.Item(i);
5248 if (Inst->m_Listplace == (itemID + 1) &&
5249 Inst->m_aInstrument !=
5250 (int)m_pListCtrlInstruments->GetItemData(itemID))
5251 Inst->m_Listplace = itemID;
5252 if (Inst->m_aInstrument ==
5253 (
int)m_pListCtrlInstruments->GetItemData(itemID) &&
5254 Inst->m_Listplace == itemID) {
5255 cont->m_aInstrumentPropertyList.Item(i)->m_Listplace = itemID + 1;
5260 m_pListCtrlInstruments->DeleteItem(itemID);
5261 m_pListCtrlInstruments->InsertItem(item);
5262 for (
int i = 0; i < m_pListCtrlInstruments->GetItemCount(); i++)
5263 m_pListCtrlInstruments->SetItemState(i, 0, wxLIST_STATE_SELECTED);
5265 m_pListCtrlInstruments->SetItemState(itemID + 1, wxLIST_STATE_SELECTED,
5266 wxLIST_STATE_SELECTED);
5268 UpdateButtonsState();
5271void DashboardPreferencesDialog::OnDistanceUnitSelect(wxCommandEvent &event) {
5273 g_iDashDistanceUnit = m_choice_distance_unit->GetSelection() - 1;
5276 m_sum_log_value->SetValue(wxString::Format(
5286AddInstrumentDlg::AddInstrumentDlg(wxWindow *pparent, wxWindowID
id)
5287 : wxDialog(pparent, id, _(
"Add instrument"), wxDefaultPosition,
5288 wxDefaultSize, wxDEFAULT_DIALOG_STYLE) {
5289 wxBoxSizer *itemBoxSizer01 =
new wxBoxSizer(wxVERTICAL);
5290 SetSizer(itemBoxSizer01);
5291 wxStaticText *itemStaticText01 =
5292 new wxStaticText(
this, wxID_ANY, _(
"Select instrument to add:"),
5293 wxDefaultPosition, wxDefaultSize, 0);
5294 itemBoxSizer01->Add(itemStaticText01, 0, wxEXPAND | wxALL, 5);
5298 wxImageList *imglist =
5299 new wxImageList(instImageRefSize, instImageRefSize,
true, 2);
5301 wxImage inst1 = wxBitmap(*_img_instrument).ConvertToImage();
5303 inst1.Scale(instImageRefSize, instImageRefSize, wxIMAGE_QUALITY_HIGH);
5304 imglist->Add(wxBitmap(inst1s));
5306 wxImage dial1 = wxBitmap(*_img_dial).ConvertToImage();
5308 dial1.Scale(instImageRefSize, instImageRefSize, wxIMAGE_QUALITY_HIGH);
5309 imglist->Add(wxBitmap(dial1s));
5312 int vsize = dsize.y * 50 / 100;
5316 wxDisplaySize(&dw, &dh);
5317 vsize = dh * 50 / 100;
5320 m_pListCtrlInstruments =
new wxListCtrl(
5321 this, wxID_ANY, wxDefaultPosition, wxSize(-1, vsize ),
5322 wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING);
5323 itemBoxSizer01->Add(m_pListCtrlInstruments, 0, wxEXPAND | wxALL, 5);
5324 m_pListCtrlInstruments->AssignImageList(imglist, wxIMAGE_LIST_SMALL);
5325 m_pListCtrlInstruments->InsertColumn(0, _(
"Instruments"));
5328 m_pListCtrlInstruments->SetFont(*pF);
5331 m_pListCtrlInstruments->GetHandle()->setStyleSheet(qtStyleSheet);
5335 wxStdDialogButtonSizer *DialogButtonSizer =
5336 CreateStdDialogButtonSizer(wxOK | wxCANCEL);
5337 itemBoxSizer01->Add(DialogButtonSizer, 0, wxALIGN_RIGHT | wxALL, 5);
5340 for (
unsigned int i = ID_DBP_I_POS; i < ID_DBP_LAST_ENTRY;
5344 if (IsObsolete(i))
continue;
5345 getListItemForInstrument(item, i);
5347 m_pListCtrlInstruments->InsertItem(item);
5351 m_pListCtrlInstruments->SetColumnWidth(0, wxLIST_AUTOSIZE);
5352 m_pListCtrlInstruments->SetItemState(0, wxLIST_STATE_SELECTED,
5353 wxLIST_STATE_SELECTED);
5357unsigned int AddInstrumentDlg::GetInstrumentAdded() {
5359 itemID = m_pListCtrlInstruments->GetNextItem(itemID, wxLIST_NEXT_ALL,
5360 wxLIST_STATE_SELECTED);
5362 return (
int)m_pListCtrlInstruments->GetItemData(itemID);
5372DashboardWindow::DashboardWindow(wxWindow *pparent, wxWindowID
id,
5375 : wxWindow(pparent, id, wxDefaultPosition, wxDefaultSize, 0) {
5381 m_Container = mycont;
5384 itemBoxSizer =
new wxBoxSizer(orient);
5385 SetSizer(itemBoxSizer);
5386 Connect(wxEVT_SIZE, wxSizeEventHandler(DashboardWindow::OnSize), NULL,
this);
5387 Connect(wxEVT_CONTEXT_MENU,
5388 wxContextMenuEventHandler(DashboardWindow::OnContextMenu), NULL,
5390 Connect(wxEVT_COMMAND_MENU_SELECTED,
5391 wxCommandEventHandler(DashboardWindow::OnContextMenuSelect), NULL,
5395 Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(DashboardWindow::OnMouseEvent));
5396 Connect(wxEVT_LEFT_UP, wxMouseEventHandler(DashboardWindow::OnMouseEvent));
5397 Connect(wxEVT_MOTION, wxMouseEventHandler(DashboardWindow::OnMouseEvent));
5399 GetHandle()->setAttribute(Qt::WA_AcceptTouchEvents);
5400 GetHandle()->grabGesture(Qt::PinchGesture);
5401 GetHandle()->grabGesture(Qt::PanGesture);
5403 Connect(wxEVT_QT_PINCHGESTURE,
5408 wxEVT_QT_PANGESTURE,
5409 (wxObjectEventFunction)(wxEventFunction)&DashboardWindow::OnEvtPanGesture,
5415 m_binResize =
false;
5419DashboardWindow::~DashboardWindow() {
5420 for (
size_t i = 0; i < m_ArrayOfInstrument.GetCount(); i++) {
5427void DashboardWindow::OnEvtPinchGesture(wxQT_PinchGestureEvent &event) {
5428 float zoom_gain = 0.3;
5430 float total_zoom_val;
5432 if (event.GetScaleFactor() > 1)
5433 zoom_val = ((
event.GetScaleFactor() - 1.0) * zoom_gain) + 1.0;
5435 zoom_val = 1.0 - ((1.0 -
event.GetScaleFactor()) * zoom_gain);
5437 if (event.GetTotalScaleFactor() > 1)
5438 total_zoom_val = ((event.GetTotalScaleFactor() - 1.0) * zoom_gain) + 1.0;
5440 total_zoom_val = 1.0 - ((1.0 -
event.GetTotalScaleFactor()) * zoom_gain);
5442 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5444 wxSize currentSize = wxSize(pane.floating_size.x, pane.floating_size.y);
5445 double aRatio = (double)currentSize.y / (
double)currentSize.x;
5448 wxPoint par_pos = wxPoint(pane.floating_pos.x, pane.floating_pos.y);
5450 switch (event.GetState()) {
5451 case GestureStarted:
5455 case GestureUpdated:
5456 currentSize.y *= zoom_val;
5457 currentSize.x *= zoom_val;
5459 if ((par_pos.y + currentSize.y) > par_size.y)
5460 currentSize.y = par_size.y - par_pos.y;
5462 if ((par_pos.x + currentSize.x) > par_size.x)
5463 currentSize.x = par_size.x - par_pos.x;
5466 currentSize.x = currentSize.y / aRatio;
5468 currentSize.x = wxMax(currentSize.x, 150);
5469 currentSize.y = wxMax(currentSize.y, 150);
5471 pane.FloatingSize(currentSize);
5472 m_pauimgr->Update();
5476 case GestureFinished: {
5477 if (itemBoxSizer->GetOrientation() == wxVERTICAL) {
5478 currentSize.y *= total_zoom_val;
5479 currentSize.x = currentSize.y / aRatio;
5481 currentSize.x *= total_zoom_val;
5482 currentSize.y = currentSize.x * aRatio;
5486 if ((par_pos.y + currentSize.y) > par_size.y)
5487 currentSize.y = par_size.y - par_pos.y;
5489 if ((par_pos.x + currentSize.x) > par_size.x)
5490 currentSize.x = par_size.x - par_pos.x;
5493 currentSize.x = wxMax(currentSize.x, 150);
5494 currentSize.y = wxMax(currentSize.y, 150);
5499 if (itemBoxSizer->GetOrientation() == wxVERTICAL) {
5501 for (
unsigned int i = 0; i < m_ArrayOfInstrument.size(); i++) {
5503 m_ArrayOfInstrument.Item(i)->m_pInstrument;
5505 inst->GetSize(itemBoxSizer->GetOrientation(), currentSize);
5509 currentSize.y = total_y;
5512 pane.FloatingSize(currentSize);
5515 for (
unsigned int i = 0; i < m_ArrayOfInstrument.size(); i++) {
5520 m_pauimgr->Update();
5523 m_binResize =
false;
5528 case GestureCanceled:
5530 m_binResize =
false;
5538void DashboardWindow::OnEvtPanGesture(wxQT_PanGestureEvent &event) {
5539 if (m_binPinch)
return;
5541 if (m_binResize)
return;
5543 int x =
event.GetOffset().x;
5544 int y =
event.GetOffset().y;
5546 int lx =
event.GetLastOffset().x;
5547 int ly =
event.GetLastOffset().y;
5552 switch (event.GetState()) {
5553 case GestureStarted:
5554 if (m_binPan)
break;
5559 case GestureUpdated:
5562 wxPoint par_pos_old = ClientToScreen(wxPoint(0, 0));
5564 wxPoint par_pos = par_pos_old;
5568 par_pos.x = wxMax(par_pos.x, 0);
5569 par_pos.y = wxMax(par_pos.y, 0);
5571 wxSize mySize = GetSize();
5573 if ((par_pos.y + mySize.y) > par_size.y)
5574 par_pos.y = par_size.y - mySize.y;
5576 if ((par_pos.x + mySize.x) > par_size.x)
5577 par_pos.x = par_size.x - mySize.x;
5579 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5580 pane.FloatingPosition(par_pos).Float();
5581 m_pauimgr->Update();
5585 case GestureFinished:
5592 case GestureCanceled:
5601void DashboardWindow::OnMouseEvent(wxMouseEvent &event) {
5602 if (m_binPinch)
return;
5605 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5606 wxSize currentSize = wxSize(pane.floating_size.x, pane.floating_size.y);
5607 double aRatio = (double)currentSize.y / (
double)currentSize.x;
5610 wxPoint par_pos = wxPoint(pane.floating_pos.x, pane.floating_pos.y);
5612 if (event.LeftDown()) {
5613 m_resizeStartPoint =
event.GetPosition();
5614 m_resizeStartSize = currentSize;
5615 m_binResize2 =
true;
5619 if (event.Dragging()) {
5620 wxPoint p =
event.GetPosition();
5622 wxSize dragSize = m_resizeStartSize;
5624 dragSize.y += p.y - m_resizeStartPoint.y;
5625 dragSize.x += p.x - m_resizeStartPoint.x;
5628 if ((par_pos.y + dragSize.y) > par_size.y)
5629 dragSize.y = par_size.y - par_pos.y;
5631 if ((par_pos.x + dragSize.x) > par_size.x)
5632 dragSize.x = par_size.x - par_pos.x;
5638 dragSize.x = wxMax(dragSize.x, 150);
5639 dragSize.y = wxMax(dragSize.y, 150);
5641 pane.FloatingSize(dragSize);
5642 m_pauimgr->Update();
5645 if (event.LeftUp()) {
5646 wxPoint p =
event.GetPosition();
5648 wxSize dragSize = m_resizeStartSize;
5650 dragSize.y += p.y - m_resizeStartPoint.y;
5651 dragSize.x += p.x - m_resizeStartPoint.x;
5654 if ((par_pos.y + dragSize.y) > par_size.y)
5655 dragSize.y = par_size.y - par_pos.y;
5657 if ((par_pos.x + dragSize.x) > par_size.x)
5658 dragSize.x = par_size.x - par_pos.x;
5661 dragSize.x = wxMax(dragSize.x, 150);
5662 dragSize.y = wxMax(dragSize.y, 150);
5669 pane.FloatingSize(dragSize);
5670 m_pauimgr->Update();
5672 m_binResize =
false;
5673 m_binResize2 =
false;
5680void DashboardWindow::OnSize(wxSizeEvent &event) {
5682 for (
unsigned int i = 0; i < m_ArrayOfInstrument.size(); i++) {
5685 inst->GetSize(itemBoxSizer->GetOrientation(), GetClientSize()));
5690 this->m_Container->m_best_size =
event.GetSize();
5693void DashboardWindow::OnContextMenu(wxContextMenuEvent &event) {
5694 wxMenu *contextMenu =
new wxMenu();
5701 new wxMenuItem(contextMenu, ID_DASH_PREFS, _(
"Preferences..."));
5702 item1->SetFont(*pf);
5703 contextMenu->Append(item1);
5706 new wxMenuItem(contextMenu, ID_DASH_RESIZE, _(
"Resize..."));
5707 item2->SetFont(*pf);
5708 contextMenu->Append(item2);
5712 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5713 if (pane.IsOk() && pane.IsDocked()) {
5714 contextMenu->Append(ID_DASH_UNDOCK, _(
"Undock"));
5716 wxMenuItem *btnVertical =
5717 contextMenu->AppendRadioItem(ID_DASH_VERTICAL, _(
"Vertical"));
5718 btnVertical->Check(itemBoxSizer->GetOrientation() == wxVERTICAL);
5719 wxMenuItem *btnHorizontal =
5720 contextMenu->AppendRadioItem(ID_DASH_HORIZONTAL, _(
"Horizontal"));
5721 btnHorizontal->Check(itemBoxSizer->GetOrientation() == wxHORIZONTAL);
5722 contextMenu->AppendSeparator();
5724 m_plugin->PopulateContextMenu(contextMenu);
5726 contextMenu->AppendSeparator();
5727 contextMenu->Append(ID_DASH_PREFS, _(
"Preferences..."));
5731 PopupMenu(contextMenu);
5735void DashboardWindow::OnContextMenuSelect(wxCommandEvent &event) {
5736 if (event.GetId() < ID_DASH_PREFS) {
5737 if (m_plugin->GetDashboardWindowShownCount() > 1 || event.IsChecked())
5738 m_plugin->ShowDashboard(event.GetId() - 1, event.IsChecked());
5740 m_plugin->ShowDashboard(event.GetId() - 1,
true);
5743 m_plugin->GetDashboardWindowShownCount() != 0);
5746 switch (event.GetId()) {
5747 case ID_DASH_PREFS: {
5748 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5750 wxPoint fp = pane.floating_pos;
5758 if (!pane.IsDocked())
5759 ChangePaneOrientation(GetSizerOrientation(),
true, fp.x, fp.y);
5761 if (g_bUseInternSumLog) m_plugin->UpdateSumLog(
false);
5764 case ID_DASH_RESIZE: {
5775 case ID_DASH_VERTICAL: {
5776 ChangePaneOrientation(wxVERTICAL,
true);
5777 m_Container->m_sOrientation =
"V";
5780 case ID_DASH_HORIZONTAL: {
5781 ChangePaneOrientation(wxHORIZONTAL,
true);
5782 m_Container->m_sOrientation =
"H";
5785 case ID_DASH_UNDOCK: {
5786 ChangePaneOrientation(GetSizerOrientation(),
true);
5790 m_plugin->SaveConfig();
5797 wxColour col = g_BackgroundColor;
5799 if (!g_ForceBackgroundColor) GetGlobalColor(
"DASHL", &col);
5800 SetBackgroundColour(col);
5805void DashboardWindow::ChangePaneOrientation(
int orient,
bool updateAUImgr,
5807 m_pauimgr->DetachPane(
this);
5808 SetSizerOrientation(orient);
5809 bool vertical = orient == wxVERTICAL;
5811 wxSize sz = GetMinSize();
5813 m_Container->m_sName = MakeName();
5814 m_pauimgr->AddPane(
this, wxAuiPaneInfo()
5815 .Name(m_Container->m_sName)
5816 .Caption(m_Container->m_sCaption)
5817 .CaptionVisible(
true)
5818 .TopDockable(!vertical)
5819 .BottomDockable(!vertical)
5820 .LeftDockable(vertical)
5821 .RightDockable(vertical)
5825 .FloatingPosition(fpx, fpy)
5827 .Show(m_Container->m_bIsVisible));
5830 wxAuiPaneInfo &pane = m_pauimgr->GetPane(
this);
5831 pane.Dockable(
false);
5834 if (updateAUImgr) m_pauimgr->Update();
5837void DashboardWindow::SetSizerOrientation(
int orient) {
5838 itemBoxSizer->SetOrientation(orient);
5840 wxWindowListNode *node = GetChildren().GetFirst();
5842 node->GetData()->SetMinSize(wxDefaultSize);
5843 node = node->GetNext();
5845 SetMinSize(wxDefaultSize);
5847 SetMinSize(itemBoxSizer->GetMinSize());
5850int DashboardWindow::GetSizerOrientation() {
5851 return itemBoxSizer->GetOrientation();
5854bool isArrayIntEqual(
const wxArrayInt &l1,
const wxArrayOfInstrument &l2) {
5855 if (l1.GetCount() != l2.GetCount())
return false;
5857 for (
size_t i = 0; i < l1.GetCount(); i++)
5858 if (l1.Item(i) != l2.Item(i)->m_ID)
return false;
5863bool DashboardWindow::isInstrumentListEqual(
const wxArrayInt &list) {
5864 return isArrayIntEqual(list, m_ArrayOfInstrument);
5867void DashboardWindow::SetInstrumentList(
5868 wxArrayInt list, wxArrayOfInstrumentProperties *InstrumentPropertyList) {
5882 m_ArrayOfInstrument.Clear();
5883 itemBoxSizer->Clear(
true);
5884 for (
size_t i = 0; i < list.GetCount(); i++) {
5885 int id = list.Item(i);
5887 for (
size_t j = 0; j < InstrumentPropertyList->GetCount(); j++) {
5888 if (InstrumentPropertyList->Item(j)->m_aInstrument ==
id &&
5889 InstrumentPropertyList->Item(j)->m_Listplace == (
int)i) {
5890 Properties = InstrumentPropertyList->Item(j);
5898 this, wxID_ANY, getInstrumentCaption(
id), Properties);
5902 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5907 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5910 ->SetOptionLabel(g_iDashSpeedMax / 20 + 1, DIAL_LABEL_HORIZONTAL);
5914 ->SetOptionMarker(0.5, DIAL_MARKER_SIMPLE, 2);
5917 DIAL_POSITION_BOTTOMMIDDLE);
5921 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5924 ->SetOptionLabel(g_iDashSpeedMax / 20 + 1, DIAL_LABEL_HORIZONTAL);
5928 ->SetOptionMarker(0.5, DIAL_MARKER_SIMPLE, 2);
5931 DIAL_POSITION_BOTTOMMIDDLE);
5935 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5940 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5945 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5948 ->SetOptionMarker(5, DIAL_MARKER_SIMPLE, 2);
5950 ->SetOptionLabel(30, DIAL_LABEL_ROTATED);
5953 DIAL_POSITION_BOTTOMLEFT);
5957 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5960 ->SetOptionMarker(5, DIAL_MARKER_SIMPLE, 2);
5962 ->SetOptionLabel(30, DIAL_LABEL_ROTATED);
5965 DIAL_POSITION_BOTTOMLEFT);
5969 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5975 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5980 this, wxID_ANY, getInstrumentCaption(
id), Properties,
5986 getInstrumentCaption(
id),
5989 ->SetOptionMainValue(
"%.0f", DIAL_POSITION_BOTTOMLEFT);
5992 DIAL_POSITION_INSIDE);
5996 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6001 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6004 ->SetOptionLabel(5, DIAL_LABEL_HORIZONTAL);
6006 ->SetOptionMarker(1, DIAL_MARKER_SIMPLE, 5);
6008 ->SetOptionMainValue(
"A %.1f", DIAL_POSITION_BOTTOMLEFT);
6011 DIAL_POSITION_BOTTOMRIGHT);
6015 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6018 ->SetOptionMainValue(
"%.0f", DIAL_POSITION_BOTTOMLEFT);
6021 DIAL_POSITION_INSIDE);
6023 case ID_DBP_D_AWA_TWA:
6025 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6029 ->SetOptionMainValue(
"%.0f", DIAL_POSITION_NONE);
6037 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6040 ->SetOptionMainValue(
"%.0f", DIAL_POSITION_BOTTOMLEFT);
6043 DIAL_POSITION_INSIDE);
6047 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6052 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6056 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6061 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6065 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6070 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6075 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6078 ->SetOptionLabel(15, DIAL_LABEL_HORIZONTAL);
6080 ->SetOptionMarker(7.5, DIAL_MARKER_SIMPLE, 1);
6082 ->SetOptionMainValue(
"%5.1f", DIAL_POSITION_INSIDE);
6086 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6091 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6097 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6103 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6108 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6113 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6118 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6123 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6128 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6133 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6136 ->SetOptionLabel(1, DIAL_LABEL_HORIZONTAL);
6138 ->SetOptionMarker(0.5, DIAL_MARKER_SIMPLE, 2);
6141 DIAL_POSITION_BOTTOMLEFT);
6145 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6150 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6154 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6159 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6163 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6166 case ID_DBP_I_GPSUTC:
6168 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6172 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6176 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6180 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6184 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6188 this, wxID_ANY, getInstrumentCaption(
id), Properties);
6190 case ID_DBP_I_PITCH:
6192 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6197 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6204 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6205 "%02i:%02i:%02i LCL");
6209 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6214 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6215 "%02i:%02i:%02i LCL");
6219 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6224 this, wxID_ANY, getInstrumentCaption(
id), Properties,
6229 instrument->instrumentTypeId = id;
6231 id, instrument, instrument->GetCapacity()));
6232 itemBoxSizer->Add(instrument, 0, wxEXPAND, 0);
6233 if (itemBoxSizer->GetOrientation() == wxHORIZONTAL) {
6234 itemBoxSizer->AddSpacer(5);
6245 wxSize Hint = wxSize(DefaultWidth, DefaultWidth);
6247 for (
unsigned int i = 0; i < m_ArrayOfInstrument.size(); i++) {
6249 inst->SetMinSize(inst->GetSize(itemBoxSizer->GetOrientation(), Hint));
6250 Hint = inst->GetMinSize();
6255 SetMinSize(itemBoxSizer->GetMinSize());
6258void DashboardWindow::SendSentenceToAllInstruments(
DASH_CAP st,
double value,
6260 for (
size_t i = 0; i < m_ArrayOfInstrument.GetCount(); i++) {
6261 if (m_ArrayOfInstrument.Item(i)->m_cap_flag.test(st))
6262 m_ArrayOfInstrument.Item(i)->m_pInstrument->SetData(st, value,
unit);
6266void DashboardWindow::SendSatInfoToAllInstruments(
int cnt,
int seq,
6269 for (
size_t i = 0; i < m_ArrayOfInstrument.GetCount(); i++) {
6272 m_ArrayOfInstrument.Item(i)->m_pInstrument))
6274 ->SetSatInfo(cnt, seq, talk, sats);
6278void DashboardWindow::SendUtcTimeToAllInstruments(wxDateTime value) {
6279 for (
size_t i = 0; i < m_ArrayOfInstrument.GetCount(); i++) {
6282 m_ArrayOfInstrument.Item(i)->m_pInstrument))
6290 ->SetUtcTime(value);
6306bool OCPNFontButton::Create(wxWindow *parent, wxWindowID
id,
6307 const wxFontData &initial,
const wxPoint &pos,
6308 const wxSize &size,
long style,
6309 const wxValidator &validator,
6310 const wxString &name) {
6311 wxString label = (style & wxFNTP_FONTDESC_AS_LABEL)
6317 if (!wxButton::Create(parent,
id, label, pos, size, style, validator, name)) {
6318 wxFAIL_MSG(
"OCPNFontButton creation failed");
6323 Connect(GetId(), wxEVT_BUTTON,
6324 wxCommandEventHandler(OCPNFontButton::OnButtonClick), NULL,
this);
6328 initial.GetChosenFont().IsOk() ? initial.GetChosenFont() : *wxNORMAL_FONT;
6334void OCPNFontButton::OnButtonClick(wxCommandEvent &WXUNUSED(ev)) {
6336 m_data.SetInitialFont(m_selectedFont);
6341 int display_height = wxGetDisplaySize().y;
6342 if (display_height < 800) {
6346 if (dlg.ShowModal() == wxID_OK) {
6347 m_data = dlg.GetFontData();
6348 m_selectedFont = m_data.GetChosenFont();
6350 wxFontPickerEvent event(
this, GetId(), m_selectedFont);
6351 GetEventHandler()->ProcessEvent(event);
6356 wxFontDialog dlg(
this, m_data);
6358 if (dlg.ShowModal() == wxID_OK) {
6359 m_data = dlg.GetFontData();
6360 m_selectedFont = m_data.GetChosenFont();
6362 wxFontPickerEvent event(
this, GetId(), m_selectedFont);
6363 GetEventHandler()->ProcessEvent(event);
6370 wxFontDialog dlg(
this, m_data);
6376 wxSize proposed_size = GetParent()->GetSize();
6378 float font_size = pF->GetPointSize();
6380 if ((proposed_size.y / font_size) < n_lines) {
6381 float new_font_size = proposed_size.y / n_lines;
6382 wxFont *smallFont =
new wxFont(*pF);
6383 smallFont->SetPointSize(new_font_size);
6384 dlg.SetFont(*smallFont);
6387 dlg.SetSize(GetParent()->GetSize());
6391 if (dlg.ShowModal() == wxID_OK) {
6392 m_data = dlg.GetFontData();
6393 m_selectedFont = m_data.GetChosenFont();
6396 wxFontPickerEvent event(
this, GetId(), m_selectedFont);
6397 GetEventHandler()->ProcessEvent(event);
6404void OCPNFontButton::UpdateFont() {
6405 if (!m_selectedFont.IsOk())
return;
6410 if (HasFlag(wxFNTP_USEFONT_FOR_LABEL)) {
6412 wxButton::SetFont(m_selectedFont);
6413 wxButton::SetForegroundColour(GetSelectedColour());
6417 wxString::Format(
"%s, %d", m_selectedFont.GetFaceName().c_str(),
6418 m_selectedFont.GetPointSize());
6420 if (HasFlag(wxFNTP_FONTDESC_AS_LABEL)) {
6424 auto minsize = GetTextExtent(label);
6427 GetParent()->Layout();
6434 wxWindowID
id,
const wxString &title,
const wxPoint &pos,
6435 const wxSize &size,
long style)
6436 : wxDialog(parent, id, title, pos, size, style) {
6437 this->SetSizeHints(wxDefaultSize, wxDefaultSize);
6439 wxBoxSizer *bSizer5;
6440 bSizer5 =
new wxBoxSizer(wxVERTICAL);
6442 wxFlexGridSizer *fgSizer2;
6443 fgSizer2 =
new wxFlexGridSizer(0, 2, 0, 0);
6444 fgSizer2->SetFlexibleDirection(wxBOTH);
6445 fgSizer2->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
6447 m_staticText1 =
new wxStaticText(
this, wxID_ANY, _(
"Title:"),
6448 wxDefaultPosition, wxDefaultSize, 0);
6449 m_staticText1->Wrap(-1);
6450 fgSizer2->Add(m_staticText1, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6452 m_fontPicker2 =
new wxFontPickerCtrl(
this, wxID_ANY, Properties.m_USTitleFont,
6453 wxDefaultPosition, wxDefaultSize);
6454 fgSizer2->Add(m_fontPicker2, 0, wxALL, 5);
6456 m_staticText5 =
new wxStaticText(
this, wxID_ANY, _(
"Title background color:"),
6457 wxDefaultPosition, wxDefaultSize, 0);
6458 m_staticText5->Wrap(-1);
6459 fgSizer2->Add(m_staticText5, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6461 m_colourPicker1 =
new wxColourPickerCtrl(
6462 this, wxID_ANY, Properties.m_TitleBackgroundColour, wxDefaultPosition,
6463 wxDefaultSize, wxCLRP_DEFAULT_STYLE);
6464 fgSizer2->Add(m_colourPicker1, 0, wxALL, 5);
6466 m_staticText2 =
new wxStaticText(
this, wxID_ANY, _(
"Data:"),
6467 wxDefaultPosition, wxDefaultSize, 0);
6468 m_staticText2->Wrap(-1);
6469 fgSizer2->Add(m_staticText2, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6471 m_fontPicker4 =
new wxFontPickerCtrl(
this, wxID_ANY, Properties.m_USDataFont,
6472 wxDefaultPosition, wxDefaultSize);
6473 fgSizer2->Add(m_fontPicker4, 0, wxALL, 5);
6475 m_staticText6 =
new wxStaticText(
this, wxID_ANY, _(
"Data background color:"),
6476 wxDefaultPosition, wxDefaultSize, 0);
6477 m_staticText6->Wrap(-1);
6478 fgSizer2->Add(m_staticText6, 0, wxALL, 5);
6480 m_colourPicker2 =
new wxColourPickerCtrl(
6481 this, wxID_ANY, Properties.m_DataBackgroundColour, wxDefaultPosition,
6482 wxDefaultSize, wxCLRP_DEFAULT_STYLE);
6483 fgSizer2->Add(m_colourPicker2, 0, wxALL, 5);
6485 m_staticText3 =
new wxStaticText(
this, wxID_ANY, _(
"Label:"),
6486 wxDefaultPosition, wxDefaultSize, 0);
6487 m_staticText3->Wrap(-1);
6488 fgSizer2->Add(m_staticText3, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6490 m_fontPicker5 =
new wxFontPickerCtrl(
this, wxID_ANY, Properties.m_USLabelFont,
6491 wxDefaultPosition, wxDefaultSize);
6492 fgSizer2->Add(m_fontPicker5, 0, wxALL, 5);
6494 m_staticText4 =
new wxStaticText(
this, wxID_ANY, _(
"Small:"),
6495 wxDefaultPosition, wxDefaultSize, 0);
6496 m_staticText4->Wrap(-1);
6497 fgSizer2->Add(m_staticText4, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6499 m_fontPicker6 =
new wxFontPickerCtrl(
this, wxID_ANY, Properties.m_USSmallFont,
6500 wxDefaultPosition, wxDefaultSize);
6501 fgSizer2->Add(m_fontPicker6, 0, wxALL, 5);
6503 m_staticText9 =
new wxStaticText(
this, wxID_ANY, _(
"Arrow 1 Color :"),
6504 wxDefaultPosition, wxDefaultSize, 0);
6505 m_staticText9->Wrap(-1);
6506 fgSizer2->Add(m_staticText9, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6508 m_colourPicker3 =
new wxColourPickerCtrl(
6509 this, wxID_ANY, Properties.m_Arrow_First_Colour, wxDefaultPosition,
6510 wxDefaultSize, wxCLRP_DEFAULT_STYLE);
6511 fgSizer2->Add(m_colourPicker3, 0, wxALL, 5);
6513 m_staticText10 =
new wxStaticText(
this, wxID_ANY, _(
"Arrow 2 Color :"),
6514 wxDefaultPosition, wxDefaultSize, 0);
6515 m_staticText10->Wrap(-1);
6516 fgSizer2->Add(m_staticText10, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
6518 m_colourPicker4 =
new wxColourPickerCtrl(
6519 this, wxID_ANY, Properties.m_Arrow_Second_Colour, wxDefaultPosition,
6520 wxDefaultSize, wxCLRP_DEFAULT_STYLE);
6521 fgSizer2->Add(m_colourPicker4, 0, wxALL, 5);
6523 m_staticline1 =
new wxStaticLine(
this, wxID_ANY, wxDefaultPosition,
6524 wxDefaultSize, wxLI_HORIZONTAL);
6525 fgSizer2->Add(m_staticline1, 0, wxEXPAND | wxALL, 5);
6527 m_staticline2 =
new wxStaticLine(
this, wxID_ANY, wxDefaultPosition,
6528 wxDefaultSize, wxLI_HORIZONTAL);
6529 fgSizer2->Add(m_staticline2, 0, wxEXPAND | wxALL, 5);
6531 fgSizer2->Add(0, 5, 1, wxEXPAND, 5);
6533 fgSizer2->Add(0, 0, 1, wxEXPAND, 5);
6535 m_staticText7 =
new wxStaticText(
this, wxID_ANY, wxEmptyString,
6536 wxDefaultPosition, wxDefaultSize, 0);
6537 m_staticText7->Wrap(-1);
6538 fgSizer2->Add(m_staticText7, 0, wxALL, 5);
6540 m_button1 =
new wxButton(
this, wxID_ANY, _(
"Set default"), wxDefaultPosition,
6542 fgSizer2->Add(m_button1, 0, wxALL, 5);
6544 fgSizer2->Add(0, 5, 1, wxEXPAND, 5);
6546 fgSizer2->Add(5, 0, 1, wxEXPAND, 5);
6548 bSizer5->Add(fgSizer2, 1, wxALL | wxEXPAND, 5);
6550 m_sdbSizer3 =
new wxStdDialogButtonSizer();
6551 m_sdbSizer3OK =
new wxButton(
this, wxID_OK);
6552 m_sdbSizer3->AddButton(m_sdbSizer3OK);
6553 m_sdbSizer3Cancel =
new wxButton(
this, wxID_CANCEL);
6554 m_sdbSizer3->AddButton(m_sdbSizer3Cancel);
6555 m_sdbSizer3->Realize();
6557 bSizer5->Add(m_sdbSizer3, 0, 0, 1);
6559 bSizer5->Add(0, 10, 0, wxEXPAND, 5);
6561 this->SetSizer(bSizer5);
6565 this->Centre(wxBOTH);
6568 m_button1->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
6569 wxCommandEventHandler(EditDialog::OnSetdefault), NULL,
6573EditDialog::~EditDialog() {
6575 m_button1->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED,
6576 wxCommandEventHandler(EditDialog::OnSetdefault), NULL,
6580void EditDialog::OnSetdefault(wxCommandEvent &event) {
6581 m_fontPicker2->SetSelectedFont(g_USFontTitle.GetChosenFont());
6582 m_fontPicker2->SetSelectedColour(g_USFontTitle.GetColour());
6583 m_fontPicker4->SetSelectedFont(g_USFontData.GetChosenFont());
6584 m_fontPicker4->SetSelectedColour(g_USFontData.GetColour());
6585 m_fontPicker5->SetSelectedFont(g_USFontLabel.GetChosenFont());
6586 m_fontPicker5->SetSelectedColour(g_USFontLabel.GetColour());
6587 m_fontPicker6->SetSelectedFont(g_USFontSmall.GetChosenFont());
6588 m_fontPicker6->SetSelectedColour(g_USFontSmall.GetColour());
6590 GetGlobalColor(
"DASHL", &dummy);
6591 m_colourPicker1->SetColour(dummy);
6592 GetGlobalColor(
"DASHB", &dummy);
6593 m_colourPicker2->SetColour(dummy);
6594 GetGlobalColor(
"DASHN", &dummy);
6595 m_colourPicker3->SetColour(dummy);
6596 GetGlobalColor(
"BLUE3", &dummy);
6597 m_colourPicker4->SetColour(dummy);
6603void dashboard_pi::UpdateSumLog(
bool write) {
6605 g_dSumLogNM += d_tripNM;
6608 if (++confprint > 10) {
6609 wxFileConfig *logConf = (wxFileConfig *)m_pconfig;
6611 logConf->SetPath(
"/PlugIns/Dashboard");
6612 logConf->Write(
"SumLogNM", g_dSumLogNM);
6618 if (g_bUseInternSumLog) {
6619 SendSentenceToAllInstruments(
6623 m_log_watchdog = 70;
6628 SendSentenceToAllInstruments(
6632 m_log_watchdog = no_nav_watchdog_timeout_ticks;
Dashboard altitude instrument.
Dashboard barometer history instrument.
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 speedometer style control.
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).
int GetAPIVersionMajor() override
Returns the major version number of the plugin API that this plugin supports.
void SetNMEASentence(wxString &sentence) override
Receive all NMEA 0183 sentences from OpenCPN.
void SetPositionFixEx(PlugIn_Position_Fix_Ex &pfix) override
Updates plugin with extended position fix data at regular intervals.
void UpdateAuiStatus() override
Updates AUI manager status.
int GetPlugInVersionMajor() override
Returns the major version number of the plugin itself.
bool DeInit() override
Clean up plugin resources.
void OnToolbarToolCallback(int id) override
Handles toolbar tool clicks.
wxString GetLongDescription() override
Get detailed plugin information.
void ShowPreferencesDialog(wxWindow *parent) override
Shows the plugin preferences dialog.
wxString GetCommonName() override
Get the plugin's common (short) name.
wxString GetShortDescription() override
Get a brief description of the plugin.
int Init() override
Initialize the plugin and declare its capabilities.
int GetPlugInVersionMinor() override
Returns the minor version number of the plugin itself.
int GetToolbarToolCount() override
Returns the number of toolbar tools this plugin provides.
int GetAPIVersionMinor() override
Returns the minor version number of the plugin API that this plugin supports.
void SetCursorLatLon(double lat, double lon) override
Receives cursor lat/lon position updates.
void SetColorScheme(PI_ColorScheme cs) override
Updates plugin color scheme.
wxBitmap * GetPlugInBitmap() override
Get the plugin's icon bitmap.
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.
Dashboard clock instrument.
@ ID_DBP_I_GPSLCL
GNSS Clock formatted in local time.
@ ID_DBP_I_CPULCL
Computer Clock formatted in local time.
@ ID_DBP_I_SUNLCL
Sunrise/Sunset time formatted in local time.
Dashboard depth instrument.
Dashboard own ship data instrument.
Dashboard GPS instrument.
@ OCPN_DBP_STC_VLW1
Trip Log.
@ OCPN_DBP_STC_AWA
Apparent wind angle.
@ OCPN_DBP_STC_PITCH
Pitch.
@ OCPN_DBP_STC_RSA
Rudder angle.
@ OCPN_DBP_STC_AWS
Apparent wind speed.
@ OCPN_DBP_STC_STW
Speed through water.
@ OCPN_DBP_STC_VMGW
Velocity made good to windward.
@ OCPN_DBP_STC_PLA
Cursor latitude.
@ OCPN_DBP_STC_SAT
Satellite count in use.
@ OCPN_DBP_STC_HDT
Heading true North.
@ OCPN_DBP_STC_VMG
Velocity made good.
@ OCPN_DBP_STC_TWS2
True Wind Speed, same calculation as TWS.
@ OCPN_DBP_STC_ALTI
Altitude.
@ OCPN_DBP_STC_GPS
GPS status.
@ OCPN_DBP_STC_HDM
Heading magnetic North.
@ OCPN_DBP_STC_TWA
True wind angle.
@ OCPN_DBP_STC_SOG
Speed over ground.
@ OCPN_DBP_STC_VLW2
Sum Log.
@ OCPN_DBP_STC_LON
Longitude.
@ OCPN_DBP_STC_MCOG
Magnetic Course over Ground.
@ OCPN_DBP_STC_PLO
Cursor longitude.
@ OCPN_DBP_STC_HMV
Magnetic variation from NMEA device if available (not from WMM)
@ OCPN_DBP_STC_ATMP
Air Temperature.
@ OCPN_DBP_STC_MDA
Barometic pressure.
@ OCPN_DBP_STC_COG
Course over ground.
@ OCPN_DBP_STC_TWD
True Wind Direction (from NMEA device if available, otherwise TWA + magnetic variation)
@ OCPN_DBP_STC_TWS
True wind speed.
@ OCPN_DBP_STC_TMP
Water temperature.
@ OCPN_DBP_STC_HUM
Humidity.
@ OCPN_DBP_STC_WCC
Windlass.
@ OCPN_DBP_STC_LAT
Latitude.
Generic font dialog for OpenCPN.
#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.
Dashboard compass instrument.
Identifier for NMEA 2000 message types.