new files for a native scrollbar frame via xbl. r=sdagley/sr=beard/a=valeski. bug#121440

This commit is contained in:
pinkerton%netscape.com 2002-03-31 18:32:35 +00:00
Родитель 6d645bc731
Коммит d369202c6a
9 изменённых файлов: 1294 добавлений и 0 удалений

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

@ -0,0 +1 @@
nsIScrollbarMediator.h

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

@ -0,0 +1,320 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* 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) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsNativeScrollbarFrame.h"
#include "nsINameSpaceManager.h"
#include "nsXULAtoms.h"
#include "nsBoxLayoutState.h"
#include "nsComponentManagerUtils.h"
#include "nsGUIEvent.h"
#include "nsIDeviceContext.h"
#include "nsIView.h"
#include "nsINativeScrollbar.h"
#include "nsIScrollbarFrame.h"
#include "nsIScrollbarMediator.h"
//
// NS_NewNativeScrollbarFrame
//
// Creates a new scrollbar frame and returns it in |aNewFrame|
//
nsresult
NS_NewNativeScrollbarFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsNativeScrollbarFrame* it = new (aPresShell) nsNativeScrollbarFrame (aPresShell);
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
*aNewFrame = it;
return NS_OK;
} // NS_NewNativeScrollbarFrame
//
// QueryInterface
//
NS_INTERFACE_MAP_BEGIN(nsNativeScrollbarFrame)
NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
nsNativeScrollbarFrame::nsNativeScrollbarFrame(nsIPresShell* aShell)
: nsBoxFrame(aShell), mScrollbarNeedsContent(PR_TRUE)
{
}
nsNativeScrollbarFrame::~nsNativeScrollbarFrame ( )
{
// frame is going away, unhook the native scrollbar from
// the content node just to be safe about lifetime issues
nsCOMPtr<nsINativeScrollbar> scrollbar ( do_QueryInterface(mScrollbar) );
if ( scrollbar )
scrollbar->SetContent(nsnull, nsnull);
}
//
// Init
//
// Pass along to our parent, but also create the native widget that
// we wrap.
//
NS_IMETHODIMP
nsNativeScrollbarFrame::Init(nsIPresContext* aPresContext, nsIContent* aContent,
nsIFrame* aParent, nsIStyleContext* aContext, nsIFrame* aPrevInFlow)
{
nsresult rv = nsBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
// create the native widget that we're wrapping, initialize and show it.
// Don't worry about sizing it, we'll do that later when we're reflowed.
mScrollbar = do_CreateInstance("@mozilla.org/widget/nativescrollbar;1", &rv);
NS_ASSERTION(mScrollbar, "Couldn't create native scrollbar!");
if ( mScrollbar ) {
nsCOMPtr<nsIWidget> parentWidget;
GetWindow(aPresContext, getter_AddRefs(parentWidget));
nsCOMPtr<nsIDeviceContext> devContext;
aPresContext->GetDeviceContext(getter_AddRefs(devContext));
nsRect bounds(0,0,0,0);
rv = mScrollbar->Create(parentWidget, bounds, nsnull, devContext);
mScrollbar->Show(PR_TRUE);
// defer telling the scrollbar about the mediator and the content
// node until its first reflow since not everything has been set
// by this point.
mScrollbarNeedsContent = PR_TRUE;
}
return rv;
}
//
// FindScrollbar
//
// Walk up the parent frame tree and find the content node of the frame
// with the tag "scrollbar". This is the content node that the GFX Scroll Frame
// is watching for attribute changes.
//
nsresult
nsNativeScrollbarFrame::FindScrollbar(nsIFrame* start, nsIFrame** outFrame, nsIContent** outContent)
{
*outContent = nsnull;
*outFrame = nsnull;
while ( start ) {
start->GetParent(&start);
if ( start ) {
// get the content node
nsCOMPtr<nsIContent> currContent;
start->GetContent(getter_AddRefs(currContent));
nsCOMPtr<nsIAtom> atom;
if (currContent && currContent->GetTag(*getter_AddRefs(atom)) == NS_OK && atom.get() == nsXULAtoms::scrollbar) {
*outContent = currContent.get();
*outFrame = start;
NS_IF_ADDREF(*outContent);
return NS_OK;
}
}
}
return NS_OK;
}
//
// AttributeChanged
//
// We inherit changes to certain attributes from the parent's content node. These
// occur when gecko changes the values of the scrollbar or scrolls the content area
// by some means other than our scrollbar (keyboard, scrollwheel, etc). Update
// our native scrollbar with the correct values.
//
NS_IMETHODIMP
nsNativeScrollbarFrame::AttributeChanged(nsIPresContext* aPresContext, nsIContent* aChild,
PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRInt32 aModType,
PRInt32 aHint)
{
nsresult rv = nsBoxFrame::AttributeChanged(aPresContext, aChild,
aNameSpaceID, aAttribute, aModType, aHint);
if ( aAttribute == nsXULAtoms::curpos || aAttribute == nsXULAtoms::maxpos ||
aAttribute == nsXULAtoms::pageincrement || aAttribute == nsXULAtoms::increment ) {
nsAutoString valueStr;
aChild->GetAttr(aNameSpaceID, aAttribute, valueStr);
PRInt32 value = atoi(NS_LossyConvertUCS2toASCII(valueStr).get());
if ( value < 0 )
value = 1; // just be safe and sanity check, scrollbar expects unsigned
nsCOMPtr<nsINativeScrollbar> scrollbar ( do_QueryInterface(mScrollbar) );
if ( scrollbar ) {
if ( aAttribute == nsXULAtoms::curpos )
scrollbar->SetPosition(value);
else if ( aAttribute == nsXULAtoms::maxpos )
scrollbar->SetMaxRange(value);
else if ( aAttribute == nsXULAtoms::pageincrement ) // poorly named, actually the height of the visible view area
scrollbar->SetViewSize(value);
else if ( aAttribute == nsXULAtoms::increment )
scrollbar->SetLineIncrement(value);
}
}
return rv;
}
//
// GetPrefSize
//
// Ask our native widget what dimensions it wants to be, convert them
// back to twips, and tell gecko.
//
NS_IMETHODIMP
nsNativeScrollbarFrame::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
{
float p2t = 0.0;
aState.GetPresContext()->GetPixelsToTwips(&p2t);
PRInt32 narrowDimension = 0;
nsCOMPtr<nsINativeScrollbar> native ( do_QueryInterface(mScrollbar) );
native->GetNarrowSize(&narrowDimension);
if ( IsVertical() )
aSize.width = narrowDimension * p2t;
else
aSize.height = narrowDimension * p2t;
return NS_OK;
}
//
// EndLayout
//
// Called when the box system is done moving us around. Move our associated widget
// to match the bounds of the frame and, if necessary, finish initializing the
// widget.
//
NS_IMETHODIMP
nsNativeScrollbarFrame::EndLayout(nsBoxLayoutState& aState)
{
nsresult rv = nsBoxFrame::EndLayout(aState);
nsRect adjustedRect;
ConvertToWidgetCoordinates(aState.GetPresContext(), mRect, adjustedRect); // also converts twips->pixels
mScrollbar->Resize(adjustedRect.x, adjustedRect.y, adjustedRect.width,
adjustedRect.height, PR_TRUE);
// By now, we have both the content node for the scrollbar and the associated
// scrollbar mediator (for outliner, if applicable). Hook up the scrollbar to
// gecko
if ( mScrollbarNeedsContent ) {
nsCOMPtr<nsIContent> scrollbarContent;
nsIFrame* scrollbarFrame = nsnull;
FindScrollbar(this, &scrollbarFrame, getter_AddRefs(scrollbarContent));
nsCOMPtr<nsIScrollbarMediator> mediator;
nsCOMPtr<nsIScrollbarFrame> sb(do_QueryInterface(scrollbarFrame));
if (sb) {
sb->GetScrollbarMediator(getter_AddRefs(mediator));
nsCOMPtr<nsINativeScrollbar> scrollbar(do_QueryInterface(mScrollbar));
if ( scrollbar ) {
scrollbar->SetContent(scrollbarContent, mediator);
mScrollbarNeedsContent = PR_FALSE;
}
}
}
return rv;
}
//
// ConvertToWidgetCoordinates
//
// Given a rect in frame coordinates (also in twips), convert to a rect (in pixels) that
// is relative to the widget containing this frame. We have to go from the frame to the
// closest view, then from the view to the closest widget.
//
void
nsNativeScrollbarFrame::ConvertToWidgetCoordinates(nsIPresContext* inPresContext, const nsRect & inRect,
nsRect & outAdjustedRect)
{
// Find offset from our view
nsIView *containingView = nsnull;
nsPoint viewOffset(0,0);
GetOffsetFromView(inPresContext, viewOffset, &containingView);
NS_ASSERTION(containingView, "No containing view!");
if ( !containingView )
return;
// get the widget associated with the containing view. The offsets we get back
// are in twips.
nsCOMPtr<nsIWidget> aWidget;
nscoord widgetOffsetX = 0, widgetOffsetY = 0;
containingView->GetOffsetFromWidget ( &widgetOffsetX, &widgetOffsetY, *getter_AddRefs(aWidget) );
if (aWidget) {
float t2p = 1.0;
inPresContext->GetTwipsToPixels(&t2p);
// GetOffsetFromWidget() actually returns the _parent's_ offset from its widget, so we
// still have to add in the offset to |containingView|'s parent ourselves.
nscoord viewOffsetToParentX = 0, viewOffsetToParentY = 0;
containingView->GetPosition ( &viewOffsetToParentX, &viewOffsetToParentY );
// Shift our offset point by offset into our view, the view's offset to its parent,
// and the parent's offset to the closest widget. Recall that everything that came from
// the view system is in twips and must be converted.
nsPoint widgetOffset(0,0);
widgetOffset.MoveBy (NSTwipsToIntPixels(widgetOffsetX + viewOffsetToParentX + viewOffset.x, t2p),
NSTwipsToIntPixels(widgetOffsetY + viewOffsetToParentY + viewOffset.y, t2p) );
outAdjustedRect.x = NSTwipsToIntPixels(inRect.x,t2p);
outAdjustedRect.y = NSTwipsToIntPixels(inRect.y,t2p);
outAdjustedRect.MoveBy(widgetOffset.x, widgetOffset.y);
outAdjustedRect.SizeTo(NSTwipsToIntPixels(inRect.width,t2p), NSTwipsToIntPixels(inRect.height,t2p));
}
} // ConvertToWidgetCoordinates

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

@ -0,0 +1,105 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* 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) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
//
// nsNativeScrollbarFrame
//
// A class that wraps a nsIWidget that is a native scrollbar
// and keeps the two in sync with the rest of gecko. Allows us to
// shim a native scrollbar into the GFX scroll-view mechanism.
//
#ifndef nsNativeScrollbarFrame_h__
#define nsNativeScrollbarFrame_h__
#include "nsScrollbarFrame.h"
#include "nsIWidget.h"
class nsISupportsArray;
class nsIPresShell;
class nsIPresContext;
class nsIContent;
class nsIStyleContext;
nsresult NS_NewNativeScrollbarFrame(nsIPresShell* aPresShell, nsIFrame** aResult) ;
class nsNativeScrollbarFrame : public nsBoxFrame
{
public:
nsNativeScrollbarFrame(nsIPresShell* aShell);
virtual ~nsNativeScrollbarFrame ( ) ;
#ifdef DEBUG
NS_IMETHOD GetFrameName(nsAString& aResult) const {
return MakeFrameName(NS_LITERAL_STRING("NativeScrollbarFrame"), aResult);
}
#endif
NS_IMETHOD Init(nsIPresContext* aPresContext, nsIContent* aContent,
nsIFrame* aParent, nsIStyleContext* aContext, nsIFrame* aPrevInFlow);
// nsIFrame overrides
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext, nsIContent* aChild,
PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRInt32 aModType,
PRInt32 aHint);
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize);
NS_IMETHOD EndLayout(nsBoxLayoutState& aState);
protected:
nsresult FindScrollbar(nsIFrame* start, nsIFrame** outFrame, nsIContent** outContent);
PRBool IsVertical() const { return mIsVertical; }
void ConvertToWidgetCoordinates(nsIPresContext* inPresContext, const nsRect & inRect,
nsRect & outAdjustedRect);
private:
PRPackedBool mIsVertical;
PRPackedBool mScrollbarNeedsContent;
nsCOMPtr<nsIWidget> mScrollbar;
}; // class nsNativeScrollbarFrame
#endif

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

@ -0,0 +1,38 @@
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2002 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Joe Hewitt (hewitt@netscape.com)
*/
/* ===== scrollbars.css =================================================
== Styles used by native scrollbar-related elements.
======================================================================= */
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
/* ::::: scrollbar ::::: */
scrollbar {
-moz-appearance: scrollbar;
-moz-binding: url(chrome://global/content/bindings/nativescrollbar.xml#scrollbar);
min-width: 16px;
cursor: default;
}

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

@ -0,0 +1,140 @@
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998-2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Joe Hewitt (hewitt@netscape.com)
*/
/* ===== scrollbars.css =================================================
== Styles used by XUL scrollbar-related elements.
======================================================================= */
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
/* ::::: scrollbar ::::: */
scrollbar {
-moz-appearance: scrollbar;
-moz-binding: url("chrome://global/content/bindings/scrollbar.xml#scrollbar");
cursor: default;
}
/* ::::: slider ::::: */
slider {
-moz-appearance: scrollbartrack-horizontal;
height: 16px;
background: url("chrome://global/skin/scrollbar/slider-hrz.gif") #AAAAAA;
}
slider[orient="vertical"] {
-moz-appearance: scrollbartrack-vertical;
width: 16px;
height: none;
background-image: url("chrome://global/skin/scrollbar/slider-vrt.gif");
}
/* ::::: borders for thumb and buttons ::::: */
thumb {
border: 2px solid;
-moz-border-top-colors: #000000 -moz-mac-accentregularhighlight;
-moz-border-right-colors: #000000 -moz-mac-accentlightshadow;
-moz-border-bottom-colors: #000000 -moz-mac-accentlightshadow;
-moz-border-left-colors: #000000 -moz-mac-accentregularhighlight;
min-width: 10px;
background: url("chrome://global/skin/scrollbar/thumb-hrz.png") -moz-mac-accentface no-repeat 50% 50%;
}
thumb:active {
-moz-border-top-colors: #000000 -moz-mac-accentregularhighlight;
-moz-border-right-colors: #000000 -moz-mac-accentlightshadow;
-moz-border-bottom-colors: #000000 -moz-mac-accentlightshadow;
-moz-border-left-colors: #000000 -moz-mac-accentregularhighlight;
background-color: -moz-mac-accentlightshadow;
background-image: url("chrome://global/skin/scrollbar/thumb-hrz-act.png");
}
thumb[orient="vertical"] {
-moz-appearance: scrollbarthumb-vertical;
min-width: 0;
min-height: 16px;
background-image: url("chrome://global/skin/scrollbar/thumb-vrt.png");
}
thumb[orient="vertical"]:active {
background-image: url("chrome://global/skin/scrollbar/thumb-vrt-act.png");
}
/* ::::: thumb (horizontal) ::::: */
thumb {
min-height: 16px;
}
thumb[orient="horizontal"] {
-moz-appearance: scrollbarthumb-horizontal;
min-width: 16px;
}
/* ::::: scrollbar button ::::: */
scrollbarbutton {
width: 16px;
height: 16px;
border: 2px solid;
-moz-border-top-colors: #000000 #FFFFFF;
-moz-border-right-colors: #000000 #BBBBBB;
-moz-border-bottom-colors: #000000 #BBBBBB;
-moz-border-left-colors: #000000 #FFFFFF;
background: #DDDDDD no-repeat 50% 50%;
}
scrollbarbutton:hover:active {
-moz-border-top-colors: #000000 #444444;
-moz-border-right-colors: #000000 #AAAAAA;
-moz-border-bottom-colors: #000000 #AAAAAA;
-moz-border-left-colors: #000000 #444444;
background-color: #666666;
}
/* ..... increment .... */
scrollbarbutton[type="increment"] {
-moz-appearance: scrollbarbutton-right;
background-image: url("chrome://global/skin/scrollbar/btn-rit.gif")
}
scrollbar[orient="vertical"] > scrollbarbutton[type="increment"] {
-moz-appearance: scrollbarbutton-down;
background-image: url("chrome://global/skin/scrollbar/btn-dn.gif")
}
/* ..... decrement .... */
scrollbarbutton[type="decrement"] {
-moz-appearance: scrollbarbutton-left;
background-image: url("chrome://global/skin/scrollbar/btn-lft.gif")
}
scrollbar[orient="vertical"] > scrollbarbutton[type="decrement"] {
-moz-appearance: scrollbarbutton-up;
background-image: url("chrome://global/skin/scrollbar/btn-up.gif")
}

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

@ -0,0 +1,67 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* 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) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
/**
* The nsINativeScrollbar is implemented internally by Gecko as a way
* to communicate between a Gecko frame and a native scrollbar for
* purposes of shimming a native OS scrollbar into the GFX scrollframe
* mechanism.
*
*/
interface nsIPresContext;
interface nsIFrame;
interface nsIContent;
interface nsIScrollbarMediator;
[uuid(dd1cb116-1dd1-11b2-9e67-abac4e09d533)]
interface nsINativeScrollbar : nsISupports
{
void setContent ( in nsIContent content, in nsIScrollbarMediator mediator);
readonly attribute long narrowSize; // the width of a vertical scrollbar, height of horizontal
attribute unsigned long position; // current position of the scrollbar
attribute unsigned long maxRange; // max value of the scrollbar
attribute unsigned long lineIncrement; // number of pixels to scroll per "line" (one click of scroll arrow)
attribute unsigned long viewSize; // size of the visible area we're scrolling (in pixels)
};

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

@ -0,0 +1,504 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* 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) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsNativeScrollbar.h"
#include "nsIDeviceContext.h"
#if TARGET_CARBON || (UNIVERSAL_INTERFACES_VERSION >= 0x0330)
#include <ControlDefinitions.h>
#endif
#include "nsWidgetAtoms.h"
#include "nsWatchTask.h"
#include "nsINameSpaceManager.h"
#include "nsIDOMElement.h"
#include "nsIScrollbarMediator.h"
#include "Sound.h"
NS_INTERFACE_MAP_BEGIN(nsNativeScrollbar)
NS_INTERFACE_MAP_ENTRY(nsINativeScrollbar)
NS_INTERFACE_MAP_END_INHERITING(nsWindow)
NS_IMPL_ADDREF(nsNativeScrollbar);
NS_IMPL_RELEASE(nsNativeScrollbar);
//
// StControlActionProcOwner
//
// A class that wraps a control action proc so that it is disposed of
// correctly when the shared library shuts down
//
class StNativeControlActionProcOwner {
public:
StNativeControlActionProcOwner ( )
{
sControlActionProc = NewControlActionUPP(nsNativeScrollbar::ScrollActionProc);
NS_ASSERTION(sControlActionProc, "Couldn't create live scrolling action proc");
}
~StNativeControlActionProcOwner ( )
{
if ( sControlActionProc )
DisposeControlActionUPP(sControlActionProc);
}
ControlActionUPP ActionProc() { return sControlActionProc; }
private:
ControlActionUPP sControlActionProc;
};
static ControlActionUPP ScrollbarActionProc ( );
static ControlActionUPP
ScrollbarActionProc ( )
{
static StNativeControlActionProcOwner sActionProcOwner;
return sActionProcOwner.ActionProc();
}
nsNativeScrollbar::nsNativeScrollbar()
: nsMacControl()
, mContent(nsnull)
, mMediator(nsnull)
, mLineIncrement(0)
, mMaxValue(0)
, mVisibleImageSize(0)
, mMouseDownInScroll(PR_FALSE)
, mClickedPartCode(0)
{
WIDGET_SET_CLASSNAME("nsNativeScrollbar");
SetControlType(kControlScrollBarLiveProc);
}
nsNativeScrollbar::~nsNativeScrollbar()
{
}
//
// ScrollActionProc
//
// Called from the OS toolbox while the scrollbar is being tracked.
//
pascal void
nsNativeScrollbar::ScrollActionProc(ControlHandle ctrl, ControlPartCode part)
{
nsNativeScrollbar* self = (nsNativeScrollbar*)(::GetControlReference(ctrl));
NS_ASSERTION(self, "NULL nsNativeScrollbar");
if ( self )
self->DoScrollAction(part);
}
//
// DoScrollAction
//
// Called from the action proc of the scrollbar, adjust the control's
// value as well as the value in the content node which communicates
// to gecko that the document is scrolling.
//
void
nsNativeScrollbar::DoScrollAction(ControlPartCode part)
{
PRUint32 oldPos, newPos;
PRUint32 incr;
PRUint32 visibleImageSize;
PRInt32 scrollBarMessage = 0;
GetPosition(&oldPos);
GetLineIncrement(&incr);
GetViewSize(&visibleImageSize);
switch(part)
{
//
// For the up/down buttons, scroll up or down by the line height and
// update the attributes on the content node (the scroll frame listens
// for these attributes and will scroll accordingly). However,
// if we have a mediator, we're in an outliner and we have to scroll by
// lines. Outliner ignores the params to ScrollbarButtonPressed() except
// to check if one is greater than the other to indicate direction.
//
case kControlUpButtonPart:
if ( mMediator )
mMediator->ScrollbarButtonPressed(1,0);
else {
newPos = oldPos - incr;
UpdateContentPosition(newPos);
}
break;
case kControlDownButtonPart:
if ( mMediator )
mMediator->ScrollbarButtonPressed(0,1);
else {
newPos = oldPos + incr;
UpdateContentPosition(newPos);
}
break;
//
// For page up/down and dragging the thumb, scroll by the page height
// (or directly report the value of the scrollbar) and update the attributes
// on the content node (as above). If we have a mediator, we're in an
// outliner so tell it directly that the position has changed. Note that
// outliner takes signed values, so we have to convert our unsigned to
// signed values first.
//
case kControlPageUpPart:
newPos = oldPos - visibleImageSize;
UpdateContentPosition(newPos);
if ( mMediator ) {
PRInt32 op = oldPos, np = mValue;
if ( np < 0 )
np = 0;
mMediator->PositionChanged(op, np);
}
break;
case kControlPageDownPart:
newPos = oldPos + visibleImageSize;
UpdateContentPosition(newPos);
if ( mMediator ) {
PRInt32 op = oldPos, np = mValue;
if ( np < 0 )
np = 0;
mMediator->PositionChanged(op, np);
}
break;
case kControlIndicatorPart:
newPos = ::GetControl32BitValue(GetControl());
UpdateContentPosition(newPos);
if ( mMediator ) {
PRInt32 op = oldPos, np = mValue;
if ( np < 0 )
np = 0;
mMediator->PositionChanged(op, np);
}
break;
}
EndDraw();
// update the area of the parent uncovered by the scrolling. Since
// we may be in a tight loop, we need to manually validate the area
// we just updated so the update rect doesn't continue to get bigger
// and bigger the more we scroll.
nsCOMPtr<nsIWidget> parent ( dont_AddRef(GetParent()) );
parent->Update();
parent->Validate();
StartDraw();
}
//
// UpdateContentPosition
//
// Tell the content node that the scrollbar has changed value and
// then update the scrollbar's position
//
void
nsNativeScrollbar::UpdateContentPosition(PRUint32 inNewPos)
{
if ( inNewPos == mValue || !mContent ) // break any possible recursion
return;
// convert the int to a string
char buffer[20];
sprintf(buffer, "%d", inNewPos);
mContent->SetAttr(kNameSpaceID_None, nsWidgetAtoms::curpos, NS_ConvertASCIItoUCS2(buffer), PR_TRUE);
SetPosition(inNewPos);
}
/**-------------------------------------------------------------------------------
* DispatchMouseEvent handle an event for this scrollbar
* @update dc 08/31/98
* @Param aEvent -- The mouse event to respond to for this button
* @return -- True if the event was handled, PR_FALSE if we did not handle it.
*/
PRBool
nsNativeScrollbar::DispatchMouseEvent(nsMouseEvent &aEvent)
{
PRBool eatEvent = PR_FALSE;
switch (aEvent.message)
{
case NS_MOUSE_LEFT_DOUBLECLICK:
case NS_MOUSE_LEFT_BUTTON_DOWN:
NS_ASSERTION(this != 0, "NULL nsNativeScrollbar2");
::SetControlReference(mControl, (UInt32) this);
StartDraw();
{
Point thePoint;
thePoint.h = aEvent.point.x;
thePoint.v = aEvent.point.y;
mClickedPartCode = ::TestControl(mControl, thePoint);
if (mClickedPartCode > 0)
::HiliteControl(mControl, mClickedPartCode);
switch (mClickedPartCode)
{
case kControlUpButtonPart:
case kControlDownButtonPart:
case kControlPageUpPart:
case kControlPageDownPart:
case kControlIndicatorPart:
// We are assuming Appearance 1.1 or later, so we
// have the "live scroll" variant of the scrollbar,
// which lets you pass the action proc to TrackControl
// for the thumb (this was illegal in previous
// versions of the defproc).
nsWatchTask::GetTask().Suspend();
::TrackControl(mControl, thePoint, ScrollbarActionProc());
nsWatchTask::GetTask().Resume();
::HiliteControl(mControl, 0);
// We don't dispatch the mouseDown event because mouseUp is eaten
// by TrackControl anyway and the only messages the app really
// cares about are the NS_SCROLLBAR_xxx messages.
eatEvent = PR_TRUE;
break;
}
SetPosition(mValue);
}
EndDraw();
break;
case NS_MOUSE_LEFT_BUTTON_UP:
mClickedPartCode = 0;
break;
case NS_MOUSE_EXIT:
if (mWidgetArmed)
{
StartDraw();
::HiliteControl(mControl, 0);
EndDraw();
}
break;
case NS_MOUSE_ENTER:
if (mWidgetArmed)
{
StartDraw();
::HiliteControl(mControl, mClickedPartCode);
EndDraw();
}
break;
}
if (eatEvent)
return PR_TRUE;
return (Inherited::DispatchMouseEvent(aEvent));
}
//
// SetMaxRange
//
// Set the maximum range of a scroll bar. This should be set to the
// full scrollable area minus the visible area.
//
NS_IMETHODIMP
nsNativeScrollbar::SetMaxRange(PRUint32 aEndRange)
{
mMaxValue = ((int)aEndRange) > 0 ? aEndRange : 10;
if ( GetControl() ) {
StartDraw();
::SetControl32BitMaximum(GetControl(), mMaxValue);
EndDraw();
}
return NS_OK;
}
//
// GetMaxRange
//
// Get the maximum range of a scroll bar
//
NS_IMETHODIMP
nsNativeScrollbar::GetMaxRange(PRUint32* aMaxRange)
{
*aMaxRange = mMaxValue;
return NS_OK;
}
//
// SetPosition
//
// Set the current position of the slider and redraw the scrollbar
//
NS_IMETHODIMP
nsNativeScrollbar::SetPosition(PRUint32 aPos)
{
if ((PRInt32)aPos < 0)
aPos = 0;
PRInt32 oldValue = mValue;
mValue = ((PRInt32)aPos) > mMaxValue ? mMaxValue : ((int)aPos);
// redraw the scrollbar. We can do the update later since we'll
// always redraw our parent when we're in a tight loop.
if ( mValue != oldValue )
Invalidate(PR_FALSE);
return NS_OK;
}
//
// GetPosition
//
// Get the current position of the slider
//
NS_IMETHODIMP
nsNativeScrollbar::GetPosition(PRUint32* aPos)
{
*aPos = mValue;
return NS_OK;
}
//
// SetViewSize
//
// According to the toolbox docs, we pass the height of the
// visible view area to SetControlViewSize(). Assuming we've set
// the max to the total area - view height, this will give us a correct
// proportional scrollbar.
//
NS_IMETHODIMP
nsNativeScrollbar::SetViewSize(PRUint32 aSize)
{
mVisibleImageSize = ((int)aSize) > 0 ? aSize : 1;
if ( GetControl() ) {
StartDraw();
SetControlViewSize(GetControl(), mVisibleImageSize);
EndDraw();
}
return NS_OK;
}
//
// GetViewSize
//
// Get the height of the visible view area.
//
NS_IMETHODIMP
nsNativeScrollbar::GetViewSize(PRUint32* aSize)
{
*aSize = mVisibleImageSize;
return NS_OK;
}
//
// SetLineIncrement
//
// Set the line increment of the scroll bar
//
NS_IMETHODIMP
nsNativeScrollbar::SetLineIncrement(PRUint32 aLineIncrement)
{
mLineIncrement = (((int)aLineIncrement) > 0 ? aLineIncrement : 1);
return NS_OK;
}
//
// GetLineIncrement
//
// Get the line increment of the scroll bar
//
NS_IMETHODIMP
nsNativeScrollbar::GetLineIncrement(PRUint32* aLineIncrement)
{
*aLineIncrement = mLineIncrement;
return NS_OK;
}
//
// GetNarrowSize
//
// Ask the appearance manager for the dimensions of the narrow axis
// of the scrollbar. We cheat and assume the width of a vertical scrollbar
// is the same as the height of a horizontal scrollbar. *shrug*. Shoot me.
//
NS_IMETHODIMP
nsNativeScrollbar::GetNarrowSize(PRInt32* outSize)
{
if ( *outSize )
return NS_ERROR_FAILURE;
SInt32 width = 0;
#if TARGET_CARBON
::GetThemeMetric(kThemeMetricScrollBarWidth, &width);
#else
width = 16;
#endif
*outSize = width;
return NS_OK;
}
//
// SetContent
//
// Hook up this native scrollbar to the rest of gecko. We care about
// the content so we can set attributes on it to affect the scrollview. We
// care about the mediator for <outliner> so we can do row-based scrolling.
//
NS_IMETHODIMP
nsNativeScrollbar::SetContent(nsIContent* inContent, nsIScrollbarMediator* inMediator)
{
mContent = inContent;
mMediator = inMediator;
return NS_OK;
}

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

@ -0,0 +1,106 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* 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) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsNativeScrollbar_h__
#define nsNativeScrollbar_h__
#include "nsMacControl.h"
#include "nsINativeScrollbar.h"
#include <Controls.h>
#include "nsIContent.h"
class nsIScrollbarMediator;
class StControlProcSingleton5;
//
// nsNativeScrollbar
//
// A wrapper around a MacOS native scrollbar that knows how to work
// with a stub gecko frame to scroll in the GFXScrollFrame mechanism
//
// {c2281100-3b4b-11d6-a384-f705fd0766fc}
#define NS_NATIVESCROLLBAR_CID \
{ 0xc2281100, 0x3b4b, 0x11d6, { 0xa3, 0x84, 0xf7, 0x05, 0xfd, 0x07, 0x66, 0xfc } }
class nsNativeScrollbar : public nsMacControl, public nsINativeScrollbar
{
private:
typedef nsMacControl Inherited;
public:
nsNativeScrollbar();
virtual ~nsNativeScrollbar();
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSINATIVESCROLLBAR
protected:
// nsWindow Interface
virtual PRBool DispatchMouseEvent(nsMouseEvent &aEvent);
ControlHandle GetControl() { return mControl; }
void UpdateContentPosition(PRUint32 inNewPos);
private:
friend class StNativeControlActionProcOwner;
static pascal void ScrollActionProc(ControlHandle, ControlPartCode);
void DoScrollAction(ControlPartCode);
// DATA
private:
nsIContent* mContent; // the content node that affects the scrollbar's value
nsIScrollbarMediator* mMediator; // for scrolling with outliners
PRUint32 mMaxValue;
PRUint32 mVisibleImageSize;
PRUint32 mLineIncrement;
PRBool mMouseDownInScroll;
ControlPartCode mClickedPartCode;
};
#endif // nsNativeScrollbar_

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

@ -0,0 +1,13 @@
<?xml version="1.0"?>
<bindings id="scrollbarBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="scrollbar">
<content>
<xul:nativescrollbar flex="1" inherits="curpos,maxpos,pageincrement,increment,orient,sborient=orient"/>
</content>
</binding>
</bindings>