michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: // This defines a common base class for nsITheme implementations, to reduce michael@0: // code duplication. michael@0: michael@0: #include "nsAlgorithm.h" michael@0: #include "nsIAtom.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsString.h" michael@0: #include "nsMargin.h" michael@0: #include "nsGkAtoms.h" michael@0: #include "nsTArray.h" michael@0: #include "nsITimer.h" michael@0: #include "nsIContent.h" michael@0: michael@0: class nsIFrame; michael@0: class nsIPresShell; michael@0: class nsPresContext; michael@0: michael@0: namespace mozilla { michael@0: class EventStates; michael@0: } // namespace mozilla michael@0: michael@0: class nsNativeTheme : public nsITimerCallback michael@0: { michael@0: protected: michael@0: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSITIMERCALLBACK michael@0: michael@0: enum ScrollbarButtonType { michael@0: eScrollbarButton_UpTop = 0, michael@0: eScrollbarButton_Down = 1 << 0, michael@0: eScrollbarButton_Bottom = 1 << 1 michael@0: }; michael@0: michael@0: enum TreeSortDirection { michael@0: eTreeSortDirection_Descending, michael@0: eTreeSortDirection_Natural, michael@0: eTreeSortDirection_Ascending michael@0: }; michael@0: michael@0: nsNativeTheme(); michael@0: virtual ~nsNativeTheme() {} michael@0: michael@0: // Returns the content state (hover, focus, etc), see EventStateManager.h michael@0: mozilla::EventStates GetContentState(nsIFrame* aFrame, uint8_t aWidgetType); michael@0: michael@0: // Returns whether the widget is already styled by content michael@0: // Normally called from ThemeSupportsWidget to turn off native theming michael@0: // for elements that are already styled. michael@0: bool IsWidgetStyled(nsPresContext* aPresContext, nsIFrame* aFrame, michael@0: uint8_t aWidgetType); michael@0: michael@0: // Accessors to widget-specific state information michael@0: michael@0: bool IsDisabled(nsIFrame* aFrame, mozilla::EventStates aEventStates); michael@0: michael@0: // RTL chrome direction michael@0: bool IsFrameRTL(nsIFrame* aFrame); michael@0: michael@0: bool IsHTMLContent(nsIFrame *aFrame); michael@0: michael@0: // button: michael@0: bool IsDefaultButton(nsIFrame* aFrame) { michael@0: return CheckBooleanAttr(aFrame, nsGkAtoms::_default); michael@0: } michael@0: michael@0: bool IsButtonTypeMenu(nsIFrame* aFrame); michael@0: michael@0: // checkbox: michael@0: bool IsChecked(nsIFrame* aFrame) { michael@0: return GetCheckedOrSelected(aFrame, false); michael@0: } michael@0: michael@0: // radiobutton: michael@0: bool IsSelected(nsIFrame* aFrame) { michael@0: return GetCheckedOrSelected(aFrame, true); michael@0: } michael@0: michael@0: bool IsFocused(nsIFrame* aFrame) { michael@0: return CheckBooleanAttr(aFrame, nsGkAtoms::focused); michael@0: } michael@0: michael@0: // scrollbar button: michael@0: int32_t GetScrollbarButtonType(nsIFrame* aFrame); michael@0: michael@0: // tab: michael@0: bool IsSelectedTab(nsIFrame* aFrame) { michael@0: return CheckBooleanAttr(aFrame, nsGkAtoms::selected); michael@0: } michael@0: michael@0: bool IsNextToSelectedTab(nsIFrame* aFrame, int32_t aOffset); michael@0: michael@0: bool IsBeforeSelectedTab(nsIFrame* aFrame) { michael@0: return IsNextToSelectedTab(aFrame, -1); michael@0: } michael@0: michael@0: bool IsAfterSelectedTab(nsIFrame* aFrame) { michael@0: return IsNextToSelectedTab(aFrame, 1); michael@0: } michael@0: michael@0: bool IsLeftToSelectedTab(nsIFrame* aFrame) { michael@0: return IsFrameRTL(aFrame) ? IsAfterSelectedTab(aFrame) : IsBeforeSelectedTab(aFrame); michael@0: } michael@0: michael@0: bool IsRightToSelectedTab(nsIFrame* aFrame) { michael@0: return IsFrameRTL(aFrame) ? IsBeforeSelectedTab(aFrame) : IsAfterSelectedTab(aFrame); michael@0: } michael@0: michael@0: // button / toolbarbutton: michael@0: bool IsCheckedButton(nsIFrame* aFrame) { michael@0: return CheckBooleanAttr(aFrame, nsGkAtoms::checked); michael@0: } michael@0: michael@0: bool IsSelectedButton(nsIFrame* aFrame) { michael@0: return CheckBooleanAttr(aFrame, nsGkAtoms::checked) || michael@0: CheckBooleanAttr(aFrame, nsGkAtoms::selected); michael@0: } michael@0: michael@0: bool IsOpenButton(nsIFrame* aFrame) { michael@0: return CheckBooleanAttr(aFrame, nsGkAtoms::open); michael@0: } michael@0: michael@0: bool IsPressedButton(nsIFrame* aFrame); michael@0: michael@0: // treeheadercell: michael@0: TreeSortDirection GetTreeSortDirection(nsIFrame* aFrame); michael@0: bool IsLastTreeHeaderCell(nsIFrame* aFrame); michael@0: michael@0: // tab: michael@0: bool IsBottomTab(nsIFrame* aFrame); michael@0: bool IsFirstTab(nsIFrame* aFrame); michael@0: michael@0: bool IsHorizontal(nsIFrame* aFrame); michael@0: michael@0: // progressbar: michael@0: bool IsIndeterminateProgress(nsIFrame* aFrame, michael@0: mozilla::EventStates aEventStates); michael@0: bool IsVerticalProgress(nsIFrame* aFrame); michael@0: michael@0: // meter: michael@0: bool IsVerticalMeter(nsIFrame* aFrame); michael@0: michael@0: // textfield: michael@0: bool IsReadOnly(nsIFrame* aFrame) { michael@0: return CheckBooleanAttr(aFrame, nsGkAtoms::readonly); michael@0: } michael@0: michael@0: // menupopup: michael@0: bool IsSubmenu(nsIFrame* aFrame, bool* aLeftOfParent); michael@0: michael@0: // True if it's not a menubar item or menulist item michael@0: bool IsRegularMenuItem(nsIFrame *aFrame); michael@0: michael@0: bool IsMenuListEditable(nsIFrame *aFrame); michael@0: michael@0: nsIPresShell *GetPresShell(nsIFrame* aFrame); michael@0: static bool CheckBooleanAttr(nsIFrame* aFrame, nsIAtom* aAtom); michael@0: static int32_t CheckIntAttr(nsIFrame* aFrame, nsIAtom* aAtom, int32_t defaultValue); michael@0: michael@0: // Helpers for progressbar. michael@0: static double GetProgressValue(nsIFrame* aFrame); michael@0: static double GetProgressMaxValue(nsIFrame* aFrame); michael@0: michael@0: bool GetCheckedOrSelected(nsIFrame* aFrame, bool aCheckSelected); michael@0: bool GetIndeterminate(nsIFrame* aFrame); michael@0: michael@0: bool QueueAnimatedContentForRefresh(nsIContent* aContent, michael@0: uint32_t aMinimumFrameRate); michael@0: michael@0: nsIFrame* GetAdjacentSiblingFrameWithSameAppearance(nsIFrame* aFrame, michael@0: bool aNextSibling); michael@0: michael@0: bool IsRangeHorizontal(nsIFrame* aFrame); michael@0: michael@0: // scrollbar michael@0: bool IsDarkBackground(nsIFrame* aFrame); michael@0: michael@0: private: michael@0: uint32_t mAnimatedContentTimeout; michael@0: nsCOMPtr mAnimatedContentTimer; michael@0: nsAutoTArray, 20> mAnimatedContentList; michael@0: };