зеркало из https://github.com/mozilla/gecko-dev.git
161 строка
6.0 KiB
C++
161 строка
6.0 KiB
C++
/* -*- Mode: C++; tab-width: 40; 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/. */
|
|
|
|
#include "nsNativeBasicThemeGTK.h"
|
|
|
|
#include "nsLayoutUtils.h"
|
|
#include "nsIFrame.h"
|
|
#include "nsContainerFrame.h"
|
|
#include "mozilla/dom/Document.h"
|
|
#include "mozilla/ClearOnShutdown.h"
|
|
#include "mozilla/StaticPrefs_widget.h"
|
|
|
|
using namespace mozilla;
|
|
|
|
already_AddRefed<nsITheme> do_GetBasicNativeThemeDoNotUseDirectly() {
|
|
static StaticRefPtr<nsITheme> gInstance;
|
|
if (MOZ_UNLIKELY(!gInstance)) {
|
|
gInstance = new nsNativeBasicThemeGTK();
|
|
ClearOnShutdown(&gInstance);
|
|
}
|
|
return do_AddRef(gInstance);
|
|
}
|
|
|
|
nsITheme::Transparency nsNativeBasicThemeGTK::GetWidgetTransparency(
|
|
nsIFrame* aFrame, StyleAppearance aAppearance) {
|
|
if (!sOverlayScrollbars &&
|
|
(aAppearance == StyleAppearance::ScrollbarVertical ||
|
|
aAppearance == StyleAppearance::ScrollbarHorizontal) &&
|
|
IsScrollbarTrackOpaque(aFrame)) {
|
|
return eOpaque;
|
|
}
|
|
return nsNativeBasicTheme::GetWidgetTransparency(aFrame, aAppearance);
|
|
}
|
|
|
|
bool nsNativeBasicThemeGTK::ThemeSupportsScrollbarButtons() {
|
|
return StaticPrefs::widget_non_native_theme_gtk_scrollbar_allow_buttons();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsNativeBasicThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext,
|
|
nsIFrame* aFrame,
|
|
StyleAppearance aAppearance,
|
|
LayoutDeviceIntSize* aResult,
|
|
bool* aIsOverridable) {
|
|
if (!IsWidgetScrollbarPart(aAppearance)) {
|
|
return nsNativeBasicTheme::GetMinimumWidgetSize(
|
|
aPresContext, aFrame, aAppearance, aResult, aIsOverridable);
|
|
}
|
|
|
|
DPIRatio dpiRatio = GetDPIRatioForScrollbarPart(aPresContext);
|
|
ComputedStyle* style = nsLayoutUtils::StyleForScrollbar(aFrame);
|
|
auto sizes = GetScrollbarSizes(
|
|
aPresContext, style->StyleUIReset()->mScrollbarWidth, Overlay::No);
|
|
MOZ_ASSERT(sizes.mHorizontal == sizes.mVertical);
|
|
aResult->SizeTo(sizes.mHorizontal, sizes.mHorizontal);
|
|
|
|
if (aAppearance == StyleAppearance::ScrollbarHorizontal ||
|
|
aAppearance == StyleAppearance::ScrollbarVertical ||
|
|
aAppearance == StyleAppearance::ScrollbarthumbHorizontal ||
|
|
aAppearance == StyleAppearance::ScrollbarthumbVertical) {
|
|
CSSCoord thumbSize(
|
|
StaticPrefs::widget_non_native_theme_gtk_scrollbar_thumb_cross_size());
|
|
const bool isVertical =
|
|
aAppearance == StyleAppearance::ScrollbarVertical ||
|
|
aAppearance == StyleAppearance::ScrollbarthumbVertical;
|
|
if (isVertical) {
|
|
aResult->height = thumbSize * dpiRatio;
|
|
} else {
|
|
aResult->width = thumbSize * dpiRatio;
|
|
}
|
|
}
|
|
|
|
*aIsOverridable = true;
|
|
return NS_OK;
|
|
}
|
|
|
|
static nsIFrame* GetParentScrollbarFrame(nsIFrame* aFrame) {
|
|
// Walk our parents to find a scrollbar frame
|
|
nsIFrame* scrollbarFrame = aFrame;
|
|
do {
|
|
if (scrollbarFrame->IsScrollbarFrame()) {
|
|
break;
|
|
}
|
|
} while ((scrollbarFrame = scrollbarFrame->GetParent()));
|
|
|
|
// We return null if we can't find a parent scrollbar frame
|
|
return scrollbarFrame;
|
|
}
|
|
|
|
static bool IsParentScrollbarHoveredOrActive(nsIFrame* aFrame) {
|
|
nsIFrame* scrollbarFrame = GetParentScrollbarFrame(aFrame);
|
|
return scrollbarFrame && scrollbarFrame->GetContent()
|
|
->AsElement()
|
|
->State()
|
|
.HasAtLeastOneOfStates(NS_EVENT_STATE_HOVER |
|
|
NS_EVENT_STATE_ACTIVE);
|
|
}
|
|
|
|
template <typename PaintBackendData>
|
|
bool nsNativeBasicThemeGTK::DoPaintScrollbarThumb(
|
|
PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
|
|
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
|
|
const EventStates& aElementState, const EventStates& aDocumentState,
|
|
const Colors& aColors, DPIRatio aDpiRatio) {
|
|
sRGBColor thumbColor = ComputeScrollbarThumbColor(
|
|
aFrame, aStyle, aElementState, aDocumentState, aColors);
|
|
|
|
LayoutDeviceRect thumbRect(aRect);
|
|
|
|
if (sOverlayScrollbars && !IsParentScrollbarHoveredOrActive(aFrame)) {
|
|
if (aHorizontal) {
|
|
thumbRect.height *= 0.5;
|
|
thumbRect.y += thumbRect.height;
|
|
} else {
|
|
thumbRect.width *= 0.5;
|
|
if (aFrame->GetWritingMode().IsPhysicalLTR()) {
|
|
thumbRect.x += thumbRect.width;
|
|
}
|
|
}
|
|
}
|
|
|
|
{
|
|
float factor = std::max(
|
|
0.0f,
|
|
1.0f - StaticPrefs::widget_non_native_theme_gtk_scrollbar_thumb_size());
|
|
thumbRect.Deflate((aHorizontal ? thumbRect.height : thumbRect.width) *
|
|
factor);
|
|
}
|
|
|
|
LayoutDeviceCoord radius =
|
|
StaticPrefs::widget_non_native_theme_gtk_scrollbar_round_thumb()
|
|
? (aHorizontal ? thumbRect.height : thumbRect.width) / 2.0f
|
|
: 0.0f;
|
|
|
|
PaintRoundedRectWithRadius(aPaintData, thumbRect, thumbColor, sRGBColor(), 0,
|
|
radius / aDpiRatio, aDpiRatio);
|
|
return true;
|
|
}
|
|
|
|
bool nsNativeBasicThemeGTK::PaintScrollbarThumb(
|
|
DrawTarget& aDrawTarget, const LayoutDeviceRect& aRect, bool aHorizontal,
|
|
nsIFrame* aFrame, const ComputedStyle& aStyle,
|
|
const EventStates& aElementState, const EventStates& aDocumentState,
|
|
const Colors& aColors, DPIRatio aDpiRatio) {
|
|
return DoPaintScrollbarThumb(aDrawTarget, aRect, aHorizontal, aFrame, aStyle,
|
|
aElementState, aDocumentState, aColors,
|
|
aDpiRatio);
|
|
}
|
|
|
|
bool nsNativeBasicThemeGTK::PaintScrollbarThumb(
|
|
WebRenderBackendData& aWrData, const LayoutDeviceRect& aRect,
|
|
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
|
|
const EventStates& aElementState, const EventStates& aDocumentState,
|
|
const Colors& aColors, DPIRatio aDpiRatio) {
|
|
return DoPaintScrollbarThumb(aWrData, aRect, aHorizontal, aFrame, aStyle,
|
|
aElementState, aDocumentState, aColors,
|
|
aDpiRatio);
|
|
}
|