Exemplo n.º 1
0
static void place_line(QList<Q3DockData> &lastLine, Qt::Orientation o, int linestrut, int fullextent, int tbstrut, int maxsize, Q3DockAreaLayout *)
{
    Q3DockWindow *last = 0;
    QRect lastRect;
    for (QList<Q3DockData>::Iterator it = lastLine.begin(); it != lastLine.end(); ++it) {
        if (tbstrut != -1 && qobject_cast<Q3ToolBar*>((*it).w))
            (*it).rect.setHeight(tbstrut);
        if (!last) {
            last = (*it).w;
            lastRect = (*it).rect;
            continue;
        }
        if (!last->isStretchable()) {
            int w = qMin(lastRect.width(), maxsize);
            set_geometry(last, lastRect.x(), lastRect.y(), w, lastRect.height(), o);
        } else {
            int w = qMin((*it).rect.x() - lastRect.x(), maxsize);
            set_geometry(last, lastRect.x(), lastRect.y(), w,
                          last->isResizeEnabled() ? linestrut : lastRect.height(), o);
        }
        last = (*it).w;
        lastRect = (*it).rect;
    }
    if (!last)
        return;
    if (!last->isStretchable()) {
        int w = qMin(lastRect.width(), maxsize);
        set_geometry(last, lastRect.x(), lastRect.y(), w, lastRect.height(), o);
    } else {
        int w = qMin(fullextent - lastRect.x() - (o == Qt::Vertical ? 1 : 0), maxsize);
        set_geometry(last, lastRect.x(), lastRect.y(), w,
                      last->isResizeEnabled() ? linestrut : lastRect.height(), o);
    }
}
Exemplo n.º 2
0
void Q3DockArea::setFixedExtent(int d, Q3DockWindow *dw)
{
    QList<Q3DockWindow *> lst;
    for (int i = 0; i < dockWindows.size(); ++i) {
        Q3DockWindow *w = dockWindows.at(i);
        if (w->isHidden())
            continue;
        if (orientation() == Qt::Horizontal) {
            if (dw->y() != w->y())
                continue;
        } else {
            if (dw->x() != w->x())
                continue;
        }
        if (orientation() == Qt::Horizontal)
            d = qMax(d, w->minimumHeight());
        else
            d = qMax(d, w->minimumWidth());
        if (w->isResizeEnabled())
            lst.append(w);
    }
    for (int i = 0; i < lst.size(); ++i) {
        Q3DockWindow *w = lst.at(i);
        if (orientation() == Qt::Horizontal)
            w->setFixedExtentHeight(d);
        else
            w->setFixedExtentWidth(d);
    }
}
Exemplo n.º 3
0
int Q3DockArea::maxSpace(int hint, Q3DockWindow *dw)
{
    int index = findDockWindow(dw);
    if (index == -1 || index + 1 >= (int)dockWindows.count()) {
        if (orientation() == Qt::Horizontal)
            return dw->width();
        return dw->height();
    }

    Q3DockWindow *w = 0;
    int i = 0;
    do {
        w = dockWindows.at(index + (++i));
    } while (i + 1 < (int)dockWindows.count() && (!w || w->isHidden()));
    if (!w || !w->isResizeEnabled() || i >= (int)dockWindows.count()) {
        if (orientation() == Qt::Horizontal)
            return dw->width();
        return dw->height();
    }
    int min = 0;
    Q3ToolBar *tb = qobject_cast<Q3ToolBar*>(w);
    if (orientation() == Qt::Horizontal) {
        w->setFixedExtentWidth(-1);
        if (!tb)
            min = qMax(w->minimumSize().width(), w->minimumSizeHint().width());
        else
            min = w->sizeHint().width();
    } else {
        w->setFixedExtentHeight(-1);
        if (!tb)
            min = qMax(w->minimumSize().height(), w->minimumSizeHint().height());
        else
            min = w->sizeHint().height();
    }

    int diff = hint - (orientation() == Qt::Horizontal ? dw->width() : dw->height());

    if ((orientation() == Qt::Horizontal ? w->width() : w->height()) - diff < min)
        hint = (orientation() == Qt::Horizontal ? dw->width() : dw->height()) + (orientation() == Qt::Horizontal ? w->width() : w->height()) - min;

    diff = hint - (orientation() == Qt::Horizontal ? dw->width() : dw->height());
    if (orientation() == Qt::Horizontal)
        w->setFixedExtentWidth(w->width() - diff);
    else
        w->setFixedExtentHeight(w->height() - diff);
    return hint;
}
Exemplo n.º 4
0
void Q3DockArea::moveDockWindow(Q3DockWindow *w, const QPoint &p, const QRect &r, bool swap)
{
    invalidateFixedSizes();
    int mse = -10;
    bool hasResizable = false;
    for (int i = 0; i < dockWindows.size(); ++i) {
        Q3DockWindow *dw = dockWindows.at(i);
        if (dw->isHidden())
            continue;
        if (dw->isResizeEnabled())
            hasResizable = true;
        if (orientation() != Qt::Horizontal)
            mse = qMax(qMax(dw->fixedExtent().width(), dw->width()), mse);
        else
            mse = qMax(qMax(dw->fixedExtent().height(), dw->height()), mse);
    }
    if (!hasResizable && w->isResizeEnabled()) {
        if (orientation() != Qt::Horizontal)
            mse = qMax(w->fixedExtent().width(), mse);
        else
            mse = qMax(w->fixedExtent().height(), mse);
    }

    Q3DockWindow *dockWindow = 0;
    int dockWindowIndex = findDockWindow(w);
    QList<Q3DockWindow *> lineStarts = layout->lineStarts();
    QList<QRect> lines = layout->lineList();
    bool wasAloneInLine = false;
    QPoint pos = mapFromGlobal(p);
    int line = lineOf(dockWindowIndex);
    QRect lr;
    if (line < lines.size())
        lr = lines.at(line);
    if (dockWindowIndex != -1) {
        if (lineStarts.contains(w)
            && ((dockWindowIndex < dockWindows.count() - 1
                 && lineStarts.contains(dockWindows.at(dockWindowIndex + 1)))
                || dockWindowIndex == dockWindows.count() - 1))
            wasAloneInLine = true;
        dockWindow = dockWindows.takeAt(dockWindowIndex);
        if (!wasAloneInLine) { // only do the pre-layout if the widget isn't the only one in its line
            if (lineStarts.contains(dockWindow) && dockWindowIndex < dockWindows.count())
                dockWindows.at(dockWindowIndex)->setNewLine(true);
            layout->layoutItems(QRect(0, 0, width(), height()), true);
        }
    } else {
        dockWindow = w;
        bool vis = dockWindow->isVisible();
        dockWindow->setParent(this);
        dockWindow->move(0, 0);
        if(vis)
            dockWindow->show();
        if (swap)
            dockWindow->resize(dockWindow->height(), dockWindow->width());
        w->installEventFilter(this);
    }

    lineStarts = layout->lineStarts();
    lines = layout->lineList();

    QRect rect = QRect(mapFromGlobal(r.topLeft()), r.size());
    if (orientation() == Qt::Horizontal && QApplication::reverseLayout()) {
        rect = QRect(width() - rect.x() - rect.width(), rect.y(), rect.width(), rect.height());
        pos.rx() = width() - pos.x();
    }
    dockWindow->setOffset(point_pos(rect.topLeft(), orientation()));
    if (orientation() == Qt::Horizontal) {
        int offs = dockWindow->offset();
        if (width() - offs < dockWindow->minimumWidth())
            dockWindow->setOffset(width() - dockWindow->minimumWidth());
    } else {
        int offs = dockWindow->offset();
        if (height() - offs < dockWindow->minimumHeight())
            dockWindow->setOffset(height() - dockWindow->minimumHeight());
    }

    if (dockWindows.isEmpty()) {
        dockWindows.append(dockWindow);
    } else {
        int dockLine = -1;
        bool insertLine = false;
        int i = 0;
        QRect lineRect;
        // find the line which we touched with the mouse
        for (QList<QRect>::Iterator it = lines.begin(); it != lines.end(); ++it, ++i) {
            if (point_pos(pos, orientation(), true) >= point_pos((*it).topLeft(), orientation(), true) &&
                 point_pos(pos, orientation(), true) <= point_pos((*it).topLeft(), orientation(), true) +
                 size_extent((*it).size(), orientation(), true)) {
                dockLine = i;
                lineRect = *it;
                break;
            }
        }
        if (dockLine == -1) { // outside the dock...
            insertLine = true;
            if (point_pos(pos, orientation(), true) < 0) // insert as first line
                dockLine = 0;
            else
                dockLine = (int)lines.count(); // insert after the last line ### size_t/int cast
        } else { // inside the dock (we have found a dockLine)
            if (point_pos(pos, orientation(), true) <
                 point_pos(lineRect.topLeft(), orientation(), true) + 4) {        // mouse was at the very beginning of the line
                insertLine = true;                                        // insert a new line before that with the docking widget
            } else if (point_pos(pos, orientation(), true) >
                        point_pos(lineRect.topLeft(), orientation(), true) +
                        size_extent(lineRect.size(), orientation(), true) - 4) {        // mouse was at the very and of the line
                insertLine = true;                                                // insert a line after that with the docking widget
                dockLine++;
            }
        }

        if (!insertLine && wasAloneInLine && lr.contains(pos)) // if we are alone in a line and just moved in there, re-insert it
            insertLine = true;

#if defined(QDOCKAREA_DEBUG)
        qDebug("insert in line %d, and insert that line: %d", dockLine, insertLine);
        qDebug("     (btw, we have %d lines)", lines.count());
#endif
        Q3DockWindow *dw = 0;
        if (dockLine >= (int)lines.count()) { // insert after last line
            dockWindows.append(dockWindow);
            dockWindow->setNewLine(true);
#if defined(QDOCKAREA_DEBUG)
            qDebug("insert at the end");
#endif
        } else if (dockLine == 0 && insertLine) { // insert before first line
            dockWindows.insert(0, dockWindow);
            dockWindows.at(1)->setNewLine(true);
#if defined(QDOCKAREA_DEBUG)
            qDebug("insert at the begin");
#endif
        } else { // insert somewhere in between
            // make sure each line start has a new line
            for (int i = 0; i < lineStarts.size(); ++i) {
                dw = lineStarts.at(i);
                dw->setNewLine(true);
            }

            // find the index of the first widget in the search line
            int searchLine = dockLine;
#if defined(QDOCKAREA_DEBUG)
            qDebug("search line start of %d", searchLine);
#endif
            Q3DockWindow *lsw = lineStarts.at(searchLine);
            int index = dockWindows.indexOf(lsw);
            if (index == -1) { // the linestart widget hasn't been found, try to find it harder
                if (lsw == w && dockWindowIndex <= dockWindows.count())
                    index = dockWindowIndex;
                else
                    index = 0;
            }
#if defined(QDOCKAREA_DEBUG)
            qDebug("     which starts at %d", index);
#endif
            if (!insertLine) { // if we insert the docking widget in the existing line
                // find the index for the widget
                bool inc = true;
                bool firstTime = true;
                for (int i = index; i < dockWindows.size(); ++i) {
                    dw = dockWindows.at(i);
                    if (orientation() == Qt::Horizontal)
                        dw->setFixedExtentWidth(-1);
                    else
                        dw->setFixedExtentHeight(-1);
                    if (!firstTime && lineStarts.contains(dw)) // we are in the next line, so break
                        break;
                    if (point_pos(pos, orientation()) <
                         point_pos(fix_pos(dw), orientation()) + size_extent(dw->size(), orientation()) / 2) {
                        inc = false;
                    }
                    if (inc)
                        index++;
                    firstTime = false;
                }
#if defined(QDOCKAREA_DEBUG)
                qDebug("insert at index: %d", index);
#endif
                // if we insert it just before a widget which has a new line, transfer the newline to the docking widget
                // but not if we didn't only mave a widget in its line which was alone in the line before
                if (!(wasAloneInLine && lr.contains(pos))
                     && index >= 0 && index < dockWindows.count() &&
                     dockWindows.at(index)->newLine() && lineOf(index) == dockLine) {
#if defined(QDOCKAREA_DEBUG)
                    qDebug("get rid of the old newline and get me one");
#endif
                    dockWindows.at(index)->setNewLine(false);
                    dockWindow->setNewLine(true);
                } else if (wasAloneInLine && lr.contains(pos)) {
                    dockWindow->setNewLine(true);
                } else { // if we are somewhere in a line, get rid of the newline
                    dockWindow->setNewLine(false);
                }
            } else { // insert in a new line, so make sure the dock widget and the widget which will be after it have a newline
#if defined(QDOCKAREA_DEBUG)
                qDebug("insert a new line");
#endif
                if (index < dockWindows.count()) {
#if defined(QDOCKAREA_DEBUG)
                    qDebug("give the widget at %d a newline", index);
#endif
                    Q3DockWindow* nldw = dockWindows.at(index);
                    if (nldw)
                        nldw->setNewLine(true);
                }
#if defined(QDOCKAREA_DEBUG)
                qDebug("give me a newline");
#endif
                dockWindow->setNewLine(true);
            }
            // finally insert the widget
            dockWindows.insert(index, dockWindow);
        }
    }

    if (mse != -10 && w->isResizeEnabled()) {
        if (orientation() != Qt::Horizontal)
            w->setFixedExtentWidth(qMin(qMax(w->minimumWidth(), mse), w->sizeHint().width()));
        else
            w->setFixedExtentHeight(qMin(qMax(w->minimumHeight(), mse), w->sizeHint().height()));
    }

    updateLayout();
    setSizePolicy(QSizePolicy(orientation() == Qt::Horizontal ? QSizePolicy::Expanding : QSizePolicy::Minimum,
                                orientation() == Qt::Vertical ? QSizePolicy::Expanding : QSizePolicy::Minimum));
}
Exemplo n.º 5
0
int Q3DockAreaLayout::layoutItems(const QRect &rect, bool testonly)
{
    if (dockWindows->isEmpty())
        return 0;

    dirty = false;

    // some corrections
    QRect r = rect;
    if (orientation() == Qt::Vertical)
        r.setHeight(r.height() - 3);

    // init
    lines.clear();
    ls.clear();
    int start = start_pos(r, orientation());
    int pos = start;
    int sectionpos = 0;
    int linestrut = 0;
    QList<Q3DockData> lastLine;
    int tbstrut = -1;
    int maxsize = size_extent(rect.size(), orientation());
    int visibleWindows = 0;

    // go through all widgets in the dock
    for (int i = 0; i < dockWindows->size(); ++i) {
        Q3DockWindow *dw = dockWindows->at(i);
        if (dw->isHidden())
            continue;
        ++visibleWindows;
        // find position for the widget: This is the maximum of the
        // end of the previous widget and the offset of the widget. If
        // the position + the width of the widget dosn't fit into the
        // dock, try moving it a bit back, if possible.
        int op = pos;
        int dockExtend = dock_extent(dw, orientation(), maxsize);
        if (!dw->isStretchable()) {
            pos = qMax(pos, dw->offset());
            if (pos + dockExtend > size_extent(r.size(), orientation()) - 1)
                pos = qMax(op, size_extent(r.size(), orientation()) - 1 - dockExtend);
        }
        if (!lastLine.isEmpty() && !dw->newLine() && space_left(rect, pos, orientation()) < dockExtend)
            shrink_extend(dw, dockExtend, space_left(rect, pos, orientation()), orientation());
        // if the current widget doesn't fit into the line anymore and it is not the first widget of the line
        if (!lastLine.isEmpty() &&
             (space_left(rect, pos, orientation()) < dockExtend || dw->newLine())) {
            if (!testonly) // place the last line, if not in test mode
                place_line(lastLine, orientation(), linestrut, size_extent(r.size(), orientation()), tbstrut, maxsize, this);
            // remember the line coordinats of the last line
            if (orientation() == Qt::Horizontal)
                lines.append(QRect(0, sectionpos, r.width(), linestrut));
            else
                lines.append(QRect(sectionpos, 0, linestrut, r.height()));
            // do some clearing for the next line
            lastLine.clear();
            sectionpos += linestrut;
            linestrut = 0;
            pos = start;
            tbstrut = -1;
        }

        // remember first widget of a line
        if (lastLine.isEmpty()) {
            ls.append(dw);
            // try to make the best position
            int op = pos;
            if (!dw->isStretchable())
                pos = qMax(pos, dw->offset());
            if (pos + dockExtend > size_extent(r.size(), orientation()) - 1)
                pos = qMax(op, size_extent(r.size(), orientation()) - 1 - dockExtend);
        }
        // do some calculations and add the remember the rect which the docking widget requires for the placing
        QRect dwRect(pos, sectionpos, dockExtend, dock_strut(dw, orientation() ));
        lastLine.append(Q3DockData(dw, dwRect));
        if (qobject_cast<Q3ToolBar*>(dw))
            tbstrut = qMax(tbstrut, dock_strut(dw, orientation()));
        linestrut = qMax(dock_strut(dw, orientation()), linestrut);
        add_size(dockExtend, pos, orientation());
    }

    // if some stuff was not placed/stored yet, do it now
    if (!testonly)
        place_line(lastLine, orientation(), linestrut, size_extent(r.size(), orientation()), tbstrut, maxsize, this);
    if (orientation() == Qt::Horizontal)
        lines.append(QRect(0, sectionpos, r.width(), linestrut));
    else
        lines.append(QRect(sectionpos, 0, linestrut, r.height()));
    if (lines.size() >= 2 && *(--lines.end()) == *(--(--lines.end())))
        lines.removeLast();

    bool hadResizable = false;
    for (int i = 0; i < dockWindows->size(); ++i) {
        Q3DockWindow *dw = dockWindows->at(i);
        if (!dw->isVisibleTo(parentWidget))
            continue;
        hadResizable = hadResizable || dw->isResizeEnabled();
        dw->updateSplitterVisibility(visibleWindows > 1); //!dw->area()->isLastDockWindow(dw));
        if (Q3ToolBar *tb = qobject_cast<Q3ToolBar *>(dw))
            tb->checkForExtension(dw->size());
    }
    return sectionpos + linestrut;
}