Fix the drawing part of bug 298677: scrollbars draw in the wrong place. Fixed by registering a Carbon Event handler on the native control that ensures that the port origin is set correctly before control draws. r=josh, jhpedemonte. sr=me. a=shaver.

git-svn-id: svn://10.0.0.236/trunk@175750 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
smfr%smfr.org 2005-07-07 15:47:49 +00:00
parent 7e51b7f153
commit 818da747fa
4 changed files with 136 additions and 10 deletions

View File

@ -40,6 +40,7 @@
#include "nsFont.h"
#include "nsFontUtils.h"
#include "nsToolkit.h"
#include "nsGfxUtils.h"
#include "nsMacControl.h"
#include "nsColor.h"
@ -55,11 +56,83 @@
#include <UnicodeConverter.h>
#include <Fonts.h>
#if 0
void DumpControlState(ControlHandle inControl, const char* message)
{
if (!message) message = "gdb called";
CGrafPtr curPort;
::GetPort((GrafPtr*)&curPort);
Rect portBounds;
::GetPortBounds(curPort, &portBounds);
Rect controlBounds = {0, 0, 0, 0};
if (inControl)
::GetControlBounds(inControl, &controlBounds);
printf("%20s -- port %p bounds %d, %d, %d, %d, control bounds %d, %d, %d, %d\n", message, curPort,
portBounds.left, portBounds.top, portBounds.right, portBounds.bottom,
controlBounds.left, controlBounds.top, controlBounds.right, controlBounds.bottom);
}
#endif
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
// TODO: leaks, need to release when unloading the dll
nsIUnicodeEncoder * nsMacControl::mUnicodeEncoder = nsnull;
nsIUnicodeDecoder * nsMacControl::mUnicodeDecoder = nsnull;
static const EventTypeSpec kControlEventList[] =
{
{ kEventClassControl, kEventControlDraw }
};
static pascal OSStatus MacControlDrawHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
{
nsMacControl* macControl = NS_REINTERPRET_CAST(nsMacControl*, inUserData);
ControlRef theControl;
::GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &theControl);
CGrafPtr controlPort; // port we're drawing into (usually the control's port)
if (::GetEventParameter(inEvent, kEventParamGrafPort, typeGrafPtr, NULL, sizeof(CGrafPtr), NULL, &controlPort) != noErr)
controlPort = ::GetWindowPort(::GetControlOwner(theControl));
OSStatus err = eventNotHandledErr;
// see if we're already inside a StartDraw/EndDraw (e.g. OnPaint())
if (macControl->IsDrawing())
{
// we need to make sure that the port origin is set correctly for the control's
// widget, because other handlers before us may have messed with it.
nsRect controlBounds;
macControl->GetBounds(controlBounds);
nsPoint origin(controlBounds.x, controlBounds.y);
macControl->LocalToWindowCoordinate(origin);
Point newOrigin;
newOrigin.h = -origin.x;
newOrigin.v = -origin.y;
StOriginSetter setter(controlPort, &newOrigin);
err = ::CallNextEventHandler(inHandlerCallRef, inEvent);
}
else
{
// make sure we leave the origin set for other controls
StOriginSetter originSetter(controlPort);
macControl->StartDraw();
err = ::CallNextEventHandler(inHandlerCallRef, inEvent);
macControl->EndDraw();
}
return err;
}
#pragma mark -
//-------------------------------------------------------------------------
//
@ -74,6 +147,7 @@ nsMacControl::nsMacControl()
mMouseInButton = PR_FALSE;
mControl = nsnull;
mControlEventHandler = nsnull;
mControlType = pushButProc;
mLastBounds.SetRect(0,0,0,0);
@ -115,7 +189,7 @@ nsMacControl::~nsMacControl()
if (mControl)
{
Show(PR_FALSE);
::DisposeControl(mControl);
ClearControl();
mControl = nsnull;
}
}
@ -339,21 +413,23 @@ ControlPartCode nsMacControl::GetControlHiliteState()
//
//-------------------------------------------------------------------------
NS_METHOD nsMacControl::CreateOrReplaceMacControl(short inControlType)
nsresult nsMacControl::CreateOrReplaceMacControl(short inControlType)
{
nsRect controlRect;
GetRectForMacControl(controlRect);
Rect macRect;
nsRectToMacRect(controlRect, macRect);
if(nsnull != mWindowPtr)
if (nsnull != mWindowPtr)
{
if (mControl)
::DisposeControl(mControl);
ClearControl();
StartDraw();
mControl = ::NewControl(mWindowPtr, &macRect, "\p", mVisible, mValue, mMin, mMax, inControlType, nil);
EndDraw();
EndDraw();
if (mControl)
InstallEventHandlerOnControl();
// need to reset the font now
// XXX to do: transfer the text in the old control over too
@ -366,6 +442,47 @@ NS_METHOD nsMacControl::CreateOrReplaceMacControl(short inControlType)
return (mControl) ? NS_OK : NS_ERROR_NULL_POINTER;
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
void nsMacControl::ClearControl()
{
RemoveEventHandlerFromControl();
if (mControl)
{
::DisposeControl(mControl);
mControl = nsnull;
}
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
DEFINE_ONE_SHOT_HANDLER_GETTER(MacControlDrawHandler)
OSStatus nsMacControl::InstallEventHandlerOnControl()
{
return ::InstallControlEventHandler(mControl,
GetMacControlDrawHandlerUPP(),
GetEventTypeCount(kControlEventList), kControlEventList,
(void*)this, &mControlEventHandler);
}
//-------------------------------------------------------------------------
//
//
//-------------------------------------------------------------------------
void nsMacControl::RemoveEventHandlerFromControl()
{
if (mControlEventHandler)
{
::RemoveEventHandler(mControlEventHandler);
mControlEventHandler = nsnull;
}
}
//-------------------------------------------------------------------------
//

View File

@ -79,7 +79,13 @@ public:
protected:
NS_METHOD CreateOrReplaceMacControl(short inControlType);
nsresult CreateOrReplaceMacControl(short inControlType);
OSStatus InstallEventHandlerOnControl();
void RemoveEventHandlerFromControl();
void ClearControl();
virtual void GetRectForMacControl(nsRect &outRect);
virtual ControlPartCode GetControlHiliteState();
@ -97,6 +103,7 @@ protected:
PRInt32 mMin;
PRInt32 mMax;
ControlHandle mControl;
EventHandlerRef mControlEventHandler;
short mControlType;
nsString mLastLabel;

View File

@ -47,7 +47,6 @@
#include "nsIDOMElement.h"
#include "nsIScrollbarMediator.h"
#include "Sound.h"
inline void BoundsCheck(PRInt32 low, PRUint32& value, PRUint32 high)
{
@ -178,7 +177,8 @@ nsNativeScrollbar::DoScrollAction(ControlPartCode part)
GetPosition(&oldPos);
GetLineIncrement(&incr);
GetViewSize(&visibleImageSize);
switch(part)
switch (part)
{
//
// For the up/down buttons, scroll up or down by the line height and
@ -485,7 +485,7 @@ nsNativeScrollbar::SetViewSize(PRUint32 aSize)
if ( GetControl() ) {
StartDraw();
SetControlViewSize(GetControl(), mVisibleImageSize);
::SetControlViewSize(GetControl(), mVisibleImageSize);
EndDraw();
}
return NS_OK;

View File

@ -180,6 +180,8 @@ public:
virtual void StartDraw(nsIRenderingContext* aRenderingContext = nsnull);
virtual void EndDraw();
PRBool IsDrawing() const { return mDrawing; }
NS_IMETHOD Update();
virtual void UpdateWidget(nsRect& aRect, nsIRenderingContext* aContext);