// 'region' is in contents coordinates relative to the frame containing 'node' // 'remainingFingerRegion' and 'intersectingRegions' will always be in main frame contents // coordinates. // Thus, before comparing, we need to map the former to main frame contents coordinates. bool FatFingers::checkFingerIntersection(const Platform::IntRectRegion& region, const Platform::IntRectRegion& remainingFingerRegion, Node* node, Vector<IntersectingRegion>& intersectingRegions) { ASSERT(node); Platform::IntRectRegion regionCopy(region); WebCore::IntPoint framePos(m_webPage->frameOffset(node->document()->frame())); regionCopy.move(framePos.x(), framePos.y()); Platform::IntRectRegion intersection = intersectRegions(regionCopy, remainingFingerRegion); if (intersection.isEmpty()) return false; #if DEBUG_FAT_FINGERS String nodeName; if (node->isTextNode()) nodeName = "text node"; else if (node->isElementNode()) nodeName = String::format("%s node", toElement(node)->tagName().latin1().data()); else nodeName = "unknown node"; log(LogLevelInfo, "%s has region %s, intersecting at %s (area %d)", nodeName.latin1().data(), regionCopy.toString().c_str(), intersection.toString().c_str(), intersection.area()); #endif intersectingRegions.append(std::make_pair(node, intersection)); return true; }
void TouchEventHandler::drawTapHighlight() { Element* elementUnderFatFinger = m_lastFatFingersResult.nodeAsElementIfApplicable(); if (!elementUnderFatFinger) return; Element* element = elementForTapHighlight(elementUnderFatFinger); if (!element) return; // Get the element bounding rect in transformed coordinates so we can extract // the focus ring relative position each rect. RenderObject* renderer = element->renderer(); ASSERT(renderer); Frame* elementFrame = element->document()->frame(); ASSERT(elementFrame); FrameView* elementFrameView = elementFrame->view(); if (!elementFrameView) return; // Tell the client if the element is either in a scrollable container or in a fixed positioned container. // On the client side, this info is being used to hide the tap highlight window on scroll. RenderLayer* layer = m_webPage->enclosingFixedPositionedAncestorOrSelfIfFixedPositioned(renderer->enclosingLayer()); bool shouldHideTapHighlightRightAfterScrolling = !layer->renderer()->isRenderView(); shouldHideTapHighlightRightAfterScrolling |= !!m_webPage->m_inRegionScroller->d->node(); IntPoint framePos(m_webPage->frameOffset(elementFrame)); // FIXME: We can get more precise on the <map> case by calculating the rect with HTMLAreaElement::computeRect(). IntRect absoluteRect(renderer->absoluteClippedOverflowRect()); absoluteRect.move(framePos.x(), framePos.y()); IntRect clippingRect; if (elementFrame == m_webPage->mainFrame()) clippingRect = IntRect(IntPoint(0, 0), elementFrameView->contentsSize()); else clippingRect = m_webPage->mainFrame()->view()->windowToContents(m_webPage->getRecursiveVisibleWindowRect(elementFrameView, true /*noClipToMainFrame*/)); clippingRect = intersection(absoluteRect, clippingRect); Vector<FloatQuad> focusRingQuads; renderer->absoluteFocusRingQuads(focusRingQuads); Platform::IntRectRegion region; for (size_t i = 0; i < focusRingQuads.size(); ++i) { IntRect rect = focusRingQuads[i].enclosingBoundingBox(); rect.move(framePos.x(), framePos.y()); IntRect clippedRect = intersection(clippingRect, rect); clippedRect.inflate(2); region = unionRegions(region, Platform::IntRect(clippedRect)); } Color highlightColor = element->renderStyle()->tapHighlightColor(); m_webPage->m_tapHighlight->draw(region, highlightColor.red(), highlightColor.green(), highlightColor.blue(), highlightColor.alpha(), shouldHideTapHighlightRightAfterScrolling); }
//--------------------------------------------------------------------------- void Plots::onCurrentFrameChanged() { // position of the current frame has changed if ( isZoomed() ) { const int n = m_frameInterval.count(); const int from = qBound( 0, framePos() - n / 2, numFrames() - n ); const int to = from + n - 1; if ( from != m_frameInterval.from ) { setVisibleFrames( from, to ); replotAll(); } } setCursorPos( framePos() ); }
bool FatFingers::checkForClickableElement(Element* curElement, Vector<IntersectingRegion>& intersectingRegions, Platform::IntRectRegion& remainingFingerRegion, RenderLayer*& lowestPositionedEnclosingLayerSoFar) { ASSERT(curElement); bool intersects = false; Platform::IntRectRegion elementRegion; bool isClickableElement = isElementClickable(curElement); if (isClickableElement) { if (curElement->isLink()) { // Links can wrap lines, and in such cases Node::getRect() can give us // not accurate rects, since it unites all InlineBox's rects. In these // cases, we can process each line of the link separately with our // intersection rect, getting a more accurate clicking. Vector<FloatQuad> quads; curElement->renderer()->absoluteFocusRingQuads(quads); size_t n = quads.size(); ASSERT(n); for (size_t i = 0; i < n; ++i) elementRegion = unionRegions(elementRegion, Platform::IntRect(quads[i].enclosingBoundingBox())); } else elementRegion = Platform::IntRectRegion(curElement->renderer()->absoluteBoundingBoxRect(true /*use transforms*/)); } else elementRegion = Platform::IntRectRegion(curElement->renderer()->absoluteBoundingBoxRect(true /*use transforms*/)); if (lowestPositionedEnclosingLayerSoFar) { RenderLayer* curElementRenderLayer = m_webPage->enclosingPositionedAncestorOrSelfIfPositioned(curElement->renderer()->enclosingLayer()); if (curElementRenderLayer != lowestPositionedEnclosingLayerSoFar) { // elementRegion will always be in contents coordinates of its container frame. It needs to be // mapped to main frame contents coordinates in order to subtract the fingerRegion, then. WebCore::IntPoint framePos(m_webPage->frameOffset(curElement->document()->frame())); Platform::IntRectRegion layerRegion(Platform::IntRect(lowestPositionedEnclosingLayerSoFar->renderer()->absoluteBoundingBoxRect(true/*use transforms*/))); layerRegion.move(framePos.x(), framePos.y()); remainingFingerRegion = subtractRegions(remainingFingerRegion, layerRegion); lowestPositionedEnclosingLayerSoFar = curElementRenderLayer; } } else lowestPositionedEnclosingLayerSoFar = m_webPage->enclosingPositionedAncestorOrSelfIfPositioned(curElement->renderer()->enclosingLayer()); if (isClickableElement) intersects = checkFingerIntersection(elementRegion, remainingFingerRegion, curElement, intersectingRegions); return intersects; }
//--------------------------------------------------------------------------- void Plots::refresh() { for ( size_t streamPos = 0; streamPos < m_fileInfoData->Stats.size(); streamPos++ ) if ( m_fileInfoData->Stats[streamPos] && m_plots[streamPos] ) { size_t type = m_fileInfoData->Stats[streamPos]->Type_Get(); for ( int i = 0; i < PerStreamType[type].CountOfGroups; i++ ) if (m_plots[streamPos][i]) { initYAxis( m_plots[streamPos][i] ); updateSamples( m_plots[streamPos][i] ); } } setCursorPos( framePos() ); replotAll(); }
//--------------------------------------------------------------------------- void Plots::zoomXAxis( ZoomTypes zoomType ) { m_zoomType = zoomType; if ( zoomType == ZoomIn ) m_zoomFactor++; else if ( zoomType == ZoomOut && m_zoomFactor ) m_zoomFactor--; else if ( zoomType == ZoomOneToOne) m_zoomFactor = 0; qDebug() << "m_zoomFactor: " << m_zoomFactor; int numVisibleFrames = m_fileInfoData->Frames_Count_Get() >> m_zoomFactor; if(m_zoomType == ZoomOneToOne) { numVisibleFrames = plot(0, 0)->canvas()->contentsRect().width(); m_zoomFactor = log(m_fileInfoData->Frames_Count_Get() / numVisibleFrames) / log(2); } int to = qMin( framePos() + numVisibleFrames / 2, numFrames() ); int from = qMax( 0, to - numVisibleFrames ); if ( to - from < numVisibleFrames) to = from + numVisibleFrames; setVisibleFrames( from, to ); for ( size_t streamPos = 0; streamPos < m_fileInfoData->Stats.size(); streamPos++ ) if ( m_fileInfoData->Stats[streamPos] && m_plots[streamPos] ) { size_t type = m_fileInfoData->Stats[streamPos]->Type_Get(); for ( int group = 0; group < PerStreamType[type].CountOfGroups; group++ ) if (m_plots[streamPos][group]) m_plots[streamPos][group]->setAxisScale( QwtPlot::xBottom, m_timeInterval.from, m_timeInterval.to ); } m_scaleWidget->setScale( m_timeInterval.from, m_timeInterval.to); refresh(); m_scaleWidget->update(); replotAll(); }
nsIFrame* nsCaret::GetGeometry(nsISelection* aSelection, nsRect* aRect) { nsCOMPtr<nsIDOMNode> focusNode; nsresult rv = aSelection->GetFocusNode(getter_AddRefs(focusNode)); if (NS_FAILED(rv) || !focusNode) return nsnull; PRInt32 focusOffset; rv = aSelection->GetFocusOffset(&focusOffset); if (NS_FAILED(rv)) return nsnull; nsCOMPtr<nsIContent> contentNode = do_QueryInterface(focusNode); if (!contentNode) return nsnull; // find the frame that contains the content node that has focus nsIFrame* theFrame = nsnull; PRInt32 theFrameOffset = 0; nsCOMPtr<nsFrameSelection> frameSelection = GetFrameSelection(); if (!frameSelection) return nsnull; PRUint8 bidiLevel = frameSelection->GetCaretBidiLevel(); rv = GetCaretFrameForNodeOffset(contentNode, focusOffset, frameSelection->GetHint(), bidiLevel, &theFrame, &theFrameOffset); if (NS_FAILED(rv) || !theFrame) return nsnull; nsPoint framePos(0, 0); rv = theFrame->GetPointFromOffset(theFrameOffset, &framePos); if (NS_FAILED(rv)) return nsnull; // now add the frame offset to the view offset, and we're done nscoord height = theFrame->GetSize().height; nscoord width = ComputeMetrics(theFrame, theFrameOffset, height).mCaretWidth; *aRect = nsRect(framePos.x, 0, width, height); return theFrame; }
//--------------------------------------------------------------------------- void Plots::setCursorPos( int newFramePos ) { setFramePos( newFramePos ); for ( size_t streamPos = 0; streamPos < m_fileInfoData->Stats.size(); streamPos++ ) if ( m_fileInfoData->Stats[streamPos] && m_plots[streamPos] ) { const double x = m_fileInfoData->Stats[streamPos]->x[m_dataTypeIndex][framePos(streamPos)]; size_t type = m_fileInfoData->Stats[streamPos]->Type_Get(); for ( int i = 0; i < PerStreamType[type].CountOfGroups; ++i ) if (m_plots[streamPos][i]) m_plots[streamPos][i]->setCursorPos( x ); } m_scaleWidget->setScale( m_timeInterval.from, m_timeInterval.to); m_scaleWidget->update(); replotAll(); }
//--------------------------------------------------------------------------- Plots::Plots( QWidget *parent, FileInformation* fileInformation ) : QWidget( parent ), m_zoomFactor ( 0 ), m_fileInfoData( fileInformation ), m_dataTypeIndex( Plots::AxisSeconds ) { setlocale(LC_NUMERIC, "C"); QGridLayout* layout = new QGridLayout( this ); layout->setSpacing( 1 ); layout->setContentsMargins( 0, 0, 0, 0 ); // bottom scale m_scaleWidget = new PlotScaleWidget(); m_scaleWidget->setFormat( Plots::AxisTime ); setVisibleFrames( 0, numFrames() - 1 ); // plots and legends m_plots = new Plot**[m_fileInfoData->Stats.size()]; m_plotsCount = 0; for ( size_t streamPos = 0; streamPos < m_fileInfoData->Stats.size(); streamPos++ ) { if (m_fileInfoData->Stats[streamPos]) { size_t type = m_fileInfoData->Stats[streamPos]->Type_Get(); size_t countOfGroups = PerStreamType[type].CountOfGroups; m_plots[streamPos] = new Plot*[countOfGroups + 1]; //+1 for axix for ( size_t group = 0; group < countOfGroups; group++ ) { if (m_fileInfoData->ActiveFilters[PerStreamType[type].PerGroup[group].ActiveFilterGroup]) { Plot* plot = new Plot( streamPos, type, group, fileInformation, this ); plot->addGuidelines(m_fileInfoData->BitsPerRawSample()); if(type == Type_Video) adjustGroupMax(group, m_fileInfoData->BitsPerRawSample()); // we allow to shrink the plot below height of the size hint plot->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Expanding ); plot->setAxisScaleDiv( QwtPlot::xBottom, m_scaleWidget->scaleDiv() ); initYAxis( plot ); updateSamples( plot ); connect( plot, SIGNAL( cursorMoved( int ) ), SLOT( onCursorMoved( int ) ) ); plot->canvas()->installEventFilter( this ); layout->addWidget( plot, m_plotsCount, 0 ); layout->addWidget( plot->legend(), m_plotsCount, 1 ); m_plots[streamPos][group] = plot; m_plotsCount++; qDebug() << "g: " << plot->group() << ", t: " << plot->type() << ", m_plotsCount: " << m_plotsCount; } else { m_plots[streamPos][group] = NULL; } } } else { m_plots[streamPos]=NULL; } } layout->addWidget( m_scaleWidget, m_plotsCount, 0, 1, 2 ); // combo box for the axis format XAxisFormatBox* xAxisBox = new XAxisFormatBox(); xAxisBox->setCurrentIndex( Plots::AxisTime ); connect( xAxisBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( onXAxisFormatChanged( int ) ) ); int axisBoxRow = layout->rowCount() - 1; #if 1 // one row below to have space enough for bottom scale tick labels layout->addWidget( xAxisBox, m_plotsCount + 1, 1 ); #else layout->addWidget( xAxisBox, layout_y, 1 ); #endif layout->setColumnStretch( 0, 10 ); layout->setColumnStretch( 1, 0 ); m_scaleWidget->setScale( m_timeInterval.from, m_timeInterval.to); setCursorPos( framePos() ); }
//----------------------------------------------------------------------------- nsresult nsCaret::GetCaretCoordinates(EViewCoordinates aRelativeToType, nsISelection *aDOMSel, nsRect *outCoordinates, PRBool *outIsCollapsed, nsIView **outView) { if (!mPresShell) return NS_ERROR_NOT_INITIALIZED; if (!outCoordinates || !outIsCollapsed) return NS_ERROR_NULL_POINTER; nsCOMPtr<nsISelection> domSelection = aDOMSel; if (outView) *outView = nsnull; // fill in defaults for failure outCoordinates->x = -1; outCoordinates->y = -1; outCoordinates->width = -1; outCoordinates->height = -1; *outIsCollapsed = PR_FALSE; nsresult err = domSelection->GetIsCollapsed(outIsCollapsed); if (NS_FAILED(err)) return err; nsCOMPtr<nsIDOMNode> focusNode; err = domSelection->GetFocusNode(getter_AddRefs(focusNode)); if (NS_FAILED(err)) return err; if (!focusNode) return NS_ERROR_FAILURE; PRInt32 focusOffset; err = domSelection->GetFocusOffset(&focusOffset); if (NS_FAILED(err)) return err; nsCOMPtr<nsIContent> contentNode = do_QueryInterface(focusNode); if (!contentNode) return NS_ERROR_FAILURE; // find the frame that contains the content node that has focus nsIFrame* theFrame = nsnull; PRInt32 theFrameOffset = 0; nsCOMPtr<nsFrameSelection> frameSelection = GetFrameSelection(); if (!frameSelection) return NS_ERROR_FAILURE; PRUint8 bidiLevel = frameSelection->GetCaretBidiLevel(); err = GetCaretFrameForNodeOffset(contentNode, focusOffset, frameSelection->GetHint(), bidiLevel, &theFrame, &theFrameOffset); if (NS_FAILED(err) || !theFrame) return err; nsPoint viewOffset(0, 0); nsIView *drawingView; // views are not refcounted GetViewForRendering(theFrame, aRelativeToType, viewOffset, &drawingView, outView); if (!drawingView) return NS_ERROR_UNEXPECTED; nsPoint framePos(0, 0); err = theFrame->GetPointFromOffset(theFrameOffset, &framePos); if (NS_FAILED(err)) return err; // we don't need drawingView anymore so reuse that; reset viewOffset values for our purposes if (aRelativeToType == eClosestViewCoordinates) { theFrame->GetOffsetFromView(viewOffset, &drawingView); if (outView) *outView = drawingView; } // now add the frame offset to the view offset, and we're done viewOffset += framePos; outCoordinates->x = viewOffset.x; outCoordinates->y = viewOffset.y; outCoordinates->height = theFrame->GetSize().height; outCoordinates->width = ComputeMetrics(theFrame, theFrameOffset, outCoordinates->height).mCaretWidth; return NS_OK; }