mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 22:55:23 +00:00
Bug 956162 - Implement @flip="none" for popups to allow them to appear off-screen without flipping or resizing. r=Enn
--HG-- extra : rebase_source : f5ddca505eb8a3b234718df1ae01c9a49a02a361
This commit is contained in:
parent
4a2291060e
commit
ea7f5d5b8f
@ -217,6 +217,7 @@
|
|||||||
hidden="true"
|
hidden="true"
|
||||||
noautofocus="true"
|
noautofocus="true"
|
||||||
noautohide="true"
|
noautohide="true"
|
||||||
|
flip="none"
|
||||||
consumeoutsideclicks="false">
|
consumeoutsideclicks="false">
|
||||||
<box id="UITourHighlight"></box>
|
<box id="UITourHighlight"></box>
|
||||||
</panel>
|
</panel>
|
||||||
|
@ -87,7 +87,7 @@ nsMenuPopupFrame::nsMenuPopupFrame(nsIPresShell* aShell, nsStyleContext* aContex
|
|||||||
mPopupAnchor(POPUPALIGNMENT_NONE),
|
mPopupAnchor(POPUPALIGNMENT_NONE),
|
||||||
mPosition(POPUPPOSITION_UNKNOWN),
|
mPosition(POPUPPOSITION_UNKNOWN),
|
||||||
mConsumeRollupEvent(nsIPopupBoxObject::ROLLUP_DEFAULT),
|
mConsumeRollupEvent(nsIPopupBoxObject::ROLLUP_DEFAULT),
|
||||||
mFlipBoth(false),
|
mFlip(FlipType_Default),
|
||||||
mIsOpenChanged(false),
|
mIsOpenChanged(false),
|
||||||
mIsContextMenu(false),
|
mIsContextMenu(false),
|
||||||
mAdjustOffsetForContextMenu(false),
|
mAdjustOffsetForContextMenu(false),
|
||||||
@ -581,8 +581,13 @@ nsMenuPopupFrame::InitializePopup(nsIContent* aAnchorContent,
|
|||||||
position.Assign(aPosition);
|
position.Assign(aPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
mFlipBoth = flip.EqualsLiteral("both");
|
if (flip.EqualsLiteral("none")) {
|
||||||
mSlide = flip.EqualsLiteral("slide");
|
mFlip = FlipType_None;
|
||||||
|
} else if (flip.EqualsLiteral("both")) {
|
||||||
|
mFlip = FlipType_Both;
|
||||||
|
} else if (flip.EqualsLiteral("slide")) {
|
||||||
|
mFlip = FlipType_Slide;
|
||||||
|
}
|
||||||
|
|
||||||
position.CompressWhitespace();
|
position.CompressWhitespace();
|
||||||
int32_t spaceIdx = position.FindChar(' ');
|
int32_t spaceIdx = position.FindChar(' ');
|
||||||
@ -685,8 +690,7 @@ nsMenuPopupFrame::InitializePopupAtScreen(nsIContent* aTriggerContent,
|
|||||||
mTriggerContent = aTriggerContent;
|
mTriggerContent = aTriggerContent;
|
||||||
mScreenXPos = aXPos;
|
mScreenXPos = aXPos;
|
||||||
mScreenYPos = aYPos;
|
mScreenYPos = aYPos;
|
||||||
mFlipBoth = false;
|
mFlip = FlipType_Default;
|
||||||
mSlide = false;
|
|
||||||
mPopupAnchor = POPUPALIGNMENT_NONE;
|
mPopupAnchor = POPUPALIGNMENT_NONE;
|
||||||
mPopupAlignment = POPUPALIGNMENT_NONE;
|
mPopupAlignment = POPUPALIGNMENT_NONE;
|
||||||
mIsContextMenu = aIsContextMenu;
|
mIsContextMenu = aIsContextMenu;
|
||||||
@ -703,8 +707,7 @@ nsMenuPopupFrame::InitializePopupWithAnchorAlign(nsIContent* aAnchorContent,
|
|||||||
|
|
||||||
mPopupState = ePopupShowing;
|
mPopupState = ePopupShowing;
|
||||||
mAdjustOffsetForContextMenu = false;
|
mAdjustOffsetForContextMenu = false;
|
||||||
mFlipBoth = false;
|
mFlip = FlipType_Default;
|
||||||
mSlide = false;
|
|
||||||
|
|
||||||
// this popup opening function is provided for backwards compatibility
|
// this popup opening function is provided for backwards compatibility
|
||||||
// only. It accepts either coordinates or an anchor and alignment value
|
// only. It accepts either coordinates or an anchor and alignment value
|
||||||
@ -981,7 +984,7 @@ nsMenuPopupFrame::AdjustPositionForAnchorAlign(nsRect& anchorRect,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
FlipStyle anchorEdge = mFlipBoth ? FlipStyle_Inside : FlipStyle_None;
|
FlipStyle anchorEdge = mFlip == FlipType_Both ? FlipStyle_Inside : FlipStyle_None;
|
||||||
aHFlip = (popupAnchor == -popupAlign) ? FlipStyle_Outside : anchorEdge;
|
aHFlip = (popupAnchor == -popupAlign) ? FlipStyle_Outside : anchorEdge;
|
||||||
if (((popupAnchor > 0) == (popupAlign > 0)) ||
|
if (((popupAnchor > 0) == (popupAlign > 0)) ||
|
||||||
(popupAnchor == POPUPALIGNMENT_TOPLEFT && popupAlign == POPUPALIGNMENT_TOPLEFT))
|
(popupAnchor == POPUPALIGNMENT_TOPLEFT && popupAlign == POPUPALIGNMENT_TOPLEFT))
|
||||||
@ -1271,9 +1274,9 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove)
|
|||||||
vFlip = FlipStyle_Outside;
|
vFlip = FlipStyle_Outside;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a panel is being moved, don't constrain or flip it. But always do this for
|
// If a panel is being moved or has flip="none", don't constrain or flip it. But always do this for
|
||||||
// content shells, so that the popup doesn't extend outside the containing frame.
|
// content shells, so that the popup doesn't extend outside the containing frame.
|
||||||
if (mInContentShell || !aIsMove || mPopupType != ePopupTypePanel) {
|
if (mInContentShell || (mFlip != FlipType_None && (!aIsMove || mPopupType != ePopupTypePanel))) {
|
||||||
nsRect screenRect = GetConstraintRect(anchorRect, rootScreenRect);
|
nsRect screenRect = GetConstraintRect(anchorRect, rootScreenRect);
|
||||||
|
|
||||||
// ensure that anchorRect is on screen
|
// ensure that anchorRect is on screen
|
||||||
@ -1303,7 +1306,7 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove)
|
|||||||
// but we can only slide on one axis - the other axis must be "flipped or
|
// but we can only slide on one axis - the other axis must be "flipped or
|
||||||
// resized" as normal.
|
// resized" as normal.
|
||||||
bool slideHorizontal = false, slideVertical = false;
|
bool slideHorizontal = false, slideVertical = false;
|
||||||
if (mSlide) {
|
if (mFlip == FlipType_Slide) {
|
||||||
int8_t position = GetAlignmentPosition();
|
int8_t position = GetAlignmentPosition();
|
||||||
slideHorizontal = position >= POPUPPOSITION_BEFORESTART &&
|
slideHorizontal = position >= POPUPPOSITION_BEFORESTART &&
|
||||||
position <= POPUPPOSITION_AFTEREND;
|
position <= POPUPPOSITION_AFTEREND;
|
||||||
|
@ -65,6 +65,14 @@ enum FlipStyle {
|
|||||||
FlipStyle_Inside = 2
|
FlipStyle_Inside = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Values for the flip attribute
|
||||||
|
enum FlipType {
|
||||||
|
FlipType_Default = 0,
|
||||||
|
FlipType_None = 1, // don't try to flip or translate to stay onscreen
|
||||||
|
FlipType_Both = 2, // flip in both directions
|
||||||
|
FlipType_Slide = 3 // allow the arrow to "slide" instead of resizing
|
||||||
|
};
|
||||||
|
|
||||||
// values are selected so that the direction can be flipped just by
|
// values are selected so that the direction can be flipped just by
|
||||||
// changing the sign
|
// changing the sign
|
||||||
#define POPUPALIGNMENT_NONE 0
|
#define POPUPALIGNMENT_NONE 0
|
||||||
@ -459,8 +467,7 @@ protected:
|
|||||||
|
|
||||||
// One of nsIPopupBoxObject::ROLLUP_DEFAULT/ROLLUP_CONSUME/ROLLUP_NO_CONSUME
|
// One of nsIPopupBoxObject::ROLLUP_DEFAULT/ROLLUP_CONSUME/ROLLUP_NO_CONSUME
|
||||||
int8_t mConsumeRollupEvent;
|
int8_t mConsumeRollupEvent;
|
||||||
bool mFlipBoth; // flip in both directions
|
FlipType mFlip; // Whether to flip
|
||||||
bool mSlide; // allow the arrow to "slide" instead of resizing
|
|
||||||
|
|
||||||
bool mIsOpenChanged; // true if the open state changed since the last layout
|
bool mIsOpenChanged; // true if the open state changed since the last layout
|
||||||
bool mIsContextMenu; // true for context menus
|
bool mIsContextMenu; // true for context menus
|
||||||
|
Loading…
Reference in New Issue
Block a user