Merge mozilla-central and tracemonkey. (a=blockers)
[mozilla-central.git] / layout / forms / nsComboboxControlFrame.h
blob917d94ec554a26dd3f024c8480afa9bfbdd1393d
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
23 * Dean Tessman <dean_tessman@hotmail.com>
24 * Mats Palmgren <mats.palmgren@bredband.net>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 #ifndef nsComboboxControlFrame_h___
41 #define nsComboboxControlFrame_h___
43 #ifdef DEBUG_evaughan
44 //#define DEBUG_rods
45 #endif
47 #ifdef DEBUG_rods
48 //#define DO_REFLOW_DEBUG
49 //#define DO_REFLOW_COUNTER
50 //#define DO_UNCONSTRAINED_CHECK
51 //#define DO_PIXELS
52 //#define DO_NEW_REFLOW
53 #endif
55 //Mark used to indicate when onchange has been fired for current combobox item
56 #define NS_SKIP_NOTIFY_INDEX -2
58 #include "nsBlockFrame.h"
59 #include "nsIFormControlFrame.h"
60 #include "nsIComboboxControlFrame.h"
61 #include "nsIAnonymousContentCreator.h"
62 #include "nsISelectControlFrame.h"
63 #include "nsIRollupListener.h"
64 #include "nsPresState.h"
65 #include "nsCSSFrameConstructor.h"
66 #include "nsIStatefulFrame.h"
67 #include "nsIScrollableFrame.h"
68 #include "nsIDOMMouseListener.h"
69 #include "nsThreadUtils.h"
71 class nsIView;
72 class nsStyleContext;
73 class nsIListControlFrame;
74 class nsComboboxDisplayFrame;
76 /**
77 * Child list name indices
78 * @see #GetAdditionalChildListName()
80 #define NS_COMBO_LIST_COUNT (NS_BLOCK_LIST_COUNT + 1)
82 class nsComboboxControlFrame : public nsBlockFrame,
83 public nsIFormControlFrame,
84 public nsIComboboxControlFrame,
85 public nsIAnonymousContentCreator,
86 public nsISelectControlFrame,
87 public nsIRollupListener,
88 public nsIStatefulFrame
90 public:
91 friend nsIFrame* NS_NewComboboxControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, PRUint32 aFlags);
92 friend class nsComboboxDisplayFrame;
94 nsComboboxControlFrame(nsStyleContext* aContext);
95 ~nsComboboxControlFrame();
97 NS_DECL_QUERYFRAME
98 NS_DECL_FRAMEARENA_HELPERS
100 // nsIAnonymousContentCreator
101 virtual nsresult CreateAnonymousContent(nsTArray<nsIContent*>& aElements);
102 virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
103 PRUint32 aFilter);
104 virtual nsIFrame* CreateFrameFor(nsIContent* aContent);
106 #ifdef ACCESSIBILITY
107 virtual already_AddRefed<nsAccessible> CreateAccessible();
108 #endif
110 virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext);
112 virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext);
114 NS_IMETHOD Reflow(nsPresContext* aCX,
115 nsHTMLReflowMetrics& aDesiredSize,
116 const nsHTMLReflowState& aReflowState,
117 nsReflowStatus& aStatus);
119 NS_IMETHOD HandleEvent(nsPresContext* aPresContext,
120 nsGUIEvent* aEvent,
121 nsEventStatus* aEventStatus);
123 NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
124 const nsRect& aDirtyRect,
125 const nsDisplayListSet& aLists);
127 void PaintFocus(nsIRenderingContext& aRenderingContext, nsPoint aPt);
129 // XXXbz this is only needed to prevent the quirk percent height stuff from
130 // leaking out of the combobox. We may be able to get rid of this as more
131 // things move to IsFrameOfType.
132 virtual nsIAtom* GetType() const;
134 virtual PRBool IsFrameOfType(PRUint32 aFlags) const
136 return nsBlockFrame::IsFrameOfType(aFlags &
137 ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
140 virtual nsIScrollableFrame* GetScrollTargetFrame() {
141 return do_QueryFrame(mDropdownFrame);
144 #ifdef NS_DEBUG
145 NS_IMETHOD GetFrameName(nsAString& aResult) const;
146 #endif
147 virtual void DestroyFrom(nsIFrame* aDestructRoot);
148 virtual nsFrameList GetChildList(nsIAtom* aListName) const;
149 NS_IMETHOD SetInitialChildList(nsIAtom* aListName,
150 nsFrameList& aChildList);
151 virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
153 virtual nsIFrame* GetContentInsertionFrame();
155 // nsIFormControlFrame
156 virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue);
157 virtual nsresult GetFormProperty(nsIAtom* aName, nsAString& aValue) const;
159 * Inform the control that it got (or lost) focus.
160 * If it lost focus, the dropdown menu will be rolled up if needed,
161 * and FireOnChange() will be called.
162 * @param aOn PR_TRUE if got focus, PR_FALSE if lost focus.
163 * @param aRepaint if PR_TRUE then force repaint (NOTE: we always force repaint currently)
164 * @note This method might destroy |this|.
166 virtual void SetFocus(PRBool aOn, PRBool aRepaint);
168 //nsIComboboxControlFrame
169 virtual PRBool IsDroppedDown() { return mDroppedDown; }
171 * @note This method might destroy |this|.
173 virtual void ShowDropDown(PRBool aDoDropDown);
174 virtual nsIFrame* GetDropDown();
175 virtual void SetDropDown(nsIFrame* aDropDownFrame);
177 * @note This method might destroy |this|.
179 virtual void RollupFromList();
180 virtual void AbsolutelyPositionDropDown();
181 virtual PRInt32 GetIndexOfDisplayArea();
183 * @note This method might destroy |this|.
185 NS_IMETHOD RedisplaySelectedText();
186 virtual PRInt32 UpdateRecentIndex(PRInt32 aIndex);
187 virtual void OnContentReset();
189 // nsISelectControlFrame
190 NS_IMETHOD AddOption(PRInt32 index);
191 NS_IMETHOD RemoveOption(PRInt32 index);
192 NS_IMETHOD DoneAddingChildren(PRBool aIsDone);
193 NS_IMETHOD OnOptionSelected(PRInt32 aIndex, PRBool aSelected);
194 NS_IMETHOD OnSetSelectedIndex(PRInt32 aOldIndex, PRInt32 aNewIndex);
196 //nsIRollupListener
198 * Hide the dropdown menu and stop capturing mouse events.
199 * @note This method might destroy |this|.
201 NS_IMETHOD Rollup(PRUint32 aCount, nsIContent** aLastRolledUp);
203 * A combobox should roll up if a mousewheel event happens outside of
204 * the popup area.
206 NS_IMETHOD ShouldRollupOnMouseWheelEvent(PRBool *aShouldRollup)
207 { *aShouldRollup = PR_TRUE; return NS_OK;}
210 * A combobox should not roll up if activated by a mouse activate message
211 * (eg. X-mouse).
213 NS_IMETHOD ShouldRollupOnMouseActivate(PRBool *aShouldRollup)
214 { *aShouldRollup = PR_FALSE; return NS_OK;}
216 //nsIStatefulFrame
217 NS_IMETHOD SaveState(SpecialStateID aStateID, nsPresState** aState);
218 NS_IMETHOD RestoreState(nsPresState* aState);
220 static PRBool ToolkitHasNativePopup();
222 protected:
224 // Utilities
225 nsresult ReflowDropdown(nsPresContext* aPresContext,
226 const nsHTMLReflowState& aReflowState);
228 // Helper for GetMinWidth/GetPrefWidth
229 nscoord GetIntrinsicWidth(nsIRenderingContext* aRenderingContext,
230 nsLayoutUtils::IntrinsicWidthType aType);
231 protected:
232 class RedisplayTextEvent;
233 friend class RedisplayTextEvent;
235 class RedisplayTextEvent : public nsRunnable {
236 public:
237 NS_DECL_NSIRUNNABLE
238 RedisplayTextEvent(nsComboboxControlFrame *c) : mControlFrame(c) {}
239 void Revoke() { mControlFrame = nsnull; }
240 private:
241 nsComboboxControlFrame *mControlFrame;
245 * Show or hide the dropdown list.
246 * @note This method might destroy |this|.
248 void ShowPopup(PRBool aShowPopup);
251 * Show or hide the dropdown list.
252 * @param aShowList PR_TRUE to show, PR_FALSE to hide the dropdown.
253 * @note This method might destroy |this|.
254 * @return PR_FALSE if this frame is destroyed, PR_TRUE if still alive.
256 PRBool ShowList(PRBool aShowList);
257 void CheckFireOnChange();
258 void FireValueChangeEvent();
259 nsresult RedisplayText(PRInt32 aIndex);
260 void HandleRedisplayTextEvent();
261 void ActuallyDisplayText(PRBool aNotify);
263 nsFrameList mPopupFrames; // additional named child list
264 nsCOMPtr<nsIContent> mDisplayContent; // Anonymous content used to display the current selection
265 nsCOMPtr<nsIContent> mButtonContent; // Anonymous content for the button
266 nsIFrame* mDisplayFrame; // frame to display selection
267 nsIFrame* mButtonFrame; // button frame
268 nsIFrame* mDropdownFrame; // dropdown list frame
269 nsIListControlFrame * mListControlFrame; // ListControl Interface for the dropdown frame
271 // The width of our display area. Used by that frame's reflow to
272 // size to the full width except the drop-marker.
273 nscoord mDisplayWidth;
275 PRPackedBool mDroppedDown; // Current state of the dropdown list, PR_TRUE is dropped down
276 PRPackedBool mInRedisplayText;
278 nsRevocableEventPtr<RedisplayTextEvent> mRedisplayTextEvent;
280 PRInt32 mRecentSelectedIndex;
281 PRInt32 mDisplayedIndex;
282 nsString mDisplayedOptionText;
284 // make someone to listen to the button. If its programmatically pressed by someone like Accessibility
285 // then open or close the combo box.
286 nsCOMPtr<nsIDOMMouseListener> mButtonListener;
288 // static class data member for Bug 32920
289 // only one control can be focused at a time
290 static nsComboboxControlFrame * mFocused;
292 #ifdef DO_REFLOW_COUNTER
293 PRInt32 mReflowId;
294 #endif
297 #endif