зеркало из https://github.com/mozilla/gecko-dev.git
made drag feedback better for containers and sorted lists. bugs 9657, 20124, 31814
This commit is contained in:
Родитель
5d9678401a
Коммит
7909e041dc
|
@ -134,6 +134,8 @@ XUL_ATOM(debug, "debug")
|
||||||
XUL_ATOM(ddDropLocation, "dd-droplocation")
|
XUL_ATOM(ddDropLocation, "dd-droplocation")
|
||||||
XUL_ATOM(ddDropLocationCoord, "dd-droplocationcoord")
|
XUL_ATOM(ddDropLocationCoord, "dd-droplocationcoord")
|
||||||
XUL_ATOM(ddDropOn, "dd-dropon")
|
XUL_ATOM(ddDropOn, "dd-dropon")
|
||||||
|
XUL_ATOM(ddTriggerRepaintSorted, "dd-triggerrepaintsorted")
|
||||||
|
XUL_ATOM(ddTriggerRepaintRestore, "dd-triggerrepaintrestore")
|
||||||
XUL_ATOM(ddTriggerRepaint, "dd-triggerrepaint")
|
XUL_ATOM(ddTriggerRepaint, "dd-triggerrepaint")
|
||||||
XUL_ATOM(container, "container")
|
XUL_ATOM(container, "container")
|
||||||
XUL_ATOM(ddDragDropArea, "dragdroparea")
|
XUL_ATOM(ddDragDropArea, "dragdroparea")
|
||||||
|
|
|
@ -49,7 +49,7 @@ NS_IMPL_QUERY_INTERFACE2(nsTreeItemDragCapturer, nsIDOMEventListener, nsIDOMDrag
|
||||||
// any subframes might not be totally intialized yet, or in the hash table
|
// any subframes might not be totally intialized yet, or in the hash table
|
||||||
//
|
//
|
||||||
nsTreeItemDragCapturer :: nsTreeItemDragCapturer ( nsTreeRowGroupFrame* inGroup, nsIPresContext* inPresContext )
|
nsTreeItemDragCapturer :: nsTreeItemDragCapturer ( nsTreeRowGroupFrame* inGroup, nsIPresContext* inPresContext )
|
||||||
: mTreeItem(inGroup), mPresContext(inPresContext), mCurrentDropLoc(-1)
|
: mTreeItem(inGroup), mPresContext(inPresContext), mCurrentDropLoc(kNoDropLoc)
|
||||||
{
|
{
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_REFCNT();
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ nsTreeItemDragCapturer :: ComputeDropPosition ( nsIDOMEvent* aDragEvent, nscoord
|
||||||
else {
|
else {
|
||||||
// we're on the container
|
// we're on the container
|
||||||
*outDropOnMe = PR_TRUE;
|
*outDropOnMe = PR_TRUE;
|
||||||
*outYLoc = -1;
|
*outYLoc = kContainerDropLoc;
|
||||||
}
|
}
|
||||||
} // if row is a container
|
} // if row is a container
|
||||||
else {
|
else {
|
||||||
|
@ -230,7 +230,7 @@ nsTreeItemDragCapturer::DragOver(nsIDOMEvent* aDragEvent)
|
||||||
char buffer[10];
|
char buffer[10];
|
||||||
|
|
||||||
// need the cast, because on some platforms, PR[U]int32 != long, but we're using "%ld"
|
// need the cast, because on some platforms, PR[U]int32 != long, but we're using "%ld"
|
||||||
sprintf(buffer, "%ld", NS_STATIC_CAST(long, yLoc));
|
sprintf(buffer, "%d", yLoc);
|
||||||
content->SetAttribute ( kNameSpaceID_None, nsXULAtoms::ddDropLocationCoord, buffer, PR_TRUE );
|
content->SetAttribute ( kNameSpaceID_None, nsXULAtoms::ddDropLocationCoord, buffer, PR_TRUE );
|
||||||
content->SetAttribute ( kNameSpaceID_None, nsXULAtoms::ddDropLocation, beforeMe ? "true" : "false", PR_FALSE );
|
content->SetAttribute ( kNameSpaceID_None, nsXULAtoms::ddDropLocation, beforeMe ? "true" : "false", PR_FALSE );
|
||||||
content->SetAttribute ( kNameSpaceID_None, nsXULAtoms::ddDropOn, onMe ? "true" : "false", PR_TRUE );
|
content->SetAttribute ( kNameSpaceID_None, nsXULAtoms::ddDropOn, onMe ? "true" : "false", PR_TRUE );
|
||||||
|
@ -251,45 +251,27 @@ nsresult
|
||||||
nsTreeItemDragCapturer::DragExit(nsIDOMEvent* aDragEvent)
|
nsTreeItemDragCapturer::DragExit(nsIDOMEvent* aDragEvent)
|
||||||
{
|
{
|
||||||
// if we are not the target of the event, bail.
|
// if we are not the target of the event, bail.
|
||||||
if ( ! IsEventTargetMyTreeItem(aDragEvent) )
|
if ( !IsEventTargetMyTreeItem(aDragEvent) )
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
// there are some bugs that cause us to not be able to correctly track dragExit events
|
|
||||||
// so until then we just get on our knees and pray we don't get fooled again.
|
|
||||||
nsCOMPtr<nsIContent> c;
|
|
||||||
mTreeItem->GetContent ( getter_AddRefs(c) );
|
|
||||||
nsCOMPtr<nsIDOMNode> d ( do_QueryInterface(c) );
|
|
||||||
nsCOMPtr<nsIDOMNode> t;
|
|
||||||
aDragEvent->GetTarget ( getter_AddRefs(t) );
|
|
||||||
//printf ( "DRAGEXIT:: toolbar DOMNode %ld, target is %ld\n", d, t );
|
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> content;
|
nsCOMPtr<nsIContent> content;
|
||||||
mTreeItem->GetContent ( getter_AddRefs(content) );
|
mTreeItem->GetContent ( getter_AddRefs(content) );
|
||||||
|
NS_ASSERTION ( content, "can't get content node, we're in trouble" );
|
||||||
#if 0
|
|
||||||
// we will get a drag exit event on sub items because we catch the event on the way down. If
|
if ( content ) {
|
||||||
// the target is not our toolbar, then ignore it.
|
// tell the treeItem to not do any more drop feedback. Note that the tree code doesn't
|
||||||
nsCOMPtr<nsIDOMNode> toolbarDOMNode ( do_QueryInterface(content) );
|
// care at all about "dd-droplocation", only the coordinate so there is no need to send the
|
||||||
nsCOMPtr<nsIDOMNode> eventTarget;
|
// AttributeChanged() about that attribute.
|
||||||
aDragEvent->GetTarget ( getter_AddRefs(eventTarget) );
|
char buffer[10];
|
||||||
if ( eventTarget != toolbarDOMNode )
|
sprintf(buffer, "%d", kNoDropLoc);
|
||||||
return NS_OK;
|
content->SetAttribute ( kNameSpaceID_None, nsXULAtoms::ddDropLocationCoord, buffer, PR_TRUE );
|
||||||
|
content->SetAttribute ( kNameSpaceID_None, nsXULAtoms::ddDropLocation, "false", PR_TRUE );
|
||||||
printf("***REAL EXIT EVENT\n");
|
content->SetAttribute ( kNameSpaceID_None, nsXULAtoms::ddDropOn, "false", PR_TRUE );
|
||||||
#endif
|
content->SetAttribute ( kNameSpaceID_None, nsXULAtoms::ddTriggerRepaintRestore, "1", PR_TRUE );
|
||||||
|
}
|
||||||
// tell the treeItem to not do any more drop feedback. Note that the tree code doesn't
|
|
||||||
// care at all about "dd-droplocation", only the coordinate so there is no need to send the
|
|
||||||
// AttributeChanged() about that attribute.
|
|
||||||
char buffer[10];
|
|
||||||
sprintf(buffer, "%d", -1);
|
|
||||||
content->SetAttribute ( kNameSpaceID_None, nsXULAtoms::ddDropLocationCoord, buffer, PR_TRUE );
|
|
||||||
content->SetAttribute ( kNameSpaceID_None, nsXULAtoms::ddDropLocation, "false", PR_TRUE );
|
|
||||||
content->SetAttribute ( kNameSpaceID_None, nsXULAtoms::ddDropOn, "false", PR_TRUE );
|
|
||||||
content->SetAttribute ( kNameSpaceID_None, nsXULAtoms::ddTriggerRepaint, "1", PR_TRUE );
|
|
||||||
|
|
||||||
// cache the current drop location
|
// cache the current drop location
|
||||||
mCurrentDropLoc = -1;
|
mCurrentDropLoc = kNoDropLoc;
|
||||||
|
|
||||||
return NS_OK; // don't consume event
|
return NS_OK; // don't consume event
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,12 @@ class nsTreeItemDragCapturer : public nsIDOMDragListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
// special values for the Y value of the drop location.
|
||||||
|
enum {
|
||||||
|
kNoDropLoc = -2, // unset, no drop feedback to be drawn.
|
||||||
|
kContainerDropLoc = -1 // a container Y is meaningless, but indicates feedback is still needed
|
||||||
|
} ;
|
||||||
|
|
||||||
// default ctor and dtor
|
// default ctor and dtor
|
||||||
nsTreeItemDragCapturer ( nsTreeRowGroupFrame* inToolbar, nsIPresContext* inPresContext );
|
nsTreeItemDragCapturer ( nsTreeRowGroupFrame* inToolbar, nsIPresContext* inPresContext );
|
||||||
virtual ~nsTreeItemDragCapturer();
|
virtual ~nsTreeItemDragCapturer();
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
* Pierre Phaneuf <pp@ludusdesign.com>
|
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "nsTreeRowGroupFrame.h"
|
||||||
|
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsXULAtoms.h"
|
#include "nsXULAtoms.h"
|
||||||
#include "nsHTMLAtoms.h"
|
#include "nsHTMLAtoms.h"
|
||||||
|
@ -28,7 +30,7 @@
|
||||||
#include "nsTreeFrame.h"
|
#include "nsTreeFrame.h"
|
||||||
#include "nsIPresContext.h"
|
#include "nsIPresContext.h"
|
||||||
#include "nsIPresShell.h"
|
#include "nsIPresShell.h"
|
||||||
#include "nsTreeRowGroupFrame.h"
|
#include "nsIDeviceContext.h"
|
||||||
#include "nsIStyleContext.h"
|
#include "nsIStyleContext.h"
|
||||||
#include "nsCSSFrameConstructor.h"
|
#include "nsCSSFrameConstructor.h"
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
|
@ -54,6 +56,15 @@
|
||||||
// XXX This should probably be based off the height of a row in pixels
|
// XXX This should probably be based off the height of a row in pixels
|
||||||
#define SCROLL_FACTOR 16
|
#define SCROLL_FACTOR 16
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prototypes
|
||||||
|
//
|
||||||
|
void GetRowStartAndCount(nsIFrame* aFrame, PRInt32& aStartRowIndex, PRInt32& aNumRows) ;
|
||||||
|
void LocateIndentationFrame ( nsIPresContext* aPresContext, nsIFrame* aParentFrame,
|
||||||
|
nsIFrame** aResult) ;
|
||||||
|
|
||||||
|
|
||||||
// I added the following function to improve keeping the frame
|
// I added the following function to improve keeping the frame
|
||||||
// chains in synch with the table. repackage as appropriate - karnaze
|
// chains in synch with the table. repackage as appropriate - karnaze
|
||||||
void GetRowStartAndCount(nsIFrame* aFrame,
|
void GetRowStartAndCount(nsIFrame* aFrame,
|
||||||
|
@ -107,7 +118,8 @@ nsTreeRowGroupFrame::nsTreeRowGroupFrame()
|
||||||
mScrollbar(nsnull), mOuterFrame(nsnull),
|
mScrollbar(nsnull), mOuterFrame(nsnull),
|
||||||
mContentChain(nsnull), mFrameConstructor(nsnull),
|
mContentChain(nsnull), mFrameConstructor(nsnull),
|
||||||
mRowGroupHeight(0), mCurrentIndex(0), mRowCount(0),
|
mRowGroupHeight(0), mCurrentIndex(0), mRowCount(0),
|
||||||
mYDropLoc(-1), mDropOnContainer(PR_FALSE)
|
mYDropLoc(nsTreeItemDragCapturer::kNoDropLoc), mDropOnContainer(PR_FALSE),
|
||||||
|
mTreeIsSorted(PR_FALSE)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
|
@ -2100,15 +2112,25 @@ nsTreeRowGroupFrame :: AttributeChanged ( nsIPresContext* aPresContext, nsIConte
|
||||||
PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRInt32 aHint)
|
PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRInt32 aHint)
|
||||||
{
|
{
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
|
PRInt32 ignore;
|
||||||
|
|
||||||
if ( aAttribute == nsXULAtoms::ddTriggerRepaint )
|
if ( aAttribute == nsXULAtoms::ddTriggerRepaint )
|
||||||
ForceDrawFrame ( aPresContext, this );
|
ForceDrawFrame ( aPresContext, this );
|
||||||
|
else if ( aAttribute == nsXULAtoms::ddTriggerRepaintSorted ) {
|
||||||
|
// Set a flag so that children won't draw the drop feedback but the parent
|
||||||
|
// will.
|
||||||
|
mOuterFrame->mTreeIsSorted = true;
|
||||||
|
ForceDrawFrame ( aPresContext, mOuterFrame );
|
||||||
|
mOuterFrame->mTreeIsSorted = false;
|
||||||
|
}
|
||||||
|
else if ( aAttribute == nsXULAtoms::ddTriggerRepaintRestore ) {
|
||||||
|
// Repaint the entire tree with no special attributes set.
|
||||||
|
ForceDrawFrame ( aPresContext, mOuterFrame );
|
||||||
|
}
|
||||||
else if ( aAttribute == nsXULAtoms::ddDropLocationCoord ) {
|
else if ( aAttribute == nsXULAtoms::ddDropLocationCoord ) {
|
||||||
nsAutoString attribute;
|
nsAutoString attribute;
|
||||||
aChild->GetAttribute ( kNameSpaceID_None, aAttribute, attribute );
|
aChild->GetAttribute ( kNameSpaceID_None, aAttribute, attribute );
|
||||||
char* iHateNSString = attribute.ToNewCString();
|
mYDropLoc = attribute.ToInteger(&ignore);
|
||||||
mYDropLoc = atoi( iHateNSString );
|
|
||||||
nsAllocator::Free ( iHateNSString );
|
|
||||||
}
|
}
|
||||||
else if ( aAttribute == nsXULAtoms::ddDropOn ) {
|
else if ( aAttribute == nsXULAtoms::ddDropOn ) {
|
||||||
nsAutoString attribute;
|
nsAutoString attribute;
|
||||||
|
@ -2160,43 +2182,302 @@ NS_IMETHODIMP
|
||||||
nsTreeRowGroupFrame :: Paint ( nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext,
|
nsTreeRowGroupFrame :: Paint ( nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext,
|
||||||
const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer)
|
const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer)
|
||||||
{
|
{
|
||||||
nsresult res = nsTableRowGroupFrame::Paint ( aPresContext, aRenderingContext, aDirtyRect, aWhichLayer );
|
nsresult res = NS_OK;
|
||||||
|
res = nsTableRowGroupFrame::Paint ( aPresContext, aRenderingContext, aDirtyRect, aWhichLayer );
|
||||||
|
|
||||||
if ( mYDropLoc != -1 || mDropOnContainer ) {
|
if ( (aWhichLayer == eFramePaintLayer_Content) &&
|
||||||
// go looking for the psuedo-style that describes the drop feedback marker. If we don't
|
(mYDropLoc != nsTreeItemDragCapturer::kNoDropLoc || mDropOnContainer || mTreeIsSorted) )
|
||||||
// have it yet, go looking for it.
|
PaintDropFeedback ( aPresContext, aRenderingContext );
|
||||||
if (!mMarkerStyle) {
|
|
||||||
nsCOMPtr<nsIAtom> atom ( getter_AddRefs(NS_NewAtom(":-moz-drop-marker")) );
|
|
||||||
aPresContext->ProbePseudoStyleContextFor(mContent, atom, mStyleContext,
|
|
||||||
PR_FALSE, getter_AddRefs(mMarkerStyle));
|
|
||||||
}
|
|
||||||
|
|
||||||
nscolor color;
|
|
||||||
if ( mMarkerStyle ) {
|
|
||||||
const nsStyleColor* styleColor =
|
|
||||||
NS_STATIC_CAST(const nsStyleColor*, mMarkerStyle->GetStyleData(eStyleStruct_Color));
|
|
||||||
color = styleColor->mColor;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
color = NS_RGB(0,0,0);
|
|
||||||
|
|
||||||
// draw different drop feedback depending on if we are dropping on the
|
|
||||||
// container or above/below it
|
|
||||||
if ( !mDropOnContainer ) {
|
|
||||||
|
|
||||||
//XXX compute horiz indentation, fix up constants.
|
|
||||||
|
|
||||||
aRenderingContext.SetColor(color);
|
|
||||||
nsRect dividingLine ( 0, mYDropLoc, 20*50, 30 );
|
|
||||||
aRenderingContext.FillRect(dividingLine);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
aRenderingContext.SetColor(NS_RGB(0x7F,0x7F,0x7F));
|
|
||||||
nsRect treeItemBounds ( 0, 0, mRect.width, mRect.height );
|
|
||||||
aRenderingContext.DrawRect ( treeItemBounds );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
} // Paint
|
} // Paint
|
||||||
|
|
||||||
|
void
|
||||||
|
nsTreeRowGroupFrame :: PaintDropFeedback ( nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext )
|
||||||
|
{
|
||||||
|
// lookup the drop marker color. default to black if not found.
|
||||||
|
nsCOMPtr<nsIAtom> atom ( getter_AddRefs(NS_NewAtom(":-moz-drop-marker")) );
|
||||||
|
nscolor color = GetColorFromStyleContext ( aPresContext, atom, NS_RGB(0,0,0) ) ;
|
||||||
|
|
||||||
|
// find the twips-to-pixels conversion. We have decided not to cache this for
|
||||||
|
// space reasons.
|
||||||
|
float p2t = 20.0;
|
||||||
|
nsCOMPtr<nsIDeviceContext> dc;
|
||||||
|
aRenderingContext.GetDeviceContext ( *getter_AddRefs(dc) );
|
||||||
|
if ( dc )
|
||||||
|
dc->GetDevUnitsToTwips ( p2t );
|
||||||
|
|
||||||
|
if ( mTreeIsSorted )
|
||||||
|
PaintSortedDropFeedback ( color, aRenderingContext, p2t );
|
||||||
|
else if ( !mOuterFrame->mTreeIsSorted ) {
|
||||||
|
// draw different drop feedback depending on if we are dropping on the
|
||||||
|
// container or above/below it
|
||||||
|
if ( !mDropOnContainer )
|
||||||
|
PaintInBetweenDropFeedback ( color, aRenderingContext, aPresContext, p2t );
|
||||||
|
else
|
||||||
|
PaintOnContainerDropFeedback ( color, aRenderingContext, aPresContext, p2t );
|
||||||
|
|
||||||
|
} // else tree not sorted
|
||||||
|
|
||||||
|
} // PaintDropFeedback
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// PaintSortedDropFeedback
|
||||||
|
//
|
||||||
|
// Draws the drop feedback for when the tree is sorted, so line-item drop feedback is
|
||||||
|
// not appliable.
|
||||||
|
//
|
||||||
|
void
|
||||||
|
nsTreeRowGroupFrame :: PaintSortedDropFeedback ( nscolor inColor, nsIRenderingContext& inRenderingContext,
|
||||||
|
float & inPixelsToTwips )
|
||||||
|
{
|
||||||
|
// two pixels wide
|
||||||
|
const PRInt32 borderWidth = NSToIntRound(2 * inPixelsToTwips);
|
||||||
|
|
||||||
|
nsRect top ( 0, 0, mRect.width, borderWidth );
|
||||||
|
nsRect left ( 0, 0, borderWidth, mRect.height );
|
||||||
|
nsRect right ( mRect.width - borderWidth, 0, borderWidth, mRect.height );
|
||||||
|
nsRect bottom ( 0, mRect.height - borderWidth, mRect.width, borderWidth );
|
||||||
|
|
||||||
|
inRenderingContext.SetColor(inColor);
|
||||||
|
inRenderingContext.FillRect ( top );
|
||||||
|
inRenderingContext.FillRect ( left );
|
||||||
|
inRenderingContext.FillRect ( bottom );
|
||||||
|
inRenderingContext.FillRect ( right );
|
||||||
|
|
||||||
|
} // PaintSortedDropFeedback
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// PaintOnContainerDropFeedback
|
||||||
|
//
|
||||||
|
// Draws the drop feedback for when the tree is sorted, so line-item drop feedback is
|
||||||
|
// not appliable.
|
||||||
|
//
|
||||||
|
void
|
||||||
|
nsTreeRowGroupFrame :: PaintOnContainerDropFeedback ( nscolor inColor, nsIRenderingContext& inRenderingContext,
|
||||||
|
nsIPresContext* inPresContext, float & inPixelsToTwips )
|
||||||
|
{
|
||||||
|
// lookup the color for the bg of the selected cell. default to gray if not found.
|
||||||
|
nsCOMPtr<nsIAtom> atom ( getter_AddRefs(NS_NewAtom(":-moz-drop-container-bg")) );
|
||||||
|
nscolor bgColor = GetColorFromStyleContext ( inPresContext, atom, NS_RGB(0xDD, 0xDD, 0xDD) ) ;
|
||||||
|
|
||||||
|
// paint the cell's bg...we really want to muck with the titled buttons, but a) there
|
||||||
|
// isn't any support for that yet, and b) we don't really know what's going
|
||||||
|
// to be there in the cell as far as anonymous content goes...
|
||||||
|
nsRect cellBounds;
|
||||||
|
nsIFrame* treeRow;
|
||||||
|
FirstChild ( inPresContext, nsnull, &treeRow );
|
||||||
|
if ( !treeRow ) return;
|
||||||
|
nsIFrame* treeCell;
|
||||||
|
treeRow->FirstChild ( inPresContext, nsnull, &treeCell );
|
||||||
|
if ( !treeCell ) return;
|
||||||
|
treeCell->GetRect ( cellBounds );
|
||||||
|
inRenderingContext.SetColor ( bgColor );
|
||||||
|
inRenderingContext.FillRect ( cellBounds );
|
||||||
|
|
||||||
|
PRInt32 horizIndent = 0;
|
||||||
|
if ( IsOpenContainer() ) {
|
||||||
|
nsIFrame* firstChild = nsnull;
|
||||||
|
FindFirstChildTreeItemFrame ( inPresContext, &firstChild );
|
||||||
|
if ( firstChild )
|
||||||
|
horizIndent = FindIndentation(inPresContext, firstChild);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// for the case where the container is closed (it doesn't have any children)
|
||||||
|
// all we can do is get our own indentation and add the hardcoded indent level
|
||||||
|
// since we don't really know...The indent level is currently hardcoded in
|
||||||
|
// the treeIndentation frame to 16..
|
||||||
|
horizIndent = FindIndentation(inPresContext, this) + NSToIntRound(16 * inPixelsToTwips);
|
||||||
|
}
|
||||||
|
|
||||||
|
inRenderingContext.SetColor(inColor);
|
||||||
|
nsRect dividingLine ( horizIndent, mRect.height - NSToIntRound(2 * inPixelsToTwips),
|
||||||
|
NSToIntRound(50 * inPixelsToTwips), NSToIntRound(2 * inPixelsToTwips) );
|
||||||
|
inRenderingContext.DrawRect ( dividingLine );
|
||||||
|
|
||||||
|
} // PaintOnContainerDropFeedback
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// PaintInBetweenDropFeedback
|
||||||
|
//
|
||||||
|
// Draw the feedback for when the drop is to go in between two nodes
|
||||||
|
//
|
||||||
|
void
|
||||||
|
nsTreeRowGroupFrame :: PaintInBetweenDropFeedback ( nscolor inColor, nsIRenderingContext& inRenderingContext,
|
||||||
|
nsIPresContext* inPresContext, float & inPixelsToTwips )
|
||||||
|
{
|
||||||
|
// the normal case is that we can just look at this frame to find the indentation we need. However,
|
||||||
|
// when we're an _open container_ and are being asked to draw the line _after_, we need to use the
|
||||||
|
// indentation of our first child instead. ick.
|
||||||
|
PRInt32 horizIndent = 0;
|
||||||
|
if ( IsOpenContainer() && mYDropLoc > 0 ) {
|
||||||
|
nsIFrame* firstChild = nsnull;
|
||||||
|
FindFirstChildTreeItemFrame ( inPresContext, &firstChild );
|
||||||
|
if ( firstChild )
|
||||||
|
horizIndent = FindIndentation(inPresContext, firstChild);
|
||||||
|
} // if open container and drop after
|
||||||
|
else
|
||||||
|
horizIndent = FindIndentation(inPresContext, this);
|
||||||
|
|
||||||
|
inRenderingContext.SetColor(inColor);
|
||||||
|
nsRect dividingLine ( horizIndent, mYDropLoc,
|
||||||
|
NSToIntRound(50 * inPixelsToTwips), NSToIntRound(2 * inPixelsToTwips) );
|
||||||
|
inRenderingContext.FillRect(dividingLine);
|
||||||
|
|
||||||
|
} // PaintInBetweenDropFeedback
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// FindIndentation
|
||||||
|
//
|
||||||
|
// Compute horizontal offset for dividing line by finding a treeindentation tag
|
||||||
|
// and using its right coordinate.
|
||||||
|
//
|
||||||
|
// NOTE: We assume this indentation tag is in the first column.
|
||||||
|
// NOTE: We aren't caching this value because of space reasons....
|
||||||
|
//
|
||||||
|
PRInt32
|
||||||
|
nsTreeRowGroupFrame :: FindIndentation ( nsIPresContext* inPresContext, nsIFrame* inStartFrame ) const
|
||||||
|
{
|
||||||
|
PRInt32 indentInTwips = 0;
|
||||||
|
|
||||||
|
if ( !inStartFrame ) return 0;
|
||||||
|
nsIFrame* treeRowFrame;
|
||||||
|
inStartFrame->FirstChild ( inPresContext, nsnull, &treeRowFrame );
|
||||||
|
if ( !treeRowFrame ) return 0;
|
||||||
|
nsIFrame* treeCellFrame;
|
||||||
|
treeRowFrame->FirstChild ( inPresContext, nsnull, &treeCellFrame );
|
||||||
|
if ( !treeCellFrame ) return 0;
|
||||||
|
|
||||||
|
nsIFrame* treeIndentFrame = nsnull;
|
||||||
|
LocateIndentationFrame ( inPresContext, treeCellFrame, &treeIndentFrame );
|
||||||
|
if ( treeIndentFrame ) {
|
||||||
|
nsRect treeIndentBounds;
|
||||||
|
treeIndentFrame->GetRect ( treeIndentBounds );
|
||||||
|
indentInTwips = treeIndentBounds.x + treeIndentBounds.width;
|
||||||
|
}
|
||||||
|
return indentInTwips;
|
||||||
|
|
||||||
|
} // FindIndentation
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// LocateIndentationFrame
|
||||||
|
//
|
||||||
|
// Recursively locate the <treeindentation> tag
|
||||||
|
//
|
||||||
|
void
|
||||||
|
LocateIndentationFrame ( nsIPresContext* aPresContext, nsIFrame* aParentFrame,
|
||||||
|
nsIFrame** aResult)
|
||||||
|
{
|
||||||
|
// Check ourselves.
|
||||||
|
*aResult = nsnull;
|
||||||
|
nsCOMPtr<nsIContent> content;
|
||||||
|
aParentFrame->GetContent(getter_AddRefs(content));
|
||||||
|
nsCOMPtr<nsIAtom> tagName;
|
||||||
|
content->GetTag ( *getter_AddRefs(tagName) );
|
||||||
|
if ( tagName == nsXULAtoms::treeindentation ) {
|
||||||
|
*aResult = aParentFrame;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check our kids.
|
||||||
|
nsIFrame* currFrame;
|
||||||
|
aParentFrame->FirstChild(aPresContext, nsnull, &currFrame);
|
||||||
|
while (currFrame) {
|
||||||
|
LocateIndentationFrame(aPresContext, currFrame, aResult);
|
||||||
|
if (*aResult)
|
||||||
|
return;
|
||||||
|
currFrame->GetNextSibling(&currFrame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// FindFirstChildTreeItemFrame
|
||||||
|
//
|
||||||
|
// Locates the first <treeitem> in our child list. Assumes that we are a container and that
|
||||||
|
// the children are visible.
|
||||||
|
//
|
||||||
|
void
|
||||||
|
nsTreeRowGroupFrame :: FindFirstChildTreeItemFrame ( nsIPresContext* inPresContext,
|
||||||
|
nsIFrame** outChild ) const
|
||||||
|
{
|
||||||
|
*outChild = nsnull;
|
||||||
|
|
||||||
|
// first find the <treechildren> tag in our child list.
|
||||||
|
nsIFrame* currChildFrame = nsnull;
|
||||||
|
FirstChild ( inPresContext, nsnull, &currChildFrame );
|
||||||
|
while ( currChildFrame ) {
|
||||||
|
nsCOMPtr<nsIContent> content;
|
||||||
|
currChildFrame->GetContent ( getter_AddRefs(content) );
|
||||||
|
nsCOMPtr<nsIAtom> tagName;
|
||||||
|
content->GetTag ( *getter_AddRefs(tagName) );
|
||||||
|
if ( tagName == nsXULAtoms::treechildren )
|
||||||
|
break;
|
||||||
|
currChildFrame->GetNextSibling ( &currChildFrame );
|
||||||
|
} // foreach child of the treeItem
|
||||||
|
NS_ASSERTION ( currChildFrame, "Can't find <treechildren>" );
|
||||||
|
|
||||||
|
// |currChildFrame| now holds the correct frame if we found it
|
||||||
|
if ( currChildFrame )
|
||||||
|
currChildFrame->FirstChild ( inPresContext, nsnull, outChild );
|
||||||
|
|
||||||
|
} // FindFirstChildTreeItemFrame
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// IsOpenContainer
|
||||||
|
//
|
||||||
|
// Determine if a node is both a container and open
|
||||||
|
//
|
||||||
|
PRBool
|
||||||
|
nsTreeRowGroupFrame :: IsOpenContainer ( ) const
|
||||||
|
{
|
||||||
|
PRBool isOpenContainer = PR_FALSE;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMElement> me ( do_QueryInterface(mContent) );
|
||||||
|
if ( me ) {
|
||||||
|
nsAutoString isContainer, isOpen;
|
||||||
|
me->GetAttribute(nsAutoString("container"), isContainer);
|
||||||
|
me->GetAttribute(nsAutoString("open"), isOpen);
|
||||||
|
isOpenContainer = (isContainer.Equals("true") && isOpen.Equals("true"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return isOpenContainer;
|
||||||
|
|
||||||
|
} // IsOpenContainer
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// GetColorFromStyleContext
|
||||||
|
//
|
||||||
|
// A little helper to root out a color from the current style context. Returns
|
||||||
|
// the given default color if we can't find it, for whatever reason.
|
||||||
|
//
|
||||||
|
nscolor
|
||||||
|
nsTreeRowGroupFrame :: GetColorFromStyleContext ( nsIPresContext* inPresContext, nsIAtom* inAtom,
|
||||||
|
nscolor inDefaultColor )
|
||||||
|
{
|
||||||
|
nscolor retColor = inDefaultColor;
|
||||||
|
|
||||||
|
// go looking for the psuedo-style. We have decided not to cache this for space reasons.
|
||||||
|
nsCOMPtr<nsIStyleContext> markerStyle;
|
||||||
|
inPresContext->ProbePseudoStyleContextFor(mContent, inAtom, mStyleContext,
|
||||||
|
PR_FALSE, getter_AddRefs(markerStyle));
|
||||||
|
|
||||||
|
// dig out the color we want.
|
||||||
|
if ( markerStyle ) {
|
||||||
|
const nsStyleColor* styleColor =
|
||||||
|
NS_STATIC_CAST(const nsStyleColor*, markerStyle->GetStyleData(eStyleStruct_Color));
|
||||||
|
retColor = styleColor->mColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retColor;
|
||||||
|
|
||||||
|
} // GetColorFromStyleContext
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,22 @@ protected:
|
||||||
void ComputeTotalRowCount(PRInt32& rowCount, nsIContent* aParent);
|
void ComputeTotalRowCount(PRInt32& rowCount, nsIContent* aParent);
|
||||||
|
|
||||||
static void ClearFrameRefs(nsIPresContext* aPresContext, nsIPresShell* aPresShell, nsIFrame *aParent);
|
static void ClearFrameRefs(nsIPresContext* aPresContext, nsIPresShell* aPresShell, nsIFrame *aParent);
|
||||||
|
|
||||||
|
// handle drawing the drop feedback
|
||||||
|
void PaintDropFeedback ( nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext ) ;
|
||||||
|
void PaintSortedDropFeedback ( nscolor inColor, nsIRenderingContext& inRenderingContext, float & inP2T ) ;
|
||||||
|
void PaintOnContainerDropFeedback ( nscolor inColor, nsIRenderingContext& inRenderingContext,
|
||||||
|
nsIPresContext* inPresContext, float & inP2T ) ;
|
||||||
|
void PaintInBetweenDropFeedback ( nscolor inColor, nsIRenderingContext& inRenderingContext,
|
||||||
|
nsIPresContext* inPresContext, float & inP2T ) ;
|
||||||
|
|
||||||
|
// helpers for drop feedback
|
||||||
|
PRInt32 FindIndentation ( nsIPresContext* inPresContext, nsIFrame* inStartFrame ) const ;
|
||||||
|
void FindFirstChildTreeItemFrame ( nsIPresContext* inPresContext, nsIFrame** outChild ) const ;
|
||||||
|
PRBool IsOpenContainer ( ) const ;
|
||||||
|
nscolor GetColorFromStyleContext ( nsIPresContext* inPresContext, nsIAtom* inAtom,
|
||||||
|
nscolor inDefaultColor ) ;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Helpers that allow access to info. The tree is the primary consumer of this
|
// Helpers that allow access to info. The tree is the primary consumer of this
|
||||||
// info.
|
// info.
|
||||||
|
@ -199,6 +214,8 @@ public:
|
||||||
static PRBool IsTableRowGroupFrame(nsIFrame*);
|
static PRBool IsTableRowGroupFrame(nsIFrame*);
|
||||||
static PRBool IsTableRowFrame(nsIFrame*);
|
static PRBool IsTableRowFrame(nsIFrame*);
|
||||||
|
|
||||||
|
PRBool IsOutermostTreeItem ( ) const { return this == mOuterFrame; }
|
||||||
|
|
||||||
protected: // Data Members
|
protected: // Data Members
|
||||||
nsIFrame* mTopFrame; // The current topmost frame in the view.
|
nsIFrame* mTopFrame; // The current topmost frame in the view.
|
||||||
nsIFrame* mBottomFrame; // The current bottom frame in the view.
|
nsIFrame* mBottomFrame; // The current bottom frame in the view.
|
||||||
|
@ -230,6 +247,6 @@ protected: // Data Members
|
||||||
// guaranteed to be meaningful when no drop is underway.
|
// guaranteed to be meaningful when no drop is underway.
|
||||||
PRInt32 mYDropLoc;
|
PRInt32 mYDropLoc;
|
||||||
PRBool mDropOnContainer;
|
PRBool mDropOnContainer;
|
||||||
nsCOMPtr<nsIStyleContext> mMarkerStyle;
|
PRBool mTreeIsSorted; // only needs to be on the topLevel rowGroup, I _think_
|
||||||
|
|
||||||
}; // class nsTreeRowGroupFrame
|
}; // class nsTreeRowGroupFrame
|
||||||
|
|
|
@ -134,6 +134,8 @@ XUL_ATOM(debug, "debug")
|
||||||
XUL_ATOM(ddDropLocation, "dd-droplocation")
|
XUL_ATOM(ddDropLocation, "dd-droplocation")
|
||||||
XUL_ATOM(ddDropLocationCoord, "dd-droplocationcoord")
|
XUL_ATOM(ddDropLocationCoord, "dd-droplocationcoord")
|
||||||
XUL_ATOM(ddDropOn, "dd-dropon")
|
XUL_ATOM(ddDropOn, "dd-dropon")
|
||||||
|
XUL_ATOM(ddTriggerRepaintSorted, "dd-triggerrepaintsorted")
|
||||||
|
XUL_ATOM(ddTriggerRepaintRestore, "dd-triggerrepaintrestore")
|
||||||
XUL_ATOM(ddTriggerRepaint, "dd-triggerrepaint")
|
XUL_ATOM(ddTriggerRepaint, "dd-triggerrepaint")
|
||||||
XUL_ATOM(container, "container")
|
XUL_ATOM(container, "container")
|
||||||
XUL_ATOM(ddDragDropArea, "dragdroparea")
|
XUL_ATOM(ddDragDropArea, "dragdroparea")
|
||||||
|
|
Загрузка…
Ссылка в новой задаче