зеркало из https://github.com/mozilla/pjs.git
Bug 606343, part 1, add centering position types for panels, r=neil, a=blocking
This commit is contained in:
Родитель
5214b9dcf8
Коммит
f86b23f261
|
@ -541,6 +541,14 @@ nsMenuPopupFrame::InitPositionFromAnchorAlign(const nsAString& aAnchor,
|
|||
mPopupAnchor = POPUPALIGNMENT_BOTTOMLEFT;
|
||||
else if (aAnchor.EqualsLiteral("bottomright"))
|
||||
mPopupAnchor = POPUPALIGNMENT_BOTTOMRIGHT;
|
||||
else if (aAnchor.EqualsLiteral("leftcenter"))
|
||||
mPopupAnchor = POPUPALIGNMENT_LEFTCENTER;
|
||||
else if (aAnchor.EqualsLiteral("rightcenter"))
|
||||
mPopupAnchor = POPUPALIGNMENT_RIGHTCENTER;
|
||||
else if (aAnchor.EqualsLiteral("topcenter"))
|
||||
mPopupAnchor = POPUPALIGNMENT_TOPCENTER;
|
||||
else if (aAnchor.EqualsLiteral("bottomcenter"))
|
||||
mPopupAnchor = POPUPALIGNMENT_BOTTOMCENTER;
|
||||
else
|
||||
mPopupAnchor = POPUPALIGNMENT_NONE;
|
||||
|
||||
|
@ -596,7 +604,14 @@ nsMenuPopupFrame::InitializePopup(nsIContent* aAnchorContent,
|
|||
|
||||
mFlipBoth = flip.EqualsLiteral("both");
|
||||
|
||||
if (position.EqualsLiteral("before_start")) {
|
||||
position.CompressWhitespace();
|
||||
PRInt32 spaceIdx = position.FindChar(' ');
|
||||
// if there is a space in the position, assume it is the anchor and
|
||||
// alignment as two separate tokens.
|
||||
if (spaceIdx >= 0) {
|
||||
InitPositionFromAnchorAlign(Substring(position, 0, spaceIdx), Substring(position, spaceIdx + 1));
|
||||
}
|
||||
else if (position.EqualsLiteral("before_start")) {
|
||||
mPopupAnchor = POPUPALIGNMENT_TOPLEFT;
|
||||
mPopupAlignment = POPUPALIGNMENT_BOTTOMLEFT;
|
||||
}
|
||||
|
@ -879,20 +894,43 @@ nsMenuPopupFrame::GetRootViewForPopup(nsIFrame* aStartFrame)
|
|||
}
|
||||
|
||||
nsPoint
|
||||
nsMenuPopupFrame::AdjustPositionForAnchorAlign(const nsRect& anchorRect,
|
||||
nsMenuPopupFrame::AdjustPositionForAnchorAlign(nsRect& anchorRect,
|
||||
FlipStyle& aHFlip, FlipStyle& aVFlip)
|
||||
{
|
||||
// flip the anchor and alignment for right-to-left
|
||||
PRInt8 popupAnchor(mPopupAnchor);
|
||||
PRInt8 popupAlign(mPopupAlignment);
|
||||
if (GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) {
|
||||
popupAnchor = -popupAnchor;
|
||||
// no need to flip the centered anchor types
|
||||
if (popupAnchor < POPUPALIGNMENT_LEFTCENTER) {
|
||||
popupAnchor = -popupAnchor;
|
||||
}
|
||||
popupAlign = -popupAlign;
|
||||
}
|
||||
|
||||
// first, determine at which corner of the anchor the popup should appear
|
||||
nsPoint pnt;
|
||||
switch (popupAnchor) {
|
||||
case POPUPALIGNMENT_LEFTCENTER:
|
||||
pnt = nsPoint(anchorRect.x, anchorRect.y + anchorRect.height / 2);
|
||||
anchorRect.y = pnt.y;
|
||||
anchorRect.height = 0;
|
||||
break;
|
||||
case POPUPALIGNMENT_RIGHTCENTER:
|
||||
pnt = nsPoint(anchorRect.XMost(), anchorRect.y + anchorRect.height / 2);
|
||||
anchorRect.y = pnt.y;
|
||||
anchorRect.height = 0;
|
||||
break;
|
||||
case POPUPALIGNMENT_TOPCENTER:
|
||||
pnt = nsPoint(anchorRect.x + anchorRect.width / 2, anchorRect.y);
|
||||
anchorRect.x = pnt.x;
|
||||
anchorRect.width = 0;
|
||||
break;
|
||||
case POPUPALIGNMENT_BOTTOMCENTER:
|
||||
pnt = nsPoint(anchorRect.x + anchorRect.width / 2, anchorRect.YMost());
|
||||
anchorRect.x = pnt.x;
|
||||
anchorRect.width = 0;
|
||||
break;
|
||||
case POPUPALIGNMENT_TOPRIGHT:
|
||||
pnt = anchorRect.TopRight();
|
||||
break;
|
||||
|
@ -944,13 +982,26 @@ nsMenuPopupFrame::AdjustPositionForAnchorAlign(const nsRect& anchorRect,
|
|||
// however horizontally, we want to to use the inside edges so the popup
|
||||
// still appears underneath the anchor menu instead of floating off the
|
||||
// side of the menu.
|
||||
FlipStyle anchorEdge = mFlipBoth ? FlipStyle_Inside: FlipStyle_None;
|
||||
aHFlip = (popupAnchor == -popupAlign) ? FlipStyle_Outside : anchorEdge;
|
||||
if (((popupAnchor > 0) == (popupAlign > 0)) ||
|
||||
(popupAnchor == POPUPALIGNMENT_TOPLEFT && popupAlign == POPUPALIGNMENT_TOPLEFT))
|
||||
aVFlip = FlipStyle_Outside;
|
||||
else
|
||||
aVFlip = anchorEdge;
|
||||
if (popupAnchor >= POPUPALIGNMENT_LEFTCENTER) {
|
||||
if (popupAnchor == POPUPALIGNMENT_LEFTCENTER ||
|
||||
popupAnchor == POPUPALIGNMENT_RIGHTCENTER) {
|
||||
aHFlip = FlipStyle_Outside;
|
||||
aVFlip = FlipStyle_Inside;
|
||||
}
|
||||
else {
|
||||
aHFlip = FlipStyle_Inside;
|
||||
aVFlip = FlipStyle_Outside;
|
||||
}
|
||||
}
|
||||
else {
|
||||
FlipStyle anchorEdge = mFlipBoth ? FlipStyle_Inside : FlipStyle_None;
|
||||
aHFlip = (popupAnchor == -popupAlign) ? FlipStyle_Outside : anchorEdge;
|
||||
if (((popupAnchor > 0) == (popupAlign > 0)) ||
|
||||
(popupAnchor == POPUPALIGNMENT_TOPLEFT && popupAlign == POPUPALIGNMENT_TOPLEFT))
|
||||
aVFlip = FlipStyle_Outside;
|
||||
else
|
||||
aVFlip = anchorEdge;
|
||||
}
|
||||
|
||||
return pnt;
|
||||
}
|
||||
|
|
|
@ -109,6 +109,11 @@ enum FlipStyle {
|
|||
#define POPUPALIGNMENT_BOTTOMLEFT 2
|
||||
#define POPUPALIGNMENT_BOTTOMRIGHT -2
|
||||
|
||||
#define POPUPALIGNMENT_LEFTCENTER 16
|
||||
#define POPUPALIGNMENT_RIGHTCENTER 17
|
||||
#define POPUPALIGNMENT_TOPCENTER 18
|
||||
#define POPUPALIGNMENT_BOTTOMCENTER 19
|
||||
|
||||
#define INC_TYP_INTERVAL 1000 // 1s. If the interval between two keypresses is shorter than this,
|
||||
// treat as a continue typing
|
||||
// XXX, kyle.yuan@sun.com, there are 4 definitions for the same purpose:
|
||||
|
@ -354,7 +359,7 @@ protected:
|
|||
// return the position where the popup should be, when it should be
|
||||
// anchored at anchorRect. aHFlip and aVFlip will be set if the popup may be
|
||||
// flipped in that direction if there is not enough space available.
|
||||
nsPoint AdjustPositionForAnchorAlign(const nsRect& anchorRect,
|
||||
nsPoint AdjustPositionForAnchorAlign(nsRect& anchorRect,
|
||||
FlipStyle& aHFlip, FlipStyle& aVFlip);
|
||||
|
||||
// check if the popup will fit into the available space and resize it. This
|
||||
|
|
|
@ -326,6 +326,33 @@ function compareEdge(anchor, popup, edge, offsetX, offsetY, testname)
|
|||
(Math.round(popuprect.bottom) - Math.round(popuprect.top)),
|
||||
testname + " size");
|
||||
|
||||
var spaceIdx = edge.indexOf(" ");
|
||||
if (spaceIdx > 0) {
|
||||
let cornerX, cornerY;
|
||||
let [anchor, align] = edge.split(" ");
|
||||
switch (anchor) {
|
||||
case "topleft": cornerX = anchorrect.left; cornerY = anchorrect.top; break;
|
||||
case "topcenter": cornerX = anchorrect.left + anchorrect.width / 2; cornerY = anchorrect.top; break;
|
||||
case "topright": cornerX = anchorrect.right; cornerY = anchorrect.top; break;
|
||||
case "leftcenter": cornerX = anchorrect.left; cornerY = anchorrect.top + anchorrect.height / 2; break;
|
||||
case "rightcenter": cornerX = anchorrect.right; cornerY = anchorrect.top + anchorrect.height / 2; break;
|
||||
case "bottomleft": cornerX = anchorrect.left; cornerY = anchorrect.bottom; break;
|
||||
case "bottomcenter": cornerX = anchorrect.left + anchorrect.width / 2; cornerY = anchorrect.bottom; break;
|
||||
case "bottomright": cornerX = anchorrect.right; cornerY = anchorrect.bottom; break;
|
||||
}
|
||||
|
||||
switch (align) {
|
||||
case "topleft": cornerX += offsetX; cornerY += offsetY; break;
|
||||
case "topright": cornerX += -popuprect.width + offsetX; cornerY += offsetY; break;
|
||||
case "bottomleft": cornerX += offsetX; cornerY += -popuprect.height + offsetY; break;
|
||||
case "bottomright": cornerX += -popuprect.width + offsetX; cornerY += -popuprect.height + offsetY; break;
|
||||
}
|
||||
|
||||
is(Math.round(popuprect.left), Math.round(cornerX), testname + " x position");
|
||||
is(Math.round(popuprect.top), Math.round(cornerY), testname + " y position");
|
||||
return;
|
||||
}
|
||||
|
||||
if (edge == "after_pointer") {
|
||||
is(Math.round(popuprect.left), Math.round(anchorrect.left) + offsetX, testname + " x position");
|
||||
is(Math.round(popuprect.top), Math.round(anchorrect.top) + offsetY + 21, testname + " y position");
|
||||
|
|
|
@ -170,7 +170,11 @@ var popupTests = [
|
|||
events: [ "popupshowing thepopup", "popupshown thepopup" ],
|
||||
autohide: "thepopup",
|
||||
steps: ["before_start", "before_end", "after_start", "after_end",
|
||||
"start_before", "start_after", "end_before", "end_after", "after_pointer", "overlap"],
|
||||
"start_before", "start_after", "end_before", "end_after", "after_pointer", "overlap",
|
||||
"topleft topleft", "topcenter topleft", "topright topleft",
|
||||
"leftcenter topright", "rightcenter topright",
|
||||
"bottomleft bottomleft", "bottomcenter bottomleft", "bottomright bottomleft",
|
||||
"topleft bottomright", "bottomcenter bottomright", "rightcenter topright"],
|
||||
test: function(testname, step) {
|
||||
gExpectedTriggerNode = "notset";
|
||||
gMenuPopup.openPopup(gTrigger, step, 0, 0, false, false);
|
||||
|
@ -190,16 +194,22 @@ var popupTests = [
|
|||
events: [ "popupshowing thepopup", "popupshown thepopup" ],
|
||||
autohide: "thepopup",
|
||||
steps: ["before_start", "before_end", "after_start", "after_end",
|
||||
"start_before", "start_after", "end_before", "end_after", "after_pointer", "overlap"],
|
||||
"start_before", "start_after", "end_before", "end_after", "after_pointer", "overlap",
|
||||
"topleft topleft", "topcenter topleft", "topright topleft",
|
||||
"leftcenter topright", "rightcenter topright",
|
||||
"bottomleft bottomleft", "bottomcenter bottomleft", "bottomright bottomleft",
|
||||
"topleft bottomright", "bottomcenter bottomright", "rightcenter topright"],
|
||||
test: function(testname, step) {
|
||||
gMenuPopup.setAttribute("style", "margin: 10px;");
|
||||
gMenuPopup.openPopup(gTrigger, step, 0, 0, false, false);
|
||||
},
|
||||
result: function(testname, step) {
|
||||
var rightmod = step == "before_end" || step == "after_end" ||
|
||||
step == "start_before" || step == "start_after";
|
||||
step == "start_before" || step == "start_after" ||
|
||||
step.match(/topright$/) || step.match(/bottomright$/);
|
||||
var bottommod = step == "before_start" || step == "before_end" ||
|
||||
step == "start_after" || step == "end_after";
|
||||
step == "start_after" || step == "end_after" ||
|
||||
step.match(/bottomleft$/) || step.match(/bottomright$/);
|
||||
compareEdge(gTrigger, gMenuPopup, step, rightmod ? -10 : 10, bottommod ? -10 : 10, testname);
|
||||
gMenuPopup.removeAttribute("style");
|
||||
}
|
||||
|
@ -231,7 +241,8 @@ var popupTests = [
|
|||
events: [ "popupshowing thepopup", "popupshown thepopup" ],
|
||||
autohide: "thepopup",
|
||||
steps: ["before_start", "before_end", "after_start", "after_end",
|
||||
"start_before", "start_after", "end_before", "end_after", "after_pointer", "overlap"],
|
||||
"start_before", "start_after", "end_before", "end_after", "after_pointer", "overlap",
|
||||
"topcenter topleft", "topright bottomright", "leftcenter topright"],
|
||||
test: function(testname, step) {
|
||||
gMenuPopup.setAttribute("position", step);
|
||||
gMenuPopup.openPopup(gTrigger, "", 0, 0, false, false);
|
||||
|
|
Загрузка…
Ссылка в новой задаче