DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (409f3966645a)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef nsNativeThemeWin_h
#define nsNativeThemeWin_h

#include "nsITheme.h"
#include "nsCOMPtr.h"
#include "nsAtom.h"
#include "nsNativeTheme.h"
#include "nsStyleConsts.h"
#include "nsUXThemeConstants.h"
#include "nsUXThemeData.h"
#include "gfxTypes.h"
#include <windows.h>
#include "mozilla/Maybe.h"
#include "mozilla/TimeStamp.h"
#include "nsSize.h"

class nsNativeThemeWin : private nsNativeTheme,
                         public nsITheme {
  virtual ~nsNativeThemeWin();

public:
  typedef mozilla::TimeStamp TimeStamp;
  typedef mozilla::TimeDuration TimeDuration;

  NS_DECL_ISUPPORTS_INHERITED

  // The nsITheme interface.
  NS_IMETHOD DrawWidgetBackground(gfxContext* aContext,
                                  nsIFrame* aFrame,
                                  WidgetType aWidgetType,
                                  const nsRect& aRect,
                                  const nsRect& aDirtyRect) override;

  nscolor GetWidgetAutoColor(mozilla::ComputedStyle* aStyle,
                             WidgetType aWidgetType) override;

  MOZ_MUST_USE LayoutDeviceIntMargin GetWidgetBorder(nsDeviceContext* aContext,
                                                     nsIFrame* aFrame,
                                                     WidgetType aWidgetType) override;

  bool GetWidgetPadding(nsDeviceContext* aContext,
                        nsIFrame* aFrame,
                        WidgetType aWidgetType,
                        LayoutDeviceIntMargin* aResult) override;

  virtual bool GetWidgetOverflow(nsDeviceContext* aContext,
                                   nsIFrame* aFrame,
                                   WidgetType aWidgetType,
                                   nsRect* aOverflowRect) override;

  NS_IMETHOD GetMinimumWidgetSize(nsPresContext* aPresContext, nsIFrame* aFrame,
                                  WidgetType aWidgetType,
                                  mozilla::LayoutDeviceIntSize* aResult,
                                  bool* aIsOverridable) override;

  virtual Transparency GetWidgetTransparency(nsIFrame* aFrame, WidgetType aWidgetType) override;

  NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, WidgetType aWidgetType, 
                                nsAtom* aAttribute, bool* aShouldRepaint,
                                const nsAttrValue* aOldValue) override;

  NS_IMETHOD ThemeChanged() override;

  bool ThemeSupportsWidget(nsPresContext* aPresContext, 
                             nsIFrame* aFrame,
                             WidgetType aWidgetType) override;

  bool WidgetIsContainer(WidgetType aWidgetType) override;

  bool ThemeDrawsFocusForWidget(WidgetType aWidgetType) override;

  bool ThemeNeedsComboboxDropmarker() override;

  virtual bool WidgetAppearanceDependsOnWindowFocus(WidgetType aWidgetType) override;

  enum {
    eThemeGeometryTypeWindowButtons = eThemeGeometryTypeUnknown + 1
  };
  virtual ThemeGeometryType ThemeGeometryTypeForWidget(nsIFrame* aFrame,
                                                       WidgetType aWidgetType) override;

  nsNativeThemeWin();

protected:
  mozilla::Maybe<nsUXThemeClass> GetThemeClass(WidgetType aWidgetType);
  HANDLE GetTheme(WidgetType aWidgetType);
  nsresult GetThemePartAndState(nsIFrame* aFrame, WidgetType aWidgetType,
                                int32_t& aPart, int32_t& aState);
  nsresult ClassicGetThemePartAndState(nsIFrame* aFrame, WidgetType aWidgetType,
                                       int32_t& aPart, int32_t& aState, bool& aFocused);
  nsresult ClassicDrawWidgetBackground(gfxContext* aContext,
                                       nsIFrame* aFrame,
                                       WidgetType aWidgetType,
                                       const nsRect& aRect,
                                       const nsRect& aClipRect);
  MOZ_MUST_USE LayoutDeviceIntMargin ClassicGetWidgetBorder(nsDeviceContext* aContext,
                                                            nsIFrame* aFrame,
                                                            WidgetType aWidgetType);
  bool ClassicGetWidgetPadding(nsDeviceContext* aContext,
                               nsIFrame* aFrame,
                               WidgetType aWidgetType,
                               LayoutDeviceIntMargin* aResult);
  nsresult ClassicGetMinimumWidgetSize(nsIFrame* aFrame, WidgetType aWidgetType,
                                       mozilla::LayoutDeviceIntSize* aResult,
                                       bool* aIsOverridable);
  bool ClassicThemeSupportsWidget(nsIFrame* aFrame, WidgetType aWidgetType);
  void DrawCheckedRect(HDC hdc, const RECT& rc, int32_t fore, int32_t back,
                       HBRUSH defaultBack);
  nsresult DrawCustomScrollbarPart(gfxContext* aContext,
                                   nsIFrame* aFrame,
                                   mozilla::ComputedStyle* aStyle,
                                   WidgetType aWidgetType,
                                   const nsRect& aRect,
                                   const nsRect& aClipRect);
  uint32_t GetWidgetNativeDrawingFlags(WidgetType aWidgetType);
  int32_t StandardGetState(nsIFrame* aFrame, WidgetType aWidgetType, bool wantFocused);
  bool IsMenuActive(nsIFrame* aFrame, WidgetType aWidgetType);
  RECT CalculateProgressOverlayRect(nsIFrame* aFrame, RECT* aWidgetRect,
                                    bool aIsVertical, bool aIsIndeterminate,
                                    bool aIsClassic);
  void DrawThemedProgressMeter(nsIFrame* aFrame, WidgetType aWidgetType,
                               HANDLE aTheme, HDC aHdc,
                               int aPart, int aState,
                               RECT* aWidgetRect, RECT* aClipRect);

  MOZ_MUST_USE LayoutDeviceIntMargin GetCachedWidgetBorder(HANDLE aTheme,
                                                           nsUXThemeClass aThemeClass,
                                                           WidgetType aWidgetType,
                                                           int32_t aPart,
                                                           int32_t aState);

  nsresult GetCachedMinimumWidgetSize(nsIFrame* aFrame, HANDLE aTheme, nsUXThemeClass aThemeClass,
                                      WidgetType aWidgetType, int32_t aPart, int32_t aState,
                                      THEMESIZE aSizeReq, mozilla::LayoutDeviceIntSize* aResult);

  SIZE GetCachedGutterSize(HANDLE theme);

private:
  TimeStamp mProgressDeterminateTimeStamp;
  TimeStamp mProgressIndeterminateTimeStamp;

  // eUXNumClasses * THEME_PART_DISTINCT_VALUE_COUNT is about 800 at the time of writing
  // this, and nsIntMargin is 16 bytes wide, which makes this cache (1/8 + 16) * 800
  // bytes, or about ~12KB. We could probably reduce this cache to 3KB by caching on
  // the aWidgetType value instead, but there would be some uncacheable values, since
  // we derive some theme parts from other arguments.
  uint8_t mBorderCacheValid[(eUXNumClasses * THEME_PART_DISTINCT_VALUE_COUNT + 7) / 8];
  LayoutDeviceIntMargin mBorderCache[eUXNumClasses * THEME_PART_DISTINCT_VALUE_COUNT];

  // See the above not for mBorderCache and friends. However mozilla::LayoutDeviceIntSize
  // is half the size of nsIntMargin, making the cache roughly half as large. In total
  // the caches should come to about 18KB.
  uint8_t mMinimumWidgetSizeCacheValid[(eUXNumClasses * THEME_PART_DISTINCT_VALUE_COUNT + 7) / 8];
  mozilla::LayoutDeviceIntSize mMinimumWidgetSizeCache[eUXNumClasses * THEME_PART_DISTINCT_VALUE_COUNT];

  bool mGutterSizeCacheValid;
  SIZE mGutterSizeCache;
};

#endif