42#include "wx/tokenzr.h"
44#ifdef __OCPN__ANDROID__
48double rad2deg(
double angle) {
return angle * 180.0 / M_PI; }
49double deg2rad(
double angle) {
return angle / 180.0 * M_PI; }
51DashboardInstrument_Dial::DashboardInstrument_Dial(
52 wxWindow* parent, wxWindowID
id, wxString title,
54 int r_angle,
int s_value,
int e_value)
56 m_AngleStart = s_angle;
57 m_AngleRange = r_angle;
58 m_MainValueMin = s_value;
59 m_MainValueMax = e_value;
60 m_MainValueCap = cap_flag;
62 m_MainValue = s_value;
64 m_MainValueFormat =
"%d";
66 m_MainValueOption = DIAL_POSITION_NONE;
67 m_ExtraValueFormat =
"%d";
68 m_ExtraValueUnit =
"";
69 m_ExtraValueOption = DIAL_POSITION_NONE;
70 m_MarkerOption = DIAL_MARKER_SIMPLE;
74 m_LabelOption = DIAL_LABEL_HORIZONTAL;
77wxSize DashboardInstrument_Dial::GetSize(
int orient, wxSize hint) {
79 InitTitleAndDataPosition(DefaultWidth);
81 if (orient == wxHORIZONTAL) {
82 w = wxMax(hint.y, GetFullHeight(DefaultWidth));
83 return wxSize(w - m_TitleHeight, w);
85 w = wxMax(hint.x, DefaultWidth);
86 return wxSize(w, GetFullHeight(w));
90void DashboardInstrument_Dial::SetData(DASH_CAP st,
double data,
92 if (st == m_MainValueCap) {
94 m_MainValueUnit =
unit;
95 }
else if (st == m_ExtraValueCap) {
97 m_ExtraValueUnit =
unit;
102void DashboardInstrument_Dial::Draw(wxGCDC* bdc) {
105 GetColourSchemeBackgroundColour(m_Properties->m_DataBackgroundColour));
106 bdc->SetBackground(b1);
109 GetGlobalColor(
"DASHB", &c1);
111 bdc->SetBackground(b1);
115 wxSize size = GetClientSize();
117 int availableHeight = GetDataBottom(size.y) - m_DataTop;
118 InitTitleAndDataPosition(availableHeight);
119 availableHeight -= 6;
123 f = m_Properties->m_LabelFont.GetChosenFont();
125 f = g_pFontLabel->GetChosenFont();
126 bdc->GetTextExtent(
"000", &width, &height, 0, 0, &f);
127 m_cy = m_DataTop + 2;
128 m_cy += availableHeight / 2;
129 m_radius = availableHeight / 2;
135 DrawData(bdc, m_MainValue, m_MainValueUnit, m_MainValueFormat,
137 DrawData(bdc, m_ExtraValue, m_ExtraValueUnit, m_ExtraValueFormat,
142void DashboardInstrument_Dial::DrawFrame(wxGCDC* dc) {
143 wxSize size = GetClientSize();
146 cl = GetColourSchemeBackgroundColour(m_Properties->m_TitleBackgroundColour);
148 GetGlobalColor(
"DASHL", &cl);
150 dc->SetTextForeground(cl);
151 dc->SetBrush(*wxTRANSPARENT_BRUSH);
153 int penwidth = 1 + size.x / 100;
154 wxPen pen(cl, penwidth, wxPENSTYLE_SOLID);
156 if (m_MarkerOption == DIAL_MARKER_REDGREENBAR) {
157 pen.SetWidth(penwidth * 2);
158 GetGlobalColor(
"DASHR", &cl);
161 double angle1 = deg2rad(270);
162 double angle2 = deg2rad(90);
163 int radi = m_radius - 1 - penwidth;
164 wxCoord x1 = m_cx + ((radi)*cos(angle1));
165 wxCoord y1 = m_cy + ((radi)*sin(angle1));
166 wxCoord x2 = m_cx + ((radi)*cos(angle2));
167 wxCoord y2 = m_cy + ((radi)*sin(angle2));
168 dc->DrawArc(x1, y1, x2, y2, m_cx, m_cy);
170 GetGlobalColor(
"DASHG", &cl);
173 angle1 = deg2rad(89);
174 angle2 = deg2rad(271);
175 x1 = m_cx + ((radi)*cos(angle1));
176 y1 = m_cy + ((radi)*sin(angle1));
177 x2 = m_cx + ((radi)*cos(angle2));
178 y2 = m_cy + ((radi)*sin(angle2));
179 dc->DrawArc(x1, y1, x2, y2, m_cx, m_cy);
183 GetGlobalColor(
"DASHF", &cl);
184 pen.SetWidth(penwidth);
188 angle2 = deg2rad(180);
191 x1 = m_cx + ((radi)*cos(angle1));
192 y1 = m_cy + ((radi)*sin(angle1));
193 x2 = m_cx + ((radi)*cos(angle2));
194 y2 = m_cy + ((radi)*sin(angle2));
195 dc->DrawArc(x1, y1, x2, y2, m_cx, m_cy);
196 dc->DrawArc(x2, y2, x1, y1, m_cx, m_cy);
199 GetGlobalColor(
"DASHF", &cl);
202 dc->DrawCircle(m_cx, m_cy, m_radius);
206void DashboardInstrument_Dial::DrawMarkers(wxGCDC* dc) {
207 if (m_MarkerOption == DIAL_MARKER_NONE)
return;
210 GetGlobalColor(
"DASHF", &cl);
211 int penwidth = GetClientSize().x / 100;
212 wxPen pen(cl, penwidth, wxPENSTYLE_SOLID);
215 int diff_angle = m_AngleStart + m_AngleRange - ANGLE_OFFSET;
217 double abm = m_AngleRange * m_MarkerStep / (m_MainValueMax - m_MainValueMin);
219 if (m_AngleRange == 360) diff_angle -= abm;
222 for (
double angle = m_AngleStart - ANGLE_OFFSET; angle <= diff_angle;
224 if (m_MarkerOption == DIAL_MARKER_REDGREEN) {
225 int a = int(angle + ANGLE_OFFSET) % 360;
227 GetGlobalColor(
"DASHR", &cl);
228 else if ((a > 0) && (a < 180))
229 GetGlobalColor(
"DASHG", &cl);
231 GetGlobalColor(
"DASHF", &cl);
238 if (offset % m_MarkerOffset) {
243 dc->DrawLine(m_cx + ((m_radius - 1) * size * cos(deg2rad(angle))),
244 m_cy + ((m_radius - 1) * size * sin(deg2rad(angle))),
245 m_cx + ((m_radius - 1) * cos(deg2rad(angle))),
246 m_cy + ((m_radius - 1) * sin(deg2rad(angle))));
249 if (m_MarkerOption == DIAL_MARKER_REDGREEN) {
250 GetGlobalColor(
"DASHF", &cl);
251 pen.SetStyle(wxPENSTYLE_SOLID);
257void DashboardInstrument_Dial::DrawLabels(wxGCDC* dc) {
258 if (m_LabelOption == DIAL_LABEL_NONE)
return;
263 GetGlobalColor(
"DASHF", &cl);
266 dc->SetFont(m_Properties->m_SmallFont.GetChosenFont());
267 dc->SetTextForeground(
268 GetColourSchemeFont(m_Properties->m_SmallFont.GetColour()));
270 dc->SetFont(g_pFontSmall->GetChosenFont());
271 dc->SetTextForeground(GetColourSchemeFont(g_pFontSmall->GetColour()));
273 int diff_angle = m_AngleStart + m_AngleRange - ANGLE_OFFSET;
275 double abm = m_AngleRange * m_LabelStep / (m_MainValueMax - m_MainValueMin);
277 if (m_AngleRange == 360) diff_angle -= abm;
280 int value = m_MainValueMin;
283 for (
double angle = m_AngleStart - ANGLE_OFFSET; angle <= diff_angle;
285 wxString label = (m_LabelArray.GetCount() ? m_LabelArray.Item(offset)
286 : wxString::Format(
"%d", value));
288 f = m_Properties->m_SmallFont.GetChosenFont();
290 f = g_pFontSmall->GetChosenFont();
291 dc->GetTextExtent(label, &width, &height, 0, 0, &f);
292 double halfW = width / 2;
293 if (m_LabelOption == DIAL_LABEL_HORIZONTAL) {
294 double halfH = height / 2;
296 double delta = sqrt(halfW * halfW + halfH * halfH);
298 m_cx + ((m_radius * 0.90) - delta) * cos(deg2rad(angle)) - halfW;
300 m_cy + ((m_radius * 0.90) - delta) * sin(deg2rad(angle)) - halfH;
301 dc->DrawText(label, TextPoint);
303 }
else if (m_LabelOption == DIAL_LABEL_ROTATED) {
308 long double tmpangle = angle - rad2deg(asin(halfW / (0.90 * m_radius)));
309 TextPoint.x = m_cx + m_radius * 0.90 * cos(deg2rad(tmpangle));
310 TextPoint.y = m_cy + m_radius * 0.90 * sin(deg2rad(tmpangle));
311 dc->DrawRotatedText(label, TextPoint, -90 - angle);
314 value += m_LabelStep;
318void DashboardInstrument_Dial::DrawBackground(wxGCDC* dc) {
323void DashboardInstrument_Dial::DrawData(wxGCDC* dc,
double value, wxString
unit,
325 DialPositionOption position) {
326 if (position == DIAL_POSITION_NONE)
return;
329 dc->SetFont(m_Properties->m_LabelFont.GetChosenFont());
330 dc->SetTextForeground(
331 GetColourSchemeFont(m_Properties->m_LabelFont.GetColour()));
333 dc->SetFont(g_pFontLabel->GetChosenFont());
334 dc->SetTextForeground(GetColourSchemeFont(g_pFontLabel->GetColour()));
338 wxSize size = GetClientSize();
341 if (!std::isnan(value)) {
342 if (
unit ==
"\u00B0")
343 text = wxString::Format(format, value) + DEGREE_SIGN;
344 else if (
unit ==
"\u00B0L")
346 text = wxString::Format(format, value) + DEGREE_SIGN;
347 else if (
unit ==
"\u00B0R")
348 text = wxString::Format(format, value) + DEGREE_SIGN;
349 else if (
unit ==
"\u00B0T")
350 text = wxString::Format(format, value) + DEGREE_SIGN +
"T";
351 else if (
unit ==
"\u00B0M")
352 text = wxString::Format(format, value) + DEGREE_SIGN +
"M";
353 else if (
unit ==
"N")
354 text = wxString::Format(format, value) +
" Kts";
356 text = wxString::Format(format, value) +
" " +
unit;
363 f = m_Properties->m_LabelFont.GetChosenFont();
365 f = g_pFontLabel->GetChosenFont();
366 dc->GetMultiLineTextExtent(text, &width, &height, NULL, &f);
369 TextPoint.width = width;
370 TextPoint.height = height;
372 case DIAL_POSITION_NONE:
376 case DIAL_POSITION_INSIDE: {
377 TextPoint.x = m_cx - (width / 2) - 1;
378 TextPoint.y = ((size.y - m_InstrumentSpacing) * .75) - height;
379 if ((g_TitleAlignment & wxALIGN_BOTTOM) != 0)
380 TextPoint.y -= m_TitleHeight;
382 cl = GetColourSchemeBackgroundColour(
383 m_Properties->m_TitleBackgroundColour);
385 GetGlobalColor(
"DASHL", &cl);
386 int penwidth = size.x / 100;
388 wxThePenList->FindOrCreatePen(cl, penwidth, wxPENSTYLE_SOLID);
391 cl = GetColourSchemeBackgroundColour(
392 m_Properties->m_DataBackgroundColour);
394 GetGlobalColor(
"DASHB", &cl);
398 dc->DrawRoundedRectangle(TextPoint.x - 2, TextPoint.y - 2, width + 4,
402 case DIAL_POSITION_TOPLEFT:
404 TextPoint.y = m_DataTop;
406 case DIAL_POSITION_TOPRIGHT:
407 TextPoint.x = size.x - width - 1;
408 TextPoint.y = m_DataTop;
410 case DIAL_POSITION_BOTTOMLEFT:
412 TextPoint.y = GetDataBottom(size.y) - height;
414 case DIAL_POSITION_BOTTOMRIGHT:
415 TextPoint.x = size.x - width - 1;
416 TextPoint.y = GetDataBottom(size.y) - height;
418 case DIAL_POSITION_BOTTOMMIDDLE:
419 if (!std::isnan(value)) {
420 TextPoint.x = m_cx - (width / 2) - 1;
421 TextPoint.y = GetDataBottom(size.y) - height;
424 dc->DrawRoundedRectangle(TextPoint.x - 2, TextPoint.y - 2, width + 4,
433 GetGlobalColor(
"DASHF", &c3);
435 wxStringTokenizer tkz(text,
"\n");
438 token = tkz.GetNextToken();
439 while (token.Length()) {
441 f = m_Properties->m_LabelFont.GetChosenFont();
443 f = g_pFontLabel->GetChosenFont();
444 dc->GetTextExtent(token, &width, &height, NULL, NULL, &f);
445 dc->DrawText(token, TextPoint.x, TextPoint.y);
446 TextPoint.y += height;
447 token = tkz.GetNextToken();
451void DashboardInstrument_Dial::DrawForeground(wxGCDC* dc) {
454 GetGlobalColor(
"DASH2", &cl);
456 pen1.SetStyle(wxPENSTYLE_SOLID);
460 GetGlobalColor(
"DASH1", &cl);
462 brush1.SetStyle(wxBRUSHSTYLE_SOLID);
463 brush1.SetColour(cl);
464 dc->SetBrush(brush1);
465 dc->DrawCircle(m_cx, m_cy, m_radius / 8);
467 dc->SetPen(*wxTRANSPARENT_PEN);
469 cl = GetColourSchemeFont(m_Properties->m_Arrow_First_Colour);
471 GetGlobalColor(
"DASHN", &cl);
473 brush.SetStyle(wxBRUSHSTYLE_SOLID);
480 if (m_MainValueUnit ==
"\u00B0L")
481 data = 360 - m_MainValue;
487 if (data < m_MainValueMin)
488 val = m_MainValueMin;
489 else if (data > m_MainValueMax)
490 val = m_MainValueMax;
494 double value = deg2rad((val - m_MainValueMin) * m_AngleRange /
495 (m_MainValueMax - m_MainValueMin)) +
496 deg2rad(m_AngleStart - ANGLE_OFFSET);
499 points[0].x = m_cx + (m_radius * 0.95 * cos(value - .010));
500 points[0].y = m_cy + (m_radius * 0.95 * sin(value - .010));
501 points[1].x = m_cx + (m_radius * 0.95 * cos(value + .015));
502 points[1].y = m_cy + (m_radius * 0.95 * sin(value + .015));
503 points[2].x = m_cx + (m_radius * 0.22 * cos(value + 2.8));
504 points[2].y = m_cy + (m_radius * 0.22 * sin(value + 2.8));
505 points[3].x = m_cx + (m_radius * 0.22 * cos(value - 2.8));
506 points[3].y = m_cy + (m_radius * 0.22 * sin(value - 2.8));
507 dc->DrawPolygon(4, points, 0, 0);
511void DrawCompassRose(wxGCDC* dc,
int cx,
int cy,
int radius,
int startangle,
513 wxPoint pt, points[3];
516 wxString CompassArray[] = {_(
"N"), _(
"NE"), _(
"E"), _(
"SE"), _(
"S"),
517 _(
"SW"), _(
"W"), _(
"NW"), _(
"N")};
519 dc->SetFont((Properties->m_SmallFont.GetChosenFont()));
521 dc->SetFont((g_pFontSmall->GetChosenFont()));
525 GetGlobalColor(
"DASH2", &cl);
526 pen = wxThePenList->FindOrCreatePen(cl, 1, wxPENSTYLE_SOLID);
527 wxBrush* b2 = wxTheBrushList->FindOrCreateBrush(cl);
529 GetGlobalColor(
"DASH1", &cl);
530 wxBrush* b1 = wxTheBrushList->FindOrCreateBrush(cl);
533 dc->SetTextForeground(cl);
538 for (
double tmpangle = startangle - ANGLE_OFFSET;
539 tmpangle < startangle + 360 - ANGLE_OFFSET; tmpangle += 90) {
541 Value = CompassArray[offset];
543 f = Properties->m_SmallFont.GetChosenFont();
544 dc->GetTextExtent(Value, &width, &height, 0, 0, &f);
546 f = g_pFontSmall->GetChosenFont();
547 dc->GetTextExtent(Value, &width, &height, 0, 0, &f);
549 double x = width / 2;
550 long double anglefortext = tmpangle - rad2deg(asin((x / radius)));
551 pt.x = cx + radius * cos(deg2rad(anglefortext));
552 pt.y = cy + radius * sin(deg2rad(anglefortext));
553 dc->DrawRotatedText(Value, pt.x, pt.y, -90 - tmpangle);
554 Value = CompassArray[offset + 1];
556 f = Properties->m_SmallFont.GetChosenFont();
557 dc->GetTextExtent(Value, &width, &height, 0, 0, &f);
559 f = g_pFontSmall->GetChosenFont();
560 dc->GetTextExtent(Value, &width, &height, 0, 0, &f);
563 anglefortext = tmpangle - rad2deg(asin((x / radius))) + 45;
564 pt.x = cx + radius * cos(deg2rad(anglefortext));
565 pt.y = cy + radius * sin(deg2rad(anglefortext));
566 dc->DrawRotatedText(Value, pt.x, pt.y, -135 - tmpangle);
570 points[1].x = cx + radius * 0.15 * cos(deg2rad(tmpangle));
571 points[1].y = cy + radius * 0.15 * sin(deg2rad(tmpangle));
572 points[2].x = cx + radius * 0.6 * cos(deg2rad(tmpangle + 45));
573 points[2].y = cy + radius * 0.6 * sin(deg2rad(tmpangle + 45));
574 dc->DrawPolygon(3, points, 0, 0);
575 points[1].x = cx + radius * 0.15 * cos(deg2rad(tmpangle + 90));
576 points[1].y = cy + radius * 0.15 * sin(deg2rad(tmpangle + 90));
578 dc->DrawPolygon(3, points, 0, 0);
579 points[2].x = cx + radius * 0.8 * cos(deg2rad(tmpangle));
580 points[2].y = cy + radius * 0.8 * sin(deg2rad(tmpangle));
581 points[1].x = cx + radius * 0.15 * cos(deg2rad(tmpangle + 45));
582 points[1].y = cy + radius * 0.15 * sin(deg2rad(tmpangle + 45));
583 dc->DrawPolygon(3, points, 0, 0);
584 points[2].x = cx + radius * 0.8 * cos(deg2rad(tmpangle + 90));
585 points[2].y = cy + radius * 0.8 * sin(deg2rad(tmpangle + 90));
587 dc->DrawPolygon(3, points, 0, 0);
592void DrawBoat(wxGCDC* dc,
int cx,
int cy,
int radius) {
595 GetGlobalColor(
"DASH2", &cl);
596 wxPen* pen = wxThePenList->FindOrCreatePen(cl, 1, wxPENSTYLE_SOLID);
598 GetGlobalColor(
"DASH1", &cl);
616 points[0].y = cy - radius * .60;
617 points[1].x = cx + radius * .15;
618 points[1].y = cy - radius * .08;
619 points[2].x = cx + radius * .15;
620 points[2].y = cy + radius * .12;
621 points[3].x = cx + radius * .10;
622 points[3].y = cy + radius * .40;
623 points[4].x = cx - radius * .10;
624 points[4].y = cy + radius * .40;
625 points[5].x = cx - radius * .15;
626 points[5].y = cy + radius * .12;
627 points[6].x = cx - radius * .15;
628 points[6].y = cy - radius * .08;
630 dc->DrawPolygon(7, points, 0, 0);