1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * 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 nsNativeThemeWin_h 8 #define nsNativeThemeWin_h 9 10 #include "nsITheme.h" 11 #include "nsCOMPtr.h" 12 #include "nsAtom.h" 13 #include "nsNativeTheme.h" 14 #include "nsThemeConstants.h" 15 #include "nsUXThemeConstants.h" 16 #include "nsUXThemeData.h" 17 #include "gfxTypes.h" 18 #include <windows.h> 19 #include "mozilla/Maybe.h" 20 #include "mozilla/TimeStamp.h" 21 #include "nsSize.h" 22 23 class nsNativeThemeWin : private nsNativeTheme, public nsITheme { 24 virtual ~nsNativeThemeWin(); 25 26 public: 27 typedef mozilla::TimeStamp TimeStamp; 28 typedef mozilla::TimeDuration TimeDuration; 29 30 NS_DECL_ISUPPORTS_INHERITED 31 32 // The nsITheme interface. 33 NS_IMETHOD DrawWidgetBackground(gfxContext* aContext, nsIFrame* aFrame, 34 uint8_t aWidgetType, const nsRect& aRect, 35 const nsRect& aDirtyRect) override; 36 37 NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame, 38 uint8_t aWidgetType, 39 nsIntMargin* aResult) override; 40 41 virtual bool GetWidgetPadding(nsDeviceContext* aContext, nsIFrame* aFrame, 42 uint8_t aWidgetType, 43 nsIntMargin* aResult) override; 44 45 virtual bool GetWidgetOverflow(nsDeviceContext* aContext, nsIFrame* aFrame, 46 uint8_t aWidgetType, 47 nsRect* aOverflowRect) override; 48 49 NS_IMETHOD GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aFrame, 50 uint8_t aWidgetType, 51 mozilla::LayoutDeviceIntSize* aResult, 52 bool* aIsOverridable) override; 53 54 virtual Transparency GetWidgetTransparency(nsIFrame* aFrame, 55 uint8_t aWidgetType) override; 56 57 NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType, 58 nsAtom* aAttribute, bool* aShouldRepaint, 59 const nsAttrValue* aOldValue) override; 60 61 NS_IMETHOD ThemeChanged() override; 62 63 bool ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* aFrame, 64 uint8_t aWidgetType) override; 65 66 bool WidgetIsContainer(uint8_t aWidgetType) override; 67 68 bool ThemeDrawsFocusForWidget(uint8_t aWidgetType) override; 69 70 bool ThemeNeedsComboboxDropmarker() override; 71 72 virtual bool WidgetAppearanceDependsOnWindowFocus( 73 uint8_t aWidgetType) override; 74 75 enum { eThemeGeometryTypeWindowButtons = eThemeGeometryTypeUnknown + 1 }; 76 virtual ThemeGeometryType ThemeGeometryTypeForWidget( 77 nsIFrame* aFrame, uint8_t aWidgetType) override; 78 79 virtual bool ShouldHideScrollbars() override; 80 81 nsNativeThemeWin(); 82 83 protected: 84 mozilla::Maybe<nsUXThemeClass> GetThemeClass(uint8_t aWidgetType); 85 HANDLE GetTheme(uint8_t aWidgetType); 86 nsresult GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, 87 int32_t& aPart, int32_t& aState); 88 nsresult ClassicGetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType, 89 int32_t& aPart, int32_t& aState, 90 bool& aFocused); 91 nsresult ClassicDrawWidgetBackground(gfxContext* aContext, nsIFrame* aFrame, 92 uint8_t aWidgetType, const nsRect& aRect, 93 const nsRect& aClipRect); 94 nsresult ClassicGetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame, 95 uint8_t aWidgetType, nsIntMargin* aResult); 96 bool ClassicGetWidgetPadding(nsDeviceContext* aContext, nsIFrame* aFrame, 97 uint8_t aWidgetType, nsIntMargin* aResult); 98 nsresult ClassicGetMinimumWidgetSize(nsIFrame* aFrame, uint8_t aWidgetType, 99 mozilla::LayoutDeviceIntSize* aResult, 100 bool* aIsOverridable); 101 bool ClassicThemeSupportsWidget(nsIFrame* aFrame, uint8_t aWidgetType); 102 void DrawCheckedRect(HDC hdc, const RECT& rc, int32_t fore, int32_t back, 103 HBRUSH defaultBack); 104 uint32_t GetWidgetNativeDrawingFlags(uint8_t aWidgetType); 105 int32_t StandardGetState(nsIFrame* aFrame, uint8_t aWidgetType, 106 bool wantFocused); 107 bool IsMenuActive(nsIFrame* aFrame, uint8_t aWidgetType); 108 RECT CalculateProgressOverlayRect(nsIFrame* aFrame, RECT* aWidgetRect, 109 bool aIsVertical, bool aIsIndeterminate, 110 bool aIsClassic); 111 void DrawThemedProgressMeter(nsIFrame* aFrame, int aWidgetType, HANDLE aTheme, 112 HDC aHdc, int aPart, int aState, 113 RECT* aWidgetRect, RECT* aClipRect); 114 115 nsresult GetCachedWidgetBorder(nsIFrame* aFrame, HANDLE aTheme, 116 nsUXThemeClass aThemeClass, 117 uint8_t aWidgetType, int32_t aPart, 118 int32_t aState, nsIntMargin* aResult); 119 120 nsresult GetCachedMinimumWidgetSize(nsIFrame* aFrame, HANDLE aTheme, 121 nsUXThemeClass aThemeClass, 122 uint8_t aWidgetType, int32_t aPart, 123 int32_t aState, THEMESIZE aSizeReq, 124 mozilla::LayoutDeviceIntSize* aResult); 125 126 SIZE GetCachedGutterSize(HANDLE theme); 127 128 private: 129 TimeStamp mProgressDeterminateTimeStamp; 130 TimeStamp mProgressIndeterminateTimeStamp; 131 132 // eUXNumClasses * THEME_PART_DISTINCT_VALUE_COUNT is about 800 at the time of 133 // writing this, and nsIntMargin is 16 bytes wide, which makes this cache (1/8 134 // + 16) * 800 bytes, or about ~12KB. We could probably reduce this cache to 135 // 3KB by caching on the aWidgetType value instead, but there would be some 136 // uncacheable values, since we derive some theme parts from other arguments. 137 uint8_t 138 mBorderCacheValid[(eUXNumClasses * THEME_PART_DISTINCT_VALUE_COUNT + 7) / 139 8]; 140 nsIntMargin mBorderCache[eUXNumClasses * THEME_PART_DISTINCT_VALUE_COUNT]; 141 142 // See the above not for mBorderCache and friends. However 143 // mozilla::LayoutDeviceIntSize is half the size of nsIntMargin, making the 144 // cache roughly half as large. In total the caches should come to about 18KB. 145 uint8_t mMinimumWidgetSizeCacheValid 146 [(eUXNumClasses * THEME_PART_DISTINCT_VALUE_COUNT + 7) / 8]; 147 mozilla::LayoutDeviceIntSize 148 mMinimumWidgetSizeCache[eUXNumClasses * THEME_PART_DISTINCT_VALUE_COUNT]; 149 150 bool mGutterSizeCacheValid; 151 SIZE mGutterSizeCache; 152 }; 153 154 #endif 155