void GaugeVario::RenderBugs(Canvas &canvas) { static int last_bugs = -1; static PixelRect label_rect = {-1,-1,-1,-1}; static PixelRect value_rect = {-1,-1,-1,-1}; static RasterPoint label_pos = {-1,-1}; static RasterPoint value_pos = {-1,-1}; if (!bugs_initialised) { const PixelRect rc = GetClientRect(); PixelSize tSize; label_pos.x = 1; label_pos.y = rc.bottom - 2 - look.text_font->GetCapitalHeight() - look.text_font->GetAscentHeight(); value_pos.x = 1; value_pos.y = rc.bottom - 1 - look.text_font->GetAscentHeight(); label_rect.left = label_pos.x; label_rect.top = label_pos.y + look.text_font->GetAscentHeight() - look.text_font->GetCapitalHeight(); value_rect.left = value_pos.x; value_rect.top = value_pos.y + look.text_font->GetAscentHeight() - look.text_font->GetCapitalHeight(); canvas.Select(*look.text_font); tSize = canvas.CalcTextSize(TEXT_BUG); label_rect.right = label_rect.left + tSize.cx; label_rect.bottom = label_rect.top + look.text_font->GetCapitalHeight() + look.text_font->GetHeight() - look.text_font->GetAscentHeight(); tSize = canvas.CalcTextSize(_T("100%")); value_rect.right = value_rect.left + tSize.cx; value_rect.bottom = value_rect.top + look.text_font->GetCapitalHeight(); bugs_initialised = true; } int bugs = iround((fixed(1) - GetComputerSettings().polar.bugs) * 100); if (!IsPersistent() || bugs != last_bugs) { canvas.Select(*look.text_font); if (IsPersistent()) canvas.SetBackgroundColor(look.background_color); else canvas.SetBackgroundTransparent(); if (IsPersistent() || last_bugs < 1 || bugs < 1) { if (bugs > 0) { canvas.SetTextColor(look.dimmed_text_color); if (IsPersistent()) canvas.DrawOpaqueText(label_pos.x, label_pos.y, label_rect, TEXT_BUG); else canvas.DrawText(label_pos.x, label_pos.y, TEXT_BUG); } else if (IsPersistent()) canvas.DrawFilledRectangle(label_rect, look.background_color); } if (bugs > 0) { TCHAR buffer[18]; _stprintf(buffer, _T("%d%%"), bugs); canvas.SetTextColor(look.text_color); if (IsPersistent()) canvas.DrawOpaqueText(value_pos.x, value_pos.y, value_rect, buffer); else canvas.DrawText(value_pos.x, value_pos.y, buffer); } else if (IsPersistent()) canvas.DrawFilledRectangle(value_rect, look.background_color); if (IsPersistent()) last_bugs = bugs; } }
void GaugeVario::RenderBallast(Canvas &canvas) { static int last_ballast = -1; static PixelRect label_rect = {-1,-1,-1,-1}; static PixelRect value_rect = {-1,-1,-1,-1}; static RasterPoint label_pos = {-1,-1}; static RasterPoint value_pos = {-1,-1}; if (!ballast_initialised) { // ontime init, origin and background rect const PixelRect rc = GetClientRect(); PixelSize tSize; // position of ballast label label_pos.x = 1; label_pos.y = rc.top + 2 + look.text_font->GetCapitalHeight() * 2 - look.text_font->GetAscentHeight(); // position of ballast value value_pos.x = 1; value_pos.y = rc.top + 1 + look.text_font->GetCapitalHeight() - look.text_font->GetAscentHeight(); // set upper left corner label_rect.left = label_pos.x; label_rect.top = label_pos.y + look.text_font->GetAscentHeight() - look.text_font->GetCapitalHeight(); // set upper left corner value_rect.left = value_pos.x; value_rect.top = value_pos.y + look.text_font->GetAscentHeight() - look.text_font->GetCapitalHeight(); // get max label size canvas.Select(*look.text_font); tSize = canvas.CalcTextSize(TEXT_BALLAST); // update back rect with max label size label_rect.right = label_rect.left + tSize.cx; label_rect.bottom = label_rect.top + look.text_font->GetCapitalHeight(); // get max value size tSize = canvas.CalcTextSize(_T("100%")); value_rect.right = value_rect.left + tSize.cx; // update back rect with max label size value_rect.bottom = value_rect.top + look.text_font->GetCapitalHeight(); ballast_initialised = true; } int ballast = iround(GetGlidePolar().GetBallast() * 100); if (!IsPersistent() || ballast != last_ballast) { // ballast hase been changed canvas.Select(*look.text_font); if (IsPersistent()) canvas.SetBackgroundColor(look.background_color); else canvas.SetBackgroundTransparent(); if (IsPersistent() || last_ballast < 1 || ballast < 1) { // new ballast is 0, hide label if (ballast > 0) { canvas.SetTextColor(look.dimmed_text_color); // ols ballast was 0, show label if (IsPersistent()) canvas.DrawOpaqueText(label_pos.x, label_pos.y, label_rect, TEXT_BALLAST); else canvas.DrawText(label_pos.x, label_pos.y, TEXT_BALLAST); } else if (IsPersistent()) canvas.DrawFilledRectangle(label_rect, look.background_color); } // new ballast 0, hide value if (ballast > 0) { TCHAR buffer[18]; _stprintf(buffer, _T("%u%%"), ballast); canvas.SetTextColor(look.text_color); if (IsPersistent()) canvas.DrawOpaqueText(value_pos.x, value_pos.y, value_rect, buffer); else canvas.DrawText(value_pos.x, value_pos.y, buffer); } else if (IsPersistent()) canvas.DrawFilledRectangle(value_rect, look.background_color); if (IsPersistent()) last_ballast = ballast; } }
// TODO code: Optimise vario rendering, this is slow void GaugeVario::RenderValue(Canvas &canvas, int x, int y, DrawInfo *value_info, DrawInfo *label_info, fixed value, const TCHAR *label) { PixelSize tsize; #ifndef FIXED_MATH value = (double)iround(value * 10) / 10; // prevent the -0.0 case #endif if (!value_info->initialised) { value_info->rc.right = x - Layout::Scale(5); value_info->rc.top = y + Layout::Scale(3) + look.text_font->GetCapitalHeight(); value_info->rc.left = value_info->rc.right; // update back rect with max label size value_info->rc.bottom = value_info->rc.top + look.value_font->GetCapitalHeight(); value_info->text_position.x = value_info->rc.left; value_info->text_position.y = value_info->rc.top + look.value_font->GetCapitalHeight() - look.value_font->GetAscentHeight(); value_info->last_value = fixed(-9999); value_info->last_text[0] = '\0'; value_info->last_unit = Unit::UNDEFINED; value_info->initialised = true; } if (!label_info->initialised) { label_info->rc.right = x; label_info->rc.top = y + Layout::Scale(1); label_info->rc.left = label_info->rc.right; // update back rect with max label size label_info->rc.bottom = label_info->rc.top + look.text_font->GetCapitalHeight(); label_info->text_position.x = label_info->rc.left; label_info->text_position.y = label_info->rc.top + look.text_font->GetCapitalHeight() - look.text_font->GetAscentHeight(); label_info->last_value = fixed(-9999); label_info->last_text[0] = '\0'; label_info->initialised = true; } canvas.SetBackgroundTransparent(); if (!IsPersistent() || (dirty && !StringIsEqual(label_info->last_text, label))) { canvas.SetTextColor(look.dimmed_text_color); canvas.Select(*look.text_font); tsize = canvas.CalcTextSize(label); label_info->text_position.x = label_info->rc.right - tsize.cx; if (IsPersistent()) { canvas.SetBackgroundColor(look.background_color); canvas.DrawOpaqueText(label_info->text_position.x, label_info->text_position.y, label_info->rc, label); label_info->rc.left = label_info->text_position.x; _tcscpy(label_info->last_text, label); } else { canvas.DrawText(label_info->text_position.x, label_info->text_position.y, label); } } if (!IsPersistent() || (dirty && value_info->last_value != value)) { TCHAR buffer[18]; canvas.SetBackgroundColor(look.background_color); canvas.SetTextColor(look.text_color); _stprintf(buffer, _T("%.1f"), (double)value); canvas.Select(*look.value_font); tsize = canvas.CalcTextSize(buffer); value_info->text_position.x = value_info->rc.right - tsize.cx; if (IsPersistent()) { canvas.DrawOpaqueText(value_info->text_position.x, value_info->text_position.y, value_info->rc, buffer); value_info->rc.left = value_info->text_position.x; value_info->last_value = value; } else { canvas.DrawText(value_info->text_position.x, value_info->text_position.y, buffer); } } if (!IsPersistent() || value_info->last_unit != Units::current.vertical_speed_unit) { value_info->last_unit = Units::current.vertical_speed_unit; const UnitSymbol *unit_symbol = units_look.GetSymbol(value_info->last_unit); unit_symbol->Draw(canvas, x - Layout::Scale(5), value_info->rc.top, look.background_color, COLOR_GRAY); } }
void DigitEntry::OnPaint(Canvas &canvas) { assert(cursor < length); const bool focused = HasCursorKeys() && HasFocus(); if (HaveClipping()) canvas.Clear(look.background_color); canvas.Select(look.text_font); canvas.SetBackgroundOpaque(); const unsigned text_height = look.text_font.GetHeight(); const int y = (top + bottom - text_height) / 2; PixelRect rc; rc.top = top; rc.bottom = bottom; TCHAR buffer[4]; for (unsigned i = 0; i < length; ++i) { const Column &c = columns[i]; rc.left = c.left; rc.right = c.right; if (focused && i == cursor) { canvas.SetTextColor(look.list.focused.text_color); canvas.SetBackgroundColor(look.list.focused.background_color); } else if (c.IsEditable()) { canvas.SetTextColor(look.list.text_color); canvas.SetBackgroundColor(look.list.background_color); } else { canvas.SetTextColor(look.list.text_color); canvas.SetBackgroundColor(look.background_color); } const TCHAR *text = buffer; buffer[1] = _T('\0'); switch (c.type) { case Column::Type::DIGIT: case Column::Type::DIGIT6: assert(c.value < 10); buffer[0] = _T('0') + c.value; break; case Column::Type::HOUR: assert(c.value < 24); _stprintf(buffer, _T("%02u"), c.value); break; case Column::Type::DIGIT36: assert(c.value < 36); _stprintf(buffer, _T("%02u"), c.value); break; case Column::Type::DIGIT19: assert(c.value < 19); _stprintf(buffer, _T("%02u"), c.value); break; case Column::Type::SIGN: buffer[0] = c.IsNegative() ? _T('-') : _T('+'); break; case Column::Type::DECIMAL_POINT: buffer[0] = _T('.'); break; case Column::Type::COLON: buffer[0] = _T(':'); break; case Column::Type::NORTH_SOUTH: buffer[0] = c.IsNegative() ? _T('S') : _T('N'); break; case Column::Type::EAST_WEST: buffer[0] = c.IsNegative() ? _T('W') : _T('E'); break; case Column::Type::DEGREES: text = _T("°"); break; case Column::Type::APOSTROPHE: text = _T("'"); break; case Column::Type::QUOTE: text = _T("\""); break; case Column::Type::UNIT: // TODO: render unit symbol? text = Units::unit_descriptors[c.value].name; break; } if (c.IsEditable() && !valid) buffer[0] = _T('\0'); const int x = (c.left + c.right - canvas.CalcTextWidth(text)) / 2; canvas.DrawOpaqueText(x, y, rc, text); } canvas.SetBackgroundTransparent(); canvas.SetTextColor(look.text_color); unsigned control_height = Layout::GetMaximumControlHeight(); PixelRect plus_rc(0, top - control_height, 0, top); PixelRect minus_rc(0, bottom, 0, bottom + control_height); for (unsigned i = 0; i < length; ++i) { const Column &c = columns[i]; if (!c.IsEditable()) continue; plus_rc.left = minus_rc.left = c.left; plus_rc.right = minus_rc.right = c.right; button_renderer.DrawButton(canvas, plus_rc, false, false); button_renderer.DrawButton(canvas, minus_rc, false, false); canvas.SelectNullPen(); canvas.Select(look.button.standard.foreground_brush); SymbolRenderer::DrawArrow(canvas, plus_rc, SymbolRenderer::UP); SymbolRenderer::DrawArrow(canvas, minus_rc, SymbolRenderer::DOWN); } }
void WndForm::OnPaint(Canvas &canvas) { const SingleWindow &main_window = GetMainWindow(); gcc_unused const bool is_active = main_window.IsTopDialog(*this); #ifdef ENABLE_OPENGL if (!IsDithered() && !IsMaximised() && is_active) { /* draw a shade around the current dialog to emphasise it */ const ScopeAlphaBlend alpha_blend; const PixelRect rc = GetClientRect(); const PixelScalar size = Layout::VptScale(4); const RasterPoint vertices[8] = { { rc.left, rc.top }, { rc.right, rc.top }, { rc.right, rc.bottom }, { rc.left, rc.bottom }, { rc.left - size, rc.top - size }, { rc.right + size, rc.top - size }, { rc.right + size, rc.bottom + size }, { rc.left - size, rc.bottom + size }, }; const ScopeVertexPointer vp(vertices); static constexpr Color inner_color = COLOR_BLACK.WithAlpha(192); static constexpr Color outer_color = COLOR_BLACK.WithAlpha(16); static constexpr Color colors[8] = { inner_color, inner_color, inner_color, inner_color, outer_color, outer_color, outer_color, outer_color, }; const ScopeColorPointer cp(colors); static constexpr GLubyte indices[] = { 0, 4, 1, 4, 5, 1, 1, 5, 2, 5, 6, 2, 2, 6, 3, 6, 7, 3, 3, 7, 0, 7, 4, 0, }; glDrawElements(GL_TRIANGLES, ARRAY_SIZE(indices), GL_UNSIGNED_BYTE, indices); } #endif ContainerWindow::OnPaint(canvas); // Get window coordinates PixelRect rcClient = GetClientRect(); // Draw the borders if (!IsMaximised()) { #ifndef USE_GDI if (IsDithered()) canvas.DrawOutlineRectangle(rcClient.left, rcClient.top, rcClient.right - 1, rcClient.bottom - 1, COLOR_BLACK); else #endif canvas.DrawRaisedEdge(rcClient); } if (!caption.empty()) { // Set the colors canvas.SetTextColor(COLOR_WHITE); // Set the titlebar font and font-size canvas.Select(*look.caption.font); // JMW todo add here icons? #ifdef EYE_CANDY if (!IsDithered() && is_active) { canvas.SetBackgroundTransparent(); canvas.Stretch(title_rect.left, title_rect.top, title_rect.right - title_rect.left, title_rect.bottom - title_rect.top, look.caption.background_bitmap); // Draw titlebar text canvas.DrawText(title_rect.left + Layout::GetTextPadding(), title_rect.top, caption.c_str()); } else { #endif canvas.SetBackgroundColor(is_active ? look.caption.background_color : look.caption.inactive_background_color); canvas.DrawOpaqueText(title_rect.left + Layout::GetTextPadding(), title_rect.top, title_rect, caption.c_str()); #ifdef EYE_CANDY } #endif } if (dragging) { #ifdef ENABLE_OPENGL const ScopeAlphaBlend alpha_blend; canvas.DrawFilledRectangle(0, 0, canvas.GetWidth(), canvas.GetHeight(), COLOR_YELLOW.WithAlpha(80)); #elif defined(USE_GDI) canvas.InvertRectangle(title_rect); #else canvas.InvertRectangle(GetClientRect()); #endif } }
void WndForm::OnPaint(Canvas &canvas) { const SingleWindow &main_window = GetMainWindow(); gcc_unused const bool is_active = main_window.IsTopDialog(*this); #ifdef ENABLE_OPENGL if (!IsMaximised() && is_active) { /* draw a shade around the current dialog to emphasise it */ GLEnable blend(GL_BLEND); glEnableClientState(GL_COLOR_ARRAY); const PixelRect rc = GetClientRect(); const PixelScalar size = Layout::SmallScale(4); const RasterPoint vertices[8] = { { rc.left, rc.top }, { rc.right, rc.top }, { rc.right, rc.bottom }, { rc.left, rc.bottom }, { rc.left - size, rc.top - size }, { rc.right + size, rc.top - size }, { rc.right + size, rc.bottom + size }, { rc.left - size, rc.bottom + size }, }; glVertexPointer(2, GL_VALUE, 0, vertices); static constexpr Color inner_color = COLOR_BLACK.WithAlpha(192); static constexpr Color outer_color = COLOR_BLACK.WithAlpha(16); static constexpr Color colors[8] = { inner_color, inner_color, inner_color, inner_color, outer_color, outer_color, outer_color, outer_color, }; #ifdef HAVE_GLES glColorPointer(4, GL_FIXED, 0, colors); #else glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors); #endif static constexpr GLubyte indices[] = { 0, 4, 1, 4, 5, 1, 1, 5, 2, 5, 6, 2, 2, 6, 3, 6, 7, 3, 3, 7, 0, 7, 4, 0, }; glDrawElements(GL_TRIANGLES, ARRAY_SIZE(indices), GL_UNSIGNED_BYTE, indices); glDisableClientState(GL_COLOR_ARRAY); } #endif ContainerWindow::OnPaint(canvas); // Get window coordinates PixelRect rcClient = GetClientRect(); // Draw the borders canvas.DrawRaisedEdge(rcClient); if (!caption.empty()) { // Set the colors canvas.SetTextColor(COLOR_WHITE); // Set the titlebar font and font-size canvas.Select(*look.caption.font); // JMW todo add here icons? #ifdef EYE_CANDY canvas.SetBackgroundTransparent(); canvas.Stretch(title_rect.left, title_rect.top, title_rect.right - title_rect.left, title_rect.bottom - title_rect.top, look.caption.background_bitmap); // Draw titlebar text canvas.DrawText(title_rect.left + Layout::FastScale(2), title_rect.top, caption.c_str()); #else canvas.SetBackgroundColor(is_active ? look.caption.background_color : look.caption.inactive_background_color); canvas.DrawOpaqueText(title_rect.left + Layout::FastScale(2), title_rect.top, title_rect, caption.c_str()); #endif } if (dragging) { #ifdef ENABLE_OPENGL GLEnable blend(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); canvas.DrawFilledRectangle(0, 0, canvas.GetWidth(), canvas.GetHeight(), COLOR_YELLOW.WithAlpha(80)); #elif defined(USE_GDI) ::InvertRect(canvas, &title_rect); #endif } }