nsComboboxControlFrame.h (4460B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 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/. */ 6 7 #ifndef nsComboboxControlFrame_h___ 8 #define nsComboboxControlFrame_h___ 9 10 #include "ButtonControlFrame.h" 11 #include "mozilla/Attributes.h" 12 #include "nsIAnonymousContentCreator.h" 13 #include "nsIRollupListener.h" 14 #include "nsISelectControlFrame.h" 15 #include "nsThreadUtils.h" 16 17 namespace mozilla { 18 class PresShell; 19 class HTMLSelectEventListener; 20 class ComboboxLabelFrame; 21 namespace dom { 22 class HTMLSelectElement; 23 } 24 } // namespace mozilla 25 26 class nsComboboxControlFrame final : public mozilla::ButtonControlFrame, 27 public nsISelectControlFrame { 28 using Element = mozilla::dom::Element; 29 30 public: 31 friend class mozilla::ComboboxLabelFrame; 32 explicit nsComboboxControlFrame(ComputedStyle* aStyle, 33 nsPresContext* aPresContext); 34 ~nsComboboxControlFrame(); 35 36 NS_DECL_QUERYFRAME 37 NS_DECL_FRAMEARENA_HELPERS(nsComboboxControlFrame) 38 39 // nsIAnonymousContentCreator 40 nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) final; 41 void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, 42 uint32_t aFilter) final; 43 44 #ifdef ACCESSIBILITY 45 mozilla::a11y::AccType AccessibleType() final; 46 #endif 47 48 nscoord IntrinsicISize(const mozilla::IntrinsicSizeInput& aInput, 49 mozilla::IntrinsicISizeType aType) final; 50 void GetLabelText(nsAString&); 51 void UpdateLabelText(); 52 53 void Reflow(nsPresContext* aCX, ReflowOutput& aDesiredSize, 54 const ReflowInput& aReflowInput, nsReflowStatus& aStatus) final; 55 56 MOZ_CAN_RUN_SCRIPT_BOUNDARY 57 nsresult HandleEvent(nsPresContext* aPresContext, 58 mozilla::WidgetGUIEvent* aEvent, 59 nsEventStatus* aEventStatus) final; 60 61 void Init(nsIContent* aContent, nsContainerFrame* aParent, 62 nsIFrame* aPrevInFlow) final; 63 void Destroy(DestroyContext&) final; 64 65 #ifdef DEBUG_FRAME_DUMP 66 nsresult GetFrameName(nsAString& aResult) const final { 67 return MakeFrameName(u"ComboboxControl"_ns, aResult); 68 } 69 #endif 70 71 /** 72 * @note This method might destroy |this|. 73 */ 74 void FireValueChangeEvent(); 75 nsresult RedisplaySelectedText(); 76 77 bool IsDroppedDown() const; 78 79 // nsISelectControlFrame 80 NS_IMETHOD AddOption(int32_t index) final; 81 NS_IMETHOD RemoveOption(int32_t index) final; 82 NS_IMETHOD DoneAddingChildren(bool aIsDone) final; 83 NS_IMETHOD OnOptionSelected(int32_t aIndex, bool aSelected) final; 84 NS_IMETHOD_(void) 85 OnSetSelectedIndex(int32_t aOldIndex, int32_t aNewIndex) final; 86 87 int32_t CharCountOfLargestOptionForInflation() const; 88 89 protected: 90 friend class RedisplayTextEvent; 91 friend class nsAsyncResize; 92 friend class nsResizeDropdownAtFinalPosition; 93 94 // Return true if we should render a dropdown button. 95 bool HasDropDownButton() const; 96 nscoord DropDownButtonISize(); 97 98 enum class Type { Longest, Current }; 99 nscoord GetOptionISize(gfxContext*, Type) const; 100 101 class RedisplayTextEvent : public mozilla::Runnable { 102 public: 103 NS_DECL_NSIRUNNABLE 104 explicit RedisplayTextEvent(nsComboboxControlFrame* c) 105 : mozilla::Runnable("nsComboboxControlFrame::RedisplayTextEvent"), 106 mControlFrame(c) {} 107 void Revoke() { mControlFrame = nullptr; } 108 109 private: 110 nsComboboxControlFrame* mControlFrame; 111 }; 112 113 nsresult RedisplayText(); 114 void HandleRedisplayTextEvent(); 115 116 mozilla::dom::HTMLSelectElement& Select() const; 117 void GetOptionText(uint32_t aIndex, nsAString& aText) const; 118 119 // TODO(emilio): Would be nice to either paint the dropmarker as part of the 120 // background somehow, or alternatively rejigger stuff a bit (using flex) so 121 // that we can get rid of the label element. 122 RefPtr<Element> mDisplayLabel; // Anonymous content for the label 123 RefPtr<Element> mButtonContent; // Anonymous content for the button 124 nsRevocableEventPtr<RedisplayTextEvent> mRedisplayTextEvent; 125 126 // The inline size of our display area. Used by that frame's reflow to size to 127 // the full inline size except the drop-marker. 128 nscoord mDisplayISize = 0; 129 int32_t mDisplayedIndex = -1; 130 RefPtr<mozilla::HTMLSelectEventListener> mEventListener; 131 }; 132 133 #endif