diff options
author | pkotwicz <pkotwicz@chromium.org> | 2014-09-06 11:32:06 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-06 18:35:54 +0000 |
commit | bc021eeb04dc604001e761ecb6451955e694a50a (patch) | |
tree | 146914db2449abfc555b2482fac412dfcd6822e4 /athena | |
parent | 4a530823516e6278f74a898189bf5cc641d9e2f9 (diff) | |
download | chromium_src-bc021eeb04dc604001e761ecb6451955e694a50a.zip chromium_src-bc021eeb04dc604001e761ecb6451955e694a50a.tar.gz chromium_src-bc021eeb04dc604001e761ecb6451955e694a50a.tar.bz2 |
Make activities have a thick border when in overview mode part 1
BUG=401559
TEST=Manual, see bug
TBR=sadrul, oshima (TBR for DEPS additions)
NOTRY=true
Review URL: https://codereview.chromium.org/518673007
Cr-Commit-Position: refs/heads/master@{#293620}
Diffstat (limited to 'athena')
-rw-r--r-- | athena/activity/DEPS | 5 | ||||
-rw-r--r-- | athena/activity/activity_frame_view.cc | 161 | ||||
-rw-r--r-- | athena/activity/activity_frame_view.h | 23 | ||||
-rw-r--r-- | athena/activity/public/activity_view_model.h | 6 | ||||
-rw-r--r-- | athena/content/app_activity.cc | 11 | ||||
-rw-r--r-- | athena/content/app_activity.h | 2 | ||||
-rw-r--r-- | athena/content/app_activity_proxy.cc | 6 | ||||
-rw-r--r-- | athena/content/app_activity_proxy.h | 2 | ||||
-rw-r--r-- | athena/content/web_activity.cc | 11 | ||||
-rw-r--r-- | athena/content/web_activity.h | 2 | ||||
-rw-r--r-- | athena/resource_manager/resource_manager_unittest.cc | 2 | ||||
-rw-r--r-- | athena/test/sample_activity.cc | 6 | ||||
-rw-r--r-- | athena/test/sample_activity.h | 2 |
13 files changed, 204 insertions, 35 deletions
diff --git a/athena/activity/DEPS b/athena/activity/DEPS index 78a4371..b121b0c 100644 --- a/athena/activity/DEPS +++ b/athena/activity/DEPS @@ -1,6 +1,9 @@ include_rules = [ - "+athena/screen", + "+athena/screen/public", + "+athena/wm/public", + "+third_party/skia/include", "+ui/aura", "+ui/base", + "+ui/gfx", "+ui/views", ] diff --git a/athena/activity/activity_frame_view.cc b/athena/activity/activity_frame_view.cc index 83b9388..e4ff413 100644 --- a/athena/activity/activity_frame_view.cc +++ b/athena/activity/activity_frame_view.cc @@ -4,64 +4,97 @@ #include "athena/activity/activity_frame_view.h" -#include <algorithm> -#include <vector> - #include "athena/activity/public/activity_view_model.h" +#include "athena/wm/public/window_manager.h" +#include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/hit_test.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/image/image_skia.h" #include "ui/views/background.h" -#include "ui/views/border.h" +#include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_delegate.h" +#include "ui/views/window/client_view.h" namespace athena { +namespace { + +// The icon size. +const int kIconSize = 32; + +// The distance between the icon and the title when the icon is visible. +const int kIconTitleSpacing = 5; + +// The height of the top border necessary to display the title without the icon. +const int kDefaultTitleHeight = 25; -//////////////////////////////////////////////////////////////////////////////// -// FrameViewAthena, public: +// The height of the top border in overview mode. +const int kOverviewTitleHeight = 55; + +// The height of the top border for fullscreen and frameless activities in +// overview mode. +const int kOverviewShortTitleHeight = 30; + +// The thickness of the left, right and bottom borders in overview mode. +const int kOverviewBorderThickness = 5; + +} // namespace // static const char ActivityFrameView::kViewClassName[] = "ActivityFrameView"; ActivityFrameView::ActivityFrameView(views::Widget* frame, ActivityViewModel* view_model) - : frame_(frame), view_model_(view_model), title_(new views::Label) { - title_->SetHorizontalAlignment(gfx::ALIGN_CENTER); + : frame_(frame), + view_model_(view_model), + title_(new views::Label), + icon_(new views::ImageView), + in_overview_(false) { title_->SetEnabledColor(SkColorSetA(SK_ColorBLACK, 0xe5)); - title_->SetBorder(views::Border::CreateSolidSidedBorder(0, 0, 1, 0, - SkColorSetA(SK_ColorGRAY, 0x7f))); + + SkBitmap bitmap; + bitmap.allocN32Pixels(kIconSize, kIconSize); + bitmap.eraseARGB(255, 0, 255, 0); + icon_->SetImage(gfx::ImageSkia::CreateFrom1xBitmap(bitmap)); + AddChildView(title_); + AddChildView(icon_); + + SkColor bgcolor = view_model_->GetRepresentativeColor(); + set_background(views::Background::CreateSolidBackground(bgcolor)); UpdateWindowTitle(); + + WindowManager::GetInstance()->AddObserver(this); } ActivityFrameView::~ActivityFrameView() { + WindowManager::GetInstance()->RemoveObserver(this); } -//////////////////////////////////////////////////////////////////////////////// -// ActivityFrameView, views::NonClientFrameView overrides: - gfx::Rect ActivityFrameView::GetBoundsForClientView() const { gfx::Rect client_bounds = bounds(); - if (view_model_->UsesFrame()) - client_bounds.Inset(0, NonClientTopBorderHeight(), 0, 0); + client_bounds.Inset(NonClientBorderInsets()); return client_bounds; } gfx::Rect ActivityFrameView::GetWindowBoundsForClientBounds( const gfx::Rect& client_bounds) const { gfx::Rect window_bounds = client_bounds; - if (view_model_->UsesFrame()) - window_bounds.Inset(0, -NonClientTopBorderHeight(), 0, 0); + window_bounds.Inset(-NonClientBorderInsets()); return window_bounds; } int ActivityFrameView::NonClientHitTest(const gfx::Point& point) { - if (frame_->IsFullscreen()) - return 0; - if (title_->bounds().Contains(point)) - return HTCAPTION; - return 0; + if (!bounds().Contains(point)) + return HTNOWHERE; + int client_hit_test = frame_->client_view()->NonClientHitTest(point); + if (client_hit_test != HTNOWHERE) + return client_hit_test; + int window_hit_test = + GetHTComponentForFrame(point, 0, NonClientBorderThickness(), 0, 0, false); + return (window_hit_test == HTNOWHERE) ? HTCAPTION : client_hit_test; } void ActivityFrameView::GetWindowMask(const gfx::Size& size, @@ -85,11 +118,9 @@ void ActivityFrameView::UpdateWindowTitle() { if (!view_model_->UsesFrame()) return; title_->SetText(frame_->widget_delegate()->GetWindowTitle()); + Layout(); } -//////////////////////////////////////////////////////////////////////////////// -// ActivityFrameView, views::View overrides: - gfx::Size ActivityFrameView::GetPreferredSize() const { gfx::Size pref = frame_->client_view()->GetPreferredSize(); gfx::Rect bounds(0, 0, pref.width(), pref.height()); @@ -103,15 +134,83 @@ const char* ActivityFrameView::GetClassName() const { } void ActivityFrameView::Layout() { - title_->SetBounds(0, 0, width(), NonClientTopBorderHeight()); + if (frame_->IsFullscreen() || !view_model_->UsesFrame()) { + title_->SetVisible(false); + icon_->SetVisible(false); + return; + } + + title_->SetVisible(true); + icon_->SetVisible(in_overview_); + + gfx::Size preferred_title_size = title_->GetPreferredSize(); + int top_height = NonClientTopBorderHeight(); + int title_x = 0; + if (in_overview_) { + int edge = (top_height - kIconSize) / 2; + icon_->SetBounds(edge, edge, kIconSize, kIconSize); + + title_x = icon_->bounds().right() + kIconTitleSpacing; + } else { + title_x = (width() - preferred_title_size.width()) / 2; + } + + title_->SetBounds(title_x, + (top_height - preferred_title_size.height()) / 2, + preferred_title_size.width(), + preferred_title_size.height()); } -//////////////////////////////////////////////////////////////////////////////// -// ActivityFrameView, private: +void ActivityFrameView::OnPaintBackground(gfx::Canvas* canvas) { + View::OnPaintBackground(canvas); + + // Paint a border around the client view. + gfx::Rect border_bounds = GetLocalBounds(); + border_bounds.Inset(NonClientBorderInsets()); + border_bounds.Inset(-1, -1, 0, 0); + canvas->DrawRect(border_bounds, SkColorSetA(SK_ColorGRAY, 0x7f)); +} + +void ActivityFrameView::OnOverviewModeEnter() { + view_model_->PrepareContentsForOverview(); + in_overview_ = true; + InvalidateLayout(); + frame_->client_view()->InvalidateLayout(); + frame_->GetRootView()->Layout(); + SchedulePaint(); +} + +void ActivityFrameView::OnOverviewModeExit() { + in_overview_ = false; + InvalidateLayout(); + frame_->client_view()->InvalidateLayout(); + frame_->GetRootView()->Layout(); + SchedulePaint(); + view_model_->ResetContentsView(); +} + +void ActivityFrameView::OnSplitViewModeEnter() { +} + +void ActivityFrameView::OnSplitViewModeExit() { +} + +gfx::Insets ActivityFrameView::NonClientBorderInsets() const { + int border_thickness = NonClientBorderThickness(); + return gfx::Insets(NonClientTopBorderHeight(), + border_thickness, + border_thickness, + border_thickness); +} + +int ActivityFrameView::NonClientBorderThickness() const { + return in_overview_ ? kOverviewBorderThickness : 0; +} int ActivityFrameView::NonClientTopBorderHeight() const { - const int kDefaultTitleHeight = 25; - return frame_->IsFullscreen() ? 0 : kDefaultTitleHeight; + if (frame_->IsFullscreen() || !view_model_->UsesFrame()) + return in_overview_ ? kOverviewShortTitleHeight : 0; + return in_overview_ ? kOverviewTitleHeight : kDefaultTitleHeight; } -} // namespace ash +} // namespace athena diff --git a/athena/activity/activity_frame_view.h b/athena/activity/activity_frame_view.h index 43b1ac9..ab473a5 100644 --- a/athena/activity/activity_frame_view.h +++ b/athena/activity/activity_frame_view.h @@ -5,10 +5,13 @@ #ifndef ATHENA_ACTIVITY_ACTIVITY_FRAME_VIEW_H_ #define ATHENA_ACTIVITY_ACTIVITY_FRAME_VIEW_H_ +#include "athena/wm/public/window_manager_observer.h" #include "base/memory/scoped_ptr.h" +#include "ui/gfx/insets.h" #include "ui/views/window/non_client_view.h" namespace views { +class ImageView; class Label; class Widget; } @@ -18,7 +21,8 @@ namespace athena { class ActivityViewModel; // A NonClientFrameView used for activity. -class ActivityFrameView : public views::NonClientFrameView { +class ActivityFrameView : public views::NonClientFrameView, + public WindowManagerObserver { public: // Internal class name. static const char kViewClassName[]; @@ -26,7 +30,7 @@ class ActivityFrameView : public views::NonClientFrameView { ActivityFrameView(views::Widget* frame, ActivityViewModel* view_model); virtual ~ActivityFrameView(); - // views::NonClientFrameView overrides: + // views::NonClientFrameView: virtual gfx::Rect GetBoundsForClientView() const OVERRIDE; virtual gfx::Rect GetWindowBoundsForClientBounds( const gfx::Rect& client_bounds) const OVERRIDE; @@ -37,18 +41,31 @@ class ActivityFrameView : public views::NonClientFrameView { virtual void UpdateWindowIcon() OVERRIDE; virtual void UpdateWindowTitle() OVERRIDE; - // views::View overrides: + // views::View: virtual gfx::Size GetPreferredSize() const OVERRIDE; virtual const char* GetClassName() const OVERRIDE; virtual void Layout() OVERRIDE; + virtual void OnPaintBackground(gfx::Canvas* canvas) OVERRIDE; private: + // WindowManagerObserver: + virtual void OnOverviewModeEnter() OVERRIDE; + virtual void OnOverviewModeExit() OVERRIDE; + virtual void OnSplitViewModeEnter() OVERRIDE; + virtual void OnSplitViewModeExit() OVERRIDE; + + gfx::Insets NonClientBorderInsets() const; + int NonClientBorderThickness() const; int NonClientTopBorderHeight() const; // Not owned. views::Widget* frame_; ActivityViewModel* view_model_; views::Label* title_; + views::ImageView* icon_; + + // Whether overview mode is active. + bool in_overview_; DISALLOW_COPY_AND_ASSIGN(ActivityFrameView); }; diff --git a/athena/activity/public/activity_view_model.h b/athena/activity/public/activity_view_model.h index 99241c8..12b8ced 100644 --- a/athena/activity/public/activity_view_model.h +++ b/athena/activity/public/activity_view_model.h @@ -57,6 +57,12 @@ class ATHENA_EXPORT ActivityViewModel { // GetRepresentativeColor() should be used to clear the preview area. // Note: We intentionally do not use a layer / view for this. virtual gfx::ImageSkia GetOverviewModeImage() = 0; + + // Prepares the contents view for overview. + virtual void PrepareContentsForOverview() = 0; + + // Undoes any changes done by PrepareContentsForOverview(). + virtual void ResetContentsView() = 0; }; } // namespace athena diff --git a/athena/content/app_activity.cc b/athena/content/app_activity.cc index 478bf92..e557b61 100644 --- a/athena/content/app_activity.cc +++ b/athena/content/app_activity.cc @@ -140,6 +140,17 @@ gfx::ImageSkia AppActivity::GetOverviewModeImage() { return overview_mode_image_; } +void AppActivity::PrepareContentsForOverview() { + // Turn on fast resizing to avoid re-laying out the web contents when + // entering / exiting overview mode. + web_view_->SetFastResize(true); +} + +void AppActivity::ResetContentsView() { + web_view_->SetFastResize(false); + web_view_->Layout(); +} + AppActivity::~AppActivity() { // If this activity is registered, we unregister it now. if (app_activity_registry_) diff --git a/athena/content/app_activity.h b/athena/content/app_activity.h index f141053..3c69596 100644 --- a/athena/content/app_activity.h +++ b/athena/content/app_activity.h @@ -45,6 +45,8 @@ class AppActivity : public Activity, virtual views::View* GetContentsView() OVERRIDE; virtual void CreateOverviewModeImage() OVERRIDE; virtual gfx::ImageSkia GetOverviewModeImage() OVERRIDE; + virtual void PrepareContentsForOverview() OVERRIDE; + virtual void ResetContentsView() OVERRIDE; protected: virtual ~AppActivity(); diff --git a/athena/content/app_activity_proxy.cc b/athena/content/app_activity_proxy.cc index dc348eb..a5ca0f4 100644 --- a/athena/content/app_activity_proxy.cc +++ b/athena/content/app_activity_proxy.cc @@ -90,4 +90,10 @@ gfx::ImageSkia AppActivityProxy::GetOverviewModeImage() { return image_; } +void AppActivityProxy::PrepareContentsForOverview() { +} + +void AppActivityProxy::ResetContentsView() { +} + } // namespace athena diff --git a/athena/content/app_activity_proxy.h b/athena/content/app_activity_proxy.h index 5685be6..6ea263f 100644 --- a/athena/content/app_activity_proxy.h +++ b/athena/content/app_activity_proxy.h @@ -45,6 +45,8 @@ class AppActivityProxy : public Activity, virtual views::View* GetContentsView() OVERRIDE; virtual void CreateOverviewModeImage() OVERRIDE; virtual gfx::ImageSkia GetOverviewModeImage() OVERRIDE; + virtual void PrepareContentsForOverview() OVERRIDE; + virtual void ResetContentsView() OVERRIDE; private: // The creator of this object which needs to be informed if the object gets diff --git a/athena/content/web_activity.cc b/athena/content/web_activity.cc index 34a21d0..85ede62 100644 --- a/athena/content/web_activity.cc +++ b/athena/content/web_activity.cc @@ -465,6 +465,17 @@ gfx::ImageSkia WebActivity::GetOverviewModeImage() { return overview_mode_image_; } +void WebActivity::PrepareContentsForOverview() { + // Turn on fast resizing to avoid re-laying out the web contents when + // entering / exiting overview mode. + web_view_->SetFastResize(true); +} + +void WebActivity::ResetContentsView() { + web_view_->SetFastResize(false); + web_view_->Layout(); +} + void WebActivity::TitleWasSet(content::NavigationEntry* entry, bool explicit_set) { ActivityManager::Get()->UpdateActivity(this); diff --git a/athena/content/web_activity.h b/athena/content/web_activity.h index 7aa8a6d..6f8f9a9 100644 --- a/athena/content/web_activity.h +++ b/athena/content/web_activity.h @@ -53,6 +53,8 @@ class WebActivity : public Activity, virtual views::View* GetContentsView() OVERRIDE; virtual void CreateOverviewModeImage() OVERRIDE; virtual gfx::ImageSkia GetOverviewModeImage() OVERRIDE; + virtual void PrepareContentsForOverview() OVERRIDE; + virtual void ResetContentsView() OVERRIDE; // content::WebContentsObserver: virtual void TitleWasSet(content::NavigationEntry* entry, diff --git a/athena/resource_manager/resource_manager_unittest.cc b/athena/resource_manager/resource_manager_unittest.cc index b84102e..4d49f0c 100644 --- a/athena/resource_manager/resource_manager_unittest.cc +++ b/athena/resource_manager/resource_manager_unittest.cc @@ -55,6 +55,8 @@ class TestActivity : public Activity, virtual views::View* GetContentsView() OVERRIDE { return view_; } virtual void CreateOverviewModeImage() OVERRIDE {} virtual gfx::ImageSkia GetOverviewModeImage() OVERRIDE { return image_; } + virtual void PrepareContentsForOverview() OVERRIDE {} + virtual void ResetContentsView() OVERRIDE {} private: // The presentation values. diff --git a/athena/test/sample_activity.cc b/athena/test/sample_activity.cc index 8e36ea0..7c052a5 100644 --- a/athena/test/sample_activity.cc +++ b/athena/test/sample_activity.cc @@ -80,5 +80,11 @@ gfx::ImageSkia SampleActivity::GetOverviewModeImage() { return gfx::ImageSkia(); } +void SampleActivity::PrepareContentsForOverview() { +} + +void SampleActivity::ResetContentsView() { +} + } // namespace test } // namespace athena diff --git a/athena/test/sample_activity.h b/athena/test/sample_activity.h index a43d609..8658e0b 100644 --- a/athena/test/sample_activity.h +++ b/athena/test/sample_activity.h @@ -38,6 +38,8 @@ class SampleActivity : public Activity, virtual views::View* GetContentsView() OVERRIDE; virtual void CreateOverviewModeImage() OVERRIDE; virtual gfx::ImageSkia GetOverviewModeImage() OVERRIDE; + virtual void PrepareContentsForOverview() OVERRIDE; + virtual void ResetContentsView() OVERRIDE; SkColor color_; SkColor contents_color_; |