diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-18 16:15:03 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-18 16:15:03 +0000 |
commit | e1296faf59c3d59b9556d626cb02a8ca45e6cd31 (patch) | |
tree | 2c73c7fd9440701f934d14e3b68b3478bba5e289 | |
parent | d14aab8fa55cf25a061ca220e79367c9d0402fe6 (diff) | |
download | chromium_src-e1296faf59c3d59b9556d626cb02a8ca45e6cd31.zip chromium_src-e1296faf59c3d59b9556d626cb02a8ca45e6cd31.tar.gz chromium_src-e1296faf59c3d59b9556d626cb02a8ca45e6cd31.tar.bz2 |
Adds support for radio menu items to bookmark menus.
BUG=45734
TEST=none
Review URL: http://codereview.chromium.org/2846014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50246 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | views/controls/menu/menu_config.h | 6 | ||||
-rw-r--r-- | views/controls/menu/menu_config_win.cc | 11 | ||||
-rw-r--r-- | views/controls/menu/menu_delegate.h | 4 | ||||
-rw-r--r-- | views/controls/menu/menu_item_view.h | 14 | ||||
-rw-r--r-- | views/controls/menu/menu_item_view_gtk.cc | 76 | ||||
-rw-r--r-- | views/controls/menu/menu_item_view_win.cc | 56 |
6 files changed, 141 insertions, 26 deletions
diff --git a/views/controls/menu/menu_config.h b/views/controls/menu/menu_config.h index 9a9a60e..eb425f6 100644 --- a/views/controls/menu/menu_config.h +++ b/views/controls/menu/menu_config.h @@ -26,6 +26,8 @@ struct MenuConfig { gutter_to_label(5), check_width(16), check_height(16), + radio_width(16), + radio_height(16), arrow_height(9), arrow_width(9), gutter_width(0), @@ -78,6 +80,10 @@ struct MenuConfig { int check_width; int check_height; + // Size of the radio bullet. + int radio_width; + int radio_height; + // Size of the submenu arrow. int arrow_height; int arrow_width; diff --git a/views/controls/menu/menu_config_win.cc b/views/controls/menu/menu_config_win.cc index aee41e9..6f1e8fd4a 100644 --- a/views/controls/menu/menu_config_win.cc +++ b/views/controls/menu/menu_config_win.cc @@ -45,6 +45,17 @@ MenuConfig* MenuConfig::Create() { config->check_height = GetSystemMetrics(SM_CYMENUCHECK); } + SIZE radio_size; + if (NativeTheme::instance()->GetThemePartSize( + NativeTheme::MENU, dc, MENU_POPUPCHECK, MC_BULLETNORMAL, &bounds, + TS_TRUE, &radio_size) == S_OK) { + config->radio_width = radio_size.cx; + config->radio_height = radio_size.cy; + } else { + config->radio_width = GetSystemMetrics(SM_CXMENUCHECK); + config->radio_height = GetSystemMetrics(SM_CYMENUCHECK); + } + SIZE arrow_size; if (NativeTheme::instance()->GetThemePartSize( NativeTheme::MENU, dc, MENU_POPUPSUBMENU, MSM_NORMAL, &bounds, diff --git a/views/controls/menu/menu_delegate.h b/views/controls/menu/menu_delegate.h index a06b4a0..bfe2dec 100644 --- a/views/controls/menu/menu_delegate.h +++ b/views/controls/menu/menu_delegate.h @@ -43,8 +43,8 @@ class MenuDelegate : Controller { DROP_ON }; - // Whether or not an item should be shown as checked. - // TODO(sky): need checked support. + // Whether or not an item should be shown as checked. This is invoked for + // radio buttons and check buttons. virtual bool IsItemChecked(int id) const { return false; } diff --git a/views/controls/menu/menu_item_view.h b/views/controls/menu/menu_item_view.h index 69d850e..1083b6a 100644 --- a/views/controls/menu/menu_item_view.h +++ b/views/controls/menu/menu_item_view.h @@ -5,6 +5,10 @@ #ifndef VIEWS_CONTROLS_MENU_MENU_ITEM_VIEW_H_ #define VIEWS_CONTROLS_MENU_MENU_ITEM_VIEW_H_ +#if defined(OS_WIN) +#include <windows.h> +#endif + #include "third_party/skia/include/core/SkBitmap.h" #include "views/view.h" @@ -293,6 +297,16 @@ class MenuItemView : public View { // are not rendered. void Paint(gfx::Canvas* canvas, bool for_drag); +#if defined(OS_WIN) + // Paints the check/radio button indicator. |part_id| is the id passed to the + // native theme drawing routines. + void PaintCheck(HDC dc, + int part_id, + bool render_selection, + int icon_width, + int icon_height); +#endif + // Paints the accelerator. void PaintAccelerator(gfx::Canvas* canvas); diff --git a/views/controls/menu/menu_item_view_gtk.cc b/views/controls/menu/menu_item_view_gtk.cc index fa0aeca..f3e7556 100644 --- a/views/controls/menu/menu_item_view_gtk.cc +++ b/views/controls/menu/menu_item_view_gtk.cc @@ -8,6 +8,7 @@ #include "gfx/canvas.h" #include "gfx/favicon_size.h" #include "grit/app_resources.h" +#include "third_party/skia/include/effects/SkGradientShader.h" #include "views/controls/button/text_button.h" #include "views/controls/menu/menu_config.h" #include "views/controls/menu/submenu_view.h" @@ -21,6 +22,23 @@ static const SkColor kSelectedBackgroundColor = SkColorSetRGB(0xDC, 0xE4, 0xFA); static const SkColor kSelectedBackgroundColor = SkColorSetRGB(246, 249, 253); #endif +// Size of the radio button inciator. +static const int kSelectedIndicatorSize = 5; +static const int kIndicatorSize = 10; + +// Used for the radio indicator. See theme_draw for details. +static const double kGradientStop = .5; +static const SkColor kGradient0 = SkColorSetRGB(255, 255, 255); +static const SkColor kGradient1 = SkColorSetRGB(255, 255, 255); +static const SkColor kGradient2 = SkColorSetRGB(0xD8, 0xD8, 0xD8); +static const SkColor kBaseStroke = SkColorSetRGB(0x8F, 0x8F, 0x8F); +static const SkColor kRadioButtonIndicatorGradient0 = + SkColorSetRGB(0, 0, 0); +static const SkColor kRadioButtonIndicatorGradient1 = + SkColorSetRGB(0x83, 0x83, 0x83); + +static const SkColor kIndicatorStroke = SkColorSetRGB(0, 0, 0); + gfx::Size MenuItemView::GetPreferredSize() { const gfx::Font& font = MenuConfig::instance().font; // TODO(sky): this is a workaround until I figure out why font.height() @@ -62,6 +80,64 @@ void MenuItemView::Paint(gfx::Canvas* canvas, bool for_drag) { gfx::Rect check_bounds(icon_x, icon_y, check->width(), icon_height); AdjustBoundsForRTLUI(&check_bounds); canvas->DrawBitmapInt(*check, check_bounds.x(), check_bounds.y()); + } else if (type_ == RADIO) { + // This code comes from theme_draw.cc. See it for details. + canvas->TranslateInt( + icon_x, + top_margin + (height() - top_margin - bottom_margin - + kIndicatorSize) / 2); + + SkPoint gradient_points[3]; + gradient_points[0].set(SkIntToScalar(0), SkIntToScalar(0)); + gradient_points[1].set( + SkIntToScalar(0), + SkIntToScalar(static_cast<int>(kIndicatorSize * kGradientStop))); + gradient_points[2].set(SkIntToScalar(0), SkIntToScalar(kIndicatorSize)); + SkColor gradient_colors[3] = { kGradient0, kGradient1, kGradient2 }; + SkShader* shader = SkGradientShader::CreateLinear( + gradient_points, gradient_colors, NULL, arraysize(gradient_points), + SkShader::kClamp_TileMode, NULL); + SkPaint paint; + paint.setStyle(SkPaint::kFill_Style); + paint.setAntiAlias(true); + paint.setShader(shader); + shader->unref(); + int radius = kIndicatorSize / 2; + canvas->drawCircle(radius, radius, radius, paint); + + paint.setStrokeWidth(SkIntToScalar(0)); + paint.setShader(NULL); + paint.setStyle(SkPaint::kStroke_Style); + paint.setColor(kBaseStroke); + canvas->drawCircle(radius, radius, radius, paint); + + if (GetDelegate()->IsItemChecked(GetCommand())) { + SkPoint selected_gradient_points[2]; + selected_gradient_points[0].set(SkIntToScalar(0), SkIntToScalar(0)); + selected_gradient_points[1].set( + SkIntToScalar(0), + SkIntToScalar(kSelectedIndicatorSize)); + SkColor selected_gradient_colors[2] = { kRadioButtonIndicatorGradient0, + kRadioButtonIndicatorGradient1 }; + shader = SkGradientShader::CreateLinear( + selected_gradient_points, selected_gradient_colors, NULL, + arraysize(selected_gradient_points), SkShader::kClamp_TileMode, NULL); + paint.setShader(shader); + shader->unref(); + paint.setStyle(SkPaint::kFill_Style); + canvas->drawCircle(radius, radius, kSelectedIndicatorSize / 2, paint); + + paint.setStrokeWidth(SkIntToScalar(0)); + paint.setShader(NULL); + paint.setStyle(SkPaint::kStroke_Style); + paint.setColor(kIndicatorStroke); + canvas->drawCircle(radius, radius, kSelectedIndicatorSize / 2, paint); + } + + canvas->TranslateInt( + -icon_x, + -(top_margin + (height() - top_margin - bottom_margin - + kIndicatorSize) / 2)); } // Render the foreground. diff --git a/views/controls/menu/menu_item_view_win.cc b/views/controls/menu/menu_item_view_win.cc index bfdac37..2ac0921 100644 --- a/views/controls/menu/menu_item_view_win.cc +++ b/views/controls/menu/menu_item_view_win.cc @@ -4,7 +4,6 @@ #include "views/controls/menu/menu_item_view.h" -#include <windows.h> #include <uxtheme.h> #include <Vssym32.h> @@ -58,33 +57,16 @@ void MenuItemView::Paint(gfx::Canvas* canvas, bool for_drag) { &item_rect); } - int icon_x = config.item_left_margin; int top_margin = GetTopMargin(); int bottom_margin = GetBottomMargin(); - int icon_y = top_margin + (height() - config.item_top_margin - - bottom_margin - config.check_height) / 2; - int icon_height = config.check_height; - int icon_width = config.check_width; if (type_ == CHECKBOX && GetDelegate()->IsItemChecked(GetCommand())) { - // Draw the check background. - gfx::Rect check_bg_bounds(0, 0, icon_x + icon_width, height()); - const int bg_state = IsEnabled() ? MCB_NORMAL : MCB_DISABLED; - AdjustBoundsForRTLUI(&check_bg_bounds); - RECT check_bg_rect = check_bg_bounds.ToRECT(); - NativeTheme::instance()->PaintMenuCheckBackground( - NativeTheme::MENU, dc, MENU_POPUPCHECKBACKGROUND, bg_state, - &check_bg_rect); - - // And the check. - gfx::Rect check_bounds(icon_x, icon_y, icon_width, icon_height); - const int check_state = IsEnabled() ? MC_CHECKMARKNORMAL : - MC_CHECKMARKDISABLED; - AdjustBoundsForRTLUI(&check_bounds); - RECT check_rect = check_bounds.ToRECT(); - NativeTheme::instance()->PaintMenuCheck( - NativeTheme::MENU, dc, MENU_POPUPCHECK, check_state, &check_rect, - render_selection); + PaintCheck(dc, + IsEnabled() ? MC_CHECKMARKNORMAL : MC_CHECKMARKDISABLED, + render_selection, config.check_height, config.check_width); + } else if (type_ == RADIO && GetDelegate()->IsItemChecked(GetCommand())) { + PaintCheck(dc, IsEnabled() ? MC_BULLETNORMAL : MC_BULLETDISABLED, + render_selection, config.radio_height, config.radio_width); } // Render the foreground. @@ -151,5 +133,31 @@ void MenuItemView::Paint(gfx::Canvas* canvas, bool for_drag) { } canvas->endPlatformPaint(); } +void MenuItemView::PaintCheck(HDC dc, + int state_id, + bool render_selection, + int icon_width, + int icon_height) { + int top_margin = GetTopMargin(); + int icon_x = MenuConfig::instance().item_left_margin; + int icon_y = top_margin + + (height() - top_margin - GetBottomMargin() - icon_height) / 2; + // Draw the background. + gfx::Rect bg_bounds(0, 0, icon_x + icon_width, height()); + int bg_state = IsEnabled() ? MCB_NORMAL : MCB_DISABLED; + AdjustBoundsForRTLUI(&bg_bounds); + RECT bg_rect = bg_bounds.ToRECT(); + NativeTheme::instance()->PaintMenuCheckBackground( + NativeTheme::MENU, dc, MENU_POPUPCHECKBACKGROUND, bg_state, + &bg_rect); + + // And the check. + gfx::Rect icon_bounds(icon_x / 2, icon_y, icon_width, icon_height); + AdjustBoundsForRTLUI(&icon_bounds); + RECT icon_rect = icon_bounds.ToRECT(); + NativeTheme::instance()->PaintMenuCheck( + NativeTheme::MENU, dc, MENU_POPUPCHECK, state_id, &icon_rect, + render_selection); +} } // namespace views |