views: Support styling of menus (issue #2102)

This commit is contained in:
Marshall Greenblatt 2017-02-25 00:03:31 -05:00
parent b08f0ed713
commit 8fa8af357b
23 changed files with 1124 additions and 65 deletions

View File

@ -301,6 +301,8 @@
'tests/cefclient/browser/temp_window_win.h',
'tests/cefclient/browser/views_menu_bar.cc',
'tests/cefclient/browser/views_menu_bar.h',
'tests/cefclient/browser/views_style.cc',
'tests/cefclient/browser/views_style.h',
'tests/cefclient/browser/views_window.cc',
'tests/cefclient/browser/views_window.h',
'tests/cefclient/browser/window_test_runner_views.cc',
@ -354,6 +356,8 @@
'tests/cefclient/browser/temp_window_x11.h',
'tests/cefclient/browser/views_menu_bar.cc',
'tests/cefclient/browser/views_menu_bar.h',
'tests/cefclient/browser/views_style.cc',
'tests/cefclient/browser/views_style.h',
'tests/cefclient/browser/views_window.cc',
'tests/cefclient/browser/views_window.h',
'tests/cefclient/browser/window_test_runner_gtk.cc',

View File

@ -384,6 +384,73 @@ typedef struct _cef_menu_model_t {
int (CEF_CALLBACK *get_accelerator_at)(struct _cef_menu_model_t* self,
int index, int* key_code, int* shift_pressed, int* ctrl_pressed,
int* alt_pressed);
///
// Set the explicit color for |command_id| and |color_type| to |color|.
// Specify a |color| value of 0 to remove the explicit color. If no explicit
// color or default color is set for |color_type| then the system color will
// be used. Returns true (1) on success.
///
int (CEF_CALLBACK *set_color)(struct _cef_menu_model_t* self, int command_id,
cef_menu_color_type_t color_type, cef_color_t color);
///
// Set the explicit color for |command_id| and |index| to |color|. Specify a
// |color| value of 0 to remove the explicit color. Specify an |index| value
// of -1 to set the default color for items that do not have an explicit color
// set. If no explicit color or default color is set for |color_type| then the
// system color will be used. Returns true (1) on success.
///
int (CEF_CALLBACK *set_color_at)(struct _cef_menu_model_t* self, int index,
cef_menu_color_type_t color_type, cef_color_t color);
///
// Returns in |color| the color that was explicitly set for |command_id| and
// |color_type|. If a color was not set then 0 will be returned in |color|.
// Returns true (1) on success.
///
int (CEF_CALLBACK *get_color)(struct _cef_menu_model_t* self, int command_id,
cef_menu_color_type_t color_type, cef_color_t* color);
///
// Returns in |color| the color that was explicitly set for |command_id| and
// |color_type|. Specify an |index| value of -1 to return the default color in
// |color|. If a color was not set then 0 will be returned in |color|. Returns
// true (1) on success.
///
int (CEF_CALLBACK *get_color_at)(struct _cef_menu_model_t* self, int index,
cef_menu_color_type_t color_type, cef_color_t* color);
///
// Sets the font list for the specified |command_id|. If |font_list| is NULL
// the system font will be used. Returns true (1) on success. The format is
// "<FONT_FAMILY_LIST>,[STYLES] <SIZE>", where: - FONT_FAMILY_LIST is a comma-
// separated list of font family names, - STYLES is an optional space-
// separated list of style names (case-sensitive
// "Bold" and "Italic" are supported), and
// - SIZE is an integer font size in pixels with the suffix "px".
//
// Here are examples of valid font description strings: - "Arial, Helvetica,
// Bold Italic 14px" - "Arial, 14px"
///
int (CEF_CALLBACK *set_font_list)(struct _cef_menu_model_t* self,
int command_id, const cef_string_t* font_list);
///
// Sets the font list for the specified |index|. Specify an |index| value of
// -1 to set the default font. If |font_list| is NULL the system font will be
// used. Returns true (1) on success. The format is
// "<FONT_FAMILY_LIST>,[STYLES] <SIZE>", where: - FONT_FAMILY_LIST is a comma-
// separated list of font family names, - STYLES is an optional space-
// separated list of style names (case-sensitive
// "Bold" and "Italic" are supported), and
// - SIZE is an integer font size in pixels with the suffix "px".
//
// Here are examples of valid font description strings: - "Arial, Helvetica,
// Bold Italic 14px" - "Arial, 14px"
///
int (CEF_CALLBACK *set_font_list_at)(struct _cef_menu_model_t* self,
int index, const cef_string_t* font_list);
} cef_menu_model_t;

View File

@ -411,6 +411,85 @@ class CefMenuModel : public virtual CefBaseRefCounted {
bool& shift_pressed,
bool& ctrl_pressed,
bool& alt_pressed) =0;
///
// Set the explicit color for |command_id| and |color_type| to |color|.
// Specify a |color| value of 0 to remove the explicit color. If no explicit
// color or default color is set for |color_type| then the system color will
// be used. Returns true on success.
///
/*--cef()--*/
virtual bool SetColor(int command_id,
cef_menu_color_type_t color_type,
cef_color_t color) =0;
///
// Set the explicit color for |command_id| and |index| to |color|. Specify a
// |color| value of 0 to remove the explicit color. Specify an |index| value
// of -1 to set the default color for items that do not have an explicit
// color set. If no explicit color or default color is set for |color_type|
// then the system color will be used. Returns true on success.
///
/*--cef()--*/
virtual bool SetColorAt(int index,
cef_menu_color_type_t color_type,
cef_color_t color) =0;
///
// Returns in |color| the color that was explicitly set for |command_id| and
// |color_type|. If a color was not set then 0 will be returned in |color|.
// Returns true on success.
///
/*--cef()--*/
virtual bool GetColor(int command_id,
cef_menu_color_type_t color_type,
cef_color_t& color) =0;
///
// Returns in |color| the color that was explicitly set for |command_id| and
// |color_type|. Specify an |index| value of -1 to return the default color
// in |color|. If a color was not set then 0 will be returned in |color|.
// Returns true on success.
///
/*--cef()--*/
virtual bool GetColorAt(int index,
cef_menu_color_type_t color_type,
cef_color_t& color) =0;
///
// Sets the font list for the specified |command_id|. If |font_list| is empty
// the system font will be used. Returns true on success. The format is
// "<FONT_FAMILY_LIST>,[STYLES] <SIZE>", where:
// - FONT_FAMILY_LIST is a comma-separated list of font family names,
// - STYLES is an optional space-separated list of style names (case-sensitive
// "Bold" and "Italic" are supported), and
// - SIZE is an integer font size in pixels with the suffix "px".
//
// Here are examples of valid font description strings:
// - "Arial, Helvetica, Bold Italic 14px"
// - "Arial, 14px"
///
/*--cef(optional_param=font_list)--*/
virtual bool SetFontList(int command_id,
const CefString& font_list) =0;
///
// Sets the font list for the specified |index|. Specify an |index| value of
// -1 to set the default font. If |font_list| is empty the system font will
// be used. Returns true on success. The format is
// "<FONT_FAMILY_LIST>,[STYLES] <SIZE>", where:
// - FONT_FAMILY_LIST is a comma-separated list of font family names,
// - STYLES is an optional space-separated list of style names (case-sensitive
// "Bold" and "Italic" are supported), and
// - SIZE is an integer font size in pixels with the suffix "px".
//
// Here are examples of valid font description strings:
// - "Arial, Helvetica, Bold Italic 14px"
// - "Arial, 14px"
///
/*--cef(optional_param=font_list)--*/
virtual bool SetFontListAt(int index,
const CefString& font_list) =0;
};
#endif // CEF_INCLUDE_CEF_MENU_MODEL_H_

View File

@ -2732,6 +2732,19 @@ typedef enum {
CEF_MENU_ANCHOR_BOTTOMCENTER,
} cef_menu_anchor_position_t;
///
// Supported color types for menu items.
///
typedef enum {
CEF_MENU_COLOR_TEXT,
CEF_MENU_COLOR_TEXT_HOVERED,
CEF_MENU_COLOR_TEXT_ACCELERATOR,
CEF_MENU_COLOR_TEXT_ACCELERATOR_HOVERED,
CEF_MENU_COLOR_BACKGROUND,
CEF_MENU_COLOR_BACKGROUND_HOVERED,
CEF_MENU_COLOR_COUNT,
} cef_menu_color_type_t;
// Supported SSL version values. See net/ssl/ssl_connection_status_flags.h
// for more information.
typedef enum {

View File

@ -19,6 +19,10 @@
namespace {
const int kSeparatorId = -1;
const int kInvalidGroupId = -1;
const int kInvalidCommandId = -1;
const int kDefaultIndex = -1;
const int kInvalidIndex = -2;
// A simple MenuModel implementation that delegates to CefMenuModelImpl.
class CefSimpleMenuModel : public ui::MenuModel {
@ -73,6 +77,10 @@ class CefSimpleMenuModel : public ui::MenuModel {
return false;
}
const gfx::FontList* GetLabelFontListAt(int index) const override {
return impl_->GetLabelFontListAt(index);
}
bool GetAcceleratorAt(int index,
ui::Accelerator* accelerator) const override {
int key_code = 0;
@ -151,6 +159,24 @@ class CefSimpleMenuModel : public ui::MenuModel {
impl_->UnhandledCloseSubmenu(is_rtl);
}
bool GetTextColor(int index,
bool is_hovered,
SkColor* override_color) const override {
return impl_->GetTextColor(index, false, is_hovered, override_color);
}
bool GetMinorTextColor(int index,
bool is_hovered,
SkColor* override_color) const override {
return impl_->GetTextColor(index, true, is_hovered, override_color);
}
bool GetBackgroundColor(int index,
bool is_hovered,
SkColor* override_color) const override {
return impl_->GetBackgroundColor(index, is_hovered, override_color);
}
void MenuWillShow() override {
impl_->MenuWillShow();
}
@ -175,6 +201,22 @@ class CefSimpleMenuModel : public ui::MenuModel {
DISALLOW_COPY_AND_ASSIGN(CefSimpleMenuModel);
};
cef_menu_color_type_t GetMenuColorType(bool is_text,
bool is_accelerator,
bool is_hovered) {
if (is_text) {
if (is_accelerator) {
return is_hovered ? CEF_MENU_COLOR_TEXT_ACCELERATOR_HOVERED :
CEF_MENU_COLOR_TEXT_ACCELERATOR;
}
return is_hovered ? CEF_MENU_COLOR_TEXT_HOVERED : CEF_MENU_COLOR_TEXT;
}
DCHECK(!is_accelerator);
return is_hovered ? CEF_MENU_COLOR_BACKGROUND_HOVERED :
CEF_MENU_COLOR_BACKGROUND;
}
} // namespace
// static
@ -198,15 +240,7 @@ struct CefMenuModelImpl::Item {
: type_(type),
command_id_(command_id),
label_(label),
group_id_(group_id),
enabled_(true),
visible_(true),
checked_(false),
has_accelerator_(false),
key_code_(0),
shift_pressed_(false),
ctrl_pressed_(false),
alt_pressed_(false) {
group_id_(group_id) {
}
// Basic information.
@ -217,16 +251,20 @@ struct CefMenuModelImpl::Item {
CefRefPtr<CefMenuModelImpl> submenu_;
// State information.
bool enabled_;
bool visible_;
bool checked_;
bool enabled_ = true;
bool visible_ = true;
bool checked_ = false;
// Accelerator information.
bool has_accelerator_;
int key_code_;
bool shift_pressed_;
bool ctrl_pressed_;
bool alt_pressed_;
bool has_accelerator_ = false;
int key_code_ = 0;
bool shift_pressed_ = false;
bool ctrl_pressed_ = false;
bool alt_pressed_ = false;
cef_color_t colors_[CEF_MENU_COLOR_COUNT] = {0};
gfx::FontList font_list_;
bool has_font_list_ = false;
};
@ -270,7 +308,8 @@ bool CefMenuModelImpl::AddSeparator() {
if (!VerifyContext())
return false;
AppendItem(Item(MENUITEMTYPE_SEPARATOR, kSeparatorId, CefString(), -1));
AppendItem(Item(MENUITEMTYPE_SEPARATOR, kSeparatorId, CefString(),
kInvalidGroupId));
return true;
}
@ -278,7 +317,8 @@ bool CefMenuModelImpl::AddItem(int command_id, const CefString& label) {
if (!VerifyContext())
return false;
AppendItem(Item(MENUITEMTYPE_COMMAND, command_id, label, -1));
AppendItem(Item(MENUITEMTYPE_COMMAND, command_id, label,
kInvalidGroupId));
return true;
}
@ -286,7 +326,7 @@ bool CefMenuModelImpl::AddCheckItem(int command_id, const CefString& label) {
if (!VerifyContext())
return false;
AppendItem(Item(MENUITEMTYPE_CHECK, command_id, label, -1));
AppendItem(Item(MENUITEMTYPE_CHECK, command_id, label, kInvalidGroupId));
return true;
}
@ -304,7 +344,7 @@ CefRefPtr<CefMenuModel> CefMenuModelImpl::AddSubMenu(int command_id,
if (!VerifyContext())
return NULL;
Item item(MENUITEMTYPE_SUBMENU, command_id, label, -1);
Item item(MENUITEMTYPE_SUBMENU, command_id, label, kInvalidGroupId);
item.submenu_ = new CefMenuModelImpl(delegate_, menu_model_delegate_, true);
AppendItem(item);
return item.submenu_.get();
@ -314,8 +354,9 @@ bool CefMenuModelImpl::InsertSeparatorAt(int index) {
if (!VerifyContext())
return false;
InsertItemAt(Item(MENUITEMTYPE_SEPARATOR, kSeparatorId, CefString(), -1),
index);
InsertItemAt(Item(MENUITEMTYPE_SEPARATOR, kSeparatorId, CefString(),
kInvalidGroupId),
index);
return true;
}
@ -324,7 +365,8 @@ bool CefMenuModelImpl::InsertItemAt(int index, int command_id,
if (!VerifyContext())
return false;
InsertItemAt(Item(MENUITEMTYPE_COMMAND, command_id, label, -1), index);
InsertItemAt(Item(MENUITEMTYPE_COMMAND, command_id, label, kInvalidGroupId),
index);
return true;
}
@ -333,7 +375,8 @@ bool CefMenuModelImpl::InsertCheckItemAt(int index, int command_id,
if (!VerifyContext())
return false;
InsertItemAt(Item(MENUITEMTYPE_CHECK, command_id, label, -1), index);
InsertItemAt(Item(MENUITEMTYPE_CHECK, command_id, label, kInvalidGroupId),
index);
return true;
}
@ -342,7 +385,7 @@ bool CefMenuModelImpl::InsertRadioItemAt(int index, int command_id,
if (!VerifyContext())
return false;
InsertItemAt(Item(MENUITEMTYPE_RADIO, command_id, label, -1), index);
InsertItemAt(Item(MENUITEMTYPE_RADIO, command_id, label, group_id), index);
return true;
}
@ -351,7 +394,7 @@ CefRefPtr<CefMenuModel> CefMenuModelImpl::InsertSubMenuAt(
if (!VerifyContext())
return NULL;
Item item(MENUITEMTYPE_SUBMENU, command_id, label, -1);
Item item(MENUITEMTYPE_SUBMENU, command_id, label, kInvalidGroupId);
item.submenu_ = new CefMenuModelImpl(delegate_, menu_model_delegate_, true);
InsertItemAt(item, index);
return item.submenu_.get();
@ -374,23 +417,23 @@ bool CefMenuModelImpl::RemoveAt(int index) {
int CefMenuModelImpl::GetIndexOf(int command_id) {
if (!VerifyContext())
return -1;
return kInvalidIndex;
for (ItemVector::iterator i = items_.begin(); i != items_.end(); ++i) {
if ((*i).command_id_ == command_id) {
return static_cast<int>(std::distance(items_.begin(), i));
}
}
return -1;
return kInvalidIndex;
}
int CefMenuModelImpl::GetCommandIdAt(int index) {
if (!VerifyContext())
return -1;
return kInvalidCommandId;
if (index >= 0 && index < static_cast<int>(items_.size()))
return items_[index].command_id_;
return -1;
return kInvalidCommandId;
}
bool CefMenuModelImpl::SetCommandIdAt(int index, int command_id) {
@ -451,11 +494,11 @@ int CefMenuModelImpl::GetGroupId(int command_id) {
int CefMenuModelImpl::GetGroupIdAt(int index) {
if (!VerifyContext())
return -1;
return kInvalidGroupId;
if (index >= 0 && index < static_cast<int>(items_.size()))
return items_[index].group_id_;
return -1;
return kInvalidGroupId;
}
bool CefMenuModelImpl::SetGroupId(int command_id, int group_id) {
@ -656,6 +699,95 @@ bool CefMenuModelImpl::GetAcceleratorAt(int index, int& key_code,
return false;
}
bool CefMenuModelImpl::SetColor(int command_id,
cef_menu_color_type_t color_type,
cef_color_t color) {
return SetColorAt(GetIndexOf(command_id), color_type, color);
}
bool CefMenuModelImpl::SetColorAt(int index,
cef_menu_color_type_t color_type,
cef_color_t color) {
if (!VerifyContext())
return false;
if (color_type < 0 || color_type >= CEF_MENU_COLOR_COUNT)
return false;
if (index == kDefaultIndex) {
default_colors_[color_type] = color;
return true;
}
if (index >= 0 && index < static_cast<int>(items_.size())) {
Item& item = items_[index];
item.colors_[color_type] = color;
return true;
}
return false;
}
bool CefMenuModelImpl::GetColor(int command_id,
cef_menu_color_type_t color_type,
cef_color_t& color) {
return GetColorAt(GetIndexOf(command_id), color_type, color);
}
bool CefMenuModelImpl::GetColorAt(int index,
cef_menu_color_type_t color_type,
cef_color_t& color) {
if (!VerifyContext())
return false;
if (color_type < 0 || color_type >= CEF_MENU_COLOR_COUNT)
return false;
if (index == kDefaultIndex) {
color = default_colors_[color_type];
return true;
}
if (index >= 0 && index < static_cast<int>(items_.size())) {
Item& item = items_[index];
color = item.colors_[color_type];
return true;
}
return false;
}
bool CefMenuModelImpl::SetFontList(int command_id, const CefString& font_list) {
return SetFontListAt(GetIndexOf(command_id), font_list);
}
bool CefMenuModelImpl::SetFontListAt(int index, const CefString& font_list) {
if (!VerifyContext())
return false;
if (index == kDefaultIndex) {
if (font_list.empty()) {
has_default_font_list_ = false;
} else {
default_font_list_ = gfx::FontList(font_list);
has_default_font_list_ = true;
}
return true;
}
if (index >= 0 && index < static_cast<int>(items_.size())) {
Item& item = items_[index];
if (font_list.empty()) {
item.has_font_list_ = false;
} else {
item.font_list_ = gfx::FontList(font_list);
item.has_font_list_ = true;
}
return true;
}
return false;
}
void CefMenuModelImpl::ActivatedAt(int index, cef_event_flags_t event_flags) {
if (!VerifyContext())
return;
@ -700,6 +832,57 @@ void CefMenuModelImpl::UnhandledCloseSubmenu(bool is_rtl) {
base::Bind(&CefMenuModelImpl::OnUnhandledCloseSubmenu, this, is_rtl));
}
bool CefMenuModelImpl::GetTextColor(int index,
bool is_accelerator,
bool is_hovered,
SkColor* override_color) const {
if (index >= 0 && index < static_cast<int>(items_.size())) {
const Item& item = items_[index];
if (!item.enabled_) {
// Use accelerator color for disabled item text.
is_accelerator = true;
}
const cef_menu_color_type_t color_type =
GetMenuColorType(true, is_accelerator, is_hovered);
if (item.colors_[color_type] != 0) {
*override_color = item.colors_[color_type];
return true;
}
}
const cef_menu_color_type_t color_type =
GetMenuColorType(true, is_accelerator, is_hovered);
if (default_colors_[color_type] != 0) {
*override_color = default_colors_[color_type];
return true;
}
return false;
}
bool CefMenuModelImpl::GetBackgroundColor(int index,
bool is_hovered,
SkColor* override_color) const {
const cef_menu_color_type_t color_type =
GetMenuColorType(false, false, is_hovered);
if (index >= 0 && index < static_cast<int>(items_.size())) {
const Item& item = items_[index];
if (item.colors_[color_type] != 0) {
*override_color = item.colors_[color_type];
return true;
}
}
if (default_colors_[color_type] != 0) {
*override_color = default_colors_[color_type];
return true;
}
return false;
}
void CefMenuModelImpl::MenuWillShow() {
if (!VerifyContext())
return;
@ -737,6 +920,18 @@ base::string16 CefMenuModelImpl::GetFormattedLabelAt(int index) {
return label;
}
const gfx::FontList* CefMenuModelImpl::GetLabelFontListAt(int index) const {
if (index >= 0 && index < static_cast<int>(items_.size())) {
const Item& item = items_[index];
if (item.has_font_list_)
return &item.font_list_;
}
if (has_default_font_list_)
return &default_font_list_;
return nullptr;
}
bool CefMenuModelImpl::VerifyRefCount() {
if (!VerifyContext())
return false;

View File

@ -14,6 +14,7 @@
#include "base/threading/platform_thread.h"
#include "ui/base/models/menu_model.h"
#include "ui/gfx/font_list.h"
namespace content {
struct MenuItem;
@ -123,15 +124,37 @@ class CefMenuModelImpl : public CefMenuModel {
bool& shift_pressed, bool& ctrl_pressed, bool& alt_pressed) override;
bool GetAcceleratorAt(int index, int& key_code, bool& shift_pressed,
bool& ctrl_pressed, bool& alt_pressed) override;
bool SetColor(int command_id,
cef_menu_color_type_t color_type,
cef_color_t color) override;
bool SetColorAt(int index,
cef_menu_color_type_t color_type,
cef_color_t color) override;
bool GetColor(int command_id,
cef_menu_color_type_t color_type,
cef_color_t& color) override;
bool GetColorAt(int index,
cef_menu_color_type_t color_type,
cef_color_t& color) override;
bool SetFontList(int command_id, const CefString& font_list) override;
bool SetFontListAt(int index, const CefString& font_list) override;
// Callbacks from the ui::MenuModel implementation.
void ActivatedAt(int index, cef_event_flags_t event_flags);
void MouseOutsideMenu(const gfx::Point& screen_point);
void UnhandledOpenSubmenu(bool is_rtl);
void UnhandledCloseSubmenu(bool is_rtl);
bool GetTextColor(int index,
bool is_accelerator,
bool is_hovered,
SkColor* override_color) const;
bool GetBackgroundColor(int index,
bool is_hovered,
SkColor* override_color) const;
void MenuWillShow();
void MenuWillClose();
base::string16 GetFormattedLabelAt(int index);
const gfx::FontList* GetLabelFontListAt(int index) const;
// Verify that only a single reference exists to all CefMenuModelImpl objects.
bool VerifyRefCount();
@ -182,6 +205,11 @@ class CefMenuModelImpl : public CefMenuModel {
ItemVector items_;
std::unique_ptr<ui::MenuModel> model_;
// Style information.
cef_color_t default_colors_[CEF_MENU_COLOR_COUNT] = {0};
gfx::FontList default_font_list_;
bool has_default_font_list_ = false;
bool auto_notify_menu_closed_ = true;
IMPLEMENT_REFCOUNTING(CefMenuModelImpl);

View File

@ -57,6 +57,13 @@ CEF_BUTTON_VIEW_T void CEF_BUTTON_VIEW_D::ButtonPressed(
views::Button* sender, const ui::Event& event) {
if (ParentClass::cef_delegate())
ParentClass::cef_delegate()->OnButtonPressed(GetCefButton());
if (ParentClass::ink_drop_mode() != views::CustomButton::InkDropMode::OFF &&
!ParentClass::IsFocusable()) {
// When ink drop is enabled for non-focusable buttons the ink drop state
// does not get reset properly on click, so we do it here explicitly.
ParentClass::AnimateInkDrop(views::InkDropState::HIDDEN,
ui::LocatedEvent::FromIfValid(&event));
}
}
#endif // CEF_LIBCEF_BROWSER_VIEWS_BUTTON_VIEW_H_

View File

@ -5,6 +5,7 @@
#include "libcef/browser/views/menu_button_view.h"
#include "ui/gfx/canvas.h"
#include "ui/views/controls/menu/menu_config.h"
CefMenuButtonView::CefMenuButtonView(
CefMenuButtonDelegate* cef_delegate)
@ -17,6 +18,9 @@ void CefMenuButtonView::Initialize() {
SetDrawStringsFlags(IsFocusable() ? gfx::Canvas::SHOW_PREFIX :
gfx::Canvas::HIDE_PREFIX);
// Use the same default font as MenuItemView.
SetFontList(views::MenuConfig::instance().font_list);
}
CefRefPtr<CefMenuButton> CefMenuButtonView::GetCefMenuButton() const {

View File

@ -994,6 +994,136 @@ int CEF_CALLBACK menu_model_get_accelerator_at(struct _cef_menu_model_t* self,
return _retval;
}
int CEF_CALLBACK menu_model_set_color(struct _cef_menu_model_t* self,
int command_id, cef_menu_color_type_t color_type, cef_color_t color) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Execute
bool _retval = CefMenuModelCppToC::Get(self)->SetColor(
command_id,
color_type,
color);
// Return type: bool
return _retval;
}
int CEF_CALLBACK menu_model_set_color_at(struct _cef_menu_model_t* self,
int index, cef_menu_color_type_t color_type, cef_color_t color) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Execute
bool _retval = CefMenuModelCppToC::Get(self)->SetColorAt(
index,
color_type,
color);
// Return type: bool
return _retval;
}
int CEF_CALLBACK menu_model_get_color(struct _cef_menu_model_t* self,
int command_id, cef_menu_color_type_t color_type, cef_color_t* color) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: color; type: simple_byref
DCHECK(color);
if (!color)
return 0;
// Translate param: color; type: simple_byref
cef_color_t colorVal = color?*color:0;
// Execute
bool _retval = CefMenuModelCppToC::Get(self)->GetColor(
command_id,
color_type,
colorVal);
// Restore param: color; type: simple_byref
if (color)
*color = colorVal;
// Return type: bool
return _retval;
}
int CEF_CALLBACK menu_model_get_color_at(struct _cef_menu_model_t* self,
int index, cef_menu_color_type_t color_type, cef_color_t* color) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: color; type: simple_byref
DCHECK(color);
if (!color)
return 0;
// Translate param: color; type: simple_byref
cef_color_t colorVal = color?*color:0;
// Execute
bool _retval = CefMenuModelCppToC::Get(self)->GetColorAt(
index,
color_type,
colorVal);
// Restore param: color; type: simple_byref
if (color)
*color = colorVal;
// Return type: bool
return _retval;
}
int CEF_CALLBACK menu_model_set_font_list(struct _cef_menu_model_t* self,
int command_id, const cef_string_t* font_list) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Unverified params: font_list
// Execute
bool _retval = CefMenuModelCppToC::Get(self)->SetFontList(
command_id,
CefString(font_list));
// Return type: bool
return _retval;
}
int CEF_CALLBACK menu_model_set_font_list_at(struct _cef_menu_model_t* self,
int index, const cef_string_t* font_list) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Unverified params: font_list
// Execute
bool _retval = CefMenuModelCppToC::Get(self)->SetFontListAt(
index,
CefString(font_list));
// Return type: bool
return _retval;
}
} // namespace
@ -1050,6 +1180,12 @@ CefMenuModelCppToC::CefMenuModelCppToC() {
GetStruct()->remove_accelerator_at = menu_model_remove_accelerator_at;
GetStruct()->get_accelerator = menu_model_get_accelerator;
GetStruct()->get_accelerator_at = menu_model_get_accelerator_at;
GetStruct()->set_color = menu_model_set_color;
GetStruct()->set_color_at = menu_model_set_color_at;
GetStruct()->get_color = menu_model_get_color;
GetStruct()->get_color_at = menu_model_get_color_at;
GetStruct()->set_font_list = menu_model_set_font_list;
GetStruct()->set_font_list_at = menu_model_set_font_list_at;
}
template<> CefRefPtr<CefMenuModel> CefCppToCRefCounted<CefMenuModelCppToC,

View File

@ -915,6 +915,115 @@ bool CefMenuModelCToCpp::GetAcceleratorAt(int index, int& key_code,
return _retval?true:false;
}
bool CefMenuModelCToCpp::SetColor(int command_id,
cef_menu_color_type_t color_type, cef_color_t color) {
cef_menu_model_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, set_color))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
int _retval = _struct->set_color(_struct,
command_id,
color_type,
color);
// Return type: bool
return _retval?true:false;
}
bool CefMenuModelCToCpp::SetColorAt(int index, cef_menu_color_type_t color_type,
cef_color_t color) {
cef_menu_model_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, set_color_at))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
int _retval = _struct->set_color_at(_struct,
index,
color_type,
color);
// Return type: bool
return _retval?true:false;
}
bool CefMenuModelCToCpp::GetColor(int command_id,
cef_menu_color_type_t color_type, cef_color_t& color) {
cef_menu_model_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_color))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
int _retval = _struct->get_color(_struct,
command_id,
color_type,
&color);
// Return type: bool
return _retval?true:false;
}
bool CefMenuModelCToCpp::GetColorAt(int index, cef_menu_color_type_t color_type,
cef_color_t& color) {
cef_menu_model_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_color_at))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
int _retval = _struct->get_color_at(_struct,
index,
color_type,
&color);
// Return type: bool
return _retval?true:false;
}
bool CefMenuModelCToCpp::SetFontList(int command_id,
const CefString& font_list) {
cef_menu_model_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, set_font_list))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: font_list
// Execute
int _retval = _struct->set_font_list(_struct,
command_id,
font_list.GetStruct());
// Return type: bool
return _retval?true:false;
}
bool CefMenuModelCToCpp::SetFontListAt(int index, const CefString& font_list) {
cef_menu_model_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, set_font_list_at))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: font_list
// Execute
int _retval = _struct->set_font_list_at(_struct,
index,
font_list.GetStruct());
// Return type: bool
return _retval?true:false;
}
// CONSTRUCTOR - Do not edit by hand.

View File

@ -90,6 +90,16 @@ class CefMenuModelCToCpp
bool& ctrl_pressed, bool& alt_pressed) OVERRIDE;
bool GetAcceleratorAt(int index, int& key_code, bool& shift_pressed,
bool& ctrl_pressed, bool& alt_pressed) OVERRIDE;
bool SetColor(int command_id, cef_menu_color_type_t color_type,
cef_color_t color) OVERRIDE;
bool SetColorAt(int index, cef_menu_color_type_t color_type,
cef_color_t color) OVERRIDE;
bool GetColor(int command_id, cef_menu_color_type_t color_type,
cef_color_t& color) OVERRIDE;
bool GetColorAt(int index, cef_menu_color_type_t color_type,
cef_color_t& color) OVERRIDE;
bool SetFontList(int command_id, const CefString& font_list) OVERRIDE;
bool SetFontListAt(int index, const CefString& font_list) OVERRIDE;
};
#endif // CEF_LIBCEF_DLL_CTOCPP_MENU_MODEL_CTOCPP_H_

View File

@ -1,5 +1,5 @@
diff --git ui/base/models/menu_model.h ui/base/models/menu_model.h
index 0755f27..72db677 100644
index 0755f27..76ad6d6 100644
--- ui/base/models/menu_model.h
+++ ui/base/models/menu_model.h
@@ -15,6 +15,7 @@
@ -10,7 +10,7 @@ index 0755f27..72db677 100644
}
namespace ui {
@@ -115,6 +116,15 @@ class UI_BASE_EXPORT MenuModel {
@@ -115,6 +116,30 @@ class UI_BASE_EXPORT MenuModel {
// |event_flags| is a bit mask of ui::EventFlags.
virtual void ActivatedAt(int index, int event_flags);
@ -22,6 +22,21 @@ index 0755f27..72db677 100644
+ // true if the menu is displaying a right-to-left language.
+ virtual void UnhandledOpenSubmenu(bool is_rtl) {}
+ virtual void UnhandledCloseSubmenu(bool is_rtl) {}
+
+ // Override the text/background color of a given menu item dependent on the
+ // |index| and its |is_hovered| state. Returns true if it chooses to override
+ // the color.
+ virtual bool GetTextColor(int index,
+ bool is_hovered,
+ SkColor* override_color) const { return false; }
+ virtual bool GetMinorTextColor(int index,
+ bool is_hovered,
+ SkColor* override_color) const
+ { return false; }
+ virtual bool GetBackgroundColor(int index,
+ bool is_hovered,
+ SkColor* override_color) const
+ { return false; }
+
// Called when the menu is about to be shown.
virtual void MenuWillShow() {}
@ -231,10 +246,25 @@ index 79ff77c..a0582c0 100644
SetSelection(item, SELECTION_UPDATE_IMMEDIATELY);
else if (item->GetParentMenuItem()->GetParentMenuItem())
diff --git ui/views/controls/menu/menu_delegate.h ui/views/controls/menu/menu_delegate.h
index 3b7cb7f..3ad68d0 100644
index 3b7cb7f..7481553 100644
--- ui/views/controls/menu/menu_delegate.h
+++ ui/views/controls/menu/menu_delegate.h
@@ -229,6 +229,11 @@ class VIEWS_EXPORT MenuDelegate {
@@ -87,6 +87,14 @@ class VIEWS_EXPORT MenuDelegate {
bool is_hovered,
SkColor* override_color) const;
+ // Override the minor text color of a given menu item dependent on the
+ // |command_id| and its |is_hovered| state. Returns true if it chooses to
+ // override the color.
+ virtual bool GetMinorTextColor(int command_id,
+ bool is_hovered,
+ SkColor* override_color) const
+ { return false; }
+
// Override the background color of a given menu item dependent on the
// |command_id| and its |is_hovered| state. Returns true if it chooses to
// override the color.
@@ -229,6 +237,11 @@ class VIEWS_EXPORT MenuDelegate {
bool* has_mnemonics,
MenuButton** button);
@ -246,11 +276,44 @@ index 3b7cb7f..3ad68d0 100644
// Returns the max width menus can grow to be.
virtual int GetMaxWidthForMenu(MenuItemView* menu);
diff --git ui/views/controls/menu/menu_item_view.cc ui/views/controls/menu/menu_item_view.cc
index b4129049..a23670a 100644
--- ui/views/controls/menu/menu_item_view.cc
+++ ui/views/controls/menu/menu_item_view.cc
@@ -871,6 +871,17 @@ void MenuItemView::PaintMinorText(gfx::Canvas* canvas,
if (minor_text.empty())
return;
+ SkColor text_color;
+
+ MenuDelegate *delegate = GetDelegate();
+ if (!delegate || !delegate->GetMinorTextColor(GetCommand(),
+ render_selection,
+ &text_color)) {
+ text_color = GetNativeTheme()->GetSystemColor(render_selection ?
+ ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor :
+ ui::NativeTheme::kColorId_MenuItemSubtitleColor);
+ }
+
int available_height = height() - GetTopMargin() - GetBottomMargin();
int max_accel_width =
parent_menu_item_->GetSubmenu()->max_minor_text_width();
@@ -889,9 +900,7 @@ void MenuItemView::PaintMinorText(gfx::Canvas* canvas,
canvas->DrawStringRectWithFlags(
minor_text,
GetFontList(),
- GetNativeTheme()->GetSystemColor(render_selection ?
- ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor :
- ui::NativeTheme::kColorId_MenuItemSubtitleColor),
+ text_color,
accel_bounds,
flags);
}
diff --git ui/views/controls/menu/menu_model_adapter.cc ui/views/controls/menu/menu_model_adapter.cc
index bc04dcb..b2ec114 100644
index bc04dcb..d786a0b 100644
--- ui/views/controls/menu/menu_model_adapter.cc
+++ ui/views/controls/menu/menu_model_adapter.cc
@@ -245,6 +245,49 @@ void MenuModelAdapter::SelectionChanged(MenuItemView* menu) {
@@ -245,6 +245,88 @@ void MenuModelAdapter::SelectionChanged(MenuItemView* menu) {
NOTREACHED();
}
@ -296,15 +359,54 @@ index bc04dcb..b2ec114 100644
+
+ NOTREACHED();
+}
+
+bool MenuModelAdapter::GetForegroundColor(int command_id,
+ bool is_hovered,
+ SkColor* override_color) const {
+ ui::MenuModel* model = menu_model_;
+ int index = 0;
+ if (ui::MenuModel::GetModelAndIndexForCommandId(command_id, &model, &index))
+ return model->GetTextColor(index, is_hovered, override_color);
+
+ NOTREACHED();
+ return false;
+}
+
+bool MenuModelAdapter::GetMinorTextColor(int command_id,
+ bool is_hovered,
+ SkColor* override_color) const {
+ ui::MenuModel* model = menu_model_;
+ int index = 0;
+ if (ui::MenuModel::GetModelAndIndexForCommandId(command_id, &model, &index))
+ return model->GetMinorTextColor(index, is_hovered, override_color);
+
+ NOTREACHED();
+ return false;
+}
+
+bool MenuModelAdapter::GetBackgroundColor(int command_id,
+ bool is_hovered,
+ SkColor* override_color) const {
+ if (command_id == -1)
+ return menu_model_->GetBackgroundColor(-1, is_hovered, override_color);
+
+ ui::MenuModel* model = menu_model_;
+ int index = 0;
+ if (ui::MenuModel::GetModelAndIndexForCommandId(command_id, &model, &index))
+ return model->GetBackgroundColor(index, is_hovered, override_color);
+
+ NOTREACHED();
+ return false;
+}
+
void MenuModelAdapter::WillShowMenu(MenuItemView* menu) {
// Look up the menu model for this menu.
const std::map<MenuItemView*, ui::MenuModel*>::const_iterator map_iterator =
diff --git ui/views/controls/menu/menu_model_adapter.h ui/views/controls/menu/menu_model_adapter.h
index c9799da..c7ecca6 100644
index c9799da..827f786 100644
--- ui/views/controls/menu/menu_model_adapter.h
+++ ui/views/controls/menu/menu_model_adapter.h
@@ -76,6 +76,13 @@ class VIEWS_EXPORT MenuModelAdapter : public MenuDelegate {
@@ -76,6 +76,22 @@ class VIEWS_EXPORT MenuModelAdapter : public MenuDelegate {
bool IsCommandVisible(int id) const override;
bool IsItemChecked(int id) const override;
void SelectionChanged(MenuItemView* menu) override;
@ -315,6 +417,31 @@ index c9799da..c7ecca6 100644
+ MenuButton** button) override;
+ void OnUnhandledOpenSubmenu(MenuItemView* menu, bool is_rtl) override;
+ void OnUnhandledCloseSubmenu(MenuItemView* menu, bool is_rtl) override;
+ bool GetForegroundColor(int command_id,
+ bool is_hovered,
+ SkColor* override_color) const override;
+ bool GetMinorTextColor(int command_id,
+ bool is_hovered,
+ SkColor* override_color) const override;
+ bool GetBackgroundColor(int command_id,
+ bool is_hovered,
+ SkColor* override_color) const override;
void WillShowMenu(MenuItemView* menu) override;
void WillHideMenu(MenuItemView* menu) override;
void OnMenuClosed(MenuItemView* menu, MenuRunner::RunResult result) override;
diff --git ui/views/controls/menu/menu_scroll_view_container.cc ui/views/controls/menu/menu_scroll_view_container.cc
index 455d289..f5f7419 100644
--- ui/views/controls/menu/menu_scroll_view_container.cc
+++ ui/views/controls/menu/menu_scroll_view_container.cc
@@ -184,6 +184,11 @@ MenuScrollViewContainer::MenuScrollViewContainer(SubmenuView* content_view)
scroll_view_ = new MenuScrollView(content_view);
AddChildView(scroll_view_);
+ SkColor override_color;
+ MenuDelegate* delegate = content_view_->GetMenuItem()->GetDelegate();
+ if (delegate && delegate->GetBackgroundColor(-1, false, &override_color))
+ set_background(views::Background::CreateSolidBackground(override_color));
+
arrow_ = BubbleBorderTypeFromAnchor(
content_view_->GetMenuItem()->GetMenuController()->GetAnchorPosition());

View File

@ -325,6 +325,9 @@ void ClientHandler::OnBeforeContextMenu(
// Test context menu features.
BuildTestMenu(model);
}
if (delegate_)
delegate_->OnBeforeContextMenu(model);
}
bool ClientHandler::OnContextMenuCommand(

View File

@ -38,7 +38,8 @@ class ClientHandler : public CefClient,
public CefRequestHandler {
public:
// Implement this interface to receive notification of ClientHandler
// events. The methods of this class will be called on the main thread.
// events. The methods of this class will be called on the main thread unless
// otherwise indicated.
class Delegate {
public:
// Called when the browser is created.
@ -74,6 +75,9 @@ class ClientHandler : public CefClient,
// Set focus to the next/previous control.
virtual void OnTakeFocus(bool next) {}
// Called on the UI thread before a context menu is displayed.
virtual void OnBeforeContextMenu(CefRefPtr<CefMenuModel> model) {}
protected:
virtual ~Delegate() {}
};

View File

@ -33,7 +33,7 @@ cef_color_t ParseColor(const std::string& color) {
return CefColorSetARGB(255, 255, 255, 255);
// Use the default color.
return 0U;
return 0;
}
} // namespace
@ -44,7 +44,7 @@ MainContextImpl::MainContextImpl(CefRefPtr<CefCommandLine> command_line,
terminate_when_all_windows_closed_(terminate_when_all_windows_closed),
initialized_(false),
shutdown_(false),
background_color_(CefColorSetARGB(255, 255, 255, 255)),
background_color_(0),
use_views_(false) {
DCHECK(command_line_.get());
@ -54,12 +54,6 @@ MainContextImpl::MainContextImpl(CefRefPtr<CefCommandLine> command_line,
if (main_url_.empty())
main_url_ = kDefaultUrl;
if (command_line_->HasSwitch(switches::kBackgroundColor)) {
// Parse the background color value.
background_color_ =
ParseColor(command_line_->GetSwitchValue(switches::kBackgroundColor));
}
// Whether windowless (off-screen) rendering will be used.
use_windowless_rendering_ =
command_line_->HasSwitch(switches::kOffScreenRenderingEnabled);
@ -81,8 +75,19 @@ MainContextImpl::MainContextImpl(CefRefPtr<CefCommandLine> command_line,
}
#endif // defined(OS_WIN) || defined(OS_LINUX)
if (command_line_->HasSwitch(switches::kBackgroundColor)) {
// Parse the background color value.
background_color_ =
ParseColor(command_line_->GetSwitchValue(switches::kBackgroundColor));
}
if (!use_views_ && background_color_ == 0) {
// Set an explicit background color when not using Views.
background_color_ = CefColorSetARGB(255, 255, 255, 255);
}
const std::string& cdm_path =
command_line_->GetSwitchValue(switches::kWidevineCdmPath);
command_line_->GetSwitchValue(switches::kWidevineCdmPath);
if (!cdm_path.empty()) {
// Register the Widevine CDM at the specified path. See comments in
// cef_web_plugin.h for details. It's safe to call this method before
@ -135,7 +140,8 @@ void MainContextImpl::PopulateSettings(CefSettings* settings) {
if (use_windowless_rendering_)
settings->windowless_rendering_enabled = true;
settings->background_color = background_color_;
if (background_color_ != 0)
settings->background_color = background_color_;
}
void MainContextImpl::PopulateBrowserSettings(CefBrowserSettings* settings) {
@ -150,7 +156,8 @@ void MainContextImpl::PopulateOsrSettings(OsrRenderer::Settings* settings) {
command_line_->HasSwitch(switches::kTransparentPaintingEnabled);
settings->show_update_rect =
command_line_->HasSwitch(switches::kShowUpdateRect);
settings->background_color = background_color_;
if (background_color_ != 0)
settings->background_color = background_color_;
}
RootWindowManager* MainContextImpl::GetRootWindowManager() {

View File

@ -341,6 +341,12 @@ void RootWindowViews::OnTakeFocus(bool next) {
window_->TakeFocus(next);
}
void RootWindowViews::OnBeforeContextMenu(CefRefPtr<CefMenuModel> model) {
CEF_REQUIRE_UI_THREAD();
if (window_)
window_->OnBeforeContextMenu(model);
}
void RootWindowViews::CreateClientHandler(const std::string& url) {
DCHECK(!client_handler_);

View File

@ -74,6 +74,7 @@ class RootWindowViews : public RootWindow,
void OnSetDraggableRegions(
const std::vector<CefDraggableRegion>& regions) OVERRIDE;
void OnTakeFocus(bool next) OVERRIDE;
void OnBeforeContextMenu(CefRefPtr<CefMenuModel> model) OVERRIDE;
private:
void CreateClientHandler(const std::string& url);

View File

@ -6,6 +6,7 @@
#include "include/views/cef_box_layout.h"
#include "include/views/cef_window.h"
#include "tests/cefclient/browser/views_style.h"
namespace client {
@ -71,12 +72,14 @@ CefRefPtr<CefMenuModel> ViewsMenuBar::CreateMenuModel(const CefString& label,
// Create the new MenuModel.
CefRefPtr<CefMenuModel> model = CefMenuModel::CreateMenuModel(this);
views_style::ApplyTo(model);
models_.push_back(model);
// Create the new MenuButton.
CefRefPtr<CefMenuButton> button =
CefMenuButton::CreateMenuButton(this, label, false, false);
button->SetID(new_menu_id);
views_style::ApplyTo(button.get());
button->SetInkDropEnabled(true);
// Assign a group ID to allow focus traversal between MenuButtons using the
@ -236,6 +239,7 @@ void ViewsMenuBar::EnsureMenuPanel() {
return;
panel_ = CefPanel::CreatePanel(NULL);
views_style::ApplyTo(panel_);
// Use a horizontal box layout.
CefBoxLayoutSettings top_panel_layout_settings;

View File

@ -0,0 +1,105 @@
// Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "tests/cefclient/browser/views_style.h"
#include "tests/cefclient/browser/main_context.h"
namespace client {
namespace views_style {
namespace {
cef_color_t g_background_color = 0;
cef_color_t g_background_hover_color = 0;
cef_color_t g_text_color = 0;
int GetShade(int component) {
return (component < 127) ? component + 75 : component - 75;
}
void MaybeInitialize() {
static bool initialized = false;
if (initialized)
return;
g_background_color = MainContext::Get()->GetBackgroundColor();
if (g_background_color != 0) {
// Use a slightly modified shade of the background color for hover.
g_background_hover_color = CefColorSetARGB(255,
GetShade(CefColorGetR(g_background_color)),
GetShade(CefColorGetG(g_background_color)),
GetShade(CefColorGetB(g_background_color)));
// Invert the background color for text.
g_text_color = CefColorSetARGB(255,
255 - CefColorGetR(g_background_color),
255 - CefColorGetG(g_background_color),
255 - CefColorGetB(g_background_color));
}
initialized = true;
}
} // namespace
bool IsSet() {
MaybeInitialize();
return g_background_color != 0;
}
void ApplyTo(CefRefPtr<CefPanel> panel) {
if (!IsSet())
return;
panel->SetBackgroundColor(g_background_color);
}
void ApplyTo(CefRefPtr<CefLabelButton> label_button) {
if (!IsSet())
return;
// All text except disabled gets the same color.
label_button->SetEnabledTextColors(g_text_color);
label_button->SetTextColor(CEF_BUTTON_STATE_DISABLED,
g_background_hover_color);
label_button->SetBackgroundColor(g_background_color);
}
void ApplyTo(CefRefPtr<CefTextfield> textfield) {
if (!IsSet())
return;
textfield->SetBackgroundColor(g_background_color);
textfield->SetTextColor(g_text_color);
}
void ApplyTo(CefRefPtr<CefMenuModel> menu_model) {
if (!IsSet())
return;
// All text except non-hovered accelerator gets the same color.
menu_model->SetColorAt(-1, CEF_MENU_COLOR_TEXT, g_text_color);
menu_model->SetColorAt(-1, CEF_MENU_COLOR_TEXT_HOVERED, g_text_color);
menu_model->SetColorAt(-1, CEF_MENU_COLOR_TEXT_ACCELERATOR,
g_background_hover_color);
menu_model->SetColorAt(-1, CEF_MENU_COLOR_TEXT_ACCELERATOR_HOVERED,
g_text_color);
menu_model->SetColorAt(-1, CEF_MENU_COLOR_BACKGROUND, g_background_color);
menu_model->SetColorAt(-1, CEF_MENU_COLOR_BACKGROUND_HOVERED,
g_background_hover_color);
// Recursively color sub-menus.
for (int i = 0; i < menu_model->GetCount(); ++i) {
if (menu_model->GetTypeAt(i) == MENUITEMTYPE_SUBMENU)
ApplyTo(menu_model->GetSubMenuAt(i));
}
}
} // namespace views_style
} // namespace client

View File

@ -0,0 +1,31 @@
// Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_VIEWS_STYLE_H_
#define CEF_TESTS_CEFCLIENT_BROWSER_VIEWS_STYLE_H_
#pragma once
#include "include/cef_menu_model.h"
#include "include/views/cef_label_button.h"
#include "include/views/cef_panel.h"
#include "include/views/cef_textfield.h"
namespace client {
namespace views_style {
// Returns true if a style is set.
bool IsSet();
// Apply style to views objects.
void ApplyTo(CefRefPtr<CefPanel> panel);
void ApplyTo(CefRefPtr<CefLabelButton> label_button);
void ApplyTo(CefRefPtr<CefTextfield> textfield);
void ApplyTo(CefRefPtr<CefMenuModel> menu_model);
} // namespace views_style
} // namespace client
#endif // CEF_TESTS_CEFCLIENT_BROWSER_VIEWS_STYLE_H_

View File

@ -11,8 +11,8 @@
#include "include/views/cef_box_layout.h"
#include "include/wrapper/cef_helpers.h"
#include "include/cef_app.h"
#include "tests/cefclient/browser/main_context.h"
#include "tests/cefclient/browser/resource.h"
#include "tests/cefclient/browser/views_style.h"
#include "tests/shared/browser/resource_util.h"
#include "tests/shared/common/client_switches.h"
@ -28,6 +28,7 @@ namespace {
// Control IDs for Views in the top-level Window.
enum ControlIds {
ID_WINDOW = 1,
ID_BROWSER_VIEW,
ID_BACK_BUTTON,
ID_FORWARD_BUTTON,
ID_STOP_BUTTON,
@ -81,11 +82,12 @@ void AddTestMenuItems(CefRefPtr<CefMenuModel> test_menu) {
test_menu->AddItem(ID_TESTS_OTHER_TESTS, "Other Tests");
}
void AddFileMenuItems(CefRefPtr<CefMenuModel> file_menu, int offset) {
void AddFileMenuItems(CefRefPtr<CefMenuModel> file_menu) {
file_menu->AddItem(ID_QUIT, "E&xit");
// Show the accelerator shortcut text in the menu.
file_menu->SetAcceleratorAt(offset, 'X', false, false, true);
file_menu->SetAcceleratorAt(file_menu->GetCount() - 1,
'X', false, false, true);
}
} // namespace
@ -243,6 +245,12 @@ void ViewsWindow::TakeFocus(bool next) {
window_->GetViewForID(ID_URL_TEXTFIELD)->RequestFocus();
}
void ViewsWindow::OnBeforeContextMenu(CefRefPtr<CefMenuModel> model) {
CEF_REQUIRE_UI_THREAD();
views_style::ApplyTo(model);
}
bool ViewsWindow::OnPopupBrowserViewCreated(
CefRefPtr<CefBrowserView> browser_view,
CefRefPtr<CefBrowserView> popup_browser_view,
@ -380,7 +388,7 @@ void ViewsWindow::OnWindowCreated(CefRefPtr<CefWindow> window) {
}
// Set the background color for regions that are not obscured by other Views.
window_->SetBackgroundColor(MainContext::Get()->GetBackgroundColor());
views_style::ApplyTo(window_.get());
if (with_controls_) {
// Add the BrowserView and other controls to the Window.
@ -452,8 +460,18 @@ bool ViewsWindow::OnKeyEvent(CefRefPtr<CefWindow> window,
return false;
if (event.type == KEYEVENT_RAWKEYDOWN && event.windows_key_code == VK_MENU) {
// ALT key is pressed. Make the menu buttons focusable.
SetMenuFocusable(true);
// ALT key is pressed.
int last_focused_view = last_focused_view_;
bool menu_had_focus = menu_has_focus_;
// Toggle menu button focusable.
SetMenuFocusable(!menu_has_focus_);
if (menu_had_focus && last_focused_view != 0) {
// Restore focus to the view that was previously focused.
window_->GetViewForID(last_focused_view)->RequestFocus();
}
return true;
}
@ -475,9 +493,16 @@ CefSize ViewsWindow::GetMinimumSize(CefRefPtr<CefView> view) {
void ViewsWindow::OnFocus(CefRefPtr<CefView> view) {
CEF_REQUIRE_UI_THREAD();
const int view_id = view->GetID();
// Keep track of the non-menu view that was last focused.
if (last_focused_view_ != view_id &&
(!top_menu_bar_ || !top_menu_bar_->HasMenuId(view_id))) {
last_focused_view_ = view_id;
}
// When focus leaves the menu buttons make them unfocusable.
if (menu_has_focus_) {
const int view_id = view->GetID();
if (top_menu_bar_) {
if (!top_menu_bar_->HasMenuId(view_id))
SetMenuFocusable(false);
@ -497,7 +522,8 @@ ViewsWindow::ViewsWindow(Delegate* delegate,
CefRefPtr<CefBrowserView> browser_view)
: delegate_(delegate),
with_controls_(false),
menu_has_focus_(false) {
menu_has_focus_(false),
last_focused_view_(false) {
DCHECK(delegate_);
if (browser_view)
SetBrowserView(browser_view);
@ -506,8 +532,9 @@ ViewsWindow::ViewsWindow(Delegate* delegate,
CefCommandLine::GetGlobalCommandLine();
frameless_ = command_line->HasSwitch(switches::kHideFrame);
if (!command_line->HasSwitch(switches::kHideTopMenu))
if (!command_line->HasSwitch(switches::kHideTopMenu)) {
top_menu_bar_ = new ViewsMenuBar(this, ID_TOP_MENU_FIRST);
}
}
void ViewsWindow::SetBrowserView(CefRefPtr<CefBrowserView> browser_view) {
@ -516,6 +543,7 @@ void ViewsWindow::SetBrowserView(CefRefPtr<CefBrowserView> browser_view) {
DCHECK(browser_view->IsValid());
DCHECK(!browser_view->IsAttached());
browser_view_ = browser_view;
browser_view_->SetID(ID_BROWSER_VIEW);
}
void ViewsWindow::CreateMenuModel() {
@ -523,12 +551,13 @@ void ViewsWindow::CreateMenuModel() {
button_menu_model_ = CefMenuModel::CreateMenuModel(this);
CefRefPtr<CefMenuModel> test_menu =
button_menu_model_->AddSubMenu(0, "&Tests");
views_style::ApplyTo(button_menu_model_);
AddTestMenuItems(test_menu);
AddFileMenuItems(button_menu_model_, 1);
AddFileMenuItems(button_menu_model_);
if (top_menu_bar_) {
// Add the menus to the top menu bar.
AddFileMenuItems(top_menu_bar_->CreateMenuModel("&File", NULL), 0);
AddFileMenuItems(top_menu_bar_->CreateMenuModel("&File", NULL));
AddTestMenuItems(top_menu_bar_->CreateMenuModel("&Tests", NULL));
}
}
@ -536,11 +565,23 @@ void ViewsWindow::CreateMenuModel() {
CefRefPtr<CefLabelButton> ViewsWindow::CreateBrowseButton(
const std::string& label,
int id) {
// The default framed button image resources (IDR_BUTTON_*) look pretty bad
// with non-default background colors, so we'll use frameless buttons with
// ink drop when a background color is specified.
const bool with_frame = !views_style::IsSet();
CefRefPtr<CefLabelButton> button =
CefLabelButton::CreateLabelButton(this, label, true);
CefLabelButton::CreateLabelButton(this, label, with_frame);
button->SetID(id);
button->SetEnabled(false); // Disabled by default.
button->SetFocusable(false); // Don't give focus to the button.
if (!with_frame) {
views_style::ApplyTo(button);
button->SetInkDropEnabled(true);
button->SetHorizontalAlignment(CEF_HORIZONTAL_ALIGNMENT_CENTER);
}
return button;
}
@ -563,12 +604,14 @@ void ViewsWindow::AddControls() {
CefRefPtr<CefTextfield> url_textfield = CefTextfield::CreateTextfield(this);
url_textfield->SetID(ID_URL_TEXTFIELD);
url_textfield->SetEnabled(false); // Disabled by default.
views_style::ApplyTo(url_textfield);
// Create the menu button.
CefRefPtr<CefMenuButton> menu_button =
CefMenuButton::CreateMenuButton(this, CefString(), false, false);
menu_button->SetID(ID_MENU_BUTTON);
menu_button->SetImage(CEF_BUTTON_STATE_NORMAL, LoadImageIcon("menu_icon"));
views_style::ApplyTo(menu_button.get());
menu_button->SetInkDropEnabled(true);
// Override the default minimum size.
menu_button->SetMinimumSize(CefSize(0, 0));
@ -587,6 +630,7 @@ void ViewsWindow::AddControls() {
top_panel->AddChildView(browse_buttons[i]);
top_panel->AddChildView(url_textfield);
top_panel->AddChildView(menu_button);
views_style::ApplyTo(top_panel);
// Allow |url_textfield| to grow and fill any remaining space.
top_panel_layout->SetFlexForView(url_textfield, 1);

View File

@ -86,6 +86,7 @@ class ViewsWindow : public CefBrowserViewDelegate,
bool canGoForward);
void SetDraggableRegions(const std::vector<CefDraggableRegion>& regions);
void TakeFocus(bool next);
void OnBeforeContextMenu(CefRefPtr<CefMenuModel> model);
// CefBrowserViewDelegate methods:
bool OnPopupBrowserViewCreated(
@ -164,6 +165,7 @@ class ViewsWindow : public CefBrowserViewDelegate,
CefRefPtr<CefMenuModel> button_menu_model_;
CefRefPtr<ViewsMenuBar> top_menu_bar_;
bool menu_has_focus_;
int last_focused_view_;
CefSize minimum_window_size_;

View File

@ -393,6 +393,79 @@ class TestMenuButtonDelegate : public CefMenuButtonDelegate,
CefRefPtr<CefMenuModel> model = CefMenuModel::CreateMenuModel(this);
model->AddItem(kMenuItemID, kMenuItemLabel);
// Verify color accessors.
for (int i = 0; i < CEF_MENU_COLOR_COUNT; ++i) {
cef_menu_color_type_t color_type = static_cast<cef_menu_color_type_t>(i);
cef_color_t color_out;
cef_color_t color = CefColorSetARGB(255, 255, 255, i);
// No color set yet.
color_out = 1;
EXPECT_TRUE(model->GetColor(kMenuItemID, color_type, color_out));
EXPECT_EQ(0U, color_out);
color_out = 1;
EXPECT_TRUE(model->GetColorAt(0, color_type, color_out));
EXPECT_EQ(0U, color_out);
color_out = 1;
EXPECT_TRUE(model->GetColorAt(-1, color_type, color_out));
EXPECT_EQ(0U, color_out);
// Set the default color.
EXPECT_TRUE(model->SetColorAt(-1, color_type, color));
color_out = 1;
EXPECT_TRUE(model->GetColorAt(-1, color_type, color_out));
EXPECT_EQ(color, color_out);
// Clear the default color.
EXPECT_TRUE(model->SetColorAt(-1, color_type, 0));
color_out = 1;
EXPECT_TRUE(model->GetColorAt(-1, color_type, color_out));
EXPECT_EQ(0U, color_out);
// Set the index color.
EXPECT_TRUE(model->SetColorAt(0, color_type, color));
color_out = 1;
EXPECT_TRUE(model->GetColorAt(0, color_type, color_out));
EXPECT_EQ(color, color_out);
// Clear the index color.
EXPECT_TRUE(model->SetColorAt(0, color_type, 0));
color_out = 1;
EXPECT_TRUE(model->GetColorAt(0, color_type, color_out));
EXPECT_EQ(0U, color_out);
// Set the ID color.
EXPECT_TRUE(model->SetColor(kMenuItemID, color_type, color));
color_out = 1;
EXPECT_TRUE(model->GetColor(kMenuItemID, color_type, color_out));
EXPECT_EQ(color, color_out);
// Clear the ID color.
EXPECT_TRUE(model->SetColor(kMenuItemID, color_type, 0));
color_out = 1;
EXPECT_TRUE(model->GetColor(kMenuItemID, color_type, color_out));
EXPECT_EQ(0U, color_out);
// Index/ID doesn't exist.
EXPECT_FALSE(model->SetColorAt(4, color_type, color));
EXPECT_FALSE(model->SetColor(4, color_type, color));
color_out = 1;
EXPECT_FALSE(model->GetColorAt(4, color_type, color_out));
EXPECT_FALSE(model->GetColor(4, color_type, color_out));
EXPECT_EQ(1U, color_out);
}
// Verify font accessors.
const std::string& font = "Tahoma, 12px";
EXPECT_TRUE(model->SetFontListAt(0, font));
EXPECT_TRUE(model->SetFontListAt(0, CefString()));
EXPECT_TRUE(model->SetFontList(kMenuItemID, font));
EXPECT_TRUE(model->SetFontList(kMenuItemID, CefString()));
// Index/ID doesn't exist.
EXPECT_FALSE(model->SetFontListAt(4, font));
EXPECT_FALSE(model->SetFontList(4, font));
// Wait a bit before trying to click the menu item.
CefPostDelayedTask(TID_UI, base::Bind(ClickMenuItem, menu_button),
kClickDelayMS);