121241 - Misplaced insertion line for outliner DND
120976 - Drop feedback needs some polishing
r=pink, sr=hyatt
Thanks for reviews and testing by zach.

- added new atom "dragSession"
- renamed atom "drop" to "dropOn"
- added new pseudo class -moz-outliner-drop-feedback
- added new paint method PaintDropFeedback()
- drop feedback in between rows is now painted at the same position for both orientations.
This commit is contained in:
varga%utcru.sk 2002-02-08 22:35:18 +00:00
Родитель cf092ddb1e
Коммит 8e1dd8f30d
8 изменённых файлов: 407 добавлений и 129 удалений

Просмотреть файл

@ -109,7 +109,8 @@ XUL_ATOM(primary, "primary")
XUL_ATOM(current, "current") XUL_ATOM(current, "current")
XUL_ATOM(seltype, "seltype") XUL_ATOM(seltype, "seltype")
XUL_ATOM(sorted, "sorted") XUL_ATOM(sorted, "sorted")
XUL_ATOM(drop, "drop") XUL_ATOM(dragSession, "dragSession")
XUL_ATOM(dropOn, "dropOn")
XUL_ATOM(dropBefore, "dropBefore") XUL_ATOM(dropBefore, "dropBefore")
XUL_ATOM(dropAfter, "dropAfter") XUL_ATOM(dropAfter, "dropAfter")
XUL_ATOM(mozoutlinerrow, ":-moz-outliner-row") XUL_ATOM(mozoutlinerrow, ":-moz-outliner-row")
@ -121,6 +122,7 @@ XUL_ATOM(mozoutlinerindentation, ":-moz-outliner-indentation")
XUL_ATOM(mozoutlinerline, ":-moz-outliner-line") XUL_ATOM(mozoutlinerline, ":-moz-outliner-line")
XUL_ATOM(mozoutlinerimage, ":-moz-outliner-image") XUL_ATOM(mozoutlinerimage, ":-moz-outliner-image")
XUL_ATOM(mozoutlinerseparator, ":-moz-outliner-separator") XUL_ATOM(mozoutlinerseparator, ":-moz-outliner-separator")
XUL_ATOM(mozoutlinerdropfeedback, ":-moz-outliner-drop-feedback")
XUL_ATOM(menubar, "menubar") // An XP menu bar. XUL_ATOM(menubar, "menubar") // An XP menu bar.
XUL_ATOM(menu, "menu") // Represents an XP menu XUL_ATOM(menu, "menu") // Represents an XP menu

Просмотреть файл

@ -1548,6 +1548,10 @@ nsOutlinerBodyFrame::PrefillPropertyArray(PRInt32 aRowIndex, nsOutlinerColumn* a
if (sorted) if (sorted)
mScratchArray->AppendElement(nsXULAtoms::sorted); mScratchArray->AppendElement(nsXULAtoms::sorted);
// drag session
if (mDragSession)
mScratchArray->AppendElement(nsXULAtoms::dragSession);
if (aRowIndex != -1) { if (aRowIndex != -1) {
nsCOMPtr<nsIOutlinerSelection> selection; nsCOMPtr<nsIOutlinerSelection> selection;
mView->GetSelection(getter_AddRefs(selection)); mView->GetSelection(getter_AddRefs(selection));
@ -1584,12 +1588,12 @@ nsOutlinerBodyFrame::PrefillPropertyArray(PRInt32 aRowIndex, nsOutlinerColumn* a
mScratchArray->AppendElement(nsXULAtoms::leaf); mScratchArray->AppendElement(nsXULAtoms::leaf);
} }
// drop feedback // drop orientation
if (mDropAllowed && mDropRow == aRowIndex) { if (mDropAllowed && mDropRow == aRowIndex) {
if (mDropOrient == nsIOutlinerView::inDropBefore) if (mDropOrient == nsIOutlinerView::inDropBefore)
mScratchArray->AppendElement(nsXULAtoms::dropBefore); mScratchArray->AppendElement(nsXULAtoms::dropBefore);
else if (mDropOrient == nsIOutlinerView::inDropOn) else if (mDropOrient == nsIOutlinerView::inDropOn)
mScratchArray->AppendElement(nsXULAtoms::drop); mScratchArray->AppendElement(nsXULAtoms::dropOn);
else if (mDropOrient == nsIOutlinerView::inDropAfter) else if (mDropOrient == nsIOutlinerView::inDropAfter)
mScratchArray->AppendElement(nsXULAtoms::dropAfter); mScratchArray->AppendElement(nsXULAtoms::dropAfter);
} }
@ -1922,6 +1926,9 @@ NS_IMETHODIMP nsOutlinerBodyFrame::Paint(nsIPresContext* aPresContext,
} }
} }
if (mDropAllowed)
PaintDropFeedback(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
return NS_OK; return NS_OK;
} }
@ -2070,9 +2077,8 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintRow(int aRowIndex, const nsRect& aRowRec
if (overflow > 0) if (overflow > 0)
cellRect.width -= overflow; cellRect.width -= overflow;
nsRect dirtyRect; nsRect dirtyRect;
if (dirtyRect.IntersectRect(aDirtyRect, cellRect)) { if (dirtyRect.IntersectRect(aDirtyRect, cellRect))
PaintCell(aRowIndex, currCol, cellRect, aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); PaintCell(aRowIndex, currCol, cellRect, aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
currX += currCol->GetWidth(); currX += currCol->GetWidth();
} }
} }
@ -2653,6 +2659,123 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintText(int aRowIndex,
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP nsOutlinerBodyFrame::PaintDropFeedback(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer,
PRUint32 aFlags)
{
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
if (mDropOrient == nsIOutlinerView::inDropBefore ||
mDropOrient == nsIOutlinerView::inDropAfter) {
// Paint the drop feedback in between rows.
nsRect rowRect(mInnerBox.x, mInnerBox.y+mRowHeight*(mDropRow-mTopRowIndex), mInnerBox.width, mRowHeight);
// Paint the drop feedback at the same position for both orientations.
if (mDropOrient == nsIOutlinerView::inDropAfter)
rowRect.y += mRowHeight;
nsRect dirtyRect;
if (dirtyRect.IntersectRect(aDirtyRect, rowRect)) {
// Find the primary cell.
nscoord currX = rowRect.x;
nsOutlinerColumn* currCol;
for (currCol = mColumns; currCol && currX < mInnerBox.x+mInnerBox.width;
currCol = currCol->GetNext()) {
if (currCol->IsPrimary())
break;
currX += currCol->GetWidth();
}
PrefillPropertyArray(mDropRow, currCol);
// Resolve the style to use for the drop feedback.
nsCOMPtr<nsIStyleContext> feedbackContext;
GetPseudoStyleContext(nsXULAtoms::mozoutlinerdropfeedback, getter_AddRefs(feedbackContext));
const nsStyleVisibility* vis =
(const nsStyleVisibility*)feedbackContext->GetStyleData(eStyleStruct_Visibility);
// Paint only if it is visible.
if (vis->IsVisibleOrCollapsed()) {
PRInt32 level;
mView->GetLevel(mDropRow, &level);
// If our previous or next row has greater level use that for
// correct visual indentation.
if (mDropOrient == nsIOutlinerView::inDropBefore) {
if (mDropRow > 0) {
PRInt32 previousLevel;
mView->GetLevel(mDropRow - 1, &previousLevel);
if (previousLevel > level)
level = previousLevel;
}
}
else {
PRInt32 rowCount;
mView->GetRowCount(&rowCount);
if (mDropRow < rowCount - 1) {
PRInt32 nextLevel;
mView->GetLevel(mDropRow + 1, &nextLevel);
if (nextLevel > level)
level = nextLevel;
}
}
currX += mIndentation * level;
nsCOMPtr<nsIStyleContext> twistyContext;
GetPseudoStyleContext(nsXULAtoms::mozoutlinertwisty, getter_AddRefs(twistyContext));
nsRect twistySize = GetImageSize(mDropRow, currCol->GetID().get(), twistyContext);
const nsStyleMargin* twistyMarginData = (const nsStyleMargin*)twistyContext->GetStyleData(eStyleStruct_Margin);
nsMargin twistyMargin;
twistyMarginData->GetMargin(twistyMargin);
twistySize.Inflate(twistyMargin);
currX += twistySize.width;
const nsStylePosition* stylePosition = (const nsStylePosition*)
feedbackContext->GetStyleData(eStyleStruct_Position);
// Obtain the width for the drop feedback or use default value.
nscoord width;
if (stylePosition->mWidth.GetUnit() == eStyleUnit_Coord)
width = stylePosition->mWidth.GetCoordValue();
else {
// Use default width 50px.
float p2t;
mPresContext->GetPixelsToTwips(&p2t);
width = NSIntPixelsToTwips(50, p2t);
}
// Obtain the height for the drop feedback or use default value.
nscoord height;
if (stylePosition->mHeight.GetUnit() == eStyleUnit_Coord)
height = stylePosition->mHeight.GetCoordValue();
else {
// Use default height 2px.
float p2t;
mPresContext->GetPixelsToTwips(&p2t);
height = NSIntPixelsToTwips(2, p2t);
}
// Obtain the margins for the drop feedback and then deflate our rect
// by that amount.
nsRect feedbackRect(currX, rowRect.y, width, height);
const nsStyleMargin* styleMargin = (const nsStyleMargin*)
feedbackContext->GetStyleData(eStyleStruct_Margin);
nsMargin margin;
styleMargin->GetMargin(margin);
feedbackRect.Deflate(margin);
// Finally paint the drop feedback.
PaintBackgroundLayer(feedbackContext, aPresContext, aRenderingContext, feedbackRect, aDirtyRect);
}
}
}
}
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsOutlinerBodyFrame::PaintBackgroundLayer(nsIStyleContext* aStyleContext, nsIPresContext* aPresContext, nsOutlinerBodyFrame::PaintBackgroundLayer(nsIStyleContext* aStyleContext, nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext, nsIRenderingContext& aRenderingContext,
@ -2705,6 +2828,18 @@ NS_IMETHODIMP nsOutlinerBodyFrame::ScrollToRow(PRInt32 aRow)
ScrollInternal(aRow); ScrollInternal(aRow);
UpdateScrollbar(); UpdateScrollbar();
#if defined(XP_MAC) || defined(XP_MACOSX)
// mac can't process the event loop during a drag, so if we're dragging,
// grab the scroll widget and make it paint synchronously. This is
// sorta slow (having to paint the entire tree), but it works.
if ( mDragSession ) {
nsCOMPtr<nsIWidget> scrollWidget;
mScrollbar->GetWindow(mPresContext, getter_AddRefs(scrollWidget));
if ( scrollWidget )
scrollWidget->Invalidate(PR_TRUE);
}
#endif
return NS_OK; return NS_OK;
} }
@ -2782,15 +2917,8 @@ nsOutlinerBodyFrame::ScrollInternal(PRInt32 aRow)
PRInt32 absDelta = delta > 0 ? delta : -delta; PRInt32 absDelta = delta > 0 ? delta : -delta;
if (hasBackground || absDelta*mRowHeight >= mRect.height) if (hasBackground || absDelta*mRowHeight >= mRect.height)
Invalidate(); Invalidate();
else if (mOutlinerWidget) { else if (mOutlinerWidget)
mOutlinerWidget->Scroll(0, -delta*rowHeightAsPixels, nsnull); mOutlinerWidget->Scroll(0, -delta*rowHeightAsPixels, nsnull);
#if defined(XP_MAC) || defined(XP_MACOSX)
// mac can't process the event loop during a drag, so if we're dragging,
// update outliner widget synchronously.
if (mDragSession)
mOutlinerWidget->Update();
#endif
}
return NS_OK; return NS_OK;
} }
@ -2987,7 +3115,7 @@ nsOutlinerBodyFrame::OnDragExit(nsIDOMEvent* aEvent)
{ {
if (mDropAllowed) { if (mDropAllowed) {
mDropAllowed = PR_FALSE; mDropAllowed = PR_FALSE;
InvalidatePrimaryCell(mDropRow); InvalidatePrimaryCell(mDropRow + (mDropOrient == nsIOutlinerView::inDropAfter ? 1 : 0));
} }
else else
mDropAllowed = PR_FALSE; mDropAllowed = PR_FALSE;
@ -3012,23 +3140,31 @@ nsOutlinerBodyFrame::OnDragExit(nsIDOMEvent* aEvent)
NS_IMETHODIMP NS_IMETHODIMP
nsOutlinerBodyFrame::OnDragOver(nsIDOMEvent* aEvent) nsOutlinerBodyFrame::OnDragOver(nsIDOMEvent* aEvent)
{ {
// while we're here, handle tracking of scrolling during a drag. if (! mView)
PRBool scrollUp = PR_FALSE;
if (IsInDragScrollRegion(aEvent, &scrollUp)) {
if (mDropAllowed) {
// invalidate primary cell at old location.
mDropAllowed = PR_FALSE;
InvalidatePrimaryCell(mDropRow);
}
ScrollByLines(scrollUp ? -1 : 1);
return NS_OK; return NS_OK;
}
// compute the row mouse is over and the above/below/on state. Below we'll use this // compute the row mouse is over and the above/below/on state. Below we'll use this
// to see if anything changed. // to see if anything changed.
PRInt32 newRow = -1; PRInt32 newRow = -1;
PRInt16 newOrient = -1; PRInt16 newOrient = -1;
ComputeDropPosition(aEvent, &newRow, &newOrient); ComputeDropPosition(aEvent, &newRow, &newOrient);
// While we're here, handle tracking of scrolling during a drag.
PRInt32 rowCount;
mView->GetRowCount(&rowCount);
// Don't scroll if we are already at the top or bottom of the view.
if (newRow > 0 && newRow < rowCount - 1) {
PRBool scrollUp = PR_FALSE;
if (IsInDragScrollRegion(aEvent, &scrollUp)) {
if (mDropAllowed) {
// invalidate primary cell at old location.
mDropAllowed = PR_FALSE;
InvalidatePrimaryCell(mDropRow + (mDropOrient == nsIOutlinerView::inDropAfter ? 1 : 0));
}
ScrollByLines(scrollUp ? -1 : 1);
return NS_OK;
}
}
// if changed from last time, invalidate primary cell at the old location and if allowed, // if changed from last time, invalidate primary cell at the old location and if allowed,
// invalidate primary cell at the new location. If nothing changed, just bail. // invalidate primary cell at the new location. If nothing changed, just bail.
@ -3036,7 +3172,7 @@ nsOutlinerBodyFrame::OnDragOver(nsIDOMEvent* aEvent)
// Invalidate row at the old location. // Invalidate row at the old location.
if (mDropAllowed) { if (mDropAllowed) {
mDropAllowed = PR_FALSE; mDropAllowed = PR_FALSE;
InvalidatePrimaryCell(mDropRow); InvalidatePrimaryCell(mDropRow + (mDropOrient == nsIOutlinerView::inDropAfter ? 1 : 0));
} }
if (mOpenTimer) { if (mOpenTimer) {
@ -3077,7 +3213,7 @@ nsOutlinerBodyFrame::OnDragOver(nsIDOMEvent* aEvent)
if (canDropAtNewLocation) { if (canDropAtNewLocation) {
// Invalidate row at the new location/ // Invalidate row at the new location/
mDropAllowed = canDropAtNewLocation; mDropAllowed = canDropAtNewLocation;
InvalidatePrimaryCell(mDropRow); InvalidatePrimaryCell(mDropRow + (mDropOrient == nsIOutlinerView::inDropAfter ? 1 : 0));
} }
} }
} }

Просмотреть файл

@ -316,6 +316,13 @@ public:
const nsRect& aDirtyRect, const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer); nsFramePaintLayer aWhichLayer);
// This method paints a drop feedback in a given row of the outliner.
NS_IMETHOD PaintDropFeedback(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer,
PRUint32 aFlags = 0);
// This method is called with a specific style context and rect to // This method is called with a specific style context and rect to
// paint the background rect as if it were a full-blown frame. // paint the background rect as if it were a full-blown frame.
NS_IMETHOD PaintBackgroundLayer(nsIStyleContext* aStyleContext, nsIPresContext* aPresContext, NS_IMETHOD PaintBackgroundLayer(nsIStyleContext* aStyleContext, nsIPresContext* aPresContext,

Просмотреть файл

@ -1548,6 +1548,10 @@ nsOutlinerBodyFrame::PrefillPropertyArray(PRInt32 aRowIndex, nsOutlinerColumn* a
if (sorted) if (sorted)
mScratchArray->AppendElement(nsXULAtoms::sorted); mScratchArray->AppendElement(nsXULAtoms::sorted);
// drag session
if (mDragSession)
mScratchArray->AppendElement(nsXULAtoms::dragSession);
if (aRowIndex != -1) { if (aRowIndex != -1) {
nsCOMPtr<nsIOutlinerSelection> selection; nsCOMPtr<nsIOutlinerSelection> selection;
mView->GetSelection(getter_AddRefs(selection)); mView->GetSelection(getter_AddRefs(selection));
@ -1584,12 +1588,12 @@ nsOutlinerBodyFrame::PrefillPropertyArray(PRInt32 aRowIndex, nsOutlinerColumn* a
mScratchArray->AppendElement(nsXULAtoms::leaf); mScratchArray->AppendElement(nsXULAtoms::leaf);
} }
// drop feedback // drop orientation
if (mDropAllowed && mDropRow == aRowIndex) { if (mDropAllowed && mDropRow == aRowIndex) {
if (mDropOrient == nsIOutlinerView::inDropBefore) if (mDropOrient == nsIOutlinerView::inDropBefore)
mScratchArray->AppendElement(nsXULAtoms::dropBefore); mScratchArray->AppendElement(nsXULAtoms::dropBefore);
else if (mDropOrient == nsIOutlinerView::inDropOn) else if (mDropOrient == nsIOutlinerView::inDropOn)
mScratchArray->AppendElement(nsXULAtoms::drop); mScratchArray->AppendElement(nsXULAtoms::dropOn);
else if (mDropOrient == nsIOutlinerView::inDropAfter) else if (mDropOrient == nsIOutlinerView::inDropAfter)
mScratchArray->AppendElement(nsXULAtoms::dropAfter); mScratchArray->AppendElement(nsXULAtoms::dropAfter);
} }
@ -1922,6 +1926,9 @@ NS_IMETHODIMP nsOutlinerBodyFrame::Paint(nsIPresContext* aPresContext,
} }
} }
if (mDropAllowed)
PaintDropFeedback(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
return NS_OK; return NS_OK;
} }
@ -2070,9 +2077,8 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintRow(int aRowIndex, const nsRect& aRowRec
if (overflow > 0) if (overflow > 0)
cellRect.width -= overflow; cellRect.width -= overflow;
nsRect dirtyRect; nsRect dirtyRect;
if (dirtyRect.IntersectRect(aDirtyRect, cellRect)) { if (dirtyRect.IntersectRect(aDirtyRect, cellRect))
PaintCell(aRowIndex, currCol, cellRect, aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); PaintCell(aRowIndex, currCol, cellRect, aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
currX += currCol->GetWidth(); currX += currCol->GetWidth();
} }
} }
@ -2653,6 +2659,123 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintText(int aRowIndex,
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP nsOutlinerBodyFrame::PaintDropFeedback(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer,
PRUint32 aFlags)
{
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
if (mDropOrient == nsIOutlinerView::inDropBefore ||
mDropOrient == nsIOutlinerView::inDropAfter) {
// Paint the drop feedback in between rows.
nsRect rowRect(mInnerBox.x, mInnerBox.y+mRowHeight*(mDropRow-mTopRowIndex), mInnerBox.width, mRowHeight);
// Paint the drop feedback at the same position for both orientations.
if (mDropOrient == nsIOutlinerView::inDropAfter)
rowRect.y += mRowHeight;
nsRect dirtyRect;
if (dirtyRect.IntersectRect(aDirtyRect, rowRect)) {
// Find the primary cell.
nscoord currX = rowRect.x;
nsOutlinerColumn* currCol;
for (currCol = mColumns; currCol && currX < mInnerBox.x+mInnerBox.width;
currCol = currCol->GetNext()) {
if (currCol->IsPrimary())
break;
currX += currCol->GetWidth();
}
PrefillPropertyArray(mDropRow, currCol);
// Resolve the style to use for the drop feedback.
nsCOMPtr<nsIStyleContext> feedbackContext;
GetPseudoStyleContext(nsXULAtoms::mozoutlinerdropfeedback, getter_AddRefs(feedbackContext));
const nsStyleVisibility* vis =
(const nsStyleVisibility*)feedbackContext->GetStyleData(eStyleStruct_Visibility);
// Paint only if it is visible.
if (vis->IsVisibleOrCollapsed()) {
PRInt32 level;
mView->GetLevel(mDropRow, &level);
// If our previous or next row has greater level use that for
// correct visual indentation.
if (mDropOrient == nsIOutlinerView::inDropBefore) {
if (mDropRow > 0) {
PRInt32 previousLevel;
mView->GetLevel(mDropRow - 1, &previousLevel);
if (previousLevel > level)
level = previousLevel;
}
}
else {
PRInt32 rowCount;
mView->GetRowCount(&rowCount);
if (mDropRow < rowCount - 1) {
PRInt32 nextLevel;
mView->GetLevel(mDropRow + 1, &nextLevel);
if (nextLevel > level)
level = nextLevel;
}
}
currX += mIndentation * level;
nsCOMPtr<nsIStyleContext> twistyContext;
GetPseudoStyleContext(nsXULAtoms::mozoutlinertwisty, getter_AddRefs(twistyContext));
nsRect twistySize = GetImageSize(mDropRow, currCol->GetID().get(), twistyContext);
const nsStyleMargin* twistyMarginData = (const nsStyleMargin*)twistyContext->GetStyleData(eStyleStruct_Margin);
nsMargin twistyMargin;
twistyMarginData->GetMargin(twistyMargin);
twistySize.Inflate(twistyMargin);
currX += twistySize.width;
const nsStylePosition* stylePosition = (const nsStylePosition*)
feedbackContext->GetStyleData(eStyleStruct_Position);
// Obtain the width for the drop feedback or use default value.
nscoord width;
if (stylePosition->mWidth.GetUnit() == eStyleUnit_Coord)
width = stylePosition->mWidth.GetCoordValue();
else {
// Use default width 50px.
float p2t;
mPresContext->GetPixelsToTwips(&p2t);
width = NSIntPixelsToTwips(50, p2t);
}
// Obtain the height for the drop feedback or use default value.
nscoord height;
if (stylePosition->mHeight.GetUnit() == eStyleUnit_Coord)
height = stylePosition->mHeight.GetCoordValue();
else {
// Use default height 2px.
float p2t;
mPresContext->GetPixelsToTwips(&p2t);
height = NSIntPixelsToTwips(2, p2t);
}
// Obtain the margins for the drop feedback and then deflate our rect
// by that amount.
nsRect feedbackRect(currX, rowRect.y, width, height);
const nsStyleMargin* styleMargin = (const nsStyleMargin*)
feedbackContext->GetStyleData(eStyleStruct_Margin);
nsMargin margin;
styleMargin->GetMargin(margin);
feedbackRect.Deflate(margin);
// Finally paint the drop feedback.
PaintBackgroundLayer(feedbackContext, aPresContext, aRenderingContext, feedbackRect, aDirtyRect);
}
}
}
}
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsOutlinerBodyFrame::PaintBackgroundLayer(nsIStyleContext* aStyleContext, nsIPresContext* aPresContext, nsOutlinerBodyFrame::PaintBackgroundLayer(nsIStyleContext* aStyleContext, nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext, nsIRenderingContext& aRenderingContext,
@ -2705,6 +2828,18 @@ NS_IMETHODIMP nsOutlinerBodyFrame::ScrollToRow(PRInt32 aRow)
ScrollInternal(aRow); ScrollInternal(aRow);
UpdateScrollbar(); UpdateScrollbar();
#if defined(XP_MAC) || defined(XP_MACOSX)
// mac can't process the event loop during a drag, so if we're dragging,
// grab the scroll widget and make it paint synchronously. This is
// sorta slow (having to paint the entire tree), but it works.
if ( mDragSession ) {
nsCOMPtr<nsIWidget> scrollWidget;
mScrollbar->GetWindow(mPresContext, getter_AddRefs(scrollWidget));
if ( scrollWidget )
scrollWidget->Invalidate(PR_TRUE);
}
#endif
return NS_OK; return NS_OK;
} }
@ -2782,15 +2917,8 @@ nsOutlinerBodyFrame::ScrollInternal(PRInt32 aRow)
PRInt32 absDelta = delta > 0 ? delta : -delta; PRInt32 absDelta = delta > 0 ? delta : -delta;
if (hasBackground || absDelta*mRowHeight >= mRect.height) if (hasBackground || absDelta*mRowHeight >= mRect.height)
Invalidate(); Invalidate();
else if (mOutlinerWidget) { else if (mOutlinerWidget)
mOutlinerWidget->Scroll(0, -delta*rowHeightAsPixels, nsnull); mOutlinerWidget->Scroll(0, -delta*rowHeightAsPixels, nsnull);
#if defined(XP_MAC) || defined(XP_MACOSX)
// mac can't process the event loop during a drag, so if we're dragging,
// update outliner widget synchronously.
if (mDragSession)
mOutlinerWidget->Update();
#endif
}
return NS_OK; return NS_OK;
} }
@ -2987,7 +3115,7 @@ nsOutlinerBodyFrame::OnDragExit(nsIDOMEvent* aEvent)
{ {
if (mDropAllowed) { if (mDropAllowed) {
mDropAllowed = PR_FALSE; mDropAllowed = PR_FALSE;
InvalidatePrimaryCell(mDropRow); InvalidatePrimaryCell(mDropRow + (mDropOrient == nsIOutlinerView::inDropAfter ? 1 : 0));
} }
else else
mDropAllowed = PR_FALSE; mDropAllowed = PR_FALSE;
@ -3012,23 +3140,31 @@ nsOutlinerBodyFrame::OnDragExit(nsIDOMEvent* aEvent)
NS_IMETHODIMP NS_IMETHODIMP
nsOutlinerBodyFrame::OnDragOver(nsIDOMEvent* aEvent) nsOutlinerBodyFrame::OnDragOver(nsIDOMEvent* aEvent)
{ {
// while we're here, handle tracking of scrolling during a drag. if (! mView)
PRBool scrollUp = PR_FALSE;
if (IsInDragScrollRegion(aEvent, &scrollUp)) {
if (mDropAllowed) {
// invalidate primary cell at old location.
mDropAllowed = PR_FALSE;
InvalidatePrimaryCell(mDropRow);
}
ScrollByLines(scrollUp ? -1 : 1);
return NS_OK; return NS_OK;
}
// compute the row mouse is over and the above/below/on state. Below we'll use this // compute the row mouse is over and the above/below/on state. Below we'll use this
// to see if anything changed. // to see if anything changed.
PRInt32 newRow = -1; PRInt32 newRow = -1;
PRInt16 newOrient = -1; PRInt16 newOrient = -1;
ComputeDropPosition(aEvent, &newRow, &newOrient); ComputeDropPosition(aEvent, &newRow, &newOrient);
// While we're here, handle tracking of scrolling during a drag.
PRInt32 rowCount;
mView->GetRowCount(&rowCount);
// Don't scroll if we are already at the top or bottom of the view.
if (newRow > 0 && newRow < rowCount - 1) {
PRBool scrollUp = PR_FALSE;
if (IsInDragScrollRegion(aEvent, &scrollUp)) {
if (mDropAllowed) {
// invalidate primary cell at old location.
mDropAllowed = PR_FALSE;
InvalidatePrimaryCell(mDropRow + (mDropOrient == nsIOutlinerView::inDropAfter ? 1 : 0));
}
ScrollByLines(scrollUp ? -1 : 1);
return NS_OK;
}
}
// if changed from last time, invalidate primary cell at the old location and if allowed, // if changed from last time, invalidate primary cell at the old location and if allowed,
// invalidate primary cell at the new location. If nothing changed, just bail. // invalidate primary cell at the new location. If nothing changed, just bail.
@ -3036,7 +3172,7 @@ nsOutlinerBodyFrame::OnDragOver(nsIDOMEvent* aEvent)
// Invalidate row at the old location. // Invalidate row at the old location.
if (mDropAllowed) { if (mDropAllowed) {
mDropAllowed = PR_FALSE; mDropAllowed = PR_FALSE;
InvalidatePrimaryCell(mDropRow); InvalidatePrimaryCell(mDropRow + (mDropOrient == nsIOutlinerView::inDropAfter ? 1 : 0));
} }
if (mOpenTimer) { if (mOpenTimer) {
@ -3077,7 +3213,7 @@ nsOutlinerBodyFrame::OnDragOver(nsIDOMEvent* aEvent)
if (canDropAtNewLocation) { if (canDropAtNewLocation) {
// Invalidate row at the new location/ // Invalidate row at the new location/
mDropAllowed = canDropAtNewLocation; mDropAllowed = canDropAtNewLocation;
InvalidatePrimaryCell(mDropRow); InvalidatePrimaryCell(mDropRow + (mDropOrient == nsIOutlinerView::inDropAfter ? 1 : 0));
} }
} }
} }

Просмотреть файл

@ -316,6 +316,13 @@ public:
const nsRect& aDirtyRect, const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer); nsFramePaintLayer aWhichLayer);
// This method paints a drop feedback in a given row of the outliner.
NS_IMETHOD PaintDropFeedback(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer,
PRUint32 aFlags = 0);
// This method is called with a specific style context and rect to // This method is called with a specific style context and rect to
// paint the background rect as if it were a full-blown frame. // paint the background rect as if it were a full-blown frame.
NS_IMETHOD PaintBackgroundLayer(nsIStyleContext* aStyleContext, nsIPresContext* aPresContext, NS_IMETHOD PaintBackgroundLayer(nsIStyleContext* aStyleContext, nsIPresContext* aPresContext,

Просмотреть файл

@ -71,32 +71,6 @@ outlinerchildren:-moz-outliner-cell-text(selected, focus) {
color: HighlightText; color: HighlightText;
} }
outlinerchildren:-moz-outliner-cell-text(primary) {
border-top: 1px solid transparent;
border-bottom: 1px solid transparent;
}
outlinerchildren:-moz-outliner-cell-text(primary, drop) {
background-color: Highlight;
color: HighlightText;
}
outlinerchildren:-moz-outliner-cell-text(primary, dropBefore) {
border-top: 1px solid Highlight;
}
outlinerchildren:-moz-outliner-cell-text(selected, primary, dropBefore) {
border-top: 1px solid HighlightText;
}
outlinerchildren:-moz-outliner-cell-text(primary, dropAfter) {
border-bottom: 1px solid Highlight;
}
outlinerchildren:-moz-outliner-cell-text(selected, primary, dropAfter) {
border-bottom: 1px solid HighlightText;
}
/* ::::: lines connecting cells ::::: */ /* ::::: lines connecting cells ::::: */
@ -108,11 +82,34 @@ outlinerchildren:-moz-outliner-line {
border: 1px dotted grey; border: 1px dotted grey;
} }
/* ::::: outliner separator ::::: */
outlinerchildren:-moz-outliner-separator { outlinerchildren:-moz-outliner-separator {
border-top: 1px solid ThreeDShadow; border-top: 1px solid ThreeDShadow;
border-bottom: 1px solid ThreeDHighlight; border-bottom: 1px solid ThreeDHighlight;
} }
/* ::::: drop feedback ::::: */
outlinerchildren:-moz-outliner-cell-text(dropOn) {
background-color: Highlight;
color: HighlightText;
}
outlinerchildren:-moz-outliner-drop-feedback {
background-color: Highlight;
width: 50px;
height: 2px;
margin-left: 5px;
}
outlinerchildren:-moz-outliner-drop-feedback(selected) {
background-color: HighlightText;
}
/* ::::: outliner columns ::::: */ /* ::::: outliner columns ::::: */
outlinercol, outlinercol,

Просмотреть файл

@ -77,32 +77,6 @@ outlinerchildren:-moz-outliner-cell-text(selected, focus) {
color: HighlightText; color: HighlightText;
} }
outlinerchildren:-moz-outliner-cell-text(primary) {
border-top: 1px solid transparent;
border-bottom: 1px solid transparent;
}
outlinerchildren:-moz-outliner-cell-text(primary, drop) {
background-color: Highlight;
color: HighlightText;
}
outlinerchildren:-moz-outliner-cell-text(primary, dropBefore) {
border-top: 1px solid Highlight;
}
outlinerchildren:-moz-outliner-cell-text(selected, primary, dropBefore) {
border-top: 1px solid HighlightText;
}
outlinerchildren:-moz-outliner-cell-text(primary, dropAfter) {
border-bottom: 1px solid Highlight;
}
outlinerchildren:-moz-outliner-cell-text(selected, primary, dropAfter) {
border-bottom: 1px solid HighlightText;
}
/* ::::: lines connecting cells ::::: */ /* ::::: lines connecting cells ::::: */
@ -114,11 +88,33 @@ outlinerchildren:-moz-outliner-line(selected, focus) {
border: 1px dotted HighlightText; border: 1px dotted HighlightText;
} }
/* ::::: outliner separator ::::: */
outlinerchildren:-moz-outliner-separator { outlinerchildren:-moz-outliner-separator {
border-top: 1px solid ThreeDShadow; border-top: 1px solid ThreeDShadow;
border-bottom: 1px solid ThreeDHighlight; border-bottom: 1px solid ThreeDHighlight;
} }
/* ::::: drop feedback ::::: */
outlinerchildren:-moz-outliner-cell-text(dropOn) {
background-color: Highlight;
color: HighlightText;
}
outlinerchildren:-moz-outliner-drop-feedback {
background-color: Highlight;
width: 50px;
height: 2px;
margin-left: 5px;
}
outlinerchildren:-moz-outliner-drop-feedback(selected) {
background-color: HighlightText;
}
/* ::::: outliner columns ::::: */ /* ::::: outliner columns ::::: */
outlinercol, outlinercol,

Просмотреть файл

@ -96,32 +96,6 @@ outlinerchildren:-moz-outliner-cell-text(selected, focus) {
color: #FFFFFF; color: #FFFFFF;
} }
outlinerchildren:-moz-outliner-cell-text(primary) {
border-top: 1px solid transparent;
border-bottom: 1px solid transparent;
}
outlinerchildren:-moz-outliner-cell-text(primary, drop) {
background-color: #424F63;
color: #FFFFFF;
}
outlinerchildren:-moz-outliner-cell-text(primary, dropBefore) {
border-top: 1px solid #424F63;
}
outlinerchildren:-moz-outliner-cell-text(selected, primary, dropBefore) {
border-top: 1px solid #FFFFFF;
}
outlinerchildren:-moz-outliner-cell-text(primary, dropAfter) {
border-bottom: 1px solid #424F63;
}
outlinerchildren:-moz-outliner-cell-text(selected, primary, dropAfter) {
border-bottom: 1px solid #FFFFFF;
}
/* ::::: lines connecting cells ::::: */ /* ::::: lines connecting cells ::::: */
@ -133,11 +107,34 @@ outlinerchildren:-moz-outliner-line(selected, focus) {
border: 1px dotted #FFFFFF; border: 1px dotted #FFFFFF;
} }
/* ::::: outliner separator ::::: */
outlinerchildren:-moz-outliner-separator { outlinerchildren:-moz-outliner-separator {
border-top: 1px solid #7A8490; border-top: 1px solid #7A8490;
border-bottom: 1px solid #FEFEFE; border-bottom: 1px solid #FEFEFE;
} }
/* ::::: drop feedback ::::: */
outlinerchildren:-moz-outliner-cell-text(dropOn) {
background-color: #424F63;
color: #FFFFFF;
}
outlinerchildren:-moz-outliner-drop-feedback {
background-color: #424F63;
width: 50px;
height: 2px;
margin-left: 5px;
}
outlinerchildren:-moz-outliner-drop-feedback(selected) {
background-color: #FFFFFF;
}
/* ::::: outliner columns ::::: */ /* ::::: outliner columns ::::: */
outlinercol, outlinercol,