mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
views: Support styling of menus (issue #2102)
This commit is contained in:
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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_
|
||||
|
@@ -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 {
|
||||
|
Reference in New Issue
Block a user