Index: ui/views/controls/combobox/combobox.cc |
diff --git a/ui/views/controls/combobox/combobox.cc b/ui/views/controls/combobox/combobox.cc |
index 2600b174f07d27d2e9f3f8511ca71049270a444c..21dcf3e0c8952ec4f8bbcd5250c0a53911d30cfd 100644 |
--- a/ui/views/controls/combobox/combobox.cc |
+++ b/ui/views/controls/combobox/combobox.cc |
@@ -12,9 +12,12 @@ |
#include "ui/base/resource/resource_bundle.h" |
#include "ui/events/event.h" |
#include "ui/events/keycodes/keyboard_codes.h" |
+#include "ui/gfx/animation/slide_animation.h" |
#include "ui/gfx/canvas.h" |
+#include "ui/gfx/image/image.h" |
#include "ui/native_theme/native_theme.h" |
#include "ui/views/color_constants.h" |
+#include "ui/views/controls/button/custom_button.h" |
#include "ui/views/controls/combobox/combobox_listener.h" |
#include "ui/views/controls/focusable_border.h" |
#include "ui/views/controls/menu/menu_runner.h" |
@@ -22,6 +25,7 @@ |
#include "ui/views/controls/prefix_selector.h" |
#include "ui/views/ime/input_method.h" |
#include "ui/views/mouse_constants.h" |
+#include "ui/views/painter.h" |
#include "ui/views/widget/widget.h" |
namespace views { |
@@ -39,6 +43,8 @@ const int kMinComboboxWidth = 25; |
// Size of the combobox arrow margins |
const int kDisclosureArrowLeftPadding = 7; |
const int kDisclosureArrowRightPadding = 7; |
+const int kDisclosureArrowButtonLeftPadding = 11; |
+const int kDisclosureArrowButtonRightPadding = 12; |
// Define the id of the first item in the menu (since it needs to be > 0) |
const int kFirstMenuItemId = 1000; |
@@ -48,6 +54,22 @@ const SkColor kInvalidTextColor = SK_ColorWHITE; |
// Used to indicate that no item is currently selected by the user. |
const int kNoSelection = -1; |
+const int kBodyButtonImages[] = IMAGE_GRID(IDR_COMBOBOX_BUTTON); |
+const int kHoveredBodyButtonImages[] = IMAGE_GRID2(IDR_COMBOBOX_BUTTON, H); |
+const int kPressedBodyButtonImages[] = IMAGE_GRID2(IDR_COMBOBOX_BUTTON, P); |
+ |
+#define MENU_IMAGE_GRID(x) { \ |
+ x ## _MENU_TOP, x ## _MENU_CENTER, x ## _MENU_BOTTOM, } |
+#define MENU_IMAGE_GRID2(x, y) { \ |
+ x ## _MENU_TOP_ ## y, x ## _MENU_CENTER_ ## y, x ## _MENU_BOTTOM_ ## y, } |
+ |
+const int kMenuButtonImages[] = MENU_IMAGE_GRID(IDR_COMBOBOX_BUTTON); |
+const int kHoveredMenuButtonImages[] = MENU_IMAGE_GRID2(IDR_COMBOBOX_BUTTON, H); |
+const int kPressedMenuButtonImages[] = MENU_IMAGE_GRID2(IDR_COMBOBOX_BUTTON, P); |
+ |
+#undef MENU_IMAGE_GRID |
+#undef MENU_IMAGE_GRID2 |
+ |
// The background to use for invalid comboboxes. |
class InvalidBackground : public Background { |
public: |
@@ -81,6 +103,132 @@ int GetAdjacentIndex(ui::ComboboxModel* model, int increment, int index) { |
return kNoSelection; |
} |
+// Returns the image resource ids of an array for the body button. |
+// |
+// TODO(hajimehoshi): This function should return the images for the 'disabled' |
+// status. (crbug/270052) |
+// |
+// TODO(hajimehoshi): Currently, |focused| is ignored. This should return the |
+// images for the 'focused' status. (crbug/270052) |
+const int* GetBodyButtonImageIds(bool focused, Button::ButtonState state) { |
+ switch (state) { |
+ case Button::STATE_DISABLED: |
+ return kBodyButtonImages; |
+ case Button::STATE_NORMAL: |
+ return kBodyButtonImages; |
+ case Button::STATE_HOVERED: |
+ return kHoveredBodyButtonImages; |
+ case Button::STATE_PRESSED: |
+ return kPressedBodyButtonImages; |
+ default: |
+ NOTREACHED(); |
+ } |
+ return NULL; |
+} |
+ |
+// Returns the image resource ids of an array for the menu button. |
+const int* GetMenuButtonImageIds(bool focused, Button::ButtonState state) { |
+ switch (state) { |
+ case Button::STATE_DISABLED: |
+ return kMenuButtonImages; |
+ case Button::STATE_NORMAL: |
+ return kMenuButtonImages; |
+ case Button::STATE_HOVERED: |
+ return kHoveredMenuButtonImages; |
+ case Button::STATE_PRESSED: |
+ return kPressedMenuButtonImages; |
+ default: |
+ NOTREACHED(); |
+ } |
+ return NULL; |
+} |
+ |
+// Returns the images for the buttons. |
+std::vector<const gfx::ImageSkia*> GetButtonImages(bool menu, |
+ bool focused, |
+ Button::ButtonState state) { |
+ const int* ids; |
+ size_t num_ids; |
+ if (!menu) { |
+ ids = GetBodyButtonImageIds(focused, state); |
+ num_ids = 9; |
+ } else { |
+ ids = GetMenuButtonImageIds(focused, state); |
+ num_ids = 3; |
+ } |
+ std::vector<const gfx::ImageSkia*> images; |
+ images.reserve(num_ids); |
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
+ for (size_t i = 0; i < num_ids; i++) { |
+ int id = ids[i]; |
+ images.push_back(rb.GetImageSkiaNamed(id)); |
+ } |
+ return images; |
+} |
+ |
+// Paints three images in a row at the given location. |
+void PaintTandemImages(gfx::Canvas* canvas, |
+ const gfx::ImageSkia& top_image, |
+ const gfx::ImageSkia& center_image, |
+ const gfx::ImageSkia& bottom_image, |
+ int x, int y, int width, int height) { |
+ canvas->DrawImageInt(top_image, |
+ 0, 0, top_image.width(), top_image.height(), |
+ x, y, width, top_image.height(), false); |
+ y += top_image.height(); |
+ int center_height = height - top_image.height() - bottom_image.height(); |
+ canvas->DrawImageInt(center_image, |
+ 0, 0, center_image.width(), center_image.height(), |
+ x, y, width, center_height, false); |
+ y += center_height; |
+ canvas->DrawImageInt(bottom_image, |
+ 0, 0, bottom_image.width(), bottom_image.height(), |
+ x, y, width, bottom_image.height(), false); |
+} |
+ |
+// Paints the text button. |
+void PaintTextButton( |
+ gfx::Canvas* canvas, |
+ const std::vector<const gfx::ImageSkia*>& text_button_images, |
+ int width, int height) { |
+ int current_x = 0; |
+ int current_width = text_button_images[0]->width(); |
+ PaintTandemImages(canvas, |
+ *text_button_images[0], |
+ *text_button_images[3], |
+ *text_button_images[6], |
+ current_x, 0, current_width, height); |
+ |
+ current_x += current_width; |
+ current_width = width - text_button_images[0]->width() - |
+ text_button_images[2]->width(); |
+ PaintTandemImages(canvas, |
+ *text_button_images[1], |
+ *text_button_images[4], |
+ *text_button_images[7], |
+ current_x, 0, current_width, height); |
+ |
+ current_x += current_width; |
+ current_width = text_button_images[2]->width(); |
+ PaintTandemImages(canvas, |
+ *text_button_images[2], |
+ *text_button_images[5], |
+ *text_button_images[8], |
+ current_x, 0, current_width, height); |
+} |
+ |
+// Paints the arrow button. |
+void PaintArrowButton( |
+ gfx::Canvas* canvas, |
+ const std::vector<const gfx::ImageSkia*>& arrow_button_images, |
+ int x, int height) { |
+ PaintTandemImages(canvas, |
+ *arrow_button_images[0], |
+ *arrow_button_images[1], |
+ *arrow_button_images[2], |
+ x, 0, arrow_button_images[0]->width(), height); |
+} |
+ |
} // namespace |
// static |
@@ -91,17 +239,46 @@ const char Combobox::kViewClassName[] = "views/Combobox"; |
Combobox::Combobox(ui::ComboboxModel* model) |
: model_(model), |
+ style_(STYLE_NORMAL), |
listener_(NULL), |
selected_index_(model_->GetDefaultIndex()), |
invalid_(false), |
text_border_(new FocusableBorder()), |
disclosure_arrow_(ui::ResourceBundle::GetSharedInstance().GetImageNamed( |
IDR_MENU_DROPARROW).ToImageSkia()), |
- dropdown_open_(false) { |
+ dropdown_open_(false), |
+ drag_started_(false), |
+ text_button_state_(Button::STATE_NORMAL), |
+ arrow_button_state_(Button::STATE_NORMAL) { |
model_->AddObserver(this); |
UpdateFromModel(); |
set_focusable(true); |
set_border(text_border_); |
+ |
+ // Initialize the button images. |
+ Button::ButtonState button_states[] = { |
+ Button::STATE_DISABLED, |
+ Button::STATE_NORMAL, |
+ Button::STATE_HOVERED, |
+ Button::STATE_PRESSED, |
+ }; |
+ for (int focused = 0; focused < 2; focused++) { |
+ for (size_t state_index = 0; state_index < arraysize(button_states); |
+ state_index++) { |
+ Button::ButtonState state = button_states[state_index]; |
+ body_button_images_[focused][state] = |
+ GetButtonImages(false, focused, state); |
+ menu_button_images_[focused][state] = |
+ GetButtonImages(true, focused, state); |
+ } |
+ } |
+ |
+ text_button_hover_animation_.reset(new gfx::SlideAnimation(this)); |
+ text_button_hover_animation_->SetSlideDuration( |
+ CustomButton::kHoverFadeDurationMs); |
+ arrow_button_hover_animation_.reset(new gfx::SlideAnimation(this)); |
+ arrow_button_hover_animation_->SetSlideDuration( |
+ CustomButton::kHoverFadeDurationMs); |
} |
Combobox::~Combobox() { |
@@ -114,6 +291,22 @@ const gfx::Font& Combobox::GetFont() { |
return rb.GetFont(ui::ResourceBundle::BaseFont); |
} |
+void Combobox::SetStyle(Style style) { |
+ if (style_ == style) |
+ return; |
+ |
+ style_ = style; |
+ switch (style) { |
+ case STYLE_NORMAL: |
+ text_border_->ResetInsets(); |
+ break; |
+ case STYLE_BUTTONS: |
+ text_border_->SetInsets(8, 13, 8, 13); |
+ break; |
+ } |
+ PreferredSizeChanged(); |
+} |
+ |
void Combobox::ModelChanged() { |
selected_index_ = std::min(0, model_->GetItemCount()); |
UpdateFromModel(); |
@@ -201,9 +394,8 @@ gfx::Size Combobox::GetPreferredSize() { |
// the minimum width for the dropdown list. |
gfx::Insets insets = GetInsets(); |
int total_width = std::max(kMinComboboxWidth, content_size_.width()) + |
- insets.width() + kDisclosureArrowLeftPadding + |
- disclosure_arrow_->width() + kDisclosureArrowRightPadding; |
- |
+ insets.width() + GetDisclosureArrowLeftPadding() + |
+ disclosure_arrow_->width() + GetDisclosureArrowRightPadding(); |
return gfx::Size(total_width, content_size_.height() + insets.height()); |
} |
@@ -225,17 +417,64 @@ bool Combobox::OnMousePressed(const ui::MouseEvent& mouse_event) { |
const base::TimeDelta delta = base::Time::Now() - closed_time_; |
if (mouse_event.IsLeftMouseButton() && |
(delta.InMilliseconds() > kMinimumMsBetweenButtonClicks)) { |
- UpdateFromModel(); |
- ShowDropDownMenu(ui::MENU_SOURCE_MOUSE); |
+ if (InArrowButton(mouse_event.location())) { |
+ UpdateFromModel(); |
+ ShowDropDownMenu(ui::MENU_SOURCE_MOUSE); |
+ } else if (InTextButton(mouse_event.location())) { |
+ SetButtonStates(Button::STATE_PRESSED, Button::STATE_NORMAL); |
+ } |
} |
- |
return true; |
} |
bool Combobox::OnMouseDragged(const ui::MouseEvent& mouse_event) { |
+ if (!drag_started_) { |
+ drag_started_ = true; |
+ drag_start_point_ = mouse_event.location(); |
+ } |
+ bool on_text = InTextButton(mouse_event.location()) && |
+ InTextButton(drag_start_point_); |
+ bool on_arrow = InArrowButton(mouse_event.location()) && |
+ InArrowButton(drag_start_point_); |
+ SetButtonStates(on_text ? Button::STATE_PRESSED : Button::STATE_NORMAL, |
+ on_arrow ? Button::STATE_PRESSED : Button::STATE_NORMAL); |
return true; |
} |
+void Combobox::OnMouseReleased(const ui::MouseEvent& mouse_event) { |
+ bool on_text = InTextButton(mouse_event.location()); |
+ bool on_arrow = InArrowButton(mouse_event.location()); |
+ SetButtonStates(on_text ? Button::STATE_HOVERED : Button::STATE_NORMAL, |
+ on_arrow ? Button::STATE_HOVERED : Button::STATE_NORMAL); |
+ if (mouse_event.IsOnlyLeftMouseButton() && |
+ InTextButton(mouse_event.location())) { |
+ HandleClickEvent(); |
+ } |
+} |
+ |
+void Combobox::OnMouseCaptureLost() { |
+ drag_started_ = false; |
+ SetButtonStates(Button::STATE_NORMAL, Button::STATE_NORMAL); |
+} |
+ |
+void Combobox::OnMouseEntered(const ui::MouseEvent& mouse_event) { |
+ bool on_text = InTextButton(mouse_event.location()); |
+ bool on_arrow = InArrowButton(mouse_event.location()); |
+ SetButtonStates(on_text ? Button::STATE_HOVERED : Button::STATE_NORMAL, |
+ on_arrow ? Button::STATE_HOVERED : Button::STATE_NORMAL); |
+} |
+ |
+void Combobox::OnMouseExited(const ui::MouseEvent& mouse_event) { |
+ SetButtonStates(Button::STATE_NORMAL, Button::STATE_NORMAL); |
+} |
+ |
+void Combobox::OnMouseMoved(const ui::MouseEvent& mouse_event) { |
+ bool on_text = InTextButton(mouse_event.location()); |
+ bool on_arrow = InArrowButton(mouse_event.location()); |
+ SetButtonStates(on_text ? Button::STATE_HOVERED : Button::STATE_NORMAL, |
+ on_arrow ? Button::STATE_HOVERED : Button::STATE_NORMAL); |
+} |
+ |
bool Combobox::OnKeyPressed(const ui::KeyEvent& e) { |
// TODO(oshima): handle IME. |
DCHECK_EQ(e.type(), ui::ET_KEY_PRESSED); |
@@ -280,6 +519,19 @@ bool Combobox::OnKeyPressed(const ui::KeyEvent& e) { |
new_index = GetAdjacentIndex(model(), -1, selected_index_); |
break; |
+ // Click the button only when the button style mode. |
+ case ui::VKEY_SPACE: |
+ SetButtonStates(Button::STATE_PRESSED, Button::STATE_NORMAL); |
+ // When pressing space, the click event will be raised after the key is |
+ // released. |
+ break; |
+ |
+ // Click the button only when the button style mode. |
+ case ui::VKEY_RETURN: |
+ SetButtonStates(Button::STATE_NORMAL, Button::STATE_NORMAL); |
+ HandleClickEvent(); |
+ break; |
+ |
default: |
return false; |
} |
@@ -297,13 +549,25 @@ bool Combobox::OnKeyPressed(const ui::KeyEvent& e) { |
} |
bool Combobox::OnKeyReleased(const ui::KeyEvent& e) { |
- return false; // crbug.com/127520 |
+ if (style_ != STYLE_BUTTONS) |
+ return false; // crbug.com/127520 |
+ |
+ if (e.key_code() == ui::VKEY_SPACE) { |
+ SetButtonStates(Button::STATE_NORMAL, Button::STATE_NORMAL); |
+ HandleClickEvent(); |
+ } |
+ return false; |
} |
void Combobox::OnGestureEvent(ui::GestureEvent* gesture) { |
if (gesture->type() == ui::ET_GESTURE_TAP) { |
- UpdateFromModel(); |
- ShowDropDownMenu(ui::MENU_SOURCE_TOUCH); |
+ if (InArrowButton(gesture->location())) { |
+ UpdateFromModel(); |
+ ShowDropDownMenu(ui::MENU_SOURCE_TOUCH); |
+ } else if (InTextButton(gesture->location())) { |
+ SetButtonStates(Button::STATE_PRESSED, Button::STATE_NORMAL); |
+ HandleClickEvent(); |
+ } |
gesture->StopPropagation(); |
return; |
} |
@@ -311,9 +575,19 @@ void Combobox::OnGestureEvent(ui::GestureEvent* gesture) { |
} |
void Combobox::OnPaint(gfx::Canvas* canvas) { |
- OnPaintBackground(canvas); |
- PaintText(canvas); |
- OnPaintBorder(canvas); |
+ switch (style_) { |
+ case STYLE_NORMAL: { |
+ OnPaintBackground(canvas); |
+ PaintText(canvas); |
+ OnPaintBorder(canvas); |
+ break; |
+ } |
+ case STYLE_BUTTONS: { |
+ PaintButtons(canvas); |
+ PaintText(canvas); |
+ break; |
+ } |
+ } |
} |
void Combobox::OnFocus() { |
@@ -341,6 +615,10 @@ void Combobox::OnModelChanged() { |
ModelChanged(); |
} |
+void Combobox::AnimationProgressed(const gfx::Animation* animation) { |
+ SchedulePaint(); |
+} |
+ |
void Combobox::UpdateFromModel() { |
int max_width = 0; |
const gfx::Font& font = Combobox::GetFont(); |
@@ -392,8 +670,8 @@ void Combobox::PaintText(gfx::Canvas* canvas) { |
selected_index_ = 0; |
string16 text = model()->GetItemAt(selected_index_); |
- int disclosure_arrow_offset = width() - disclosure_arrow_->width() |
- - kDisclosureArrowLeftPadding - kDisclosureArrowRightPadding; |
+ int disclosure_arrow_offset = width() - disclosure_arrow_->width() - |
+ GetDisclosureArrowLeftPadding() - GetDisclosureArrowRightPadding(); |
const gfx::Font& font = Combobox::GetFont(); |
int text_width = font.GetStringWidth(text); |
@@ -404,7 +682,8 @@ void Combobox::PaintText(gfx::Canvas* canvas) { |
AdjustBoundsForRTLUI(&text_bounds); |
canvas->DrawStringInt(text, font, text_color, text_bounds); |
- gfx::Rect arrow_bounds(disclosure_arrow_offset + kDisclosureArrowLeftPadding, |
+ int arrow_x = disclosure_arrow_offset + GetDisclosureArrowLeftPadding(); |
+ gfx::Rect arrow_bounds(arrow_x, |
height() / 2 - disclosure_arrow_->height() / 2, |
disclosure_arrow_->width(), |
disclosure_arrow_->height()); |
@@ -420,6 +699,59 @@ void Combobox::PaintText(gfx::Canvas* canvas) { |
canvas->Restore(); |
} |
+void Combobox::PaintButtons(gfx::Canvas* canvas) { |
+ canvas->Save(); |
+ if (base::i18n::IsRTL()) { |
+ canvas->Translate(gfx::Vector2d(width(), 0)); |
+ canvas->Scale(-1, 1); |
+ } |
+ |
+ bool focused = HasFocus() && IsAccessibilityFocusable(); |
+ const std::vector<const gfx::ImageSkia*>& text_button_images = |
+ body_button_images_[focused][text_button_state_ == Button::STATE_HOVERED ? |
+ Button::STATE_NORMAL : text_button_state_]; |
+ const std::vector<const gfx::ImageSkia*>& arrow_button_images = |
+ menu_button_images_[focused][ |
+ arrow_button_state_ == Button::STATE_HOVERED ? |
+ Button::STATE_NORMAL : arrow_button_state_]; |
+ |
+ int text_button_width = width() - arrow_button_images[0]->width(); |
+ int text_button_hover_alpha = |
+ static_cast<int>(text_button_hover_animation_->GetCurrentValue() * 255); |
+ if (text_button_hover_alpha < 255) { |
+ canvas->SaveLayerAlpha(255 - text_button_hover_alpha); |
+ PaintTextButton(canvas, text_button_images, text_button_width, height()); |
+ canvas->Restore(); |
+ } |
+ if (0 < text_button_hover_alpha) { |
+ canvas->SaveLayerAlpha(text_button_hover_alpha); |
+ const std::vector<const gfx::ImageSkia*>& text_button_hovered_images = |
+ body_button_images_[focused][Button::STATE_HOVERED]; |
+ PaintTextButton(canvas, text_button_hovered_images, |
+ text_button_width, height()); |
+ canvas->Restore(); |
+ } |
+ |
+ int arrow_button_x = text_button_width; |
+ int arrow_button_hover_alpha = |
+ static_cast<int>(arrow_button_hover_animation_->GetCurrentValue() * 255); |
+ if (arrow_button_hover_alpha < 255) { |
+ canvas->SaveLayerAlpha(255 - arrow_button_hover_alpha); |
+ PaintArrowButton(canvas, arrow_button_images, arrow_button_x, height()); |
+ canvas->Restore(); |
+ } |
+ if (0 < arrow_button_hover_alpha) { |
+ canvas->SaveLayerAlpha(arrow_button_hover_alpha); |
+ const std::vector<const gfx::ImageSkia*>& arrow_button_hovered_images = |
+ menu_button_images_[focused][Button::STATE_HOVERED]; |
+ PaintArrowButton(canvas, arrow_button_hovered_images, |
+ arrow_button_x, height()); |
+ canvas->Restore(); |
+ } |
+ |
+ canvas->Restore(); |
+} |
+ |
void Combobox::ShowDropDownMenu(ui::MenuSourceType source_type) { |
if (!dropdown_list_menu_runner_.get()) |
UpdateFromModel(); |
@@ -427,8 +759,8 @@ void Combobox::ShowDropDownMenu(ui::MenuSourceType source_type) { |
// Extend the menu to the width of the combobox. |
MenuItemView* menu = dropdown_list_menu_runner_->GetMenu(); |
SubmenuView* submenu = menu->CreateSubmenu(); |
- submenu->set_minimum_preferred_width(size().width() - |
- (kMenuBorderWidthLeft + kMenuBorderWidthRight)); |
+ submenu->set_minimum_preferred_width( |
+ size().width() - (kMenuBorderWidthLeft + kMenuBorderWidthRight)); |
gfx::Rect lb = GetLocalBounds(); |
gfx::Point menu_position(lb.origin()); |
@@ -441,15 +773,19 @@ void Combobox::ShowDropDownMenu(ui::MenuSourceType source_type) { |
View::ConvertPointToScreen(this, &menu_position); |
if (menu_position.x() < 0) |
- menu_position.set_x(0); |
+ menu_position.set_x(0); |
gfx::Rect bounds(menu_position, lb.size()); |
dropdown_open_ = true; |
+ Button::ButtonState original_arrow_button_state = arrow_button_state_; |
+ SetButtonStates(Button::STATE_NORMAL, Button::STATE_PRESSED); |
if (dropdown_list_menu_runner_->RunMenuAt(GetWidget(), NULL, bounds, |
MenuItemView::TOPLEFT, source_type, MenuRunner::COMBOBOX) == |
- MenuRunner::MENU_DELETED) |
+ MenuRunner::MENU_DELETED) { |
return; |
+ } |
+ SetButtonStates(Button::STATE_NORMAL, original_arrow_button_state); |
dropdown_open_ = false; |
closed_time_ = base::Time::Now(); |
@@ -474,4 +810,88 @@ int Combobox::MenuCommandToIndex(int menu_command_id) const { |
return index; |
} |
+int Combobox::GetDisclosureArrowLeftPadding() const { |
+ switch (style_) { |
+ case STYLE_NORMAL: |
+ return kDisclosureArrowLeftPadding; |
+ case STYLE_BUTTONS: |
+ return kDisclosureArrowButtonLeftPadding; |
+ } |
+ NOTREACHED(); |
+ return 0; |
+} |
+ |
+int Combobox::GetDisclosureArrowRightPadding() const { |
+ switch (style_) { |
+ case STYLE_NORMAL: |
+ return kDisclosureArrowRightPadding; |
+ case STYLE_BUTTONS: |
+ return kDisclosureArrowButtonRightPadding; |
+ } |
+ NOTREACHED(); |
+ return 0; |
+} |
+ |
+void Combobox::HandleClickEvent() { |
+ if (style_ != STYLE_BUTTONS) |
+ return; |
+ |
+ if (listener_) |
+ listener_->OnTextButtonClicked(this); |
+} |
+ |
+void Combobox::SetButtonStates(Button::ButtonState text_button_state, |
+ Button::ButtonState arrow_button_state) { |
+ if (style_ != STYLE_BUTTONS) |
+ return; |
+ |
+ AnimateStateTransition(text_button_hover_animation_.get(), |
+ text_button_state_, text_button_state); |
+ AnimateStateTransition(arrow_button_hover_animation_.get(), |
+ arrow_button_state_, arrow_button_state); |
+ |
+ text_button_state_ = text_button_state; |
+ arrow_button_state_ = arrow_button_state; |
+ SchedulePaint(); |
+} |
+ |
+void Combobox::AnimateStateTransition(gfx::SlideAnimation* animation, |
+ Button::ButtonState from, |
+ Button::ButtonState to) { |
+ if (from == Button::STATE_NORMAL && to == Button::STATE_HOVERED) |
+ animation->Show(); |
+ else if (from == Button::STATE_HOVERED && to == Button::STATE_NORMAL) |
+ animation->Hide(); |
+ else if (from != to) |
+ animation->Reset(to == Button::STATE_HOVERED ? 1.0 : 0.0); |
+} |
+ |
+bool Combobox::InTextButton(const gfx::Point& point) { |
+ if (!HitTestPoint(point)) |
+ return false; |
+ |
+ if (style_ != STYLE_BUTTONS) |
+ return false; |
+ |
+ int x = point.x(); |
+ const gfx::ImageSkia* menu_button_image = |
+ menu_button_images_[false][Button::STATE_NORMAL][0]; |
+ return x < width() - menu_button_image->width(); |
+} |
+ |
+bool Combobox::InArrowButton(const gfx::Point& point) { |
+ if (!HitTestPoint(point)) |
+ return false; |
+ |
+ // When |style_| is not the button style, whole of this control functions as a |
+ // disclosure arrow button. |
+ if (style_ != STYLE_BUTTONS) |
+ return true; |
+ |
+ int x = point.x(); |
+ const gfx::ImageSkia* menu_button_image = |
+ menu_button_images_[false][Button::STATE_NORMAL][0]; |
+ return width() - menu_button_image->width() <= x && x < width(); |
+} |
+ |
} // namespace views |