Ejemplo n.º 1
0
ScrollbarPart ScrollbarThemeQt::hitTest(Scrollbar* scrollbar, const PlatformMouseEvent& evt)
{
    QStyleOptionSlider* opt = styleOptionSlider(scrollbar);
    const QPoint pos = scrollbar->convertFromContainingWindow(evt.pos());
    opt->rect.moveTo(QPoint(0, 0));
    QStyle::SubControl sc = style()->hitTestComplexControl(QStyle::CC_ScrollBar, opt, pos, 0);
    return scrollbarPart(sc);
}
Ejemplo n.º 2
0
bool PlatformScrollbar::handleMousePressEvent(const PlatformMouseEvent& e)
{
    if (!parent())
        return true;

    // TODO(pkasting): http://b/583875 Right-click should invoke a context menu
    // (maybe this would be better handled elsewhere?)
    if (!m_enabled || (e.button() != LeftButton)) {
        return true;
    }

    ASSERT(m_captureStart == None);

    IntPoint pos = convertFromContainingWindow(e.pos());

    const bool horz = (orientation() == HorizontalScrollbar);
    updateMousePosition(pos.x(), pos.y());
    switch (m_mouseOver) {
    case Arrow1:
        scroll(horz ? ScrollLeft : ScrollUp, ScrollByLine);
        break;
    case Track:
        return true;
    case BeforeThumb:
        scroll(horz ? ScrollLeft : ScrollUp, ScrollByPage);
        break;
    case Thumb:
        m_dragOrigin.thumbPos = horz ? pos.x() : pos.y();
        m_dragOrigin.scrollVal = value();
        break;
    case AfterThumb:
        scroll(horz ? ScrollRight : ScrollDown, ScrollByPage);
        break;
    case Arrow2:
        scroll(horz ? ScrollRight : ScrollDown, ScrollByLine);
        break;
    default:
        ASSERT_NOT_REACHED();
    }

    setCapturingMouse(true);

    // Kick off auto-repeat timer
    if (m_mouseOver != Thumb)
        m_autorepeatTimer.start(kAutorepeatInitialDelay,
                                kAutorepeatRepeatInterval);

    m_needsLayout = true;
    // FIXME: Invalidate only the portions that actually changed
    invalidate();

    return true;
}
Ejemplo n.º 3
0
void PlatformScrollbar::handleMouseMoveEventWhenCapturing(const PlatformMouseEvent& e)
{
    IntPoint pos = convertFromContainingWindow(e.pos());
    updateMousePosition(pos.x(), pos.y());

    if (m_captureStart != Thumb) {
        // FIXME: Invalidate only the portions that actually changed
        invalidate();
        return;
    }

    int xCancelDistance, yCancelDistance, backgroundSpan, thumbGirth, delta;
    // NOTE: The cancel distance calculations are based on the behavior of the
    // MSVC8 main window scrollbar + some guessing/extrapolation
    if (orientation() == HorizontalScrollbar) {
        xCancelDistance = kOffEndMultiplier * horizontalScrollbarHeight();
        yCancelDistance = kOffSideMultiplier * horizontalScrollbarHeight();
        backgroundSpan = m_segmentRects[AfterThumb].right() -
            m_segmentRects[BeforeThumb].x();
        thumbGirth = m_segmentRects[Thumb].right() - m_segmentRects[Thumb].x();
        delta = pos.x() - m_dragOrigin.thumbPos;
    } else {
        xCancelDistance = kOffSideMultiplier * verticalScrollbarWidth();
        yCancelDistance = kOffEndMultiplier * verticalScrollbarWidth();
        backgroundSpan = m_segmentRects[AfterThumb].bottom() -
            m_segmentRects[BeforeThumb].y();
        thumbGirth = m_segmentRects[Thumb].bottom() - m_segmentRects[Thumb].y();
        delta = pos.y() - m_dragOrigin.thumbPos;
    }

    // Snap scrollbar back to drag origin if mouse gets too far away
    if ((m_lastNativePos.x() <
            (m_segmentRects[BeforeThumb].x() - xCancelDistance)) ||
        (m_lastNativePos.x() >
            (m_segmentRects[AfterThumb].right() + xCancelDistance)) ||
        (m_lastNativePos.y() <
            (m_segmentRects[BeforeThumb].y() - yCancelDistance)) ||
        (m_lastNativePos.y() >
            (m_segmentRects[AfterThumb].bottom() + yCancelDistance)))
        delta = 0;

    // Convert delta from pixel coords to scrollbar logical coords
    if (backgroundSpan > thumbGirth) {
        if (setValue(m_dragOrigin.scrollVal + (delta *
            (m_totalSize - m_visibleSize) / (backgroundSpan - thumbGirth)))) {
            m_needsLayout = true;
            // FIXME: Invalidate only the portions that actually changed
            invalidate();
        }
    }
}
Ejemplo n.º 4
0
bool EventTargetNode::dispatchMouseEvent(const PlatformMouseEvent& _mouse, const AtomicString& eventType,
                                             int detail, Node* relatedTarget)
{
    assert(!eventDispatchForbidden());
    
    IntPoint contentsPos;
    if (FrameView* view = document()->view())
        contentsPos = view->viewportToContents(_mouse.pos());
    
    return dispatchMouseEvent(eventType, _mouse.button(), detail,
                              contentsPos.x(), contentsPos.y(), _mouse.globalX(), _mouse.globalY(),
                              _mouse.ctrlKey(), _mouse.altKey(), _mouse.shiftKey(), _mouse.metaKey(),
                              false, relatedTarget);
}
Ejemplo n.º 5
0
bool PlatformScrollbar::handleMouseReleaseEvent(const PlatformMouseEvent& e)
{
    ScrollView* parentView = parent();
    if (!parentView)
        return true;

    IntPoint pos = convertFromContainingWindow(e.pos());
    updateMousePosition(pos.x(), pos.y());

    setCapturingMouse(false);

    // FIXME: Invalidate only the portions that actually changed
    invalidate();
    return true;
}
Ejemplo n.º 6
0
bool PlatformScrollbar::handleMouseMoveEvent(const PlatformMouseEvent& e)
{
    if (!parent())
        return true;

    if (m_captureStart != None) {
        handleMouseMoveEventWhenCapturing(e);
        return true;
    }

    IntPoint pos = convertFromContainingWindow(e.pos());
    updateMousePosition(pos.x(), pos.y());

    // FIXME: Invalidate only the portions that actually changed
    invalidate();
    return true;
}
Ejemplo n.º 7
0
bool ScrollbarThemeWin::shouldSnapBackToDragOrigin(Scrollbar* scrollbar, const PlatformMouseEvent& evt)
{
    // Find the rect within which we shouldn't snap, by expanding the track rect
    // in both dimensions.
    IntRect rect = trackRect(scrollbar);
    const bool horz = scrollbar->orientation() == HorizontalScrollbar;
    const int thickness = scrollbarThickness(scrollbar->controlSize());
    rect.inflateX((horz ? kOffEndMultiplier : kOffSideMultiplier) * thickness);
    rect.inflateY((horz ? kOffSideMultiplier : kOffEndMultiplier) * thickness);

    // Convert the event to local coordinates.
    IntPoint mousePosition = scrollbar->convertFromContainingWindow(evt.pos());
    mousePosition.move(scrollbar->x(), scrollbar->y());

    // We should snap iff the event is outside our calculated rect.
    return !rect.contains(mousePosition);
}
Ejemplo n.º 8
0
bool EventTargetNode::dispatchMouseEvent(const PlatformMouseEvent& event, const AtomicString& eventType,
    int detail, Node* relatedTarget)
{
    ASSERT(!eventDispatchForbidden());
    
    IntPoint contentsPos;
    if (FrameView* view = document()->view())
        contentsPos = view->windowToContents(event.pos());

    short button = event.button();

    ASSERT(event.eventType() == MouseEventMoved || button != NoButton);
    
    return dispatchMouseEvent(eventType, button, detail,
        contentsPos.x(), contentsPos.y(), event.globalX(), event.globalY(),
        event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(),
        false, relatedTarget);
}
Ejemplo n.º 9
0
bool PlatformScrollbar::handleMouseReleaseEvent(const PlatformMouseEvent& evt)
{
    const QPoint pos = convertFromContainingWindow(evt.pos());
    const QPoint topLeft = m_opt.rect.topLeft();
    m_opt.rect.moveTo(QPoint(0, 0));
    QStyle::SubControl scAtMousePoint = QApplication::style()->hitTestComplexControl(QStyle::CC_ScrollBar, &m_opt, pos, 0);
    m_opt.rect.moveTo(topLeft);

    m_hoveredPart = scAtMousePoint;
    if (m_hoveredPart == QStyle::SC_None)
        m_opt.state &= ~QStyle::State_MouseOver;

    m_opt.state &= ~QStyle::State_Sunken;
    m_pressedPart = QStyle::SC_None;
    m_pressedPos = 0;
    stopTimerIfNeeded();
    invalidate();
    return true;
}
Ejemplo n.º 10
0
bool PlatformScrollbar::handleContextMenuEvent(const PlatformMouseEvent& event)
{
#ifndef QT_NO_CONTEXTMENU
    bool horizontal = (m_orientation == HorizontalScrollbar);

    QMenu menu;
    QAction* actScrollHere = menu.addAction(tr("Scroll here"));
    menu.addSeparator();

    QAction* actScrollTop = menu.addAction(horizontal ? tr("Left edge") : tr("Top"));
    QAction* actScrollBottom = menu.addAction(horizontal ? tr("Right edge") : tr("Bottom"));
    menu.addSeparator();

    QAction* actPageUp = menu.addAction(horizontal ? tr("Page left") : tr("Page up"));
    QAction* actPageDown = menu.addAction(horizontal ? tr("Page right") : tr("Page down"));
    menu.addSeparator();

    QAction* actScrollUp = menu.addAction(horizontal ? tr("Scroll left") : tr("Scroll up"));
    QAction* actScrollDown = menu.addAction(horizontal ? tr("Scroll right") : tr("Scroll down"));

    const QPoint globalPos = QPoint(event.globalX(), event.globalY());
    QAction* actionSelected = menu.exec(globalPos);

    if (actionSelected == 0)
        /* Do nothing */ ;
    else if (actionSelected == actScrollHere) {
        const QPoint pos = convertFromContainingWindow(event.pos());
        setValue(pixelPosToRangeValue(horizontal ? pos.x() : pos.y()));
    } else if (actionSelected == actScrollTop)
        setValue(0);
    else if (actionSelected == actScrollBottom)
        setValue(m_totalSize - m_visibleSize);
    else if (actionSelected == actPageUp)
        scroll(horizontal ? ScrollLeft: ScrollUp, ScrollByPage, 1);
    else if (actionSelected == actPageDown)
        scroll(horizontal ? ScrollRight : ScrollDown, ScrollByPage, 1);
    else if (actionSelected == actScrollUp)
        scroll(horizontal ? ScrollLeft : ScrollUp, ScrollByLine, 1);
    else if (actionSelected == actScrollDown)
        scroll(horizontal ? ScrollRight : ScrollDown, ScrollByLine, 1);
#endif // QT_NO_CONTEXTMENU
    return true;
}
Ejemplo n.º 11
0
bool PlatformScrollbar::handleMousePressEvent(const PlatformMouseEvent& evt)
{
    // Early exit for right click
    if (evt.button() == RightButton)
        return true; // Handled as context menu

    const QPoint pos = convertFromContainingWindow(evt.pos());
    bool midButtonAbsPos = QApplication::style()->styleHint(QStyle::SH_ScrollBar_MiddleClickAbsolutePosition);

    // Middle click centers slider thumb, if supported
    if (midButtonAbsPos && evt.button() == MiddleButton) {
        setValue(pixelPosToRangeValue((m_orientation == HorizontalScrollbar ?
                                        pos.x() : pos.y()) - thumbLength() / 2));

    } else { // Left button, or if middle click centering is not supported
        const QPoint topLeft = m_opt.rect.topLeft();
        m_opt.rect.moveTo(QPoint(0, 0));
        QStyle::SubControl sc = QApplication::style()->hitTestComplexControl(QStyle::CC_ScrollBar, &m_opt, pos, 0);
        m_opt.rect.moveTo(topLeft);
        switch (sc) {
            case QStyle::SC_ScrollBarAddLine:
            case QStyle::SC_ScrollBarSubLine:
            case QStyle::SC_ScrollBarSlider:
                m_opt.state |= QStyle::State_Sunken;
            case QStyle::SC_ScrollBarAddPage:
            case QStyle::SC_ScrollBarSubPage:
            case QStyle::SC_ScrollBarGroove:
                m_pressedPart = sc;
                break;
            default:
                m_pressedPart = QStyle::SC_None;
                return false;
        }
        m_pressedPos = m_orientation == HorizontalScrollbar ? pos.x() : pos.y();
        autoscrollPressedPart(cInitialTimerDelay);
        invalidate();
    }

    return true;
}
ScrollbarPart ScrollbarThemeComposite::hitTest(Scrollbar* scrollbar, const PlatformMouseEvent& evt)
{
    ScrollbarPart result = NoPart;
    if (!scrollbar->enabled())
        return result;

    IntPoint mousePosition = scrollbar->convertFromContainingWindow(evt.pos());
    mousePosition.move(scrollbar->x(), scrollbar->y());
    
    if (!scrollbar->frameRect().contains(mousePosition))
        return NoPart;

    result = ScrollbarBGPart;

    IntRect track = trackRect(scrollbar);
    if (track.contains(mousePosition)) {
        IntRect beforeThumbRect;
        IntRect thumbRect;
        IntRect afterThumbRect;
        splitTrack(scrollbar, track, beforeThumbRect, thumbRect, afterThumbRect);
        if (thumbRect.contains(mousePosition))
            result = ThumbPart;
        else if (beforeThumbRect.contains(mousePosition))
            result = BackTrackPart;
        else if (afterThumbRect.contains(mousePosition))
            result = ForwardTrackPart;
        else
            result = TrackBGPart;
    } else if (backButtonRect(scrollbar, BackButtonStartPart).contains(mousePosition))
        result = BackButtonStartPart;
    else if (backButtonRect(scrollbar, BackButtonEndPart).contains(mousePosition))
        result = BackButtonEndPart;
    else if (forwardButtonRect(scrollbar, ForwardButtonStartPart).contains(mousePosition))
        result = ForwardButtonStartPart;
    else if (forwardButtonRect(scrollbar, ForwardButtonEndPart).contains(mousePosition))
        result = ForwardButtonEndPart;
    return result;
}
Ejemplo n.º 13
0
bool Scrollbar::mouseMoved(const PlatformMouseEvent& evt)
{
    if (m_pressedPart == ThumbPart) {
        if (theme()->shouldSnapBackToDragOrigin(this, evt)) {
            if (m_scrollableArea)
                m_scrollableArea->scrollToOffsetWithoutAnimation(m_orientation, m_dragOrigin);
        } else {
            moveThumb(m_orientation == HorizontalScrollbar ? 
                      convertFromContainingWindow(evt.pos()).x() :
                      convertFromContainingWindow(evt.pos()).y(), theme()->shouldDragDocumentInsteadOfThumb(this, evt));
        }
        return true;
    }

    if (m_pressedPart != NoPart)
        m_pressedPos = (orientation() == HorizontalScrollbar ? convertFromContainingWindow(evt.pos()).x() : convertFromContainingWindow(evt.pos()).y());

    ScrollbarPart part = theme()->hitTest(this, evt);    
    if (part != m_hoveredPart) {
        if (m_pressedPart != NoPart) {
            if (part == m_pressedPart) {
                // The mouse is moving back over the pressed part.  We
                // need to start up the timer action again.
                startTimerIfNeeded(theme()->autoscrollTimerDelay());
                theme()->invalidatePart(this, m_pressedPart);
            } else if (m_hoveredPart == m_pressedPart) {
                // The mouse is leaving the pressed part.  Kill our timer
                // if needed.
                stopTimerIfNeeded();
                theme()->invalidatePart(this, m_pressedPart);
            }
        } 
        
        setHoveredPart(part);
    } 

    return true;
}
Ejemplo n.º 14
0
bool DragController::startDrag(Frame* src, Clipboard* clipboard, DragOperation srcOp, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin, bool isDHTMLDrag)
#endif
{    
    ASSERT(src);
    ASSERT(clipboard);
    
    if (!src->view() || !src->renderer())
        return false;
    
    HitTestResult dragSource = HitTestResult(dragOrigin);
    dragSource = src->eventHandler()->hitTestResultAtPoint(dragOrigin, true);
    KURL linkURL = dragSource.absoluteLinkURL();
    KURL imageURL = dragSource.absoluteImageURL();
    bool isSelected = dragSource.isSelected();
    
    IntPoint mouseDraggedPoint = src->view()->windowToContents(dragEvent.pos());
    
    m_draggingImageURL = KURL();
    m_dragOperation = srcOp;
    
    DragImageRef dragImage = 0;
    IntPoint dragLoc(0, 0);
    IntPoint dragImageOffset(0, 0);
    
    if (isDHTMLDrag) 
        dragImage = clipboard->createDragImage(dragImageOffset);
    
    // We allow DHTML/JS to set the drag image, even if its a link, image or text we're dragging.
    // This is in the spirit of the IE API, which allows overriding of pasteboard data and DragOp.
    if (dragImage) {
        dragLoc = dragLocForDHTMLDrag(mouseDraggedPoint, dragOrigin, dragImageOffset, !linkURL.isEmpty());
        m_dragOffset = dragImageOffset;
    }
    
    bool startedDrag = true; // optimism - we almost always manage to start the drag
    
    Node* node = dragSource.innerNonSharedNode();
    
    if (!imageURL.isEmpty() && node && node->isElementNode()
            && getImage(static_cast<Element*>(node)) 
            && (m_dragSourceAction & DragSourceActionImage)) {
        Element* element = static_cast<Element*>(node);
        if (!clipboard->hasData()) {
            m_draggingImageURL = imageURL; 
            prepareClipboardForImageDrag(src, clipboard, element, linkURL, imageURL, dragSource.altDisplayString());
        }
        
        m_client->willPerformDragSourceAction(DragSourceActionImage, dragOrigin, clipboard);
        
        if (!dragImage) {
            IntRect imageRect = dragSource.imageRect();
            imageRect.setLocation(m_page->mainFrame()->view()->windowToContents(src->view()->contentsToWindow(imageRect.location())));
            doImageDrag(element, dragOrigin, dragSource.imageRect(), clipboard, src, m_dragOffset);
        } else 
            // DHTML defined drag image
            doSystemDrag(dragImage, dragLoc, dragOrigin, clipboard, src, false);

    } else if (!linkURL.isEmpty() && (m_dragSourceAction & DragSourceActionLink)) {
        if (!clipboard->hasData())
            // Simplify whitespace so the title put on the clipboard resembles what the user sees
            // on the web page. This includes replacing newlines with spaces.
            clipboard->writeURL(linkURL, dragSource.textContent().simplifyWhiteSpace(), src);
        
        m_client->willPerformDragSourceAction(DragSourceActionLink, dragOrigin, clipboard);
        if (!dragImage) {
            dragImage = m_client->createDragImageForLink(linkURL, dragSource.textContent(), src);
            IntSize size = dragImageSize(dragImage);
            m_dragOffset = IntPoint(-size.width() / 2, -LinkDragBorderInset);
            dragLoc = IntPoint(mouseDraggedPoint.x() + m_dragOffset.x(), mouseDraggedPoint.y() + m_dragOffset.y());
        } 
        doSystemDrag(dragImage, dragLoc, mouseDraggedPoint, clipboard, src, true);
    } else if (isSelected && (m_dragSourceAction & DragSourceActionSelection)) {
        RefPtr<Range> selectionRange = src->selectionController()->toRange();
        ASSERT(selectionRange);
        if (!clipboard->hasData()) 
            clipboard->writeRange(selectionRange.get(), src);
        m_client->willPerformDragSourceAction(DragSourceActionSelection, dragOrigin, clipboard);
        if (!dragImage) {
            dragImage = createDragImageForSelection(src);
            dragLoc = dragLocForSelectionDrag(src);
            m_dragOffset = IntPoint((int)(dragOrigin.x() - dragLoc.x()), (int)(dragOrigin.y() - dragLoc.y()));
        }
        doSystemDrag(dragImage, dragLoc, dragOrigin, clipboard, src, false);
    } else if (isDHTMLDrag) {
        ASSERT(m_dragSourceAction & DragSourceActionDHTML);
        m_client->willPerformDragSourceAction(DragSourceActionDHTML, dragOrigin, clipboard);
        doSystemDrag(dragImage, dragLoc, dragOrigin, clipboard, src, false);
    } else {
        // Only way I know to get here is if to get here is if the original element clicked on in the mousedown is no longer
        // under the mousedown point, so linkURL, imageURL and isSelected are all false/empty.
        startedDrag = false;
    }
    
    if (dragImage)
        deleteDragImage(dragImage);
    return startedDrag;
}
Ejemplo n.º 15
0
bool PlatformScrollbar::handleMousePressEvent(const PlatformMouseEvent& evt)
{
    m_pressedPart = hitTest(evt);
    m_pressedPos = (m_orientation == HorizontalScrollbar ? convertFromContainingWindow(evt.pos()).x() : convertFromContainingWindow(evt.pos()).y());
    invalidatePart(m_pressedPart);
    autoscrollPressedPart(cInitialTimerDelay);
    return true;
}
Ejemplo n.º 16
0
bool PlatformScrollbar::handleMouseMoveEvent(const PlatformMouseEvent& evt)
{
    if (m_pressedPart == ThumbPart) 
    {
        // Drag the thumb.
        int thumbPos = thumbPosition();
        int thumbLen = thumbLength();
        int trackLen = trackLength();
        int maxPos = trackLen - thumbLen;
        int delta = 0;
        if (m_orientation == HorizontalScrollbar)
            delta = convertFromContainingWindow(evt.pos()).x() - m_pressedPos;
        else
            delta = convertFromContainingWindow(evt.pos()).y() - m_pressedPos;

        if (delta > 0)
            // The mouse moved down/right.
            delta = min(maxPos - thumbPos, delta);
        else if (delta < 0)
            // The mouse moved up/left.
            delta = max(-thumbPos, delta);

        if (delta != 0) 
        {
            setValue(static_cast<int>((float)(thumbPos + delta) * (m_totalSize - m_visibleSize) / (trackLen - thumbLen)));
            m_pressedPos += thumbPosition() - thumbPos;
        }

        return true;
    }

    if (m_pressedPart != NoPart)
        m_pressedPos = (m_orientation == HorizontalScrollbar ? convertFromContainingWindow(evt.pos()).x() : convertFromContainingWindow(evt.pos()).y());

    ScrollbarPart part = hitTest(evt);    
    if (part != m_hoveredPart) 
    {
        if (m_pressedPart != NoPart) 
        {
            if (part == m_pressedPart) 
            {
                // The mouse is moving back over the pressed part.  We
                // need to start up the timer action again.
                startTimerIfNeeded(cNormalTimerDelay);
                invalidatePart(m_pressedPart);
            } else if (m_hoveredPart == m_pressedPart) 
            {
                // The mouse is leaving the pressed part.  Kill our timer
                // if needed.
                stopTimerIfNeeded();
                invalidatePart(m_pressedPart);
            }
        } 
        else 
        {
            invalidatePart(part);
            invalidatePart(m_hoveredPart);

        }
        m_hoveredPart = part;

    } 

    updateViewOnMouseHover();
    return true;
}
Ejemplo n.º 17
0
bool PlatformScrollbar::handleMouseMoveEvent(const PlatformMouseEvent& evt)
{
    const QPoint pos = convertFromContainingWindow(evt.pos());
    //qDebug() << "PlatformScrollbar::handleMouseMoveEvent" << m_opt.rect << pos << evt.pos();

    m_opt.state |= QStyle::State_MouseOver;
    const QPoint topLeft = m_opt.rect.topLeft();
    m_opt.rect.moveTo(QPoint(0, 0));
    QStyle::SubControl sc = QApplication::style()->hitTestComplexControl(QStyle::CC_ScrollBar, &m_opt, pos, 0);
    m_opt.rect.moveTo(topLeft);

    if (m_pressedPart == QStyle::SC_ScrollBarSlider) {
        // Drag the thumb.
        int thumbPos = thumbPosition();
        int thumbLen = thumbLength();
        int trackLen = trackLength();
        int maxPos = trackLen - thumbLen;
        int delta = 0;
        if (m_orientation == HorizontalScrollbar)
            delta = pos.x() - m_pressedPos;
        else
            delta = pos.y() - m_pressedPos;

        if (delta > 0)
            // The mouse moved down/right.
            delta = min(maxPos - thumbPos, delta);
        else if (delta < 0)
            // The mouse moved up/left.
            delta = max(-thumbPos, delta);

        if (delta != 0) {
            setValue((int)((float)(thumbPos + delta) * (m_totalSize - m_visibleSize) / (trackLen - thumbLen)));
            m_pressedPos += thumbPosition() - thumbPos;
        }

        return true;
    }

    if (m_pressedPart != QStyle::SC_None)
        m_pressedPos = m_orientation == HorizontalScrollbar ? pos.x() : pos.y();

    if (sc != m_hoveredPart) {
        if (m_pressedPart != QStyle::SC_None) {
            if (sc == m_pressedPart) {
                // The mouse is moving back over the pressed part.  We
                // need to start up the timer action again.
                startTimerIfNeeded(cNormalTimerDelay);
                invalidate();
            } else if (m_hoveredPart == m_pressedPart) {
                // The mouse is leaving the pressed part.  Kill our timer
                // if needed.
                stopTimerIfNeeded();
                invalidate();
            }
        } else {
            invalidate();
        }
        m_hoveredPart = sc;
    }

    return true;
}
Ejemplo n.º 18
0
bool Scrollbar::mouseDown(const PlatformMouseEvent& evt)
{
    // Early exit for right click
    if (evt.button() == RightButton)
        return true; // FIXME: Handled as context menu by Qt right now.  Should just avoid even calling this method on a right click though.

    setPressedPart(theme()->hitTest(this, evt));
    int pressedPos = (orientation() == HorizontalScrollbar ? convertFromContainingWindow(evt.pos()).x() : convertFromContainingWindow(evt.pos()).y());
    
    if ((m_pressedPart == BackTrackPart || m_pressedPart == ForwardTrackPart) && theme()->shouldCenterOnThumb(this, evt)) {
        setHoveredPart(ThumbPart);
        setPressedPart(ThumbPart);
        m_dragOrigin = m_currentPos;
        int thumbLen = theme()->thumbLength(this);
        int desiredPos = pressedPos;
        // Set the pressed position to the middle of the thumb so that when we do the move, the delta
        // will be from the current pixel position of the thumb to the new desired position for the thumb.
        m_pressedPos = theme()->trackPosition(this) + theme()->thumbPosition(this) + thumbLen / 2;
        moveThumb(desiredPos);
        return true;
    } else if (m_pressedPart == ThumbPart)
        m_dragOrigin = m_currentPos;
    
    m_pressedPos = pressedPos;

    autoscrollPressedPart(theme()->initialAutoscrollTimerDelay());
    return true;
}
Ejemplo n.º 19
0
bool DragController::startDrag(Frame* src, Clipboard* clipboard, DragOperation srcOp, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin, bool isDHTMLDrag)
{
    ASSERT(src);
    ASSERT(clipboard);

    if (!src->view() || !src->contentRenderer())
        return false;

    HitTestResult dragSource = HitTestResult(dragOrigin);
    dragSource = src->eventHandler()->hitTestResultAtPoint(dragOrigin, true);
    KURL linkURL = dragSource.absoluteLinkURL();
    KURL imageURL = dragSource.absoluteImageURL();
    bool isSelected = dragSource.isSelected();

    IntPoint mouseDraggedPoint = src->view()->windowToContents(dragEvent.pos());

    m_draggingImageURL = KURL();
    m_sourceDragOperation = srcOp;

    DragImageRef dragImage = 0;
    IntPoint dragLoc(0, 0);
    IntPoint dragImageOffset(0, 0);

    if (isDHTMLDrag)
        dragImage = clipboard->createDragImage(dragImageOffset);
    else {
        // This drag operation is not a DHTML drag and may go outside the WebView.
        // We provide a default set of allowed drag operations that follows from:
        // http://trac.webkit.org/browser/trunk/WebKit/mac/WebView/WebHTMLView.mm?rev=48526#L3430
        m_sourceDragOperation = (DragOperation)(DragOperationGeneric | DragOperationCopy);
    }

    // We allow DHTML/JS to set the drag image, even if its a link, image or text we're dragging.
    // This is in the spirit of the IE API, which allows overriding of pasteboard data and DragOp.
    if (dragImage) {
        dragLoc = dragLocForDHTMLDrag(mouseDraggedPoint, dragOrigin, dragImageOffset, !linkURL.isEmpty());
        m_dragOffset = dragImageOffset;
    }

    bool startedDrag = true; // optimism - we almost always manage to start the drag

    Node* node = dragSource.innerNonSharedNode();

    Image* image = getImage(static_cast<Element*>(node));
    if (!imageURL.isEmpty() && node && node->isElementNode() && image
            && (m_dragSourceAction & DragSourceActionImage)) {
        // We shouldn't be starting a drag for an image that can't provide an extension.
        // This is an early detection for problems encountered later upon drop.
        ASSERT(!image->filenameExtension().isEmpty());
        Element* element = static_cast<Element*>(node);
        if (!clipboard->hasData()) {
            m_draggingImageURL = imageURL;
            prepareClipboardForImageDrag(src, clipboard, element, linkURL, imageURL, dragSource.altDisplayString());
        }

        m_client->willPerformDragSourceAction(DragSourceActionImage, dragOrigin, clipboard);

        if (!dragImage) {
            IntRect imageRect = dragSource.imageRect();
            imageRect.setLocation(m_page->mainFrame()->view()->windowToContents(src->view()->contentsToWindow(imageRect.location())));
            doImageDrag(element, dragOrigin, dragSource.imageRect(), clipboard, src, m_dragOffset);
        } else
            // DHTML defined drag image
            doSystemDrag(dragImage, dragLoc, dragOrigin, clipboard, src, false);

    } else if (!linkURL.isEmpty() && (m_dragSourceAction & DragSourceActionLink)) {
        if (!clipboard->hasData())
            // Simplify whitespace so the title put on the clipboard resembles what the user sees
            // on the web page. This includes replacing newlines with spaces.
            clipboard->writeURL(linkURL, dragSource.textContent().simplifyWhiteSpace(), src);

        if (src->selection()->isCaret() && src->selection()->isContentEditable()) {
            // a user can initiate a drag on a link without having any text
            // selected.  In this case, we should expand the selection to
            // the enclosing anchor element
            Position pos = src->selection()->base();
            Node* node = enclosingAnchorElement(pos);
            if (node)
                src->selection()->setSelection(VisibleSelection::selectionFromContentsOfNode(node));
        }

        m_client->willPerformDragSourceAction(DragSourceActionLink, dragOrigin, clipboard);
        if (!dragImage) {
            dragImage = m_client->createDragImageForLink(linkURL, dragSource.textContent(), src);
            IntSize size = dragImageSize(dragImage);
            m_dragOffset = IntPoint(-size.width() / 2, -LinkDragBorderInset);
            dragLoc = IntPoint(mouseDraggedPoint.x() + m_dragOffset.x(), mouseDraggedPoint.y() + m_dragOffset.y());
        }
        doSystemDrag(dragImage, dragLoc, mouseDraggedPoint, clipboard, src, true);
    } else if (isSelected && (m_dragSourceAction & DragSourceActionSelection)) {
        RefPtr<Range> selectionRange = src->selection()->toNormalizedRange();
        ASSERT(selectionRange);
        if (!clipboard->hasData())
            clipboard->writeRange(selectionRange.get(), src);
        m_client->willPerformDragSourceAction(DragSourceActionSelection, dragOrigin, clipboard);
        if (!dragImage) {
            dragImage = createDragImageForSelection(src);
            dragLoc = dragLocForSelectionDrag(src);
            m_dragOffset = IntPoint((int)(dragOrigin.x() - dragLoc.x()), (int)(dragOrigin.y() - dragLoc.y()));
        }
        doSystemDrag(dragImage, dragLoc, dragOrigin, clipboard, src, false);
    } else if (isDHTMLDrag) {
        ASSERT(m_dragSourceAction & DragSourceActionDHTML);
        m_client->willPerformDragSourceAction(DragSourceActionDHTML, dragOrigin, clipboard);
        doSystemDrag(dragImage, dragLoc, dragOrigin, clipboard, src, false);
    } else {
        // Only way I know to get here is if to get here is if the original element clicked on in the mousedown is no longer
        // under the mousedown point, so linkURL, imageURL and isSelected are all false/empty.
        startedDrag = false;
    }

    if (dragImage)
        deleteDragImage(dragImage);
    return startedDrag;
}