| Index: ui/views/controls/combobox/combobox.cc
|
| diff --git a/ui/views/controls/combobox/combobox.cc b/ui/views/controls/combobox/combobox.cc
|
| index 5e487d27dcb36922868e4b49334caf2a333ee177..41e9938461f3bc23ee69f2a9847ace0ac9d6fbc3 100644
|
| --- a/ui/views/controls/combobox/combobox.cc
|
| +++ b/ui/views/controls/combobox/combobox.cc
|
| @@ -12,17 +12,24 @@
|
| #include "ui/base/resource/resource_bundle.h"
|
| #include "ui/events/event.h"
|
| #include "ui/events/keycodes/keyboard_codes.h"
|
| +#include "ui/gfx/animation/throb_animation.h"
|
| #include "ui/gfx/canvas.h"
|
| +#include "ui/gfx/image/image.h"
|
| +#include "ui/gfx/scoped_canvas.h"
|
| #include "ui/native_theme/native_theme.h"
|
| #include "ui/views/background.h"
|
| #include "ui/views/color_constants.h"
|
| +#include "ui/views/controls/button/custom_button.h"
|
| +#include "ui/views/controls/button/label_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"
|
| +#include "ui/views/controls/menu/menu_runner_handler.h"
|
| #include "ui/views/controls/menu/submenu_view.h"
|
| #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 {
|
| @@ -40,6 +47,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;
|
| @@ -49,6 +58,19 @@ 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_GRID(IDR_COMBOBOX_BUTTON_H);
|
| +const int kPressedBodyButtonImages[] = IMAGE_GRID(IDR_COMBOBOX_BUTTON_P);
|
| +
|
| +#define MENU_IMAGE_GRID(x) { \
|
| + x ## _MENU_TOP, x ## _MENU_CENTER, x ## _MENU_BOTTOM, }
|
| +
|
| +const int kMenuButtonImages[] = MENU_IMAGE_GRID(IDR_COMBOBOX_BUTTON);
|
| +const int kHoveredMenuButtonImages[] = MENU_IMAGE_GRID(IDR_COMBOBOX_BUTTON_H);
|
| +const int kPressedMenuButtonImages[] = MENU_IMAGE_GRID(IDR_COMBOBOX_BUTTON_P);
|
| +
|
| +#undef MENU_IMAGE_GRID
|
| +
|
| // The background to use for invalid comboboxes.
|
| class InvalidBackground : public Background {
|
| public:
|
| @@ -67,6 +89,23 @@ class InvalidBackground : public Background {
|
| DISALLOW_COPY_AND_ASSIGN(InvalidBackground);
|
| };
|
|
|
| +// The transparent button which holds a button state but is not rendered.
|
| +class TransparentButton : public CustomButton {
|
| + public:
|
| + TransparentButton(ButtonListener* listener)
|
| + : CustomButton(listener) {
|
| + SetAnimationDuration(LabelButton::kHoverAnimationDurationMs);
|
| + }
|
| + virtual ~TransparentButton() {}
|
| +
|
| + double GetAnimationValue() const {
|
| + return hover_animation_->GetCurrentValue();
|
| + }
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(TransparentButton);
|
| +};
|
| +
|
| // Returns the next or previous valid index (depending on |increment|'s value).
|
| // Skips separator or disabled indices. Returns -1 if there is no valid adjacent
|
| // index.
|
| @@ -82,6 +121,102 @@ 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,
|
| + size_t* num) {
|
| + DCHECK(num);
|
| + *num = 9;
|
| + 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,
|
| + size_t* num) {
|
| + DCHECK(num);
|
| + *num = 3;
|
| + 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 menu buttons.
|
| +std::vector<const gfx::ImageSkia*> GetMenuButtonImages(
|
| + bool focused,
|
| + Button::ButtonState state) {
|
| + const int* ids;
|
| + size_t num_ids;
|
| + ids = GetMenuButtonImageIds(focused, state, &num_ids);
|
| + 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++)
|
| + images.push_back(rb.GetImageSkiaNamed(ids[i]));
|
| + return images;
|
| +}
|
| +
|
| +// Paints three images in a column at the given location. The center image is
|
| +// stretched so as to fit the given height.
|
| +void PaintImagesVertically(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 arrow button.
|
| +void PaintArrowButton(
|
| + gfx::Canvas* canvas,
|
| + const std::vector<const gfx::ImageSkia*>& arrow_button_images,
|
| + int x, int height) {
|
| + PaintImagesVertically(canvas,
|
| + *arrow_button_images[0],
|
| + *arrow_button_images[1],
|
| + *arrow_button_images[2],
|
| + x, 0, arrow_button_images[0]->width(), height);
|
| +}
|
| +
|
| } // namespace
|
|
|
| // static
|
| @@ -92,17 +227,46 @@ const char Combobox::kViewClassName[] = "views/Combobox";
|
|
|
| Combobox::Combobox(ui::ComboboxModel* model)
|
| : model_(model),
|
| + style_(STYLE_SHOW_DROP_DOWN_ON_CLICK),
|
| 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),
|
| + text_button_(new TransparentButton(this)),
|
| + arrow_button_(new TransparentButton(this)) {
|
| model_->AddObserver(this);
|
| UpdateFromModel();
|
| set_focusable(true);
|
| - set_border(text_border_);
|
| + UpdateBorder();
|
| +
|
| + // Initialize the button images.
|
| + Button::ButtonState button_states[] = {
|
| + Button::STATE_DISABLED,
|
| + Button::STATE_NORMAL,
|
| + Button::STATE_HOVERED,
|
| + Button::STATE_PRESSED,
|
| + };
|
| + for (int i = 0; i < 2; i++) {
|
| + for (size_t state_index = 0; state_index < arraysize(button_states);
|
| + state_index++) {
|
| + Button::ButtonState state = button_states[state_index];
|
| + size_t num;
|
| + bool focused = !!i;
|
| + const int* ids = GetBodyButtonImageIds(focused, state, &num);
|
| + body_button_painters_[focused][state].reset(
|
| + Painter::CreateImageGridPainter(ids));
|
| + menu_button_images_[focused][state] = GetMenuButtonImages(focused, state);
|
| + }
|
| + }
|
| +
|
| + text_button_->SetVisible(true);
|
| + arrow_button_->SetVisible(true);
|
| + text_button_->set_focusable(false);
|
| + arrow_button_->set_focusable(false);
|
| + AddChildView(text_button_);
|
| + AddChildView(arrow_button_);
|
| }
|
|
|
| Combobox::~Combobox() {
|
| @@ -115,6 +279,16 @@ const gfx::Font& Combobox::GetFont() {
|
| return rb.GetFont(ui::ResourceBundle::BaseFont);
|
| }
|
|
|
| +void Combobox::SetStyle(Style style) {
|
| + if (style_ == style)
|
| + return;
|
| +
|
| + style_ = style;
|
| +
|
| + UpdateBorder();
|
| + PreferredSizeChanged();
|
| +}
|
| +
|
| void Combobox::ModelChanged() {
|
| selected_index_ = std::min(0, model_->GetItemCount());
|
| UpdateFromModel();
|
| @@ -145,13 +319,9 @@ void Combobox::SetInvalid(bool invalid) {
|
| return;
|
|
|
| invalid_ = invalid;
|
| - if (invalid_) {
|
| - text_border_->SetColor(kWarningColor);
|
| - set_background(new InvalidBackground());
|
| - } else {
|
| - text_border_->UseDefaultColor();
|
| - set_background(NULL);
|
| - }
|
| +
|
| + set_background(invalid_ ? new InvalidBackground() : NULL);
|
| + UpdateBorder();
|
| SchedulePaint();
|
| }
|
|
|
| @@ -161,6 +331,30 @@ ui::TextInputClient* Combobox::GetTextInputClient() {
|
| return selector_.get();
|
| }
|
|
|
| +void Combobox::Layout() {
|
| + PrefixDelegate::Layout();
|
| +
|
| + gfx::Insets insets = GetInsets();
|
| + int text_button_width = 0;
|
| + int arrow_button_width = 0;
|
| +
|
| + switch (style_) {
|
| + case STYLE_SHOW_DROP_DOWN_ON_CLICK: {
|
| + arrow_button_width = width();
|
| + break;
|
| + }
|
| + case STYLE_NOTIFY_ON_CLICK: {
|
| + arrow_button_width = GetDisclosureArrowLeftPadding() +
|
| + disclosure_arrow_->width() + GetDisclosureArrowRightPadding();
|
| + text_button_width = width() - arrow_button_width;
|
| + break;
|
| + }
|
| + }
|
| +
|
| + int arrow_button_x = std::max(0, text_button_width);
|
| + text_button_->SetBounds(0, 0, std::max(0, text_button_width), height());
|
| + arrow_button_->SetBounds(arrow_button_x, 0, arrow_button_width, height());
|
| +}
|
|
|
| bool Combobox::IsItemChecked(int id) const {
|
| return false;
|
| @@ -206,9 +400,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,22 +418,6 @@ bool Combobox::SkipDefaultKeyEventProcessing(const ui::KeyEvent& e) {
|
| return dropdown_open_;
|
| }
|
|
|
| -bool Combobox::OnMousePressed(const ui::MouseEvent& mouse_event) {
|
| - RequestFocus();
|
| - const base::TimeDelta delta = base::Time::Now() - closed_time_;
|
| - if (mouse_event.IsLeftMouseButton() &&
|
| - (delta.InMilliseconds() > kMinimumMsBetweenButtonClicks)) {
|
| - UpdateFromModel();
|
| - ShowDropDownMenu(ui::MENU_SOURCE_MOUSE);
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool Combobox::OnMouseDragged(const ui::MouseEvent& mouse_event) {
|
| - return true;
|
| -}
|
| -
|
| bool Combobox::OnKeyPressed(const ui::KeyEvent& e) {
|
| // TODO(oshima): handle IME.
|
| DCHECK_EQ(e.type(), ui::ET_KEY_PRESSED);
|
| @@ -285,6 +462,20 @@ 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:
|
| + if (style_ == STYLE_NOTIFY_ON_CLICK) {
|
| + // When pressing space, the click event will be raised after the key is
|
| + // released.
|
| + text_button_->SetState(Button::STATE_PRESSED);
|
| + }
|
| + break;
|
| +
|
| + // Click the button only when the button style mode.
|
| + case ui::VKEY_RETURN:
|
| + HandleClickEvent();
|
| + break;
|
| +
|
| default:
|
| return false;
|
| }
|
| @@ -302,23 +493,29 @@ bool Combobox::OnKeyPressed(const ui::KeyEvent& e) {
|
| }
|
|
|
| bool Combobox::OnKeyReleased(const ui::KeyEvent& e) {
|
| - return false; // crbug.com/127520
|
| -}
|
| + if (style_ != STYLE_NOTIFY_ON_CLICK)
|
| + return false; // crbug.com/127520
|
|
|
| -void Combobox::OnGestureEvent(ui::GestureEvent* gesture) {
|
| - if (gesture->type() == ui::ET_GESTURE_TAP) {
|
| - UpdateFromModel();
|
| - ShowDropDownMenu(ui::MENU_SOURCE_TOUCH);
|
| - gesture->StopPropagation();
|
| - return;
|
| - }
|
| - View::OnGestureEvent(gesture);
|
| + if (e.key_code() == ui::VKEY_SPACE)
|
| + HandleClickEvent();
|
| +
|
| + return false;
|
| }
|
|
|
| void Combobox::OnPaint(gfx::Canvas* canvas) {
|
| - OnPaintBackground(canvas);
|
| - PaintText(canvas);
|
| - OnPaintBorder(canvas);
|
| + switch (style_) {
|
| + case STYLE_SHOW_DROP_DOWN_ON_CLICK: {
|
| + OnPaintBackground(canvas);
|
| + PaintText(canvas);
|
| + OnPaintBorder(canvas);
|
| + break;
|
| + }
|
| + case STYLE_NOTIFY_ON_CLICK: {
|
| + PaintButtons(canvas);
|
| + PaintText(canvas);
|
| + break;
|
| + }
|
| + }
|
| }
|
|
|
| void Combobox::OnFocus() {
|
| @@ -348,6 +545,28 @@ void Combobox::OnModelChanged() {
|
| ModelChanged();
|
| }
|
|
|
| +void Combobox::ButtonPressed(Button* sender, const ui::Event& event) {
|
| + RequestFocus();
|
| +
|
| + if (sender == text_button_) {
|
| + HandleClickEvent();
|
| + } else {
|
| + DCHECK_EQ(arrow_button_, sender);
|
| + // TODO(hajimehoshi): Fix the problem that the arrow button blinks when
|
| + // cliking this while the dropdown menu is opened.
|
| + const base::TimeDelta delta = base::Time::Now() - closed_time_;
|
| + if (delta.InMilliseconds() <= kMinimumMsBetweenButtonClicks)
|
| + return;
|
| +
|
| + ui::MenuSourceType source_type = ui::MENU_SOURCE_MOUSE;
|
| + if (event.IsKeyEvent())
|
| + source_type = ui::MENU_SOURCE_KEYBOARD;
|
| + else if (event.IsGestureEvent() || event.IsTouchEvent())
|
| + source_type = ui::MENU_SOURCE_TOUCH;
|
| + ShowDropDownMenu(source_type);
|
| + }
|
| +}
|
| +
|
| void Combobox::UpdateFromModel() {
|
| int max_width = 0;
|
| const gfx::Font& font = Combobox::GetFont();
|
| @@ -376,6 +595,15 @@ void Combobox::UpdateFromModel() {
|
| content_size_.SetSize(max_width, font.GetHeight());
|
| }
|
|
|
| +void Combobox::UpdateBorder() {
|
| + FocusableBorder* border = new FocusableBorder();
|
| + if (style_ == STYLE_NOTIFY_ON_CLICK)
|
| + border->SetInsets(8, 13, 8, 13);
|
| + if (invalid_)
|
| + border->SetColor(kWarningColor);
|
| + set_border(border);
|
| +}
|
| +
|
| void Combobox::AdjustBoundsForRTLUI(gfx::Rect* rect) const {
|
| rect->set_x(GetMirroredXForRect(*rect));
|
| }
|
| @@ -383,7 +611,7 @@ void Combobox::AdjustBoundsForRTLUI(gfx::Rect* rect) const {
|
| void Combobox::PaintText(gfx::Canvas* canvas) {
|
| gfx::Insets insets = GetInsets();
|
|
|
| - canvas->Save();
|
| + gfx::ScopedCanvas scoped_canvas(canvas);
|
| canvas->ClipRect(GetContentsBounds());
|
|
|
| int x = insets.left();
|
| @@ -399,8 +627,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);
|
| @@ -411,7 +639,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());
|
| @@ -423,8 +652,63 @@ void Combobox::PaintText(gfx::Canvas* canvas) {
|
| paint.setXfermodeMode(SkXfermode::kDstOut_Mode);
|
| canvas->DrawImageInt(*disclosure_arrow_, arrow_bounds.x(), arrow_bounds.y(),
|
| paint);
|
| +}
|
| +
|
| +void Combobox::PaintButtons(gfx::Canvas* canvas) {
|
| + DCHECK(style_ == STYLE_NOTIFY_ON_CLICK);
|
| +
|
| + gfx::ScopedCanvas scoped_canvas(canvas);
|
| + if (base::i18n::IsRTL()) {
|
| + canvas->Translate(gfx::Vector2d(width(), 0));
|
| + canvas->Scale(-1, 1);
|
| + }
|
|
|
| - canvas->Restore();
|
| + bool focused = HasFocus();
|
| + 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_hover_alpha =
|
| + text_button_->state() == Button::STATE_PRESSED ? 0 :
|
| + static_cast<int>(static_cast<TransparentButton*>(text_button_)->
|
| + GetAnimationValue() * 255);
|
| + if (text_button_hover_alpha < 255) {
|
| + canvas->SaveLayerAlpha(255 - text_button_hover_alpha);
|
| + Painter* text_button_painter =
|
| + body_button_painters_[focused][
|
| + text_button_->state() == Button::STATE_HOVERED ?
|
| + Button::STATE_NORMAL : text_button_->state()].get();
|
| + Painter::PaintPainterAt(canvas, text_button_painter,
|
| + gfx::Rect(0, 0, text_button_->width(), height()));
|
| + canvas->Restore();
|
| + }
|
| + if (0 < text_button_hover_alpha) {
|
| + canvas->SaveLayerAlpha(text_button_hover_alpha);
|
| + Painter* text_button_hovered_painter =
|
| + body_button_painters_[focused][Button::STATE_HOVERED].get();
|
| + Painter::PaintPainterAt(canvas, text_button_hovered_painter,
|
| + gfx::Rect(0, 0, text_button_->width(), height()));
|
| + canvas->Restore();
|
| + }
|
| +
|
| + int arrow_button_hover_alpha =
|
| + arrow_button_->state() == Button::STATE_PRESSED ? 0 :
|
| + static_cast<int>(static_cast<TransparentButton*>(arrow_button_)->
|
| + GetAnimationValue() * 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();
|
| + }
|
| }
|
|
|
| void Combobox::ShowDropDownMenu(ui::MenuSourceType source_type) {
|
| @@ -434,8 +718,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());
|
| @@ -448,16 +732,25 @@ 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());
|
|
|
| + Button::ButtonState original_state = Button::STATE_NORMAL;
|
| + if (arrow_button_) {
|
| + original_state = arrow_button_->state();
|
| + arrow_button_->SetState(Button::STATE_PRESSED);
|
| + }
|
| dropdown_open_ = true;
|
| if (dropdown_list_menu_runner_->RunMenuAt(GetWidget(), NULL, bounds,
|
| - MenuItemView::TOPLEFT, source_type, MenuRunner::COMBOBOX) ==
|
| - MenuRunner::MENU_DELETED)
|
| + MenuItemView::TOPLEFT, source_type,
|
| + MenuRunner::COMBOBOX) ==
|
| + MenuRunner::MENU_DELETED) {
|
| return;
|
| + }
|
| dropdown_open_ = false;
|
| + if (arrow_button_)
|
| + arrow_button_->SetState(original_state);
|
| closed_time_ = base::Time::Now();
|
|
|
| // Need to explicitly clear mouse handler so that events get sent
|
| @@ -482,4 +775,34 @@ int Combobox::MenuCommandToIndex(int menu_command_id) const {
|
| return index;
|
| }
|
|
|
| +int Combobox::GetDisclosureArrowLeftPadding() const {
|
| + switch (style_) {
|
| + case STYLE_SHOW_DROP_DOWN_ON_CLICK:
|
| + return kDisclosureArrowLeftPadding;
|
| + case STYLE_NOTIFY_ON_CLICK:
|
| + return kDisclosureArrowButtonLeftPadding;
|
| + }
|
| + NOTREACHED();
|
| + return 0;
|
| +}
|
| +
|
| +int Combobox::GetDisclosureArrowRightPadding() const {
|
| + switch (style_) {
|
| + case STYLE_SHOW_DROP_DOWN_ON_CLICK:
|
| + return kDisclosureArrowRightPadding;
|
| + case STYLE_NOTIFY_ON_CLICK:
|
| + return kDisclosureArrowButtonRightPadding;
|
| + }
|
| + NOTREACHED();
|
| + return 0;
|
| +}
|
| +
|
| +void Combobox::HandleClickEvent() {
|
| + if (style_ != STYLE_NOTIFY_ON_CLICK)
|
| + return;
|
| +
|
| + if (listener_)
|
| + listener_->OnComboboxTextButtonClicked(this);
|
| +}
|
| +
|
| } // namespace views
|
|
|