mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 372047, support reverse direction scales, r=neil,josh
This commit is contained in:
parent
14eecdeff4
commit
c04abaf92b
@ -398,21 +398,23 @@ nsSliderFrame::DoLayout(nsBoxLayoutState& aState)
|
||||
if (float(maxpos) != 0)
|
||||
mRatio = float(ourmaxpos) / float(maxpos);
|
||||
|
||||
nscoord curpos = (curpospx - minpospx) * onePixel;
|
||||
// in reverse mode, curpos is reversed such that lower values are to the
|
||||
// right or bottom and increase leftwards or upwards. In this case, use the
|
||||
// offset from the end instead of the beginning.
|
||||
PRBool reverse = mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::dir,
|
||||
nsGkAtoms::reverse, eCaseMatters);
|
||||
nscoord pos = reverse ? (maxpospx - curpospx) : (curpospx - minpospx);
|
||||
|
||||
// set the thumbs y coord to be the current pos * the ratio.
|
||||
nscoord pos = nscoord(float(curpos)*mRatio);
|
||||
// set the thumb's coord to be the current pos * the ratio.
|
||||
nsRect thumbRect(clientRect.x, clientRect.y, thumbSize.width, thumbSize.height);
|
||||
|
||||
if (isHorizontal)
|
||||
thumbRect.x += pos;
|
||||
thumbRect.x += nscoord(float(pos * onePixel) * mRatio);
|
||||
else
|
||||
thumbRect.y += pos;
|
||||
thumbRect.y += nscoord(float(pos * onePixel) * mRatio);
|
||||
|
||||
nsRect oldThumbRect(thumbBox->GetRect());
|
||||
LayoutChildAt(aState, thumbBox, thumbRect);
|
||||
|
||||
|
||||
SyncLayout(aState);
|
||||
|
||||
#ifdef DEBUG_SLIDER
|
||||
@ -494,11 +496,10 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
if (isMouseOutsideThumb)
|
||||
{
|
||||
// XXX see bug 81586
|
||||
SetCurrentPosition(scrollbar, thumbFrame, (int) (mThumbStart / onePixel / mRatio), PR_FALSE);
|
||||
SetCurrentPosition(scrollbar, (int) (mThumbStart / onePixel / mRatio), PR_FALSE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// convert to pixels
|
||||
nscoord pospx = pos/onePixel;
|
||||
|
||||
@ -514,8 +515,7 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
}
|
||||
|
||||
// set it
|
||||
SetCurrentPosition(scrollbar, thumbFrame, pospx, PR_FALSE);
|
||||
|
||||
SetCurrentPosition(scrollbar, pospx, PR_FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -566,12 +566,11 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
thumbLength /= onePixel;
|
||||
pospx -= (thumbLength/2);
|
||||
|
||||
|
||||
// convert to our internal coordinate system
|
||||
pospx = nscoord(pospx/mRatio);
|
||||
|
||||
// set it
|
||||
SetCurrentPosition(scrollbar, thumbFrame, pospx, PR_FALSE);
|
||||
SetCurrentPosition(scrollbar, pospx, PR_FALSE);
|
||||
|
||||
DragThumb(PR_TRUE);
|
||||
|
||||
@ -610,7 +609,7 @@ nsSliderFrame::GetScrollbar()
|
||||
}
|
||||
|
||||
void
|
||||
nsSliderFrame::PageUpDown(nsIFrame* aThumbFrame, nscoord change)
|
||||
nsSliderFrame::PageUpDown(nscoord change)
|
||||
{
|
||||
// on a page up or down get our page increment. We get this by getting the scrollbar we are in and
|
||||
// asking it for the current position and the page increment. If we are not in a scrollbar we will
|
||||
@ -619,13 +618,26 @@ nsSliderFrame::PageUpDown(nsIFrame* aThumbFrame, nscoord change)
|
||||
nsCOMPtr<nsIContent> scrollbar;
|
||||
scrollbar = GetContentOfBox(scrollbarBox);
|
||||
|
||||
if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::dir,
|
||||
nsGkAtoms::reverse, eCaseMatters))
|
||||
change = -change;
|
||||
|
||||
if (mScrollbarListener)
|
||||
mScrollbarListener->PagedUpDown(); // Let the listener decide our increment.
|
||||
|
||||
nscoord pageIncrement = GetPageIncrement(scrollbar);
|
||||
PRInt32 curpos = GetCurrentPosition(scrollbar);
|
||||
PRInt32 minpos = GetMinPosition(scrollbar);
|
||||
SetCurrentPosition(scrollbar, aThumbFrame, curpos - minpos + change*pageIncrement, PR_TRUE);
|
||||
PRInt32 maxpos = GetMaxPosition(scrollbar);
|
||||
|
||||
// get the new position and make sure it is in bounds
|
||||
PRInt32 newpos = curpos - minpos + change * pageIncrement;
|
||||
if (newpos < minpos || maxpos < minpos)
|
||||
newpos = minpos;
|
||||
else if (newpos > maxpos)
|
||||
newpos = maxpos;
|
||||
|
||||
SetCurrentPositionInternal(scrollbar, newpos, PR_TRUE);
|
||||
}
|
||||
|
||||
// called when the current position changed and we need to update the thumb's location
|
||||
@ -638,62 +650,64 @@ nsSliderFrame::CurrentPositionChanged(nsPresContext* aPresContext)
|
||||
|
||||
PRBool isHorizontal = IsHorizontal();
|
||||
|
||||
// get the current position
|
||||
PRInt32 curpos = GetCurrentPosition(scrollbar);
|
||||
// get the current position
|
||||
PRInt32 curpospx = GetCurrentPosition(scrollbar);
|
||||
|
||||
// do nothing if the position did not change
|
||||
if (mCurPos == curpos)
|
||||
return NS_OK;
|
||||
// do nothing if the position did not change
|
||||
if (mCurPos == curpospx)
|
||||
return NS_OK;
|
||||
|
||||
// get our current min and max position from our content node
|
||||
PRInt32 minpos = GetMinPosition(scrollbar);
|
||||
PRInt32 maxpos = GetMaxPosition(scrollbar);
|
||||
// get our current min and max position from our content node
|
||||
PRInt32 minpospx = GetMinPosition(scrollbar);
|
||||
PRInt32 maxpospx = GetMaxPosition(scrollbar);
|
||||
|
||||
if (curpos < minpos || maxpos < minpos)
|
||||
curpos = minpos;
|
||||
else if (curpos > maxpos)
|
||||
curpos = maxpos;
|
||||
if (curpospx < minpospx || maxpospx < minpospx)
|
||||
curpospx = minpospx;
|
||||
else if (curpospx > maxpospx)
|
||||
curpospx = maxpospx;
|
||||
|
||||
// convert to pixels
|
||||
nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1);
|
||||
nscoord curpospx = (curpos - minpos) * onePixel;
|
||||
// get the thumb's rect
|
||||
nsIFrame* thumbFrame = mFrames.FirstChild();
|
||||
if (!thumbFrame)
|
||||
return NS_OK; // The thumb may stream in asynchronously via XBL.
|
||||
|
||||
// get the thumb's rect
|
||||
nsIFrame* thumbFrame = mFrames.FirstChild();
|
||||
if (!thumbFrame)
|
||||
return NS_OK; // The thumb may stream in asynchronously via XBL.
|
||||
nsRect thumbRect = thumbFrame->GetRect();
|
||||
|
||||
nsRect thumbRect = thumbFrame->GetRect();
|
||||
nsRect clientRect;
|
||||
GetClientRect(clientRect);
|
||||
|
||||
nsRect clientRect;
|
||||
GetClientRect(clientRect);
|
||||
// figure out the new rect
|
||||
nsRect newThumbRect(thumbRect);
|
||||
|
||||
// figure out the new rect
|
||||
nsRect newThumbRect(thumbRect);
|
||||
PRBool reverse = mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::dir,
|
||||
nsGkAtoms::reverse, eCaseMatters);
|
||||
nscoord pos = reverse ? (maxpospx - curpospx) : (curpospx - minpospx);
|
||||
|
||||
if (isHorizontal)
|
||||
newThumbRect.x = clientRect.x + nscoord(float(curpospx)*mRatio);
|
||||
else
|
||||
newThumbRect.y = clientRect.y + nscoord(float(curpospx)*mRatio);
|
||||
// convert to pixels
|
||||
nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1);
|
||||
if (isHorizontal)
|
||||
newThumbRect.x = clientRect.x + nscoord(float(pos * onePixel) * mRatio);
|
||||
else
|
||||
newThumbRect.y = clientRect.y + nscoord(float(pos * onePixel) * mRatio);
|
||||
|
||||
// set the rect
|
||||
thumbFrame->SetRect(newThumbRect);
|
||||
// set the rect
|
||||
thumbFrame->SetRect(newThumbRect);
|
||||
|
||||
// Figure out the union of the rect so we know what to redraw.
|
||||
// Combine the old and new thumb overflow areas.
|
||||
nsRect changeRect;
|
||||
changeRect.UnionRect(thumbFrame->GetOverflowRect() + thumbRect.TopLeft(),
|
||||
thumbFrame->GetOverflowRect() + newThumbRect.TopLeft());
|
||||
// Figure out the union of the rect so we know what to redraw.
|
||||
// Combine the old and new thumb overflow areas.
|
||||
nsRect changeRect;
|
||||
changeRect.UnionRect(thumbFrame->GetOverflowRect() + thumbRect.TopLeft(),
|
||||
thumbFrame->GetOverflowRect() + newThumbRect.TopLeft());
|
||||
|
||||
// redraw just the change
|
||||
Invalidate(changeRect, mRedrawImmediate);
|
||||
// redraw just the change
|
||||
Invalidate(changeRect, mRedrawImmediate);
|
||||
|
||||
if (mScrollbarListener)
|
||||
mScrollbarListener->PositionChanged(aPresContext, mCurPos, curpos);
|
||||
if (mScrollbarListener)
|
||||
mScrollbarListener->PositionChanged(aPresContext, mCurPos, curpospx);
|
||||
|
||||
mCurPos = curpos;
|
||||
mCurPos = curpospx;
|
||||
|
||||
return NS_OK;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static void UpdateAttribute(nsIContent* aScrollbar, nscoord aNewPos, PRBool aNotify, PRBool aIsSmooth) {
|
||||
@ -710,23 +724,35 @@ static void UpdateAttribute(nsIContent* aScrollbar, nscoord aNewPos, PRBool aNot
|
||||
}
|
||||
|
||||
// newpos should be passed to this function as a position as if the minpos is 0.
|
||||
// That is, the minpos will be added to the position by this function.
|
||||
// That is, the minpos will be added to the position by this function. In a reverse
|
||||
// direction slider, the newpos should be the distance from the end.
|
||||
void
|
||||
nsSliderFrame::SetCurrentPosition(nsIContent* scrollbar, nsIFrame* aThumbFrame, nscoord newpos, PRBool aIsSmooth)
|
||||
nsSliderFrame::SetCurrentPosition(nsIContent* scrollbar, nscoord newpos, PRBool aIsSmooth)
|
||||
{
|
||||
|
||||
// get our current, min and max position from our content node
|
||||
// get min and max position from our content node
|
||||
PRInt32 minpos = GetMinPosition(scrollbar);
|
||||
PRInt32 maxpos = GetMaxPosition(scrollbar);
|
||||
|
||||
newpos += minpos;
|
||||
// in reverse direction sliders, flip the value so that it goes from
|
||||
// right to left, or bottom to top.
|
||||
if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::dir,
|
||||
nsGkAtoms::reverse, eCaseMatters))
|
||||
newpos = maxpos - newpos;
|
||||
else
|
||||
newpos += minpos;
|
||||
|
||||
// get the new position and make sure it is in bounds
|
||||
if (newpos < minpos || maxpos < minpos)
|
||||
newpos = minpos;
|
||||
newpos = minpos;
|
||||
else if (newpos > maxpos)
|
||||
newpos = maxpos;
|
||||
newpos = maxpos;
|
||||
|
||||
SetCurrentPositionInternal(scrollbar, newpos, aIsSmooth);
|
||||
}
|
||||
|
||||
void
|
||||
nsSliderFrame::SetCurrentPositionInternal(nsIContent* scrollbar, nscoord newpos, PRBool aIsSmooth)
|
||||
{
|
||||
nsIBox* scrollbarBox = GetScrollbar();
|
||||
nsIScrollbarFrame* scrollbarFrame;
|
||||
CallQueryInterface(scrollbarBox, &scrollbarFrame);
|
||||
@ -842,7 +868,7 @@ nsSliderFrame::MouseDown(nsIDOMEvent* aMouseEvent)
|
||||
scrollbar = GetContentOfBox(scrollbarBox);
|
||||
|
||||
// set it
|
||||
SetCurrentPosition(scrollbar, thumbFrame, pospx, PR_FALSE);
|
||||
SetCurrentPosition(scrollbar, pospx, PR_FALSE);
|
||||
}
|
||||
|
||||
DragThumb(PR_TRUE);
|
||||
@ -972,7 +998,7 @@ nsSliderFrame::HandlePress(nsPresContext* aPresContext,
|
||||
mChange = change;
|
||||
DragThumb(PR_TRUE);
|
||||
mDestinationPoint = eventPoint;
|
||||
PageUpDown(thumbFrame, change);
|
||||
PageUpDown(change);
|
||||
|
||||
nsRepeatService::GetInstance()->Start(mMediator);
|
||||
|
||||
@ -1090,7 +1116,7 @@ NS_IMETHODIMP_(void) nsSliderFrame::Notify(nsITimer *timer)
|
||||
if (stop) {
|
||||
nsRepeatService::GetInstance()->Stop();
|
||||
} else {
|
||||
PageUpDown(thumbFrame, mChange);
|
||||
PageUpDown(mChange);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,8 +217,9 @@ private:
|
||||
|
||||
nsIBox* GetScrollbar();
|
||||
|
||||
void PageUpDown(nsIFrame* aThumbFrame, nscoord change);
|
||||
void SetCurrentPosition(nsIContent* scrollbar, nsIFrame* aThumbFrame, nscoord pos, PRBool aIsSmooth);
|
||||
void PageUpDown(nscoord change);
|
||||
void SetCurrentPosition(nsIContent* scrollbar, nscoord pos, PRBool aIsSmooth);
|
||||
void SetCurrentPositionInternal(nsIContent* scrollbar, nscoord pos, PRBool aIsSmooth);
|
||||
void DragThumb(PRBool aGrabMouseEvents);
|
||||
void AddListener();
|
||||
void RemoveListener();
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
<content align="center" pack="center">
|
||||
<xul:slider anonid="slider" class="scale-slider" snap="true" flex="1"
|
||||
xbl:inherits="disabled,orient,curpos=value,minpos=min,maxpos=max,increment,pageincrement">
|
||||
xbl:inherits="disabled,orient,dir,curpos=value,minpos=min,maxpos=max,increment,pageincrement">
|
||||
<xul:thumb class="scale-thumb" xbl:inherits="disabled,orient"/>
|
||||
</xul:slider>
|
||||
</content>
|
||||
@ -52,6 +52,18 @@
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<constructor>
|
||||
<![CDATA[
|
||||
var value = parseInt(this.getAttribute("value"), 10);
|
||||
if (!isNaN(value))
|
||||
this.value = value;
|
||||
else if (this.min > 0)
|
||||
this.value = this.min;
|
||||
else if (this.max < 0)
|
||||
this.value = this.max;
|
||||
]]>
|
||||
</constructor>
|
||||
|
||||
<method name="_getIntegerAttribute">
|
||||
<parameter name="aAttr"/>
|
||||
<parameter name="aDefaultValue"/>
|
||||
@ -134,7 +146,7 @@
|
||||
this.setAttribute("value", event.newValue);
|
||||
|
||||
var changeEvent = document.createEvent("Events");
|
||||
changeEvent.initEvent("change", false, true);
|
||||
changeEvent.initEvent("change", true, true);
|
||||
this.dispatchEvent(changeEvent);
|
||||
break;
|
||||
|
||||
@ -149,28 +161,28 @@
|
||||
</handler>
|
||||
|
||||
<handler event="keypress" keycode="VK_UP" preventdefault="true">
|
||||
this.decrease();
|
||||
return (this.dir == "reverse") ? this.increase() : this.decrease();
|
||||
</handler>
|
||||
<handler event="keypress" keycode="VK_LEFT" preventdefault="true">
|
||||
this.decrease();
|
||||
return (this.dir == "reverse") ? this.increase() : this.decrease();
|
||||
</handler>
|
||||
<handler event="keypress" keycode="VK_DOWN" preventdefault="true">
|
||||
this.increase();
|
||||
return (this.dir == "reverse") ? this.decrease() : this.increase();
|
||||
</handler>
|
||||
<handler event="keypress" keycode="VK_RIGHT" preventdefault="true">
|
||||
this.increase();
|
||||
return (this.dir == "reverse") ? this.decrease() : this.increase();
|
||||
</handler>
|
||||
<handler event="keypress" keycode="VK_PAGE_UP" preventdefault="true">
|
||||
this.decreasePage();
|
||||
return (this.dir == "reverse") ? this.increasePage() : this.decreasePage();
|
||||
</handler>
|
||||
<handler event="keypress" keycode="VK_PAGE_DOWN" preventdefault="true">
|
||||
this.increasePage();
|
||||
return (this.dir == "reverse") ? this.decreasePage() : this.increasePage();
|
||||
</handler>
|
||||
<handler event="keypress" keycode="VK_HOME" preventdefault="true">
|
||||
this.value = this.min;
|
||||
this.value = (this.dir == "reverse") ? this.max : this.min;
|
||||
</handler>
|
||||
<handler event="keypress" keycode="VK_END" preventdefault="true">
|
||||
this.value = this.max;
|
||||
this.value = (this.dir == "reverse") ? this.min : this.max;
|
||||
</handler>
|
||||
</handlers>
|
||||
|
||||
|
@ -111,7 +111,8 @@ protected:
|
||||
void DrawTabPanel (CGContextRef context, const HIRect& inBoxRect);
|
||||
void DrawScale (CGContextRef context, const HIRect& inBoxRect,
|
||||
PRBool inIsDisabled, PRInt32 inState,
|
||||
PRBool inDirection, PRInt32 inCurrentValue,
|
||||
PRBool inDirection, PRBool inIsReverse,
|
||||
PRInt32 inCurrentValue,
|
||||
PRInt32 inMinValue, PRInt32 inMaxValue);
|
||||
void DrawButton (CGContextRef context, ThemeButtonKind inKind,
|
||||
const HIRect& inBoxRect, PRBool inIsDefault,
|
||||
|
@ -247,7 +247,8 @@ nsNativeThemeCocoa::DrawTabPanel(CGContextRef cgContext, const HIRect& inBoxRect
|
||||
void
|
||||
nsNativeThemeCocoa::DrawScale(CGContextRef cgContext, const HIRect& inBoxRect,
|
||||
PRBool inIsDisabled, PRInt32 inState,
|
||||
PRBool inIsVertical, PRInt32 inCurrentValue,
|
||||
PRBool inIsVertical, PRBool inIsReverse,
|
||||
PRInt32 inCurrentValue,
|
||||
PRInt32 inMinValue, PRInt32 inMaxValue)
|
||||
{
|
||||
HIThemeTrackDrawInfo tdi;
|
||||
@ -261,6 +262,8 @@ nsNativeThemeCocoa::DrawScale(CGContextRef cgContext, const HIRect& inBoxRect,
|
||||
tdi.attributes = kThemeTrackShowThumb;
|
||||
if (!inIsVertical)
|
||||
tdi.attributes |= kThemeTrackHorizontal;
|
||||
if (inIsReverse)
|
||||
tdi.attributes |= kThemeTrackRightToLeft;
|
||||
if (inState & NS_EVENT_STATE_FOCUS)
|
||||
tdi.attributes |= kThemeTrackHasFocus;
|
||||
tdi.enableState = inIsDisabled ? kThemeTrackDisabled : kThemeTrackActive;
|
||||
@ -610,8 +613,11 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsIRenderingContext* aContext, nsIFrame
|
||||
if (!maxpos)
|
||||
maxpos = 100;
|
||||
|
||||
PRBool reverse = aFrame->GetContent()->
|
||||
AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::dir,
|
||||
NS_LITERAL_STRING("reverse"), eCaseMatters);
|
||||
DrawScale(cgContext, macRect, IsDisabled(aFrame), eventState,
|
||||
(aWidgetType == NS_THEME_SCALE_VERTICAL),
|
||||
(aWidgetType == NS_THEME_SCALE_VERTICAL), reverse,
|
||||
curpos, minpos, maxpos);
|
||||
}
|
||||
break;
|
||||
|
@ -54,7 +54,7 @@ toolkit.jar:
|
||||
content/global/bindings/radio.xml (resources/content/bindings/radio.xml)
|
||||
content/global/bindings/scrollbar.xml (resources/content/bindings/scrollbar.xml)
|
||||
content/global/bindings/nativescrollbar.xml (resources/content/bindings/nativescrollbar.xml)
|
||||
content/global/bindings/scale.xml (resources/content/bindings/scale.xml)
|
||||
content/global/bindings/scale.xml (/toolkit/content/widgets/scale.xml)
|
||||
content/global/bindings/scrollbox.xml (resources/content/bindings/scrollbox.xml)
|
||||
content/global/bindings/splitter.xml (resources/content/bindings/splitter.xml)
|
||||
content/global/bindings/spinbuttons.xml (/toolkit/content/widgets/spinbuttons.xml)
|
||||
|
Loading…
Reference in New Issue
Block a user