📄 renderthemewin.cpp
字号:
break; case CSSValueWebkitSmallControl: case CSSValueWebkitMiniControl: // Just map to small. case CSSValueWebkitControl: // Just map to small. if (!controlFont.isAbsoluteSize()) { HGDIOBJ hGDI = ::GetStockObject(DEFAULT_GUI_FONT); if (hGDI) { LOGFONT logFont; if (::GetObject(hGDI, sizeof(logFont), &logFont) > 0) fillFontDescription(controlFont, logFont, defaultControlFontPixelSize); } } fontDescription = controlFont; break; default: { // Everything else uses the stock GUI font. if (!systemFont.isAbsoluteSize()) { HGDIOBJ hGDI = ::GetStockObject(DEFAULT_GUI_FONT); if (hGDI) { LOGFONT logFont; if (::GetObject(hGDI, sizeof(logFont), &logFont) > 0) fillFontDescription(systemFont, logFont); } } fontDescription = systemFont; } }}bool RenderThemeWin::supportsFocus(ControlPart appearance) const{ switch (appearance) { case PushButtonPart: case ButtonPart: case DefaultButtonPart: return true; default: return false; }}bool RenderThemeWin::supportsFocusRing(const RenderStyle* style) const{ return supportsFocus(style->appearance());}unsigned RenderThemeWin::determineClassicState(RenderObject* o){ unsigned state = 0; switch (o->style()->appearance()) { case PushButtonPart: case ButtonPart: case DefaultButtonPart: state = DFCS_BUTTONPUSH; if (!isEnabled(o)) state |= DFCS_INACTIVE; else if (isPressed(o)) state |= DFCS_PUSHED; break; case RadioPart: case CheckboxPart: state = (o->style()->appearance() == RadioPart) ? DFCS_BUTTONRADIO : DFCS_BUTTONCHECK; if (isChecked(o)) state |= DFCS_CHECKED; if (!isEnabled(o)) state |= DFCS_INACTIVE; else if (isPressed(o)) state |= DFCS_PUSHED; break; case MenulistPart: state = DFCS_SCROLLCOMBOBOX; if (!isEnabled(o)) state |= DFCS_INACTIVE; else if (isPressed(o)) state |= DFCS_PUSHED; default: break; } return state;}unsigned RenderThemeWin::determineState(RenderObject* o){ unsigned result = TS_NORMAL; ControlPart appearance = o->style()->appearance(); if (!isEnabled(o)) result = TS_DISABLED; else if (isReadOnlyControl(o) && (TextFieldPart == appearance || TextAreaPart == appearance || SearchFieldPart == appearance)) result = TFS_READONLY; // Readonly is supported on textfields. else if (isPressed(o)) // Active overrides hover and focused. result = TS_ACTIVE; else if (supportsFocus(appearance) && isFocused(o)) result = TS_FOCUSED; else if (isHovered(o)) result = TS_HOVER; if (isChecked(o)) result += 4; // 4 unchecked states, 4 checked states. return result;}unsigned RenderThemeWin::determineSliderThumbState(RenderObject* o){ unsigned result = TUS_NORMAL; if (!isEnabled(o->parent())) result = TUS_DISABLED; else if (supportsFocus(o->style()->appearance()) && isFocused(o->parent())) result = TUS_FOCUSED; else if (static_cast<RenderSlider*>(o->parent())->inDragMode()) result = TUS_PRESSED; else if (isHovered(o)) result = TUS_HOT; return result;}unsigned RenderThemeWin::determineButtonState(RenderObject* o){ unsigned result = PBS_NORMAL; if (!isEnabled(o)) result = PBS_DISABLED; else if (isPressed(o)) result = PBS_PRESSED; else if (supportsFocus(o->style()->appearance()) && isFocused(o)) result = PBS_DEFAULTED; else if (isHovered(o)) result = PBS_HOT; else if (isDefault(o)) result = PBS_DEFAULTED; return result;}ThemeData RenderThemeWin::getClassicThemeData(RenderObject* o){ ThemeData result; switch (o->style()->appearance()) { case PushButtonPart: case ButtonPart: case DefaultButtonPart: case CheckboxPart: case RadioPart: result.m_part = DFC_BUTTON; result.m_state = determineClassicState(o); break; case MenulistPart: result.m_part = DFC_SCROLL; result.m_state = determineClassicState(o); break; case SearchFieldPart: case TextFieldPart: case TextAreaPart: result.m_part = TFP_TEXTFIELD; result.m_state = determineState(o); break; case SliderHorizontalPart: result.m_part = TKP_TRACK; result.m_state = TS_NORMAL; break; case SliderVerticalPart: result.m_part = TKP_TRACKVERT; result.m_state = TS_NORMAL; break; case SliderThumbHorizontalPart: result.m_part = TKP_THUMBBOTTOM; result.m_state = determineSliderThumbState(o); break; case SliderThumbVerticalPart: result.m_part = TKP_THUMBRIGHT; result.m_state = determineSliderThumbState(o); break; default: break; } return result;}ThemeData RenderThemeWin::getThemeData(RenderObject* o){ if (!haveTheme) return getClassicThemeData(o); ThemeData result; switch (o->style()->appearance()) { case PushButtonPart: case ButtonPart: case DefaultButtonPart: result.m_part = BP_BUTTON; result.m_state = determineButtonState(o); break; case CheckboxPart: result.m_part = BP_CHECKBOX; result.m_state = determineState(o); break; case MenulistPart: case MenulistButtonPart: result.m_part = CP_DROPDOWNBUTTON; result.m_state = determineState(o); break; case RadioPart: result.m_part = BP_RADIO; result.m_state = determineState(o); break; case SearchFieldPart: case TextFieldPart: case TextAreaPart: result.m_part = TFP_TEXTFIELD; result.m_state = determineState(o); break; case SliderHorizontalPart: result.m_part = TKP_TRACK; result.m_state = TS_NORMAL; break; case SliderVerticalPart: result.m_part = TKP_TRACKVERT; result.m_state = TS_NORMAL; break; case SliderThumbHorizontalPart: result.m_part = TKP_THUMBBOTTOM; result.m_state = determineSliderThumbState(o); break; case SliderThumbVerticalPart: result.m_part = TKP_THUMBRIGHT; result.m_state = determineSliderThumbState(o); break; } return result;}static void drawControl(GraphicsContext* context, RenderObject* o, HANDLE theme, const ThemeData& themeData, const IntRect& r){ bool alphaBlend = false; if (theme) alphaBlend = IsThemeBackgroundPartiallyTransparent(theme, themeData.m_part, themeData.m_state); HDC hdc = context->getWindowsContext(r, alphaBlend); RECT widgetRect = r; if (theme) DrawThemeBackground(theme, hdc, themeData.m_part, themeData.m_state, &widgetRect, NULL); else { if (themeData.m_part == TFP_TEXTFIELD) { ::DrawEdge(hdc, &widgetRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); if (themeData.m_state == TS_DISABLED || themeData.m_state == TFS_READONLY) ::FillRect(hdc, &widgetRect, (HBRUSH)(COLOR_BTNFACE+1)); else ::FillRect(hdc, &widgetRect, (HBRUSH)(COLOR_WINDOW+1)); } else if (themeData.m_part == TKP_TRACK || themeData.m_part == TKP_TRACKVERT) { ::DrawEdge(hdc, &widgetRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); ::FillRect(hdc, &widgetRect, (HBRUSH)GetStockObject(GRAY_BRUSH)); } else if ((o->style()->appearance() == SliderThumbHorizontalPart || o->style()->appearance() == SliderThumbVerticalPart) && (themeData.m_part == TKP_THUMBBOTTOM || themeData.m_part == TKP_THUMBTOP || themeData.m_part == TKP_THUMBLEFT || themeData.m_part == TKP_THUMBRIGHT)) { ::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_RECT | BF_SOFT | BF_MIDDLE | BF_ADJUST); if (themeData.m_state == TUS_DISABLED) { static WORD patternBits[8] = {0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55}; HBITMAP patternBmp = ::CreateBitmap(8, 8, 1, 1, patternBits); if (patternBmp) { HBRUSH brush = (HBRUSH) ::CreatePatternBrush(patternBmp); COLORREF oldForeColor = ::SetTextColor(hdc, ::GetSysColor(COLOR_3DFACE)); COLORREF oldBackColor = ::SetBkColor(hdc, ::GetSysColor(COLOR_3DHILIGHT)); POINT p; ::GetViewportOrgEx(hdc, &p); ::SetBrushOrgEx(hdc, p.x + widgetRect.left, p.y + widgetRect.top, NULL); HBRUSH oldBrush = (HBRUSH) ::SelectObject(hdc, brush); ::FillRect(hdc, &widgetRect, brush); ::SetTextColor(hdc, oldForeColor); ::SetBkColor(hdc, oldBackColor); ::SelectObject(hdc, oldBrush); ::DeleteObject(brush); } else ::FillRect(hdc, &widgetRect, (HBRUSH)COLOR_3DHILIGHT); ::DeleteObject(patternBmp); } } else { // Push buttons, buttons, checkboxes and radios, and the dropdown arrow in menulists. if (o->style()->appearance() == DefaultButtonPart) { HBRUSH brush = ::GetSysColorBrush(COLOR_3DDKSHADOW); ::FrameRect(hdc, &widgetRect, brush); ::InflateRect(&widgetRect, -1, -1); ::DrawEdge(hdc, &widgetRect, BDR_RAISEDOUTER, BF_RECT | BF_MIDDLE); } ::DrawFrameControl(hdc, &widgetRect, themeData.m_part, themeData.m_state); } } context->releaseWindowsContext(hdc, r, alphaBlend);}bool RenderThemeWin::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r){ drawControl(i.context, o, buttonTheme(), getThemeData(o), r); return false;}void RenderThemeWin::setCheckboxSize(RenderStyle* style) const{ // If the width and height are both specified, then we have nothing to do. if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) return; // FIXME: A hard-coded size of 13 is used. This is wrong but necessary for now. It matches Firefox. // At different DPI settings on Windows, querying the theme gives you a larger size that accounts for // the higher DPI. Until our entire engine honors a DPI setting other than 96, we can't rely on the theme's // metrics. if (style->width().isIntrinsicOrAuto()) style->setWidth(Length(13, Fixed)); if (style->height().isAuto())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -