OpenCPN Partial API docs
Loading...
Searching...
No Matches
dial.cpp
Go to the documentation of this file.
1/**************************************************************************
2 * Copyright (C) 2010 by Jean-Eudes Onfray *
3 * Copyright (C) 2010 by David S. Register *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, see <https://www.gnu.org/licenses/>. *
17 **************************************************************************/
18
27#include <wx/wxprec.h>
28
29#ifndef WX_PRECOMP
30#include <wx/wx.h>
31#endif
32
33#include "dial.h"
34
35#include <cmath>
36#include "wx/tokenzr.h"
37
38#ifdef __ANDROID__
39#include "qdebug.h"
40#endif
41
42double rad2deg(double angle) { return angle * 180.0 / M_PI; }
43double deg2rad(double angle) { return angle / 180.0 * M_PI; }
44
45DashboardInstrument_Dial::DashboardInstrument_Dial(
46 wxWindow* parent, wxWindowID id, wxString title,
47 InstrumentProperties* Properties, DASH_CAP cap_flag, int s_angle,
48 int r_angle, int s_value, int e_value)
49 : DashboardInstrument(parent, id, title, cap_flag, Properties) {
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;
55
56 m_main_value = s_value;
57 m_extra_value = 0;
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;
65 m_marker_step = 1;
66 m_label_step = 1;
67 m_marker_offset = 1;
68 m_label_option = DIAL_LABEL_HORIZONTAL;
69}
70
71wxSize DashboardInstrument_Dial::GetSize(int orient, wxSize hint) {
72 InitTitleSize();
73 InitTitleAndDataPosition(DefaultWidth);
74 int w;
75 if (orient == wxHORIZONTAL) {
76 w = wxMax(hint.y, GetFullHeight(DefaultWidth));
77 return wxSize(w - m_TitleHeight, w);
78 } else {
79 w = wxMax(hint.x, DefaultWidth);
80 return wxSize(w, GetFullHeight(w));
81 }
82}
83
84void DashboardInstrument_Dial::SetData(DASH_CAP st, double data,
85 wxString unit) {
86 if (st == m_main_value_cap) {
87 m_main_value = data;
88 m_main_value_unit = unit;
89 } else if (st == m_extra_value_cap) {
90 m_extra_value = data;
91 m_extra_value_unit = unit;
92 }
93 Refresh();
94}
95
96void DashboardInstrument_Dial::Draw(wxGCDC* bdc) {
97 if (m_Properties) {
98 wxBrush b1(
99 GetColourSchemeBackgroundColour(m_Properties->m_DataBackgroundColour));
100 bdc->SetBackground(b1);
101 } else {
102 wxColour c1;
103 GetGlobalColor("DASHB", &c1);
104 wxBrush b1(c1);
105 bdc->SetBackground(b1);
106 }
107 bdc->Clear();
108
109 wxSize size = GetClientSize();
110 m_cx = size.x / 2;
111 int availableHeight = GetDataBottom(size.y) - m_DataTop;
112 InitTitleAndDataPosition(availableHeight);
113 availableHeight -= 6;
114 int width, height;
115 wxFont f;
116 if (m_Properties)
117 f = m_Properties->m_LabelFont.GetChosenFont();
118 else
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;
124
125 DrawFrame(bdc);
126 DrawLabels(bdc);
127 DrawMarkers(bdc);
128 DrawBackground(bdc);
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);
133 DrawForeground(bdc);
134}
135
136void DashboardInstrument_Dial::DrawFrame(wxGCDC* dc) {
137 wxSize size = GetClientSize();
138 wxColour cl;
139 if (m_Properties) {
140 cl = GetColourSchemeBackgroundColour(m_Properties->m_TitleBackgroundColour);
141 } else {
142 GetGlobalColor("DASHL", &cl);
143 }
144 dc->SetTextForeground(cl);
145 dc->SetBrush(*wxTRANSPARENT_BRUSH);
146
147 int penwidth = 1 + size.x / 100;
148 wxPen pen(cl, penwidth, wxPENSTYLE_SOLID);
149
150 if (m_marker_option == DIAL_MARKER_REDGREENBAR) {
151 pen.SetWidth(penwidth * 2);
152 GetGlobalColor("DASHR", &cl);
153 pen.SetColour(cl);
154 dc->SetPen(pen);
155 double angle1 = deg2rad(270); // 305-ANGLE_OFFSET
156 double angle2 = deg2rad(90); // 55-ANGLE_OFFSET
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);
163
164 GetGlobalColor("DASHG", &cl);
165 pen.SetColour(cl);
166 dc->SetPen(pen);
167 angle1 = deg2rad(89); // 305-ANGLE_OFFSET
168 angle2 = deg2rad(271); // 55-ANGLE_OFFSET
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);
174
175 // Some platforms have trouble with transparent pen.
176 // so we simply draw arcs for the outer ring.
177 GetGlobalColor("DASHF", &cl);
178 pen.SetWidth(penwidth);
179 pen.SetColour(cl);
180 dc->SetPen(pen);
181 angle1 = deg2rad(0);
182 angle2 = deg2rad(180);
183 radi = m_radius - 1;
184
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);
191
192 } else {
193 GetGlobalColor("DASHF", &cl);
194 pen.SetColour(cl);
195 dc->SetPen(pen);
196 dc->DrawCircle(m_cx, m_cy, m_radius);
197 }
198}
199
200void DashboardInstrument_Dial::DrawMarkers(wxGCDC* dc) {
201 if (m_marker_option == DIAL_MARKER_NONE) return;
202
203 wxColour cl;
204 GetGlobalColor("DASHF", &cl);
205 int penwidth = GetClientSize().x / 100;
206 wxPen pen(cl, penwidth, wxPENSTYLE_SOLID);
207 dc->SetPen(pen);
208
209 int diff_angle = m_angle_start + m_angle_range - ANGLE_OFFSET;
210 // angle between markers
211 double abm =
212 m_angle_range * m_marker_step / (m_main_value_max - m_main_value_min);
213 // don't draw last value, it's already done as first
214 if (m_angle_range == 360) diff_angle -= abm;
215
216 int offset = 0;
217 for (double angle = m_angle_start - ANGLE_OFFSET; angle <= diff_angle;
218 angle += abm) {
219 if (m_marker_option == DIAL_MARKER_REDGREEN) {
220 int a = int(angle + ANGLE_OFFSET) % 360;
221 if (a > 180)
222 GetGlobalColor("DASHR", &cl);
223 else if ((a > 0) && (a < 180))
224 GetGlobalColor("DASHG", &cl);
225 else
226 GetGlobalColor("DASHF", &cl);
227
228 pen.SetColour(cl);
229 dc->SetPen(pen);
230 }
231
232 double size = 0.92;
233 if (offset % m_marker_offset) {
234 size = 0.96;
235 }
236 offset++;
237
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))));
242 }
243 // We must reset pen color so following drawings are fine
244 if (m_marker_option == DIAL_MARKER_REDGREEN) {
245 GetGlobalColor("DASHF", &cl);
246 pen.SetStyle(wxPENSTYLE_SOLID);
247 pen.SetColour(cl);
248 dc->SetPen(pen);
249 }
250}
251
252void DashboardInstrument_Dial::DrawLabels(wxGCDC* dc) {
253 if (m_label_option == DIAL_LABEL_NONE) return;
254
255 wxPoint TextPoint;
256 wxPen pen;
257 wxColor cl;
258 GetGlobalColor("DASHF", &cl);
259
260 if (m_Properties) {
261 dc->SetFont(m_Properties->m_SmallFont.GetChosenFont());
262 dc->SetTextForeground(
263 GetColourSchemeFont(m_Properties->m_SmallFont.GetColour()));
264 } else {
265 dc->SetFont(g_pFontSmall->GetChosenFont());
266 dc->SetTextForeground(GetColourSchemeFont(g_pFontSmall->GetColour()));
267 }
268 int diff_angle = m_angle_start + m_angle_range - ANGLE_OFFSET;
269 // angle between markers
270 double abm =
271 m_angle_range * m_label_step / (m_main_value_max - m_main_value_min);
272 // don't draw last value, it's already done as first
273 if (m_angle_range == 360) diff_angle -= abm;
274
275 int offset = 0;
276 int value = m_main_value_min;
277 int width, height;
278 wxFont f;
279 for (double angle = m_angle_start - ANGLE_OFFSET; angle <= diff_angle;
280 angle += abm) {
281 wxString label = (m_label_array.GetCount() ? m_label_array.Item(offset)
282 : wxString::Format("%d", value));
283 if (m_Properties)
284 f = m_Properties->m_SmallFont.GetChosenFont();
285 else
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;
291 // double delta = sqrt(width*width+height*height);
292 double delta = sqrt(halfW * halfW + halfH * halfH);
293 TextPoint.x =
294 m_cx + ((m_radius * 0.90) - delta) * cos(deg2rad(angle)) - halfW;
295 TextPoint.y =
296 m_cy + ((m_radius * 0.90) - delta) * sin(deg2rad(angle)) - halfH;
297 dc->DrawText(label, TextPoint);
298
299 } else if (m_label_option == DIAL_LABEL_ROTATED) {
300 // The coordinates of dc->DrawRotatedText refer to the top-left corner
301 // of the rectangle bounding the string. So we must calculate the
302 // right coordinates depending of the angle.
303 // Move left from the Marker so that the position is in the Middle of Text
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);
308 }
309 offset++;
310 value += m_label_step;
311 }
312}
313
314void DashboardInstrument_Dial::DrawBackground(wxGCDC* dc) {
315 // Nothing to do here right now, will be overwritten
316 // by child classes if required
317}
318
319void DashboardInstrument_Dial::DrawData(wxGCDC* dc, double value, wxString unit,
320 wxString format,
321 DialPositionOption position) {
322 if (position == DIAL_POSITION_NONE) return;
323
324 if (m_Properties) {
325 dc->SetFont(m_Properties->m_LabelFont.GetChosenFont());
326 dc->SetTextForeground(
327 GetColourSchemeFont(m_Properties->m_LabelFont.GetColour()));
328 } else {
329 dc->SetFont(g_pFontLabel->GetChosenFont());
330 dc->SetTextForeground(GetColourSchemeFont(g_pFontLabel->GetColour()));
331 }
332 wxColour cl;
333 // GetGlobalColor("DASHF", &cl);
334 wxSize size = GetClientSize();
335
336 wxString text;
337 if (!std::isnan(value)) {
338 if (unit == "\u00B0")
339 text = wxString::Format(format, value) + DEGREE_SIGN;
340 else if (unit == "\u00B0L") // No special display for now, might be
341 // XX�< (as in text-only instrument)
342 text = wxString::Format(format, value) + DEGREE_SIGN;
343 else if (unit == "\u00B0R") // No special display for now, might be >XX�
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") // Knots
350 text = wxString::Format(format, value) + " Kts";
351 else
352 text = wxString::Format(format, value) + " " + unit;
353 } else
354 text = "---";
355
356 int width, height;
357 wxFont f;
358 if (m_Properties)
359 f = m_Properties->m_LabelFont.GetChosenFont();
360 else
361 f = g_pFontLabel->GetChosenFont();
362 dc->GetMultiLineTextExtent(text, &width, &height, nullptr, &f);
363
364 wxRect TextPoint;
365 TextPoint.width = width;
366 TextPoint.height = height;
367 switch (position) {
368 case DIAL_POSITION_NONE:
369 // This case was already handled before, it's here just
370 // to avoid compiler warning.
371 return;
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;
377 if (m_Properties)
378 cl = GetColourSchemeBackgroundColour(
379 m_Properties->m_TitleBackgroundColour);
380 else
381 GetGlobalColor("DASHL", &cl);
382 int penwidth = size.x / 100;
383 wxPen* pen =
384 wxThePenList->FindOrCreatePen(cl, penwidth, wxPENSTYLE_SOLID);
385 dc->SetPen(*pen);
386 if (m_Properties)
387 cl = GetColourSchemeBackgroundColour(
388 m_Properties->m_DataBackgroundColour);
389 else
390 GetGlobalColor("DASHB", &cl);
391 dc->SetBrush(cl);
392 // There might be a background drawn below
393 // so we must clear it first.
394 dc->DrawRoundedRectangle(TextPoint.x - 2, TextPoint.y - 2, width + 4,
395 height + 4, 3);
396 break;
397 }
398 case DIAL_POSITION_TOPLEFT:
399 TextPoint.x = 0;
400 TextPoint.y = m_DataTop;
401 break;
402 case DIAL_POSITION_TOPRIGHT:
403 TextPoint.x = size.x - width - 1;
404 TextPoint.y = m_DataTop;
405 break;
406 case DIAL_POSITION_BOTTOMLEFT:
407 TextPoint.x = 0;
408 TextPoint.y = GetDataBottom(size.y) - height;
409 break;
410 case DIAL_POSITION_BOTTOMRIGHT:
411 TextPoint.x = size.x - width - 1;
412 TextPoint.y = GetDataBottom(size.y) - height;
413 break;
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;
418 // There might be a background drawn below
419 // so we must clear it first.
420 dc->DrawRoundedRectangle(TextPoint.x - 2, TextPoint.y - 2, width + 4,
421 height + 4, 3);
422 }
423 break;
424 }
425
426 // wxColour c2;
427 // GetGlobalColor("DASHB", &c2);
428 wxColour c3;
429 GetGlobalColor("DASHF", &c3);
430
431 wxStringTokenizer tkz(text, "\n");
432 wxString token;
433
434 token = tkz.GetNextToken();
435 while (token.Length()) {
436 if (m_Properties)
437 f = m_Properties->m_LabelFont.GetChosenFont();
438 else
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();
444 }
445}
446
447void DashboardInstrument_Dial::DrawForeground(wxGCDC* dc) {
448 // The default foreground is the arrow used in most dials
449 wxColour cl;
450 GetGlobalColor("DASH2", &cl);
451 wxPen pen1;
452 pen1.SetStyle(wxPENSTYLE_SOLID);
453 pen1.SetColour(cl);
454 pen1.SetWidth(2);
455 dc->SetPen(pen1);
456 GetGlobalColor("DASH1", &cl);
457 wxBrush brush1;
458 brush1.SetStyle(wxBRUSHSTYLE_SOLID);
459 brush1.SetColour(cl);
460 dc->SetBrush(brush1);
461 dc->DrawCircle(m_cx, m_cy, m_radius / 8);
462
463 dc->SetPen(*wxTRANSPARENT_PEN);
464 if (m_Properties)
465 cl = GetColourSchemeFont(m_Properties->m_Arrow_First_Colour);
466 else
467 GetGlobalColor("DASHN", &cl);
468 wxBrush brush;
469 brush.SetStyle(wxBRUSHSTYLE_SOLID);
470 brush.SetColour(cl);
471 dc->SetBrush(brush);
472
473 /* this is fix for a +/-180� round instrument, when m_MainValue is supplied as
474 * <0..180><L | R> for example TWA & AWA */
475 double data;
476 if (m_main_value_unit == "\u00B0L")
477 data = 360 - m_main_value;
478 else
479 data = m_main_value;
480
481 // The arrow should stay inside fixed limits
482 double val;
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;
487 else
488 val = data;
489
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);
493
494 wxPoint points[4];
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);
504}
505
506/* Shared functions */
507void DrawCompassRose(wxGCDC* dc, int cx, int cy, int radius, int startangle,
508 bool showlabels, InstrumentProperties* Properties) {
509 wxPoint pt, points[3];
510 wxString Value;
511 int width, height;
512 wxString CompassArray[] = {_("N"), _("NE"), _("E"), _("SE"), _("S"),
513 _("SW"), _("W"), _("NW"), _("N")};
514 if (Properties)
515 dc->SetFont((Properties->m_SmallFont.GetChosenFont()));
516 else
517 dc->SetFont((g_pFontSmall->GetChosenFont()));
518
519 wxColour cl;
520 wxPen* pen;
521 GetGlobalColor("DASH2", &cl);
522 pen = wxThePenList->FindOrCreatePen(cl, 1, wxPENSTYLE_SOLID);
523 wxBrush* b2 = wxTheBrushList->FindOrCreateBrush(cl);
524
525 GetGlobalColor("DASH1", &cl);
526 wxBrush* b1 = wxTheBrushList->FindOrCreateBrush(cl);
527
528 dc->SetPen(*pen);
529 dc->SetTextForeground(cl);
530 dc->SetBrush(*b2);
531
532 int offset = 0;
533 wxFont f;
534 for (double tmpangle = startangle - ANGLE_OFFSET;
535 tmpangle < startangle + 360 - ANGLE_OFFSET; tmpangle += 90) {
536 if (showlabels) {
537 Value = CompassArray[offset];
538 if (Properties) {
539 f = Properties->m_SmallFont.GetChosenFont();
540 dc->GetTextExtent(Value, &width, &height, nullptr, nullptr, &f);
541 } else {
542 f = g_pFontSmall->GetChosenFont();
543 dc->GetTextExtent(Value, &width, &height, nullptr, nullptr, &f);
544 }
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];
551 if (Properties) {
552 f = Properties->m_SmallFont.GetChosenFont();
553 dc->GetTextExtent(Value, &width, &height, nullptr, nullptr, &f);
554 } else {
555 f = g_pFontSmall->GetChosenFont();
556 dc->GetTextExtent(Value, &width, &height, nullptr, nullptr, &f);
557 }
558 x = width / 2;
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);
563 }
564 points[0].x = cx;
565 points[0].y = cy;
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));
573 dc->SetBrush(*b1);
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));
582 dc->SetBrush(*b2);
583 dc->DrawPolygon(3, points, 0, 0);
584 offset += 2;
585 }
586}
587
588void DrawBoat(wxGCDC* dc, int cx, int cy, int radius) {
589 // Now draw the boat
590 wxColour cl;
591 GetGlobalColor("DASH2", &cl);
592 wxPen* pen = wxThePenList->FindOrCreatePen(cl, 1, wxPENSTYLE_SOLID);
593 dc->SetPen(*pen);
594 GetGlobalColor("DASH1", &cl);
595 dc->SetBrush(cl);
596 wxPoint points[7];
597
598 /*
599 * 0
600 * /\
601 * / \
602 * / \
603 * 6 / \ 1
604 * | |
605 * | X |
606 * 5 | | 2
607 * \ /
608 * \__ _/
609 * 4 3
610 */
611 points[0].x = cx;
612 points[0].y = cy - radius * .60; // a little bit longer than compass rose
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;
625
626 dc->DrawPolygon(7, points, 0, 0);
627}
Dashboard dial instrument.
DASH_CAP
Definition instrument.h:77