layout/base/nsCaret.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/base/nsCaret.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,260 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim: set ts=2 sw=2 et tw=78: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +/* the caret is the text cursor used, e.g., when editing */
    1.11 +
    1.12 +#ifndef nsCaret_h__
    1.13 +#define nsCaret_h__
    1.14 +
    1.15 +#include "nsCoord.h"
    1.16 +#include "nsISelectionListener.h"
    1.17 +#include "nsIWeakReferenceUtils.h"
    1.18 +#include "nsFrameSelection.h"
    1.19 +
    1.20 +class nsRenderingContext;
    1.21 +class nsDisplayListBuilder;
    1.22 +class nsITimer;
    1.23 +
    1.24 +//-----------------------------------------------------------------------------
    1.25 +class nsCaret : public nsISelectionListener
    1.26 +{
    1.27 +  public:
    1.28 +
    1.29 +                  nsCaret();
    1.30 +    virtual       ~nsCaret();
    1.31 +
    1.32 +    enum EViewCoordinates {
    1.33 +      eTopLevelWindowCoordinates,
    1.34 +      eRenderingViewCoordinates,
    1.35 +      eClosestViewCoordinates
    1.36 +    };
    1.37 +
    1.38 +  public:
    1.39 +
    1.40 +    NS_DECL_ISUPPORTS
    1.41 +
    1.42 +    nsresult    Init(nsIPresShell *inPresShell);
    1.43 +    void    Terminate();
    1.44 +
    1.45 +    nsISelection*    GetCaretDOMSelection();
    1.46 +    nsresult    SetCaretDOMSelection(nsISelection *inDOMSel);
    1.47 +
    1.48 +    /** GetCaretVisible will get the visibility of the caret
    1.49 +     *  This function is virtual so that it can be used by nsCaretAccessible
    1.50 +     *  without linking
    1.51 +     *  @param inMakeVisible true it is shown, false it is hidden
    1.52 +     *  @return false if and only if inMakeVisible is null, otherwise true 
    1.53 +     */
    1.54 +    virtual nsresult    GetCaretVisible(bool *outMakeVisible);
    1.55 +
    1.56 +    /** SetCaretVisible will set the visibility of the caret
    1.57 +     *  @param inMakeVisible true to show the caret, false to hide it
    1.58 +     */
    1.59 +    void    SetCaretVisible(bool intMakeVisible);
    1.60 +
    1.61 +    /** SetCaretReadOnly set the appearance of the caret
    1.62 +     *  @param inMakeReadonly true to show the caret in a 'read only' state,
    1.63 +     *	    false to show the caret in normal, editing state
    1.64 +     */
    1.65 +    void    SetCaretReadOnly(bool inMakeReadonly);
    1.66 +
    1.67 +    /** GetCaretReadOnly get the appearance of the caret
    1.68 +     *	@return true if the caret is in 'read only' state, otherwise,
    1.69 +     *	    returns false
    1.70 +     */
    1.71 +    bool GetCaretReadOnly()
    1.72 +    {
    1.73 +      return mReadOnly;
    1.74 +    }
    1.75 +
    1.76 +    /**
    1.77 +     * Gets the position and size of the caret that would be drawn for
    1.78 +     * the focus node/offset of aSelection (assuming it would be drawn,
    1.79 +     * i.e., disregarding blink status). The geometry is stored in aRect,
    1.80 +     * and we return the frame aRect is relative to.
    1.81 +     * @param aRect must be non-null
    1.82 +     * @param aBidiIndicatorSize if non-null, set to the bidi indicator size.
    1.83 +     */
    1.84 +    virtual nsIFrame* GetGeometry(nsISelection* aSelection,
    1.85 +                                  nsRect* aRect,
    1.86 +                                  nscoord* aBidiIndicatorSize = nullptr);
    1.87 +
    1.88 +    /** EraseCaret
    1.89 +     *  this will erase the caret if its drawn and reset drawn status
    1.90 +     */
    1.91 +    void    EraseCaret();
    1.92 +
    1.93 +    void    SetVisibilityDuringSelection(bool aVisibility);
    1.94 +
    1.95 +    /** DrawAtPosition
    1.96 +     *
    1.97 +     *  Draw the caret explicitly, at the specified node and offset.
    1.98 +     *  To avoid drawing glitches, you should call EraseCaret()
    1.99 +     *  after each call to DrawAtPosition().
   1.100 +     *
   1.101 +     *  Note: This call breaks the caret's ability to blink at all.
   1.102 +     **/
   1.103 +    nsresult    DrawAtPosition(nsIDOMNode* aNode, int32_t aOffset);
   1.104 +
   1.105 +    /** GetCaretFrame
   1.106 +     *  Get the current frame that the caret should be drawn in. If the caret is
   1.107 +     *  not currently visible (i.e., it is between blinks), then this will
   1.108 +     *  return null.
   1.109 +     *
   1.110 +     *  @param aOffset is result of the caret offset in the content.
   1.111 +     */
   1.112 +    nsIFrame*     GetCaretFrame(int32_t *aOffset = nullptr);
   1.113 +
   1.114 +    /** GetCaretRect
   1.115 +     *  Get the current caret rect. Only call this when GetCaretFrame returns
   1.116 +     *  non-null.
   1.117 +     */
   1.118 +    nsRect        GetCaretRect()
   1.119 +    {
   1.120 +      nsRect r;
   1.121 +      r.UnionRect(mCaretRect, GetHookRect());
   1.122 +      return r;
   1.123 +    }
   1.124 +
   1.125 +    /** InvalidateOutsideCaret
   1.126 +     *  Invalidate the area that the caret currently occupies if the caret is
   1.127 +     *  outside of its frame's overflow area. This is used when the content that
   1.128 +     *  the caret is currently drawn is is being deleted or reflowed.
   1.129 +     */
   1.130 +    void      InvalidateOutsideCaret();
   1.131 +
   1.132 +    /** UpdateCaretPosition
   1.133 +     *  Update the caret's current frame and rect, but don't draw yet. This is
   1.134 +     *  useful for flickerless moving of the caret (e.g., when the frame the
   1.135 +     *  caret is in reflows and is moved).
   1.136 +     */
   1.137 +    void      UpdateCaretPosition();
   1.138 +
   1.139 +    /** PaintCaret
   1.140 +     *  Actually paint the caret onto the given rendering context.
   1.141 +     */
   1.142 +    void      PaintCaret(nsDisplayListBuilder *aBuilder,
   1.143 +                         nsRenderingContext *aCtx,
   1.144 +                         nsIFrame *aForFrame,
   1.145 +                         const nsPoint &aOffset);
   1.146 +    /**
   1.147 +     * Sets whether the caret should only be visible in nodes that are not
   1.148 +     * user-modify: read-only, or whether it should be visible in all nodes.
   1.149 +     *
   1.150 +     * @param aIgnoreUserModify true to have the cursor visible in all nodes,
   1.151 +     *                          false to have it visible in all nodes except
   1.152 +     *                          those with user-modify: read-only
   1.153 +     */
   1.154 +
   1.155 +    void SetIgnoreUserModify(bool aIgnoreUserModify);
   1.156 +
   1.157 +    //nsISelectionListener interface
   1.158 +    NS_DECL_NSISELECTIONLISTENER
   1.159 +
   1.160 +    static void   CaretBlinkCallback(nsITimer *aTimer, void *aClosure);
   1.161 +
   1.162 +    nsresult      GetCaretFrameForNodeOffset(nsIContent* aContentNode,
   1.163 +                                             int32_t aOffset,
   1.164 +                                             nsFrameSelection::HINT aFrameHint,
   1.165 +                                             uint8_t aBidiLevel,
   1.166 +                                             nsIFrame** aReturnFrame,
   1.167 +                                             int32_t* aReturnOffset);
   1.168 +
   1.169 +    void CheckCaretDrawingState();
   1.170 +
   1.171 +protected:
   1.172 +
   1.173 +    void          KillTimer();
   1.174 +    nsresult      PrimeTimer();
   1.175 +
   1.176 +    void          StartBlinking();
   1.177 +    void          StopBlinking();
   1.178 +
   1.179 +    bool          DrawAtPositionWithHint(nsIDOMNode* aNode,
   1.180 +                                         int32_t aOffset,
   1.181 +                                         nsFrameSelection::HINT aFrameHint,
   1.182 +                                         uint8_t aBidiLevel,
   1.183 +                                         bool aInvalidate);
   1.184 +
   1.185 +    struct Metrics {
   1.186 +      nscoord mBidiIndicatorSize; // width and height of bidi indicator
   1.187 +      nscoord mCaretWidth;        // full caret width including bidi indicator
   1.188 +    };
   1.189 +    Metrics ComputeMetrics(nsIFrame* aFrame, int32_t aOffset, nscoord aCaretHeight);
   1.190 +    nsresult GetGeometryForFrame(nsIFrame* aFrame,
   1.191 +                                 int32_t   aFrameOffset,
   1.192 +                                 nsRect*   aRect,
   1.193 +                                 nscoord*  aBidiIndicatorSize);
   1.194 +
   1.195 +    // Returns true if the caret should be drawn. When |mDrawn| is true,
   1.196 +    // this returns true, so that we erase the drawn caret. If |aIgnoreDrawnState|
   1.197 +    // is true, we don't take into account whether the caret is currently
   1.198 +    // drawn or not. This can be used to determine if the caret is drawn when
   1.199 +    // it shouldn't be.
   1.200 +    bool          MustDrawCaret(bool aIgnoreDrawnState);
   1.201 +
   1.202 +    void          DrawCaret(bool aInvalidate);
   1.203 +    void          DrawCaretAfterBriefDelay();
   1.204 +    bool          UpdateCaretRects(nsIFrame* aFrame, int32_t aFrameOffset);
   1.205 +    nsRect        GetHookRect()
   1.206 +    {
   1.207 +      return mHookRect;
   1.208 +    }
   1.209 +    void          ToggleDrawnStatus() { mDrawn = !mDrawn; }
   1.210 +
   1.211 +    nsFrameSelection* GetFrameSelection();
   1.212 +
   1.213 +    // Returns true if we should not draw the caret because of XUL menu popups.
   1.214 +    // The caret should be hidden if:
   1.215 +    // 1. An open popup contains the caret, but a menu popup exists before the
   1.216 +    //    caret-owning popup in the popup list (i.e. a menu is in front of the
   1.217 +    //    popup with the caret). If the menu itself contains the caret we don't
   1.218 +    //    hide it.
   1.219 +    // 2. A menu popup is open, but there is no caret present in any popup.
   1.220 +    // 3. The caret selection is empty.
   1.221 +    bool IsMenuPopupHidingCaret();
   1.222 +
   1.223 +protected:
   1.224 +
   1.225 +    nsWeakPtr             mPresShell;
   1.226 +    nsWeakPtr             mDomSelectionWeak;
   1.227 +
   1.228 +    nsCOMPtr<nsITimer>    mBlinkTimer;
   1.229 +
   1.230 +    // XXX these fields should go away and the values be acquired as needed,
   1.231 +    // probably by ComputeMetrics.
   1.232 +    uint32_t              mBlinkRate;         // time for one cyle (on then off), in milliseconds
   1.233 +    nscoord               mCaretWidthCSSPx;   // caret width in CSS pixels
   1.234 +    float                 mCaretAspectRatio;  // caret width/height aspect ratio
   1.235 +    
   1.236 +    bool                  mVisible;           // is the caret blinking
   1.237 +
   1.238 +    bool                  mDrawn;             // Denotes when the caret is physically drawn on the screen.
   1.239 +    bool                  mPendingDraw;       // True when the last on-state draw was suppressed.
   1.240 +
   1.241 +    bool                  mReadOnly;          // it the caret in readonly state (draws differently)      
   1.242 +    bool                  mShowDuringSelection; // show when text is selected
   1.243 +
   1.244 +    bool                  mIgnoreUserModify;
   1.245 +
   1.246 +    bool                  mKeyboardRTL;       // is the keyboard language right-to-left
   1.247 +    bool                  mBidiUI;            // is bidi UI turned on
   1.248 +    nsRect                mHookRect;          // directional hook on the caret
   1.249 +    uint8_t               mLastBidiLevel;     // saved bidi level of the last draw request, to use when we erase
   1.250 +    nsRect                mCaretRect;         // the last caret rect, in the coodinates of the last frame.
   1.251 +
   1.252 +    nsCOMPtr<nsIContent>  mLastContent;       // store the content the caret was last requested to be drawn
   1.253 +                                              // in (by DrawAtPosition()/DrawCaret()),
   1.254 +                                              // note that this can be different than where it was
   1.255 +                                              // actually drawn (anon <BR> in text control)
   1.256 +    int32_t               mLastContentOffset; // the offset for the last request
   1.257 +
   1.258 +    nsFrameSelection::HINT mLastHint;        // the hint associated with the last request, see also
   1.259 +                                              // mLastBidiLevel below
   1.260 +
   1.261 +};
   1.262 +
   1.263 +#endif //nsCaret_h__

mercurial