ScrollbarThemeChromiumWin.cpp [plain text]
#include "config.h"
#include "ScrollbarThemeChromiumWin.h"
#include <windows.h>
#include <vsstyle.h>
#include "GraphicsContext.h"
#include "PlatformContextSkia.h"
#include "PlatformMouseEvent.h"
#include "PlatformSupport.h"
#include "Scrollbar.h"
#include "SystemInfo.h"
namespace WebCore {
ScrollbarTheme* ScrollbarTheme::nativeTheme()
{
static ScrollbarThemeChromiumWin theme;
return &theme;
}
static const int kMacScrollbarSize[3] = { 15, 11, 15 };
static const int kOffEndMultiplier = 3;
static const int kOffSideMultiplier = 8;
int ScrollbarThemeChromiumWin::scrollbarThickness(ScrollbarControlSize controlSize)
{
static int thickness;
if (!thickness) {
if (PlatformSupport::layoutTestMode())
return kMacScrollbarSize[controlSize];
thickness = GetSystemMetrics(SM_CXVSCROLL);
}
return thickness;
}
bool ScrollbarThemeChromiumWin::invalidateOnMouseEnterExit()
{
return windowsVersion() >= WindowsVista;
}
bool ScrollbarThemeChromiumWin::shouldSnapBackToDragOrigin(ScrollbarThemeClient* scrollbar, const PlatformMouseEvent& evt)
{
IntRect rect = trackRect(scrollbar);
const bool horz = scrollbar->orientation() == HorizontalScrollbar;
const int thickness = scrollbarThickness(scrollbar->controlSize());
rect.inflateX((horz ? kOffEndMultiplier : kOffSideMultiplier) * thickness);
rect.inflateY((horz ? kOffSideMultiplier : kOffEndMultiplier) * thickness);
IntPoint mousePosition = scrollbar->convertFromContainingWindow(evt.position());
mousePosition.move(scrollbar->x(), scrollbar->y());
return !rect.contains(mousePosition);
}
void ScrollbarThemeChromiumWin::paintTrackPiece(GraphicsContext* gc, ScrollbarThemeClient* scrollbar, const IntRect& rect, ScrollbarPart partType)
{
bool horz = scrollbar->orientation() == HorizontalScrollbar;
int partId;
if (partType == BackTrackPart)
partId = horz ? SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT;
else
partId = horz ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
IntRect alignRect = trackRect(scrollbar, false);
PlatformSupport::paintScrollbarTrack(
gc,
partId,
getThemeState(scrollbar, partType),
getClassicThemeState(scrollbar, partType),
rect,
alignRect);
}
void ScrollbarThemeChromiumWin::paintButton(GraphicsContext* gc, ScrollbarThemeClient* scrollbar, const IntRect& rect, ScrollbarPart part)
{
bool horz = scrollbar->orientation() == HorizontalScrollbar;
int partId;
if (part == BackButtonStartPart || part == ForwardButtonStartPart)
partId = horz ? DFCS_SCROLLLEFT : DFCS_SCROLLUP;
else
partId = horz ? DFCS_SCROLLRIGHT : DFCS_SCROLLDOWN;
PlatformSupport::paintScrollbarArrow(
gc,
getThemeArrowState(scrollbar, part),
partId | getClassicThemeState(scrollbar, part),
rect);
}
void ScrollbarThemeChromiumWin::paintThumb(GraphicsContext* gc, ScrollbarThemeClient* scrollbar, const IntRect& rect)
{
bool horz = scrollbar->orientation() == HorizontalScrollbar;
PlatformSupport::paintScrollbarThumb(
gc,
horz ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT,
getThemeState(scrollbar, ThumbPart),
getClassicThemeState(scrollbar, ThumbPart),
rect);
PlatformSupport::paintScrollbarThumb(
gc,
horz ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT,
getThemeState(scrollbar, ThumbPart),
getClassicThemeState(scrollbar, ThumbPart),
rect);
}
int ScrollbarThemeChromiumWin::getThemeState(ScrollbarThemeClient* scrollbar, ScrollbarPart part) const
{
if (scrollbar->pressedPart() == ThumbPart) {
if (part == ThumbPart)
return SCRBS_PRESSED;
return (windowsVersion() < WindowsVista) ? SCRBS_NORMAL : SCRBS_HOVER;
}
if (!scrollbar->enabled())
return SCRBS_DISABLED;
if (scrollbar->hoveredPart() != part || part == BackTrackPart || part == ForwardTrackPart)
return (scrollbar->hoveredPart() == NoPart || (windowsVersion() < WindowsVista)) ? SCRBS_NORMAL : SCRBS_HOVER;
if (scrollbar->pressedPart() == NoPart)
return SCRBS_HOT;
return (scrollbar->pressedPart() == part) ? SCRBS_PRESSED : SCRBS_NORMAL;
}
int ScrollbarThemeChromiumWin::getThemeArrowState(ScrollbarThemeClient* scrollbar, ScrollbarPart part) const
{
if (part == BackButtonStartPart || part == ForwardButtonStartPart) {
if (scrollbar->orientation() == HorizontalScrollbar) {
if (scrollbar->pressedPart() == ThumbPart)
return (windowsVersion() < WindowsVista) ? ABS_LEFTNORMAL : ABS_LEFTHOVER;
if (!scrollbar->enabled())
return ABS_LEFTDISABLED;
if (scrollbar->hoveredPart() != part)
return ((scrollbar->hoveredPart() == NoPart) || (windowsVersion() < WindowsVista)) ? ABS_LEFTNORMAL : ABS_LEFTHOVER;
if (scrollbar->pressedPart() == NoPart)
return ABS_LEFTHOT;
return (scrollbar->pressedPart() == part) ?
ABS_LEFTPRESSED : ABS_LEFTNORMAL;
}
if (scrollbar->pressedPart() == ThumbPart)
return (windowsVersion() < WindowsVista) ? ABS_UPNORMAL : ABS_UPHOVER;
if (!scrollbar->enabled())
return ABS_UPDISABLED;
if (scrollbar->hoveredPart() != part)
return ((scrollbar->hoveredPart() == NoPart) || (windowsVersion() < WindowsVista)) ? ABS_UPNORMAL : ABS_UPHOVER;
if (scrollbar->pressedPart() == NoPart)
return ABS_UPHOT;
return (scrollbar->pressedPart() == part) ? ABS_UPPRESSED : ABS_UPNORMAL;
}
if (scrollbar->orientation() == HorizontalScrollbar) {
if (scrollbar->pressedPart() == ThumbPart)
return (windowsVersion() < WindowsVista) ? ABS_RIGHTNORMAL : ABS_RIGHTHOVER;
if (!scrollbar->enabled())
return ABS_RIGHTDISABLED;
if (scrollbar->hoveredPart() != part)
return ((scrollbar->hoveredPart() == NoPart) || (windowsVersion() < WindowsVista)) ? ABS_RIGHTNORMAL : ABS_RIGHTHOVER;
if (scrollbar->pressedPart() == NoPart)
return ABS_RIGHTHOT;
return (scrollbar->pressedPart() == part) ? ABS_RIGHTPRESSED : ABS_RIGHTNORMAL;
}
if (scrollbar->pressedPart() == ThumbPart)
return (windowsVersion() < WindowsVista) ? ABS_DOWNNORMAL : ABS_DOWNHOVER;
if (!scrollbar->enabled())
return ABS_DOWNDISABLED;
if (scrollbar->hoveredPart() != part)
return ((scrollbar->hoveredPart() == NoPart) || (windowsVersion() < WindowsVista)) ? ABS_DOWNNORMAL : ABS_DOWNHOVER;
if (scrollbar->pressedPart() == NoPart)
return ABS_DOWNHOT;
return (scrollbar->pressedPart() == part) ? ABS_DOWNPRESSED : ABS_DOWNNORMAL;
}
int ScrollbarThemeChromiumWin::getClassicThemeState(ScrollbarThemeClient* scrollbar, ScrollbarPart part) const
{
if (scrollbar->pressedPart() == ThumbPart)
return 0;
if (!scrollbar->enabled())
return DFCS_INACTIVE;
if (scrollbar->hoveredPart() != part || part == BackTrackPart || part == ForwardTrackPart)
return 0;
if (scrollbar->pressedPart() == NoPart)
return DFCS_HOT;
return (scrollbar->pressedPart() == part) ? (DFCS_PUSHED | DFCS_FLAT) : 0;
}
bool ScrollbarThemeChromiumWin::shouldCenterOnThumb(ScrollbarThemeClient*, const PlatformMouseEvent& evt)
{
return evt.shiftKey() && evt.button() == LeftButton;
}
IntSize ScrollbarThemeChromiumWin::buttonSize(ScrollbarThemeClient* scrollbar)
{
int thickness = scrollbarThickness(scrollbar->controlSize());
const int kLayoutTestModeGirth = 17;
int girth = PlatformSupport::layoutTestMode() ? kLayoutTestModeGirth : thickness;
if (scrollbar->orientation() == HorizontalScrollbar) {
int width = scrollbar->width() < 2 * girth ? scrollbar->width() / 2 : girth;
return IntSize(width, thickness);
}
int height = scrollbar->height() < 2 * girth ? scrollbar->height() / 2 : girth;
return IntSize(thickness, height);
}
}