nsITheme.h (9670B)
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 /* service providing platform-specific native rendering for widgets */ 8 9 #ifndef nsITheme_h_ 10 #define nsITheme_h_ 11 12 #include "mozilla/AlreadyAddRefed.h" 13 #include "nsISupports.h" 14 #include "nsID.h" 15 #include "nscore.h" 16 #include "Units.h" 17 18 struct nsRect; 19 class gfxContext; 20 class nsAttrValue; 21 class nsPresContext; 22 class nsDeviceContext; 23 class nsIFrame; 24 class nsAtom; 25 class nsIWidget; 26 27 namespace mozilla { 28 class ComputedStyle; 29 enum class StyleAppearance : uint8_t; 30 enum class StyleScrollbarWidth : uint8_t; 31 namespace layers { 32 class StackingContextHelper; 33 class RenderRootStateManager; 34 } // namespace layers 35 namespace widget { 36 class Theme; 37 } // namespace widget 38 namespace wr { 39 class DisplayListBuilder; 40 class IpcResourceUpdateQueue; 41 } // namespace wr 42 } // namespace mozilla 43 44 // IID for the nsITheme interface 45 // {7329f760-08cb-450f-8225-dae729096dec} 46 #define NS_ITHEME_IID \ 47 {0x7329f760, 0x08cb, 0x450f, {0x82, 0x25, 0xda, 0xe7, 0x29, 0x09, 0x6d, 0xec}} 48 49 /** 50 * nsITheme is a service that provides platform-specific native 51 * rendering for widgets. In other words, it provides the necessary 52 * operations to draw a rendering object (an nsIFrame) as a native 53 * widget. 54 * 55 * All the methods on nsITheme take a rendering context or device 56 * context, a frame (the rendering object), and a widget type (one of 57 * the constants in nsThemeConstants.h). 58 */ 59 class nsITheme : public nsISupports { 60 protected: 61 using LayoutDeviceIntMargin = mozilla::LayoutDeviceIntMargin; 62 using LayoutDeviceIntSize = mozilla::LayoutDeviceIntSize; 63 using LayoutDeviceIntCoord = mozilla::LayoutDeviceIntCoord; 64 using StyleAppearance = mozilla::StyleAppearance; 65 using StyleScrollbarWidth = mozilla::StyleScrollbarWidth; 66 using ComputedStyle = mozilla::ComputedStyle; 67 68 public: 69 NS_INLINE_DECL_STATIC_IID(NS_ITHEME_IID) 70 71 /** 72 * Draw the actual theme background. 73 * @param aContext the context to draw into 74 * @param aFrame the frame for the widget that we're drawing 75 * @param aWidgetType the -moz-appearance value to draw 76 * @param aRect the rectangle defining the area occupied by the widget 77 * @param aDirtyRect the rectangle that needs to be drawn 78 * @param DrawOverflow whether outlines, shadows and other such overflowing 79 * things should be drawn. Honoring this creates better results for 80 * box-shadow, though it's not a hard requirement. 81 */ 82 enum class DrawOverflow { No, Yes }; 83 virtual void DrawWidgetBackground(gfxContext* aContext, nsIFrame* aFrame, 84 StyleAppearance aWidgetType, 85 const nsRect& aRect, 86 const nsRect& aDirtyRect, 87 DrawOverflow = DrawOverflow::Yes) = 0; 88 89 /** 90 * Create WebRender commands for the theme background. 91 * @return true if the theme knows how to create WebRender commands for the 92 * given widget type, false if DrawWidgetBackground need sto be called 93 * instead. 94 */ 95 virtual bool CreateWebRenderCommandsForWidget( 96 mozilla::wr::DisplayListBuilder& aBuilder, 97 mozilla::wr::IpcResourceUpdateQueue& aResources, 98 const mozilla::layers::StackingContextHelper& aSc, 99 mozilla::layers::RenderRootStateManager* aManager, nsIFrame* aFrame, 100 StyleAppearance aWidgetType, const nsRect& aRect) { 101 return false; 102 } 103 104 /** 105 * Returns the minimum widths of a scrollbar for a given style, that is, the 106 * minimum width for a vertical scrollbar, and the minimum height of a 107 * horizontal scrollbar. 108 */ 109 enum class Overlay { No, Yes }; 110 virtual LayoutDeviceIntCoord GetScrollbarSize(const nsPresContext*, 111 StyleScrollbarWidth, 112 Overlay) = 0; 113 114 /** 115 * Return the border for the widget, in device pixels. 116 */ 117 [[nodiscard]] virtual LayoutDeviceIntMargin GetWidgetBorder( 118 nsDeviceContext* aContext, nsIFrame* aFrame, 119 StyleAppearance aWidgetType) = 0; 120 121 /** 122 * This method can return false to indicate that the CSS padding 123 * value should be used. Otherwise, it will fill in aResult with the 124 * computed padding, in pixels, and return true. 125 * 126 * XXXldb This ought to be required to return true for non-containers 127 * so that we don't let specified padding that has no effect change 128 * the computed padding and potentially the size. 129 */ 130 virtual bool GetWidgetPadding(nsDeviceContext* aContext, nsIFrame* aFrame, 131 StyleAppearance aWidgetType, 132 LayoutDeviceIntMargin* aResult) = 0; 133 134 /** 135 * On entry, *aResult is positioned at 0,0 and sized to the new size 136 * of aFrame (aFrame->GetSize() may be stale and should not be used). 137 * This method can return false to indicate that no special 138 * overflow area is required by the native widget. Otherwise it will 139 * fill in aResult with the desired overflow area, in appunits, relative 140 * to the frame origin, and return true. 141 * 142 * This overflow area is used to determine what area needs to be 143 * repainted when the widget changes. However, it does not affect the 144 * widget's size or what area is reachable by scrollbars. (In other 145 * words, in layout terms, it affects ink overflow but not 146 * scrollable overflow.) 147 */ 148 virtual bool GetWidgetOverflow(nsDeviceContext* aContext, nsIFrame* aFrame, 149 StyleAppearance aWidgetType, 150 /*INOUT*/ nsRect* aOverflowRect) { 151 return false; 152 } 153 154 /** 155 * Get the preferred content-box size of a checkbox / radio button, in app 156 * units. Historically 9px. 157 */ 158 virtual mozilla::CSSCoord GetCheckboxRadioPrefSize() { 159 return mozilla::CSSCoord(9.0f); 160 } 161 162 /** Get the border width of a checkbox / radio button. */ 163 virtual mozilla::CSSCoord GetCheckboxRadioBorderWidth() { 164 return mozilla::CSSCoord(1.0f); 165 } 166 167 /* Get the minimum size of a themed range */ 168 virtual mozilla::CSSCoord GetMinimumRangeThumbSize() { 169 return mozilla::CSSCoord(20.0f); 170 } 171 172 /** 173 * Get the minimum border-box size of a widget, in device pixels. 174 */ 175 virtual mozilla::LayoutDeviceIntSize GetMinimumWidgetSize( 176 nsPresContext* aPresContext, nsIFrame* aFrame, 177 StyleAppearance aWidgetType) = 0; 178 179 enum Transparency { eOpaque = 0, eTransparent, eUnknownTransparency }; 180 181 /** Returns what we know about the transparency of the widget. */ 182 virtual Transparency GetWidgetTransparency(nsIFrame* aFrame, 183 StyleAppearance aWidgetType) { 184 return eUnknownTransparency; 185 } 186 187 /** Returns whether an attribute change should trigger a repaint. */ 188 virtual bool WidgetAttributeChangeRequiresRepaint(StyleAppearance, 189 nsAtom* aAttribute) = 0; 190 191 virtual void ThemeChanged() {} 192 193 virtual bool WidgetAppearanceDependsOnWindowFocus( 194 StyleAppearance aWidgetType) { 195 return false; 196 } 197 198 /** 199 * ThemeGeometryType values are used for describing themed nsIFrames in 200 * calls to nsIWidget::UpdateThemeGeometries. We don't simply pass the 201 * -moz-appearance value ("widget type") of the frame because the widget may 202 * want to treat different frames with the same -moz-appearance differently 203 * based on other properties of the frame. So we give the theme a first look 204 * at the frame in nsITheme::ThemeGeometryTypeForWidget and pass the 205 * returned ThemeGeometryType along to the widget. 206 * Each theme backend defines the ThemeGeometryType values it needs in its 207 * own nsITheme subclass. eThemeGeometryTypeUnknown is the only value that's 208 * shared between backends. 209 */ 210 typedef uint8_t ThemeGeometryType; 211 enum { eThemeGeometryTypeUnknown = 0 }; 212 213 /** 214 * Returns the theme geometry type that should be used in the ThemeGeometry 215 * array that's passed to the widget using nsIWidget::UpdateThemeGeometries. 216 * A return value of eThemeGeometryTypeUnknown means that this frame will 217 * not be included in the ThemeGeometry array. 218 */ 219 virtual ThemeGeometryType ThemeGeometryTypeForWidget( 220 nsIFrame* aFrame, StyleAppearance aWidgetType) { 221 return eThemeGeometryTypeUnknown; 222 } 223 224 /** 225 * Can the nsITheme implementation handle this widget? 226 */ 227 virtual bool ThemeSupportsWidget(nsPresContext* aPresContext, 228 nsIFrame* aFrame, 229 StyleAppearance aWidgetType) = 0; 230 231 /** 232 * Does the nsITheme implementation draw its own focus ring for this widget? 233 */ 234 virtual bool ThemeDrawsFocusForWidget(nsIFrame*, StyleAppearance) = 0; 235 236 /** 237 * Should we insert a dropmarker inside of combobox button? 238 */ 239 virtual bool ThemeNeedsComboboxDropmarker() = 0; 240 241 virtual bool ThemeSupportsScrollbarButtons() = 0; 242 }; 243 244 // Singleton accessor functions, these should never return null. 245 // 246 // Do not use directly, use nsPresContext::Theme instead. 247 extern already_AddRefed<nsITheme> do_GetNativeThemeDoNotUseDirectly(); 248 extern already_AddRefed<nsITheme> do_GetBasicNativeThemeDoNotUseDirectly(); 249 extern already_AddRefed<nsITheme> do_GetRDMThemeDoNotUseDirectly(); 250 251 // Native theme creation function, these should never return null. 252 extern already_AddRefed<mozilla::widget::Theme> 253 do_CreateNativeThemeDoNotUseDirectly(); 254 255 #endif