Back to index

lightning-sunbird  0.9+nobinonly
nsListControlFrame.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Mats Palmgren <mats.palmgren@bredband.net>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 #ifndef nsListControlFrame_h___
00039 #define nsListControlFrame_h___
00040 
00041 #ifdef DEBUG_evaughan
00042 //#define DEBUG_rods
00043 #endif
00044 
00045 #ifdef DEBUG_rods
00046 //#define DO_REFLOW_DEBUG
00047 //#define DO_REFLOW_COUNTER
00048 //#define DO_UNCONSTRAINED_CHECK
00049 //#define DO_PIXELS
00050 #endif
00051 
00052 #include "nsGfxScrollFrame.h"
00053 #include "nsIFormControlFrame.h"
00054 #include "nsIListControlFrame.h"
00055 #include "nsISelectControlFrame.h"
00056 #include "nsIDOMEventListener.h"
00057 #include "nsIContent.h"
00058 #include "nsAutoPtr.h"
00059 
00060 class nsIDOMHTMLSelectElement;
00061 class nsIDOMHTMLOptionsCollection;
00062 class nsIDOMHTMLOptionElement;
00063 class nsIComboboxControlFrame;
00064 class nsIViewManager;
00065 class nsPresContext;
00066 class nsVoidArray;
00067 class nsIScrollableView;
00068 
00069 class nsVoidArray;
00070 class nsListEventListener;
00071 
00076 class nsListControlFrame : public nsHTMLScrollFrame,
00077                            public nsIFormControlFrame, 
00078                            public nsIListControlFrame,
00079                            public nsISelectControlFrame
00080 {
00081 public:
00082   friend nsresult NS_NewListControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
00083 
00084    // nsISupports
00085   NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
00086 
00087     // nsIFrame
00088   NS_IMETHOD HandleEvent(nsPresContext* aPresContext,
00089                          nsGUIEvent* aEvent,
00090                          nsEventStatus* aEventStatus);
00091   
00092   NS_IMETHOD SetInitialChildList(nsPresContext* aPresContext,
00093                                  nsIAtom*        aListName,
00094                                  nsIFrame*       aChildList);
00095 
00096   NS_IMETHOD Reflow(nsPresContext*          aCX,
00097                     nsHTMLReflowMetrics&     aDesiredSize,
00098                     const nsHTMLReflowState& aReflowState,
00099                     nsReflowStatus&          aStatus);
00100 
00101   NS_IMETHOD Init(nsPresContext*  aPresContext,
00102                    nsIContent*      aContent,
00103                    nsIFrame*        aParent,
00104                    nsStyleContext*  aContext,
00105                    nsIFrame*        aPrevInFlow);
00106 
00107   NS_IMETHOD DidReflow(nsPresContext*           aPresContext, 
00108                        const nsHTMLReflowState*  aReflowState, 
00109                        nsDidReflowStatus         aStatus);
00110   NS_IMETHOD Destroy(nsPresContext *aPresContext);
00111 
00112   NS_IMETHOD Paint(nsPresContext*      aPresContext,
00113                    nsIRenderingContext& aRenderingContext,
00114                    const nsRect&        aDirtyRect,
00115                    nsFramePaintLayer    aWhichLayer,
00116                    PRUint32             aFlags = 0);
00117 
00118   virtual nsIFrame* GetContentInsertionFrame();
00119 
00125   virtual nsIAtom* GetType() const;
00126 
00127 #ifdef DEBUG
00128     // nsIFrameDebug
00129   NS_IMETHOD GetFrameName(nsAString& aResult) const;
00130 #endif
00131 
00132     // nsIFormControlFrame
00133   NS_IMETHOD_(PRInt32) GetFormControlType() const;
00134   NS_IMETHOD GetName(nsAString* aName);
00135   NS_IMETHOD SetProperty(nsPresContext* aPresContext, nsIAtom* aName, const nsAString& aValue);
00136   NS_IMETHOD GetProperty(nsIAtom* aName, nsAString& aValue); 
00137 
00142   NS_IMETHOD GetMultiple(PRBool* aResult, nsIDOMHTMLSelectElement* aSelect = nsnull);
00143   NS_IMETHOD GetFormContent(nsIContent*& aContent) const;
00144   NS_IMETHOD OnContentReset();
00145 
00146   virtual void SetFocus(PRBool aOn = PR_TRUE, PRBool aRepaint = PR_FALSE);
00147   virtual void ScrollIntoView(nsPresContext* aPresContext);
00148   virtual nscoord GetVerticalInsidePadding(nsPresContext* aPresContext,
00149                                            float aPixToTwip,
00150                                            nscoord aInnerHeight) const;
00151   virtual nscoord GetHorizontalInsidePadding(nsPresContext* aPresContext,
00152                                              float aPixToTwip, 
00153                                              nscoord aInnerWidth,
00154                                              nscoord aCharWidth) const;
00155 
00156   virtual nsGfxScrollFrameInner::ScrollbarStyles GetScrollbarStyles() const;
00157 
00158     // for accessibility purposes
00159 #ifdef ACCESSIBILITY
00160   NS_IMETHOD GetAccessible(nsIAccessible** aAccessible);
00161 #endif
00162 
00163     // nsHTMLContainerFrame
00164   virtual PRIntn GetSkipSides() const;
00165 
00166     // nsIListControlFrame
00167   NS_IMETHOD SetComboboxFrame(nsIFrame* aComboboxFrame);
00168   NS_IMETHOD GetSelectedIndex(PRInt32* aIndex); 
00169 
00175   NS_IMETHOD GetOptionText(PRInt32 aIndex, nsAString & aStr);
00176 
00177   NS_IMETHOD CaptureMouseEvents(nsPresContext* aPresContext, PRBool aGrabMouseEvents);
00178   NS_IMETHOD GetMaximumSize(nsSize &aSize);
00179   NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight);
00180   NS_IMETHOD GetNumberOfOptions(PRInt32* aNumOptions);  
00181   NS_IMETHOD SyncViewWithFrame();
00182   NS_IMETHOD AboutToDropDown();
00183 
00187   NS_IMETHOD AboutToRollup();
00188   NS_IMETHOD SetOverrideReflowOptimization(PRBool aValue) { mOverrideReflowOpt = aValue; return NS_OK; }
00189   NS_IMETHOD GetOptionsContainer(nsPresContext* aPresContext, nsIFrame** aFrame);
00190 
00195   NS_IMETHOD FireOnChange();
00196 
00201   NS_IMETHOD ComboboxFinish(PRInt32 aIndex);
00202 
00203   // nsISelectControlFrame
00204   NS_IMETHOD AddOption(nsPresContext* aPresContext, PRInt32 index);
00205   NS_IMETHOD RemoveOption(nsPresContext* aPresContext, PRInt32 index);
00206   NS_IMETHOD GetOptionSelected(PRInt32 aIndex, PRBool* aValue);
00207   NS_IMETHOD DoneAddingChildren(PRBool aIsDone);
00208 
00213   NS_IMETHOD OnOptionSelected(nsPresContext* aPresContext,
00214                               PRInt32 aIndex,
00215                               PRBool aSelected);
00216   NS_IMETHOD GetDummyFrame(nsIFrame** aFrame);
00217   NS_IMETHOD SetDummyFrame(nsIFrame* aFrame);
00218   NS_IMETHOD OnSetSelectedIndex(PRInt32 aOldIndex, PRInt32 aNewIndex);
00219 
00220   // mouse event listeners (both might destroy |this|)
00221   nsresult MouseDown(nsIDOMEvent* aMouseEvent);
00222   nsresult MouseUp(nsIDOMEvent* aMouseEvent);
00223 
00224   // mouse motion listeners
00225   nsresult MouseMove(nsIDOMEvent* aMouseEvent);
00226   nsresult DragMove(nsIDOMEvent* aMouseEvent);
00227 
00228   // key listener (might destroy |this|)
00229   nsresult KeyPress(nsIDOMEvent* aKeyEvent);
00230 
00231   static nsIDOMHTMLSelectElement* GetSelect(nsIContent * aContent);
00232 
00236   static nsIDOMHTMLOptionsCollection* GetOptions(nsIContent * aContent, nsIDOMHTMLSelectElement* aSelect = nsnull);
00237 
00242   static nsIDOMHTMLOptionElement* GetOption(nsIDOMHTMLOptionsCollection* aOptions, PRInt32 aIndex);
00243 
00248   static already_AddRefed<nsIContent> GetOptionAsContent(nsIDOMHTMLOptionsCollection* aCollection,PRInt32 aIndex);
00249 
00250   static void ComboboxFocusSet();
00251 
00252   // Helper
00253   void SetPassId(PRInt16 aId)  { mPassId = aId; }
00254 
00255   void PaintFocus(nsIRenderingContext& aRC, nsFramePaintLayer aWhichLayer);
00256 
00257 #ifdef ACCESSIBILITY
00258 
00263   void FireMenuItemActiveEvent(); // Inform assistive tech what got focused
00264 #endif
00265 
00266 protected:
00271   PRBool     UpdateSelection();
00272 
00277   void       DropDownToggleKey(nsIDOMEvent* aKeyEvent);
00278   nsresult   IsOptionDisabled(PRInt32 anIndex, PRBool &aIsDisabled);
00279   nsresult   ScrollToFrame(nsIContent * aOptElement);
00280   nsresult   ScrollToIndex(PRInt32 anIndex);
00281 
00290   PRBool     IgnoreMouseEventForSelection(nsIDOMEvent* aEvent);
00291 
00296   void       UpdateInListState(nsIDOMEvent* aEvent);
00297   void       AdjustIndexForDisabledOpt(PRInt32 aStartIndex, PRInt32 &anNewIndex,
00298                                        PRInt32 aNumOptions, PRInt32 aDoAdjustInc, PRInt32 aDoAdjustIncNext);
00299 
00304   virtual void ResetList(PRBool aAllowScrolling);
00305 
00306   nsListControlFrame(nsIPresShell* aShell, nsIDocument* aDocument);
00307   virtual ~nsListControlFrame();
00308 
00309   // Utility methods
00310   nsresult GetSizeAttribute(PRInt32 *aSize);
00311   nsIContent* GetOptionFromContent(nsIContent *aContent);
00312 
00318   nsresult GetIndexFromDOMEvent(nsIDOMEvent* aMouseEvent, PRInt32& aCurIndex);
00319 
00324   already_AddRefed<nsIContent> GetOptionContent(PRInt32 aIndex);
00325 
00331   PRBool   IsContentSelected(nsIContent* aContent);
00332 
00336   PRBool   IsContentSelectedByIndex(PRInt32 aIndex);
00337 
00338   PRBool   IsOptionElement(nsIContent* aContent);
00339   PRBool   CheckIfAllFramesHere();
00340   PRInt32  GetIndexFromContent(nsIContent *aContent);
00341   PRBool   IsLeftButton(nsIDOMEvent* aMouseEvent);
00342 
00343   // Dropped down stuff
00344   void     SetComboboxItem(PRInt32 aIndex);
00345   PRBool   IsInDropDownMode() const;
00346 
00347   // Selection
00348   PRBool   SetOptionsSelectedFromFrame(PRInt32 aStartIndex,
00349                                        PRInt32 aEndIndex,
00350                                        PRBool aValue,
00351                                        PRBool aClearAll);
00352   PRBool   ToggleOptionSelectedFromFrame(PRInt32 aIndex);
00353   PRBool   SingleSelection(PRInt32 aClickedIndex, PRBool aDoToggle);
00354   PRBool   ExtendedSelection(PRInt32 aStartIndex, PRInt32 aEndIndex,
00355                              PRBool aClearAll);
00356   PRBool   PerformSelection(PRInt32 aClickedIndex, PRBool aIsShift,
00357                             PRBool aIsControl);
00358   PRBool   HandleListSelection(nsIDOMEvent * aDOMEvent, PRInt32 selectedIndex);
00359   void     InitSelectionRange(PRInt32 aClickedIndex);
00360 
00361   // Data Members
00362   PRInt32      mStartSelectionIndex;
00363   PRInt32      mEndSelectionIndex;
00364 
00365   nsIComboboxControlFrame *mComboboxFrame;
00366   nscoord      mMaxWidth;
00367   nscoord      mMaxHeight;
00368   PRInt32      mNumDisplayRows;
00369   PRPackedBool mChangesSinceDragStart:1;
00370   PRPackedBool mButtonDown:1;
00371   // Has the user selected a visible item since we showed the
00372   // dropdown?
00373   PRPackedBool mItemSelectionStarted:1;
00374 
00375   PRPackedBool mIsAllContentHere:1;
00376   PRPackedBool mIsAllFramesHere:1;
00377   PRPackedBool mHasBeenInitialized:1;
00378   PRPackedBool mNeedToReset:1;
00379   PRPackedBool mPostChildrenLoadedReset:1;
00380 
00381   PRPackedBool mOverrideReflowOpt:1;
00382 
00383   //bool value for multiple discontiguous selection
00384   PRPackedBool mControlSelectMode:1;
00385 
00386   PRInt16 mPassId;
00387   nscoord mCachedDesiredMEW;
00388 
00389   nsRefPtr<nsListEventListener> mEventListener;
00390 
00391   nsIFrame* mDummyFrame;
00392 
00393   //Resize Reflow OpitmizationSize;
00394   nsSize       mCacheSize;
00395   nscoord      mCachedAscent;
00396   nscoord      mCachedMaxElementWidth;
00397   nsSize       mCachedUnconstrainedSize;
00398   nsSize       mCachedAvailableSize;
00399 
00400   static nsListControlFrame * mFocused;
00401 
00402 #ifdef DO_REFLOW_COUNTER
00403   PRInt32 mReflowId;
00404 #endif
00405 
00406 private:
00407   NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
00408   NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
00409 
00410   // for incremental typing navigation
00411   static nsAString& GetIncrementalString ();
00412   static DOMTimeStamp gLastKeyTime;
00413 };
00414 
00415 #endif /* nsListControlFrame_h___ */
00416