diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-05 04:19:35 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-05 04:19:35 +0000 |
commit | 1966d6d1568191bb984efd30f20d884553e35450 (patch) | |
tree | cac5a77663b4c5a976970be83ad9dff926ed4599 | |
parent | fc18b9eacd5657f6ebc3b5f9e6a72ddcf751896e (diff) | |
download | chromium_src-1966d6d1568191bb984efd30f20d884553e35450.zip chromium_src-1966d6d1568191bb984efd30f20d884553e35450.tar.gz chromium_src-1966d6d1568191bb984efd30f20d884553e35450.tar.bz2 |
Removes FocusBorder from views
This patch removes FocusBorder from View along with
View::OnPaintFocusBorder. Views that want to render focus and that
need to allow overriding get a Painter that is responsible for
rendering the focus. Views that render focus differently must override
OnFocus/OnBlur to SchedulePaint the necessary region.
This patch simplifies View and cleans things up for views that don't
ever want to paint focus, or paint focus differently (say TableView,
or Textfield). On the down side it does mean any view that is
focusable needs to override a few more additional methods. It was easy
to get this wrong previously though as a common pattern is to
override OnPaint and not invoke View::OnPaint.
BUG=none
TEST=none
R=ben@chromium.org
Review URL: https://codereview.chromium.org/105013002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@238888 0039d316-1c4b-4281-b951-d872f2087c98
60 files changed, 532 insertions, 369 deletions
diff --git a/ash/shelf/alternate_app_list_button.cc b/ash/shelf/alternate_app_list_button.cc index 4ce2834..bf442d1 100644 --- a/ash/shelf/alternate_app_list_button.cc +++ b/ash/shelf/alternate_app_list_button.cc @@ -4,8 +4,10 @@ #include "ash/shelf/alternate_app_list_button.h" +#include "ash/ash_constants.h" #include "ash/ash_switches.h" #include "ash/launcher/launcher_types.h" +#include "ash/shelf/shelf_button.h" #include "ash/shelf/shelf_button_host.h" #include "ash/shelf/shelf_layout_manager.h" #include "ash/shelf/shelf_widget.h" @@ -22,6 +24,7 @@ #include "ui/gfx/canvas.h" #include "ui/gfx/image/image_skia_operations.h" #include "ui/views/controls/button/image_button.h" +#include "ui/views/painter.h" namespace ash { namespace internal { @@ -39,6 +42,8 @@ AlternateAppListButton::AlternateAppListButton(views::ButtonListener* listener, SetAccessibleName(l10n_util::GetStringUTF16(IDS_AURA_APP_LIST_TITLE)); SetSize(gfx::Size(ShelfLayoutManager::kShelfSize, ShelfLayoutManager::kShelfSize)); + SetFocusPainter(views::Painter::CreateSolidFocusPainter( + kFocusBorderColor, gfx::Insets(1, 1, 1, 1))); } AlternateAppListButton::~AlternateAppListButton() { @@ -156,7 +161,7 @@ void AlternateAppListButton::OnPaint(gfx::Canvas* canvas) { forground_bounds.x(), forground_bounds.y()); - OnPaintFocusBorder(canvas); + views::Painter::PaintFocusPainter(this, canvas, focus_painter()); } void AlternateAppListButton::GetAccessibleState( diff --git a/ash/shelf/app_list_button.cc b/ash/shelf/app_list_button.cc index a9612bf..697ed77 100644 --- a/ash/shelf/app_list_button.cc +++ b/ash/shelf/app_list_button.cc @@ -6,6 +6,7 @@ #include <vector> +#include "ash/ash_constants.h" #include "ash/launcher/launcher_types.h" #include "ash/shelf/shelf_button_host.h" #include "grit/ash_resources.h" @@ -17,6 +18,7 @@ #include "ui/compositor/layer_animation_element.h" #include "ui/compositor/layer_animation_sequence.h" #include "ui/compositor/scoped_layer_animation_settings.h" +#include "ui/views/painter.h" namespace ash { namespace internal { @@ -43,6 +45,8 @@ AppListButton::AppListButton(views::ButtonListener* listener, SetAccessibleName(l10n_util::GetStringUTF16(IDS_AURA_APP_LIST_TITLE)); SetSize(gfx::Size(kLauncherPreferredSize, kLauncherPreferredSize)); SetImageAlignment(ImageButton::ALIGN_CENTER, ImageButton::ALIGN_TOP); + SetFocusPainter(views::Painter::CreateSolidFocusPainter( + kFocusBorderColor, gfx::Insets(1, 1, 1, 1))); } AppListButton::~AppListButton() { diff --git a/ash/shelf/shelf_button.cc b/ash/shelf/shelf_button.cc index 4b10b8f..93a44e1 100644 --- a/ash/shelf/shelf_button.cc +++ b/ash/shelf/shelf_button.cc @@ -6,6 +6,7 @@ #include <algorithm> +#include "ash/ash_constants.h" #include "ash/ash_switches.h" #include "ash/shelf/shelf_button_host.h" #include "ash/shelf/shelf_layout_manager.h" @@ -470,6 +471,15 @@ void ShelfButton::OnBlur() { CustomButton::OnBlur(); } +void ShelfButton::OnPaint(gfx::Canvas* canvas) { + CustomButton::OnPaint(canvas); + if (HasFocus()) { + gfx::Rect paint_bounds(GetLocalBounds()); + paint_bounds.Inset(1, 1, 1, 1); + canvas->DrawSolidFocusRect(paint_bounds, kFocusBorderColor); + } +} + void ShelfButton::OnGestureEvent(ui::GestureEvent* event) { switch (event->type()) { case ui::ET_GESTURE_TAP_DOWN: diff --git a/ash/shelf/shelf_button.h b/ash/shelf/shelf_button.h index 1bfc510..60158f2 100644 --- a/ash/shelf/shelf_button.h +++ b/ash/shelf/shelf_button.h @@ -107,6 +107,7 @@ class ASH_EXPORT ShelfButton : public views::CustomButton { virtual void ChildPreferredSizeChanged(views::View* child) OVERRIDE; virtual void OnFocus() OVERRIDE; virtual void OnBlur() OVERRIDE; + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; // ui::EventHandler overrides: virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE; diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc index 274014f..c31f63a 100644 --- a/ash/shelf/shelf_view.cc +++ b/ash/shelf/shelf_view.cc @@ -51,7 +51,6 @@ #include "ui/views/controls/menu/menu_model_adapter.h" #include "ui/views/controls/menu/menu_runner.h" #include "ui/views/focus/focus_search.h" -#include "ui/views/focus_border.h" #include "ui/views/view_model.h" #include "ui/views/view_model_utils.h" #include "ui/views/widget/widget.h" @@ -932,9 +931,6 @@ views::View* ShelfView::CreateViewForItem(const LauncherItem& item) { break; } view->set_context_menu_controller(this); - view->set_focus_border(views::FocusBorder::CreateSolidFocusBorder( - kFocusBorderColor, - gfx::Insets(1, 1, 1, 1))); DCHECK(view); ConfigureChildView(view); diff --git a/ash/system/tray/actionable_view.cc b/ash/system/tray/actionable_view.cc index 9a21b04..40d90b4 100644 --- a/ash/system/tray/actionable_view.cc +++ b/ash/system/tray/actionable_view.cc @@ -22,12 +22,16 @@ ActionableView::ActionableView() ActionableView::~ActionableView() { } -void ActionableView::DrawBorder(gfx::Canvas* canvas, const gfx::Rect& bounds) { - gfx::Rect rect = bounds; +void ActionableView::OnPaintFocus(gfx::Canvas* canvas) { + gfx::Rect rect(GetFocusBounds()); rect.Inset(1, 1, 3, 2); canvas->DrawSolidFocusRect(rect, kFocusBorderColor); } +gfx::Rect ActionableView::GetFocusBounds() { + return GetLocalBounds(); +} + const char* ActionableView::GetClassName() const { return kViewClassName; } @@ -59,9 +63,26 @@ void ActionableView::SetAccessibleName(const base::string16& name) { accessible_name_ = name; } -void ActionableView::OnPaintFocusBorder(gfx::Canvas* canvas) { - if (HasFocus()) - DrawBorder(canvas, GetLocalBounds()); +void ActionableView::GetAccessibleState(ui::AccessibleViewState* state) { + state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; + state->name = accessible_name_; +} + +void ActionableView::OnPaint(gfx::Canvas* canvas) { + View::OnPaint(canvas); + OnPaintFocus(canvas); +} + +void ActionableView::OnFocus() { + View::OnFocus(); + // We render differently when focused. + SchedulePaint(); +} + +void ActionableView::OnBlur() { + View::OnBlur(); + // We render differently when focused. + SchedulePaint(); } void ActionableView::OnGestureEvent(ui::GestureEvent* event) { @@ -69,10 +90,5 @@ void ActionableView::OnGestureEvent(ui::GestureEvent* event) { event->SetHandled(); } -void ActionableView::GetAccessibleState(ui::AccessibleViewState* state) { - state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; - state->name = accessible_name_; -} - } // namespace internal } // namespace ash diff --git a/ash/system/tray/actionable_view.h b/ash/system/tray/actionable_view.h index 0d0f1a1..f2b3ec1 100644 --- a/ash/system/tray/actionable_view.h +++ b/ash/system/tray/actionable_view.h @@ -21,6 +21,8 @@ namespace internal { // Exported for SystemTray. class ASH_EXPORT ActionableView : public views::View { public: + static const char kViewClassName[]; + ActionableView(); virtual ~ActionableView(); @@ -28,10 +30,11 @@ class ASH_EXPORT ActionableView : public views::View { void SetAccessibleName(const base::string16& name); const base::string16& accessible_name() const { return accessible_name_; } - static const char kViewClassName[]; - protected: - void DrawBorder(gfx::Canvas* canvas, const gfx::Rect& bounds); + void OnPaintFocus(gfx::Canvas* canvas); + + // Returns the bounds to paint the focus rectangle in. + virtual gfx::Rect GetFocusBounds(); // Performs an action when user clicks on the view (on mouse-press event), or // presses a key when this view is in focus. Returns true if the event has @@ -45,7 +48,9 @@ class ASH_EXPORT ActionableView : public views::View { virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE; virtual void OnMouseCaptureLost() OVERRIDE; virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; - virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE; + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; + virtual void OnFocus() OVERRIDE; + virtual void OnBlur() OVERRIDE; // Overridden from ui::EventHandler. virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE; diff --git a/ash/system/tray/fixed_sized_scroll_view.cc b/ash/system/tray/fixed_sized_scroll_view.cc index 59b524b..d3fff9ad 100644 --- a/ash/system/tray/fixed_sized_scroll_view.cc +++ b/ash/system/tray/fixed_sized_scroll_view.cc @@ -9,7 +9,6 @@ namespace internal { FixedSizedScrollView::FixedSizedScrollView() { set_notify_enter_exit_on_child(true); - set_focus_border(NULL); } FixedSizedScrollView::~FixedSizedScrollView() { @@ -54,9 +53,5 @@ void FixedSizedScrollView::OnBoundsChanged(const gfx::Rect& previous_bounds) { contents()->SetBoundsRect(bounds); } -void FixedSizedScrollView::OnPaintFocusBorder(gfx::Canvas* canvas) { - // Do not paint the focus border. -} - } // namespace internal } // namespace ash diff --git a/ash/system/tray/fixed_sized_scroll_view.h b/ash/system/tray/fixed_sized_scroll_view.h index c5d9bc0..aff53c2 100644 --- a/ash/system/tray/fixed_sized_scroll_view.h +++ b/ash/system/tray/fixed_sized_scroll_view.h @@ -33,7 +33,6 @@ class FixedSizedScrollView : public views::ScrollView { protected: // Overridden from views::View: virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE; - virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE; private: gfx::Size fixed_size_; diff --git a/ash/system/tray/tray_background_view.cc b/ash/system/tray/tray_background_view.cc index 3939b70..9eb80c1 100644 --- a/ash/system/tray/tray_background_view.cc +++ b/ash/system/tray/tray_background_view.cc @@ -379,14 +379,6 @@ void TrayBackgroundView::ChildPreferredSizeChanged(views::View* child) { PreferredSizeChanged(); } -void TrayBackgroundView::OnPaintFocusBorder(gfx::Canvas* canvas) { - // The tray itself expands to the right and bottom edge of the screen to make - // sure clicking on the edges brings up the popup. However, the focus border - // should be only around the container. - if (HasFocus()) - DrawBorder(canvas, GetContentsBounds()); -} - void TrayBackgroundView::GetAccessibleState(ui::AccessibleViewState* state) { state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON; state->name = GetAccessibleNameForTray(); @@ -403,6 +395,13 @@ bool TrayBackgroundView::PerformAction(const ui::Event& event) { return false; } +gfx::Rect TrayBackgroundView::GetFocusBounds() { + // The tray itself expands to the right and bottom edge of the screen to make + // sure clicking on the edges brings up the popup. However, the focus border + // should be only around the container. + return GetContentsBounds(); +} + void TrayBackgroundView::UpdateBackground(int alpha) { // The animator should never fire when the alternate shelf layout is used. if (!background_ || draw_background_as_active_) diff --git a/ash/system/tray/tray_background_view.h b/ash/system/tray/tray_background_view.h index b459684..0f6e2f7 100644 --- a/ash/system/tray/tray_background_view.h +++ b/ash/system/tray/tray_background_view.h @@ -70,12 +70,12 @@ class ASH_EXPORT TrayBackgroundView : public ActionableView, virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE; virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; virtual void ChildPreferredSizeChanged(views::View* child) OVERRIDE; - virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE; virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; virtual void AboutToRequestFocusFromTabTraversal(bool reverse) OVERRIDE; // Overridden from internal::ActionableView. virtual bool PerformAction(const ui::Event& event) OVERRIDE; + virtual gfx::Rect GetFocusBounds() OVERRIDE; // Overridden from internal::BackgroundAnimatorDelegate. virtual void UpdateBackground(int alpha) OVERRIDE; diff --git a/ash/system/tray/tray_popup_header_button.cc b/ash/system/tray/tray_popup_header_button.cc index ceeda04..e9430e5 100644 --- a/ash/system/tray/tray_popup_header_button.cc +++ b/ash/system/tray/tray_popup_header_button.cc @@ -8,6 +8,7 @@ #include "ash/system/tray/tray_constants.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas.h" +#include "ui/views/painter.h" namespace ash { namespace internal { @@ -38,9 +39,9 @@ TrayPopupHeaderButton::TrayPopupHeaderButton(views::ButtonListener* listener, set_focusable(true); set_request_focus_on_press(false); - set_focus_border(views::FocusBorder::CreateSolidFocusBorder( - kFocusBorderColor, - gfx::Insets(1, 2, 2, 3))); + SetFocusPainter(views::Painter::CreateSolidFocusPainter( + kFocusBorderColor, + gfx::Insets(1, 2, 2, 3))); } TrayPopupHeaderButton::~TrayPopupHeaderButton() {} diff --git a/ash/system/tray/tray_popup_label_button.cc b/ash/system/tray/tray_popup_label_button.cc index aa72a3b..2f97c37 100644 --- a/ash/system/tray/tray_popup_label_button.cc +++ b/ash/system/tray/tray_popup_label_button.cc @@ -8,6 +8,7 @@ #include "ash/system/tray/tray_popup_label_button_border.h" #include "ui/gfx/canvas.h" #include "ui/gfx/rect.h" +#include "ui/views/painter.h" namespace ash { namespace internal { @@ -20,7 +21,7 @@ TrayPopupLabelButton::TrayPopupLabelButton(views::ButtonListener* listener, set_request_focus_on_press(false); set_animate_on_state_change(false); SetHorizontalAlignment(gfx::ALIGN_CENTER); - set_focus_border(views::FocusBorder::CreateSolidFocusBorder( + SetFocusPainter(views::Painter::CreateSolidFocusPainter( kFocusBorderColor, gfx::Insets(1, 1, 2, 2))); } diff --git a/ash/system/tray/tray_popup_label_button.h b/ash/system/tray/tray_popup_label_button.h index 83ff439..a1f9db6 100644 --- a/ash/system/tray/tray_popup_label_button.h +++ b/ash/system/tray/tray_popup_label_button.h @@ -21,7 +21,6 @@ class TrayPopupLabelButton : public views::LabelButton { virtual ~TrayPopupLabelButton(); private: - DISALLOW_COPY_AND_ASSIGN(TrayPopupLabelButton); }; diff --git a/chrome/browser/chromeos/ui/focus_ring_layer.cc b/chrome/browser/chromeos/ui/focus_ring_layer.cc index f1420d4..303d594 100644 --- a/chrome/browser/chromeos/ui/focus_ring_layer.cc +++ b/chrome/browser/chromeos/ui/focus_ring_layer.cc @@ -80,9 +80,8 @@ void FocusRingLayer::SetForView(views::View* view) { view_bounds.Inset(2, 2, 2, 2); } - // Workarounds for system tray items that has a customized - // OnPaintFocusBorder. The insets here must be consistent with - // the ones used in OnPaintFocusBorder and DrawBorder. + // Workarounds for system tray items that have customized focus borders. The + // insets here must be consistent with the ones used by those classes. if (view->GetClassName() == ash::internal::ActionableView::kViewClassName) { view_bounds = view->GetLocalBounds(); diff --git a/chrome/browser/ui/views/autofill/autofill_dialog_views.cc b/chrome/browser/ui/views/autofill/autofill_dialog_views.cc index e0990a8..64cdc04 100644 --- a/chrome/browser/ui/views/autofill/autofill_dialog_views.cc +++ b/chrome/browser/ui/views/autofill/autofill_dialog_views.cc @@ -60,6 +60,7 @@ #include "ui/views/layout/fill_layout.h" #include "ui/views/layout/grid_layout.h" #include "ui/views/layout/layout_constants.h" +#include "ui/views/painter.h" #include "ui/views/widget/widget.h" #include "ui/views/window/dialog_client_view.h" @@ -476,11 +477,8 @@ AutofillDialogViews::AccountChooser::AccountChooser( menu_button_->set_background(NULL); menu_button_->set_border(NULL); gfx::Insets insets = GetInsets(); - menu_button_->set_focus_border( - views::FocusBorder::CreateDashedFocusBorder(insets.left(), - insets.top(), - insets.right(), - insets.bottom())); + menu_button_->SetFocusPainter( + views::Painter::CreateDashedFocusPainterWithInsets(insets)); menu_button_->set_focusable(true); AddChildView(menu_button_); @@ -937,11 +935,8 @@ AutofillDialogViews::SuggestedButton::SuggestedButton( gfx::Insets insets = GetInsets(); insets += gfx::Insets(-kFocusBorderWidth, -kFocusBorderWidth, -kFocusBorderWidth, -kFocusBorderWidth); - set_focus_border( - views::FocusBorder::CreateDashedFocusBorder(insets.left(), - insets.top(), - insets.right(), - insets.bottom())); + SetFocusPainter( + views::Painter::CreateDashedFocusPainterWithInsets(insets)); set_focusable(true); } @@ -966,7 +961,7 @@ void AutofillDialogViews::SuggestedButton::OnPaint(gfx::Canvas* canvas) { const gfx::Insets insets = GetInsets(); canvas->DrawImageInt(*rb.GetImageSkiaNamed(ResourceIDForState()), insets.left(), insets.top()); - views::View::OnPaintFocusBorder(canvas); + views::Painter::PaintFocusPainter(this, canvas, focus_painter()); } int AutofillDialogViews::SuggestedButton::ResourceIDForState() const { diff --git a/chrome/browser/ui/views/autofill/tooltip_icon.cc b/chrome/browser/ui/views/autofill/tooltip_icon.cc index e0f4a68..4fd2a67 100644 --- a/chrome/browser/ui/views/autofill/tooltip_icon.cc +++ b/chrome/browser/ui/views/autofill/tooltip_icon.cc @@ -10,8 +10,8 @@ #include "grit/theme_resources.h" #include "ui/base/resource/resource_bundle.h" #include "ui/views/bubble/bubble_frame_view.h" -#include "ui/views/focus_border.h" #include "ui/views/mouse_watcher_view_host.h" +#include "ui/views/painter.h" namespace autofill { @@ -79,9 +79,8 @@ void TooltipIcon::OnMouseExited(const ui::MouseEvent& event) { } void TooltipIcon::OnBoundsChanged(const gfx::Rect& prev_bounds) { - gfx::Insets insets = GetPreferredInsets(this); - set_focus_border(views::FocusBorder::CreateDashedFocusBorder( - insets.left(), insets.top(), insets.right(), insets.bottom())); + SetFocusPainter(views::Painter::CreateDashedFocusPainterWithInsets( + GetPreferredInsets(this))); } void TooltipIcon::OnFocus() { diff --git a/chrome/browser/ui/views/autofill/tooltip_icon.h b/chrome/browser/ui/views/autofill/tooltip_icon.h index 50b88b7..5d9ff3d 100644 --- a/chrome/browser/ui/views/autofill/tooltip_icon.h +++ b/chrome/browser/ui/views/autofill/tooltip_icon.h @@ -21,11 +21,11 @@ class InfoBubble; class TooltipIcon : public views::ImageView, public views::MouseWatcherListener { public: + static const char kViewClassName[]; + explicit TooltipIcon(const base::string16& tooltip); virtual ~TooltipIcon(); - static const char kViewClassName[]; - // views::ImageView: virtual const char* GetClassName() const OVERRIDE; virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE; diff --git a/chrome/browser/ui/views/desktop_media_picker_views.cc b/chrome/browser/ui/views/desktop_media_picker_views.cc index 560fad1..116014d 100644 --- a/chrome/browser/ui/views/desktop_media_picker_views.cc +++ b/chrome/browser/ui/views/desktop_media_picker_views.cc @@ -12,12 +12,12 @@ #include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" #include "ui/events/keycodes/keyboard_codes.h" +#include "ui/gfx/canvas.h" #include "ui/native_theme/native_theme.h" #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" #include "ui/views/controls/scroll_view.h" #include "ui/views/corewm/shadow_types.h" -#include "ui/views/focus_border.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/layout_constants.h" #include "ui/views/widget/widget.h" @@ -85,7 +85,9 @@ class DesktopMediaSourceView : public views::View { virtual void Layout() OVERRIDE; virtual views::View* GetSelectedViewForGroup(int group) OVERRIDE; virtual bool IsGroupFocusTraversable() const OVERRIDE; + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; virtual void OnFocus() OVERRIDE; + virtual void OnBlur() OVERRIDE; virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; private: @@ -264,10 +266,6 @@ void DesktopMediaSourceView::Layout() { kThumbnailWidth, kThumbnailHeight); label_->SetBounds(kThumbnailMargin, kThumbnailHeight + kThumbnailMargin, kThumbnailWidth, kLabelHeight); - - set_focus_border(views::FocusBorder::CreateDashedFocusBorder( - kThumbnailMargin / 2, kThumbnailMargin / 2, - kThumbnailMargin / 2, kThumbnailMargin / 2)); } views::View* DesktopMediaSourceView::GetSelectedViewForGroup(int group) { @@ -290,10 +288,27 @@ bool DesktopMediaSourceView::IsGroupFocusTraversable() const { return false; } +void DesktopMediaSourceView::OnPaint(gfx::Canvas* canvas) { + View::OnPaint(canvas); + if (HasFocus()) { + gfx::Rect bounds(GetLocalBounds()); + bounds.Inset(kThumbnailMargin / 2, kThumbnailMargin / 2); + canvas->DrawFocusRect(bounds); + } +} + void DesktopMediaSourceView::OnFocus() { View::OnFocus(); SetSelected(true); ScrollRectToVisible(gfx::Rect(size())); + // We paint differently when focused. + SchedulePaint(); +} + +void DesktopMediaSourceView::OnBlur() { + View::OnBlur(); + // We paint differently when focused. + SchedulePaint(); } bool DesktopMediaSourceView::OnMousePressed(const ui::MouseEvent& event) { diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h index e088e3a..f983329 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.h +++ b/chrome/browser/ui/views/location_bar/location_bar_view.h @@ -223,9 +223,6 @@ class LocationBarView : public LocationBar, virtual void Layout() OVERRIDE; virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; - // No focus border for the location bar, the caret is enough. - virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE {} - // Set if we should show a focus rect while the location entry field is // focused. Used when the toolbar is in full keyboard accessibility mode. // Repaints if necessary. diff --git a/chrome/browser/ui/views/new_avatar_button.cc b/chrome/browser/ui/views/new_avatar_button.cc index 5e19334..feb5324 100644 --- a/chrome/browser/ui/views/new_avatar_button.cc +++ b/chrome/browser/ui/views/new_avatar_button.cc @@ -113,7 +113,7 @@ void NewAvatarButton::OnPaint(gfx::Canvas* canvas) { // From TextButton::PaintButton, draw everything but the text. OnPaintBackground(canvas); OnPaintBorder(canvas); - OnPaintFocusBorder(canvas); + views::Painter::PaintFocusPainter(this, canvas, focus_painter()); gfx::Rect rect; // In RTL languages the marker gets drawn leftmost, so account for its offset. diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index eafc48d..84706b5 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc @@ -631,8 +631,6 @@ TabStrip::TabStrip(TabStripController* controller) mouse_move_count_(0), immersive_style_(false) { Init(); - // TODO(sky): temporary work around for 323255. - set_focus_border(NULL); } TabStrip::~TabStrip() { diff --git a/chrome/browser/ui/views/toolbar/back_button.cc b/chrome/browser/ui/views/toolbar/back_button.cc index 1e4c4a4..97d9555 100644 --- a/chrome/browser/ui/views/toolbar/back_button.cc +++ b/chrome/browser/ui/views/toolbar/back_button.cc @@ -4,8 +4,9 @@ #include "chrome/browser/ui/views/toolbar/back_button.h" +#include "ui/gfx/insets.h" #include "ui/views/controls/button/label_button_border.h" -#include "ui/views/focus_border.h" +#include "ui/views/painter.h" BackButton::BackButton(views::ButtonListener* listener, ui::MenuModel* model) @@ -36,9 +37,9 @@ void BackButton::SetLeadingMargin(int margin) { // TODO(gbillock): Refactor this magic number somewhere global to views, // probably a FocusBorder constant. const int kFocusRectInset = 3; - set_focus_border(views::FocusBorder::CreateDashedFocusBorder( - kFocusRectInset + margin, kFocusRectInset, - kFocusRectInset, kFocusRectInset)); + SetFocusPainter(views::Painter::CreateDashedFocusPainterWithInsets( + gfx::Insets(kFocusRectInset, kFocusRectInset + margin, + kFocusRectInset, kFocusRectInset))); margin_leading_ = margin; InvalidateLayout(); diff --git a/chrome/browser/ui/views/toolbar/wrench_toolbar_button.cc b/chrome/browser/ui/views/toolbar/wrench_toolbar_button.cc index 86954e0..06e8862 100644 --- a/chrome/browser/ui/views/toolbar/wrench_toolbar_button.cc +++ b/chrome/browser/ui/views/toolbar/wrench_toolbar_button.cc @@ -34,7 +34,7 @@ void WrenchToolbarButton::OnPaint(gfx::Canvas* canvas) { wrench_icon_painter_->Paint( canvas, GetThemeProvider(), gfx::Rect(size()), GetCurrentBezelType()); - OnPaintFocusBorder(canvas); + views::Painter::PaintFocusPainter(this, canvas, focus_painter()); } void WrenchToolbarButton::ScheduleWrenchIconPaint() { diff --git a/ui/app_list/views/folder_header_view.cc b/ui/app_list/views/folder_header_view.cc index 558726c..ba80dee 100644 --- a/ui/app_list/views/folder_header_view.cc +++ b/ui/app_list/views/folder_header_view.cc @@ -14,6 +14,7 @@ #include "ui/gfx/canvas.h" #include "ui/views/controls/button/image_button.h" #include "ui/views/controls/textfield/textfield.h" +#include "ui/views/painter.h" namespace app_list { @@ -37,7 +38,7 @@ class FolderHeaderView::FolderNameView : public views::Textfield { FolderNameView() { set_border(views::Border::CreateEmptyBorder(1, 1, 1, 1)); const SkColor kFocusBorderColor = SkColorSetRGB(64, 128, 250); - set_focus_border(views::FocusBorder::CreateSolidFocusBorder( + SetFocusPainter(views::Painter::CreateSolidFocusPainter( kFocusBorderColor, gfx::Insets(0, 0, 1, 1))); } diff --git a/ui/message_center/views/bounded_label.cc b/ui/message_center/views/bounded_label.cc index 852d583..2b8423b 100644 --- a/ui/message_center/views/bounded_label.cc +++ b/ui/message_center/views/bounded_label.cc @@ -168,7 +168,6 @@ void InnerBoundedLabel::OnBoundsChanged(const gfx::Rect& previous_bounds) { void InnerBoundedLabel::OnPaint(gfx::Canvas* canvas) { views::Label::OnPaintBackground(canvas); - views::Label::OnPaintFocusBorder(canvas); views::Label::OnPaintBorder(canvas); int lines = owner_->GetLineLimit(); int height = GetSizeForWidthAndLines(width(), lines).height(); diff --git a/ui/message_center/views/message_center_button_bar.cc b/ui/message_center/views/message_center_button_bar.cc index 3fcc9c8..9eb7246 100644 --- a/ui/message_center/views/message_center_button_bar.cc +++ b/ui/message_center/views/message_center_button_bar.cc @@ -24,6 +24,7 @@ #include "ui/views/controls/menu/menu_runner.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/grid_layout.h" +#include "ui/views/painter.h" namespace message_center { @@ -76,7 +77,7 @@ NotificationCenterButton::NotificationCenterButton( set_focusable(true); set_request_focus_on_press(false); - set_focus_border(views::FocusBorder::CreateSolidFocusBorder( + SetFocusPainter(views::Painter::CreateSolidFocusPainter( kFocusBorderColor, gfx::Insets(1, 2, 2, 2))); } diff --git a/ui/message_center/views/message_center_view.cc b/ui/message_center/views/message_center_view.cc index d176ff7..4f774a9 100644 --- a/ui/message_center/views/message_center_view.cc +++ b/ui/message_center/views/message_center_view.cc @@ -78,8 +78,6 @@ BoundedScrollView::BoundedScrollView(int min_height, int max_height) : min_height_(min_height), max_height_(max_height) { set_notify_enter_exit_on_child(true); - // Cancels the default dashed focus border. - set_focus_border(NULL); set_background( views::Background::CreateSolidBackground(kMessageCenterBackgroundColor)); SetVerticalScrollBar(new views::OverlayScrollBar(false)); diff --git a/ui/message_center/views/message_view.cc b/ui/message_center/views/message_view.cc index a6c9f00..856231b 100644 --- a/ui/message_center/views/message_view.cc +++ b/ui/message_center/views/message_view.cc @@ -20,6 +20,7 @@ #include "ui/views/controls/button/image_button.h" #include "ui/views/controls/menu/menu_runner.h" #include "ui/views/controls/scroll_view.h" +#include "ui/views/painter.h" #include "ui/views/shadow_border.h" #include "ui/views/widget/widget.h" @@ -172,9 +173,9 @@ MessageView::MessageView(const string16& display_source) IDS_MESSAGE_CENTER_CLOSE_NOTIFICATION_BUTTON_ACCESSIBLE_NAME)); close_button_.reset(close); - set_focus_border(views::FocusBorder::CreateSolidFocusBorder( + focus_painter_ = views::Painter::CreateSolidFocusPainter( kFocusBorderColor, - gfx::Insets(0, 1, 3, 2))); + gfx::Insets(0, 1, 3, 2)).Pass(); } MessageView::~MessageView() { @@ -243,6 +244,23 @@ bool MessageView::OnKeyReleased(const ui::KeyEvent& event) { return true; } +void MessageView::OnPaint(gfx::Canvas* canvas) { + SlideOutView::OnPaint(canvas); + views::Painter::PaintFocusPainter(this, canvas, focus_painter_.get()); +} + +void MessageView::OnFocus() { + SlideOutView::OnFocus(); + // We paint a focus indicator. + SchedulePaint(); +} + +void MessageView::OnBlur() { + SlideOutView::OnBlur(); + // We paint a focus indicator. + SchedulePaint(); +} + void MessageView::OnGestureEvent(ui::GestureEvent* event) { if (event->type() == ui::ET_GESTURE_TAP) { ClickOnNotification(); diff --git a/ui/message_center/views/message_view.h b/ui/message_center/views/message_view.h index c3a4d6b..341e9ad 100644 --- a/ui/message_center/views/message_view.h +++ b/ui/message_center/views/message_view.h @@ -5,6 +5,7 @@ #ifndef UI_MESSAGE_CENTER_VIEWS_MESSAGE_VIEW_H_ #define UI_MESSAGE_CENTER_VIEWS_MESSAGE_VIEW_H_ +#include "base/memory/scoped_ptr.h" #include "base/strings/string16.h" #include "ui/gfx/insets.h" #include "ui/message_center/message_center_export.h" @@ -14,6 +15,7 @@ namespace views { class ImageButton; +class Painter; class ScrollView; } @@ -58,6 +60,9 @@ class MESSAGE_CENTER_EXPORT MessageView : public views::SlideOutView, virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE; virtual bool OnKeyReleased(const ui::KeyEvent& event) OVERRIDE; + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; + virtual void OnFocus() OVERRIDE; + virtual void OnBlur() OVERRIDE; // Overridden from ui::EventHandler: virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE; @@ -82,6 +87,8 @@ class MESSAGE_CENTER_EXPORT MessageView : public views::SlideOutView, string16 accessible_name_; + scoped_ptr<views::Painter> focus_painter_; + DISALLOW_COPY_AND_ASSIGN(MessageView); }; diff --git a/ui/message_center/views/notification_view.cc b/ui/message_center/views/notification_view.cc index 1ed5c83..a5c902a 100644 --- a/ui/message_center/views/notification_view.cc +++ b/ui/message_center/views/notification_view.cc @@ -32,6 +32,7 @@ #include "ui/views/controls/progress_bar.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" +#include "ui/views/painter.h" #include "ui/views/widget/widget.h" #if defined(USE_AURA) @@ -321,7 +322,9 @@ class NotificationButton : public views::CustomButton { // Overridden from views::View: virtual gfx::Size GetPreferredSize() OVERRIDE; virtual int GetHeightForWidth(int width) OVERRIDE; + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; virtual void OnFocus() OVERRIDE; + virtual void OnBlur() OVERRIDE; // Overridden from views::CustomButton: virtual void StateChanged() OVERRIDE; @@ -329,12 +332,18 @@ class NotificationButton : public views::CustomButton { private: views::ImageView* icon_; views::Label* title_; + scoped_ptr<views::Painter> focus_painter_; + + DISALLOW_COPY_AND_ASSIGN(NotificationButton); }; NotificationButton::NotificationButton(views::ButtonListener* listener) : views::CustomButton(listener), icon_(NULL), - title_(NULL) { + title_(NULL), + focus_painter_(views::Painter::CreateSolidFocusPainter( + message_center::kFocusBorderColor, + gfx::Insets(1, 2, 2, 2))) { set_focusable(true); set_request_focus_on_press(false); set_notify_enter_exit_on_child(true); @@ -343,9 +352,6 @@ NotificationButton::NotificationButton(views::ButtonListener* listener) message_center::kButtonHorizontalPadding, kButtonVecticalPadding, message_center::kButtonIconToTitlePadding)); - set_focus_border(views::FocusBorder::CreateSolidFocusBorder( - message_center::kFocusBorderColor, - gfx::Insets(1, 2, 2, 2))); } NotificationButton::~NotificationButton() { @@ -394,9 +400,22 @@ int NotificationButton::GetHeightForWidth(int width) { return message_center::kButtonHeight; } +void NotificationButton::OnPaint(gfx::Canvas* canvas) { + CustomButton::OnPaint(canvas); + views::Painter::PaintFocusPainter(this, canvas, focus_painter_.get()); +} + void NotificationButton::OnFocus() { views::CustomButton::OnFocus(); ScrollRectToVisible(GetLocalBounds()); + // We render differently when focused. + SchedulePaint(); +} + +void NotificationButton::OnBlur() { + views::CustomButton::OnBlur(); + // We render differently when focused. + SchedulePaint(); } void NotificationButton::StateChanged() { diff --git a/ui/message_center/views/notifier_settings_view.cc b/ui/message_center/views/notifier_settings_view.cc index 7446b0d..399283b 100644 --- a/ui/message_center/views/notifier_settings_view.cc +++ b/ui/message_center/views/notifier_settings_view.cc @@ -38,6 +38,7 @@ #include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/layout/grid_layout.h" +#include "ui/views/painter.h" #include "ui/views/widget/widget.h" #if defined(USE_AURA) @@ -124,9 +125,9 @@ const int kComputedTitleElementSpacing = settings::kDescriptionToSwitcherSpace - kButtonPainterInsets - 1; // A function to create a focus border. -views::FocusBorder* CreateFocusBorder() { - return views::FocusBorder::CreateSolidFocusBorder(kFocusBorderColor, - gfx::Insets(1, 2, 3, 2)); +scoped_ptr<views::Painter> CreateFocusPainter() { + return views::Painter::CreateSolidFocusPainter(kFocusBorderColor, + gfx::Insets(1, 2, 3, 2)); } // EntryView ------------------------------------------------------------------ @@ -135,7 +136,7 @@ views::FocusBorder* CreateFocusBorder() { // middle. It also guarantee the left margin. class EntryView : public views::View { public: - EntryView(views::View* contents); + explicit EntryView(views::View* contents); virtual ~EntryView(); // views::View: @@ -145,13 +146,17 @@ class EntryView : public views::View { virtual void OnFocus() OVERRIDE; virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE; virtual bool OnKeyReleased(const ui::KeyEvent& event) OVERRIDE; + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; + virtual void OnBlur() OVERRIDE; private: + scoped_ptr<views::Painter> focus_painter_; + DISALLOW_COPY_AND_ASSIGN(EntryView); }; -EntryView::EntryView(views::View* contents) { - set_focus_border(CreateFocusBorder()); +EntryView::EntryView(views::View* contents) + : focus_painter_(CreateFocusPainter()) { AddChildView(contents); } @@ -181,6 +186,8 @@ void EntryView::GetAccessibleState(ui::AccessibleViewState* state) { void EntryView::OnFocus() { views::View::OnFocus(); ScrollRectToVisible(GetLocalBounds()); + // We render differently when focused. + SchedulePaint(); } bool EntryView::OnKeyPressed(const ui::KeyEvent& event) { @@ -191,6 +198,17 @@ bool EntryView::OnKeyReleased(const ui::KeyEvent& event) { return child_at(0)->OnKeyReleased(event); } +void EntryView::OnPaint(gfx::Canvas* canvas) { + View::OnPaint(canvas); + views::Painter::PaintFocusPainter(this, canvas, focus_painter_.get()); +} + +void EntryView::OnBlur() { + View::OnBlur(); + // We render differently when focused. + SchedulePaint(); +} + } // namespace @@ -294,7 +312,7 @@ NotifierSettingsView::NotifierButton::NotifierButton( if (ShouldHaveLearnMoreButton()) { // Create a more-info button that will be right-aligned. learn_more_ = new views::ImageButton(this); - learn_more_->set_focus_border(CreateFocusBorder()); + learn_more_->SetFocusPainter(CreateFocusPainter()); learn_more_->set_request_focus_on_press(false); learn_more_->set_focusable(true); @@ -466,7 +484,6 @@ NotifierSettingsView::NotifierSettingsView(NotifierSettingsProvider* provider) provider_->AddObserver(this); set_focusable(true); - set_focus_border(NULL); set_background( views::Background::CreateSolidBackground(kMessageCenterBackgroundColor)); if (get_use_acceleration_when_possible()) @@ -582,7 +599,7 @@ void NotifierSettingsView::UpdateContentsView( kMenuButtonVerticalPadding, kMenuButtonLeftPadding, kMenuButtonVerticalPadding, kMenuButtonRightPadding)); notifier_group_selector_->set_border(selector_border.release()); - notifier_group_selector_->set_focus_border(NULL); + notifier_group_selector_->SetFocusPainter(scoped_ptr<views::Painter>()); notifier_group_selector_->set_animate_on_state_change(false); notifier_group_selector_->set_focusable(true); contents_title_view->AddChildView(notifier_group_selector_); diff --git a/ui/message_center/views/padded_button.cc b/ui/message_center/views/padded_button.cc index 51e11c5..cb7810b 100644 --- a/ui/message_center/views/padded_button.cc +++ b/ui/message_center/views/padded_button.cc @@ -9,14 +9,15 @@ #include "ui/gfx/canvas.h" #include "ui/message_center/message_center_style.h" #include "ui/views/controls/button/image_button.h" +#include "ui/views/painter.h" namespace message_center { PaddedButton::PaddedButton(views::ButtonListener* listener) - : views::ImageButton(listener) { + : views::ImageButton(listener) { set_focusable(true); set_request_focus_on_press(false); - set_focus_border(views::FocusBorder::CreateSolidFocusBorder( + SetFocusPainter(views::Painter::CreateSolidFocusPainter( kFocusBorderColor, gfx::Insets(1, 2, 2, 2))); } @@ -68,7 +69,7 @@ void PaddedButton::OnPaint(gfx::Canvas* canvas) { if (!overlay_image_.isNull()) canvas->DrawImageInt(overlay_image_, position.x(), position.y()); } - OnPaintFocusBorder(canvas); + views::Painter::PaintFocusPainter(this, canvas, focus_painter()); } void PaddedButton::OnFocus() { diff --git a/ui/views/controls/button/checkbox.cc b/ui/views/controls/button/checkbox.cc index 6405689..6db5802 100644 --- a/ui/views/controls/button/checkbox.cc +++ b/ui/views/controls/button/checkbox.cc @@ -8,6 +8,7 @@ #include "ui/base/accessibility/accessible_view_state.h" #include "ui/base/resource/resource_bundle.h" #include "ui/views/controls/button/label_button_border.h" +#include "ui/views/painter.h" namespace views { @@ -79,11 +80,13 @@ void Checkbox::SetChecked(bool checked) { void Checkbox::Layout() { LabelButton::Layout(); - // Construct a focus border that only surrounds the label area. + // Construct a focus painter that only surrounds the label area. gfx::Rect rect = label()->GetMirroredBounds(); rect.Inset(-2, 3); - set_focus_border(FocusBorder::CreateDashedFocusBorder( - rect.x(), rect.y(), width() - rect.right(), height() - rect.bottom())); + SetFocusPainter(Painter::CreateDashedFocusPainterWithInsets( + gfx::Insets(rect.y(), rect.x(), + height() - rect.bottom(), + width() - rect.right()))); } const char* Checkbox::GetClassName() const { diff --git a/ui/views/controls/button/image_button.cc b/ui/views/controls/button/image_button.cc index 3811916..6a84234 100644 --- a/ui/views/controls/button/image_button.cc +++ b/ui/views/controls/button/image_button.cc @@ -10,6 +10,7 @@ #include "ui/gfx/canvas.h" #include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/scoped_canvas.h" +#include "ui/views/painter.h" #include "ui/views/widget/widget.h" namespace views { @@ -27,7 +28,8 @@ ImageButton::ImageButton(ButtonListener* listener) h_alignment_(ALIGN_LEFT), v_alignment_(ALIGN_TOP), preferred_size_(kDefaultWidth, kDefaultHeight), - draw_image_mirrored_(false) { + draw_image_mirrored_(false), + focus_painter_(Painter::CreateDashedFocusPainter()) { // By default, we request that the gfx::Canvas passed to our View::OnPaint() // implementation is flipped horizontally so that the button's images are // mirrored when the UI directionality is right-to-left. @@ -73,6 +75,10 @@ void ImageButton::SetImageAlignment(HorizontalAlignment h_align, SchedulePaint(); } +void ImageButton::SetFocusPainter(scoped_ptr<Painter> focus_painter) { + focus_painter_ = focus_painter.Pass(); +} + //////////////////////////////////////////////////////////////////////////////// // ImageButton, View overrides: @@ -114,12 +120,25 @@ void ImageButton::OnPaint(gfx::Canvas* canvas) { if (!overlay_image_.isNull()) canvas->DrawImageInt(overlay_image_, position.x(), position.y()); } - OnPaintFocusBorder(canvas); + + Painter::PaintFocusPainter(this, canvas, focus_painter()); } //////////////////////////////////////////////////////////////////////////////// // ImageButton, protected: +void ImageButton::OnFocus() { + View::OnFocus(); + if (focus_painter_.get()) + SchedulePaint(); +} + +void ImageButton::OnBlur() { + View::OnBlur(); + if (focus_painter_.get()) + SchedulePaint(); +} + gfx::ImageSkia ImageButton::GetImageToPaint() { gfx::ImageSkia img; diff --git a/ui/views/controls/button/image_button.h b/ui/views/controls/button/image_button.h index dd6b461..d74eceb 100644 --- a/ui/views/controls/button/image_button.h +++ b/ui/views/controls/button/image_button.h @@ -13,6 +13,8 @@ namespace views { +class Painter; + // An image button. // Note that this type of button is not focusable by default and will not be @@ -57,10 +59,7 @@ class VIEWS_EXPORT ImageButton : public CustomButton { void SetImageAlignment(HorizontalAlignment h_align, VerticalAlignment v_align); - // Overridden from View: - virtual gfx::Size GetPreferredSize() OVERRIDE; - virtual const char* GetClassName() const OVERRIDE; - virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; + void SetFocusPainter(scoped_ptr<Painter> focus_painter); // Sets preferred size, so it could be correctly positioned in layout even if // it is NULL. @@ -73,7 +72,16 @@ class VIEWS_EXPORT ImageButton : public CustomButton { draw_image_mirrored_ = mirrored; } + // Overridden from View: + virtual gfx::Size GetPreferredSize() OVERRIDE; + virtual const char* GetClassName() const OVERRIDE; + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; + protected: + // Overridden from View: + virtual void OnFocus() OVERRIDE; + virtual void OnBlur() OVERRIDE; + // Returns the image to paint. This is invoked from paint and returns a value // from images. virtual gfx::ImageSkia GetImageToPaint(); @@ -81,6 +89,8 @@ class VIEWS_EXPORT ImageButton : public CustomButton { // Updates button background for |scale_factor|. void UpdateButtonBackground(ui::ScaleFactor scale_factor); + Painter* focus_painter() { return focus_painter_.get(); } + // The images used to render the different states of this button. gfx::ImageSkia images_[STATE_COUNT]; @@ -109,6 +119,8 @@ class VIEWS_EXPORT ImageButton : public CustomButton { // resources. bool draw_image_mirrored_; + scoped_ptr<Painter> focus_painter_; + DISALLOW_COPY_AND_ASSIGN(ImageButton); }; diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc index c5bafdb..3fa79f85 100644 --- a/ui/views/controls/button/label_button.cc +++ b/ui/views/controls/button/label_button.cc @@ -11,7 +11,7 @@ #include "ui/gfx/sys_color_change_listener.h" #include "ui/native_theme/native_theme.h" #include "ui/views/controls/button/label_button_border.h" -#include "ui/views/focus_border.h" +#include "ui/views/painter.h" #include "ui/views/window/dialog_delegate.h" #if defined(OS_WIN) @@ -146,8 +146,12 @@ void LabelButton::SetStyle(ButtonStyle style) { style_ = style; set_border(new LabelButtonBorder(style)); // Inset the button focus rect from the actual border; roughly match Windows. - set_focus_border(style == STYLE_BUTTON ? - NULL : FocusBorder::CreateDashedFocusBorder(3, 3, 3, 3)); + if (style == STYLE_BUTTON) { + SetFocusPainter(scoped_ptr<Painter>()); + } else { + SetFocusPainter(Painter::CreateDashedFocusPainterWithInsets( + gfx::Insets(3, 3, 3, 3))); + } if (style == STYLE_BUTTON || style == STYLE_NATIVE_TEXTBUTTON) { label_->SetHorizontalAlignment(gfx::ALIGN_CENTER); set_focusable(true); @@ -159,6 +163,10 @@ void LabelButton::SetStyle(ButtonStyle style) { ResetColorsFromNativeTheme(); } +void LabelButton::SetFocusPainter(scoped_ptr<Painter> focus_painter) { + focus_painter_ = focus_painter.Pass(); +} + gfx::Size LabelButton::GetPreferredSize() { // Use a temporary label copy for sizing to avoid calculation side-effects. gfx::Font font = GetFont(); @@ -254,6 +262,11 @@ const char* LabelButton::GetClassName() const { return kViewClassName; } +void LabelButton::OnPaint(gfx::Canvas* canvas) { + View::OnPaint(canvas); + Painter::PaintFocusPainter(this, canvas, focus_painter_.get()); +} + void LabelButton::OnFocus() { View::OnFocus(); // Typically the border renders differently when focused. diff --git a/ui/views/controls/button/label_button.h b/ui/views/controls/button/label_button.h index f37d9c8..05dc128 100644 --- a/ui/views/controls/button/label_button.h +++ b/ui/views/controls/button/label_button.h @@ -6,6 +6,7 @@ #define UI_VIEWS_CONTROLS_BUTTON_LABEL_BUTTON_H_ #include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/font.h" #include "ui/gfx/image/image_skia.h" @@ -16,6 +17,8 @@ namespace views { +class Painter; + // LabelButton is an alternative to TextButton, it's not focusable by default. class VIEWS_EXPORT LabelButton : public CustomButton, public NativeThemeDelegate { @@ -65,16 +68,19 @@ class VIEWS_EXPORT LabelButton : public CustomButton, ButtonStyle style() const { return style_; } void SetStyle(ButtonStyle style); + void SetFocusPainter(scoped_ptr<Painter> focus_painter); + // View: virtual gfx::Size GetPreferredSize() OVERRIDE; virtual void Layout() OVERRIDE; virtual const char* GetClassName() const OVERRIDE; protected: - ImageView* image() const { return image_; } - Label* label() const { return label_; } + ImageView* image() const { return image_; } + Label* label() const { return label_; } - // Overridden from View: + // View: + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; virtual void OnFocus() OVERRIDE; virtual void OnBlur() OVERRIDE; @@ -138,6 +144,8 @@ class VIEWS_EXPORT LabelButton : public CustomButton, // The button's overall style. ButtonStyle style_; + scoped_ptr<Painter> focus_painter_; + DISALLOW_COPY_AND_ASSIGN(LabelButton); }; diff --git a/ui/views/controls/button/label_button_border.cc b/ui/views/controls/button/label_button_border.cc index 7eaef00..1bd1b74 100644 --- a/ui/views/controls/button/label_button_border.cc +++ b/ui/views/controls/button/label_button_border.cc @@ -147,11 +147,6 @@ void LabelButtonBorder::Paint(const View& view, gfx::Canvas* canvas) { rect.Inset(insets_); canvas->FillRect(rect, extra.button.background_color); } - - // Draw the Views focus border for the native theme style. - if (style() == Button::STYLE_NATIVE_TEXTBUTTON && - view.focus_border() && extra.button.is_focused) - view.focus_border()->Paint(view, canvas); } gfx::Insets LabelButtonBorder::GetInsets() const { diff --git a/ui/views/controls/button/text_button.cc b/ui/views/controls/button/text_button.cc index fcb0391..e829405 100644 --- a/ui/views/controls/button/text_button.cc +++ b/ui/views/controls/button/text_button.cc @@ -13,7 +13,7 @@ #include "ui/gfx/canvas.h" #include "ui/gfx/image/image.h" #include "ui/views/controls/button/button.h" -#include "ui/views/focus_border.h" +#include "ui/views/painter.h" #include "ui/views/widget/widget.h" #if defined(OS_WIN) @@ -37,12 +37,11 @@ const int kPreferredPaddingVertical = 5; const int kPreferredNativeThemePaddingHorizontal = 12; const int kPreferredNativeThemePaddingVertical = 5; -// By default the focus rect is drawn at the border of the view. -// For a button, we inset the focus rect by 3 pixels so that it -// doesn't draw on top of the button's border. This roughly matches -// how the Windows native focus rect for buttons looks. A subclass -// that draws a button with different padding may need to -// override OnPaintFocusBorder and do something different. +// By default the focus rect is drawn at the border of the view. For a button, +// we inset the focus rect by 3 pixels so that it doesn't draw on top of the +// button's border. This roughly matches how the Windows native focus rect for +// buttons looks. A subclass that draws a button with different padding may need +// to provide a different focus painter and do something different. const int kFocusRectInset = 3; // How long the hover fade animation should last. @@ -218,7 +217,8 @@ TextButtonBase::TextButtonBase(ButtonListener* listener, const string16& text) use_enabled_color_from_theme_(true), use_disabled_color_from_theme_(true), use_highlight_color_from_theme_(true), - use_hover_color_from_theme_(true) { + use_hover_color_from_theme_(true), + focus_painter_(Painter::CreateDashedFocusPainter()) { SetText(text); // OnNativeThemeChanged sets the color member variables. TextButtonBase::OnNativeThemeChanged(GetNativeTheme()); @@ -407,6 +407,18 @@ int TextButtonBase::ComputeCanvasStringFlags() const { return flags; } +void TextButtonBase::OnFocus() { + View::OnFocus(); + if (focus_painter_) + SchedulePaint(); +} + +void TextButtonBase::OnBlur() { + View::OnBlur(); + if (focus_painter_) + SchedulePaint(); +} + void TextButtonBase::GetExtraParams( ui::NativeTheme::ExtraParams* params) const { params->button.checked = false; @@ -452,11 +464,15 @@ gfx::Rect TextButtonBase::GetTextBounds() const { return GetContentBounds(0); } +void TextButtonBase::SetFocusPainter(scoped_ptr<Painter> focus_painter) { + focus_painter_ = focus_painter.Pass(); +} + void TextButtonBase::PaintButton(gfx::Canvas* canvas, PaintButtonMode mode) { if (mode == PB_NORMAL) { OnPaintBackground(canvas); OnPaintBorder(canvas); - OnPaintFocusBorder(canvas); + Painter::PaintFocusPainter(this, canvas, focus_painter_.get()); } gfx::Rect text_bounds(GetTextBounds()); @@ -601,10 +617,9 @@ TextButton::TextButton(ButtonListener* listener, const string16& text) icon_text_spacing_(kDefaultIconTextSpacing), ignore_minimum_size_(true) { set_border(new TextButtonDefaultBorder); - set_focus_border(FocusBorder::CreateDashedFocusBorder(kFocusRectInset, - kFocusRectInset, - kFocusRectInset, - kFocusRectInset)); + SetFocusPainter(Painter::CreateDashedFocusPainterWithInsets( + gfx::Insets(kFocusRectInset, kFocusRectInset, + kFocusRectInset, kFocusRectInset))); } TextButton::~TextButton() { diff --git a/ui/views/controls/button/text_button.h b/ui/views/controls/button/text_button.h index 49f12c6..18d2ba2 100644 --- a/ui/views/controls/button/text_button.h +++ b/ui/views/controls/button/text_button.h @@ -166,6 +166,9 @@ class VIEWS_EXPORT TextButtonBase : public CustomButton, bool show_multiple_icon_states() const { return show_multiple_icon_states_; } void SetShowMultipleIconStates(bool show_multiple_icon_states); + void SetFocusPainter(scoped_ptr<Painter> focus_painter); + Painter* focus_painter() { return focus_painter_.get(); } + // Paint the button into the specified canvas. If |mode| is |PB_FOR_DRAG|, the // function paints a drag image representation into the canvas. enum PaintButtonMode { PB_NORMAL, PB_FOR_DRAG }; @@ -221,6 +224,10 @@ class VIEWS_EXPORT TextButtonBase : public CustomButton, virtual ui::NativeTheme::State GetForegroundThemeState( ui::NativeTheme::ExtraParams* params) const OVERRIDE; + // Overridden from View: + virtual void OnFocus() OVERRIDE; + virtual void OnBlur() OVERRIDE; + virtual void GetExtraParams(ui::NativeTheme::ExtraParams* params) const; virtual gfx::Rect GetTextBounds() const; @@ -289,6 +296,8 @@ class VIEWS_EXPORT TextButtonBase : public CustomButton, bool use_highlight_color_from_theme_; bool use_hover_color_from_theme_; + scoped_ptr<Painter> focus_painter_; + DISALLOW_COPY_AND_ASSIGN(TextButtonBase); }; diff --git a/ui/views/controls/combobox/combobox.cc b/ui/views/controls/combobox/combobox.cc index d726fe2..ed66de7 100644 --- a/ui/views/controls/combobox/combobox.cc +++ b/ui/views/controls/combobox/combobox.cc @@ -101,8 +101,6 @@ Combobox::Combobox(ui::ComboboxModel* model) model_->AddObserver(this); UpdateFromModel(); set_focusable(true); - // |text_border_| draws focus. - set_focus_border(NULL); set_border(text_border_); } diff --git a/ui/views/controls/image_view.cc b/ui/views/controls/image_view.cc index bc2ad8e..2bbf91c 100644 --- a/ui/views/controls/image_view.cc +++ b/ui/views/controls/image_view.cc @@ -10,6 +10,7 @@ #include "ui/base/accessibility/accessible_view_state.h" #include "ui/gfx/canvas.h" #include "ui/gfx/insets.h" +#include "ui/views/painter.h" namespace views { @@ -19,7 +20,8 @@ ImageView::ImageView() vert_alignment_(CENTER), interactive_(true), last_paint_scale_(0.f), - last_painted_bitmap_pixels_(NULL) { + last_painted_bitmap_pixels_(NULL), + focus_painter_(Painter::CreateDashedFocusPainter()) { } ImageView::~ImageView() { @@ -73,6 +75,10 @@ void ImageView::ResetImageSize() { image_size_set_ = false; } +void ImageView::SetFocusPainter(scoped_ptr<Painter> focus_painter) { + focus_painter_ = focus_painter.Pass(); +} + gfx::Size ImageView::GetPreferredSize() { gfx::Insets insets = GetInsets(); if (image_size_set_) { @@ -126,31 +132,22 @@ gfx::Point ImageView::ComputeImageOrigin(const gfx::Size& image_size) const { return gfx::Point(x, y); } -void ImageView::OnPaint(gfx::Canvas* canvas) { - View::OnPaint(canvas); - - last_paint_scale_ = canvas->image_scale(); - last_painted_bitmap_pixels_ = NULL; - - if (image_.isNull()) - return; +void ImageView::OnFocus() { + View::OnFocus(); + if (focus_painter_.get()) + SchedulePaint(); +} - gfx::Rect image_bounds(GetImageBounds()); - if (image_bounds.IsEmpty()) - return; +void ImageView::OnBlur() { + View::OnBlur(); + if (focus_painter_.get()) + SchedulePaint(); +} - if (image_bounds.size() != gfx::Size(image_.width(), image_.height())) { - // Resize case - SkPaint paint; - paint.setFilterBitmap(true); - canvas->DrawImageInt(image_, 0, 0, image_.width(), image_.height(), - image_bounds.x(), image_bounds.y(), image_bounds.width(), - image_bounds.height(), true, paint); - } else { - canvas->DrawImageInt(image_, image_bounds.x(), image_bounds.y()); - } - last_painted_bitmap_pixels_ = - image_.GetRepresentation(last_paint_scale_).sk_bitmap().getPixels(); +void ImageView::OnPaint(gfx::Canvas* canvas) { + View::OnPaint(canvas); + OnPaintImage(canvas); + Painter::PaintFocusPainter(this, canvas, focus_painter_.get()); } void ImageView::GetAccessibleState(ui::AccessibleViewState* state) { @@ -200,4 +197,30 @@ bool ImageView::HitTestRect(const gfx::Rect& rect) const { return interactive_ ? View::HitTestRect(rect) : false; } + +void ImageView::OnPaintImage(gfx::Canvas* canvas) { + last_paint_scale_ = canvas->image_scale(); + last_painted_bitmap_pixels_ = NULL; + + if (image_.isNull()) + return; + + gfx::Rect image_bounds(GetImageBounds()); + if (image_bounds.IsEmpty()) + return; + + if (image_bounds.size() != gfx::Size(image_.width(), image_.height())) { + // Resize case + SkPaint paint; + paint.setFilterBitmap(true); + canvas->DrawImageInt(image_, 0, 0, image_.width(), image_.height(), + image_bounds.x(), image_bounds.y(), image_bounds.width(), + image_bounds.height(), true, paint); + } else { + canvas->DrawImageInt(image_, image_bounds.x(), image_bounds.y()); + } + last_painted_bitmap_pixels_ = + image_.GetRepresentation(last_paint_scale_).sk_bitmap().getPixels(); +} + } // namespace views diff --git a/ui/views/controls/image_view.h b/ui/views/controls/image_view.h index b40cb83..b0f4ce8 100644 --- a/ui/views/controls/image_view.h +++ b/ui/views/controls/image_view.h @@ -14,6 +14,8 @@ class Canvas; namespace views { +class Painter; + ///////////////////////////////////////////////////////////////////////////// // // ImageView class. @@ -75,8 +77,12 @@ class VIEWS_EXPORT ImageView : public View { void set_interactive(bool interactive) { interactive_ = interactive; } + void SetFocusPainter(scoped_ptr<Painter> focus_painter); + // Overriden from View: virtual gfx::Size GetPreferredSize() OVERRIDE; + virtual void OnFocus() OVERRIDE; + virtual void OnBlur() OVERRIDE; virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; virtual bool GetTooltipText(const gfx::Point& p, @@ -84,6 +90,8 @@ class VIEWS_EXPORT ImageView : public View { virtual bool HitTestRect(const gfx::Rect& rect) const OVERRIDE; private: + void OnPaintImage(gfx::Canvas* canvas); + // Returns true if |img| is the same as the last image we painted. This is // intended to be a quick check, not exhaustive. In other words it's possible // for this to return false even though the images are in fact equal. @@ -121,6 +129,8 @@ class VIEWS_EXPORT ImageView : public View { // safe to cache. void* last_painted_bitmap_pixels_; + scoped_ptr<views::Painter> focus_painter_; + DISALLOW_COPY_AND_ASSIGN(ImageView); }; diff --git a/ui/views/controls/link.cc b/ui/views/controls/link.cc index b2bcc8f..5a5729a 100644 --- a/ui/views/controls/link.cc +++ b/ui/views/controls/link.cc @@ -11,6 +11,7 @@ #include "ui/base/accessibility/accessible_view_state.h" #include "ui/events/event.h" #include "ui/events/keycodes/keyboard_codes.h" +#include "ui/gfx/canvas.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/font.h" #include "ui/views/controls/link_listener.h" @@ -62,6 +63,25 @@ gfx::NativeCursor Link::GetCursor(const ui::MouseEvent& event) { #endif } +void Link::OnPaint(gfx::Canvas* canvas) { + Label::OnPaint(canvas); + + if (HasFocus()) + canvas->DrawFocusRect(GetLocalBounds()); +} + +void Link::OnFocus() { + Label::OnFocus(); + // We render differently focused. + SchedulePaint(); +} + +void Link::OnBlur() { + Label::OnBlur(); + // We render differently focused. + SchedulePaint(); +} + bool Link::HitTestRect(const gfx::Rect& rect) const { // We need to allow clicks on the link. So we override the implementation in // Label and use the default implementation of View. diff --git a/ui/views/controls/link.h b/ui/views/controls/link.h index 9230acb..f6a876d 100644 --- a/ui/views/controls/link.h +++ b/ui/views/controls/link.h @@ -37,6 +37,9 @@ class VIEWS_EXPORT Link : public Label { virtual void OnEnabledChanged() OVERRIDE; virtual const char* GetClassName() const OVERRIDE; virtual gfx::NativeCursor GetCursor(const ui::MouseEvent& event) OVERRIDE; + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; + virtual void OnFocus() OVERRIDE; + virtual void OnBlur() OVERRIDE; virtual bool HitTestRect(const gfx::Rect& rect) const OVERRIDE; virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE; diff --git a/ui/views/controls/native/native_view_host.cc b/ui/views/controls/native/native_view_host.cc index 760f856..28b1fe3 100644 --- a/ui/views/controls/native/native_view_host.cc +++ b/ui/views/controls/native/native_view_host.cc @@ -17,7 +17,7 @@ const char NativeViewHost::kViewClassName[] = "NativeViewHost"; const char kWidgetNativeViewHostKey[] = "WidgetNativeViewHost"; #if defined(USE_AURA) -// Views implmenetatxion draws the focus. +// Views implementation draws the focus. // TODO(oshima): Eliminate this flag and consolidate // the focus border code. const bool NativeViewHost::kRenderNativeControlFocus = false; diff --git a/ui/views/controls/slider.cc b/ui/views/controls/slider.cc index b68ea1d..242ff5e 100644 --- a/ui/views/controls/slider.cc +++ b/ui/views/controls/slider.cc @@ -171,6 +171,19 @@ void Slider::SetAccessibleName(const string16& name) { accessible_name_ = name; } +void Slider::OnPaintFocus(gfx::Canvas* canvas) { + if (!HasFocus()) + return; + + if (!focus_border_color_) { + canvas->DrawFocusRect(GetLocalBounds()); + } else if (HasFocus()) { + canvas->DrawSolidFocusRect( + gfx::Rect(1, 1, width() - 3, height() - 3), + focus_border_color_); + } +} + gfx::Size Slider::GetPreferredSize() { const int kSizeMajor = 200; const int kSizeMinor = 40; @@ -248,6 +261,7 @@ void Slider::OnPaint(gfx::Canvas* canvas) { canvas->DrawImageInt(*thumb_, thumb_x, button_cy); } View::OnPaint(canvas); + OnPaintFocus(canvas); } bool Slider::OnMousePressed(const ui::MouseEvent& event) { @@ -316,14 +330,4 @@ void Slider::GetAccessibleState(ui::AccessibleViewState* state) { base::StringPrintf("%d%%", (int)(value_ * 100 + 0.5))); } -void Slider::OnPaintFocusBorder(gfx::Canvas* canvas) { - if (!focus_border_color_) { - View::OnPaintFocusBorder(canvas); - } else if (HasFocus()) { - canvas->DrawSolidFocusRect( - gfx::Rect(1, 1, width() - 3, height() - 3), - focus_border_color_); - } -} - } // namespace views diff --git a/ui/views/controls/slider.h b/ui/views/controls/slider.h index 3c17e94..cec24c2 100644 --- a/ui/views/controls/slider.h +++ b/ui/views/controls/slider.h @@ -41,8 +41,7 @@ class VIEWS_EXPORT SliderListener { virtual ~SliderListener() {} }; -class VIEWS_EXPORT Slider : public View, - public gfx::AnimationDelegate { +class VIEWS_EXPORT Slider : public View, public gfx::AnimationDelegate { public: enum Orientation { HORIZONTAL, @@ -80,6 +79,8 @@ class VIEWS_EXPORT Slider : public View, // Moves the button to the specified point and updates the value accordingly. void MoveButtonTo(const gfx::Point& point); + void OnPaintFocus(gfx::Canvas* canvas); + // views::View overrides: virtual gfx::Size GetPreferredSize() OVERRIDE; virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; @@ -88,7 +89,6 @@ class VIEWS_EXPORT Slider : public View, virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE; virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE; virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE; - virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE; // ui::EventHandler overrides: virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE; diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index fe2296b..04003ba 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc @@ -23,6 +23,7 @@ #include "ui/views/controls/textfield/native_textfield_views.h" #include "ui/views/controls/textfield/native_textfield_wrapper.h" #include "ui/views/controls/textfield/textfield_controller.h" +#include "ui/views/painter.h" #include "ui/views/views_delegate.h" #include "ui/views/widget/widget.h" @@ -78,8 +79,8 @@ Textfield::Textfield() GetDefaultTextfieldObscuredRevealDuration(); } - if (!NativeViewHost::kRenderNativeControlFocus) - set_focus_border(NULL); + if (NativeViewHost::kRenderNativeControlFocus) + focus_painter_ = Painter::CreateDashedFocusPainter(); } Textfield::Textfield(StyleFlags style) @@ -108,8 +109,8 @@ Textfield::Textfield(StyleFlags style) GetDefaultTextfieldObscuredRevealDuration(); } - if (!NativeViewHost::kRenderNativeControlFocus) - set_focus_border(NULL); + if (NativeViewHost::kRenderNativeControlFocus) + focus_painter_ = Painter::CreateDashedFocusPainter(); } Textfield::~Textfield() { @@ -407,6 +408,10 @@ void Textfield::ExecuteCommand(int command_id) { native_wrapper_->ExecuteTextCommand(command_id); } +void Textfield::SetFocusPainter(scoped_ptr<Painter> focus_painter) { + focus_painter_ = focus_painter.Pass(); +} + bool Textfield::HasTextBeingDragged() { return native_wrapper_->HasTextBeingDragged(); } @@ -449,9 +454,10 @@ bool Textfield::SkipDefaultKeyEventProcessing(const ui::KeyEvent& e) { return e.key_code() == ui::VKEY_BACK || e.IsUnicodeKeyCode(); } -void Textfield::OnPaintFocusBorder(gfx::Canvas* canvas) { +void Textfield::OnPaint(gfx::Canvas* canvas) { + View::OnPaint(canvas); if (NativeViewHost::kRenderNativeControlFocus) - View::OnPaintFocusBorder(canvas); + Painter::PaintFocusPainter(this, canvas, focus_painter_.get()); } bool Textfield::OnKeyPressed(const ui::KeyEvent& e) { diff --git a/ui/views/controls/textfield/textfield.h b/ui/views/controls/textfield/textfield.h index 2c10b8e..307e562 100644 --- a/ui/views/controls/textfield/textfield.h +++ b/ui/views/controls/textfield/textfield.h @@ -9,6 +9,7 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/strings/string16.h" #include "base/time/time.h" @@ -38,7 +39,7 @@ class TextInputClient; namespace views { class ImageView; - +class Painter; class TextfieldController; // This class implements a View that wraps a native text (edit) field. @@ -239,6 +240,8 @@ class VIEWS_EXPORT Textfield : public View { // Performs the action associated with the specified command id. void ExecuteCommand(int command_id); + void SetFocusPainter(scoped_ptr<Painter> focus_painter); + // Provided only for testing: gfx::NativeView GetTestingHandle() const { return native_wrapper_ ? native_wrapper_->GetTestingHandle() : NULL; @@ -257,7 +260,7 @@ class VIEWS_EXPORT Textfield : public View { virtual void AboutToRequestFocusFromTabTraversal(bool reverse) OVERRIDE; virtual bool SkipDefaultKeyEventProcessing(const ui::KeyEvent& e) OVERRIDE; virtual void OnEnabledChanged() OVERRIDE; - virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE; + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; virtual bool OnKeyPressed(const ui::KeyEvent& e) OVERRIDE; virtual bool OnKeyReleased(const ui::KeyEvent& e) OVERRIDE; virtual bool OnMouseDragged(const ui::MouseEvent& e) OVERRIDE; @@ -343,6 +346,8 @@ class VIEWS_EXPORT Textfield : public View { // Used to bind callback functions to this object. base::WeakPtrFactory<Textfield> weak_ptr_factory_; + scoped_ptr<Painter> focus_painter_; + DISALLOW_COPY_AND_ASSIGN(Textfield); }; diff --git a/ui/views/controls/webview/webview.cc b/ui/views/controls/webview/webview.cc index eef661f..f2ea02f 100644 --- a/ui/views/controls/webview/webview.cc +++ b/ui/views/controls/webview/webview.cc @@ -35,8 +35,6 @@ WebView::WebView(content::BrowserContext* browser_context) is_embedding_fullscreen_widget_(false), browser_context_(browser_context), allow_accelerators_(false) { - // WebView shouldn't render focus. - set_focus_border(NULL); AddChildView(wcv_holder_); NativeViewAccessibility::RegisterWebView(this); } diff --git a/ui/views/focus_border.cc b/ui/views/focus_border.cc deleted file mode 100644 index 3ff28c3..0000000 --- a/ui/views/focus_border.cc +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2012 The Chromium 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 "ui/views/focus_border.h" - -#include "ui/gfx/canvas.h" -#include "ui/gfx/insets.h" -#include "ui/gfx/rect.h" -#include "ui/views/view.h" - -namespace views { -namespace { - -class DashedFocusBorder : public FocusBorder { - public: - DashedFocusBorder( - int left_inset, int top_inset, int right_inset, int bottom_inset) - : left_inset_(left_inset), - top_inset_(top_inset), - right_inset_(right_inset), - bottom_inset_(bottom_inset) { - } - - virtual void Paint(const View& view, gfx::Canvas* canvas) const OVERRIDE { - gfx::Rect rect(view.GetLocalBounds()); - rect.Inset(left_inset_, top_inset_, right_inset_, bottom_inset_); - canvas->DrawFocusRect(rect); - } - - private: - int left_inset_; - int top_inset_; - int right_inset_; - int bottom_inset_; - - DISALLOW_COPY_AND_ASSIGN(DashedFocusBorder); -}; - -class SolidFocusBorder : public FocusBorder { - public: - SolidFocusBorder(SkColor focus_color, const gfx::Insets& insets) - : focus_color_(focus_color), insets_(insets) { - } - - virtual void Paint(const View& view, gfx::Canvas* canvas) const OVERRIDE { - gfx::Rect rect(view.GetLocalBounds()); - rect.Inset(insets_); - canvas->DrawSolidFocusRect(rect, focus_color_); - } - - private: - // The focus color to use. - SkColor focus_color_; - - // The insets to use. - gfx::Insets insets_; - - DISALLOW_COPY_AND_ASSIGN(SolidFocusBorder); -}; - -} // namespace - -FocusBorder::~FocusBorder() { -} - -// static -FocusBorder* FocusBorder::CreateDashedFocusBorder() { - return new DashedFocusBorder(0, 0, 0, 0); -} - -// static -FocusBorder* FocusBorder::CreateDashedFocusBorder( - int left, int top, int right, int bottom) { - return new DashedFocusBorder(left, top, right, bottom); -} - -// static -FocusBorder* FocusBorder::CreateSolidFocusBorder( - SkColor focus_color, const gfx::Insets& insets) { - return new SolidFocusBorder(focus_color, insets); -} - -FocusBorder::FocusBorder() { -} - -} // namespace views diff --git a/ui/views/focus_border.h b/ui/views/focus_border.h deleted file mode 100644 index e10ca41..0000000 --- a/ui/views/focus_border.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2012 The Chromium 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 UI_VIEWS_FOCUS_BORDER_H_ -#define UI_VIEWS_FOCUS_BORDER_H_ - -#include "base/basictypes.h" -#include "third_party/skia/include/core/SkColor.h" -#include "ui/gfx/insets.h" -#include "ui/views/views_export.h" - -namespace gfx { -class Canvas; -} - -namespace views { -class View; - -//////////////////////////////////////////////////////////////////////////////// -// -// Focus border class. -// -// The focus border class is used to display an indication of focus on a view. -// To set a focus border on a view, call SetFocusBorder on the view. Once set -// on a view, the focus border is owned by the view. -// -//////////////////////////////////////////////////////////////////////////////// - -class VIEWS_EXPORT FocusBorder { - public: - virtual ~FocusBorder(); - - // Creates the default inset dashed line focus border. - static FocusBorder* CreateDashedFocusBorder(); - static FocusBorder* CreateDashedFocusBorder( - int left, int top, int right, int bottom); - - // Creates a focus border with a given |inset| and |focus_color| which is one - // pixel thick. - static FocusBorder* CreateSolidFocusBorder( - SkColor focus_color, const gfx::Insets& insets); - - // Renders the focus border for the specified view. - virtual void Paint(const View& view, gfx::Canvas* canvas) const = 0; - - protected: - FocusBorder(); - - private: - DISALLOW_COPY_AND_ASSIGN(FocusBorder); -}; - -} // namespace views - -#endif // UI_VIEWS_FOCUS_BORDER_H_ diff --git a/ui/views/painter.cc b/ui/views/painter.cc index ce84a58..b6a2e7d 100644 --- a/ui/views/painter.cc +++ b/ui/views/painter.cc @@ -15,12 +15,83 @@ #include "ui/gfx/insets.h" #include "ui/gfx/point.h" #include "ui/gfx/rect.h" - +#include "ui/views/view.h" namespace views { namespace { +// DashedFocusPainter ---------------------------------------------------------- + +class DashedFocusPainter : public Painter { + public: + explicit DashedFocusPainter(const gfx::Insets& insets); + virtual ~DashedFocusPainter(); + + // Painter: + virtual gfx::Size GetMinimumSize() const OVERRIDE; + virtual void Paint(gfx::Canvas* canvas, const gfx::Size& size) OVERRIDE; + + private: + const gfx::Insets insets_; + + DISALLOW_COPY_AND_ASSIGN(DashedFocusPainter); +}; + +DashedFocusPainter::DashedFocusPainter(const gfx::Insets& insets) + : insets_(insets) { +} + +DashedFocusPainter::~DashedFocusPainter() { +} + +gfx::Size DashedFocusPainter::GetMinimumSize() const { + return gfx::Size(); +} + +void DashedFocusPainter::Paint(gfx::Canvas* canvas, const gfx::Size& size) { + gfx::Rect rect(size); + rect.Inset(insets_); + canvas->DrawFocusRect(rect); +} + +// SolidFocusPainter ----------------------------------------------------------- + +class SolidFocusPainter : public Painter { + public: + SolidFocusPainter(SkColor color, const gfx::Insets& insets); + virtual ~SolidFocusPainter(); + + // Painter: + virtual gfx::Size GetMinimumSize() const OVERRIDE; + virtual void Paint(gfx::Canvas* canvas, const gfx::Size& size) OVERRIDE; + + private: + const SkColor color_; + const gfx::Insets insets_; + + DISALLOW_COPY_AND_ASSIGN(SolidFocusPainter); +}; + +SolidFocusPainter::SolidFocusPainter(SkColor color, + const gfx::Insets& insets) + : color_(color), + insets_(insets) { +} + +SolidFocusPainter::~SolidFocusPainter() { +} + +gfx::Size SolidFocusPainter::GetMinimumSize() const { + return gfx::Size(); +} + +void SolidFocusPainter::Paint(gfx::Canvas* canvas, const gfx::Size& size) { + gfx::Rect rect(size); + rect.Inset(insets_); + canvas->DrawSolidFocusRect(rect, color_); +} + // GradientPainter ------------------------------------------------------------ class GradientPainter : public Painter { @@ -88,7 +159,6 @@ void GradientPainter::Paint(gfx::Canvas* canvas, const gfx::Size& size) { SkIntToScalar(size.height()), paint); } - // ImagePainter --------------------------------------------------------------- // ImagePainter stores and paints nine images as a scalable grid. @@ -239,6 +309,14 @@ void Painter::PaintPainterAt(gfx::Canvas* canvas, } // static +void Painter::PaintFocusPainter(View* view, + gfx::Canvas* canvas, + Painter* focus_painter) { + if (focus_painter && view->HasFocus()) + PaintPainterAt(canvas, focus_painter, view->GetLocalBounds()); +} + +// static Painter* Painter::CreateHorizontalGradient(SkColor c1, SkColor c2) { SkColor colors[2]; colors[0] = c1; @@ -274,6 +352,23 @@ Painter* Painter::CreateImageGridPainter(const int image_ids[]) { return new ImagePainter(image_ids); } +// static +scoped_ptr<Painter> Painter::CreateDashedFocusPainter() { + return scoped_ptr<Painter>(new DashedFocusPainter(gfx::Insets())).Pass(); +} + +// static +scoped_ptr<Painter> Painter::CreateDashedFocusPainterWithInsets( + const gfx::Insets& insets) { + return scoped_ptr<Painter>(new DashedFocusPainter(insets)).Pass(); +} + +// static +scoped_ptr<Painter> Painter::CreateSolidFocusPainter( + SkColor color, + const gfx::Insets& insets) { + return scoped_ptr<Painter>(new SolidFocusPainter(color, insets)).Pass(); +} // HorizontalPainter ---------------------------------------------------------- diff --git a/ui/views/painter.h b/ui/views/painter.h index c0ff443..3799e91 100644 --- a/ui/views/painter.h +++ b/ui/views/painter.h @@ -7,6 +7,7 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/views/views_export.h" @@ -25,6 +26,8 @@ class Size; namespace views { +class View; + // Painter, as the name implies, is responsible for painting in a particular // region. Think of Painter as a Border or Background that can be painted // in any region of a View. @@ -39,6 +42,12 @@ class VIEWS_EXPORT Painter { Painter* painter, const gfx::Rect& rect); + // Convenience that paints |focus_painter| only if |view| HasFocus() and + // |focus_painter| is non-NULL. + static void PaintFocusPainter(View* view, + gfx::Canvas* canvas, + Painter* focus_painter); + // Creates a painter that draws a gradient between the two colors. static Painter* CreateHorizontalGradient(SkColor c1, SkColor c2); static Painter* CreateVerticalGradient(SkColor c1, SkColor c2); @@ -65,6 +74,13 @@ class VIEWS_EXPORT Painter { // Top-Left/Top/Top-Right/Left/[Center]/Right/Bottom-Left/Bottom/Bottom-Right. static Painter* CreateImageGridPainter(const int image_ids[]); + // Factory methods for creating painters intended for rendering focus. + static scoped_ptr<Painter> CreateDashedFocusPainter(); + static scoped_ptr<Painter> CreateDashedFocusPainterWithInsets( + const gfx::Insets& insets); + static scoped_ptr<Painter> CreateSolidFocusPainter(SkColor color, + const gfx::Insets& insets); + // Returns the minimum size this painter can paint without obvious graphical // problems (e.g. overlapping images). virtual gfx::Size GetMinimumSize() const = 0; diff --git a/ui/views/view.cc b/ui/views/view.cc index becd1bc1..f74d0f9 100644 --- a/ui/views/view.cc +++ b/ui/views/view.cc @@ -161,7 +161,6 @@ View::View() registered_for_visible_bounds_notification_(false), clip_insets_(0, 0, 0, 0), needs_layout_(true), - focus_border_(FocusBorder::CreateDashedFocusBorder()), flip_canvas_on_paint_for_rtl_ui_(false), paint_to_layer_(false), accelerator_focus_manager_(NULL), @@ -1404,7 +1403,6 @@ void View::PaintChildren(gfx::Canvas* canvas) { void View::OnPaint(gfx::Canvas* canvas) { TRACE_EVENT1("views", "View::OnPaint", "class", GetClassName()); OnPaintBackground(canvas); - OnPaintFocusBorder(canvas); OnPaintBorder(canvas); } @@ -1426,15 +1424,6 @@ void View::OnPaintBorder(gfx::Canvas* canvas) { } } -void View::OnPaintFocusBorder(gfx::Canvas* canvas) { - if (focus_border_.get() && HasFocus()) { - TRACE_EVENT2("views", "views::OnPaintFocusBorder", - "width", canvas->sk_canvas()->getDevice()->width(), - "height", canvas->sk_canvas()->getDevice()->height()); - focus_border_->Paint(*this, canvas); - } -} - // Accelerated Painting -------------------------------------------------------- void View::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) { @@ -1606,14 +1595,10 @@ void View::OnBlur() { } void View::Focus() { - if (focus_border_.get()) - SchedulePaint(); OnFocus(); } void View::Blur() { - if (focus_border_.get()) - SchedulePaint(); OnBlur(); } diff --git a/ui/views/view.h b/ui/views/view.h index e5d6297..9bdf8405 100644 --- a/ui/views/view.h +++ b/ui/views/view.h @@ -31,7 +31,6 @@ #include "ui/gfx/vector2d.h" #include "ui/views/background.h" #include "ui/views/border.h" -#include "ui/views/focus_border.h" #if defined(OS_WIN) #include "base/win/scoped_comptr.h" @@ -516,11 +515,6 @@ class VIEWS_EXPORT View : public ui::LayerDelegate, const Border* border() const { return border_.get(); } Border* border() { return border_.get(); } - // The focus_border object is owned by this object and may be NULL. - void set_focus_border(FocusBorder* b) { focus_border_.reset(b); } - const FocusBorder* focus_border() const { return focus_border_.get(); } - FocusBorder* focus_border() { return focus_border_.get(); } - // Get the theme provider from the parent widget. virtual ui::ThemeProvider* GetThemeProvider() const; @@ -1089,10 +1083,6 @@ class VIEWS_EXPORT View : public ui::LayerDelegate, // Override to paint a border not specified by SetBorder(). virtual void OnPaintBorder(gfx::Canvas* canvas); - // Override to paint a focus border not specified by set_focus_border() around - // relevant contents. The focus border is usually a dotted rectangle. - virtual void OnPaintFocusBorder(gfx::Canvas* canvas); - // Accelerated painting ------------------------------------------------------ // Returns the offset from this view to the nearest ancestor with a layer. If @@ -1512,9 +1502,6 @@ class VIEWS_EXPORT View : public ui::LayerDelegate, // Border. scoped_ptr<Border> border_; - // Focus border. - scoped_ptr<FocusBorder> focus_border_; - // RTL painting -------------------------------------------------------------- // Indicates whether or not the gfx::Canvas object passed to View::Paint() diff --git a/ui/views/view_unittest.cc b/ui/views/view_unittest.cc index 964efdf..264da27 100644 --- a/ui/views/view_unittest.cc +++ b/ui/views/view_unittest.cc @@ -27,7 +27,6 @@ #include "ui/views/controls/textfield/textfield.h" #include "ui/views/focus/accelerator_handler.h" #include "ui/views/focus/view_storage.h" -#include "ui/views/focus_border.h" #include "ui/views/test/views_test_base.h" #include "ui/views/view.h" #include "ui/views/views_delegate.h" @@ -2212,9 +2211,7 @@ TEST_F(ViewTest, FocusBlurPaints) { parent_view.scheduled_paint_rects_.clear(); child_view1->scheduled_paint_rects_.clear(); - // If no FocusBorder is installed then focus changes shouldn't - // SchedulePaint(). - child_view1->set_focus_border(NULL); + // Focus change shouldn't trigger paints. child_view1->DoFocus(); EXPECT_TRUE(parent_view.scheduled_paint_rects_.empty()); @@ -2223,15 +2220,6 @@ TEST_F(ViewTest, FocusBlurPaints) { child_view1->DoBlur(); EXPECT_TRUE(parent_view.scheduled_paint_rects_.empty()); EXPECT_TRUE(child_view1->scheduled_paint_rects_.empty()); - - // Repeat with a FocusBorder, should now paint. - child_view1->set_focus_border(FocusBorder::CreateDashedFocusBorder()); - child_view1->DoFocus(); - EXPECT_FALSE(child_view1->scheduled_paint_rects_.empty()); - child_view1->scheduled_paint_rects_.clear(); - - child_view1->DoBlur(); - EXPECT_FALSE(child_view1->scheduled_paint_rects_.empty()); } // Verifies SetBounds(same bounds) doesn't trigger a SchedulePaint(). diff --git a/ui/views/views.gyp b/ui/views/views.gyp index da105c5..3c0454d 100644 --- a/ui/views/views.gyp +++ b/ui/views/views.gyp @@ -293,8 +293,6 @@ 'focus/view_storage.h', 'focus/widget_focus_manager.cc', 'focus/widget_focus_manager.h', - 'focus_border.cc', - 'focus_border.h', 'ime/input_method_base.cc', 'ime/input_method_base.h', 'ime/input_method_bridge.cc', |