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 = _T(
"%d");
65 m_MainValueUnit = _T(
"");
66 m_MainValueOption = DIAL_POSITION_NONE;
67 m_ExtraValueFormat = _T(
"%d");
68 m_ExtraValueUnit = _T(
"");
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(_T(
"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(_T(
"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(_T(
"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(_T(
"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(_T(
"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(_T(
"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(_T(
"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(_T(
"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(_T(
"DASHR"), &cl);
228 else if ((a > 0) && (a < 180))
229 GetGlobalColor(_T(
"DASHG"), &cl);
231 GetGlobalColor(_T(
"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(_T(
"DASHF"), &cl);
251 pen.SetStyle(wxPENSTYLE_SOLID);
257void DashboardInstrument_Dial::DrawLabels(wxGCDC* dc) {
258 if (m_LabelOption == DIAL_LABEL_NONE)
return;
263 GetGlobalColor(_T(
"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;
286 (m_LabelArray.GetCount() ? m_LabelArray.Item(offset)
287 : wxString::Format(_T(
"%d"), value));
289 f = m_Properties->m_SmallFont.GetChosenFont();
291 f = g_pFontSmall->GetChosenFont();
292 dc->GetTextExtent(label, &width, &height, 0, 0, &f);
293 double halfW = width / 2;
294 if (m_LabelOption == DIAL_LABEL_HORIZONTAL) {
295 double halfH = height / 2;
297 double delta = sqrt(halfW * halfW + halfH * halfH);
299 m_cx + ((m_radius * 0.90) - delta) * cos(deg2rad(angle)) - halfW;
301 m_cy + ((m_radius * 0.90) - delta) * sin(deg2rad(angle)) - halfH;
302 dc->DrawText(label, TextPoint);
304 }
else if (m_LabelOption == DIAL_LABEL_ROTATED) {
309 long double tmpangle = angle - rad2deg(asin(halfW / (0.90 * m_radius)));
310 TextPoint.x = m_cx + m_radius * 0.90 * cos(deg2rad(tmpangle));
311 TextPoint.y = m_cy + m_radius * 0.90 * sin(deg2rad(tmpangle));
312 dc->DrawRotatedText(label, TextPoint, -90 - angle);
315 value += m_LabelStep;
319void DashboardInstrument_Dial::DrawBackground(wxGCDC* dc) {
324void DashboardInstrument_Dial::DrawData(wxGCDC* dc,
double value, wxString
unit,
326 DialPositionOption position) {
327 if (position == DIAL_POSITION_NONE)
return;
330 dc->SetFont(m_Properties->m_LabelFont.GetChosenFont());
331 dc->SetTextForeground(
332 GetColourSchemeFont(m_Properties->m_LabelFont.GetColour()));
334 dc->SetFont(g_pFontLabel->GetChosenFont());
335 dc->SetTextForeground(GetColourSchemeFont(g_pFontLabel->GetColour()));
339 wxSize size = GetClientSize();
342 if (!std::isnan(value)) {
343 if (
unit == _T(
"\u00B0"))
344 text = wxString::Format(format, value) + DEGREE_SIGN;
345 else if (
unit == _T(
"\u00B0L"))
347 text = wxString::Format(format, value) + DEGREE_SIGN;
350 text = wxString::Format(format, value) + DEGREE_SIGN;
351 else if (
unit == _T(
"\u00B0T"))
352 text = wxString::Format(format, value) + DEGREE_SIGN + _T(
"T");
353 else if (
unit == _T(
"\u00B0M"))
354 text = wxString::Format(format, value) + DEGREE_SIGN + _T(
"M");
355 else if (
unit == _T(
"N"))
356 text = wxString::Format(format, value) + _T(
" Kts");
358 text = wxString::Format(format, value) + _T(
" ") +
unit;
365 f = m_Properties->m_LabelFont.GetChosenFont();
367 f = g_pFontLabel->GetChosenFont();
368 dc->GetMultiLineTextExtent(text, &width, &height, NULL, &f);
371 TextPoint.width = width;
372 TextPoint.height = height;
374 case DIAL_POSITION_NONE:
378 case DIAL_POSITION_INSIDE: {
379 TextPoint.x = m_cx - (width / 2) - 1;
380 TextPoint.y = ((size.y - m_InstrumentSpacing) * .75) - height;
381 if ((g_TitleAlignment & wxALIGN_BOTTOM) != 0)
382 TextPoint.y -= m_TitleHeight;
384 cl = GetColourSchemeBackgroundColour(
385 m_Properties->m_TitleBackgroundColour);
387 GetGlobalColor(_T(
"DASHL"), &cl);
388 int penwidth = size.x / 100;
390 wxThePenList->FindOrCreatePen(cl, penwidth, wxPENSTYLE_SOLID);
393 cl = GetColourSchemeBackgroundColour(
394 m_Properties->m_DataBackgroundColour);
396 GetGlobalColor(_T(
"DASHB"), &cl);
400 dc->DrawRoundedRectangle(TextPoint.x - 2, TextPoint.y - 2, width + 4,
404 case DIAL_POSITION_TOPLEFT:
406 TextPoint.y = m_DataTop;
408 case DIAL_POSITION_TOPRIGHT:
409 TextPoint.x = size.x - width - 1;
410 TextPoint.y = m_DataTop;
412 case DIAL_POSITION_BOTTOMLEFT:
414 TextPoint.y = GetDataBottom(size.y) - height;
416 case DIAL_POSITION_BOTTOMRIGHT:
417 TextPoint.x = size.x - width - 1;
418 TextPoint.y = GetDataBottom(size.y) - height;
420 case DIAL_POSITION_BOTTOMMIDDLE:
421 if (!std::isnan(value)) {
422 TextPoint.x = m_cx - (width / 2) - 1;
423 TextPoint.y = GetDataBottom(size.y) - height;
426 dc->DrawRoundedRectangle(TextPoint.x - 2, TextPoint.y - 2, width + 4,
435 GetGlobalColor(_T(
"DASHF"), &c3);
437 wxStringTokenizer tkz(text, _T(
"\n"));
440 token = tkz.GetNextToken();
441 while (token.Length()) {
443 f = m_Properties->m_LabelFont.GetChosenFont();
445 f = g_pFontLabel->GetChosenFont();
446 dc->GetTextExtent(token, &width, &height, NULL, NULL, &f);
447 dc->DrawText(token, TextPoint.x, TextPoint.y);
448 TextPoint.y += height;
449 token = tkz.GetNextToken();
453void DashboardInstrument_Dial::DrawForeground(wxGCDC* dc) {
456 GetGlobalColor(_T(
"DASH2"), &cl);
458 pen1.SetStyle(wxPENSTYLE_SOLID);
462 GetGlobalColor(_T(
"DASH1"), &cl);
464 brush1.SetStyle(wxBRUSHSTYLE_SOLID);
465 brush1.SetColour(cl);
466 dc->SetBrush(brush1);
467 dc->DrawCircle(m_cx, m_cy, m_radius / 8);
469 dc->SetPen(*wxTRANSPARENT_PEN);
471 cl = GetColourSchemeFont(m_Properties->m_Arrow_First_Colour);
473 GetGlobalColor(_T(
"DASHN"), &cl);
475 brush.SetStyle(wxBRUSHSTYLE_SOLID);
482 if (m_MainValueUnit == _T(
"\u00B0L"))
483 data = 360 - m_MainValue;
489 if (data < m_MainValueMin)
490 val = m_MainValueMin;
491 else if (data > m_MainValueMax)
492 val = m_MainValueMax;
496 double value = deg2rad((val - m_MainValueMin) * m_AngleRange /
497 (m_MainValueMax - m_MainValueMin)) +
498 deg2rad(m_AngleStart - ANGLE_OFFSET);
501 points[0].x = m_cx + (m_radius * 0.95 * cos(value - .010));
502 points[0].y = m_cy + (m_radius * 0.95 * sin(value - .010));
503 points[1].x = m_cx + (m_radius * 0.95 * cos(value + .015));
504 points[1].y = m_cy + (m_radius * 0.95 * sin(value + .015));
505 points[2].x = m_cx + (m_radius * 0.22 * cos(value + 2.8));
506 points[2].y = m_cy + (m_radius * 0.22 * sin(value + 2.8));
507 points[3].x = m_cx + (m_radius * 0.22 * cos(value - 2.8));
508 points[3].y = m_cy + (m_radius * 0.22 * sin(value - 2.8));
509 dc->DrawPolygon(4, points, 0, 0);
513void DrawCompassRose(wxGCDC* dc,
int cx,
int cy,
int radius,
int startangle,
515 wxPoint pt, points[3];
518 wxString CompassArray[] = {_(
"N"), _(
"NE"), _(
"E"), _(
"SE"), _(
"S"),
519 _(
"SW"), _(
"W"), _(
"NW"), _(
"N")};
521 dc->SetFont((Properties->m_SmallFont.GetChosenFont()));
523 dc->SetFont((g_pFontSmall->GetChosenFont()));
527 GetGlobalColor(_T(
"DASH2"), &cl);
528 pen = wxThePenList->FindOrCreatePen(cl, 1, wxPENSTYLE_SOLID);
529 wxBrush* b2 = wxTheBrushList->FindOrCreateBrush(cl);
531 GetGlobalColor(_T(
"DASH1"), &cl);
532 wxBrush* b1 = wxTheBrushList->FindOrCreateBrush(cl);
535 dc->SetTextForeground(cl);
540 for (
double tmpangle = startangle - ANGLE_OFFSET;
541 tmpangle < startangle + 360 - ANGLE_OFFSET; tmpangle += 90) {
543 Value = CompassArray[offset];
545 f = Properties->m_SmallFont.GetChosenFont();
546 dc->GetTextExtent(Value, &width, &height, 0, 0, &f);
548 f = g_pFontSmall->GetChosenFont();
549 dc->GetTextExtent(Value, &width, &height, 0, 0, &f);
551 double x = width / 2;
552 long double anglefortext = tmpangle - rad2deg(asin((x / radius)));
553 pt.x = cx + radius * cos(deg2rad(anglefortext));
554 pt.y = cy + radius * sin(deg2rad(anglefortext));
555 dc->DrawRotatedText(Value, pt.x, pt.y, -90 - tmpangle);
556 Value = CompassArray[offset + 1];
558 f = Properties->m_SmallFont.GetChosenFont();
559 dc->GetTextExtent(Value, &width, &height, 0, 0, &f);
561 f = g_pFontSmall->GetChosenFont();
562 dc->GetTextExtent(Value, &width, &height, 0, 0, &f);
565 anglefortext = tmpangle - rad2deg(asin((x / radius))) + 45;
566 pt.x = cx + radius * cos(deg2rad(anglefortext));
567 pt.y = cy + radius * sin(deg2rad(anglefortext));
568 dc->DrawRotatedText(Value, pt.x, pt.y, -135 - tmpangle);
572 points[1].x = cx + radius * 0.15 * cos(deg2rad(tmpangle));
573 points[1].y = cy + radius * 0.15 * sin(deg2rad(tmpangle));
574 points[2].x = cx + radius * 0.6 * cos(deg2rad(tmpangle + 45));
575 points[2].y = cy + radius * 0.6 * sin(deg2rad(tmpangle + 45));
576 dc->DrawPolygon(3, points, 0, 0);
577 points[1].x = cx + radius * 0.15 * cos(deg2rad(tmpangle + 90));
578 points[1].y = cy + radius * 0.15 * sin(deg2rad(tmpangle + 90));
580 dc->DrawPolygon(3, points, 0, 0);
581 points[2].x = cx + radius * 0.8 * cos(deg2rad(tmpangle));
582 points[2].y = cy + radius * 0.8 * sin(deg2rad(tmpangle));
583 points[1].x = cx + radius * 0.15 * cos(deg2rad(tmpangle + 45));
584 points[1].y = cy + radius * 0.15 * sin(deg2rad(tmpangle + 45));
585 dc->DrawPolygon(3, points, 0, 0);
586 points[2].x = cx + radius * 0.8 * cos(deg2rad(tmpangle + 90));
587 points[2].y = cy + radius * 0.8 * sin(deg2rad(tmpangle + 90));
589 dc->DrawPolygon(3, points, 0, 0);
594void DrawBoat(wxGCDC* dc,
int cx,
int cy,
int radius) {
597 GetGlobalColor(_T(
"DASH2"), &cl);
598 wxPen* pen = wxThePenList->FindOrCreatePen(cl, 1, wxPENSTYLE_SOLID);
600 GetGlobalColor(_T(
"DASH1"), &cl);
618 points[0].y = cy - radius * .60;
619 points[1].x = cx + radius * .15;
620 points[1].y = cy - radius * .08;
621 points[2].x = cx + radius * .15;
622 points[2].y = cy + radius * .12;
623 points[3].x = cx + radius * .10;
624 points[3].y = cy + radius * .40;
625 points[4].x = cx - radius * .10;
626 points[4].y = cy + radius * .40;
627 points[5].x = cx - radius * .15;
628 points[5].y = cy + radius * .12;
629 points[6].x = cx - radius * .15;
630 points[6].y = cy - radius * .08;
632 dc->DrawPolygon(7, points, 0, 0);