Accessible* XULTreeGridRowAccessible::ChildAtPoint(
    int32_t aX, int32_t aY, EWhichChildAtPoint aWhichChild) {
  nsIFrame* frame = GetFrame();
  if (!frame) return nullptr;

  nsPresContext* presContext = frame->PresContext();
  PresShell* presShell = presContext->PresShell();

  nsIFrame* rootFrame = presShell->GetRootFrame();
  NS_ENSURE_TRUE(rootFrame, nullptr);

  CSSIntRect rootRect = rootFrame->GetScreenRect();

  int32_t clientX = presContext->DevPixelsToIntCSSPixels(aX) - rootRect.X();
  int32_t clientY = presContext->DevPixelsToIntCSSPixels(aY) - rootRect.Y();

  ErrorResult rv;
  dom::TreeCellInfo cellInfo;
  mTree->GetCellAt(clientX, clientY, cellInfo, rv);

  // Return if we failed to find tree cell in the row for the given point.
  if (cellInfo.mRow != mRow || !cellInfo.mCol) return nullptr;

  return GetCellAccessible(cellInfo.mCol);
}
Accessible*
XULTreeGridRowAccessible::ChildAtPoint(int32_t aX, int32_t aY,
                                       EWhichChildAtPoint aWhichChild)
{
  nsIFrame *frame = GetFrame();
  if (!frame)
    return nullptr;

  nsPresContext *presContext = frame->PresContext();
  nsIPresShell* presShell = presContext->PresShell();

  nsIFrame *rootFrame = presShell->GetRootFrame();
  NS_ENSURE_TRUE(rootFrame, nullptr);

  CSSIntRect rootRect = rootFrame->GetScreenRect();

  int32_t clientX = presContext->DevPixelsToIntCSSPixels(aX) - rootRect.X();
  int32_t clientY = presContext->DevPixelsToIntCSSPixels(aY) - rootRect.Y();

  int32_t row = -1;
  nsCOMPtr<nsITreeColumn> column;
  nsAutoString childEltUnused;
  mTree->GetCellAt(clientX, clientY, &row, getter_AddRefs(column),
                   childEltUnused);

  // Return if we failed to find tree cell in the row for the given point.
  if (row != mRow || !column)
    return nullptr;

  return GetCellAccessible(column);
}
Example #3
0
Accessible*
XULTreeAccessible::ChildAtPoint(int32_t aX, int32_t aY,
                                EWhichChildAtPoint aWhichChild)
{
  nsIFrame *frame = GetFrame();
  if (!frame)
    return nullptr;

  nsPresContext *presContext = frame->PresContext();
  nsIPresShell* presShell = presContext->PresShell();

  nsIFrame *rootFrame = presShell->GetRootFrame();
  NS_ENSURE_TRUE(rootFrame, nullptr);

  CSSIntRect rootRect = rootFrame->GetScreenRect();

  int32_t clientX = presContext->DevPixelsToIntCSSPixels(aX) - rootRect.X();
  int32_t clientY = presContext->DevPixelsToIntCSSPixels(aY) - rootRect.Y();

  int32_t row = -1;
  nsCOMPtr<nsITreeColumn> column;
  nsAutoString childEltUnused;
  mTree->GetCellAt(clientX, clientY, &row, getter_AddRefs(column),
                   childEltUnused);

  // If we failed to find tree cell for the given point then it might be
  // tree columns.
  if (row == -1 || !column)
    return AccessibleWrap::ChildAtPoint(aX, aY, aWhichChild);

  Accessible* child = GetTreeItemAccessible(row);
  if (aWhichChild == eDeepestChild && child) {
    // Look for accessible cell for the found item accessible.
    RefPtr<XULTreeItemAccessibleBase> treeitem = do_QueryObject(child);

    Accessible* cell = treeitem->GetCellAccessible(column);
    if (cell)
      child = cell;
  }

  return child;
}
Example #4
0
nsresult
nsBaseDragService::DrawDrag(nsIDOMNode* aDOMNode,
                            nsIScriptableRegion* aRegion,
                            CSSIntPoint aScreenPosition,
                            LayoutDeviceIntRect* aScreenDragRect,
                            RefPtr<SourceSurface>* aSurface,
                            nsPresContext** aPresContext)
{
  *aSurface = nullptr;
  *aPresContext = nullptr;

  // use a default size, in case of an error.
  aScreenDragRect->SetRect(aScreenPosition.x - mImageOffset.x,
                           aScreenPosition.y - mImageOffset.y,
                           1, 1);

  // if a drag image was specified, use that, otherwise, use the source node
  nsCOMPtr<nsIDOMNode> dragNode = mImage ? mImage.get() : aDOMNode;

  // get the presshell for the node being dragged. If the drag image is not in
  // a document or has no frame, get the presshell from the source drag node
  nsIPresShell* presShell = GetPresShellForContent(dragNode);
  if (!presShell && mImage)
    presShell = GetPresShellForContent(aDOMNode);
  if (!presShell)
    return NS_ERROR_FAILURE;

  *aPresContext = presShell->GetPresContext();

  nsCOMPtr<nsIFrameLoaderOwner> flo = do_QueryInterface(dragNode);
  if (flo) {
    RefPtr<nsFrameLoader> fl = flo->GetFrameLoader();
    if (fl) {
      auto* tp = static_cast<mozilla::dom::TabParent*>(fl->GetRemoteBrowser());
      if (tp && tp->TakeDragVisualization(*aSurface, aScreenDragRect)) {
        if (mImage) {
          // Just clear the surface if chrome has overridden it with an image.
          *aSurface = nullptr;
        }

        return NS_OK;
      }
    }
  }

  // convert mouse position to dev pixels of the prescontext
  CSSIntPoint screenPosition(aScreenPosition);
  screenPosition.x -= mImageOffset.x;
  screenPosition.y -= mImageOffset.y;
  LayoutDeviceIntPoint screenPoint = ConvertToUnscaledDevPixels(*aPresContext, screenPosition);
  aScreenDragRect->MoveTo(screenPoint.x, screenPoint.y);

  // check if drag images are disabled
  bool enableDragImages = Preferences::GetBool(DRAGIMAGES_PREF, true);

  // didn't want an image, so just set the screen rectangle to the frame size
  if (!enableDragImages || !mHasImage) {
    // if a region was specified, set the screen rectangle to the area that
    // the region occupies
    CSSIntRect dragRect;
    if (aRegion) {
      // the region's coordinates are relative to the root frame
      int32_t dragRectX, dragRectY, dragRectW, dragRectH;
      aRegion->GetBoundingBox(&dragRectX, &dragRectY, &dragRectW, &dragRectH);
      dragRect.SetRect(dragRectX, dragRectY, dragRectW, dragRectH);

      nsIFrame* rootFrame = presShell->GetRootFrame();
      CSSIntRect screenRect = rootFrame->GetScreenRect();
      dragRect.MoveBy(screenRect.TopLeft());
    }
    else {
      // otherwise, there was no region so just set the rectangle to
      // the size of the primary frame of the content.
      nsCOMPtr<nsIContent> content = do_QueryInterface(dragNode);
      nsIFrame* frame = content->GetPrimaryFrame();
      if (frame) {
        dragRect = frame->GetScreenRect();
      }
    }

    nsIntRect dragRectDev =
      ToAppUnits(dragRect, nsPresContext::AppUnitsPerCSSPixel()).
      ToOutsidePixels((*aPresContext)->AppUnitsPerDevPixel());
    aScreenDragRect->SizeTo(dragRectDev.Width(), dragRectDev.Height());
    return NS_OK;
  }

  // draw the image for selections
  if (mSelection) {
    LayoutDeviceIntPoint pnt(aScreenDragRect->TopLeft());
    *aSurface = presShell->RenderSelection(mSelection, pnt, aScreenDragRect,
        mImage ? 0 : nsIPresShell::RENDER_AUTO_SCALE);
    return NS_OK;
  }

  // if a custom image was specified, check if it is an image node and draw
  // using the source rather than the displayed image. But if mImage isn't
  // an image or canvas, fall through to RenderNode below.
  if (mImage) {
    nsCOMPtr<nsIContent> content = do_QueryInterface(dragNode);
    HTMLCanvasElement *canvas = HTMLCanvasElement::FromContentOrNull(content);
    if (canvas) {
      return DrawDragForImage(*aPresContext, nullptr, canvas, aScreenDragRect, aSurface);
    }

    nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(dragNode);
    // for image nodes, create the drag image from the actual image data
    if (imageLoader) {
      return DrawDragForImage(*aPresContext, imageLoader, nullptr, aScreenDragRect, aSurface);
    }

    // If the image is a popup, use that as the image. This allows custom drag
    // images that can change during the drag, but means that any platform
    // default image handling won't occur.
    // XXXndeakin this should be chrome-only

    nsIFrame* frame = content->GetPrimaryFrame();
    if (frame && frame->IsMenuPopupFrame()) {
      mDragPopup = content;
    }
  }

  if (!mDragPopup) {
    // otherwise, just draw the node
    nsIntRegion clipRegion;
    uint32_t renderFlags = mImage ? 0 : nsIPresShell::RENDER_AUTO_SCALE;
    if (aRegion) {
      aRegion->GetRegion(&clipRegion);
    }

    if (renderFlags) {
      nsCOMPtr<nsINode> dragINode = do_QueryInterface(dragNode);
      // check if the dragged node itself is an img element
      if (dragINode->NodeName().LowerCaseEqualsLiteral("img")) {
        renderFlags = renderFlags | nsIPresShell::RENDER_IS_IMAGE;
      } else {
        nsINodeList* childList = dragINode->ChildNodes();
        uint32_t length = childList->Length();
        // check every childnode for being an img element
        // XXXbz why don't we need to check descendants recursively?
        for (uint32_t count = 0; count < length; ++count) {
          if (childList->Item(count)->NodeName().LowerCaseEqualsLiteral("img")) {
            // if the dragnode contains an image, set RENDER_IS_IMAGE flag
            renderFlags = renderFlags | nsIPresShell::RENDER_IS_IMAGE;
            break;
          }
        }
      }
    }
    LayoutDeviceIntPoint pnt(aScreenDragRect->TopLeft());
    *aSurface = presShell->RenderNode(dragNode, aRegion ? &clipRegion : nullptr,
                                      pnt, aScreenDragRect,
                                      renderFlags);
  }

  // If an image was specified, reset the position from the offset that was supplied.
  if (mImage) {
    aScreenDragRect->MoveTo(screenPoint.x, screenPoint.y);
  }

  return NS_OK;
}