⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 connectionedit.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                +--------+                |        |   +--------+                |     o--+---+--x     |                |     o  |   |        |                +-----|--+   |        |                      +------+--x     |                             +--------+                When dragging one end point, move the other end point to the same y position,                if that does not cause it to exit it's rectangle.*/                if (m_edit->state() == ConnectionEdit::Dragging) {                    if (m_edit->m_drag_end_point.type == EndPoint::Source) {                        QPoint p(t.x(), s.y());                        m_knee_list.append(p);                        if (tr.contains(p))                            t = m_target_pos = p;                    } else {                        QPoint p(s.x(), t.y());                        m_knee_list.append(p);                        if (sr.contains(p))                            s = m_source_pos = p;                    }                } else {                    m_knee_list.append(QPoint(s.x(), t.y()));                }            } else {/*                +--------+                |   o----+-------+                |        |   +---|----+                +--------+   |   |    |                             |   x    |                             +--------+*/                m_knee_list.append(QPoint(t.x(), s.y()));            }        } else if (r.width() < sr.width() + tr.width()) {            if (s.x() >= tr.left() && s.x() <= tr.right() || t.x() >= sr.right() || t.x() <= sr.left()) {/*                +--------+                |        |                |    o  o+--+                +----|---+  |                   +-|------|-+                   | x      x |                   |          |                   +----------+                When dragging one end point, move the other end point to the same x position,                if that does not cause it to exit it's rectangle.*/                if (m_edit->state() == ConnectionEdit::Dragging) {                    if (m_edit->m_drag_end_point.type == EndPoint::Source) {                        QPoint p(s.x(), t.y());                        m_knee_list.append(p);                        if (tr.contains(p))                            t = m_target_pos = p;                    } else {                        QPoint p(t.x(), s.y());                        m_knee_list.append(p);                        if (sr.contains(p))                            s = m_source_pos = p;                    }                } else {                    m_knee_list.append(QPoint(t.x(), s.y()));                }            } else {/*                +--------+                |        |                |  o     |                +--|-----+                   |   +--------+                   +---+-x      |                       |        |                       +--------+*/                m_knee_list.append(QPoint(s.x(), t.y()));            }        } else {/*            +--------+            |        |            |  o   o-+--------+            +--|-----+        |               |        +-----|--+               |        |     x  |               +--------+-x      |                        +--------+            The line enters the target rectangle through the closest edge.*/            if (sr.topLeft() == r.topLeft()) {                if (pointAboveLine(tr.topLeft(), tr.bottomRight(), t))                    m_knee_list.append(QPoint(t.x(), s.y()));                else                    m_knee_list.append(QPoint(s.x(), t.y()));            } else if (sr.topRight() == r.topRight()) {                if (pointAboveLine(tr.bottomLeft(), tr.topRight(), t))                    m_knee_list.append(QPoint(t.x(), s.y()));                else                    m_knee_list.append(QPoint(s.x(), t.y()));            } else if (sr.bottomRight() == r.bottomRight()) {                if (pointAboveLine(tr.topLeft(), tr.bottomRight(), t))                    m_knee_list.append(QPoint(s.x(), t.y()));                else                    m_knee_list.append(QPoint(t.x(), s.y()));            } else {                if (pointAboveLine(tr.bottomLeft(), tr.topRight(), t))                    m_knee_list.append(QPoint(s.x(), t.y()));                else                    m_knee_list.append(QPoint(t.x(), s.y()));            }        }    }    m_knee_list.append(t);    if (m_knee_list.size() == 2)        m_knee_list.clear();    trimLine();    LineDir new_source_label_dir = labelDir(EndPoint::Source);    LineDir new_target_label_dir = labelDir(EndPoint::Target);    if (new_source_label_dir != old_source_label_dir)        updatePixmap(EndPoint::Source);    if (new_target_label_dir != old_target_label_dir)        updatePixmap(EndPoint::Target);}void Connection::trimLine(){    if (m_source == 0 || m_source_pos == QPoint(-1, -1) || m_target_pos == QPoint(-1, -1))        return;    int cnt = m_knee_list.size();    if (cnt < 2)        return;    QRect sr = m_source_rect;    QRect tr = m_target_rect;    if (sr.contains(m_knee_list.at(1)))        m_knee_list.removeFirst();    cnt = m_knee_list.size();    if (cnt < 2)        return;    if (!tr.contains(sr) && tr.contains(m_knee_list.at(cnt - 2)))        m_knee_list.removeLast();    cnt = m_knee_list.size();    if (cnt < 2)        return;    if (sr.contains(m_knee_list.at(0)) && !sr.contains(m_knee_list.at(1)))        m_knee_list[0] = lineEntryPos(m_knee_list.at(1), m_knee_list.at(0), sr);    if (tr.contains(m_knee_list.at(cnt - 1)) && !tr.contains(m_knee_list.at(cnt - 2))) {        m_knee_list[cnt - 1]            = lineEntryPos(m_knee_list.at(cnt - 2), m_knee_list.at(cnt - 1), tr);        m_arrow_head = arrowHead(m_knee_list.at(cnt - 2), m_knee_list.at(cnt - 1));    }}void Connection::setSource(QObject *source, const QPoint &pos){    if (source == m_source && m_source_pos == pos)        return;    update(false);    m_source = source;    if (QWidget *widget = qobject_cast<QWidget*>(source)) {        m_source_pos = pos;        m_source_rect = m_edit->widgetRect(widget);        updateKneeList();    }    update(false);}void Connection::setTarget(QObject *target, const QPoint &pos){    if (target == m_target && m_target_pos == pos)        return;    update(false);    m_target = target;    if (QWidget *widget = qobject_cast<QWidget*>(target)) {        m_target_pos = pos;        m_target_rect = m_edit->widgetRect(widget);        updateKneeList();    }    update(false);}static QRect lineRect(const QPoint &a, const QPoint &b){    QPoint c(qMin(a.x(), b.x()), qMin(a.y(), b.y()));    QPoint d(qMax(a.x(), b.x()), qMax(a.y(), b.y()));    QRect result(c, d);    return expand(result, LINE_PROXIMITY_RADIUS);}QRect Connection::groundRect() const{    if (!ground())        return QRect();    if (m_knee_list.isEmpty())        return QRect();    QPoint p = m_knee_list.last();    return QRect(p.x() - GROUND_W/2, p.y(), GROUND_W, GROUND_H);}QRegion Connection::region() const{    QRegion result;    for (int i = 0; i < m_knee_list.size() - 1; ++i)        result = result.unite(lineRect(m_knee_list.at(i), m_knee_list.at(i + 1)));    if (!m_arrow_head.isEmpty()) {        QRect r = m_arrow_head.boundingRect().toRect();        r = expand(r, 1);        result = result.unite(r);    } else if (ground()) {        result = result.unite(groundRect());    }    result = result.unite(labelRect(EndPoint::Source));    result = result.unite(labelRect(EndPoint::Target));    return result;}void Connection::update(bool update_widgets) const{    m_edit->update(region());    if (update_widgets) {        if (m_source != 0)            m_edit->update(m_source_rect);        if (m_target != 0)            m_edit->update(m_target_rect);    }    m_edit->update(endPointRect(EndPoint::Source));    m_edit->update(endPointRect(EndPoint::Target));}void Connection::paint(QPainter *p) const{    for (int i = 0; i < m_knee_list.size() - 1; ++i)        p->drawLine(m_knee_list.at(i), m_knee_list.at(i + 1));    if (!m_arrow_head.isEmpty()) {        p->save();        p->setBrush(p->pen().color());        p->drawPolygon(m_arrow_head);        p->restore();    } else if (ground()) {        paintGround(p, groundRect());    }}bool Connection::contains(const QPoint &pos) const{    return region().contains(pos);}QRect Connection::endPointRect(EndPoint::Type type) const{    if (type == EndPoint::Source) {        if (m_source_pos != QPoint(-1, -1))            return qdesigner_internal::endPointRect(m_source_pos);    } else {        if (m_target_pos != QPoint(-1, -1))            return qdesigner_internal::endPointRect(m_target_pos);    }    return QRect();}CETypes::LineDir Connection::labelDir(EndPoint::Type type) const{    int cnt = m_knee_list.size();    if (cnt < 2)        return RightDir;    LineDir dir;    if (type == EndPoint::Source)        dir = classifyLine(m_knee_list.at(0), m_knee_list.at(1));    else        dir = classifyLine(m_knee_list.at(cnt - 2), m_knee_list.at(cnt - 1));    if (dir == LeftDir)        dir = RightDir;    if (dir == UpDir)        dir = DownDir;    return dir;}QRect Connection::labelRect(EndPoint::Type type) const{    int cnt = m_knee_list.size();    if (cnt < 2)        return QRect();    QString text = label(type);    if (text.isEmpty())        return QRect();    QSize size = labelPixmap(type).size();    QPoint p1, p2;    if (type == EndPoint::Source) {        p1 = m_knee_list.at(0);        p2 = m_knee_list.at(1);    } else {        p1 = m_knee_list.at(cnt - 1);        p2 = m_knee_list.at(cnt - 2);    }    LineDir dir = classifyLine(p1, p2);    QRect result;    switch (dir) {        case UpDir:            result = QRect(p1 + QPoint(-size.width()/2, 0), size);            break;        case DownDir:            result = QRect(p1 + QPoint(-size.width()/2, -size.height()), size);            break;        case LeftDir:            result = QRect(p1 + QPoint(0, -size.height()/2), size);            break;        case RightDir:            result = QRect(p1 + QPoint(-size.width(), -size.height()/2), size);            break;    }    return result;}void Connection::setLabel(EndPoint::Type type, const QString &text){    if (text == label(type))        return;    if (type == EndPoint::Source)        m_source_label = text;    else        m_target_label = text;    updatePixmap(type);}void Connection::updatePixmap(EndPoint::Type type){    QPixmap *pm = type == EndPoint::Source ? &m_source_label_pm : &m_target_label_pm;    *pm = QPixmap();    QString text = label(type);    if (text.isEmpty())        return;    QFontMetrics fm = m_edit->fontMetrics();    QSize size = fm.size(Qt::TextSingleLine, text) + QSize(HLABEL_MARGIN*2, VLABEL_MARGIN*2);    *pm = QPixmap(size);    pm->fill(m_edit->palette().color(QPalette::Normal, QPalette::Base));    QPainter p(pm);    p.setPen(m_edit->palette().color(QPalette::Normal, QPalette::Text));    p.drawText(-fm.leftBearing(text.at(0)) + HLABEL_MARGIN, fm.ascent() + VLABEL_MARGIN, text);    p.end();    LineDir dir = labelDir(type);    if (dir == DownDir)        *pm = pm->transformed(QMatrix(0.0, -1.0, 1.0, 0.0, 0.0, 0.0));}void Connection::checkWidgets(){    bool changed = false;    if (QWidget *sourceWidget = qobject_cast<QWidget*>(m_source)) {        QRect r = m_edit->widgetRect(sourceWidget);        if (r != m_source_rect) {            if (m_source_pos != QPoint(-1, -1) && !r.contains(m_source_pos)) {                QPoint offset = m_source_pos - m_source_rect.topLeft();                QPoint old_pos = m_source_pos;                m_source_pos = pointInsideRect(r, r.topLeft() + offset);            }            m_edit->update(m_source_rect);            m_source_rect = r;            changed = true;        }    }    if (QWidget *targetWidget = qobject_cast<QWidget*>(m_target)) {        QRect r = m_edit->widgetRect(targetWidget);        if (r != m_target_rect) {            if (m_target_pos != QPoint(-1, -1) && !r.contains(m_target_pos)) {                QPoint offset = m_target_pos - m_target_rect.topLeft();                QPoint old_pos = m_target_pos;                m_target_pos = pointInsideRect(r, r.topLeft() + offset);            }            m_edit->update(m_target_rect);            m_target_rect = r;            changed = true;        }    }    if (changed) {        update();        updateKneeList();        update();    }}/********************************************************************************* ConnectionEdit*/ConnectionEdit::ConnectionEdit(QWidget *parent, QDesignerFormWindowInterface *form)    : QWidget(parent){    m_bg_widget = 0;    m_widget_under_mouse = 0;    m_tmp_con = 0;    m_start_connection_on_drag = true;    m_enable_update_background = false;    m_undo_stack = form->commandHistory();    m_active_color = Qt::red;    m_inactive_color = Qt::blue;    setAttribute(Qt::WA_MouseTracking, true);    setFocusPolicy(Qt::ClickFocus);    connect(form, SIGNAL(widgetRemoved(QWidget*)), this, SLOT(widgetRemoved(QWidget*)));}void ConnectionEdit::clear(){    m_con_list.clear();    m_sel_con_set.clear();    m_bg_widget = 0;    m_widget_under_mouse = 0;    m_tmp_con = 0;}void ConnectionEdit::setBackground(QWidget *background){    if (background == m_bg_widget) {        // nothing to do        return;    }    m_bg_widget = background;    updateBackground();}void ConnectionEdit::enableUpdateBackground(bool enable){    m_enable_update_background = enable;    if (enable)        updateBackground();}void ConnectionEdit::updateBackground(){    if (m_bg_widget == 0)        return;    if (!m_enable_update_background)        return;    foreach(Connection *c, m_con_list)        c->updateVisibility();    updateLines();    update();}QWidget *ConnectionEdit::widgetAt(const QPoint &pos) const{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -