diff options
| author | estade <estade@chromium.org> | 2016-03-23 12:07:11 -0700 |
|---|---|---|
| committer | Commit bot <commit-bot@chromium.org> | 2016-03-23 19:08:52 +0000 |
| commit | 9c5853b50cb270fabac8533c2c6844fd83f00158 (patch) | |
| tree | 0474243995b68415d88d75891343901fc760afae | |
| parent | 4ed171b7b7cf88fea577208abbe901a125f675dc (diff) | |
| download | chromium_src-9c5853b50cb270fabac8533c2c6844fd83f00158.zip chromium_src-9c5853b50cb270fabac8533c2c6844fd83f00158.tar.gz chromium_src-9c5853b50cb270fabac8533c2c6844fd83f00158.tar.bz2 | |
Allow NonClientFrameView to define a clip for the client view. This fixes the website settings bubble.
Also draw the border on top in BubbleFrameView. This fixes the bookmark bubble sync promo.
This patch does not address client views with layers, such as ExtensionPopup.
BUG=581600
Review URL: https://codereview.chromium.org/1773393002
Cr-Commit-Position: refs/heads/master@{#382895}
| -rw-r--r-- | ui/app_list/views/search_result_page_view.cc | 5 | ||||
| -rw-r--r-- | ui/gfx/path.h | 3 | ||||
| -rw-r--r-- | ui/views/bubble/bubble_frame_view.cc | 32 | ||||
| -rw-r--r-- | ui/views/bubble/bubble_frame_view.h | 5 | ||||
| -rw-r--r-- | ui/views/view.cc | 21 | ||||
| -rw-r--r-- | ui/views/view.h | 11 | ||||
| -rw-r--r-- | ui/views/window/non_client_view.cc | 12 | ||||
| -rw-r--r-- | ui/views/window/non_client_view.h | 6 |
8 files changed, 71 insertions, 24 deletions
diff --git a/ui/app_list/views/search_result_page_view.cc b/ui/app_list/views/search_result_page_view.cc index ca065cb..4d9d644 100644 --- a/ui/app_list/views/search_result_page_view.cc +++ b/ui/app_list/views/search_result_page_view.cc @@ -236,7 +236,10 @@ void SearchResultPageView::OnAnimationUpdated(double progress, gfx::Rect onscreen_bounds( GetPageBoundsForState(AppListModel::STATE_SEARCH_RESULTS)); - set_clip_insets(bounds().InsetsFrom(onscreen_bounds)); + onscreen_bounds -= bounds().OffsetFromOrigin(); + gfx::Path path; + path.addRect(gfx::RectToSkRect(onscreen_bounds)); + set_clip_path(path); } int SearchResultPageView::GetSearchBoxZHeight() const { diff --git a/ui/gfx/path.h b/ui/gfx/path.h index bb00e13..e1cbfa9 100644 --- a/ui/gfx/path.h +++ b/ui/gfx/path.h @@ -33,9 +33,6 @@ class GFX_EXPORT Path : public SkPath { Path(const PointF* points, size_t count); ~Path(); - - private: - DISALLOW_COPY_AND_ASSIGN(Path); }; } diff --git a/ui/views/bubble/bubble_frame_view.cc b/ui/views/bubble/bubble_frame_view.cc index 3e63de9..4c342a5 100644 --- a/ui/views/bubble/bubble_frame_view.cc +++ b/ui/views/bubble/bubble_frame_view.cc @@ -12,6 +12,8 @@ #include "ui/base/hit_test.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/compositor/paint_context.h" +#include "ui/compositor/paint_recorder.h" #include "ui/gfx/geometry/vector2d.h" #include "ui/gfx/path.h" #include "ui/gfx/screen.h" @@ -134,6 +136,15 @@ gfx::Rect BubbleFrameView::GetWindowBoundsForClientBounds( return bubble_border_->GetBounds(gfx::Rect(), size); } +bool BubbleFrameView::GetClientMask(const gfx::Size& size, + gfx::Path* path) const { + const int radius = bubble_border_->GetBorderCornerRadius(); + gfx::RectF rect((gfx::Rect(size))); + rect.Inset(gfx::InsetsF(0.5f)); + path->addRoundRect(gfx::RectFToSkRect(rect), radius, radius); + return true; +} + int BubbleFrameView::NonClientHitTest(const gfx::Point& point) { if (!bounds().Contains(point)) return HTNOWHERE; @@ -217,6 +228,10 @@ void BubbleFrameView::SetTitleFontList(const gfx::FontList& font_list) { title_->SetFontList(font_list); } +const char* BubbleFrameView::GetClassName() const { + return kViewClassName; +} + gfx::Insets BubbleFrameView::GetInsets() const { gfx::Insets insets = content_margins_; @@ -317,10 +332,6 @@ void BubbleFrameView::Layout() { } } -const char* BubbleFrameView::GetClassName() const { - return kViewClassName; -} - void BubbleFrameView::OnThemeChanged() { UpdateWindowTitle(); ResetWindowControls(); @@ -335,6 +346,19 @@ void BubbleFrameView::OnNativeThemeChanged(const ui::NativeTheme* theme) { } } +void BubbleFrameView::OnPaint(gfx::Canvas* canvas) { + OnPaintBackground(canvas); + // Border comes after children. +} + +void BubbleFrameView::PaintChildren(const ui::PaintContext& context) { + NonClientFrameView::PaintChildren(context); + + ui::PaintCache paint_cache; + ui::PaintRecorder recorder(context, size(), &paint_cache); + OnPaintBorder(recorder.canvas()); +} + void BubbleFrameView::ButtonPressed(Button* sender, const ui::Event& event) { if (sender == close_) { close_button_clicked_ = true; diff --git a/ui/views/bubble/bubble_frame_view.h b/ui/views/bubble/bubble_frame_view.h index 2ec295a..812c3e7 100644 --- a/ui/views/bubble/bubble_frame_view.h +++ b/ui/views/bubble/bubble_frame_view.h @@ -41,6 +41,7 @@ class VIEWS_EXPORT BubbleFrameView : public NonClientFrameView, gfx::Rect GetBoundsForClientView() const override; gfx::Rect GetWindowBoundsForClientBounds( const gfx::Rect& client_bounds) const override; + bool GetClientMask(const gfx::Size& size, gfx::Path* path) const override; int NonClientHitTest(const gfx::Point& point) override; void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) override; void ResetWindowControls() override; @@ -53,12 +54,14 @@ class VIEWS_EXPORT BubbleFrameView : public NonClientFrameView, void SetTitleFontList(const gfx::FontList& font_list); // View overrides: + const char* GetClassName() const override; gfx::Insets GetInsets() const override; gfx::Size GetPreferredSize() const override; gfx::Size GetMinimumSize() const override; gfx::Size GetMaximumSize() const override; void Layout() override; - const char* GetClassName() const override; + void OnPaint(gfx::Canvas* canvas) override; + void PaintChildren(const ui::PaintContext& context) override; void OnThemeChanged() override; void OnNativeThemeChanged(const ui::NativeTheme* theme) override; diff --git a/ui/views/view.cc b/ui/views/view.cc index 3580d04..beedbb1 100644 --- a/ui/views/view.cc +++ b/ui/views/view.cc @@ -804,16 +804,17 @@ void View::Paint(const ui::PaintContext& parent_context) { // std::optional once we can do so. ui::ClipRecorder clip_recorder(parent_context); if (paint_relative_to_parent) { - // Set the clip rect to the bounds of this View. Note that the X (or left) - // position we pass to ClipRect takes into consideration whether or not the - // View uses a right-to-left layout so that we paint the View in its - // mirrored position if need be. - gfx::Rect clip_rect_in_parent = bounds(); - clip_rect_in_parent.Inset(clip_insets_); - if (parent_) - clip_rect_in_parent.set_x( - parent_->GetMirroredXForRect(clip_rect_in_parent)); - clip_recorder.ClipRect(clip_rect_in_parent); + // Set the clip rect to the bounds of this View, or |clip_path_| if it's + // been set. Note that the X (or left) position we pass to ClipRect takes + // into consideration whether or not the View uses a right-to-left layout so + // that we paint the View in its mirrored position if need be. + if (clip_path_.isEmpty()) { + clip_recorder.ClipRect(GetMirroredBounds()); + } else { + gfx::Path clip_path_in_parent = clip_path_; + clip_path_in_parent.offset(GetMirroredX(), y()); + clip_recorder.ClipPath(clip_path_in_parent); + } } ui::TransformRecorder transform_recorder(context); diff --git a/ui/views/view.h b/ui/views/view.h index adc31cc..83d8601 100644 --- a/ui/views/view.h +++ b/ui/views/view.h @@ -35,6 +35,7 @@ #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/vector2d.h" #include "ui/gfx/native_widget_types.h" +#include "ui/gfx/path.h" #include "ui/views/view_targeter.h" #include "ui/views/views_export.h" @@ -298,8 +299,8 @@ class VIEWS_EXPORT View : public ui::LayerDelegate, gfx::Transform GetTransform() const; - // Clipping parameters. Clipping is done relative to the view bounds. - void set_clip_insets(gfx::Insets clip_insets) { clip_insets_ = clip_insets; } + // Clipping is done relative to the view's local bounds. + void set_clip_path(const gfx::Path& path) { clip_path_ = path; } // Sets the transform to the supplied transform. void SetTransform(const gfx::Transform& transform); @@ -1485,9 +1486,9 @@ class VIEWS_EXPORT View : public ui::LayerDelegate, // Transformations ----------------------------------------------------------- - // Clipping parameters. skia transformation matrix does not give us clipping. - // So we do it ourselves. - gfx::Insets clip_insets_; + // Painting will be clipped to this path. TODO(estade): this doesn't work for + // layers. + gfx::Path clip_path_; // Layout -------------------------------------------------------------------- diff --git a/ui/views/window/non_client_view.cc b/ui/views/window/non_client_view.cc index 0718c2c..a6d38a2 100644 --- a/ui/views/window/non_client_view.cc +++ b/ui/views/window/non_client_view.cc @@ -31,6 +31,14 @@ static const int kClientViewIndex = 1; // The overlay view is always on top (index == child_count() - 1). //////////////////////////////////////////////////////////////////////////////// +// NonClientFrameView, default implementations: + +bool NonClientFrameView::GetClientMask(const gfx::Size& size, + gfx::Path* mask) const { + return false; +} + +//////////////////////////////////////////////////////////////////////////////// // NonClientView, public: NonClientView::NonClientView() @@ -159,6 +167,10 @@ void NonClientView::Layout() { // Then layout the ClientView, using those bounds. client_view_->SetBoundsRect(frame_view_->GetBoundsForClientView()); + gfx::Path client_clip; + if (frame_view_->GetClientMask(client_view_->size(), &client_clip)) + client_view_->set_clip_path(client_clip); + // We need to manually call Layout on the ClientView as well for the same // reason as above. client_view_->Layout(); diff --git a/ui/views/window/non_client_view.h b/ui/views/window/non_client_view.h index 1eac8c2..4000024 100644 --- a/ui/views/window/non_client_view.h +++ b/ui/views/window/non_client_view.h @@ -65,6 +65,12 @@ class VIEWS_EXPORT NonClientFrameView : public View, virtual gfx::Rect GetWindowBoundsForClientBounds( const gfx::Rect& client_bounds) const = 0; + // Gets the clip mask (in this View's parent's coordinates) that should be + // applied to the client view. Returns false if no special clip should be + // used. + virtual bool GetClientMask(const gfx::Size& size, + gfx::Path* mask) const; + // This function must ask the ClientView to do a hittest. We don't do this in // the parent NonClientView because that makes it more difficult to calculate // hittests for regions that are partially obscured by the ClientView, e.g. |
