summaryrefslogtreecommitdiffstats
path: root/views/controls
diff options
context:
space:
mode:
Diffstat (limited to 'views/controls')
-rw-r--r--views/controls/menu/menu_config.h6
-rw-r--r--views/controls/menu/menu_config_win.cc11
-rw-r--r--views/controls/menu/menu_delegate.h4
-rw-r--r--views/controls/menu/menu_item_view.h14
-rw-r--r--views/controls/menu/menu_item_view_gtk.cc76
-rw-r--r--views/controls/menu/menu_item_view_win.cc56
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