Fix bugs 45881 and 46850 -- general caret cruft. Ensure that caret is clipped to the scrolling view, and fix things so that the caret is properly hidden on scrolling. r=beard

This commit is contained in:
sfraser%netscape.com 2000-09-07 05:26:25 +00:00
parent 52fdde87b9
commit 5543105886
7 changed files with 1048 additions and 976 deletions

File diff suppressed because it is too large Load Diff

View File

@ -41,72 +41,72 @@ class nsISelectionController;
class nsCaret : public nsICaret,
public nsIDOMSelectionListener
{
public:
public:
nsCaret();
virtual ~nsCaret();
nsCaret();
virtual ~nsCaret();
NS_DECL_ISUPPORTS
NS_DECL_ISUPPORTS
public:
// nsICaret interface
NS_IMETHOD Init(nsIPresShell *inPresShell);
public:
// nsICaret interface
NS_IMETHOD Init(nsIPresShell *inPresShell);
NS_IMETHOD SetCaretDOMSelection(nsIDOMSelection *inDOMSel);
NS_IMETHOD GetCaretVisible(PRBool *outMakeVisible);
NS_IMETHOD SetCaretVisible(PRBool intMakeVisible);
NS_IMETHOD SetCaretReadOnly(PRBool inMakeReadonly);
NS_IMETHOD GetWindowRelativeCoordinates(nsRect& outCoordinates, PRBool& outIsCollapsed, nsIDOMSelection *inDOMSel);
NS_IMETHOD ClearFrameRefs(nsIFrame* aFrame);
NS_IMETHOD EraseCaret();
NS_IMETHOD SetCaretVisible(PRBool intMakeVisible);
NS_IMETHOD SetCaretReadOnly(PRBool inMakeReadonly);
NS_IMETHOD GetWindowRelativeCoordinates(nsRect& outCoordinates, PRBool& outIsCollapsed, nsIDOMSelection *inDOMSel);
NS_IMETHOD ClearFrameRefs(nsIFrame* aFrame);
NS_IMETHOD EraseCaret();
NS_IMETHOD SetCaretWidth(nscoord aPixels);
//nsIDOMSelectionListener interface
NS_IMETHOD NotifySelectionChanged(nsIDOMDocument *aDoc, nsIDOMSelection *aSel, short aReason);
static void CaretBlinkCallback(nsITimer *aTimer, void *aClosure);
protected:
//nsIDOMSelectionListener interface
NS_IMETHOD NotifySelectionChanged(nsIDOMDocument *aDoc, nsIDOMSelection *aSel, short aReason);
static void CaretBlinkCallback(nsITimer *aTimer, void *aClosure);
protected:
void KillTimer();
nsresult PrimeTimer();
nsresult StartBlinking();
nsresult StopBlinking();
enum EViewCoordinates {
eTopLevelWindowCoordinates,
eViewCoordinates
};
void GetViewForRendering(nsIFrame *caretFrame, EViewCoordinates coordType, nsPoint &viewOffset, nsIView* &outView);
PRBool SetupDrawingFrameAndOffset();
PRBool MustDrawCaret();
void RefreshDrawCaret(nsIView *aView, nsIRenderingContext& inRendContext, const nsRect& aDirtyRect);
void DrawCaretWithContext(nsIRenderingContext* inRendContext);
void KillTimer();
nsresult PrimeTimer();
nsresult StartBlinking();
nsresult StopBlinking();
enum EViewCoordinates {
eTopLevelWindowCoordinates,
eViewCoordinates
};
void GetViewForRendering(nsIFrame *caretFrame, EViewCoordinates coordType, nsPoint &viewOffset, nsRect& outClipRect, nsIView* &outView);
PRBool SetupDrawingFrameAndOffset();
PRBool MustDrawCaret();
void RefreshDrawCaret(nsIView *aView, nsIRenderingContext& inRendContext, const nsRect& aDirtyRect);
void DrawCaretWithContext(nsIRenderingContext* inRendContext);
void DrawCaret();
void ToggleDrawnStatus() { mDrawn = !mDrawn; }
void DrawCaret();
void ToggleDrawnStatus() { mDrawn = !mDrawn; }
nsCOMPtr<nsIWeakReference> mPresShell;
nsCOMPtr<nsIWeakReference> mPresShell;
nsCOMPtr<nsITimer> mBlinkTimer;
PRUint32 mBlinkRate; // time for one cyle (off then on), in milliseconds
nscoord mCaretTwipsWidth; // caret width in twips
nscoord mCaretPixelsWidth; // caret width in pixels
PRBool mVisible; // is the caret blinking
PRBool mReadOnly; // it the caret in readonly state (draws differently)
private:
PRBool mDrawn; // this should be mutable
nsRect mCaretRect; // the last caret rect
nsIFrame* mLastCaretFrame; // store the frame the caret was last drawn in.
PRInt32 mLastContentOffset;
PRUint32 mBlinkRate; // time for one cyle (off then on), in milliseconds
nscoord mCaretTwipsWidth; // caret width in twips
nscoord mCaretPixelsWidth; // caret width in pixels
PRBool mVisible; // is the caret blinking
PRBool mReadOnly; // it the caret in readonly state (draws differently)
private:
PRBool mDrawn; // this should be mutable
nsRect mCaretRect; // the last caret rect
nsIFrame* mLastCaretFrame; // store the frame the caret was last drawn in.
PRInt32 mLastContentOffset;
nsWeakPtr mDomSelectionWeak;
};

View File

@ -2019,9 +2019,11 @@ NS_IMETHODIMP PresShell::SetCaretEnabled(PRBool aInEnable)
if (mCaret && (mCaretEnabled != oldEnabled))
{
/* Don't change the caret's selection here! This was an evil side-effect of SetCaretEnabled()
nsCOMPtr<nsIDOMSelection> domSel;
if (NS_SUCCEEDED(GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(domSel))) && domSel)
mCaret->SetCaretDOMSelection(domSel);
*/
result = mCaret->SetCaretVisible(mCaretEnabled);
}

File diff suppressed because it is too large Load Diff

View File

@ -41,72 +41,72 @@ class nsISelectionController;
class nsCaret : public nsICaret,
public nsIDOMSelectionListener
{
public:
public:
nsCaret();
virtual ~nsCaret();
nsCaret();
virtual ~nsCaret();
NS_DECL_ISUPPORTS
NS_DECL_ISUPPORTS
public:
// nsICaret interface
NS_IMETHOD Init(nsIPresShell *inPresShell);
public:
// nsICaret interface
NS_IMETHOD Init(nsIPresShell *inPresShell);
NS_IMETHOD SetCaretDOMSelection(nsIDOMSelection *inDOMSel);
NS_IMETHOD GetCaretVisible(PRBool *outMakeVisible);
NS_IMETHOD SetCaretVisible(PRBool intMakeVisible);
NS_IMETHOD SetCaretReadOnly(PRBool inMakeReadonly);
NS_IMETHOD GetWindowRelativeCoordinates(nsRect& outCoordinates, PRBool& outIsCollapsed, nsIDOMSelection *inDOMSel);
NS_IMETHOD ClearFrameRefs(nsIFrame* aFrame);
NS_IMETHOD EraseCaret();
NS_IMETHOD SetCaretVisible(PRBool intMakeVisible);
NS_IMETHOD SetCaretReadOnly(PRBool inMakeReadonly);
NS_IMETHOD GetWindowRelativeCoordinates(nsRect& outCoordinates, PRBool& outIsCollapsed, nsIDOMSelection *inDOMSel);
NS_IMETHOD ClearFrameRefs(nsIFrame* aFrame);
NS_IMETHOD EraseCaret();
NS_IMETHOD SetCaretWidth(nscoord aPixels);
//nsIDOMSelectionListener interface
NS_IMETHOD NotifySelectionChanged(nsIDOMDocument *aDoc, nsIDOMSelection *aSel, short aReason);
static void CaretBlinkCallback(nsITimer *aTimer, void *aClosure);
protected:
//nsIDOMSelectionListener interface
NS_IMETHOD NotifySelectionChanged(nsIDOMDocument *aDoc, nsIDOMSelection *aSel, short aReason);
static void CaretBlinkCallback(nsITimer *aTimer, void *aClosure);
protected:
void KillTimer();
nsresult PrimeTimer();
nsresult StartBlinking();
nsresult StopBlinking();
enum EViewCoordinates {
eTopLevelWindowCoordinates,
eViewCoordinates
};
void GetViewForRendering(nsIFrame *caretFrame, EViewCoordinates coordType, nsPoint &viewOffset, nsIView* &outView);
PRBool SetupDrawingFrameAndOffset();
PRBool MustDrawCaret();
void RefreshDrawCaret(nsIView *aView, nsIRenderingContext& inRendContext, const nsRect& aDirtyRect);
void DrawCaretWithContext(nsIRenderingContext* inRendContext);
void KillTimer();
nsresult PrimeTimer();
nsresult StartBlinking();
nsresult StopBlinking();
enum EViewCoordinates {
eTopLevelWindowCoordinates,
eViewCoordinates
};
void GetViewForRendering(nsIFrame *caretFrame, EViewCoordinates coordType, nsPoint &viewOffset, nsRect& outClipRect, nsIView* &outView);
PRBool SetupDrawingFrameAndOffset();
PRBool MustDrawCaret();
void RefreshDrawCaret(nsIView *aView, nsIRenderingContext& inRendContext, const nsRect& aDirtyRect);
void DrawCaretWithContext(nsIRenderingContext* inRendContext);
void DrawCaret();
void ToggleDrawnStatus() { mDrawn = !mDrawn; }
void DrawCaret();
void ToggleDrawnStatus() { mDrawn = !mDrawn; }
nsCOMPtr<nsIWeakReference> mPresShell;
nsCOMPtr<nsIWeakReference> mPresShell;
nsCOMPtr<nsITimer> mBlinkTimer;
PRUint32 mBlinkRate; // time for one cyle (off then on), in milliseconds
nscoord mCaretTwipsWidth; // caret width in twips
nscoord mCaretPixelsWidth; // caret width in pixels
PRBool mVisible; // is the caret blinking
PRBool mReadOnly; // it the caret in readonly state (draws differently)
private:
PRBool mDrawn; // this should be mutable
nsRect mCaretRect; // the last caret rect
nsIFrame* mLastCaretFrame; // store the frame the caret was last drawn in.
PRInt32 mLastContentOffset;
PRUint32 mBlinkRate; // time for one cyle (off then on), in milliseconds
nscoord mCaretTwipsWidth; // caret width in twips
nscoord mCaretPixelsWidth; // caret width in pixels
PRBool mVisible; // is the caret blinking
PRBool mReadOnly; // it the caret in readonly state (draws differently)
private:
PRBool mDrawn; // this should be mutable
nsRect mCaretRect; // the last caret rect
nsIFrame* mLastCaretFrame; // store the frame the caret was last drawn in.
PRInt32 mLastContentOffset;
nsWeakPtr mDomSelectionWeak;
};

View File

@ -2019,9 +2019,11 @@ NS_IMETHODIMP PresShell::SetCaretEnabled(PRBool aInEnable)
if (mCaret && (mCaretEnabled != oldEnabled))
{
/* Don't change the caret's selection here! This was an evil side-effect of SetCaretEnabled()
nsCOMPtr<nsIDOMSelection> domSel;
if (NS_SUCCEEDED(GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(domSel))) && domSel)
mCaret->SetCaretDOMSelection(domSel);
*/
result = mCaret->SetCaretVisible(mCaretEnabled);
}

View File

@ -696,25 +696,27 @@ NS_IMETHODIMP
nsTextInputSelectionImpl::SetCaretEnabled(PRBool enabled)
{
if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
nsresult result;
nsCOMPtr<nsIPresShell> shell = do_QueryReferent(mPresShellWeak, &result);
if (shell)
{
nsCOMPtr<nsICaret> caret;
if (NS_SUCCEEDED(result = shell->GetCaret(getter_AddRefs(caret))))
{
nsCOMPtr<nsIDOMSelection> domSel;
if (NS_SUCCEEDED(result = mFrameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(domSel))))
{
nsCOMPtr<nsIDOMSelection> domSel;
if (NS_SUCCEEDED(GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(domSel))) && domSel)
caret->SetCaretDOMSelection(domSel);
return caret->SetCaretVisible(enabled);
}
}
}
return NS_ERROR_FAILURE;
nsCOMPtr<nsIPresShell> shell = do_QueryReferent(mPresShellWeak);
if (!shell) return NS_ERROR_FAILURE;
// first, tell the caret which selection to use
nsCOMPtr<nsIDOMSelection> domSel;
GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(domSel));
if (!domSel) return NS_ERROR_FAILURE;
nsCOMPtr<nsICaret> caret;
shell->GetCaret(getter_AddRefs(caret));
if (!caret) return NS_OK;
caret->SetCaretDOMSelection(domSel);
// tell the pres shell to enable the caret, rather than settings its visibility directly.
// this way the presShell's idea of caret visibility is maintained.
nsCOMPtr<nsISelectionController> selCon = do_QueryInterface(shell);
if (!selCon) return NS_ERROR_NO_INTERFACE;
selCon->SetCaretEnabled(enabled);
return NS_OK;
}
NS_IMETHODIMP