void TreeCanvas::update(void) { QMutexLocker locker(&mutex); layoutMutex.lock(); if (root != NULL) { root->layout(*na); BoundingBox bb = root->getBoundingBox(); int w = static_cast<int>((bb.right-bb.left+Layout::extent)*scale); int h = static_cast<int>(2*Layout::extent+ root->getShape()->depth()*Layout::dist_y*scale); xtrans = -bb.left+(Layout::extent / 2); QSize viewport_size = size(); QAbstractScrollArea* sa = static_cast<QAbstractScrollArea*>(parentWidget()->parentWidget()); sa->horizontalScrollBar()->setRange(0,w-viewport_size.width()); sa->verticalScrollBar()->setRange(0,h-viewport_size.height()); sa->horizontalScrollBar()->setPageStep(viewport_size.width()); sa->verticalScrollBar()->setPageStep(viewport_size.height()); sa->horizontalScrollBar()->setSingleStep(Layout::extent); sa->verticalScrollBar()->setSingleStep(Layout::extent); } if (autoZoom) zoomToFit(); layoutMutex.unlock(); QWidget::update(); }
void tst_QAbstractScrollArea::setScrollBars2() { QAbstractScrollArea scrollArea; scrollArea.resize(300, 300); QScrollBar *hbar = new QScrollBar; scrollArea.setHorizontalScrollBar(hbar); qApp->processEvents(); QCOMPARE(scrollArea.horizontalScrollBar(), hbar); QScrollBar *vbar = new QScrollBar; scrollArea.setVerticalScrollBar(vbar); qApp->processEvents(); QCOMPARE(scrollArea.verticalScrollBar(), vbar); scrollArea.horizontalScrollBar()->setRange(0, 100); scrollArea.verticalScrollBar()->setRange(0, 100); scrollArea.show(); // Make sure scroll bars are not explicitly hidden by QAbstractScrollArea itself. QVERIFY(hbar->isVisible()); QVERIFY(vbar->isVisible()); // Hide the OLD scroll bar and ensure that the NEW one is hidden. hbar->hide(); scrollArea.setHorizontalScrollBar(new QScrollBar); qApp->processEvents(); QVERIFY(!scrollArea.horizontalScrollBar()->isVisible()); vbar->hide(); scrollArea.setVerticalScrollBar(new QScrollBar); qApp->processEvents(); QVERIFY(!scrollArea.verticalScrollBar()->isVisible()); scrollArea.verticalScrollBar()->show(); scrollArea.horizontalScrollBar()->show(); // Hide the NEW scroll bar and ensure that it's visible // (because the OLD one is visible). hbar = new QScrollBar; hbar->hide(); scrollArea.setHorizontalScrollBar(hbar); qApp->processEvents(); QVERIFY(hbar->isVisible()); vbar = new QScrollBar; vbar->hide(); scrollArea.setVerticalScrollBar(vbar); qApp->processEvents(); QVERIFY(vbar->isVisible()); vbar->setRange(0, 0); qApp->processEvents(); QVERIFY(!vbar->isVisible()); hbar->setRange(0, 0); qApp->processEvents(); QVERIFY(!hbar->isVisible()); }
void TreeCanvas::resizeEvent(QResizeEvent* e) { QAbstractScrollArea* sa = static_cast<QAbstractScrollArea*>(parentWidget()->parentWidget()); int w = sa->horizontalScrollBar()->maximum()+e->oldSize().width(); int h = sa->verticalScrollBar()->maximum()+e->oldSize().height(); sa->horizontalScrollBar()->setRange(0,w-e->size().width()); sa->verticalScrollBar()->setRange(0,h-e->size().height()); sa->horizontalScrollBar()->setPageStep(e->size().width()); sa->verticalScrollBar()->setPageStep(e->size().height()); }
void TreeCanvas::scroll(int i) { QAbstractScrollArea* sa = static_cast<QAbstractScrollArea*>(parentWidget()->parentWidget()); double p = static_cast<double>(i)/100.0; double xdiff = static_cast<double>(targetX-sourceX)*p; double ydiff = static_cast<double>(targetY-sourceY)*p; sa->horizontalScrollBar()->setValue(sourceX+static_cast<int>(xdiff)); sa->verticalScrollBar()->setValue(sourceY+static_cast<int>(ydiff)); }
void TreeCanvas::scaleTree(int scale0, int zoomx, int zoomy) { QMutexLocker locker(&layoutMutex); QSize viewport_size = size(); QAbstractScrollArea* sa = static_cast<QAbstractScrollArea*>(parentWidget()->parentWidget()); if (zoomx==-1) zoomx = viewport_size.width()/2; if (zoomy==-1) zoomy = viewport_size.height()/2; int xoff = (sa->horizontalScrollBar()->value()+zoomx)/scale; int yoff = (sa->verticalScrollBar()->value()+zoomy)/scale; BoundingBox bb; scale0 = std::min(std::max(scale0, LayoutConfig::minScale), LayoutConfig::maxScale); scale = (static_cast<double>(scale0)) / 100.0; bb = root->getBoundingBox(); int w = static_cast<int>((bb.right-bb.left+Layout::extent)*scale); int h = static_cast<int>(2*Layout::extent+ root->getShape()->depth()*Layout::dist_y*scale); sa->horizontalScrollBar()->setRange(0,w-viewport_size.width()); sa->verticalScrollBar()->setRange(0,h-viewport_size.height()); sa->horizontalScrollBar()->setPageStep(viewport_size.width()); sa->verticalScrollBar()->setPageStep(viewport_size.height()); sa->horizontalScrollBar()->setSingleStep(Layout::extent); sa->verticalScrollBar()->setSingleStep(Layout::extent); xoff *= scale; yoff *= scale; sa->horizontalScrollBar()->setValue(xoff-zoomx); sa->verticalScrollBar()->setValue(yoff-zoomy); emit scaleChanged(scale0); QWidget::update(); }
void TreeCanvas::centerCurrentNode(void) { QMutexLocker locker(&mutex); int x=0; int y=0; VisualNode* c = currentNode; while (c != NULL) { x += c->getOffset(); y += Layout::dist_y; c = c->getParent(*na); } x = static_cast<int>((xtrans+x)*scale); y = static_cast<int>(y*scale); QAbstractScrollArea* sa = static_cast<QAbstractScrollArea*>(parentWidget()->parentWidget()); x -= sa->viewport()->width() / 2; y -= sa->viewport()->height() / 2; sourceX = sa->horizontalScrollBar()->value(); targetX = std::max(sa->horizontalScrollBar()->minimum(), x); targetX = std::min(sa->horizontalScrollBar()->maximum(), targetX); sourceY = sa->verticalScrollBar()->value(); targetY = std::max(sa->verticalScrollBar()->minimum(), y); targetY = std::min(sa->verticalScrollBar()->maximum(), targetY); if (!smoothScrollAndZoom) { sa->horizontalScrollBar()->setValue(targetX); sa->verticalScrollBar()->setValue(targetY); } else { scrollTimeLine.stop(); scrollTimeLine.setFrameRange(0,100); scrollTimeLine.setDuration(std::max(200, std::min(1000, std::min(std::abs(sourceX-targetX), std::abs(sourceY-targetY))))); scrollTimeLine.start(); } }
// scroll by dx, dy // return true if the widget was scrolled bool scrollWidget(const int dx, const int dy) { QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea*>(widget); if (scrollArea) { const int x = scrollArea->horizontalScrollBar()->value(); const int y = scrollArea->verticalScrollBar()->value(); scrollArea->horizontalScrollBar()->setValue(x - dx); scrollArea->verticalScrollBar()->setValue(y - dy); return (scrollArea->horizontalScrollBar()->value() != x || scrollArea->verticalScrollBar()->value() != y); } QWebView *webView = qobject_cast<QWebView*>(widget); if (webView) { QWebFrame *frame = webView->page()->mainFrame(); const QPoint position = frame->scrollPosition(); frame->setScrollPosition(position - QPoint(dx, dy)); return frame->scrollPosition() != position; } return false; }
void TreeCanvas::layoutDone(int w, int h, int scale0) { targetW = w; targetH = h; targetScale = scale0; QSize viewport_size = size(); QAbstractScrollArea* sa = static_cast<QAbstractScrollArea*>(parentWidget()->parentWidget()); sa->horizontalScrollBar()->setRange(0,w-viewport_size.width()); sa->verticalScrollBar()->setRange(0,h-viewport_size.height()); if (layoutDoneTimerId == 0) layoutDoneTimerId = startTimer(15); }
VisualNode* TreeCanvas::eventNode(QEvent* event) { int x = 0; int y = 0; switch (event->type()) { case QEvent::ToolTip: { QHelpEvent* he = static_cast<QHelpEvent*>(event); x = he->x(); y = he->y(); break; } case QEvent::MouseButtonDblClick: case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: case QEvent::MouseMove: { QMouseEvent* me = static_cast<QMouseEvent*>(event); x = me->x(); y = me->y(); break; } case QEvent::ContextMenu: { QContextMenuEvent* ce = static_cast<QContextMenuEvent*>(event); x = ce->x(); y = ce->y(); break; } default: return NULL; } QAbstractScrollArea* sa = static_cast<QAbstractScrollArea*>(parentWidget()->parentWidget()); int xoff = sa->horizontalScrollBar()->value()/scale; int yoff = sa->verticalScrollBar()->value()/scale; BoundingBox bb = root->getBoundingBox(); int w = static_cast<int>((bb.right-bb.left+Layout::extent)*scale); if (w < sa->viewport()->width()) xoff -= (sa->viewport()->width()-w)/2; VisualNode* n; n = root->findNode(*na, static_cast<int>(x/scale-xtrans+xoff), static_cast<int>((y-30)/scale+yoff)); return n; }
bool TextView::eventFilter(QObject *obj, QEvent *event) { #ifdef SCINTILLA QAbstractScrollArea * sa = scintEditor; #else QAbstractScrollArea * sa = plainTextEdit; #endif if (obj == sa) { sa->setAttribute(Qt::WA_NoMousePropagation, false); if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); switch (keyEvent->key()) { case Qt::Key_Z: if (keyEvent->modifiers().testFlag(Qt::ShiftModifier) && keyEvent->modifiers().testFlag(Qt::ControlModifier)) { byteSource->historyForward(); keyEvent->accept(); return true; } else if (keyEvent->modifiers().testFlag(Qt::ControlModifier)) { byteSource->historyBackward(); keyEvent->accept(); return true; } break; default: return false; } } else if (event->type() == QEvent::Wheel) { if (sa->verticalScrollBar()->isVisible()) { sa->setAttribute(Qt::WA_NoMousePropagation); } return false; } } return QWidget::eventFilter(obj, event); }
void TreeCanvas::paintEvent(QPaintEvent* event) { QMutexLocker locker(&layoutMutex); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); QAbstractScrollArea* sa = static_cast<QAbstractScrollArea*>(parentWidget()->parentWidget()); int xoff = sa->horizontalScrollBar()->value()/scale; int yoff = sa->verticalScrollBar()->value()/scale; BoundingBox bb = root->getBoundingBox(); int w = static_cast<int>((bb.right-bb.left+Layout::extent)*scale); if (w < sa->viewport()->width()) xoff -= (sa->viewport()->width()-w)/2; QRect origClip = event->rect(); painter.translate(0, 30); painter.scale(scale,scale); painter.translate(xtrans-xoff, -yoff); QRect clip(static_cast<int>(origClip.x()/scale-xtrans+xoff), static_cast<int>(origClip.y()/scale+yoff), static_cast<int>(origClip.width()/scale), static_cast<int>(origClip.height()/scale)); DrawingCursor dc(root, *na, curBest, painter, clip, showCopies); PreorderNodeVisitor<DrawingCursor>(dc).run(); // int nodesLayouted = 1; // clock_t t0 = clock(); // while (v.next()) { nodesLayouted++; } // double t = (static_cast<double>(clock()-t0) / CLOCKS_PER_SEC) * 1000.0; // double nps = static_cast<double>(nodesLayouted) / // (static_cast<double>(clock()-t0) / CLOCKS_PER_SEC); // std::cout << "Drawing done. " << nodesLayouted << " nodes in " // << t << " ms. " << nps << " nodes/s." << std::endl; }
void FindBar::find(FindBar::FindDirection dir) { Q_ASSERT(m_associatedWebView); if (isHidden()) { QPoint previous_position = m_associatedWebView->page()->currentFrame()->scrollPosition(); m_associatedWebView->page()->focusNextPrevChild(true); m_associatedWebView->page()->currentFrame()->setScrollPosition(previous_position); return; } QWebPage::FindFlags options = QWebPage::FindWrapsAroundDocument; if (dir == Backward) options |= QWebPage::FindBackward; if (matchCase()) options |= QWebPage::FindCaseSensitively; // HACK Because we're using the QWebView inside a QScrollArea container, the attempts // to scroll the QWebView itself have no direct effect. // Therefore we temporarily shrink the page viewport to the message viewport (ie. the size it // can cover at max), then perform the search, store the scrollPosition, restore the page viewport // and finally scroll the messageview to the gathered scrollPosition, mapped to the message (ie. // usually offset by the mail header) auto emb = qobject_cast<EmbeddedWebView *>(m_associatedWebView); QAbstractScrollArea *container = emb ? static_cast<QAbstractScrollArea*>(emb->scrollParent()) : nullptr; const QSize oldVpS = m_associatedWebView->page()->viewportSize(); const bool useResizeTrick = container ? !!container->verticalScrollBar() : false; // first shrink the page viewport if (useResizeTrick) { m_associatedWebView->setUpdatesEnabled(false); // don't let the user see the flicker we might produce QSize newVpS = oldVpS.boundedTo(container->size()); m_associatedWebView->page()->setViewportSize(newVpS); } // now perform the search (pot. in the shrinked viewport) bool found = m_associatedWebView->page()->findText(_lastStringSearched, options); notifyMatch(found); // scroll and reset the page viewport if necessary if (useResizeTrick) { Q_ASSERT(container->verticalScrollBar()); // the page has now a usable scroll position ... int scrollPosition = m_associatedWebView->page()->currentFrame()->scrollPosition().y(); // ... which needs to be extended by the pages offset (usually the header widget) // NOTICE: QWidget::mapTo() fails as the viewport child position can be negative, so we run ourself QWidget *runner = m_associatedWebView; while (runner->parentWidget() != container->viewport()) { scrollPosition += runner->y(); runner = runner->parentWidget(); } // reset viewport to original size ... m_associatedWebView->page()->setViewportSize(oldVpS); // ... let the user see the change ... m_associatedWebView->setUpdatesEnabled(true); // ... and finally scroll to the desired position if (found) container->verticalScrollBar()->setValue(scrollPosition); } if (!found) { QPoint previous_position = m_associatedWebView->page()->currentFrame()->scrollPosition(); m_associatedWebView->page()->focusNextPrevChild(true); m_associatedWebView->page()->currentFrame()->setScrollPosition(previous_position); } }
void ScrollAreaLayout::setGeometry ( const QRect & r ) { QAbstractScrollArea* theChild = dynamic_cast<QAbstractScrollArea*>(theItem->widget()); //qDebug() << "--------------------------------------"; // qDebug() << " Layout geometry:" << r; //qDebug() << " Scroll bar width: " << theChild->verticalScrollBar()->width(); // get the widget which is scrolled by the scrollarea //QWidget* wdg = theChild->widget(); // qDebug() << "Widget sizeHint():" << wdg->objectName() << " - "<< wdg->sizeHint(); //qDebug() << "Widget size():" << wdg->objectName() << " - "<< wdg->size(); // int fh = theChild->fontMetrics().height(); //qDebug() << "Scroll area max size:" << QSize(36 * fh, 24 * fh); int wid = theChild->sizeHint().width(); // frame width is considered! int h = theChild->sizeHint().height(); // frame height is considered! int xpos = 0; int ypos = 0; if (r.width() < wid && r.height() < h) { // both scrollbars required wid = r.width(); h = r.height(); } else if (r.width() < wid) { // only horizontal scroll bar required h += theChild->horizontalScrollBar()->sizeHint().height(); wid = r.width(); // the new y position is based on the extended height (including scroll bars) // this leads to a lesser smoothly transition from no scroll bars to scroll bars, // but avoids an asymmetry once the scroll bars are shown. ypos = (r.height() - h) / 2; if (r.height() < h) { // again both required xpos = 0; ypos = 0; h = r.height(); } } else if (r.height() < h) { // only vertical scroll bar required wid += theChild->verticalScrollBar()->sizeHint().width(); h = r.height(); // the new x position is based on the extended width (including scroll bars) // this leads to a lesser smoothly transition from no scroll bars to scroll bars, // but avoids an asymmetry once the scroll bars are shown. xpos = (r.width() - wid) / 2; if (r.width() < wid) { // again both required xpos = 0; ypos = 0; wid = r.width(); } } else { xpos = (r.width() - wid) / 2; ypos = (r.height() - h) / 2; } int frameWidth = 0; // !!!! QRect newRect = QRect(xpos, ypos, wid + frameWidth, h + frameWidth); //qDebug() << " Child geometry:" << newRect; theChild->setGeometry(newRect); }