/*! \brief Replay all recorded painter commands The graphic is scaled to fit into the given rectangle \param painter Qt painter \param rect Rectangle for the scaled graphic \param aspectRatioMode Mode how to scale - See Qt::AspectRatioMode */ void QwtGraphic::render( QPainter *painter, const QRectF &rect, Qt::AspectRatioMode aspectRatioMode ) const { if ( isEmpty() || rect.isEmpty() ) return; double sx = 1.0; double sy = 1.0; if ( d_data->pointRect.width() > 0.0 ) sx = rect.width() / d_data->pointRect.width(); if ( d_data->pointRect.height() > 0.0 ) sy = rect.height() / d_data->pointRect.height(); const bool scalePens = !d_data->renderHints.testFlag( RenderPensUnscaled ); for ( int i = 0; i < d_data->pathInfos.size(); i++ ) { const PathInfo info = d_data->pathInfos[i]; const double ssx = info.scaleFactorX( d_data->pointRect, rect, scalePens ); if ( ssx > 0.0 ) sx = qMin( sx, ssx ); const double ssy = info.scaleFactorY( d_data->pointRect, rect, scalePens ); if ( ssy > 0.0 ) sy = qMin( sy, ssy ); } if ( aspectRatioMode == Qt::KeepAspectRatio ) { const double s = qMin( sx, sy ); sx = s; sy = s; } else if ( aspectRatioMode == Qt::KeepAspectRatioByExpanding ) { const double s = qMax( sx, sy ); sx = s; sy = s; } QTransform tr; tr.translate( rect.center().x() - 0.5 * sx * d_data->pointRect.width(), rect.center().y() - 0.5 * sy * d_data->pointRect.height() ); tr.scale( sx, sy ); tr.translate( -d_data->pointRect.x(), -d_data->pointRect.y() ); const QTransform transform = painter->transform(); painter->setTransform( tr, true ); render( painter ); painter->setTransform( transform ); }
void ChooseGeneralBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { //============================================================ //||========================================================|| //|| 萩僉夲�揖米薦議冷繍 || //|| ______ ______ ______ ______ ______ || //|| | | | | | | | | | | || //|| | g1 | | g2 | | g3 | | g4 | | g5 | || //|| | | | | | | | | | | || //|| !!!!!! !!!!!! !!!!!! !!!!!! !!!!!! || //|| ______ ______ ______ ______ || //|| | | | | | | | | || //|| | g6 | | g7 | | g8 | | g9 | || //|| | | | | | | | | || //|| !!!!!! !!!!!! !!!!!! !!!!!! || //|| ---------------------------------------------- || //|| \/ || //|| ______ ______ || //|| | | | | || //|| | hg | | dg | || //|| | | | | || //|| !!!!!! !!!!!! || //|| __________ || //|| | 鳩協 | || //|| !!!!!!!!!! || //|| ========================= || //|| || //============================================================ // // //================================================== //|| 岑失岑泳鉱心麼繍 || //||==============================================|| //|| || //|| __________________ || //|| | | || //|| | | || //|| | | || //|| | | || //|| | | || //|| | | || //|| | | || //|| | | || //|| | | || //|| | | || //|| !!!!!!!!!!!!!!!!!! || //|| || //|| ================== || //|| || confirm || || //|| ================== || //|| || //================================================== painter->save(); painter->setBrush(QBrush(G_COMMON_LAYOUT.m_chooseGeneralBoxBackgroundColor)); QRectF rect = boundingRect(); const int x = rect.x(); const int y = rect.y(); const int w = rect.width(); const int h = rect.height(); painter->drawRect(QRect(x, y, w, h)); painter->drawRect(QRect(x, y, w, top_dark_bar)); G_COMMON_LAYOUT.m_chooseGeneralBoxTitleFont.paintText(painter, QRect(x, y, w, top_dark_bar), Qt::AlignCenter, single_result ? tr("Please select one general") : tr("Please select the same nationality generals")); painter->restore(); painter->setPen(G_COMMON_LAYOUT.m_chooseGeneralBoxBorderColor); painter->drawRect(QRect(x + 1, y + 1, w - 2, h - 2)); if (single_result) return; int split_line_y = top_blank_width + G_COMMON_LAYOUT.m_cardNormalHeight + card_bottom_to_split_line; if (general_number > 5) split_line_y += (card_to_center_line + G_COMMON_LAYOUT.m_cardNormalHeight); QPixmap line = G_ROOM_SKIN.getPixmap(QSanRoomSkin::S_SKIN_KEY_CHOOSE_GENERAL_BOX_SPLIT_LINE); const int line_length = boundingRect().width() - 2 * left_blank_width; painter->drawPixmap(left_blank_width, split_line_y, line, (line.width() - line_length) / 2, y, line_length, line.height()); QPixmap seat = G_ROOM_SKIN.getPixmap(QSanRoomSkin::S_SKIN_KEY_CHOOSE_GENERAL_BOX_DEST_SEAT); QRect seat1_rect(rect.center().x() - G_COMMON_LAYOUT.m_cardNormalWidth - card_to_center_line - 2, split_line_y + split_line_to_card_seat - 2, G_COMMON_LAYOUT.m_cardNormalWidth + 4, G_COMMON_LAYOUT.m_cardNormalHeight + 4); painter->drawPixmap(seat1_rect, seat); IQSanComponentSkin::QSanSimpleTextFont font = G_COMMON_LAYOUT.m_chooseGeneralBoxDestSeatFont; font.paintText(painter, seat1_rect, Qt::AlignCenter, tr("head_general")); QRect seat2_rect(rect.center().x() + card_to_center_line - 2, split_line_y + split_line_to_card_seat - 2, G_COMMON_LAYOUT.m_cardNormalWidth + 4, G_COMMON_LAYOUT.m_cardNormalHeight + 4); painter->drawPixmap(seat2_rect, seat); font.paintText(painter, seat2_rect, Qt::AlignCenter, tr("deputy_general")); }
QPainterPath linePath; linePath.addText(0, linePos, font(), line); linePos += lineSpacing; if ( m_alignment == Qt::AlignHCenter ) { double offset = (bounding.width() - metrics.width(line)) / 2; linePath.translate(offset, 0); } else if ( m_alignment == Qt::AlignRight ) { double offset = (bounding.width() - metrics.width(line)); linePath.translate(offset, 0); } path.addPath(linePath); } // Calculate position of text in parent item QRectF pathRect = QRectF(0, 0, bounding.width(), linePos - lineSpacing + metrics.descent() ); QPointF offset = bounding.center() - pathRect.center() + QPointF(2 * m_shadowBlur, 2 * m_shadowBlur); path.translate(offset); QRectF fullSize = bounding.united(path.boundingRect()); m_shadow = QImage(fullSize.width() + qAbs(m_shadowOffset.x()) + 4 * m_shadowBlur, fullSize.height() + qAbs(m_shadowOffset.y()) + 4 * m_shadowBlur, QImage::Format_ARGB32_Premultiplied); m_shadow.fill(Qt::transparent); QPainter painter(&m_shadow); painter.fillPath(path, QBrush(m_shadowColor)); painter.end(); if (m_shadowBlur > 0) { blurShadow(m_shadow, m_shadowBlur); } } void MyTextItem::blurShadow(QImage &result, int radius) { int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
void PosteRazorCore::paintPosterOnCanvasOverlapped(PaintCanvasInterface *paintCanvas) const { const QSizeF canvasSize = paintCanvas->size(); QSizeF pagePrintableAreaSize = printablePaperAreaSize(); const QSizeF posterSizePages = posterSize(Types::PosterSizeModePages); const int pagesHorizontal = (int)ceil(posterSizePages.width()); const int pagesVertical = (int)ceil(posterSizePages.height()); const QSizeF posterSize( pagesHorizontal*pagePrintableAreaSize.width() - (pagesHorizontal-1)*overlappingWidth() + paperBorderLeft() + paperBorderRight(), pagesVertical*pagePrintableAreaSize.height() - (pagesVertical-1)*overlappingHeight() + paperBorderTop() + paperBorderBottom() ); const QSizeF boxSize = previewSize(posterSize, canvasSize.toSize(), true); const QPointF offset((canvasSize.width() - boxSize.width()) / 2, (canvasSize.height() - boxSize.height()) / 2); const qreal UnitOfLengthToPixelfactor = boxSize.width()/posterSize.width(); const qreal borderTop = paperBorderTop() * UnitOfLengthToPixelfactor; const qreal borderRight = paperBorderRight() * UnitOfLengthToPixelfactor; const qreal borderBottom = paperBorderBottom() * UnitOfLengthToPixelfactor; const qreal borderLeft = paperBorderLeft() * UnitOfLengthToPixelfactor; const QSizeF posterPrintableAreaSize(boxSize.width() - borderLeft - borderRight, boxSize.height() - borderTop - borderBottom); const QPointF posterPrintableAreaOrigin = QPointF(borderLeft, borderTop) + offset; const QRectF posterPrintableArea(posterPrintableAreaOrigin, posterPrintableAreaSize); paintCanvas->drawFilledRect(QRectF(offset, boxSize), QColor(128, 128, 128)); paintCanvas->drawFilledRect(posterPrintableArea, QColor(230, 230, 230)); const QSizeF posterSizeAbsolute = this->posterSize(Types::PosterSizeModeAbsolute); const QSizeF imageSize = posterSizeAbsolute * UnitOfLengthToPixelfactor; const Qt::Alignment alignment = posterAlignment(); paintCanvas->drawImage( QRectF( QPointF( ( alignment & Qt::AlignLeft?borderLeft :alignment & Qt::AlignHCenter?qBound(borderLeft, (boxSize.width() - imageSize.width()) / 2, borderLeft + posterPrintableAreaSize.width() - imageSize.width()) :(borderLeft + posterPrintableAreaSize.width() - imageSize.width()) ) + offset.x(), ( alignment & Qt::AlignTop?borderTop :alignment & Qt::AlignVCenter?qBound(borderTop, (boxSize.height() - imageSize.height()) / 2, borderTop + posterPrintableAreaSize.height() - imageSize.height()) :(borderTop + posterPrintableAreaSize.height() - imageSize.height()) ) + offset.y() ), imageSize ) ); const qreal overlappingHeight = this->overlappingHeight() * UnitOfLengthToPixelfactor; const qreal overlappingWidth = this->overlappingWidth() * UnitOfLengthToPixelfactor; pagePrintableAreaSize *= UnitOfLengthToPixelfactor; const QColor overlappingColor(255, 128, 128, 128); qreal overlappingRectangleYPosition = borderTop; for (int pagesRow = 0; pagesRow < pagesVertical - 1; pagesRow++) { overlappingRectangleYPosition += pagePrintableAreaSize.height() - overlappingHeight; paintCanvas->drawFilledRect(QRectF(QPointF(0, overlappingRectangleYPosition) + offset, QSizeF(boxSize.width(), overlappingHeight)), overlappingColor); } qreal overlappingRectangleXPosition = borderLeft; for (int pagesColumn = 0; pagesColumn < pagesHorizontal - 1; pagesColumn++) { overlappingRectangleXPosition += pagePrintableAreaSize.width() - overlappingWidth; paintCanvas->drawFilledRect(QRectF(QPointF(overlappingRectangleXPosition, 0) + offset, QSizeF(overlappingWidth, boxSize.height())), overlappingColor); } const int fontSize = int(qMin(pagePrintableAreaSize.width() / 2.5, pagePrintableAreaSize.height() / 1.5)); for (int pagesRow = 0; pagesRow < pagesVertical; ++pagesRow) { for (int pagesColumn = 0; pagesColumn < pagesHorizontal; ++pagesColumn) { const QPointF pagePrintableAreaOrigin = posterPrintableAreaOrigin + QPointF( pagesColumn * (pagePrintableAreaSize.width() - overlappingWidth), pagesRow * (pagePrintableAreaSize.height() - overlappingHeight) ); const QRectF pageNumberArea = QRectF(pagePrintableAreaOrigin, pagePrintableAreaSize).adjusted( pagesColumn == 0 ? 0 : overlappingWidth, pagesRow == 0 ? 0 : overlappingHeight, pagesColumn == pagesHorizontal - 1 ? 0 : -overlappingWidth, pagesRow == pagesVertical - 1 ? 0 : -overlappingHeight ); const int pageNumber = pagesRow * pagesHorizontal + pagesColumn + 1; paintCanvas->drawOverlayText(pageNumberArea.center(), Qt::AlignCenter, fontSize, QString::number(pageNumber)); } } }
void ChooseGeneralBox::paintLayout(QPainter *painter) { //============================================================ //||========================================================|| //|| Please select the same nationality generals || //|| ______ ______ ______ ______ ______ || //|| | | | | | | | | | | || //|| | g1 | | g2 | | g3 | | g4 | | g5 | || //|| | | | | | | | | | | || //|| ------ ------ ------ ------ ------ || //|| ______ ______ ______ ______ || //|| | | | | | | | | || //|| | g6 | | g7 | | g8 | | g9 | || //|| | | | | | | | | || //|| ------ ------ ------ ------ || //|| ---------------------------------------------- || //|| \/ || //|| ______ ______ || //|| | | | | || //|| | hg | | dg | || //|| | | | | || //|| ------ ------ || //|| __________ || //|| | fight | || //|| ---------- || //|| ========================= || //|| || //============================================================ // // //================================================== //|| KnownBoth View Head || //||==============================================|| //|| || //|| __________________ || //|| | | || //|| | | || //|| | | || //|| | | || //|| | | || //|| | | || //|| | | || //|| | | || //|| | | || //|| | | || //|| ------------------ || //|| || //|| ================== || //|| || confirm || || //|| ================== || //|| || //================================================== if (m_viewOnly || single_result) return; int split_line_y = top_blank_width + G_COMMON_LAYOUT.m_cardNormalHeight + card_bottom_to_split_line; if (general_number > 5) split_line_y += (card_to_center_line + G_COMMON_LAYOUT.m_cardNormalHeight); QPixmap line = G_ROOM_SKIN.getPixmap(QSanRoomSkin::S_SKIN_KEY_CHOOSE_GENERAL_BOX_SPLIT_LINE); const int line_length = boundingRect().width() - 2 * left_blank_width; const QRectF rect = boundingRect(); painter->drawPixmap(left_blank_width, split_line_y, line, (line.width() - line_length) / 2, rect.y(), line_length, line.height()); QPixmap seat = G_ROOM_SKIN.getPixmap(QSanRoomSkin::S_SKIN_KEY_CHOOSE_GENERAL_BOX_DEST_SEAT); QRect seat1_rect(rect.center().x() - G_COMMON_LAYOUT.m_cardNormalWidth - card_to_center_line - 2, split_line_y + split_line_to_card_seat - 2, G_COMMON_LAYOUT.m_cardNormalWidth + 4, G_COMMON_LAYOUT.m_cardNormalHeight + 4); painter->drawPixmap(seat1_rect, seat); IQSanComponentSkin::QSanSimpleTextFont font = G_COMMON_LAYOUT.m_chooseGeneralBoxDestSeatFont; font.paintText(painter, seat1_rect, Qt::AlignCenter, tr("head_general")); QRect seat2_rect(rect.center().x() + card_to_center_line - 2, split_line_y + split_line_to_card_seat - 2, G_COMMON_LAYOUT.m_cardNormalWidth + 4, G_COMMON_LAYOUT.m_cardNormalHeight + 4); painter->drawPixmap(seat2_rect, seat); font.paintText(painter, seat2_rect, Qt::AlignCenter, tr("deputy_general")); }
/*! \brief Draw the identifier representing the curve on the legend \param painter Painter \param rect Bounding rectangle for the identifier \sa setLegendAttribute(), QwtPlotItem::Legend */ void QwtPlotCurve::drawLegendIdentifier( QPainter *painter, const QRectF &rect ) const { if ( rect.isEmpty() ) return; const double dim = qMin( rect.width(), rect.height() ); QSizeF size( dim, dim ); QRectF r( 0, 0, size.width(), size.height() ); r.moveCenter( rect.center() ); if ( d_data->legendAttributes == 0 ) { QBrush brush = d_data->brush; if ( brush.style() == Qt::NoBrush ) { if ( style() != QwtPlotCurve::NoCurve ) brush = QBrush( pen().color() ); else if ( d_data->symbol && ( d_data->symbol->style() != QwtSymbol::NoSymbol ) ) { brush = QBrush( d_data->symbol->pen().color() ); } } if ( brush.style() != Qt::NoBrush ) painter->fillRect( r, brush ); } if ( d_data->legendAttributes & QwtPlotCurve::LegendShowBrush ) { if ( d_data->brush.style() != Qt::NoBrush ) painter->fillRect( r, d_data->brush ); } if ( d_data->legendAttributes & QwtPlotCurve::LegendShowLine ) { if ( pen() != Qt::NoPen ) { painter->setPen( pen() ); QwtPainter::drawLine( painter, rect.left(), rect.center().y(), rect.right() - 1.0, rect.center().y() ); } } if ( d_data->legendAttributes & QwtPlotCurve::LegendShowSymbol ) { if ( d_data->symbol && ( d_data->symbol->style() != QwtSymbol::NoSymbol ) ) { QSize symbolSize = d_data->symbol->boundingSize(); symbolSize -= QSize( 2, 2 ); // scale the symbol size down if it doesn't fit into rect. double xRatio = 1.0; if ( rect.width() < symbolSize.width() ) xRatio = rect.width() / symbolSize.width(); double yRatio = 1.0; if ( rect.height() < symbolSize.height() ) yRatio = rect.height() / symbolSize.height(); const double ratio = qMin( xRatio, yRatio ); painter->save(); painter->scale( ratio, ratio ); d_data->symbol->drawSymbol( painter, rect.center() / ratio ); painter->restore(); } } }
void drawDial(const QStyleOptionSlider *option, QPainter *painter) { QPalette pal = option->palette; QColor buttonColor = pal.button().color(); const int width = option->rect.width(); const int height = option->rect.height(); const bool enabled = option->state & QStyle::State_Enabled; qreal r = qMin(width, height) / 2; r -= r/50; const qreal penSize = r/20.0; painter->save(); // Draw notches if (option->subControls & QStyle::SC_DialTickmarks) { painter->setPen(option->palette.dark().color().darker(120)); painter->drawLines(QStyleHelper::calcLines(option)); } // Cache dial background BEGIN_STYLE_PIXMAPCACHE(QString::fromLatin1("qdial")); const qreal d_ = r / 6; const qreal dx = option->rect.x() + d_ + (width - 2 * r) / 2 + 1; const qreal dy = option->rect.y() + d_ + (height - 2 * r) / 2 + 1; QRectF br = QRectF(dx + 0.5, dy + 0.5, int(r * 2 - 2 * d_ - 2), int(r * 2 - 2 * d_ - 2)); buttonColor.setHsv(buttonColor .hue(), qMin(140, buttonColor .saturation()), qMax(180, buttonColor.value())); QColor shadowColor(0, 0, 0, 20); if (enabled) { // Drop shadow qreal shadowSize = qMax(1.0, penSize/2.0); QRectF shadowRect= br.adjusted(-2*shadowSize, -2*shadowSize, 2*shadowSize, 2*shadowSize); QRadialGradient shadowGradient(shadowRect.center().x(), shadowRect.center().y(), shadowRect.width()/2.0, shadowRect.center().x(), shadowRect.center().y()); shadowGradient.setColorAt(qreal(0.91), QColor(0, 0, 0, 40)); shadowGradient.setColorAt(qreal(1.0), Qt::transparent); p->setBrush(shadowGradient); p->setPen(Qt::NoPen); p->translate(shadowSize, shadowSize); p->drawEllipse(shadowRect); p->translate(-shadowSize, -shadowSize); // Main gradient QRadialGradient gradient(br.center().x() - br.width()/3, dy, br.width()*1.3, br.center().x(), br.center().y() - br.height()/2); gradient.setColorAt(0, buttonColor.lighter(110)); gradient.setColorAt(qreal(0.5), buttonColor); gradient.setColorAt(qreal(0.501), buttonColor.darker(102)); gradient.setColorAt(1, buttonColor.darker(115)); p->setBrush(gradient); } else { p->setBrush(Qt::NoBrush); } p->setPen(QPen(buttonColor.darker(280))); p->drawEllipse(br); p->setBrush(Qt::NoBrush); p->setPen(buttonColor.lighter(110)); p->drawEllipse(br.adjusted(1, 1, -1, -1)); if (option->state & QStyle::State_HasFocus) { QColor highlight = pal.highlight().color(); highlight.setHsv(highlight.hue(), qMin(160, highlight.saturation()), qMax(230, highlight.value())); highlight.setAlpha(127); p->setPen(QPen(highlight, 2.0)); p->setBrush(Qt::NoBrush); p->drawEllipse(br.adjusted(-1, -1, 1, 1)); } END_STYLE_PIXMAPCACHE QPointF dp = calcRadialPos(option, qreal(0.70)); buttonColor = buttonColor.lighter(104); buttonColor.setAlphaF(qreal(0.8)); const qreal ds = r/qreal(7.0); QRectF dialRect(dp.x() - ds, dp.y() - ds, 2*ds, 2*ds); QRadialGradient dialGradient(dialRect.center().x() + dialRect.width()/2, dialRect.center().y() + dialRect.width(), dialRect.width()*2, dialRect.center().x(), dialRect.center().y()); dialGradient.setColorAt(1, buttonColor.darker(140)); dialGradient.setColorAt(qreal(0.4), buttonColor.darker(120)); dialGradient.setColorAt(0, buttonColor.darker(110)); if (penSize > 3.0) { painter->setPen(QPen(QColor(0, 0, 0, 25), penSize)); painter->drawLine(calcRadialPos(option, qreal(0.90)), calcRadialPos(option, qreal(0.96))); } painter->setBrush(dialGradient); painter->setPen(QColor(255, 255, 255, 150)); painter->drawEllipse(dialRect.adjusted(-1, -1, 1, 1)); painter->setPen(QColor(0, 0, 0, 80)); painter->drawEllipse(dialRect); painter->restore(); }
void CustomGraphicsScene::appendCard(int _cardType, const QString& _title, const QString& _description) { QPointF scenePosition = sceneRect().center(); // // Если выделена карточка // CardShape* selectedCard = nullptr; CardShape* previousCard = nullptr; CardShape* nextCard = nullptr; CardShape* parentCard = nullptr; if (!selectedItems().isEmpty() && selectedItems().size() == 1 && (selectedCard = dynamic_cast<CardShape*>(selectedItems().last()))) { // // Если карточка вложена в группирующую, то расширяем родителя и вкладываем карту в него // if (selectedCard->parentItem() != nullptr) { // // Запомним родителя // parentCard = dynamic_cast<CardShape*>(selectedCard->parentItem()); } // // Если выделен группирующий элемент, то соединять будем с последним из его детей // if (hasCards(selectedCard)) { selectedCard = dynamic_cast<CardShape*>(lastCard(selectedCard)); } // // Предыдущей будет выделенная // previousCard = selectedCard; // // Настроим позицию для добавления новой карточки // scenePosition = previousCard->scenePos(); scenePosition.setX(scenePosition.x() + previousCard->boundingRect().width() + SHAPE_MOVE_DELTA); scenePosition.setY(scenePosition.y() + previousCard->boundingRect().height() + SHAPE_MOVE_DELTA); // // Определим карточку, которая будет следовать за новой // Flow* flow = cardFlow(previousCard, CARD_ON_FLOW_START); if (flow != nullptr) { nextCard = dynamic_cast<CardShape*>(flow->endShape()); removeShape(flow); } } // // В противном случае добавляем карточку после самой последней карточки, если карточки уже есть // else if (hasCards()) { // // Определим последнюю карточку // Shape* lastCardShape = lastCard(); previousCard = dynamic_cast<CardShape*>(lastCardShape); // // Настроим позицию для добавления новой карточки // scenePosition = previousCard->scenePos(); scenePosition.setX(scenePosition.x() + previousCard->boundingRect().width() + SHAPE_MOVE_DELTA); scenePosition.setY(scenePosition.y() + previousCard->boundingRect().height() + SHAPE_MOVE_DELTA); } // // В противном случае добавляем карточку по середине видимой части сцены, если подключены представления // else if (!views().isEmpty()) { if (QGraphicsView* view = views().last()) { const QRect viewportRect(0, 0, view->viewport()->width(), view->viewport()->height()); const QRectF visibleSceneRect = view->mapToScene(viewportRect).boundingRect(); scenePosition = visibleSceneRect.center(); } } // // Добавляем карточку // CardShape* newCard = new CardShape((CardShape::CardType)_cardType, _title, _description, scenePosition, parentCard); insertShape(newCard, previousCard); // // ... корректируем позицию вкладываемой карточки // if (parentCard != nullptr) { const QPointF newPos = parentCard->mapFromScene(newCard->scenePos()); const QPointF newBottomRightPos = newPos + QPointF(newCard->boundingRect().width(), newCard->boundingRect().height()); // newCard->setParentItem(parentCard); newCard->setPos(newPos); // // ... и масштабируем родителя, если нужно // if (!parentCard->contains(newBottomRightPos)) { QSizeF newSize = parentCard->size(); if (newSize.width() <= newBottomRightPos.x()) { newSize.setWidth(newBottomRightPos.x() + SHAPE_MICROMOVE_DELTA); } if (newSize.height() <= newBottomRightPos.y()) { newSize.setHeight(newBottomRightPos.y() + SHAPE_MICROMOVE_DELTA); } parentCard->setSize(newSize); } } // // Соединяем с предыдущей // if (previousCard != nullptr) { appendShape(new ArrowFlow(previousCard, newCard, parentCard)); } // // Соединяем со следующей // if (nextCard != nullptr) { appendShape(new ArrowFlow(newCard, nextCard, parentCard)); } }
static QPointF topCenter(const QRectF &rect) { return QPointF(rect.center().x(), rect.top()); }
/** Internal method that draws the surface of one of the pies in a pie chart. \param painter the QPainter to draw in \param dataset the dataset to draw the pie for \param pie the pie to draw */ void PieDiagram::drawPieSurface( QPainter* painter, DataValueTextInfoList* list, uint dataset, uint pie, qreal granularity ) { // Is there anything to draw at all? qreal angleLen = d->angleLens[ pie ]; if ( angleLen ) { qreal startAngle = d->startAngles[ pie ]; QModelIndex index( model()->index( 0, pie, rootIndex() ) ); const PieAttributes attrs( pieAttributes( index ) ); const ThreeDPieAttributes threeDAttrs( threeDPieAttributes( index ) ); QRectF drawPosition = piePosition( dataset, pie ); painter->setRenderHint ( QPainter::Antialiasing ); QBrush br = brush( index ); if( threeDAttrs.isEnabled() ) { br = threeDAttrs.threeDBrush( br, drawPosition ); } painter->setBrush( br ); painter->setPen( pen( index ) ); if ( angleLen == 360 ) { // full circle, avoid nasty line in the middle painter->drawEllipse( drawPosition ); //Add polygon to Reverse mapper for showing tool tips. QPolygonF poly( drawPosition ); d->reverseMapper.addPolygon( index.row(), index.column(), poly ); } else { // draw the top of this piece // Start with getting the points for the arc. const int arcPoints = static_cast<int>(trunc( angleLen / granularity )); QPolygonF poly( arcPoints+2 ); qreal degree=0.0; int iPoint = 0; bool perfectMatch = false; while ( degree <= angleLen ){ poly[ iPoint ] = pointOnCircle( drawPosition, startAngle + degree ); //qDebug() << degree << angleLen << poly[ iPoint ]; perfectMatch = (degree == angleLen); degree += granularity; ++iPoint; } // if necessary add one more point to fill the last small gap if( ! perfectMatch ){ poly[ iPoint ] = pointOnCircle( drawPosition, startAngle + angleLen ); // add the center point of the piece poly.append( drawPosition.center() ); }else{ poly[ iPoint ] = drawPosition.center(); } //find the value and paint it //fix value position d->reverseMapper.addPolygon( index.row(), index.column(), poly ); painter->drawPolygon( poly ); } // the new code is setting the needed position points according to the slice: // all is calculated as if the slice were 'standing' on it's tip and the border // were on top, so North is the middle of the curved outside line and South is the tip // const qreal sum = valueTotals(); const QPointF south = drawPosition.center(); const QPointF southEast = south; const QPointF southWest = south; const QPointF north = pointOnCircle( drawPosition, startAngle + angleLen/2.0 ); const QPointF northEast = pointOnCircle( drawPosition, startAngle ); const QPointF northWest = pointOnCircle( drawPosition, startAngle + angleLen ); QPointF center = (south + north) / 2.0; const QPointF east = (south + northEast) / 2.0; const QPointF west = (south + northWest) / 2.0; CartesianDiagramDataCompressor::DataValueAttributesList allAttrs( d->aggregatedAttrs( this, index, 0 ) ); const QFontMetrics * fm = (d->cachedFontMetrics( allAttrs.value(index).textAttributes().calculatedFont(d->plane,KDChartEnums::MeasureOrientationMinimum ), this )); if(!list->isEmpty()) { QRect textRect = fm->boundingRect(QString::number(list->last().value)); textRect.translated(center.toPoint()); QPoint textRectCenter = textRect.center(); qreal newX = center.x() - textRectCenter.x(); qreal newY = center.y() - textRectCenter.y(); center.setX(newX); center.setY(newY); } PositionPoints points( center, northWest, north, northEast, east, southEast, south, southWest, west); qreal topAngle = startAngle - 90; if( topAngle < 0.0 ) topAngle += 360; points.setDegrees(KDChartEnums::PositionEast, topAngle); points.setDegrees(KDChartEnums::PositionNorthEast, topAngle); points.setDegrees(KDChartEnums::PositionWest, topAngle + angleLen); points.setDegrees(KDChartEnums::PositionNorthWest, topAngle + angleLen); points.setDegrees(KDChartEnums::PositionCenter, topAngle + angleLen/2.0); points.setDegrees(KDChartEnums::PositionNorth, topAngle + angleLen/2.0); //painter->drawText(points.mPositionCenter,QLatin1String("P")); d->appendDataValueTextInfoToList( this, *list, index, 0, points, Position::Center, Position::Center, angleLen*sum / 360 ); // The following, old code (since kdc 2.0.0) was not correct: // Settings made for the position had been totally ignored, // AND the center was NOT the center - except for pieces of 45 degrees size // // QLineF centerLine( drawPosition.center(), // QPointF( (poly[ last - 2].x() + poly.first().x())/2, // ( poly.first().y() + poly[last-2].y() )/2 ) ); // QPointF valuePos( ( centerLine.x1() + centerLine.x2() )/2, // ( centerLine.y1() + centerLine.y2() )/2 ) ; // // paintDataValueText( painter, index, valuePos, angleLen*sum / 360 ); } }
void CalloutNote::drawNoteNodeConnector(QPainter *painter, bool visible) { float width; float height; QRectF itemPos; if(_scene->_pathBubbles[_pid]==NULL) //does not work return; PathBubble1* path=_scene->_pathBubbles[_pid]; if(!path || path==NULL || !path->isVisible()) return; QPointF dis1=this->sceneBoundingRect().center(); QPointF dis2=path->sceneBoundingRect().center(); if(fixedSize) { width=graphReferenceSize/2*path->_scale; height=graphReferenceSize/2*path->_scale; } else { width=this->realRect().width()/2*path->_scale; height=this->realRect().height()/2*path->_scale; } if(_type == 'L' && _id>=path->ANodeRect.size()) return; switch(_type) { case 'C': itemPos = path->complexRect[_id]; break; case 'E': itemPos = path->physicalEntityRect[_id]; break; case 'P': itemPos = path->proteinRect[_id]; break; case 'S': itemPos = path->smallMoleculeRect[_id]; break; case 'D': itemPos = path->DnaRect[_id]; break; case 'R': itemPos = path->reactionRect[_id]; break; case 'L': itemPos = path->ANodeRect[_id]; break; case 'M': itemPos = path->compartmentRect[_id]; break; } QPointF start,end; start=QPointF(0,0); end=itemPos.center(); start=start+dis1; end=end+dis2; QRectF noteRect=this->sceneBoundingRect(); QRectF pathRect=path->sceneBoundingRect(); float w,h; w=realRect().width(), h=realRect().height(); noteRect=QRectF(noteRect.center().x()-w/2, noteRect.center().y()-h/2, w, h ); QPointF markPos(end.x()+itemPos.width()*0.5, end.y()-itemPos.height()*0.1); _deleteMark = QRectF(noteRect.x()+noteRect.width()*0.90, noteRect.y()+noteRect.height()*0.03, noteRect.width()*0.08, noteRect.width()*0.08); _minimizeMark = QRectF(noteRect.x()+noteRect.width()*0.80, noteRect.y()+noteRect.height()*0.03, noteRect.width()*0.08, noteRect.width()*0.08); //clip QColor c=QColor(_colorBoarder.a, _colorBoarder.b, _colorBoarder.c, 255); if(visible) { if(!noteRect.contains(end)) { drawArrow_5(painter, start, markPos-QPointF(itemPos.width()*0.04,0), QRect(noteRect.center().x()-w/2,noteRect.center().y()-h/2, w, h ), width, height, c ); } drawCross(painter,_deleteMark, c); drawMinus(painter,_minimizeMark, c); } else { //if within the path bubble if(pathRect.contains(start)|| pathRect.contains(end)) drawNoteMark(painter, start, end, QRect(noteRect.center().x()-w/2,noteRect.center().y()-h/2, w, h ), markPos, markRect, width, height, c ); } }
void KFollowWindow::resetGeometry() { Q_D(KFollowWindow); if(d->target == NULL) return; bool bHandled = false; emit aboutToAdjust(this, &bHandled); if(bHandled) { return; } QRectF targetRt = d->target->rectToScreen(); QSizeF targetSize = targetRt.size(); QSizeF winSize = d->winSize; QRectF winRt(0, 0, winSize.width(), winSize.height()); QPointF winCenterPt = winRt.center(); QPointF targetCenterPt = targetRt.center(); QSizeF hitDistance = (targetSize + winSize) / 2; Direction tmpDirection = d->direction; if(tmpDirection == LeftTop) { QPointF targetPt = QPointF(targetCenterPt.x(), targetRt.top()); QPointF winPt = QPointF(winCenterPt.x(), winRt.top()); QPointF offsetPt = targetPt - QPointF(hitDistance.width(), 0) - winPt; offsetPt += d->offsetPt; winRt.translate(offsetPt); setGeometry(winRt.toRect()); } else if(tmpDirection == LeftCenter) { QPointF offsetPt = targetCenterPt - QPointF(hitDistance.width(), 0) - winCenterPt; offsetPt += d->offsetPt; winRt.translate(offsetPt); setGeometry(winRt.toRect()); } else if(tmpDirection == LeftBottom) { QPointF targetPt = QPointF(targetCenterPt.x(), targetRt.bottom()); QPointF winPt = QPointF(winCenterPt.x(), winRt.bottom()); QPointF offsetPt = targetPt - QPointF(hitDistance.width(), 0) - winPt; offsetPt += d->offsetPt; winRt.translate(offsetPt); setGeometry(winRt.toRect()); } else if(tmpDirection == RightTop) { QPointF targetPt = QPointF(targetCenterPt.x(), targetRt.top()); QPointF winPt = QPointF(winCenterPt.x(), winRt.top()); QPointF offsetPt = targetPt + QPointF(hitDistance.width(), 0) - winPt; offsetPt += d->offsetPt; winRt.translate(offsetPt); setGeometry(winRt.toRect()); } else if(tmpDirection == RightCenter) { QPointF offsetPt = targetCenterPt + QPointF(hitDistance.width(), 0) - winCenterPt; offsetPt += d->offsetPt; winRt.translate(offsetPt); setGeometry(winRt.toRect()); } else if(tmpDirection == RightBottom) { QPointF targetPt = QPointF(targetCenterPt.x(), targetRt.bottom()); QPointF winPt = QPointF(winCenterPt.x(), winRt.bottom()); QPointF offsetPt = targetPt + QPointF(hitDistance.width(), 0) - winPt; offsetPt += d->offsetPt; winRt.translate(offsetPt); setGeometry(winRt.toRect()); } else if(tmpDirection == TopLeft) { QPointF targetPt = QPointF(targetRt.left(), targetCenterPt.y()); QPointF winPt = QPointF(winRt.left(), winCenterPt.y()); QPointF offsetPt = targetPt - QPointF(0, hitDistance.height()) - winPt; offsetPt += d->offsetPt; winRt.translate(offsetPt); setGeometry(winRt.toRect()); } else if(tmpDirection == TopCenter) { QPointF offsetPt = targetCenterPt - QPointF(0, hitDistance.height()) - winCenterPt; offsetPt += d->offsetPt; winRt.translate(offsetPt); setGeometry(winRt.toRect()); } else if(tmpDirection == TopRight) { QPointF targetPt = QPointF(targetRt.right(), targetCenterPt.y()); QPointF winPt = QPointF(winRt.right(), winCenterPt.y()); QPointF offsetPt = targetPt - QPointF(0, hitDistance.height()) - winPt; offsetPt += d->offsetPt; winRt.translate(offsetPt); setGeometry(winRt.toRect()); } else if(tmpDirection == BottomLeft) { QPointF targetPt = QPointF(targetRt.left(), targetCenterPt.y()); QPointF winPt = QPointF(winRt.left(), winCenterPt.y()); QPointF offsetPt = targetPt + QPointF(0, hitDistance.height()) - winPt; offsetPt += d->offsetPt; winRt.translate(offsetPt); setGeometry(winRt.toRect()); } else if(tmpDirection == BottomCenter) { QPointF winCenterPt = winRt.center(); QPointF targetCenterPt = targetRt.center(); QPointF offsetPt = targetCenterPt + QPointF(0, hitDistance.height()) - winCenterPt; offsetPt += d->offsetPt; winRt.translate(offsetPt); setGeometry(winRt.toRect()); } else if(tmpDirection == BottomRight) { QPointF targetPt = QPointF(targetRt.right(), targetCenterPt.y()); QPointF winPt = QPointF(winRt.right(), winCenterPt.y()); QPointF offsetPt = targetPt + QPointF(0, hitDistance.height()) - winPt; offsetPt += d->offsetPt; winRt.translate(offsetPt); setGeometry(winRt.toRect()); } update(); }
void EmulatedCardWindow::layoutWidgets() { qreal angle = rotationAdjustmentAngle(); int side = 0; QRectF emuRect = rotateEmulationBoundingRect(angle); QPointF center = emuRect.center(); qreal height = emuRect.height(); qreal width = emuRect.width(); QPointF bottomCenter = QPointF(center.x(), center.y()+(height/2)); QPointF topCenter = QPointF(center.x(), center.y()-(height/2)); QPointF leftCenter = QPointF(center.x()-(width/2), center.y()); QPointF rightCenter = QPointF(center.x()+(width/2), center.y()); int orient = WindowServer::instance()->getUiOrientation(); //The keyboard button actually tracks the system UI rather than the //app, so it's laid out independently QRectF brect = boundingRect(); //X-axis margin: 17px //Y-axis margin: 18px m_keyboardButton->setPos(brect.bottomRight().x() - m_keyboardButton->boundingRect().width() - 17, brect.bottomRight().y() - m_keyboardButton->boundingRect().height() - 18); //The button should be "fixed", meaning the system orientations map //as follows: // // Up->left // Left->Up // Right->down // down->right const Event::Orientation app_orientations[] = {Event::Orientation_Up, Event::Orientation_Left, Event::Orientation_Down, Event::Orientation_Right}; const Event::Orientation system_orientations[] = {Event::Orientation_Left, Event::Orientation_Up, Event::Orientation_Right, Event::Orientation_Down}; for (int i=0; i<4; i++) { if (orient == system_orientations[i]) { side = app_orientations[i]; } } int back_button_offset = 14; /* Terminology note-- here, "side" means the following: * * up -> buttons go on bottom, status bar on top * right -> buttons go on right, status bar (which shouldn't show) on left * left -> opposite of right * down -> opposite of up * * This is slightly better self-documenting than relying strictly on the * adjustment angle. */ if (side == Event::Orientation_Up) { m_gestureStrip->setPos(topCenter.x(), topCenter.y()-m_gestureStrip->boundingRect().height()/2); m_gestureStrip->setRotation(180); m_statusBar->setPos(emuRect.right() - emuRect.width()/2, emuRect.bottom() + Settings::LunaSettings()->positiveSpaceTopPadding/2); m_statusBar->setRotation(180); } else if (side == Event::Orientation_Down) { m_gestureStrip->setPos(bottomCenter.x(), bottomCenter.y()+m_gestureStrip->boundingRect().height()/2); m_gestureStrip->setRotation(0); m_statusBar->setPos(emuRect.right() - emuRect.width()/2, emuRect.top() - Settings::LunaSettings()->positiveSpaceTopPadding/2); m_statusBar->setRotation(0); } else if (side == Event::Orientation_Left) { m_gestureStrip->setRotation(-90); m_gestureStrip->setPos(rightCenter.x()+m_gestureStrip->boundingRect().height()/2, rightCenter.y()); m_statusBar->setPos(emuRect.left()-Settings::LunaSettings()->positiveSpaceTopPadding/2, emuRect.bottom() - emuRect.height()/2); m_statusBar->setRotation(-90); } else if (side == Event::Orientation_Right) { m_gestureStrip->setRotation(90); m_gestureStrip->setPos(leftCenter.x()-m_gestureStrip->boundingRect().height()/2, leftCenter.y()); m_statusBar->setPos(emuRect.right()+Settings::LunaSettings()->positiveSpaceTopPadding/2, emuRect.top() + emuRect.height()/2); m_statusBar->setRotation(90); } //Translate the widgets to adjust for changes to positive space m_gestureStrip->setPos(m_gestureStrip->pos().x(), m_gestureStrip->pos().y()-m_positiveSpaceAdjustment); m_statusBar->setPos(m_statusBar->pos().x(), m_statusBar->pos().y()-m_positiveSpaceAdjustment); }
void AbstractDiagram::Private::addLabel( LabelPaintCache* cache, const QModelIndex& index, const CartesianDiagramDataCompressor::CachePosition* position, const PositionPoints& points, const Position& autoPositionPositive, const Position& autoPositionNegative, const qreal value, qreal favoriteAngle /* = 0.0 */ ) { CartesianDiagramDataCompressor::AggregatedDataValueAttributes allAttrs( aggregatedAttrs( index, position ) ); QMap<QModelIndex, DataValueAttributes>::const_iterator it; for ( it = allAttrs.constBegin(); it != allAttrs.constEnd(); ++it ) { DataValueAttributes dva = it.value(); if ( !dva.isVisible() ) { continue; } const bool isPositive = ( value >= 0.0 ); RelativePosition relPos( dva.position( isPositive ) ); relPos.setReferencePoints( points ); if ( relPos.referencePosition().isUnknown() ) { relPos.setReferencePosition( isPositive ? autoPositionPositive : autoPositionNegative ); } // Rotate the label position (not the label itself) if the diagram is rotated so that the defaults still work if ( isTransposed() ) { KChartEnums::PositionValue posValue = relPos.referencePosition().value(); if ( posValue >= KChartEnums::PositionNorthWest && posValue <= KChartEnums::PositionWest ) { // rotate 90 degrees clockwise posValue = static_cast< KChartEnums::PositionValue >( posValue + 2 ); if ( posValue > KChartEnums::PositionWest ) { // wraparound posValue = static_cast< KChartEnums::PositionValue >( posValue - ( KChartEnums::PositionWest - KChartEnums::PositionNorthWest ) ); } relPos.setReferencePosition( Position( posValue ) ); } } const QPointF referencePoint = relPos.referencePoint(); if ( !diagram->coordinatePlane()->isVisiblePoint( referencePoint ) ) { continue; } const qreal fontHeight = cachedFontMetrics( dva.textAttributes(). calculatedFont( plane, KChartEnums::MeasureOrientationMinimum ), diagram )->height(); // Note: When printing data value texts and padding's Measure is using automatic reference area // detection, the font height is used as reference size for both horizontal and vertical // padding. QSizeF relativeMeasureSize( fontHeight, fontHeight ); if ( !dva.textAttributes().hasRotation() ) { TextAttributes ta = dva.textAttributes(); ta.setRotation( favoriteAngle ); dva.setTextAttributes( ta ); } // get the size of the label text using a subset of the information going into the final layout const QString text = formatDataValueText( dva, index, value ); QTextDocument doc; doc.setDocumentMargin( 0 ); if ( Qt::mightBeRichText( text ) ) { doc.setHtml( text ); } else { doc.setPlainText( text ); } const QFont calculatedFont( dva.textAttributes() .calculatedFont( plane, KChartEnums::MeasureOrientationMinimum ) ); doc.setDefaultFont( calculatedFont ); const QRectF plainRect = doc.documentLayout()->frameBoundingRect( doc.rootFrame() ); /** * A few hints on how the positioning of the text frame is done: * * Let's assume we have a bar chart, a text for a positive value * to be drawn, and "North" as attrs.positivePosition(). * * The reference point (pos) is then set to the top center point * of a bar. The offset now depends on the alignment: * * Top: text is centered horizontally to the bar, bottom of * text frame starts at top of bar * * Bottom: text is centered horizontally to the bar, top of * text frame starts at top of bar * * Center: text is centered horizontally to the bar, center * line of text frame is same as top of bar * * TopLeft: right edge of text frame is horizontal center of * bar, bottom of text frame is top of bar. * * ... * * Positive and negative value labels are treated equally, "North" * also refers to the top of a negative bar, and *not* to the bottom. * * * "NorthEast" likewise refers to the top right edge of the bar, * "NorthWest" to the top left edge of the bar, and so on. * * In other words, attrs.positivePosition() always refers to a * position of the *bar*, and relPos.alignment() always refers * to an alignment of the text frame relative to this position. */ QTransform transform; { // move to the general area where the label should be QPointF calcPoint = relPos.calculatedPoint( relativeMeasureSize ); transform.translate( calcPoint.x(), calcPoint.y() ); // align the text rect; find out by how many half-widths / half-heights to move. int dx = -1; if ( relPos.alignment() & Qt::AlignLeft ) { dx -= 1; } else if ( relPos.alignment() & Qt::AlignRight ) { dx += 1; } int dy = -1; if ( relPos.alignment() & Qt::AlignTop ) { dy -= 1; } else if ( relPos.alignment() & Qt::AlignBottom ) { dy += 1; } transform.translate( qreal( dx ) * plainRect.width() * 0.5, qreal( dy ) * plainRect.height() * 0.5 ); // rotate the text rect around its center transform.translate( plainRect.center().x(), plainRect.center().y() ); int rotation = dva.textAttributes().rotation(); if ( !isPositive && dva.mirrorNegativeValueTextRotation() ) { rotation *= -1; } transform.rotate( rotation ); transform.translate( -plainRect.center().x(), -plainRect.center().y() ); } QPainterPath labelArea; //labelArea.addPolygon( transform.mapToPolygon( plainRect.toRect() ) ); //labelArea.closeSubpath(); // Not doing that because QTransform has a special case for 180° that gives a different than // usual ordering of the points in the polygon returned by mapToPolygon( const QRect & ). // We expect a particular ordering in paintDataValueTextsAndMarkers() by using elementAt( 0 ), // and similar things might happen elsewhere. labelArea.addPolygon( transform.map( QPolygon( plainRect.toRect(), true ) ) ); // store the label geometry and auxiliary data cache->paintReplay.append( LabelPaintInfo( it.key(), dva, labelArea, referencePoint, value >= 0.0, text ) ); } }
bool EnhancedPathCommand::execute() { /* * The parameters of the commands are in viewbox coordinates, which have * to be converted to the shapes coordinate system by calling viewboxToShape * on the enhanced path the command works on. * Parameters which resemble angles are angles corresponding to the viewbox * coordinate system. Those have to be transformed into angles corresponding * to the normal mathematically coordinate system to be used for the arcTo * drawing routine. This is done by computing (2*M_PI - angle). */ QList<QPointF> points = pointsFromParameters(); const int pointsCount = points.size(); switch (m_command.unicode()) { // starts new subpath at given position (x y) + case 'M': if (!pointsCount) return false; m_parent->moveTo(points[0]); if (pointsCount > 1) for (int i = 1; i < pointsCount; i++) m_parent->lineTo(points[i]); break; // line from current point (x y) + case 'L': foreach(const QPointF &point, points) m_parent->lineTo(point); break; // cubic bezier curve from current point (x1 y1 x2 y2 x y) + case 'C': for (int i = 0; i < pointsCount; i+=3) m_parent->curveTo(points[i], points[i+1], points[i+2]); break; // closes the current subpath case 'Z': m_parent->close(); break; // ends the current set of subpaths case 'N': // N just ends the complete path break; // no fill for current set of subpaths case 'F': // TODO implement me break; // no stroke for current set of subpaths case 'S': // TODO implement me break; // segment of an ellipse (x y w h t0 t1) + case 'T': // same like T but with implied movement to starting point (x y w h t0 t1) + case 'U': { bool lineTo = m_command.unicode() == 'T'; for (int i = 0; i < pointsCount; i+=3) { const QPointF &radii = points[i+1]; const QPointF &angles = points[i+2] / rad2deg; // compute the ellipses starting point QPointF start(radii.x() * cos(angles.x()), -1 * radii.y() * sin(angles.x())); qreal sweepAngle = degSweepAngle(points[i+2].x(), points[i+2].y(), false); if (lineTo) m_parent->lineTo(points[i] + start); else m_parent->moveTo(points[i] + start); m_parent->arcTo(radii.x(), radii.y(), points[i+2].x(), sweepAngle); } break; } // counter-clockwise arc (x1 y1 x2 y2 x3 y3 x y) + case 'A': // the same as A, with implied moveto to the starting point (x1 y1 x2 y2 x3 y3 x y) + case 'B': // clockwise arc (x1 y1 x2 y2 x3 y3 x y) + case 'W': // the same as W, but implied moveto (x1 y1 x2 y2 x3 y3 x y) + case 'V': { bool lineTo = ((m_command.unicode() == 'A') || (m_command.unicode() == 'W')); bool clockwise = ((m_command.unicode() == 'W') || (m_command.unicode() == 'V')); for (int i = 0; i < pointsCount; i+=4) { QRectF bbox = rectFromPoints(points[i], points[i+1]); QPointF center = bbox.center(); qreal rx = 0.5 * bbox.width(); qreal ry = 0.5 * bbox.height(); if (rx == 0) { rx = 1; } if (ry == 0) { ry = 1; } QPointF startRadialVector = points[i+2] - center; QPointF endRadialVector = points[i+3] - center; // convert from ellipse space to unit-circle space qreal x0 = startRadialVector.x() / rx; qreal y0 = startRadialVector.y() / ry; qreal x1 = endRadialVector.x() / rx; qreal y1 = endRadialVector.y() / ry; qreal startAngle = angleFromPoint(QPointF(x0,y0)); qreal stopAngle = angleFromPoint(QPointF(x1,y1)); // we are moving counter-clockwise to the end angle qreal sweepAngle = radSweepAngle(startAngle, stopAngle, clockwise); // compute the starting point to draw the line to // as the point x3 y3 is not on the ellipse, spec says the point define radial vector QPointF startPoint(rx * cos(startAngle), ry * sin(2*M_PI - startAngle)); // if A or W is first command in enhanced path // move to the starting point bool isFirstCommandInPath = (m_parent->subpathCount() == 0); bool isFirstCommandInSubpath = m_parent->isClosedSubpath( m_parent->subpathCount() - 1 ); if (lineTo && !isFirstCommandInPath && !isFirstCommandInSubpath) { m_parent->lineTo(center + startPoint); } else { m_parent->moveTo(center + startPoint); } m_parent->arcTo(rx, ry, startAngle * rad2deg, sweepAngle * rad2deg); } break; } // elliptical quadrant (initial segment tangential to x-axis) (x y) + case 'X': { KoPathPoint * lastPoint = lastPathPoint(); bool xDir = true; foreach (const QPointF &point, points) { qreal rx = point.x() - lastPoint->point().x(); qreal ry = point.y() - lastPoint->point().y(); qreal startAngle = xDir ? (ry > 0.0 ? 90.0 : 270.0) : (rx < 0.0 ? 0.0 : 180.0); qreal sweepAngle = xDir ? (rx*ry < 0.0 ? 90.0 : -90.0) : (rx*ry > 0.0 ? 90.0 : -90.0); lastPoint = m_parent->arcTo(fabs(rx), fabs(ry), startAngle, sweepAngle); xDir = !xDir; } break; } // elliptical quadrant (initial segment tangential to y-axis) (x y) + case 'Y': { KoPathPoint * lastPoint = lastPathPoint(); bool xDir = false; foreach (const QPointF &point, points) { qreal rx = point.x() - lastPoint->point().x(); qreal ry = point.y() - lastPoint->point().y(); qreal startAngle = xDir ? (ry > 0.0 ? 90.0 : 270.0) : (rx < 0.0 ? 0.0 : 180.0); qreal sweepAngle = xDir ? (rx*ry < 0.0 ? 90.0 : -90.0) : (rx*ry > 0.0 ? 90.0 : -90.0); lastPoint = m_parent->arcTo(fabs(rx), fabs(ry), startAngle, sweepAngle); xDir = !xDir; } break; }
static QPointF leftCenter(const QRectF &rect) { return QPointF(rect.left(), rect.center().y()); }
void GraphAggRenderer::copyToWindow(QPainter *d, int x, int y, int w, int h) { if (NULL == d || m_data->tiles == 0) { return; } QTime time; time.start(); GraphLib::TileManager *tm = m_data->tiles; QTransform t; t.translate(-1 * x, -1 * y); QPainter &painter = *d; painter.setTransform(t); int i, j; for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT))) { for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH))) { GraphLib::Tile *t = tm->get_tile(j, i, true, false); if (t == NULL) continue; Tile::release(t, false); if (1 == needRedraw(QRectF(j, i, 1, 1))) { t = tm->get_tile(j, i, true, true); int tile_x, tile_y; tm->get_tile_coordinates(t, &tile_x, &tile_y); QImage image(t->data, t->ewidth, t->eheight, QImage::Format_ARGB32_Premultiplied); memset(t->data, 0, t->size); agg::trans_affine mtx; QRectF extent = calculate_extent(m_data->bbox); mtx *= agg::trans_affine_translation(-1*extent.center().x(), -1*extent.center().y()); mtx *= agg::trans_affine_translation(tm->width/2, tm->height/2); mtx *= agg::trans_affine_translation(-1 * tile_x, -1 * tile_y); render(&image, QRectF(tile_x, tile_y, w, h), &mtx); Tile::release(t, true); int index = tm->get_tile_num(tile_x, tile_y); m_data->redrawFlags[index] = 0; } t = tm->get_tile(j, i, true, false); int tile_x, tile_y; tm->get_tile_coordinates(t, &tile_x, &tile_y); QImage image(t->data, t->ewidth, t->eheight, QImage::Format_ARGB32_Premultiplied); int w = t->ewidth; int h = t->eheight; QRectF targetRect(tile_x, tile_y, w, h); QRectF sourceRect(0, 0, w, h); painter.drawImage(targetRect, image, sourceRect); Tile::release(t, false); #ifdef TILE_PROFILING // 显示tile painter.setPen(Qt::red); int index = tm->get_tile_num(tile_x, tile_y); //image.save(QString("%1.png").arg(index)); painter.drawText(QRectF(tile_x, tile_y, w, h), Qt::AlignCenter, QString("%1").arg(index)); painter.drawRect(QRectF(tile_x, tile_y, w, h)); #endif } // j循环 } // i循环 //qDebug() << "Time elapsed: " << time.elapsed() << " md."; }
static QPointF rightCenter(const QRectF &rect) { return QPointF(rect.right(), rect.center().y()); }
/*! \brief Draw the marker at the knob's front \param painter Painter \param rect Bounding rectangle of the knob without scale \param angle Angle of the marker in degrees */ void QwtKnob::drawMarker( QPainter *painter, const QRectF &rect, double angle ) const { if ( d_data->markerStyle == NoMarker || !isValid() ) return; const double radians = angle * M_PI / 180.0; const double sinA = -qFastSin( radians ); const double cosA = qFastCos( radians ); const double xm = rect.center().x(); const double ym = rect.center().y(); const double margin = 4.0; double radius = 0.5 * ( rect.width() - d_data->borderWidth ) - margin; if ( radius < 1.0 ) radius = 1.0; switch ( d_data->markerStyle ) { case Notch: case Nub: { const double dotWidth = qMin( double( d_data->markerSize ), radius); const double dotCenterDist = radius - 0.5 * dotWidth; if ( dotCenterDist > 0.0 ) { const QPointF center( xm - sinA * dotCenterDist, ym - cosA * dotCenterDist ); QRectF ellipse( 0.0, 0.0, dotWidth, dotWidth ); ellipse.moveCenter( center ); QColor c1 = palette().color( QPalette::Light ); QColor c2 = palette().color( QPalette::Mid ); if ( d_data->markerStyle == Notch ) qSwap( c1, c2 ); QLinearGradient gradient( ellipse.topLeft(), ellipse.bottomRight() ); gradient.setColorAt( 0.0, c1 ); gradient.setColorAt( 1.0, c2 ); painter->setPen( Qt::NoPen ); painter->setBrush( gradient ); painter->drawEllipse( ellipse ); } break; } case Dot: { const double dotWidth = qMin( double( d_data->markerSize ), radius); const double dotCenterDist = radius - 0.5 * dotWidth; if ( dotCenterDist > 0.0 ) { const QPointF center( xm - sinA * dotCenterDist, ym - cosA * dotCenterDist ); QRectF ellipse( 0.0, 0.0, dotWidth, dotWidth ); ellipse.moveCenter( center ); painter->setPen( Qt::NoPen ); painter->setBrush( palette().color( QPalette::ButtonText ) ); painter->drawEllipse( ellipse ); } break; } case Tick: { const double rb = qMax( radius - d_data->markerSize, 1.0 ); const double re = radius; const QLineF line( xm - sinA * rb, ym - cosA * rb, xm - sinA * re, ym - cosA * re ); QPen pen( palette().color( QPalette::ButtonText ), 0 ); pen.setCapStyle( Qt::FlatCap ); painter->setPen( pen ); painter->drawLine ( line ); break; } #if 0 case Triangle: { const double rb = qMax( radius - d_data->markerSize, 1.0 ); const double re = radius; painter->translate( rect.center() ); painter->rotate( angle - 90.0 ); QPolygonF polygon; polygon += QPointF( re, 0.0 ); polygon += QPointF( rb, 0.5 * ( re - rb ) ); polygon += QPointF( rb, -0.5 * ( re - rb ) ); painter->setPen( Qt::NoPen ); painter->setBrush( palette().color( QPalette::Text ) ); painter->drawPolygon( polygon ); break; } #endif default: break; } }
static QPointF bottomCenter(const QRectF &rect) { return QPointF(rect.center().x(), rect.bottom()); }
void PageViewportControllerClientQt::zoomToAreaGestureEnded(const QPointF& touchPoint, const QRectF& targetArea) { // This can only happen as a result of a user interaction. ASSERT(m_controller->hadUserInteraction()); if (!targetArea.isValid()) return; if (m_scrollChange.inProgress() || m_scaleChange.inProgress()) return; const float margin = 10; // We want at least a little bit of margin. QRectF endArea = targetArea.adjusted(-margin, -margin, margin, margin); const QRectF viewportRect = m_viewportItem->boundingRect(); qreal minViewportScale = qreal(2.5); qreal targetScale = viewportRect.size().width() / endArea.size().width(); targetScale = m_controller->innerBoundedViewportScale(qMin(minViewportScale, targetScale)); qreal currentScale = m_pageItem->contentsScale(); // We want to end up with the target area filling the whole width of the viewport (if possible), // and centralized vertically where the user requested zoom. Thus our hotspot is the center of // the targetArea x-wise and the requested zoom position, y-wise. const QPointF hotspot = QPointF(endArea.center().x(), touchPoint.y()); const QPointF viewportHotspot = viewportRect.center(); QPointF endPosition = hotspot - viewportHotspot / targetScale; endPosition = m_controller->clampViewportToContents(endPosition, targetScale); QRectF endVisibleContentRect(endPosition, viewportRect.size() / targetScale); enum { ZoomIn, ZoomBack, ZoomOut, NoZoom } zoomAction = ZoomIn; // Zoom back out if attempting to scale to the same current scale, or // attempting to continue scaling out from the inner most level. // Use fuzzy compare with a fixed error to be able to deal with largish differences due to pixel rounding. if (!m_scaleStack.isEmpty() && fuzzyCompare(targetScale, currentScale, 0.01)) { // If moving the viewport would expose more of the targetRect and move at least 40 pixels, update position but do not scale out. QRectF currentContentRect(m_viewportItem->mapRectToWebContent(viewportRect)); QRectF targetIntersection = endVisibleContentRect.intersected(targetArea); if (!currentContentRect.contains(targetIntersection) && (qAbs(endVisibleContentRect.top() - currentContentRect.top()) >= 40 || qAbs(endVisibleContentRect.left() - currentContentRect.left()) >= 40)) zoomAction = NoZoom; else zoomAction = ZoomBack; } else if (fuzzyCompare(targetScale, m_zoomOutScale, 0.01)) zoomAction = ZoomBack; else if (targetScale < currentScale) zoomAction = ZoomOut; switch (zoomAction) { case ZoomIn: m_scaleStack.append(ScaleStackItem(currentScale, m_viewportItem->contentPos().x() / currentScale)); m_zoomOutScale = targetScale; break; case ZoomBack: { if (m_scaleStack.isEmpty()) { targetScale = m_controller->minimumContentsScale(); endPosition.setY(hotspot.y() - viewportHotspot.y() / targetScale); endPosition.setX(0); m_zoomOutScale = 0; } else { ScaleStackItem lastScale = m_scaleStack.takeLast(); targetScale = lastScale.scale; // Recalculate endPosition and clamp it according to the new scale. endPosition.setY(hotspot.y() - viewportHotspot.y() / targetScale); endPosition.setX(lastScale.xPosition); } endPosition = m_controller->clampViewportToContents(endPosition, targetScale); endVisibleContentRect = QRectF(endPosition, viewportRect.size() / targetScale); break; } case ZoomOut: // Unstack all scale-levels deeper than the new level, so a zoom-back won't end up zooming in. while (!m_scaleStack.isEmpty() && m_scaleStack.last().scale >= targetScale) m_scaleStack.removeLast(); m_zoomOutScale = targetScale; break; case NoZoom: break; } animateContentRectVisible(endVisibleContentRect); }
void TupGraphicsScene::addTweeningObjects(int photogram) { QList<TupGraphicObject *> tweenList = k->scene->tweeningGraphicObjects(); for (int i=0; i < tweenList.count(); i++) { TupGraphicObject *object = tweenList.at(i); if (object->frame()->layer()->isVisible()) { int origin = object->frame()->index(); if (TupItemTweener *tween = object->tween()) { int adjustX = object->item()->boundingRect().width()/2; int adjustY = object->item()->boundingRect().height()/2; if (origin == photogram) { TupTweenerStep *stepItem = tween->stepAt(0); object->item()->setToolTip(tween->tweenType() + ": " + tween->name() + tr("/Step: 0")); if (tween->type() == TupItemTweener::Compound) { object->item()->setTransformOriginPoint(tween->transformOriginPoint()); if (stepItem->has(TupTweenerStep::Position)) { // tFatal() << "TupGraphicsScene::addTweeningObjects() - Applying position..."; QPointF point = QPoint(-adjustX, -adjustY); object->setLastTweenPos(stepItem->position() + point); object->item()->setPos(tween->transformOriginPoint()); } if (stepItem->has(TupTweenerStep::Rotation)) { QRectF rect = object->item()->sceneBoundingRect(); object->item()->setTransformOriginPoint(rect.center()); double angle = stepItem->rotation(); object->item()->setRotation(angle); // tFatal() << "TupGraphicsScene::addTweeningObjects() - Applying rotation - Angle: " << angle; } else { // tFatal() << "TupGraphicsScene::addTweeningObjects() - No rotation parameter!"; } } else { if (stepItem->has(TupTweenerStep::Position)) { QPointF point = QPoint(-adjustX, -adjustY); object->setLastTweenPos(stepItem->position() + point); object->item()->setPos(tween->transformOriginPoint()); } if (stepItem->has(TupTweenerStep::Rotation)) { double angle = stepItem->rotation(); object->item()->setTransformOriginPoint(tween->transformOriginPoint()); object->item()->setRotation(angle); } if (stepItem->has(TupTweenerStep::Scale)) { QPointF point = tween->transformOriginPoint(); object->item()->setTransformOriginPoint(point); object->item()->setScale(1.0); } if (stepItem->has(TupTweenerStep::Shear)) { QTransform transform; transform.shear(0, 0); object->item()->setTransform(transform); } if (stepItem->has(TupTweenerStep::Coloring)) { QColor itemColor = stepItem->color(); if (TupPathItem *path = qgraphicsitem_cast<TupPathItem *>(object->item())) { QPen pen = path->pen(); pen.setColor(itemColor); path->setPen(pen); } else if (TupEllipseItem *ellipse = qgraphicsitem_cast<TupEllipseItem *>(object->item())) { QPen pen = ellipse->pen(); pen.setColor(itemColor); ellipse->setPen(pen); } else if (TupLineItem *line = qgraphicsitem_cast<TupLineItem *>(object->item())) { QPen pen = line->pen(); pen.setColor(itemColor); line->setPen(pen); } else if (TupRectItem *rect = qgraphicsitem_cast<TupRectItem *>(object->item())) { QPen pen = rect->pen(); pen.setColor(itemColor); rect->setPen(pen); } } if (stepItem->has(TupTweenerStep::Opacity)) object->item()->setOpacity(stepItem->opacity()); } } else if ((origin < photogram) && (photogram < origin + tween->frames())) { int step = photogram - origin; TupTweenerStep *stepItem = tween->stepAt(step); object->item()->setToolTip(tween->tweenType() + ": " + tween->name() + tr("/Step: ") + QString::number(step)); if (tween->type() == TupItemTweener::Compound) { if (stepItem->has(TupTweenerStep::Position)) { qreal dx = stepItem->position().x() - (object->lastTweenPos().x() + adjustX); qreal dy = stepItem->position().y() - (object->lastTweenPos().y() + adjustY); object->item()->moveBy(dx, dy); QPointF point = QPoint(-adjustX, -adjustY); object->setLastTweenPos(stepItem->position() + point); } if (stepItem->has(TupTweenerStep::Rotation)) { double angle = stepItem->rotation(); object->item()->setRotation(angle); // tFatal() << "TupGraphicsScene::addTweeningObjects() - Applying rotation - Angle: " << angle; } addGraphicObject(object); } else { if (stepItem->has(TupTweenerStep::Position)) { qreal dx = stepItem->position().x() - (object->lastTweenPos().x() + adjustX); qreal dy = stepItem->position().y() - (object->lastTweenPos().y() + adjustY); object->item()->moveBy(dx, dy); QPointF point = QPoint(-adjustX, -adjustY); object->setLastTweenPos(stepItem->position() + point); } if (stepItem->has(TupTweenerStep::Rotation)) { double angle = stepItem->rotation(); object->item()->setRotation(angle); } if (stepItem->has(TupTweenerStep::Scale)) { QPointF point = tween->transformOriginPoint(); double scaleX = stepItem->horizontalScale(); double scaleY = stepItem->verticalScale(); QTransform transform; transform.translate(point.x(), point.y()); transform.scale(scaleX, scaleY); transform.translate(-point.x(), -point.y()); object->item()->setTransform(transform); } if (stepItem->has(TupTweenerStep::Shear)) { QPointF point = tween->transformOriginPoint(); double shearX = stepItem->horizontalShear(); double shearY = stepItem->verticalShear(); QTransform transform; transform.translate(point.x(), point.y()); transform.shear(shearX, shearY); transform.translate(-point.x(), -point.y()); object->item()->setTransform(transform); } if (stepItem->has(TupTweenerStep::Coloring)) { QColor itemColor = stepItem->color(); if (TupPathItem *path = qgraphicsitem_cast<TupPathItem *>(object->item())) { QPen pen = path->pen(); pen.setColor(itemColor); path->setPen(pen); } else if (TupEllipseItem *ellipse = qgraphicsitem_cast<TupEllipseItem *>(object->item())) { QPen pen = ellipse->pen(); pen.setColor(itemColor); ellipse->setPen(pen); } else if (TupLineItem *line = qgraphicsitem_cast<TupLineItem *>(object->item())) { QPen pen = line->pen(); pen.setColor(itemColor); line->setPen(pen); } else if (TupRectItem *rect = qgraphicsitem_cast<TupRectItem *>(object->item())) { QPen pen = rect->pen(); pen.setColor(itemColor); rect->setPen(pen); } } addGraphicObject(object); if (stepItem->has(TupTweenerStep::Opacity)) object->item()->setOpacity(stepItem->opacity()); } } } } } }
void MainWindow::on_filesTable_currentCellChanged(int currentRow, int /*currentColumn*/, int /*previousRow*/, int /*previousColumn*/) { ui->stackedWidget->setCurrentWidget(ui->emptyPage); QString resourceName = ui->filesTable->item(currentRow, 0)->text(); QRectF boundingBox; m_scene.clear(); if(resourceName.endsWith(".pcx")) { ImageItem *item = new ImageItem(readPCXimage(resourceName)); m_scene.addItem(item); boundingBox = item->boundingRect(); ui->stackedWidget->setCurrentWidget(ui->graphicsPage); } if(resourceName.endsWith(".gob")) { std::vector<GobImage> gobImages = m_resourceContainer.readGOB( resourceName.toStdString() ); QPointF coordinates; for(const GobImage &gobImage : gobImages) { ImageItem *item = new ImageItem(readGobImage(gobImage)); m_scene.addItem(item); item->setPos(coordinates); coordinates.rx() += gobImage.width() + 2; QRectF itemBB = item->mapToScene(item->boundingRect()).boundingRect(); boundingBox.setRight( qMax( boundingBox.right(), itemBB.right() ) ); boundingBox.setBottom( qMax( boundingBox.bottom(), item->boundingRect().bottom() ) ); m_scene.addRect(itemBB, QPen(QColor(127, 127, 127, 200))); } ui->stackedWidget->setCurrentWidget(ui->graphicsPage); } if(resourceName == "levelmap.txt") { ImageItem *item = new ImageItem(readPCXimage("level.pcx")); m_scene.addItem(item); boundingBox = item->boundingRect(); std::vector<char> entryData = m_resourceContainer.readLevel( resourceName.toStdString() ); std::vector<char>::size_type index = 0; for(int row = 0; row < 16; row++) { for(int column = 0; column < 22; column++) { QColor blockColor; switch( entryData[index] ) { case '0': blockColor.setRgb(0, 0, 0, 0); break; case '1': blockColor.setRgb(200, 100, 0, 200); break; case '2': blockColor.setRgb(0, 60, 85, 200); break; case '3': blockColor.setRgb(140, 220, 255, 200); break; case '4': blockColor.setRgb(200, 200, 0, 200); break; default: blockColor.setRgb(200, 0, 0, 200); } QPen pen; pen.setWidth(0); m_scene.addRect(QRect(column * 16, row * 16, 16, 16), QPen(pen), QBrush(blockColor)); index++; } index += 2; // Skip "\r\n" at the end of line; } ui->stackedWidget->setCurrentWidget(ui->graphicsPage); } m_scene.setSceneRect(boundingBox); ui->graphicsView->setZoom(1.0); ui->graphicsView->centerOn(boundingBox.center()); if(resourceName.endsWith(".smp")) { ui->stackedWidget->setCurrentWidget(ui->soundPage); ui->soundPage->setSoundData(readSMP(resourceName)); ui->soundPage->setSoundDescription("Raw 8 bit signed 22050Hz"); } if(resourceName.endsWith(".mod")) { ui->stackedWidget->setCurrentWidget(ui->musicPage); ui->musicPage->setMusicData(readMOD(resourceName)); } }
void QtViewportInteractionEngine::zoomToAreaGestureEnded(const QPointF& touchPoint, const QRectF& targetArea) { if (!targetArea.isValid()) return; if (scrollAnimationActive() || scaleAnimationActive()) return; m_hadUserInteraction = true; const int margin = 10; // We want at least a little bit of margin. QRectF endArea = itemRectFromCSS(targetArea.adjusted(-margin, -margin, margin, margin)); const QRectF viewportRect = m_viewport->boundingRect(); qreal targetCSSScale = viewportRect.size().width() / endArea.size().width(); qreal endCSSScale = innerBoundedCSSScale(qMin(targetCSSScale, qreal(2.5))); qreal endItemScale = itemScaleFromCSS(endCSSScale); qreal currentScale = m_content->contentsScale(); // We want to end up with the target area filling the whole width of the viewport (if possible), // and centralized vertically where the user requested zoom. Thus our hotspot is the center of // the targetArea x-wise and the requested zoom position, y-wise. const QPointF hotspot = QPointF(endArea.center().x(), itemCoordFromCSS(touchPoint.y())); const QPointF viewportHotspot = viewportRect.center(); QPointF endPosition = hotspot * endCSSScale - viewportHotspot; QRectF endPosRange = computePosRangeForItemAtScale(endItemScale); endPosition = boundPosition(endPosRange.topLeft(), endPosition, endPosRange.bottomRight()); QRectF endVisibleContentRect(endPosition / endItemScale, viewportRect.size() / endItemScale); enum { ZoomIn, ZoomBack, ZoomOut, NoZoom } zoomAction = ZoomIn; if (!m_scaleStack.isEmpty()) { // Zoom back out if attempting to scale to the same current scale, or // attempting to continue scaling out from the inner most level. // Use fuzzy compare with a fixed error to be able to deal with largish differences due to pixel rounding. if (fuzzyCompare(endItemScale, currentScale, 0.01)) { // If moving the viewport would expose more of the targetRect and move at least 40 pixels, update position but do not scale out. QRectF currentContentRect(m_viewport->contentPos() / currentScale, viewportRect.size() / currentScale); QRectF targetIntersection = endVisibleContentRect.intersected(targetArea); if (!currentContentRect.contains(targetIntersection) && (qAbs(endVisibleContentRect.top() - currentContentRect.top()) >= 40 || qAbs(endVisibleContentRect.left() - currentContentRect.left()) >= 40)) zoomAction = NoZoom; else zoomAction = ZoomBack; } else if (fuzzyCompare(endItemScale, m_zoomOutScale, 0.01)) zoomAction = ZoomBack; else if (endItemScale < currentScale) zoomAction = ZoomOut; } switch (zoomAction) { case ZoomIn: m_scaleStack.append(ScaleStackItem(currentScale, m_viewport->contentPos().x())); m_zoomOutScale = endItemScale; break; case ZoomBack: { ScaleStackItem lastScale = m_scaleStack.takeLast(); endItemScale = lastScale.scale; endCSSScale = cssScaleFromItem(lastScale.scale); // Recalculate endPosition and bound it according to new scale. endPosition.setY(hotspot.y() * endCSSScale - viewportHotspot.y()); endPosition.setX(lastScale.xPosition); endPosRange = computePosRangeForItemAtScale(endItemScale); endPosition = boundPosition(endPosRange.topLeft(), endPosition, endPosRange.bottomRight()); endVisibleContentRect = QRectF(endPosition / endItemScale, viewportRect.size() / endItemScale); break; } case ZoomOut: // Unstack all scale-levels deeper than the new level, so a zoom-back won't end up zooming in. while (!m_scaleStack.isEmpty() && m_scaleStack.last().scale >= endItemScale) m_scaleStack.removeLast(); m_zoomOutScale = endItemScale; break; case NoZoom: break; } animateItemRectVisible(endVisibleContentRect); }
static QPainterPath qwtCombinePathList( const QRectF &rect, const QList<QPainterPath> &pathList ) { if ( pathList.isEmpty() ) return QPainterPath(); QPainterPath ordered[8]; // starting top left for ( int i = 0; i < pathList.size(); i++ ) { int index = -1; QPainterPath subPath = pathList[i]; const QRectF br = pathList[i].controlPointRect(); if ( br.center().x() < rect.center().x() ) { if ( br.center().y() < rect.center().y() ) { if ( qAbs( br.top() - rect.top() ) < qAbs( br.left() - rect.left() ) ) { index = 1; } else { index = 0; } } else { if ( qAbs( br.bottom() - rect.bottom() ) < qAbs( br.left() - rect.left() ) ) { index = 6; } else { index = 7; } } if ( subPath.currentPosition().y() > br.center().y() ) qwtRevertPath( subPath ); } else { if ( br.center().y() < rect.center().y() ) { if ( qAbs( br.top() - rect.top() ) < qAbs( br.right() - rect.right() ) ) { index = 2; } else { index = 3; } } else { if ( qAbs( br.bottom() - rect.bottom() ) < qAbs( br.right() - rect.right() ) ) { index = 5; } else { index = 4; } } if ( subPath.currentPosition().y() < br.center().y() ) qwtRevertPath( subPath ); } ordered[index] = subPath; } for ( int i = 0; i < 4; i++ ) { if ( ordered[ 2 * i].isEmpty() != ordered[2 * i + 1].isEmpty() ) { // we don't accept incomplete rounded borders return QPainterPath(); } } const QPolygonF corners( rect ); QPainterPath path; //path.moveTo( rect.topLeft() ); for ( int i = 0; i < 4; i++ ) { if ( ordered[2 * i].isEmpty() ) { path.lineTo( corners[i] ); } else { path.connectPath( ordered[2 * i] ); path.connectPath( ordered[2 * i + 1] ); } } path.closeSubpath(); #if 0 return path.simplified(); #else return path; #endif }
void SCgAlphabet::paintStruct(QPainter *painter, const QColor &color, const QRectF &boundRect, const SCgNodeStructType &type) { QPen pen = QPen(QBrush(color, Qt::SolidPattern), 2, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); painter->setPen(pen); // structure types QPointF c, d; switch (type) { case Struct: float w, h; w = boundRect.width() / 10.f; h = boundRect.height() / 10.f; painter->setBrush(QBrush(color, Qt::SolidPattern)); painter->drawEllipse(-w, -h, w * 2 - 1, h * 2 - 1); painter->setBrush(QBrush(Qt::NoBrush)); break; case Abstract: { QPen p = painter->pen(); p.setWidthF(0); painter->setPen(p); qreal x1, x2, top, bottom; top = boundRect.top(); bottom = boundRect.bottom(); x1 = boundRect.left(); x2 = boundRect.right(); for (qreal y = top; y < bottom; y += 3) painter->drawLine(QLineF(x1, y, x2, y)); break; } case Material: { QPen p = painter->pen(); p.setWidthF(0); painter->setPen(p); qreal y1, y2, left, right; left = boundRect.left(); right = boundRect.right(); qreal dist = right - left; y1 = boundRect.top(); y2 = boundRect.bottom(); for (qreal d = 0; d <= dist; d += 4.2) { painter->drawLine(QLineF(left + d, y1, left, y1 + d)); painter->drawLine(QLineF(right - d, y2, right, y2 - d)); } break; } case Tuple: c = boundRect.center(); d = QPointF(boundRect.width() / 2.0, 0.f); painter->drawLine(c - d, c + d); break; case Role: c = boundRect.center(); d = QPointF(boundRect.width() / 2.0, 0.f); painter->drawLine(c - d, c + d); d = QPointF(0.f, boundRect.height() / 2.0); painter->drawLine(c - d, c + d); break; case Relation: painter->drawLine(boundRect.topLeft(), boundRect.bottomRight()); painter->drawLine(boundRect.topRight(), boundRect.bottomLeft()); break; case Group: painter->drawLine(boundRect.topLeft(), boundRect.bottomRight()); painter->drawLine(boundRect.topRight(), boundRect.bottomLeft()); painter->drawLine(boundRect.left(), boundRect.center().y(), boundRect.right(), boundRect.center().y()); break; default: break; } }
bool MapHelperUniversal::touch(QTouchEvent *event) { Q_D(MapHelperUniversal); D_MAP; if (!d->touch) return false; d->touch->touchPoints.clear(); for (int i = 0; i < event->touchPoints().count(); ++i) { if (!(event->touchPoints().at(i).state() & Qt::TouchPointReleased)) { d->touch->touchPoints << event->touchPoints().at(i); } } switch (event->type()) { case QEvent::TouchBegin: d->touch->tapState = MapHelperTouch::tapNone; case QEvent::TouchUpdate: { d->touch->touchPoints.clear(); for (int i = 0; i < event->touchPoints().count(); ++i) { if (!(event->touchPoints().at(i).state() & Qt::TouchPointReleased)) { d->touch->touchPoints << event->touchPoints().at(i); } } d->touch->updateTouchPosition(); break; } case QEvent::TouchEnd: { if (d->touch->tapState == MapHelperTouch::tapDown) { d->touch->tapState = MapHelperTouch::tapUp; MapCamera *cam = d->map->camera(); MapOptions opt = d->map->settings()->mapOptions(); QRectF rgn; if (!d->touch->touchPoints.isEmpty()) rgn = d->touch->touchPoints.first().sceneRect(); else if (!event->touchPoints().isEmpty()) rgn = event->touchPoints().first().sceneRect(); rgn.moveCenter(rgn.center() - d->map->position()); #warning ERROR #if 0 QList<MapObject*> lo(d->map->selectObjects(rgn, cam)); QList<MapObject*> reslo; reslo.reserve(lo.size()); foreach (MapObject *mo, lo) if (mo->drawer()->hit(mo, rgn, cam, opt)) reslo.append(mo); MHETap mhtap(reslo, rgn.center()); emit d->handler(&mhtap); #endif } d->touch->touchPoints.clear(); d->touch->updateTouchPosition(); break; } default: // no-op break; }
static void drawDial ( const QStyleOptionSlider *option, QPainter *painter ) { QPalette pal = option->palette; QColor buttonColor = pal.button().color(); const int width = option->rect.width(); const int height = option->rect.height(); const bool enabled = option->state & QStyle::State_Enabled; qreal r = qMin(width, height) / 2; r -= r/50; const qreal penSize = r/20.0; painter->save(); painter->setRenderHint(QPainter::Antialiasing); // Draw notches if (option->subControls & QStyle::SC_DialTickmarks) { painter->setPen(option->palette.dark().color().darker(120)); painter->drawLines(calcLines(option)); } // Cache dial background QString a = QString::fromLatin1("qdial"); QRect rect = option->rect; QPixmap internalPixmapCache; QImage imageCache; QPainter *p = painter; QString unique = uniqueName((a), option, option->rect.size()); int txType = painter->deviceTransform().type() | painter->worldTransform().type(); bool doPixmapCache = txType <= QTransform::TxTranslate; if (doPixmapCache && QPixmapCache::find(unique, internalPixmapCache)) { painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); } else { if (doPixmapCache) { rect.setRect(0, 0, option->rect.width(), option->rect.height()); imageCache = QImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); imageCache.fill(0); p = new QPainter(&imageCache); } //--BEGIN_STYLE_PIXMAPCACHE(QString::fromLatin1("qdial")); p->setRenderHint(QPainter::Antialiasing); const qreal d_ = r / 6; const qreal dx = option->rect.x() + d_ + (width - 2 * r) / 2 + 1; const qreal dy = option->rect.y() + d_ + (height - 2 * r) / 2 + 1; QRectF br = QRectF(dx + 0.5, dy + 0.5, int(r * 2 - 2 * d_ - 2), int(r * 2 - 2 * d_ - 2)); buttonColor.setHsv(buttonColor .hue(), qMin(140, buttonColor .saturation()), qMax(180, buttonColor.value())); QColor shadowColor(0, 0, 0, 20); if (enabled) { // Drop shadow qreal shadowSize = qMax(1.0, penSize/2.0); QRectF shadowRect= br.adjusted(-2*shadowSize, -2*shadowSize, 2*shadowSize, 2*shadowSize); QRadialGradient shadowGradient(shadowRect.center().x(), shadowRect.center().y(), shadowRect.width()/2.0, shadowRect.center().x(), shadowRect.center().y()); shadowGradient.setColorAt(qreal(0.91), QColor(0, 0, 0, 40)); shadowGradient.setColorAt(qreal(1.0), Qt::transparent); p->setBrush(shadowGradient); p->setPen(Qt::NoPen); p->translate(shadowSize, shadowSize); p->drawEllipse(shadowRect); p->translate(-shadowSize, -shadowSize); // Main gradient QRadialGradient gradient(br.center().x() - br.width()/3, dy, br.width()*1.3, br.center().x(), br.center().y() - br.height()/2); gradient.setColorAt(0, buttonColor.lighter(110)); gradient.setColorAt(qreal(0.5), buttonColor); gradient.setColorAt(qreal(0.501), buttonColor.darker(102)); gradient.setColorAt(1, buttonColor.darker(115)); p->setBrush(gradient); } else { p->setBrush(Qt::NoBrush); } p->setPen(QPen(buttonColor.darker(280))); p->drawEllipse(br); p->setBrush(Qt::NoBrush); p->setPen(buttonColor.lighter(110)); p->drawEllipse(br.adjusted(1, 1, -1, -1)); if (option->state & QStyle::State_HasFocus) { QColor highlight = pal.highlight().color(); highlight.setHsv(highlight.hue(), qMin(160, highlight.saturation()), qMax(230, highlight.value())); highlight.setAlpha(127); p->setPen(QPen(highlight, 2.0)); p->setBrush(Qt::NoBrush); p->drawEllipse(br.adjusted(-1, -1, 1, 1)); } //--END_STYLE_PIXMAPCACHE if (doPixmapCache) { p->end(); delete p; internalPixmapCache = QPixmap::fromImage(imageCache); painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); QPixmapCache::insert(unique, internalPixmapCache); } } QPointF dp = calcRadialPos(option, qreal(0.70)); buttonColor = buttonColor.lighter(104); buttonColor.setAlphaF(qreal(0.8)); const qreal ds = r/qreal(7.0); QRectF dialRect(dp.x() - ds, dp.y() - ds, 2*ds, 2*ds); QRadialGradient dialGradient(dialRect.center().x() + dialRect.width()/2, dialRect.center().y() + dialRect.width(), dialRect.width()*2, dialRect.center().x(), dialRect.center().y()); dialGradient.setColorAt(1, buttonColor.darker(140)); dialGradient.setColorAt(qreal(0.4), buttonColor.darker(120)); dialGradient.setColorAt(0, buttonColor.darker(110)); if (penSize > 3.0) { painter->setPen(QPen(QColor(0, 0, 0, 25), penSize)); painter->drawLine(calcRadialPos(option, qreal(0.90)), calcRadialPos(option, qreal(0.96))); } painter->setBrush(dialGradient); painter->setPen(QColor(255, 255, 255, 150)); painter->drawEllipse(dialRect.adjusted(-1, -1, 1, 1)); painter->setPen(QColor(0, 0, 0, 80)); painter->drawEllipse(dialRect); painter->restore(); }
/*! \return Bounding interval of the radial scale that is visible on the canvas. */ QwtInterval QwtPolarPlot::visibleInterval() const { const QwtScaleDiv *sd = scaleDiv( QwtPolar::Radius ); const QRectF cRect = canvas()->contentsRect(); const QRectF pRect = plotRect( cRect ); if ( cRect.contains( pRect ) || !cRect.intersects( pRect ) ) { return QwtInterval( sd->lowerBound(), sd->upperBound() ); } const QPointF pole = pRect.center(); const QRectF scaleRect = pRect & cRect; const QwtScaleMap map = scaleMap( QwtPolar::Radius ); double dmin = 0.0; double dmax = 0.0; if ( scaleRect.contains( pole ) ) { dmin = 0.0; QPointF corners[4]; corners[0] = scaleRect.bottomRight(); corners[1] = scaleRect.topRight(); corners[2] = scaleRect.topLeft(); corners[3] = scaleRect.bottomLeft(); dmax = 0.0; for ( int i = 0; i < 4; i++ ) { const double dist = qwtDistance( pole, corners[i] ); if ( dist > dmax ) dmax = dist; } } else { if ( pole.x() < scaleRect.left() ) { if ( pole.y() < scaleRect.top() ) { dmin = qwtDistance( pole, scaleRect.topLeft() ); dmax = qwtDistance( pole, scaleRect.bottomRight() ); } else if ( pole.y() > scaleRect.bottom() ) { dmin = qwtDistance( pole, scaleRect.bottomLeft() ); dmax = qwtDistance( pole, scaleRect.topRight() ); } else { dmin = scaleRect.left() - pole.x(); dmax = qMax( qwtDistance( pole, scaleRect.bottomRight() ), qwtDistance( pole, scaleRect.topRight() ) ); } } else if ( pole.x() > scaleRect.right() ) { if ( pole.y() < scaleRect.top() ) { dmin = qwtDistance( pole, scaleRect.topRight() ); dmax = qwtDistance( pole, scaleRect.bottomLeft() ); } else if ( pole.y() > scaleRect.bottom() ) { dmin = qwtDistance( pole, scaleRect.bottomRight() ); dmax = qwtDistance( pole, scaleRect.topLeft() ); } else { dmin = pole.x() - scaleRect.right(); dmax = qMax( qwtDistance( pole, scaleRect.bottomLeft() ), qwtDistance( pole, scaleRect.topLeft() ) ); } } else if ( pole.y() < scaleRect.top() ) { dmin = scaleRect.top() - pole.y(); dmax = qMax( qwtDistance( pole, scaleRect.bottomLeft() ), qwtDistance( pole, scaleRect.bottomRight() ) ); } else if ( pole.y() > scaleRect.bottom() ) { dmin = pole.y() - scaleRect.bottom(); dmax = qMax( qwtDistance( pole, scaleRect.topLeft() ), qwtDistance( pole, scaleRect.topRight() ) ); } } const double radius = pRect.width() / 2.0; if ( dmax > radius ) dmax = radius; QwtInterval interval; interval.setMinValue( map.invTransform( dmin ) ); interval.setMaxValue( map.invTransform( dmax ) ); return interval; }
void QArcItem::SetPattern(int nPATTERN) { nPatternType = nPATTERN; //样式类型 //QRectF nrect(0,0,qWidth,qHeight); QRectF nrect = this->m_qrcEllipseBndRect; QLinearGradient gradient(nrect.topLeft(),nrect.bottomRight()); QRadialGradient Radial(nrect.center(),nrect.width()/2,nrect.center()); gradient.setSpread(QGradient::PadSpread);// RepeatSpread QBrush br=brush(); br.setColor(nFrontColor); //设置前景色即样式颜色 switch(nPATTERN) { // case 0:br.setStyle(Qt::NoBrush);break; // case 1:br.setColor(nBackColor);br.setStyle(Qt::SolidPattern);break; // case 2:br.setStyle(Qt::Dense1Pattern);break; // case 3:br.setStyle(Qt::Dense2Pattern);break; // case 4:br.setStyle(Qt::Dense3Pattern);break; // case 5:br.setStyle(Qt::Dense4Pattern);break; // case 6:br.setStyle(Qt::Dense5Pattern);break; // case 7:br.setStyle(Qt::Dense6Pattern);break; // case 8:br.setStyle(Qt::Dense7Pattern);break; // case 9:br.setStyle(Qt::HorPattern);break;//setBrush(Qt::HorPattern);break; // case 10:br.setStyle(Qt::VerPattern);break; // case 11:br.setStyle(Qt::CrossPattern);break; // case 12:br.setStyle(Qt::BDiagPattern);break; // case 13:br.setStyle(Qt::FDiagPattern);break; // case 14:br.setStyle(Qt::DiagCrossPattern);break; case 0:br.setStyle(Qt::NoBrush);break;//透明 case 1:br.setColor(nBackColor);br.setStyle(Qt::SolidPattern);break;//纯色 case 2: //横向过度 gradient.setStart(nrect.x(),nrect.y()+nrect.height()); gradient.setColorAt(0,nFrontColor ); gradient.setColorAt(1,nBackColor ); break; case 3: //横向对称过度 gradient.setStart(nrect.x(),nrect.y()+nrect.height()); gradient.setColorAt(0,nFrontColor ); gradient.setColorAt(0.5,nBackColor ); gradient.setColorAt(1,nFrontColor ); break; case 4: //纵向过度 gradient.setStart(nrect.x()+nrect.width(),nrect.y()); gradient.setColorAt(0,nFrontColor ); gradient.setColorAt(1,nBackColor); break; case 5: //纵向对称过度 gradient.setStart(nrect.x()+nrect.width(),nrect.y()); gradient.setColorAt(0,nFrontColor ); gradient.setColorAt(0.5,nBackColor); gradient.setColorAt(1,nFrontColor ); break; case 6: //斜上过度 gradient.setColorAt(0,nFrontColor ); gradient.setColorAt(1,nBackColor ); break; case 7: //斜上对称过度 gradient.setColorAt(0,nFrontColor ); gradient.setColorAt(0.5,nBackColor ); gradient.setColorAt(1,nFrontColor ); break; case 8: //斜下过度 gradient.setStart(nrect.x(),nrect.y()+nrect.height()); gradient.setFinalStop(nrect.x()+nrect.width(),nrect.y()); gradient.setColorAt(0,nBackColor ); gradient.setColorAt(1,nFrontColor); break; case 9: //斜下对称过度 gradient.setStart(nrect.x(),nrect.y()+nrect.height()); gradient.setFinalStop(nrect.x()+nrect.width(),nrect.y()); gradient.setColorAt(0,nFrontColor ); gradient.setColorAt(0.5,nBackColor ); gradient.setColorAt(1,nFrontColor ); break; case 10: //右上角辐射 gradient.setStart(nrect.x()+nrect.width(),nrect.y()); gradient.setFinalStop(nrect.x(),nrect.y()+nrect.height()); gradient.setColorAt(0,nBackColor ); gradient.setColorAt(1,nFrontColor ); break; case 11: //左上角辐射 gradient.setColorAt(0,nBackColor ); gradient.setColorAt(1, nFrontColor); break; case 12: //中心辐射 Radial.setColorAt(0,nBackColor ); Radial.setColorAt(1,nFrontColor ); setBrush(Radial); return; break; case 13: //待操作 Radial.setFocalPoint(nrect.x(),nrect.y()+nrect.height()/2); Radial.setColorAt(0,nBackColor ); Radial.setColorAt(1,nFrontColor ); setBrush(Radial); return; break; default: break; } if(nPATTERN >= 2 ) { setBrush(gradient); } else { setBrush(br); } }