Пример #1
0
//-----------------------------------------------------------------------------
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;
}
Пример #2
0
PRBool
nsDragService::ComputeGlobalRectFromFrame ( nsIDOMNode* aDOMNode, Rect & outScreenRect )
{
  NS_ASSERTION ( aDOMNode, "Oopps, no DOM node" );

// this isn't so much of an issue as long as we're just dragging around outlines,
// but it is when we are showing the text being drawn. Comment it out for now
// but leave it around when we turn this all back on (pinkerton).
#if USE_TRANSLUCENT_DRAGGING && defined(MOZ_XUL)
  // until bug 41237 is fixed, only do translucent dragging if the drag is in
  // the chrome or it's a link.
  nsCOMPtr<nsIContent> content = do_QueryInterface(aDOMNode);
  if (!content || !content->IsContentOfType(nsIContent::eXUL)) {
    // the link node is the parent of the node we have (which is probably text or image).
    nsCOMPtr<nsIDOMNode> parent;
    aDOMNode->GetParentNode ( getter_AddRefs(parent) );
    if ( parent ) {
      nsAutoString localName;
      parent->GetLocalName ( localName );
      if ( ! localName.EqualsLiteral("A") )
        return PR_FALSE;
    }
    else
      return FALSE;
  }
#endif
  
  outScreenRect.left = outScreenRect.right = outScreenRect.top = outScreenRect.bottom = 0;

  // Get the frame for this content node (note: frames are not refcounted)
  nsIFrame *aFrame = nsnull;
  nsCOMPtr<nsPresContext> presContext;
  GetFrameFromNode ( aDOMNode, &aFrame, getter_AddRefs(presContext) );
  if ( !aFrame || !presContext )
    return PR_FALSE;
  
  //
  // Now that we have the frame, we have to convert its coordinates into global screen
  // coordinates.
  //
  
  nsRect rect = aFrame->GetRect();

  // Find offset from our view
	nsIView *containingView = nsnull;
	nsPoint	viewOffset(0,0);
	aFrame->GetOffsetFromView(viewOffset, &containingView);
  NS_ASSERTION(containingView, "No containing view!");
  if ( !containingView )
    return PR_FALSE;

  // get the widget associated with the containing view. 
  nsPoint widgetOffset;
  nsIWidget* aWidget = containingView->GetNearestWidget ( &widgetOffset );

  float t2p = 1.0;
  t2p = presContext->TwipsToPixels();

  // Shift our offset rect by offset into our view, and
  // the view's offset to the closest widget. Then convert that to global coordinates.
  // Recall that WidgetToScreen() will give us the global coordinates of the rectangle we 
  // give it, but it expects  everything to be in pixels.
  nsRect screenOffset;                                
  screenOffset.MoveBy ( NSTwipsToIntPixels(widgetOffset.x + viewOffset.x, t2p),
                        NSTwipsToIntPixels(widgetOffset.y + viewOffset.y, t2p) );
  aWidget->WidgetToScreen ( screenOffset, screenOffset );

  // stash it all in a mac rect
  outScreenRect.left = screenOffset.x;
  outScreenRect.top = screenOffset.y;
  outScreenRect.right = outScreenRect.left + NSTwipsToIntPixels(rect.width, t2p);
  outScreenRect.bottom = outScreenRect.top + NSTwipsToIntPixels(rect.height, t2p);
            
  return PR_TRUE;
} // ComputeGlobalRectFromFrame