layout/base/nsCaret.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set ts=2 sw=2 et tw=78: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 /* the caret is the text cursor used, e.g., when editing */
     9 #ifndef nsCaret_h__
    10 #define nsCaret_h__
    12 #include "nsCoord.h"
    13 #include "nsISelectionListener.h"
    14 #include "nsIWeakReferenceUtils.h"
    15 #include "nsFrameSelection.h"
    17 class nsRenderingContext;
    18 class nsDisplayListBuilder;
    19 class nsITimer;
    21 //-----------------------------------------------------------------------------
    22 class nsCaret : public nsISelectionListener
    23 {
    24   public:
    26                   nsCaret();
    27     virtual       ~nsCaret();
    29     enum EViewCoordinates {
    30       eTopLevelWindowCoordinates,
    31       eRenderingViewCoordinates,
    32       eClosestViewCoordinates
    33     };
    35   public:
    37     NS_DECL_ISUPPORTS
    39     nsresult    Init(nsIPresShell *inPresShell);
    40     void    Terminate();
    42     nsISelection*    GetCaretDOMSelection();
    43     nsresult    SetCaretDOMSelection(nsISelection *inDOMSel);
    45     /** GetCaretVisible will get the visibility of the caret
    46      *  This function is virtual so that it can be used by nsCaretAccessible
    47      *  without linking
    48      *  @param inMakeVisible true it is shown, false it is hidden
    49      *  @return false if and only if inMakeVisible is null, otherwise true 
    50      */
    51     virtual nsresult    GetCaretVisible(bool *outMakeVisible);
    53     /** SetCaretVisible will set the visibility of the caret
    54      *  @param inMakeVisible true to show the caret, false to hide it
    55      */
    56     void    SetCaretVisible(bool intMakeVisible);
    58     /** SetCaretReadOnly set the appearance of the caret
    59      *  @param inMakeReadonly true to show the caret in a 'read only' state,
    60      *	    false to show the caret in normal, editing state
    61      */
    62     void    SetCaretReadOnly(bool inMakeReadonly);
    64     /** GetCaretReadOnly get the appearance of the caret
    65      *	@return true if the caret is in 'read only' state, otherwise,
    66      *	    returns false
    67      */
    68     bool GetCaretReadOnly()
    69     {
    70       return mReadOnly;
    71     }
    73     /**
    74      * Gets the position and size of the caret that would be drawn for
    75      * the focus node/offset of aSelection (assuming it would be drawn,
    76      * i.e., disregarding blink status). The geometry is stored in aRect,
    77      * and we return the frame aRect is relative to.
    78      * @param aRect must be non-null
    79      * @param aBidiIndicatorSize if non-null, set to the bidi indicator size.
    80      */
    81     virtual nsIFrame* GetGeometry(nsISelection* aSelection,
    82                                   nsRect* aRect,
    83                                   nscoord* aBidiIndicatorSize = nullptr);
    85     /** EraseCaret
    86      *  this will erase the caret if its drawn and reset drawn status
    87      */
    88     void    EraseCaret();
    90     void    SetVisibilityDuringSelection(bool aVisibility);
    92     /** DrawAtPosition
    93      *
    94      *  Draw the caret explicitly, at the specified node and offset.
    95      *  To avoid drawing glitches, you should call EraseCaret()
    96      *  after each call to DrawAtPosition().
    97      *
    98      *  Note: This call breaks the caret's ability to blink at all.
    99      **/
   100     nsresult    DrawAtPosition(nsIDOMNode* aNode, int32_t aOffset);
   102     /** GetCaretFrame
   103      *  Get the current frame that the caret should be drawn in. If the caret is
   104      *  not currently visible (i.e., it is between blinks), then this will
   105      *  return null.
   106      *
   107      *  @param aOffset is result of the caret offset in the content.
   108      */
   109     nsIFrame*     GetCaretFrame(int32_t *aOffset = nullptr);
   111     /** GetCaretRect
   112      *  Get the current caret rect. Only call this when GetCaretFrame returns
   113      *  non-null.
   114      */
   115     nsRect        GetCaretRect()
   116     {
   117       nsRect r;
   118       r.UnionRect(mCaretRect, GetHookRect());
   119       return r;
   120     }
   122     /** InvalidateOutsideCaret
   123      *  Invalidate the area that the caret currently occupies if the caret is
   124      *  outside of its frame's overflow area. This is used when the content that
   125      *  the caret is currently drawn is is being deleted or reflowed.
   126      */
   127     void      InvalidateOutsideCaret();
   129     /** UpdateCaretPosition
   130      *  Update the caret's current frame and rect, but don't draw yet. This is
   131      *  useful for flickerless moving of the caret (e.g., when the frame the
   132      *  caret is in reflows and is moved).
   133      */
   134     void      UpdateCaretPosition();
   136     /** PaintCaret
   137      *  Actually paint the caret onto the given rendering context.
   138      */
   139     void      PaintCaret(nsDisplayListBuilder *aBuilder,
   140                          nsRenderingContext *aCtx,
   141                          nsIFrame *aForFrame,
   142                          const nsPoint &aOffset);
   143     /**
   144      * Sets whether the caret should only be visible in nodes that are not
   145      * user-modify: read-only, or whether it should be visible in all nodes.
   146      *
   147      * @param aIgnoreUserModify true to have the cursor visible in all nodes,
   148      *                          false to have it visible in all nodes except
   149      *                          those with user-modify: read-only
   150      */
   152     void SetIgnoreUserModify(bool aIgnoreUserModify);
   154     //nsISelectionListener interface
   155     NS_DECL_NSISELECTIONLISTENER
   157     static void   CaretBlinkCallback(nsITimer *aTimer, void *aClosure);
   159     nsresult      GetCaretFrameForNodeOffset(nsIContent* aContentNode,
   160                                              int32_t aOffset,
   161                                              nsFrameSelection::HINT aFrameHint,
   162                                              uint8_t aBidiLevel,
   163                                              nsIFrame** aReturnFrame,
   164                                              int32_t* aReturnOffset);
   166     void CheckCaretDrawingState();
   168 protected:
   170     void          KillTimer();
   171     nsresult      PrimeTimer();
   173     void          StartBlinking();
   174     void          StopBlinking();
   176     bool          DrawAtPositionWithHint(nsIDOMNode* aNode,
   177                                          int32_t aOffset,
   178                                          nsFrameSelection::HINT aFrameHint,
   179                                          uint8_t aBidiLevel,
   180                                          bool aInvalidate);
   182     struct Metrics {
   183       nscoord mBidiIndicatorSize; // width and height of bidi indicator
   184       nscoord mCaretWidth;        // full caret width including bidi indicator
   185     };
   186     Metrics ComputeMetrics(nsIFrame* aFrame, int32_t aOffset, nscoord aCaretHeight);
   187     nsresult GetGeometryForFrame(nsIFrame* aFrame,
   188                                  int32_t   aFrameOffset,
   189                                  nsRect*   aRect,
   190                                  nscoord*  aBidiIndicatorSize);
   192     // Returns true if the caret should be drawn. When |mDrawn| is true,
   193     // this returns true, so that we erase the drawn caret. If |aIgnoreDrawnState|
   194     // is true, we don't take into account whether the caret is currently
   195     // drawn or not. This can be used to determine if the caret is drawn when
   196     // it shouldn't be.
   197     bool          MustDrawCaret(bool aIgnoreDrawnState);
   199     void          DrawCaret(bool aInvalidate);
   200     void          DrawCaretAfterBriefDelay();
   201     bool          UpdateCaretRects(nsIFrame* aFrame, int32_t aFrameOffset);
   202     nsRect        GetHookRect()
   203     {
   204       return mHookRect;
   205     }
   206     void          ToggleDrawnStatus() { mDrawn = !mDrawn; }
   208     nsFrameSelection* GetFrameSelection();
   210     // Returns true if we should not draw the caret because of XUL menu popups.
   211     // The caret should be hidden if:
   212     // 1. An open popup contains the caret, but a menu popup exists before the
   213     //    caret-owning popup in the popup list (i.e. a menu is in front of the
   214     //    popup with the caret). If the menu itself contains the caret we don't
   215     //    hide it.
   216     // 2. A menu popup is open, but there is no caret present in any popup.
   217     // 3. The caret selection is empty.
   218     bool IsMenuPopupHidingCaret();
   220 protected:
   222     nsWeakPtr             mPresShell;
   223     nsWeakPtr             mDomSelectionWeak;
   225     nsCOMPtr<nsITimer>    mBlinkTimer;
   227     // XXX these fields should go away and the values be acquired as needed,
   228     // probably by ComputeMetrics.
   229     uint32_t              mBlinkRate;         // time for one cyle (on then off), in milliseconds
   230     nscoord               mCaretWidthCSSPx;   // caret width in CSS pixels
   231     float                 mCaretAspectRatio;  // caret width/height aspect ratio
   233     bool                  mVisible;           // is the caret blinking
   235     bool                  mDrawn;             // Denotes when the caret is physically drawn on the screen.
   236     bool                  mPendingDraw;       // True when the last on-state draw was suppressed.
   238     bool                  mReadOnly;          // it the caret in readonly state (draws differently)      
   239     bool                  mShowDuringSelection; // show when text is selected
   241     bool                  mIgnoreUserModify;
   243     bool                  mKeyboardRTL;       // is the keyboard language right-to-left
   244     bool                  mBidiUI;            // is bidi UI turned on
   245     nsRect                mHookRect;          // directional hook on the caret
   246     uint8_t               mLastBidiLevel;     // saved bidi level of the last draw request, to use when we erase
   247     nsRect                mCaretRect;         // the last caret rect, in the coodinates of the last frame.
   249     nsCOMPtr<nsIContent>  mLastContent;       // store the content the caret was last requested to be drawn
   250                                               // in (by DrawAtPosition()/DrawCaret()),
   251                                               // note that this can be different than where it was
   252                                               // actually drawn (anon <BR> in text control)
   253     int32_t               mLastContentOffset; // the offset for the last request
   255     nsFrameSelection::HINT mLastHint;        // the hint associated with the last request, see also
   256                                               // mLastBidiLevel below
   258 };
   260 #endif //nsCaret_h__

mercurial