void WAzimuthCircleGlyph::paint(WPainter* painter) { static const size_t LEVEL_1_COUNT = 4; static const size_t LEVEL_2_COUNT = 3; static const size_t LEVEL_3_COUNT = 5; static const double RADIAN = 2 * M_PI; static const double RADIAN_LEVEL_1 = RADIAN / LEVEL_1_COUNT; static const double RADIAN_LEVEL_2 = RADIAN_LEVEL_1 / LEVEL_2_COUNT; static const double RADIAN_LEVEL_3 = RADIAN_LEVEL_2 / LEVEL_3_COUNT; static const double L1 = 30.0; static const double L2 = 20.0; static const double L3 = 10.0; static const double L4 = 0.0; WSizeF size = painter->deviceSize(); const double WIDTH = size.width(); const double HEIGHT = size.height(); const double DIAMETER = std::min(WIDTH, HEIGHT); const double X = (WIDTH - DIAMETER) / 2; const double Y = (HEIGHT - DIAMETER) / 2; const WRectF R1(X + L1, Y + L1, DIAMETER - 2 * L1, DIAMETER - 2 * L1); const WRectF R2(X + L2, Y + L2, DIAMETER - 2* L2, DIAMETER - 2 * L2); const WRectF R3(X + L3, Y + L3, DIAMETER - 2 * L3, DIAMETER - 2 * L3); const WRectF R4(X + L4, Y + L4, DIAMETER - 2* L4, DIAMETER - 2 * L4); WPainterProxy proxy(painter); painter->setWorldTransform(WMatrix()); WBrush brush = painter->brush(); brush.setStyle(Ws::NoBrush); painter->setBrush(brush); painter->setPen(data()->m_pen); painter->setBrush(WBrush(Ws::NoBrush)); painter->drawEllipse(R4); for (size_t i = 0; i < LEVEL_1_COUNT; ++i) { double radian_1 = i * RADIAN_LEVEL_1; painter->drawText(point_on_ellipse(R4, radian_1), boost::lexical_cast<std::string>(world_to_clockwise(radian_1)) + char(0xb0)); painter->drawLine(WLineF(point_on_ellipse(R4, radian_1), point_on_ellipse(R1, radian_1))); for (size_t j = 0; j < LEVEL_2_COUNT; ++j) { double radian_2 = radian_1 + j * RADIAN_LEVEL_2; painter->drawLine(WLineF(point_on_ellipse(R4, radian_2), point_on_ellipse(R2, radian_2))); for (size_t k = 0; k < LEVEL_3_COUNT; ++k) { double radian_3 = radian_2 + k * RADIAN_LEVEL_3; painter->drawLine(WLineF(point_on_ellipse(R4, radian_3), point_on_ellipse(R3, radian_3))); } } } }
void WPainter::fillRect(const WRectF& rectangle, const WBrush& b) { WBrush oldBrush = WBrush(brush()); WPen oldPen = WPen(pen()); setBrush(b); setPen(NoPen); drawRect(rectangle); setBrush(oldBrush); setPen(oldPen); }
void WPainter::fillPath(const WPainterPath& path, const WBrush& b) { WBrush oldBrush = WBrush(brush()); WPen oldPen = WPen(pen()); setBrush(b); setPen(NoPen); drawPath(path); setBrush(oldBrush); setPen(oldPen); }
void WAzimuthRectGlyph::paint(WPainter* painter) { static const size_t SCALE_COUNT = 20; static const size_t SCALE_COUNT_2 = SCALE_COUNT / 2; static const double SCALE_LENGTH = 30.0; WSizeF size = painter->deviceSize(); const double WIDTH = size.width(); const double HEIGHT = size.height(); const double CELL_WIDTH = WIDTH / SCALE_COUNT; const double CELL_HEIGHT = HEIGHT / SCALE_COUNT; const WPointF C(WIDTH / 2.0, HEIGHT / 2.0); WPainterProxy proxy(painter); painter->setWorldTransform(WMatrix()); painter->setPen(data()->m_pen); painter->setBrush(WBrush(Ws::NoBrush)); painter->drawRect(WRectF(1.0, 1.0, WIDTH - 2.0, HEIGHT - 2.0)); WPointF pts[4]; pts[0].ry() = 0.0; pts[1].rx() = WIDTH; pts[2].ry() = HEIGHT; pts[3].rx() = 0.0; for (size_t i = 0; i < SCALE_COUNT; ++i) { pts[0].rx() = CELL_WIDTH * i; pts[1].ry() = CELL_HEIGHT * i; pts[2].rx() = pts[0].x(); pts[3].ry() = pts[1].y(); bool drawAngle = (i == SCALE_COUNT_2); size_t count = 0; BOOST_FOREACH(const WPointF& p, pts) { WLineF line(p, C); line.setLength(SCALE_LENGTH); painter->drawLine(line); if (drawAngle) { painter->drawText(line.p2(), boost::lexical_cast<std::string>(90 * (count++)) + char(0xb0)); } } }
void WRunwayGlyph::paint(WPainter* painter) { data_type& d = *data(); WPointF c = d.m_line.center(); double w = d.m_size.width(); //double h = d.m_size.height(); double h = d.m_line.length(); d.m_dProlongLength = h / 2; WPainterProxy proxy(painter); painter->setPen(d.m_pen); painter->setBrush(WBrush(Ws::NoBrush)); painter->setWorldTransform(WMatrix().translate(c).rotate(90 - d.m_angle).translate(-c), true); painter->drawRect(WRectF(c.x() - h / 2, c.y() - w / 2, h, w)); if (data()->m_bShowProlong) { WPointF s(c.x() + h / 2, c.y()); //line start point WLineF line(s, WPointF(s.x() + data()->m_dProlongLength, s.y())); painter->drawLine(line); const size_t scaleCount = data()->m_genericScaleCount * data()->m_detailScaleCount; const double genericScaleLength = data()->m_dProlongLength / 20.0; const double detailScaleLength = data()->m_dProlongLength / 40.0; const double scaleDistance = data()->m_dProlongLength / scaleCount; for (size_t i = 1; i < scaleCount + 1; ++i) { WPointF p(s.x() + i * scaleDistance, s.y()); WPointF p1(p); WPointF p2(p); const double& scaleLength = (i % data()->m_detailScaleCount == 0 ? genericScaleLength : detailScaleLength); p1.ry() -= scaleLength; p2.ry() += scaleLength; painter->drawLine(WLineF(p1, p2)); } } }
void WArcCreator::mousePressEvent(WGraphicsSceneMouseEvent* event) { if (event->button() == Ws::RightButton) { if (_item) { scene()->currentLayer()->removeItem(_item, true); scene()->currentLayer()->removeItem(_helperItem, true); } emit finished(0); clear(); } else if (event->button() == Ws::LeftButton) { WWorldPointF pos = event->scenePos(); if (_step == 0) { WWorldRectF rect(pos.x()-20, pos.y(), 20, 20); _item = scene()->currentLayer()->addArc(rect, 30, 150, WCreatorSettings::instance().pen(), true); _helperItem = scene()->currentLayer()->addRect(rect, 0.0, WPen(Ws::DashLine, WColor(0, 0, 255), 1.0), WBrush(), true); emit geometry(cell_format(*_item)); emit tip("move mouse and release left button to select rectangle's bottom right point or press right button to cancel"); ++_step; } } }
WBrush transform(const QBrush& brush) { return WBrush(transform(brush.color()), static_cast<Ws::BrushStyle>(brush.style())); }
void WLegend3D::renderLegend(WPainter* painter, const std::vector<WAbstractDataSeries3D*> &dataseries) { if (!legendEnabled_) return; painter->save(); int nbItems = 0; for (unsigned i = 0; i < dataseries.size(); i++) { WAbstractDataSeries3D *series = dataseries[i]; if (series->isLegendEnabled() && !series->isHidden()) nbItems++; } double textHeight = legendFont_.sizeLength().toPixels(); double labelWidth = textHeight * 0.618; double lineHeight = textHeight * 1.5; double offset = (lineHeight-textHeight)/2; painter->setPen(legendBorder_); painter->setFont(legendFont_); painter->setBrush(legendBackground_); int nbRows = nbItems/legendColumns_; if (nbItems % legendColumns_) nbRows++; painter->drawRect(0, 0, legendColumns_*legendColumnWidth_.value() + 2*boxPadding, nbRows*lineHeight + 2*boxPadding); painter->translate(boxPadding, boxPadding); int count = 0; for (unsigned i = 0; i < dataseries.size(); i++) { WAbstractDataSeries3D *series = dataseries[i]; if (!series->isLegendEnabled() || series->isHidden()) continue; count++; // paint icon if (series->colorMap() == 0) { // if chartpalette WColor seriesColor = series->chartpaletteColor(); painter->fillRect(0, offset, labelWidth, textHeight, WBrush(seriesColor)); } else { // else colormap series->colorMap()->createStrip(painter, WRectF(0, offset, labelWidth, textHeight)); } // draw label painter->drawText( labelWidth + 10, 0, 100, lineHeight, AlignLeft | AlignMiddle, series->title() ); // offset painter if (count == legendColumns_) { painter->translate(-(legendColumns_-1)*legendColumnWidth_.value(), lineHeight); count = 0; } else { painter->translate(legendColumnWidth_.value(), 0); } } painter->restore(); }
void WAircraftGlyph::paint(WPainter* painter) { data_type& d = *data(); painter->setBrush(WBrush(Ws::NoBrush)); m_cd.aircraftMatrix = painter->worldTransform(); m_cd.labelMatrix_1 = m_cd.aircraftMatrix.inverted(); const WMatrix& mapToView = m_cd.aircraftMatrix; painter->setWorldTransform(WMatrix()); WColor symbolColor = d.m_SymbolColor; WPointF view_aircraft_pos_f = mapToView.map(d.m_pos); static const double R = 10.0; static const double RS = 15.0; //draw a bigger circle around, when aircraft is selected double x = view_aircraft_pos_f.x(); double y = view_aircraft_pos_f.y(); if (d.m_eSymbolType == SYMBOL_COMBINED/*AIRCRAFT_NOR*/) { painter->setPen(WPen(symbolColor)); if (isSelected()) { painter->drawEllipse(WRectF(x - RS, y - RS, RS * 2, RS * 2)); } //tmp painter->drawEllipse(WRectF(x - R, y - R, R * 2, R * 2)); painter->drawLine(WLineF(x - R, y, x + R, y)); painter->drawLine(WLineF(x, y - R, x, y + R)); //DrawAircraft(painter, view_aircraft_pos); } else if (d.m_eSymbolType == SYMBOL_PRIMARY)//一次雷达 { painter->setPen(WPen(symbolColor)); if (isSelected()) { painter->drawEllipse(WRectF(x - RS, y - RS, RS * 2, RS * 2)); } painter->drawLine(WLineF(x - R, y, x + R, y)); painter->drawLine(WLineF(x, y - R, x, y + R)); } else if (d.m_eSymbolType == SYMBOL_SECONDARY)//二次雷达 { painter->setPen(WPen(symbolColor)); if (isSelected()) { painter->drawEllipse(WRectF(x - RS, y - RS, RS * 2, RS * 2)); } painter->drawEllipse(WRectF(x - R, y - R, R * 2, R * 2)); } else if (d.m_eSymbolType == SYMBOL_PLAN)//计划航迹 { painter->setPen(WPen(symbolColor)); if (isSelected()) { painter->drawEllipse(WRectF(x - RS, y - RS, RS * 2, RS * 2)); } painter->drawRect(WRectF(x - R, y - R, R * 2, R * 2)); } else if (d.m_eSymbolType == SYMBOL_COAST)//进入盲区 { painter->setPen(WPen(symbolColor)); if (isSelected()) { painter->drawEllipse(WRectF(x - RS, y - RS, RS * 2, RS * 2)); } WPen pen; pen.setWidth(4); pen.setColor(WColor(255, 255, 255)); painter->setPen(pen); painter->drawLine(WWorldLineF(x - R, y, x - R / 2, y)); painter->drawLine(WWorldLineF(x + R, y, x + R / 2, y)); painter->drawLine(WWorldLineF(x, y - R, x, y - R / 2)); painter->drawLine(WWorldLineF(x, y + R, x, y + R / 2)); pen.setWidth(1); pen.setColor(symbolColor); painter->setPen(pen); } else if (d.m_eSymbolType == SYMBOL_SPI)//处于SPI告警状态 { painter->setPen(WPen(symbolColor)); if (isSelected()) { painter->drawEllipse(WRectF(x - RS, y - RS, RS * 2, RS * 2)); } painter->drawLine(WLineF(x - R, y, x + R, y)); painter->drawLine(WLineF(x, y - R, x, y + R)); WPen pen; pen.setStyle(Ws::DashLine); pen.setColor(WColor(255, 255, 255)); painter->setPen(pen); painter->drawEllipse(WRectF(x - R, y - R, R * 2, R * 2)); pen.setStyle(Ws::SolidLine); pen.setColor(symbolColor); painter->setPen(pen); } else if (d.m_eSymbolType == SYMBOL_VEHICLE)//车辆航迹(实心三角) { painter->setPen(WPen(symbolColor)); painter->setBrush(WBrush(symbolColor, Ws::SolidPattern)); WPointF Tmppoint; std::vector<WPointF> vPoints; Tmppoint.setXY(x, y - 5); vPoints.push_back(Tmppoint); Tmppoint.setXY(x - 5, y + 5); vPoints.push_back(Tmppoint); Tmppoint.setXY(x + 5, y + 5); vPoints.push_back(Tmppoint); painter->drawPolygon(WWorldPolygonF(vPoints)); painter->setBrush(WBrush(Ws::NoBrush)); if (isSelected()) { painter->drawEllipse(WRectF(x - R, y - R, R * 2, R * 2)); } } else if (d.m_eSymbolType == SYMBOL_ADSB) // ADSB暂定符号(参考Indra手册)实心菱形 { painter->setPen(WPen(symbolColor)); painter->setBrush(WBrush(symbolColor, Ws::SolidPattern)); WPointF Tmppoint; std::vector<WPointF> vPoints; Tmppoint.setXY(x, y - 5); vPoints.push_back(Tmppoint); Tmppoint.setXY(x - 5, y); vPoints.push_back(Tmppoint); Tmppoint.setXY(x, y + 5); vPoints.push_back(Tmppoint); Tmppoint.setXY(x + 5, y); vPoints.push_back(Tmppoint); painter->drawPolygon(WWorldPolygonF(vPoints)); painter->setBrush(WBrush(Ws::NoBrush)); if (isSelected()) { painter->drawEllipse(WRectF(x - R, y - R, R * 2, R * 2)); } } else if (d.m_eSymbolType == SYMBOL_PIC_AIRCRAFT || d.m_eSymbolType == SYMBOL_PIC_HELICOPTER) { painter->setPen(WPen(symbolColor)); painter->setBrush(WBrush(symbolColor, Ws::SolidPattern)); painter->setBrush(WBrush(Ws::NoBrush)); painter->setRenderHint(Ws::SmoothPixmapTransform); WPixmap pixmap(d.m_eSymbolType == SYMBOL_PIC_AIRCRAFT ? ":/plane.png" : ":/helicopter.png"); WPixmap newPixmap = pixmap.xrotated(-90 + d.m_nHeading, Ws::SmoothTransformation); painter->drawPixmap(view_aircraft_pos_f-WPointF(newPixmap.width()/2, newPixmap.height()/2), newPixmap); } WLineF line(WPointF(), d.m_boundingRect.center()); if (line.length() > m_sLineMaxLength) { line.setLength(m_sLineMaxLength); WPointF offPoint = line.p2() - d.m_boundingRect.center(); d.m_boundingRect.translate(offPoint); d.m_showRect.translate(offPoint); } WPointF view_label_pos_f = d.m_boundingRect.bottomLeft() + view_aircraft_pos_f;// aircraft pos + label offset pos WPointF offset_f = d.m_showRect.bottomLeft() - d.m_boundingRect.bottomLeft(); WRectF view_label_rect(WRectF(view_label_pos_f, WSizeF(d.m_boundingRect.width(), d.m_boundingRect.height()))); //标牌避让 if (m_sLabelAvoidance) { const WRectF& r = view_label_rect; Mosaic::Instance().Allocate(reinterpret_cast<int>(this), r.left(), r.bottom(), r.right(), r.top()); } // label show rect指标牌边框显示区域,标牌有时候需要显示边框,边框与内容区域可能不一致,如C显示 WRectF label_show_rect(WRectF(view_label_rect.bottomLeft(), WSizeF(d.m_showRect.width(), d.m_showRect.height()))); label_show_rect.translate(offset_f); //show history // 尾迹点访问外部数据,本应该加锁,由于外部默认分配了很大数据存在,且点数据一致增加到默认最大值 // 内部通过下标访问不存在问题 // 如外部数据容器变小,就必须得加锁保护 if (m_sShowHistoryPoint && d.m_vHistory != NULL && d.m_vHistory->size() > 1) { size_t n = d.m_vHistory->size() - 1; size_t count = (m_sHstNum < n) ? m_sHstNum : n; size_t pos = n - 1; for (size_t i = 0; i < count; ++i, --pos) { static const double R = 0.8; double dx = 0.00; double dy = 0.00; mapToView.map((*d.m_vHistory)[pos]->x(), (*d.m_vHistory)[pos]->y(), &dx, &dy); painter->drawEllipse(WRectF(dx - R, dy - R, R * 2, R * 2)); //尾迹点 } } //show preline if (m_sShowPreLine) { painter->drawLine(WLineF(view_aircraft_pos_f, mapToView.map(d.m_PRLPos))); //预计线 } if (d.m_bShowLabel) { //show linkline (内部包含了外一点与一矩形中心点连线只绘制外一点到矩形边框的算法) DrawLabelLine(painter, view_aircraft_pos_f, label_show_rect); WPainterProxy proxy(painter); painter->setRenderHint(Ws::Antialiasing, false); // 绘制矩形的时候去掉反锯齿,效果更好 painter->setRenderHint(Ws::TextAntialiasing, false); if (d.m_bShowBounding) { painter->setPen(d.m_penBounding); // 标牌边框颜色与航迹符号与文本是分开的 painter->drawRect(label_show_rect); } //show label painter->setFont(m_sLabelFont); m_cache_locker.lock(); // 对访问d.m_blocks进行加锁,网络线程在FormatLable的时候会重新组织m_blocks数据,数据需要同步操作 BOOST_FOREACH(const WBlockData& block, m_blocks) { painter->setPen(block.m_penText); WRectF r = block.m_boundingRect.translated(view_label_pos_f); painter->drawText(r, Ws::AlignCenter, block.m_text); }
void WStandardColorMap::paintLegend(WPainter *painter, const WRectF& area) const { painter->save(); WPainterPath clipPath; painter->setRenderHint(WPainter::Antialiasing, false); painter->setFont(labelFont_); int height; if (area.isNull()) { height = (int)painter->device()->height().value(); } else { clipPath.addRect(area); painter->setClipPath(clipPath); painter->setClipping(true); painter->translate(area.x(), area.y()); height = (int)area.height(); } int textHeight = (int)painter->font().sizeLength().toPixels(); // draw the colormap with a box around it int stripWidth = 50; createStrip(painter, WRectF(0, (int)(textHeight/2+0.5), (int)stripWidth, (int)(height-textHeight))); painter->setPen(WPen()); painter->setBrush(WBrush()); painter->drawRect(WRectF(0.5, (int)(textHeight/2) + 0.5, stripWidth, height-textHeight)); // draw the ticks + labels painter->translate(stripWidth, textHeight/2); if (continuous_) { int lineHeights = (int)(height/textHeight); int lhPerTick = 1 + tickSpacing_; int nbTicks = lineHeights % lhPerTick == 0 ? lineHeights/lhPerTick : lineHeights/lhPerTick + 1; int interval = (height-textHeight)/(nbTicks-1); int rest = (height-textHeight) % (nbTicks-1); int adjustedInterval = interval; double value = max_; double valDiff = (max_-min_)/(nbTicks-1); for (int i=0; i < nbTicks; i++) { painter->drawLine(0, 0.5, 4, 0.5); painter->drawText(10, -textHeight/2, 40, textHeight, AlignLeft | AlignMiddle, Wt::asString(value, format_)); value -= valDiff; if (rest > 0) { adjustedInterval = interval + 1; rest--; } else { adjustedInterval = interval; } painter->translate(0, adjustedInterval); } } else { // first paint tick for maximum value painter->drawLine(0, 0.5, 4, 0.5); painter->drawText(10, -textHeight/2, 100, textHeight, AlignLeft | AlignMiddle, Wt::asString(max_, format_)); // paint the rest of the ticks int nbTicks = colors_.size(); int prevDiff = 0; for (int i=nbTicks-1; i >= 0; i--) { double relPos = -(colors_[i].value()-max_)/(max_-min_); double diff = relPos*(height-textHeight); int roundedDiff = (int)(diff + 0.5); painter->translate(0, roundedDiff-prevDiff); painter->drawLine(0, 0.5, 4, 0.5); painter->drawText(10, -textHeight/2, 40, textHeight, AlignLeft | AlignMiddle, Wt::asString(colors_[i].value(), format_)); prevDiff = roundedDiff; } } painter->restore(); }