зеркало из https://github.com/mozilla/gecko-dev.git
Bug 472090, change scale to use a listener instead of mutation events, r=smaug,sr=neil
This commit is contained in:
Родитель
043ac8e978
Коммит
dd6cf51b95
|
@ -63,6 +63,7 @@ XPIDLSRCS= nsIBoxObject.idl \
|
|||
nsIEditorBoxObject.idl \
|
||||
nsIContainerBoxObject.idl \
|
||||
nsIListBoxObject.idl \
|
||||
nsISliderListener.idl \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -12,15 +12,13 @@
|
|||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* The Initial Developer of the Original Code is Neil Deakin
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -36,29 +34,19 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsIScrollbarListener_h___
|
||||
#define nsIScrollbarListener_h___
|
||||
#include "nsISupports.idl"
|
||||
|
||||
// {A0ADBD81-2911-11d3-97FA-00400553EEF0}
|
||||
#define NS_ISCROLLBARLISTENER_IID \
|
||||
{ 0xa0adbd81, 0x2911, 0x11d3, { 0x97, 0xfa, 0x0, 0x40, 0x5, 0x53, 0xee, 0xf0 } }
|
||||
|
||||
static NS_DEFINE_IID(kIScrollbarListenerIID, NS_ISCROLLBARLISTENER_IID);
|
||||
|
||||
class nsPresContext;
|
||||
|
||||
class nsIScrollbarListener : public nsISupports {
|
||||
|
||||
public:
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCROLLBARLISTENER_IID)
|
||||
|
||||
NS_IMETHOD PositionChanged(nsPresContext* aPresContext, PRInt32 aOldIndex, PRInt32& aNewIndex) = 0;
|
||||
|
||||
NS_IMETHOD PagedUpDown() = 0;
|
||||
/**
|
||||
* Used for <scale> to listen to slider changes to avoid mutation listeners
|
||||
*/
|
||||
[scriptable, uuid(CD380CB5-E9F6-4B7D-A19F-B1FD7B31C532)]
|
||||
interface nsISliderListener : nsISupports
|
||||
{
|
||||
/**
|
||||
* Called when the current, minimum or maximum value has been changed to
|
||||
* newValue. The which parameter will either be 'curpos', 'minpos' or 'maxpos'.
|
||||
* If userChanged is true, then the user changed ths slider, otherwise it
|
||||
* was changed via some other means.
|
||||
*/
|
||||
void valueChanged(in AString which, in long newValue, in boolean userChanged);
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIScrollbarListener, NS_ISCROLLBARLISTENER_IID)
|
||||
|
||||
#endif
|
||||
|
|
@ -59,7 +59,7 @@
|
|||
#include "nsIDOMMouseEvent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsScrollbarButtonFrame.h"
|
||||
#include "nsIScrollbarListener.h"
|
||||
#include "nsISliderListener.h"
|
||||
#include "nsIScrollbarMediator.h"
|
||||
#include "nsIScrollbarFrame.h"
|
||||
#include "nsILookAndFeel.h"
|
||||
|
@ -115,8 +115,8 @@ NS_NewSliderFrame (nsIPresShell* aPresShell, nsStyleContext* aContext)
|
|||
nsSliderFrame::nsSliderFrame(nsIPresShell* aPresShell, nsStyleContext* aContext):
|
||||
nsBoxFrame(aPresShell, aContext),
|
||||
mCurPos(0),
|
||||
mScrollbarListener(nsnull),
|
||||
mChange(0)
|
||||
mChange(0),
|
||||
mUserChanged(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -228,6 +228,30 @@ nsSliderFrame::GetIntegerAttribute(nsIContent* content, nsIAtom* atom, PRInt32 d
|
|||
return defaultValue;
|
||||
}
|
||||
|
||||
class nsValueChangedRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
nsValueChangedRunnable(nsISliderListener* aListener,
|
||||
nsIAtom* aWhich,
|
||||
PRInt32 aValue,
|
||||
PRBool aUserChanged)
|
||||
: mListener(aListener), mWhich(aWhich),
|
||||
mValue(aValue), mUserChanged(aUserChanged)
|
||||
{}
|
||||
|
||||
NS_IMETHODIMP Run()
|
||||
{
|
||||
nsAutoString which;
|
||||
mWhich->ToString(atom);
|
||||
return mListener->ValueChanged(which, mValue, mUserChanged);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISliderListener> mListener;
|
||||
nsCOMPtr<nsIAtom> mWhich;
|
||||
PRInt32 mValue;
|
||||
PRBool mUserChanged;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSliderFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
|
@ -251,6 +275,18 @@ nsSliderFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
|||
PRInt32 current = GetCurrentPosition(scrollbar);
|
||||
PRInt32 min = GetMinPosition(scrollbar);
|
||||
PRInt32 max = GetMaxPosition(scrollbar);
|
||||
|
||||
// inform the parent <scale> that the minimum or maximum changed
|
||||
nsIFrame* parent = GetParent();
|
||||
if (parent) {
|
||||
nsCOMPtr<nsISliderListener> sliderListener = do_QueryInterface(parent->GetContent());
|
||||
if (sliderListener) {
|
||||
nsContentUtils::AddScriptRunner(
|
||||
new nsValueChangedRunnable(sliderListener, aAttribute,
|
||||
aAttribute == nsGkAtoms::minpos ? min : max, PR_FALSE));
|
||||
}
|
||||
}
|
||||
|
||||
if (current < min || current > max)
|
||||
{
|
||||
if (current < min || max < min)
|
||||
|
@ -610,9 +646,6 @@ nsSliderFrame::PageUpDown(nscoord change)
|
|||
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);
|
||||
|
@ -685,11 +718,18 @@ nsSliderFrame::CurrentPositionChanged(nsPresContext* aPresContext,
|
|||
// Redraw the scrollbar
|
||||
InvalidateWithFlags(clientRect, aImmediateRedraw ? INVALIDATE_IMMEDIATE : 0);
|
||||
|
||||
if (mScrollbarListener)
|
||||
mScrollbarListener->PositionChanged(aPresContext, mCurPos, curpospx);
|
||||
|
||||
mCurPos = curpospx;
|
||||
|
||||
// inform the parent <scale> if it exists that the value changed
|
||||
nsIFrame* parent = GetParent();
|
||||
if (parent) {
|
||||
nsCOMPtr<nsISliderListener> sliderListener = do_QueryInterface(parent->GetContent());
|
||||
if (sliderListener) {
|
||||
nsContentUtils::AddScriptRunner(
|
||||
new nsValueChangedRunnable(sliderListener, nsGkAtoms::curpos, mCurPos, mUserChanged));
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -766,6 +806,9 @@ nsSliderFrame::SetCurrentPositionInternal(nsIContent* aScrollbar, PRInt32 aNewPo
|
|||
{
|
||||
nsCOMPtr<nsIContent> scrollbar = aScrollbar;
|
||||
nsIBox* scrollbarBox = GetScrollbar();
|
||||
|
||||
mUserChanged = PR_TRUE;
|
||||
|
||||
nsIScrollbarFrame* scrollbarFrame = do_QueryFrame(scrollbarBox);
|
||||
if (scrollbarFrame) {
|
||||
// See if we have a mediator.
|
||||
|
@ -784,11 +827,13 @@ nsSliderFrame::SetCurrentPositionInternal(nsIContent* aScrollbar, PRInt32 aNewPo
|
|||
CurrentPositionChanged(frame->PresContext(), aImmediateRedraw);
|
||||
}
|
||||
}
|
||||
mUserChanged = PR_FALSE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateAttribute(scrollbar, aNewPos, PR_TRUE, aIsSmooth);
|
||||
mUserChanged = PR_FALSE;
|
||||
|
||||
#ifdef DEBUG_SLIDER
|
||||
printf("Current Pos=%d\n",aNewPos);
|
||||
|
@ -1091,13 +1136,6 @@ nsSliderFrame::EnsureOrient()
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
nsSliderFrame::SetScrollbarListener(nsIScrollbarListener* aListener)
|
||||
{
|
||||
// Don't addref/release this, since it's actually a frame.
|
||||
mScrollbarListener = aListener;
|
||||
}
|
||||
|
||||
void nsSliderFrame::Notify(void)
|
||||
{
|
||||
PRBool stop = PR_FALSE;
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
#include "nsIDOMMouseListener.h"
|
||||
|
||||
class nsString;
|
||||
class nsIScrollbarListener;
|
||||
class nsISupportsArray;
|
||||
class nsITimer;
|
||||
class nsSliderFrame;
|
||||
|
@ -186,8 +185,6 @@ public:
|
|||
static PRInt32 GetIntegerAttribute(nsIContent* content, nsIAtom* atom, PRInt32 defaultValue);
|
||||
void EnsureOrient();
|
||||
|
||||
void SetScrollbarListener(nsIScrollbarListener* aListener);
|
||||
|
||||
virtual nsIView* GetMouseCapturer() const { return GetView(); }
|
||||
|
||||
NS_IMETHOD HandlePress(nsPresContext* aPresContext,
|
||||
|
@ -242,12 +239,15 @@ private:
|
|||
|
||||
PRInt32 mCurPos;
|
||||
|
||||
nsIScrollbarListener* mScrollbarListener;
|
||||
|
||||
nscoord mChange;
|
||||
nsPoint mDestinationPoint;
|
||||
nsRefPtr<nsSliderMediator> mMediator;
|
||||
|
||||
// true if an attribute change has been caused by the user manipulating the
|
||||
// slider. This allows notifications to tell how a slider's current position
|
||||
// was changed.
|
||||
PRBool mUserChanged;
|
||||
|
||||
static PRBool gMiddlePref;
|
||||
static PRInt32 gSnapMultiplier;
|
||||
}; // class nsSliderFrame
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
</xul:slider>
|
||||
</content>
|
||||
|
||||
<implementation implements="nsIAccessibleProvider">
|
||||
<implementation implements="nsIAccessibleProvider, nsISliderListener">
|
||||
<property name="accessibleType" readonly="true">
|
||||
<getter>
|
||||
return Components.interfaces.nsIAccessibleProvider.XULScale;
|
||||
|
@ -57,6 +57,7 @@
|
|||
<property name="pageIncrement" onget="return this._getIntegerAttribute('pageincrement', 10);"
|
||||
onset="return this._setIntegerAttribute('pageincrement', val);"/>
|
||||
|
||||
<field name="_userChanged">false</field>
|
||||
<field name="_sliderElement"/>
|
||||
<property name="_slider" readonly="true">
|
||||
<getter>
|
||||
|
@ -148,55 +149,77 @@
|
|||
</body>
|
||||
</method>
|
||||
|
||||
<method name="valueChanged">
|
||||
<parameter name="which"/>
|
||||
<parameter name="newValue"/>
|
||||
<parameter name="userChanged"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
switch (which) {
|
||||
case "curpos":
|
||||
this.setAttribute("value", newValue);
|
||||
|
||||
// in the future, only fire the change event when userChanged
|
||||
// or _userChanged is true
|
||||
var changeEvent = document.createEvent("Events");
|
||||
changeEvent.initEvent("change", true, true);
|
||||
this.dispatchEvent(changeEvent);
|
||||
break;
|
||||
|
||||
case "minpos":
|
||||
this.setAttribute("min", newValue);
|
||||
break;
|
||||
|
||||
case "maxpos":
|
||||
this.setAttribute("max", newValue);
|
||||
break;
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
</implementation>
|
||||
|
||||
<handlers>
|
||||
<handler event="DOMAttrModified">
|
||||
if (event.originalTarget != this._slider)
|
||||
return;
|
||||
|
||||
switch (event.attrName) {
|
||||
case "curpos":
|
||||
this.setAttribute("value", event.newValue);
|
||||
|
||||
var changeEvent = document.createEvent("Events");
|
||||
changeEvent.initEvent("change", true, true);
|
||||
this.dispatchEvent(changeEvent);
|
||||
break;
|
||||
|
||||
case "minpos":
|
||||
this.setAttribute("min", event.newValue);
|
||||
break;
|
||||
|
||||
case "maxpos":
|
||||
this.setAttribute("max", event.newValue);
|
||||
break;
|
||||
}
|
||||
</handler>
|
||||
|
||||
<handler event="keypress" keycode="VK_UP" preventdefault="true">
|
||||
return (this.dir == "reverse") ? this.increase() : this.decrease();
|
||||
this._userChanged = true;
|
||||
(this.dir == "reverse") ? this.increase() : this.decrease();
|
||||
this._userChanged = false;
|
||||
</handler>
|
||||
<handler event="keypress" keycode="VK_LEFT" preventdefault="true">
|
||||
return (this.dir == "reverse") ? this.increase() : this.decrease();
|
||||
this._userChanged = true;
|
||||
(this.dir == "reverse") ? this.increase() : this.decrease();
|
||||
this._userChanged = false;
|
||||
</handler>
|
||||
<handler event="keypress" keycode="VK_DOWN" preventdefault="true">
|
||||
return (this.dir == "reverse") ? this.decrease() : this.increase();
|
||||
this._userChanged = true;
|
||||
(this.dir == "reverse") ? this.decrease() : this.increase();
|
||||
this._userChanged = false;
|
||||
</handler>
|
||||
<handler event="keypress" keycode="VK_RIGHT" preventdefault="true">
|
||||
return (this.dir == "reverse") ? this.decrease() : this.increase();
|
||||
this._userChanged = true;
|
||||
(this.dir == "reverse") ? this.decrease() : this.increase();
|
||||
this._userChanged = false;
|
||||
</handler>
|
||||
<handler event="keypress" keycode="VK_PAGE_UP" preventdefault="true">
|
||||
return (this.dir == "reverse") ? this.increasePage() : this.decreasePage();
|
||||
this._userChanged = true;
|
||||
(this.dir == "reverse") ? this.increasePage() : this.decreasePage();
|
||||
this._userChanged = false;
|
||||
</handler>
|
||||
<handler event="keypress" keycode="VK_PAGE_DOWN" preventdefault="true">
|
||||
return (this.dir == "reverse") ? this.decreasePage() : this.increasePage();
|
||||
this._userChanged = true;
|
||||
(this.dir == "reverse") ? this.decreasePage() : this.increasePage();
|
||||
this._userChanged = false;
|
||||
</handler>
|
||||
<handler event="keypress" keycode="VK_HOME" preventdefault="true">
|
||||
this._userChanged = true;
|
||||
this.value = (this.dir == "reverse") ? this.max : this.min;
|
||||
this._userChanged = false;
|
||||
</handler>
|
||||
<handler event="keypress" keycode="VK_END" preventdefault="true">
|
||||
this._userChanged = true;
|
||||
this.value = (this.dir == "reverse") ? this.min : this.max;
|
||||
this._userChanged = false;
|
||||
</handler>
|
||||
</handlers>
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче