void ItemAttributeMgr::SetRealEx(Attr attr, const real_t &v, bool persist) { // first check if it can be stored as integer if(_IsInt(v)) { // store as integer SetIntEx(attr, static_cast<int32>(v), persist); } else { // store as real PyRep *oldValue = NULL; if(GetNotify() == true && !IsRechargable(attr)) { // get old value oldValue = PyGet(attr); } // set the attribute value EVEAdvancedAttributeMgr::SetReal(attr, v); // check if we shall save to DB if(GetSave() == true && (persist || IsPersistent(attr))) { // save to DB m_factory.db().UpdateAttribute_double(m_item.itemID(), attr, v); } if(GetNotify() == true) { std::map<Attr, TauCap>::const_iterator i = m_tauCap.find(attr); if(i != m_tauCap.end()) { // build the special list for rechargables PyList *l = new PyList; l->AddItemReal( v ); l->AddItemLong( Win32TimeNow() ); l->AddItem( _PyGet( GetReal( i->second.tau ) / 5.0 ) ); l->AddItem( PyGet( i->second.cap ) ); oldValue = l; } // send change _SendAttributeChange(attr, oldValue, new PyFloat(v)); } } }
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::OnPaintBuffer(Canvas &canvas) { const PixelRect rc = GetClientRect(); const unsigned width = rc.right - rc.left; const unsigned height = rc.bottom - rc.top; if (!IsPersistent() || !layout_initialised) { unsigned value_height = 4 + look.value_font->GetCapitalHeight() + look.text_font->GetCapitalHeight(); middle_position.y = offset.y - value_height / 2; middle_position.x = rc.right; top_position.y = middle_position.y - value_height; top_position.x = rc.right; bottom_position.y = middle_position.y + value_height; bottom_position.x = rc.right; canvas.Stretch(rc.left, rc.top, width, height, look.background_bitmap, look.background_x, 0, 58, 120); layout_initialised = true; } if (Settings().show_average) { // JMW averager now displays netto average if not circling if (!Calculated().circling) { RenderValue(canvas, top_position.x, top_position.y, &value_top, &label_top, Units::ToUserVSpeed(Calculated().netto_average), _T("NetAvg")); } else { RenderValue(canvas, top_position.x, top_position.y, &value_top, &label_top, Units::ToUserVSpeed(Calculated().average), _T("Avg")); } } if (Settings().show_mc) { fixed mc = Units::ToUserVSpeed(GetGlidePolar().GetMC()); RenderValue(canvas, bottom_position.x, bottom_position.y, &value_bottom, &label_bottom, mc, GetComputerSettings().task.auto_mc ? _T("Auto MC") : _T("MC")); } if (Settings().show_speed_to_fly) RenderSpeedToFly(canvas, rc.right - 11, (rc.top + rc.bottom) / 2); else RenderClimb(canvas); if (Settings().show_ballast) RenderBallast(canvas); if (Settings().show_bugs) RenderBugs(canvas); dirty = false; int ival, sval, ival_av = 0; static int vval_last = 0; static int sval_last = 0; static int ival_last = 0; fixed vval = Basic().brutto_vario; ival = ValueToNeedlePos(fixed(vval)); sval = ValueToNeedlePos(Calculated().sink_rate); if (Settings().show_average_needle) { if (!Calculated().circling) ival_av = ValueToNeedlePos(Calculated().netto_average); else ival_av = ValueToNeedlePos(Calculated().average); } // clear items first if (Settings().show_average_needle) { if (!IsPersistent() || ival_av != ival_last) RenderNeedle(canvas, ival_last, true, true); ival_last = ival_av; } if (!IsPersistent() || (sval != sval_last) || (ival != vval_last)) RenderVarioLine(canvas, vval_last, sval_last, true); sval_last = sval; if (!IsPersistent() || ival != vval_last) RenderNeedle(canvas, vval_last, false, true); vval_last = ival; // now draw items RenderVarioLine(canvas, ival, sval, false); if (Settings().show_average_needle) RenderNeedle(canvas, ival_av, true, false); RenderNeedle(canvas, ival, false, false); if (Settings().show_gross) { fixed vvaldisplay = Clamp(Units::ToUserVSpeed(vval), fixed(-99.9), fixed(99.9)); RenderValue(canvas, middle_position.x, middle_position.y, &value_middle, &label_middle, vvaldisplay, _T("Gross")); } RenderZero(canvas); }
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; } }
void GaugeVario::RenderSpeedToFly(Canvas &canvas, int x, int y) { if (!Basic().airspeed_available || !Basic().total_energy_vario_available) return; static fixed last_v_diff; fixed v_diff; const unsigned arrow_y_size = Layout::Scale(3); const unsigned arrow_x_size = Layout::Scale(7); const PixelRect rc = GetClientRect(); int nary = NARROWS * arrow_y_size; int ytop = rc.top + YOFFSET + nary; // JMW int ybottom = rc.bottom - YOFFSET - nary - Layout::FastScale(1); ytop += Layout::Scale(14); ybottom -= Layout::Scale(14); x = rc.right - 2 * arrow_x_size; // only draw speed command if flying and vario is not circling if ((Calculated().flight.flying) && (!Basic().gps.simulator || !Calculated().circling)) { v_diff = Calculated().V_stf - Basic().indicated_airspeed; v_diff = Clamp(v_diff, -DELTA_V_LIMIT, DELTA_V_LIMIT); // limit it v_diff = iround(v_diff/DELTA_V_STEP) * DELTA_V_STEP; } else v_diff = fixed(0); if (!IsPersistent() || last_v_diff != v_diff || dirty) { last_v_diff = v_diff; if (IsPersistent()) { // bottom (too slow) canvas.DrawFilledRectangle(x, ybottom + YOFFSET, x + arrow_x_size * 2 + 1, ybottom + YOFFSET + nary + arrow_y_size + Layout::FastScale(2), look.background_color); // top (too fast) canvas.DrawFilledRectangle(x, ytop - YOFFSET + 1, x + arrow_x_size * 2 +1, ytop - YOFFSET - nary + 1 - arrow_y_size - Layout::FastScale(2), look.background_color); } RenderClimb(canvas); canvas.SelectNullPen(); if (look.colors) { if (positive(v_diff)) { // too slow canvas.Select(look.sink_brush); } else { canvas.Select(look.lift_brush); } } else { if (look.inverse) canvas.SelectWhiteBrush(); else canvas.SelectBlackBrush(); } if (positive(v_diff)) { // too slow y = ybottom; y += YOFFSET; while (positive(v_diff)) { if (v_diff > DELTA_V_STEP) { canvas.Rectangle(x, y, x + arrow_x_size * 2 + 1, y + arrow_y_size - 1); } else { RasterPoint arrow[3]; arrow[0].x = x; arrow[0].y = y; arrow[1].x = x + arrow_x_size; arrow[1].y = y + arrow_y_size - 1; arrow[2].x = x + 2 * arrow_x_size; arrow[2].y = y; canvas.DrawTriangleFan(arrow, 3); } v_diff -= DELTA_V_STEP; y += arrow_y_size; } } else if (negative(v_diff)) { // too fast y = ytop; y -= YOFFSET; while (negative(v_diff)) { if (v_diff < -DELTA_V_STEP) { canvas.Rectangle(x, y + 1, x + arrow_x_size * 2 + 1, y - arrow_y_size + 2); } else { RasterPoint arrow[3]; arrow[0].x = x; arrow[0].y = y; arrow[1].x = x + arrow_x_size; arrow[1].y = y - arrow_y_size + 1; arrow[2].x = x + 2 * arrow_x_size; arrow[2].y = y; canvas.DrawTriangleFan(arrow, 3); } v_diff += DELTA_V_STEP; y -= arrow_y_size; } } } }
// 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); } }
// --------------------------------------------------------------------------- // From class CAknTreeItem. // Checks whether the item can be removed from the tree when its parent node // is being collapsed. // --------------------------------------------------------------------------- // TBool CAknTreeLeaf::IsRemovableFromCollapsedNode() const { return !( IsMarked() || IsPersistent() ); }