#include "WindowAppBlockComment.h" #include "DialogEditComment.h" #include WindowAppBlockComment::WindowAppBlockComment(QGraphicsItem* parent) : QGraphicsTextItem(parent) , m_bSel(false) , m_strComment(COMM_DEFAULT_TEXT) , resizing(false) { // 初始化UI风格 this->initStyle(); // 设置注释控件的默认宽度 blockRect.setRect( 0, 0, COMM_BASIC_WIDTH, COMM_BASIC_HEIGHT ); // 更新矩形区域的尺寸 this->updateRect(); reDirection = ResizeNone; } WindowAppBlockComment::~WindowAppBlockComment() { } /// /// 初始化UI风格 /// void WindowAppBlockComment::initStyle() { // 允许移动 setFlag(QGraphicsItem::ItemIsMovable); // 允许选中 setFlag(QGraphicsItem::ItemIsSelectable); // 允许发送尺寸变更通知 setFlag(QGraphicsItem::ItemSendsGeometryChanges); // 设置字体 this->setFont(FONT_COMM); // 设置文字颜色 this->setDefaultTextColor(COLOR_COMM_TEXT); // 允许文字交互 this->setTextInteractionFlags(Qt::TextEditorInteraction); // 置于最底层 this->setZValue(1000.0); // 设置默认注释文本 this->setPlainText(m_strComment); // 设置其他参数(左上角对齐,文字最大宽度等等) auto document = this->document(); auto option = document->defaultTextOption(); option.setAlignment(Qt::AlignLeft | Qt::AlignTop); document->setDefaultTextOption(option); //this->setTextWidth(110); // 绑定文本变更信号,自动调整边距 connect(this->document(), SIGNAL(contentsChanged()), this, SLOT(onContentsChanged())); } ///// ///// 设置注释的文字 ///// ///// //void WindowAppBlockComment::setComment(const QString& strComm) //{ // this->m_strComment = strComm; //} /// /// 绘制注释功能块 /// /// /// /// void WindowAppBlockComment::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { m_bSel = isSelected(); painter->setRenderHints(QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing); painter->save(); // 绘制边框 this->drawFrame(painter); paintSelected(painter, 1); //// 绘制文字 //this->drawContent(painter); painter->restore(); // 去掉黑色虚线框 //QStyleOptionGraphicsItem op(*option); //op.state = QStyle::State_None; //QGraphicsTextItem::paint(painter, &op, widget); //// 编辑状态按原来的执行 //if (hasFocus()) //{ // QItem::paint(painter, option, widget); //} //// 选中状态去掉虚线 //else //{ // // 原来什么属性就要什么属性,只不过去掉多余的选中状态 // QStyleOptionGraphicsItem optionx(*option); // optionx.state &= ~QStyle::State_Selected; // QItem::paint(painter, &optionx, widget); //} QGraphicsTextItem::paint(painter, option, widget); } QVariant WindowAppBlockComment::itemChange(GraphicsItemChange change, const QVariant& value) { if (change == QGraphicsItem::ItemSelectedHasChanged) { emit selectedChange(this); } return value; } void WindowAppBlockComment::focusOutEvent(QFocusEvent* event) { setTextInteractionFlags(Qt::NoTextInteraction); emit lostFocus(this); QGraphicsTextItem::focusOutEvent(event); } /// /// 在文本内容变更时触发,自动更新边距 /// void WindowAppBlockComment::onContentsChanged() { // 有内容变更时,更新一下外边界 this->updateRect(); this->update(); } /// /// 响应双击事件,激活文本编辑模式 /// /// void WindowAppBlockComment::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) { if (event->button() == Qt::LeftButton && textInteractionFlags() == Qt::NoTextInteraction) { setTextInteractionFlags(Qt::TextEditorInteraction); } QGraphicsTextItem::mouseDoubleClickEvent(event); } /// /// 绘制边框 /// /// void WindowAppBlockComment::drawFrame(QPainter* painter) { //if (!m_bSel) //{ // painter->setPen(QPen(COLOR_TBD_FRAME1, PEN_LINE_WIDTH)); //} //else //{ // painter->setPen(QPen(COLOR_TBD_FRAME1, PEN_LINE_WIDTH_SEL)); //} // 设置画笔 painter->setPen(QPen(COLOR_COMM_FRAME, PEN_WIDTH_FRAME)); // 设置透明 //painter->setBrush(Qt::transparent); // 绘制边框 painter->drawRoundedRect(blockRect, 10, 10); } /// /// 更新矩形区域的尺寸 /// void WindowAppBlockComment::updateRect() { m_strComment = this->toPlainText(); // Reason:由于将 boundingRect 强制设定成了和 blockRect 一样的大小(方便做拉伸), // 所以在有文字内容变动的时候,需要手动扩大一下矩形区域 QRectF textRect = QFontMetrics(FONT_COMM).boundingRect(m_strComment); float xFix = textRect.width() - blockRect.width(); float yFix = textRect.height() - blockRect.width(); if (xFix > 0.0) { blockRect.setRight(blockRect.right() + xFix); } if (yFix > 0.0) { blockRect.setBottom(blockRect.bottom() + yFix); } //blockBoundingRect = boundingRect(); //if (blockBoundingRect.width() > blockRect.width()) //{ // blockRect.setWidth(blockBoundingRect.width()); // // 然后微调一下外边框,方便拖放操作 // blockRect.adjust(0, 0, 2, 0); //} //if (blockBoundingRect.height() > blockRect.height()) //{ // blockRect.setHeight(blockBoundingRect.height()); // // 然后微调一下外边框,方便拖放操作 // blockRect.adjust(0, 0, 0, 2); //} } //void WindowAppBlockComment::hoverEnterEvent(QGraphicsSceneHoverEvent* event) //{ // update(); // QGraphicsObject::hoverEnterEvent(event); //} // // //void WindowAppBlockComment::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) //{ // setCursor(QCursor(Qt::ArrowCursor)); // scene()->update(sceneBoundingRect()); // update(); // QGraphicsObject::hoverLeaveEvent(event); //} void WindowAppBlockComment::hoverMoveEvent(QGraphicsSceneHoverEvent* event) { if (this->isSelected()) { QPointF mousePoint = event->pos(); QPointF mouseHandler = QPointF(5, 5); QPointF topLeft = blockRect.topLeft(); QPointF topRight = blockRect.topRight(); QPointF bottomLeft = blockRect.bottomLeft(); QPointF bottomRight = blockRect.bottomRight(); // resize top if (mousePoint.x() >= (topLeft.x() + mouseHandler.x()) && mousePoint.x() <= (topRight.x() - mouseHandler.x()) && mousePoint.y() >= (topLeft.y() - mouseHandler.y()) && mousePoint.y() <= (topLeft.y() + mouseHandler.y())) { setCursor(Qt::SizeVerCursor); } // resize bottom else if (mousePoint.x() >= (bottomLeft.x() + mouseHandler.x()) && mousePoint.x() <= (bottomRight.x() - mouseHandler.x()) && mousePoint.y() >= (bottomLeft.y() - mouseHandler.y()) && mousePoint.y() <= (bottomLeft.y() + mouseHandler.y())) { setCursor(Qt::SizeVerCursor); } // resize left else if (mousePoint.x() >= (topLeft.x() - mouseHandler.x()) && mousePoint.x() <= (topLeft.x() + mouseHandler.x()) && mousePoint.y() >= (topLeft.y() + mouseHandler.y()) && mousePoint.y() <= (bottomLeft.y() - mouseHandler.y())) { setCursor(Qt::SizeHorCursor); } // resize right else if (mousePoint.x() >= (topRight.x() - mouseHandler.x()) && mousePoint.x() <= (topRight.x() + mouseHandler.x()) && mousePoint.y() >= (topRight.y() + mouseHandler.y()) && mousePoint.y() <= (bottomRight.y() - mouseHandler.y())) { setCursor(Qt::SizeHorCursor); } // resize top left else if (mousePoint.x() <= (topLeft.x() + mouseHandler.x()) && mousePoint.x() >= (topLeft.x() - mouseHandler.x()) && mousePoint.y() <= (topLeft.y() + mouseHandler.y()) && mousePoint.y() >= (topLeft.y() - mouseHandler.y())) { setCursor(Qt::SizeFDiagCursor); } // resize bottom right else if (mousePoint.x() <= (bottomRight.x() + mouseHandler.x()) && mousePoint.x() >= (bottomRight.x() - mouseHandler.x()) && mousePoint.y() <= (bottomRight.y() + mouseHandler.y()) && mousePoint.y() >= (bottomRight.y() - mouseHandler.y())) { setCursor(Qt::SizeFDiagCursor); } // resize bottom left else if (mousePoint.x() <= (bottomLeft.x() + mouseHandler.x()) && mousePoint.x() >= (bottomLeft.x() - mouseHandler.x()) && mousePoint.y() >= (bottomLeft.y() - mouseHandler.y()) && mousePoint.y() <= (bottomLeft.y() + mouseHandler.y())) { setCursor(Qt::SizeBDiagCursor); } // resize top right else if (mousePoint.x() <= (topRight.x() + mouseHandler.x()) && mousePoint.x() >= (topRight.x() - mouseHandler.x()) && mousePoint.y() >= (topRight.y() - mouseHandler.y()) && mousePoint.y() <= (topRight.y() + mouseHandler.y())) { setCursor(Qt::SizeBDiagCursor); } else { setCursor(Qt::ArrowCursor); } } QGraphicsObject::hoverMoveEvent(event); } void WindowAppBlockComment::mouseMoveEvent(QGraphicsSceneMouseEvent* event) { //if (!isSelected()) //{ // return; //} QPointF mousePoint = event->pos(); if (resizing) { QTextDocument* doc = this->document(); QAbstractTextDocumentLayout* layout = doc->documentLayout(); //int pixelsWidth = layout->documentSize().width(); //int pixelsHeight = layout->documentSize().height(); //qDebug() << "layout: " << pixelsWidth << "," << pixelsHeight; if (reDirection & ResizeLeft) { blockRect.setLeft(mousePoint.x()); //setElementXPos(static_cast(mapToScene(blockRect.topLeft()).x())); //setElementWidth(static_cast(qAbs(mapToScene(blockRect.topLeft()).x() - mapToScene(blockRect.topRight()).x()))); // document->setDocumentLayout() //QSizeF size(200, 200); //doc->setPageSize(size); } if (reDirection & ResizeRight) { blockRect.setRight(mousePoint.x()); //setElementWidth(static_cast(qAbs(mapToScene(blockRect.topLeft()).x() - mapToScene(blockRect.topRight()).x()))); } if (reDirection & ResizeTop) { blockRect.setTop(mousePoint.y()); //setElementYPos(static_cast(mapToScene(blockRect.topLeft()).y())); //setElementHeight(static_cast(qAbs(mapToScene(blockRect.topLeft()).y() - mapToScene(blockRect.bottomLeft()).y()))); } if (reDirection & ResizeBottom) { blockRect.setBottom(mousePoint.y()); // setElementHeight(static_cast(qAbs(blockRect.topLeft().y() - blockRect.bottomLeft().y()))); } scene()->update(); return; } QGraphicsItem::mouseMoveEvent(event); } void WindowAppBlockComment::mousePressEvent(QGraphicsSceneMouseEvent* event) { QPointF mousePoint = event->pos(); QPointF mouseHandler = QPointF(5, 5); QPointF topLeft = blockRect.topLeft(); QPointF topRight = blockRect.topRight(); QPointF bottomLeft = blockRect.bottomLeft(); QPointF bottomRight = blockRect.bottomRight(); reDirection = ResizeNone; resizing = false; // resize top if (mousePoint.x() >= (topLeft.x() + 0) && mousePoint.x() <= (topRight.x() - 0) && mousePoint.y() >= (topLeft.y() - mouseHandler.y()) && mousePoint.y() <= (topLeft.y() + mouseHandler.y())) { reDirection |= ResizeTop; resizing = true; } // resize bottom if (mousePoint.x() >= (bottomLeft.x() + 0) && mousePoint.x() <= (bottomRight.x() - 0) && mousePoint.y() >= (bottomLeft.y() - mouseHandler.y()) && mousePoint.y() <= (bottomLeft.y() + mouseHandler.y())) { reDirection |= ResizeBottom; resizing = true; } // resize left if (mousePoint.x() >= (topLeft.x() - mouseHandler.x()) && mousePoint.x() <= (topLeft.x() + mouseHandler.x()) && mousePoint.y() >= (topLeft.y() + 0) && mousePoint.y() <= (bottomLeft.y() - 0)) { reDirection |= ResizeLeft; resizing = true; } // resize right if (mousePoint.x() >= (topRight.x() - mouseHandler.x()) && mousePoint.x() <= (topRight.x() + mouseHandler.x()) && mousePoint.y() >= (topRight.y() + 0) && mousePoint.y() <= (bottomRight.y() - 0)) { reDirection |= ResizeRight; resizing = true; } switch (reDirection) { case ResizeRight: case ResizeLeft: setCursor(Qt::SizeHorCursor); break; case ResizeBottom: case ResizeTop: setCursor(Qt::SizeVerCursor); break; case ResizeRight | ResizeBottom: case ResizeLeft | ResizeTop: setCursor(Qt::SizeFDiagCursor); break; case ResizeLeft | ResizeBottom: case ResizeRight | ResizeTop: setCursor(Qt::SizeBDiagCursor); break; default: setCursor(Qt::ArrowCursor); break; } oldPos = pos(); oldWidth = blockRect.width(); oldHeight = blockRect.height(); QGraphicsObject::mousePressEvent(event); } void WindowAppBlockComment::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) { setCursor(Qt::ArrowCursor); //elementXPos = static_cast(pos().x()); //elementYPos = static_cast(pos().y()); //updatePropertyModel(); //if (oldPos != pos()) //{ // emit elementMoved(oldPos); //} //if (resizing) //{ // emit elementResized(oldWidth, oldHeight, oldPos); //} resizing = false; reDirection = ResizeNone; QGraphicsObject::mouseReleaseEvent(event); } /** * @brief Element::paintSelected * @details 绘制选中状态 * @param painter * @param iLineWidth 线宽 */ void WindowAppBlockComment::paintSelected(QPainter* painter, int iLineWidth) { if (isSelected()) { painter->save(); painter->setBrush(Qt::NoBrush); //QPen pen(Qt::green, iLineWidth, Qt::DashLine); //painter->setPen(pen); QRectF rect = blockRect.adjusted(-1, -1, 1, 1); // painter->drawRect(rect); QPen pen2(Qt::green, iLineWidth, Qt::SolidLine); painter->setPen(pen2); QPointF pt = QPointF(3, 3); painter->drawRect(QRectF(rect.topLeft() - pt, rect.topLeft() + pt)); QPointF ptMid = QPointF(rect.left() + rect.width() / 2, rect.top()); painter->drawRect(QRectF(ptMid - pt, ptMid + pt)); painter->drawRect(QRectF(rect.topRight() - pt, rect.topRight() + pt)); ptMid = QPointF(rect.left(), rect.top() + rect.height() / 2); painter->drawRect(QRectF(ptMid - pt, ptMid + pt)); ptMid = QPointF(rect.right(), rect.top() + rect.height() / 2); painter->drawRect(QRectF(ptMid - pt, ptMid + pt)); painter->drawRect(QRectF(rect.bottomLeft() - pt, rect.bottomLeft() + pt)); ptMid = QPointF(rect.left() + rect.width() / 2, rect.bottom()); painter->drawRect(QRectF(ptMid - pt, ptMid + pt)); painter->drawRect(QRectF(rect.bottomRight() - pt, rect.bottomRight() + pt)); painter->restore(); } } /// /// 计算区域边界 /// /// QRectF WindowAppBlockComment::boundingRect() const { return blockRect; } /// /// 重写Shape函数,使其没有文字的空白部分也可以响应消息 /// /// QPainterPath WindowAppBlockComment::shape() const { QPainterPath path; path.addRect(blockRect); return path; } // // ///// ///// 刷新全部(包括文字和尺寸) ///// //void WindowAppBlockComment::updateAll() //{ // //} //==================================================== // // Del // //==================================================== ///// ///// 键盘按下时(回车键结束编辑) ///// ///// //void WindowAppBlockComment::keyPressEvent(QKeyEvent* event) //{ // // 点击回车失去焦点,编辑完成,后续给FocusOutEvent处理 // if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) // { // clearFocus(); // // return; // } // // QGraphicsTextItem::keyPressEvent(event); //} ///// ///// 返回边界矩形区域 ///// ///// //QRectF WindowAppBlockComment::boundingRect() const //{ // return blockBoundingRect; //} ///// ///// 响应双击事件,弹出编辑注释文字对话框 ///// ///// //void WindowAppBlockComment::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) //{ // // 只有鼠标左键才响应 // if (event->button() == Qt::LeftButton) // { // DialogEditComment dialogComm(m_strComment); // // if (dialogComm.exec() == QDialog::Accepted) // { // this->m_strComment = dialogComm.m_strComment; // // // 刷新整个界面 // this->updateAll(); // } // } //} ///// ///// 绘制文字(文字左上角对齐) ///// ///// //void WindowAppBlockComment::drawContent(QPainter* painter) //{ // // 设置画笔 // painter->setPen(QPen(COLOR_COMM_FRAME, PEN_WIDTH_FRAME)); // // // 绘制文字 // painter->setFont(FONT_COMM); // QRectF textRect = QFontMetrics(FONT_COMM).boundingRect(m_strComment); // int textX = blockRect.left() + COMM_SIDE_SPACING; // int textY = blockRect.top() + COMM_SIDE_SPACING + textRect.height() / 2; // painter->drawText(textX, textY, m_strComment); //} //void WindowAppBlockComment::keyReleaseEvent(QKeyEvent* event) //{ // // 编译完毕后,更新一下外边界 // this->updateRect(); // this->update(); // // QGraphicsTextItem::keyReleaseEvent(event); //}