layout/forms/nsComboboxControlFrame.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef nsComboboxControlFrame_h___
michael@0 7 #define nsComboboxControlFrame_h___
michael@0 8
michael@0 9 #ifdef DEBUG_evaughan
michael@0 10 //#define DEBUG_rods
michael@0 11 #endif
michael@0 12
michael@0 13 #ifdef DEBUG_rods
michael@0 14 //#define DO_REFLOW_DEBUG
michael@0 15 //#define DO_REFLOW_COUNTER
michael@0 16 //#define DO_UNCONSTRAINED_CHECK
michael@0 17 //#define DO_PIXELS
michael@0 18 //#define DO_NEW_REFLOW
michael@0 19 #endif
michael@0 20
michael@0 21 //Mark used to indicate when onchange has been fired for current combobox item
michael@0 22 #define NS_SKIP_NOTIFY_INDEX -2
michael@0 23
michael@0 24 #include "mozilla/Attributes.h"
michael@0 25 #include "nsBlockFrame.h"
michael@0 26 #include "nsIFormControlFrame.h"
michael@0 27 #include "nsIComboboxControlFrame.h"
michael@0 28 #include "nsIAnonymousContentCreator.h"
michael@0 29 #include "nsISelectControlFrame.h"
michael@0 30 #include "nsIRollupListener.h"
michael@0 31 #include "nsIStatefulFrame.h"
michael@0 32 #include "nsThreadUtils.h"
michael@0 33
michael@0 34 class nsStyleContext;
michael@0 35 class nsIListControlFrame;
michael@0 36 class nsComboboxDisplayFrame;
michael@0 37 class nsIDOMEventListener;
michael@0 38 class nsIScrollableFrame;
michael@0 39
michael@0 40 class nsComboboxControlFrame : public nsBlockFrame,
michael@0 41 public nsIFormControlFrame,
michael@0 42 public nsIComboboxControlFrame,
michael@0 43 public nsIAnonymousContentCreator,
michael@0 44 public nsISelectControlFrame,
michael@0 45 public nsIRollupListener,
michael@0 46 public nsIStatefulFrame
michael@0 47 {
michael@0 48 public:
michael@0 49 friend nsIFrame* NS_NewComboboxControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, nsFrameState aFlags);
michael@0 50 friend class nsComboboxDisplayFrame;
michael@0 51
michael@0 52 nsComboboxControlFrame(nsStyleContext* aContext);
michael@0 53 ~nsComboboxControlFrame();
michael@0 54
michael@0 55 NS_DECL_QUERYFRAME
michael@0 56 NS_DECL_FRAMEARENA_HELPERS
michael@0 57
michael@0 58 // nsIAnonymousContentCreator
michael@0 59 virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
michael@0 60 virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
michael@0 61 uint32_t aFilter) MOZ_OVERRIDE;
michael@0 62 virtual nsIFrame* CreateFrameFor(nsIContent* aContent) MOZ_OVERRIDE;
michael@0 63
michael@0 64 #ifdef ACCESSIBILITY
michael@0 65 virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
michael@0 66 #endif
michael@0 67
michael@0 68 virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
michael@0 69
michael@0 70 virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
michael@0 71
michael@0 72 virtual nsresult Reflow(nsPresContext* aCX,
michael@0 73 nsHTMLReflowMetrics& aDesiredSize,
michael@0 74 const nsHTMLReflowState& aReflowState,
michael@0 75 nsReflowStatus& aStatus) MOZ_OVERRIDE;
michael@0 76
michael@0 77 virtual nsresult HandleEvent(nsPresContext* aPresContext,
michael@0 78 mozilla::WidgetGUIEvent* aEvent,
michael@0 79 nsEventStatus* aEventStatus) MOZ_OVERRIDE;
michael@0 80
michael@0 81 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
michael@0 82 const nsRect& aDirtyRect,
michael@0 83 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
michael@0 84
michael@0 85 void PaintFocus(nsRenderingContext& aRenderingContext, nsPoint aPt);
michael@0 86
michael@0 87 // XXXbz this is only needed to prevent the quirk percent height stuff from
michael@0 88 // leaking out of the combobox. We may be able to get rid of this as more
michael@0 89 // things move to IsFrameOfType.
michael@0 90 virtual nsIAtom* GetType() const MOZ_OVERRIDE;
michael@0 91
michael@0 92 virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
michael@0 93 {
michael@0 94 return nsBlockFrame::IsFrameOfType(aFlags &
michael@0 95 ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
michael@0 96 }
michael@0 97
michael@0 98 virtual nsIScrollableFrame* GetScrollTargetFrame() MOZ_OVERRIDE {
michael@0 99 return do_QueryFrame(mDropdownFrame);
michael@0 100 }
michael@0 101
michael@0 102 #ifdef DEBUG_FRAME_DUMP
michael@0 103 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
michael@0 104 #endif
michael@0 105 virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
michael@0 106 virtual nsresult SetInitialChildList(ChildListID aListID,
michael@0 107 nsFrameList& aChildList) MOZ_OVERRIDE;
michael@0 108 virtual const nsFrameList& GetChildList(ChildListID aListID) const MOZ_OVERRIDE;
michael@0 109 virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE;
michael@0 110
michael@0 111 virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE;
michael@0 112
michael@0 113 // nsIFormControlFrame
michael@0 114 virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) MOZ_OVERRIDE;
michael@0 115 /**
michael@0 116 * Inform the control that it got (or lost) focus.
michael@0 117 * If it lost focus, the dropdown menu will be rolled up if needed,
michael@0 118 * and FireOnChange() will be called.
michael@0 119 * @param aOn true if got focus, false if lost focus.
michael@0 120 * @param aRepaint if true then force repaint (NOTE: we always force repaint currently)
michael@0 121 * @note This method might destroy |this|.
michael@0 122 */
michael@0 123 virtual void SetFocus(bool aOn, bool aRepaint) MOZ_OVERRIDE;
michael@0 124
michael@0 125 //nsIComboboxControlFrame
michael@0 126 virtual bool IsDroppedDown() MOZ_OVERRIDE { return mDroppedDown; }
michael@0 127 /**
michael@0 128 * @note This method might destroy |this|.
michael@0 129 */
michael@0 130 virtual void ShowDropDown(bool aDoDropDown) MOZ_OVERRIDE;
michael@0 131 virtual nsIFrame* GetDropDown() MOZ_OVERRIDE;
michael@0 132 virtual void SetDropDown(nsIFrame* aDropDownFrame) MOZ_OVERRIDE;
michael@0 133 /**
michael@0 134 * @note This method might destroy |this|.
michael@0 135 */
michael@0 136 virtual void RollupFromList() MOZ_OVERRIDE;
michael@0 137
michael@0 138 /**
michael@0 139 * Return the available space above and below this frame for
michael@0 140 * placing the drop-down list, and the current 2D translation.
michael@0 141 * Note that either or both can be less than or equal to zero,
michael@0 142 * if both are then the drop-down should be closed.
michael@0 143 */
michael@0 144 void GetAvailableDropdownSpace(nscoord* aAbove,
michael@0 145 nscoord* aBelow,
michael@0 146 nsPoint* aTranslation);
michael@0 147 virtual int32_t GetIndexOfDisplayArea() MOZ_OVERRIDE;
michael@0 148 /**
michael@0 149 * @note This method might destroy |this|.
michael@0 150 */
michael@0 151 NS_IMETHOD RedisplaySelectedText() MOZ_OVERRIDE;
michael@0 152 virtual int32_t UpdateRecentIndex(int32_t aIndex) MOZ_OVERRIDE;
michael@0 153 virtual void OnContentReset() MOZ_OVERRIDE;
michael@0 154
michael@0 155 // nsISelectControlFrame
michael@0 156 NS_IMETHOD AddOption(int32_t index) MOZ_OVERRIDE;
michael@0 157 NS_IMETHOD RemoveOption(int32_t index) MOZ_OVERRIDE;
michael@0 158 NS_IMETHOD DoneAddingChildren(bool aIsDone) MOZ_OVERRIDE;
michael@0 159 NS_IMETHOD OnOptionSelected(int32_t aIndex, bool aSelected) MOZ_OVERRIDE;
michael@0 160 NS_IMETHOD OnSetSelectedIndex(int32_t aOldIndex, int32_t aNewIndex) MOZ_OVERRIDE;
michael@0 161
michael@0 162 //nsIRollupListener
michael@0 163 /**
michael@0 164 * Hide the dropdown menu and stop capturing mouse events.
michael@0 165 * @note This method might destroy |this|.
michael@0 166 */
michael@0 167 virtual bool Rollup(uint32_t aCount, const nsIntPoint* pos, nsIContent** aLastRolledUp) MOZ_OVERRIDE;
michael@0 168 virtual void NotifyGeometryChange() MOZ_OVERRIDE;
michael@0 169
michael@0 170 /**
michael@0 171 * A combobox should roll up if a mousewheel event happens outside of
michael@0 172 * the popup area.
michael@0 173 */
michael@0 174 virtual bool ShouldRollupOnMouseWheelEvent() MOZ_OVERRIDE
michael@0 175 { return true; }
michael@0 176
michael@0 177 virtual bool ShouldConsumeOnMouseWheelEvent() MOZ_OVERRIDE
michael@0 178 { return false; }
michael@0 179
michael@0 180 /**
michael@0 181 * A combobox should not roll up if activated by a mouse activate message
michael@0 182 * (eg. X-mouse).
michael@0 183 */
michael@0 184 virtual bool ShouldRollupOnMouseActivate() MOZ_OVERRIDE
michael@0 185 { return false; }
michael@0 186
michael@0 187 virtual uint32_t GetSubmenuWidgetChain(nsTArray<nsIWidget*> *aWidgetChain) MOZ_OVERRIDE
michael@0 188 { return 0; }
michael@0 189
michael@0 190 virtual nsIWidget* GetRollupWidget() MOZ_OVERRIDE;
michael@0 191
michael@0 192 //nsIStatefulFrame
michael@0 193 NS_IMETHOD SaveState(nsPresState** aState) MOZ_OVERRIDE;
michael@0 194 NS_IMETHOD RestoreState(nsPresState* aState) MOZ_OVERRIDE;
michael@0 195
michael@0 196 static bool ToolkitHasNativePopup();
michael@0 197
michael@0 198 protected:
michael@0 199 friend class RedisplayTextEvent;
michael@0 200 friend class nsAsyncResize;
michael@0 201 friend class nsResizeDropdownAtFinalPosition;
michael@0 202
michael@0 203 // Utilities
michael@0 204 nsresult ReflowDropdown(nsPresContext* aPresContext,
michael@0 205 const nsHTMLReflowState& aReflowState);
michael@0 206
michael@0 207 enum DropDownPositionState {
michael@0 208 // can't show the dropdown at its current position
michael@0 209 eDropDownPositionSuppressed,
michael@0 210 // a resize reflow is pending, don't show it yet
michael@0 211 eDropDownPositionPendingResize,
michael@0 212 // the dropdown has its final size and position and can be displayed here
michael@0 213 eDropDownPositionFinal
michael@0 214 };
michael@0 215 DropDownPositionState AbsolutelyPositionDropDown();
michael@0 216
michael@0 217 // Helper for GetMinWidth/GetPrefWidth
michael@0 218 nscoord GetIntrinsicWidth(nsRenderingContext* aRenderingContext,
michael@0 219 nsLayoutUtils::IntrinsicWidthType aType);
michael@0 220
michael@0 221 class RedisplayTextEvent : public nsRunnable {
michael@0 222 public:
michael@0 223 NS_DECL_NSIRUNNABLE
michael@0 224 RedisplayTextEvent(nsComboboxControlFrame *c) : mControlFrame(c) {}
michael@0 225 void Revoke() { mControlFrame = nullptr; }
michael@0 226 private:
michael@0 227 nsComboboxControlFrame *mControlFrame;
michael@0 228 };
michael@0 229
michael@0 230 /**
michael@0 231 * Show or hide the dropdown list.
michael@0 232 * @note This method might destroy |this|.
michael@0 233 */
michael@0 234 void ShowPopup(bool aShowPopup);
michael@0 235
michael@0 236 /**
michael@0 237 * Show or hide the dropdown list.
michael@0 238 * @param aShowList true to show, false to hide the dropdown.
michael@0 239 * @note This method might destroy |this|.
michael@0 240 * @return false if this frame is destroyed, true if still alive.
michael@0 241 */
michael@0 242 bool ShowList(bool aShowList);
michael@0 243 void CheckFireOnChange();
michael@0 244 void FireValueChangeEvent();
michael@0 245 nsresult RedisplayText(int32_t aIndex);
michael@0 246 void HandleRedisplayTextEvent();
michael@0 247 void ActuallyDisplayText(bool aNotify);
michael@0 248
michael@0 249 private:
michael@0 250 // If our total transform to the root frame of the root document is only a 2d
michael@0 251 // translation then return that translation, otherwise returns (0,0).
michael@0 252 nsPoint GetCSSTransformTranslation();
michael@0 253
michael@0 254 protected:
michael@0 255 nsFrameList mPopupFrames; // additional named child list
michael@0 256 nsCOMPtr<nsIContent> mDisplayContent; // Anonymous content used to display the current selection
michael@0 257 nsCOMPtr<nsIContent> mButtonContent; // Anonymous content for the button
michael@0 258 nsIFrame* mDisplayFrame; // frame to display selection
michael@0 259 nsIFrame* mButtonFrame; // button frame
michael@0 260 nsIFrame* mDropdownFrame; // dropdown list frame
michael@0 261 nsIListControlFrame * mListControlFrame; // ListControl Interface for the dropdown frame
michael@0 262
michael@0 263 // The width of our display area. Used by that frame's reflow to
michael@0 264 // size to the full width except the drop-marker.
michael@0 265 nscoord mDisplayWidth;
michael@0 266
michael@0 267 nsRevocableEventPtr<RedisplayTextEvent> mRedisplayTextEvent;
michael@0 268
michael@0 269 int32_t mRecentSelectedIndex;
michael@0 270 int32_t mDisplayedIndex;
michael@0 271 nsString mDisplayedOptionText;
michael@0 272
michael@0 273 // make someone to listen to the button. If its programmatically pressed by someone like Accessibility
michael@0 274 // then open or close the combo box.
michael@0 275 nsCOMPtr<nsIDOMEventListener> mButtonListener;
michael@0 276
michael@0 277 // The last y-positions used for estimating available space above and
michael@0 278 // below for the dropdown list in GetAvailableDropdownSpace. These are
michael@0 279 // reset to nscoord_MIN in AbsolutelyPositionDropDown when placing the
michael@0 280 // dropdown at its actual position. The GetAvailableDropdownSpace call
michael@0 281 // from nsListControlFrame::ReflowAsDropdown use the last position.
michael@0 282 nscoord mLastDropDownAboveScreenY;
michael@0 283 nscoord mLastDropDownBelowScreenY;
michael@0 284 // Current state of the dropdown list, true is dropped down.
michael@0 285 bool mDroppedDown;
michael@0 286 // See comment in HandleRedisplayTextEvent().
michael@0 287 bool mInRedisplayText;
michael@0 288 // Acting on ShowDropDown(true) is delayed until we're focused.
michael@0 289 bool mDelayedShowDropDown;
michael@0 290
michael@0 291 // static class data member for Bug 32920
michael@0 292 // only one control can be focused at a time
michael@0 293 static nsComboboxControlFrame* sFocused;
michael@0 294
michael@0 295 #ifdef DO_REFLOW_COUNTER
michael@0 296 int32_t mReflowId;
michael@0 297 #endif
michael@0 298 };
michael@0 299
michael@0 300 #endif

mercurial