36#include "wx/tokenzr.h"
42double rad2deg(
double angle) {
return angle * 180.0 / M_PI; }
43double deg2rad(
double angle) {
return angle / 180.0 * M_PI; }
45DashboardInstrument_Dial::DashboardInstrument_Dial(
46 wxWindow* parent, wxWindowID
id, wxString title,
48 int r_angle,
int s_value,
int e_value)
50 m_angle_start = s_angle;
51 m_angle_range = r_angle;
52 m_main_value_min = s_value;
53 m_main_value_max = e_value;
54 m_main_value_cap = cap_flag;
56 m_main_value = s_value;
58 m_main_value_format =
"%d";
59 m_main_value_unit =
"";
60 m_main_value_option = DIAL_POSITION_NONE;
61 m_extra_value_format =
"%d";
62 m_extra_value_unit =
"";
63 m_extra_value_option = DIAL_POSITION_NONE;
64 m_marker_option = DIAL_MARKER_SIMPLE;
68 m_label_option = DIAL_LABEL_HORIZONTAL;
71wxSize DashboardInstrument_Dial::GetSize(
int orient, wxSize hint) {
73 InitTitleAndDataPosition(DefaultWidth);
75 if (orient == wxHORIZONTAL) {
76 w = wxMax(hint.y, GetFullHeight(DefaultWidth));
77 return wxSize(w - m_TitleHeight, w);
79 w = wxMax(hint.x, DefaultWidth);
80 return wxSize(w, GetFullHeight(w));
84void DashboardInstrument_Dial::SetData(
DASH_CAP st,
double data,
86 if (st == m_main_value_cap) {
88 m_main_value_unit =
unit;
89 }
else if (st == m_extra_value_cap) {
91 m_extra_value_unit =
unit;
96void DashboardInstrument_Dial::Draw(wxGCDC* bdc) {
99 GetColourSchemeBackgroundColour(m_Properties->m_DataBackgroundColour));
100 bdc->SetBackground(b1);
103 GetGlobalColor(
"DASHB", &c1);
105 bdc->SetBackground(b1);
109 wxSize size = GetClientSize();
111 int availableHeight = GetDataBottom(size.y) - m_DataTop;
112 InitTitleAndDataPosition(availableHeight);
113 availableHeight -= 6;
117 f = m_Properties->m_LabelFont.GetChosenFont();
119 f = g_pFontLabel->GetChosenFont();
120 bdc->GetTextExtent(
"000", &width, &height,
nullptr,
nullptr, &f);
121 m_cy = m_DataTop + 2;
122 m_cy += availableHeight / 2;
123 m_radius = availableHeight / 2;
129 DrawData(bdc, m_main_value, m_main_value_unit, m_main_value_format,
130 m_main_value_option);
131 DrawData(bdc, m_extra_value, m_extra_value_unit, m_extra_value_format,
132 m_extra_value_option);
136void DashboardInstrument_Dial::DrawFrame(wxGCDC* dc) {
137 wxSize size = GetClientSize();
140 cl = GetColourSchemeBackgroundColour(m_Properties->m_TitleBackgroundColour);
142 GetGlobalColor(
"DASHL", &cl);
144 dc->SetTextForeground(cl);
145 dc->SetBrush(*wxTRANSPARENT_BRUSH);
147 int penwidth = 1 + size.x / 100;
148 wxPen pen(cl, penwidth, wxPENSTYLE_SOLID);
150 if (m_marker_option == DIAL_MARKER_REDGREENBAR) {
151 pen.SetWidth(penwidth * 2);
152 GetGlobalColor(
"DASHR", &cl);
155 double angle1 = deg2rad(270);
156 double angle2 = deg2rad(90);
157 int radi = m_radius - 1 - penwidth;
158 wxCoord x1 = m_cx + ((radi)*cos(angle1));
159 wxCoord y1 = m_cy + ((radi)*sin(angle1));
160 wxCoord x2 = m_cx + ((radi)*cos(angle2));
161 wxCoord y2 = m_cy + ((radi)*sin(angle2));
162 dc->DrawArc(x1, y1, x2, y2, m_cx, m_cy);
164 GetGlobalColor(
"DASHG", &cl);
167 angle1 = deg2rad(89);
168 angle2 = deg2rad(271);
169 x1 = m_cx + ((radi)*cos(angle1));
170 y1 = m_cy + ((radi)*sin(angle1));
171 x2 = m_cx + ((radi)*cos(angle2));
172 y2 = m_cy + ((radi)*sin(angle2));
173 dc->DrawArc(x1, y1, x2, y2, m_cx, m_cy);
177 GetGlobalColor(
"DASHF", &cl);
178 pen.SetWidth(penwidth);
182 angle2 = deg2rad(180);
185 x1 = m_cx + ((radi)*cos(angle1));
186 y1 = m_cy + ((radi)*sin(angle1));
187 x2 = m_cx + ((radi)*cos(angle2));
188 y2 = m_cy + ((radi)*sin(angle2));
189 dc->DrawArc(x1, y1, x2, y2, m_cx, m_cy);
190 dc->DrawArc(x2, y2, x1, y1, m_cx, m_cy);
193 GetGlobalColor(
"DASHF", &cl);
196 dc->DrawCircle(m_cx, m_cy, m_radius);
200void DashboardInstrument_Dial::DrawMarkers(wxGCDC* dc) {
201 if (m_marker_option == DIAL_MARKER_NONE)
return;
204 GetGlobalColor(
"DASHF", &cl);
205 int penwidth = GetClientSize().x / 100;
206 wxPen pen(cl, penwidth, wxPENSTYLE_SOLID);
209 int diff_angle = m_angle_start + m_angle_range - ANGLE_OFFSET;
212 m_angle_range * m_marker_step / (m_main_value_max - m_main_value_min);
214 if (m_angle_range == 360) diff_angle -= abm;
217 for (
double angle = m_angle_start - ANGLE_OFFSET; angle <= diff_angle;
219 if (m_marker_option == DIAL_MARKER_REDGREEN) {
220 int a = int(angle + ANGLE_OFFSET) % 360;
222 GetGlobalColor(
"DASHR", &cl);
223 else if ((a > 0) && (a < 180))
224 GetGlobalColor(
"DASHG", &cl);
226 GetGlobalColor(
"DASHF", &cl);
233 if (offset % m_marker_offset) {
238 dc->DrawLine(m_cx + ((m_radius - 1) * size * cos(deg2rad(angle))),
239 m_cy + ((m_radius - 1) * size * sin(deg2rad(angle))),
240 m_cx + ((m_radius - 1) * cos(deg2rad(angle))),
241 m_cy + ((m_radius - 1) * sin(deg2rad(angle))));
244 if (m_marker_option == DIAL_MARKER_REDGREEN) {
245 GetGlobalColor(
"DASHF", &cl);
246 pen.SetStyle(wxPENSTYLE_SOLID);
252void DashboardInstrument_Dial::DrawLabels(wxGCDC* dc) {
253 if (m_label_option == DIAL_LABEL_NONE)
return;
258 GetGlobalColor(
"DASHF", &cl);
261 dc->SetFont(m_Properties->m_SmallFont.GetChosenFont());
262 dc->SetTextForeground(
263 GetColourSchemeFont(m_Properties->m_SmallFont.GetColour()));
265 dc->SetFont(g_pFontSmall->GetChosenFont());
266 dc->SetTextForeground(GetColourSchemeFont(g_pFontSmall->GetColour()));
268 int diff_angle = m_angle_start + m_angle_range - ANGLE_OFFSET;
271 m_angle_range * m_label_step / (m_main_value_max - m_main_value_min);
273 if (m_angle_range == 360) diff_angle -= abm;
276 int value = m_main_value_min;
279 for (
double angle = m_angle_start - ANGLE_OFFSET; angle <= diff_angle;
281 wxString label = (m_label_array.GetCount() ? m_label_array.Item(offset)
282 : wxString::Format(
"%d", value));
284 f = m_Properties->m_SmallFont.GetChosenFont();
286 f = g_pFontSmall->GetChosenFont();
287 dc->GetTextExtent(label, &width, &height,
nullptr,
nullptr, &f);
288 double halfW = width / 2;
289 if (m_label_option == DIAL_LABEL_HORIZONTAL) {
290 double halfH = height / 2;
292 double delta = sqrt(halfW * halfW + halfH * halfH);
294 m_cx + ((m_radius * 0.90) - delta) * cos(deg2rad(angle)) - halfW;
296 m_cy + ((m_radius * 0.90) - delta) * sin(deg2rad(angle)) - halfH;
297 dc->DrawText(label, TextPoint);
299 }
else if (m_label_option == DIAL_LABEL_ROTATED) {
304 long double tmpangle = angle - rad2deg(asin(halfW / (0.90 * m_radius)));
305 TextPoint.x = m_cx + m_radius * 0.90 * cos(deg2rad(tmpangle));
306 TextPoint.y = m_cy + m_radius * 0.90 * sin(deg2rad(tmpangle));
307 dc->DrawRotatedText(label, TextPoint, -90 - angle);
310 value += m_label_step;
314void DashboardInstrument_Dial::DrawBackground(wxGCDC* dc) {
319void DashboardInstrument_Dial::DrawData(wxGCDC* dc,
double value, wxString
unit,
321 DialPositionOption position) {
322 if (position == DIAL_POSITION_NONE)
return;
325 dc->SetFont(m_Properties->m_LabelFont.GetChosenFont());
326 dc->SetTextForeground(
327 GetColourSchemeFont(m_Properties->m_LabelFont.GetColour()));
329 dc->SetFont(g_pFontLabel->GetChosenFont());
330 dc->SetTextForeground(GetColourSchemeFont(g_pFontLabel->GetColour()));
334 wxSize size = GetClientSize();
337 if (!std::isnan(value)) {
338 if (
unit ==
"\u00B0")
339 text = wxString::Format(format, value) + DEGREE_SIGN;
340 else if (
unit ==
"\u00B0L")
342 text = wxString::Format(format, value) + DEGREE_SIGN;
343 else if (
unit ==
"\u00B0R")
344 text = wxString::Format(format, value) + DEGREE_SIGN;
345 else if (
unit ==
"\u00B0T")
346 text = wxString::Format(format, value) + DEGREE_SIGN +
"T";
347 else if (
unit ==
"\u00B0M")
348 text = wxString::Format(format, value) + DEGREE_SIGN +
"M";
349 else if (
unit ==
"N")
350 text = wxString::Format(format, value) +
" Kts";
352 text = wxString::Format(format, value) +
" " +
unit;
359 f = m_Properties->m_LabelFont.GetChosenFont();
361 f = g_pFontLabel->GetChosenFont();
362 dc->GetMultiLineTextExtent(text, &width, &height,
nullptr, &f);
365 TextPoint.width = width;
366 TextPoint.height = height;
368 case DIAL_POSITION_NONE:
372 case DIAL_POSITION_INSIDE: {
373 TextPoint.x = m_cx - (width / 2) - 1;
374 TextPoint.y = ((size.y - m_InstrumentSpacing) * .75) - height;
375 if ((g_TitleAlignment & wxALIGN_BOTTOM) != 0)
376 TextPoint.y -= m_TitleHeight;
378 cl = GetColourSchemeBackgroundColour(
379 m_Properties->m_TitleBackgroundColour);
381 GetGlobalColor(
"DASHL", &cl);
382 int penwidth = size.x / 100;
384 wxThePenList->FindOrCreatePen(cl, penwidth, wxPENSTYLE_SOLID);
387 cl = GetColourSchemeBackgroundColour(
388 m_Properties->m_DataBackgroundColour);
390 GetGlobalColor(
"DASHB", &cl);
394 dc->DrawRoundedRectangle(TextPoint.x - 2, TextPoint.y - 2, width + 4,
398 case DIAL_POSITION_TOPLEFT:
400 TextPoint.y = m_DataTop;
402 case DIAL_POSITION_TOPRIGHT:
403 TextPoint.x = size.x - width - 1;
404 TextPoint.y = m_DataTop;
406 case DIAL_POSITION_BOTTOMLEFT:
408 TextPoint.y = GetDataBottom(size.y) - height;
410 case DIAL_POSITION_BOTTOMRIGHT:
411 TextPoint.x = size.x - width - 1;
412 TextPoint.y = GetDataBottom(size.y) - height;
414 case DIAL_POSITION_BOTTOMMIDDLE:
415 if (!std::isnan(value)) {
416 TextPoint.x = m_cx - (width / 2) - 1;
417 TextPoint.y = GetDataBottom(size.y) - height;
420 dc->DrawRoundedRectangle(TextPoint.x - 2, TextPoint.y - 2, width + 4,
429 GetGlobalColor(
"DASHF", &c3);
431 wxStringTokenizer tkz(text,
"\n");
434 token = tkz.GetNextToken();
435 while (token.Length()) {
437 f = m_Properties->m_LabelFont.GetChosenFont();
439 f = g_pFontLabel->GetChosenFont();
440 dc->GetTextExtent(token, &width, &height,
nullptr,
nullptr, &f);
441 dc->DrawText(token, TextPoint.x, TextPoint.y);
442 TextPoint.y += height;
443 token = tkz.GetNextToken();
447void DashboardInstrument_Dial::DrawForeground(wxGCDC* dc) {
450 GetGlobalColor(
"DASH2", &cl);
452 pen1.SetStyle(wxPENSTYLE_SOLID);
456 GetGlobalColor(
"DASH1", &cl);
458 brush1.SetStyle(wxBRUSHSTYLE_SOLID);
459 brush1.SetColour(cl);
460 dc->SetBrush(brush1);
461 dc->DrawCircle(m_cx, m_cy, m_radius / 8);
463 dc->SetPen(*wxTRANSPARENT_PEN);
465 cl = GetColourSchemeFont(m_Properties->m_Arrow_First_Colour);
467 GetGlobalColor(
"DASHN", &cl);
469 brush.SetStyle(wxBRUSHSTYLE_SOLID);
476 if (m_main_value_unit ==
"\u00B0L")
477 data = 360 - m_main_value;
483 if (data < m_main_value_min)
484 val = m_main_value_min;
485 else if (data > m_main_value_max)
486 val = m_main_value_max;
490 double value = deg2rad((val - m_main_value_min) * m_angle_range /
491 (m_main_value_max - m_main_value_min)) +
492 deg2rad(m_angle_start - ANGLE_OFFSET);
495 points[0].x = m_cx + (m_radius * 0.95 * cos(value - .010));
496 points[0].y = m_cy + (m_radius * 0.95 * sin(value - .010));
497 points[1].x = m_cx + (m_radius * 0.95 * cos(value + .015));
498 points[1].y = m_cy + (m_radius * 0.95 * sin(value + .015));
499 points[2].x = m_cx + (m_radius * 0.22 * cos(value + 2.8));
500 points[2].y = m_cy + (m_radius * 0.22 * sin(value + 2.8));
501 points[3].x = m_cx + (m_radius * 0.22 * cos(value - 2.8));
502 points[3].y = m_cy + (m_radius * 0.22 * sin(value - 2.8));
503 dc->DrawPolygon(4, points, 0, 0);
507void DrawCompassRose(wxGCDC* dc,
int cx,
int cy,
int radius,
int startangle,
509 wxPoint pt, points[3];
512 wxString CompassArray[] = {_(
"N"), _(
"NE"), _(
"E"), _(
"SE"), _(
"S"),
513 _(
"SW"), _(
"W"), _(
"NW"), _(
"N")};
515 dc->SetFont((Properties->m_SmallFont.GetChosenFont()));
517 dc->SetFont((g_pFontSmall->GetChosenFont()));
521 GetGlobalColor(
"DASH2", &cl);
522 pen = wxThePenList->FindOrCreatePen(cl, 1, wxPENSTYLE_SOLID);
523 wxBrush* b2 = wxTheBrushList->FindOrCreateBrush(cl);
525 GetGlobalColor(
"DASH1", &cl);
526 wxBrush* b1 = wxTheBrushList->FindOrCreateBrush(cl);
529 dc->SetTextForeground(cl);
534 for (
double tmpangle = startangle - ANGLE_OFFSET;
535 tmpangle < startangle + 360 - ANGLE_OFFSET; tmpangle += 90) {
537 Value = CompassArray[offset];
539 f = Properties->m_SmallFont.GetChosenFont();
540 dc->GetTextExtent(Value, &width, &height,
nullptr,
nullptr, &f);
542 f = g_pFontSmall->GetChosenFont();
543 dc->GetTextExtent(Value, &width, &height,
nullptr,
nullptr, &f);
545 double x = width / 2;
546 long double anglefortext = tmpangle - rad2deg(asin((x / radius)));
547 pt.x = cx + radius * cos(deg2rad(anglefortext));
548 pt.y = cy + radius * sin(deg2rad(anglefortext));
549 dc->DrawRotatedText(Value, pt.x, pt.y, -90 - tmpangle);
550 Value = CompassArray[offset + 1];
552 f = Properties->m_SmallFont.GetChosenFont();
553 dc->GetTextExtent(Value, &width, &height,
nullptr,
nullptr, &f);
555 f = g_pFontSmall->GetChosenFont();
556 dc->GetTextExtent(Value, &width, &height,
nullptr,
nullptr, &f);
559 anglefortext = tmpangle - rad2deg(asin((x / radius))) + 45;
560 pt.x = cx + radius * cos(deg2rad(anglefortext));
561 pt.y = cy + radius * sin(deg2rad(anglefortext));
562 dc->DrawRotatedText(Value, pt.x, pt.y, -135 - tmpangle);
566 points[1].x = cx + radius * 0.15 * cos(deg2rad(tmpangle));
567 points[1].y = cy + radius * 0.15 * sin(deg2rad(tmpangle));
568 points[2].x = cx + radius * 0.6 * cos(deg2rad(tmpangle + 45));
569 points[2].y = cy + radius * 0.6 * sin(deg2rad(tmpangle + 45));
570 dc->DrawPolygon(3, points, 0, 0);
571 points[1].x = cx + radius * 0.15 * cos(deg2rad(tmpangle + 90));
572 points[1].y = cy + radius * 0.15 * sin(deg2rad(tmpangle + 90));
574 dc->DrawPolygon(3, points, 0, 0);
575 points[2].x = cx + radius * 0.8 * cos(deg2rad(tmpangle));
576 points[2].y = cy + radius * 0.8 * sin(deg2rad(tmpangle));
577 points[1].x = cx + radius * 0.15 * cos(deg2rad(tmpangle + 45));
578 points[1].y = cy + radius * 0.15 * sin(deg2rad(tmpangle + 45));
579 dc->DrawPolygon(3, points, 0, 0);
580 points[2].x = cx + radius * 0.8 * cos(deg2rad(tmpangle + 90));
581 points[2].y = cy + radius * 0.8 * sin(deg2rad(tmpangle + 90));
583 dc->DrawPolygon(3, points, 0, 0);
588void DrawBoat(wxGCDC* dc,
int cx,
int cy,
int radius) {
591 GetGlobalColor(
"DASH2", &cl);
592 wxPen* pen = wxThePenList->FindOrCreatePen(cl, 1, wxPENSTYLE_SOLID);
594 GetGlobalColor(
"DASH1", &cl);
612 points[0].y = cy - radius * .60;
613 points[1].x = cx + radius * .15;
614 points[1].y = cy - radius * .08;
615 points[2].x = cx + radius * .15;
616 points[2].y = cy + radius * .12;
617 points[3].x = cx + radius * .10;
618 points[3].y = cy + radius * .40;
619 points[4].x = cx - radius * .10;
620 points[4].y = cy + radius * .40;
621 points[5].x = cx - radius * .15;
622 points[5].y = cy + radius * .12;
623 points[6].x = cx - radius * .15;
624 points[6].y = cy - radius * .08;
626 dc->DrawPolygon(7, points, 0, 0);
Dashboard dial instrument.