Commit bc021eeb authored by pkotwicz's avatar pkotwicz Committed by Commit bot

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}
parent 4a530823
include_rules = [ include_rules = [
"+athena/screen", "+athena/screen/public",
"+athena/wm/public",
"+third_party/skia/include",
"+ui/aura", "+ui/aura",
"+ui/base", "+ui/base",
"+ui/gfx",
"+ui/views", "+ui/views",
] ]
...@@ -4,64 +4,97 @@ ...@@ -4,64 +4,97 @@
#include "athena/activity/activity_frame_view.h" #include "athena/activity/activity_frame_view.h"
#include <algorithm>
#include <vector>
#include "athena/activity/public/activity_view_model.h" #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/base/hit_test.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/views/background.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/controls/label.h"
#include "ui/views/view.h" #include "ui/views/view.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h" #include "ui/views/widget/widget_delegate.h"
#include "ui/views/window/client_view.h"
namespace athena { 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;
//////////////////////////////////////////////////////////////////////////////// // The height of the top border in overview mode.
// FrameViewAthena, public: 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 // static
const char ActivityFrameView::kViewClassName[] = "ActivityFrameView"; const char ActivityFrameView::kViewClassName[] = "ActivityFrameView";
ActivityFrameView::ActivityFrameView(views::Widget* frame, ActivityFrameView::ActivityFrameView(views::Widget* frame,
ActivityViewModel* view_model) ActivityViewModel* view_model)
: frame_(frame), view_model_(view_model), title_(new views::Label) { : frame_(frame),
title_->SetHorizontalAlignment(gfx::ALIGN_CENTER); view_model_(view_model),
title_(new views::Label),
icon_(new views::ImageView),
in_overview_(false) {
title_->SetEnabledColor(SkColorSetA(SK_ColorBLACK, 0xe5)); 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(title_);
AddChildView(icon_);
SkColor bgcolor = view_model_->GetRepresentativeColor();
set_background(views::Background::CreateSolidBackground(bgcolor));
UpdateWindowTitle(); UpdateWindowTitle();
WindowManager::GetInstance()->AddObserver(this);
} }
ActivityFrameView::~ActivityFrameView() { ActivityFrameView::~ActivityFrameView() {
WindowManager::GetInstance()->RemoveObserver(this);
} }
////////////////////////////////////////////////////////////////////////////////
// ActivityFrameView, views::NonClientFrameView overrides:
gfx::Rect ActivityFrameView::GetBoundsForClientView() const { gfx::Rect ActivityFrameView::GetBoundsForClientView() const {
gfx::Rect client_bounds = bounds(); gfx::Rect client_bounds = bounds();
if (view_model_->UsesFrame()) client_bounds.Inset(NonClientBorderInsets());
client_bounds.Inset(0, NonClientTopBorderHeight(), 0, 0);
return client_bounds; return client_bounds;
} }
gfx::Rect ActivityFrameView::GetWindowBoundsForClientBounds( gfx::Rect ActivityFrameView::GetWindowBoundsForClientBounds(
const gfx::Rect& client_bounds) const { const gfx::Rect& client_bounds) const {
gfx::Rect window_bounds = client_bounds; gfx::Rect window_bounds = client_bounds;
if (view_model_->UsesFrame()) window_bounds.Inset(-NonClientBorderInsets());
window_bounds.Inset(0, -NonClientTopBorderHeight(), 0, 0);
return window_bounds; return window_bounds;
} }
int ActivityFrameView::NonClientHitTest(const gfx::Point& point) { int ActivityFrameView::NonClientHitTest(const gfx::Point& point) {
if (frame_->IsFullscreen()) if (!bounds().Contains(point))
return 0; return HTNOWHERE;
if (title_->bounds().Contains(point)) int client_hit_test = frame_->client_view()->NonClientHitTest(point);
return HTCAPTION; if (client_hit_test != HTNOWHERE)
return 0; 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, void ActivityFrameView::GetWindowMask(const gfx::Size& size,
...@@ -85,11 +118,9 @@ void ActivityFrameView::UpdateWindowTitle() { ...@@ -85,11 +118,9 @@ void ActivityFrameView::UpdateWindowTitle() {
if (!view_model_->UsesFrame()) if (!view_model_->UsesFrame())
return; return;
title_->SetText(frame_->widget_delegate()->GetWindowTitle()); title_->SetText(frame_->widget_delegate()->GetWindowTitle());
Layout();
} }
////////////////////////////////////////////////////////////////////////////////
// ActivityFrameView, views::View overrides:
gfx::Size ActivityFrameView::GetPreferredSize() const { gfx::Size ActivityFrameView::GetPreferredSize() const {
gfx::Size pref = frame_->client_view()->GetPreferredSize(); gfx::Size pref = frame_->client_view()->GetPreferredSize();
gfx::Rect bounds(0, 0, pref.width(), pref.height()); gfx::Rect bounds(0, 0, pref.width(), pref.height());
...@@ -103,15 +134,83 @@ const char* ActivityFrameView::GetClassName() const { ...@@ -103,15 +134,83 @@ const char* ActivityFrameView::GetClassName() const {
} }
void ActivityFrameView::Layout() { 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());
} }
//////////////////////////////////////////////////////////////////////////////// void ActivityFrameView::OnPaintBackground(gfx::Canvas* canvas) {
// ActivityFrameView, private: 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 { int ActivityFrameView::NonClientTopBorderHeight() const {
const int kDefaultTitleHeight = 25; if (frame_->IsFullscreen() || !view_model_->UsesFrame())
return frame_->IsFullscreen() ? 0 : kDefaultTitleHeight; return in_overview_ ? kOverviewShortTitleHeight : 0;
return in_overview_ ? kOverviewTitleHeight : kDefaultTitleHeight;
} }
} // namespace ash } // namespace athena
...@@ -5,10 +5,13 @@ ...@@ -5,10 +5,13 @@
#ifndef ATHENA_ACTIVITY_ACTIVITY_FRAME_VIEW_H_ #ifndef ATHENA_ACTIVITY_ACTIVITY_FRAME_VIEW_H_
#define 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 "base/memory/scoped_ptr.h"
#include "ui/gfx/insets.h"
#include "ui/views/window/non_client_view.h" #include "ui/views/window/non_client_view.h"
namespace views { namespace views {
class ImageView;
class Label; class Label;
class Widget; class Widget;
} }
...@@ -18,7 +21,8 @@ namespace athena { ...@@ -18,7 +21,8 @@ namespace athena {
class ActivityViewModel; class ActivityViewModel;
// A NonClientFrameView used for activity. // A NonClientFrameView used for activity.
class ActivityFrameView : public views::NonClientFrameView { class ActivityFrameView : public views::NonClientFrameView,
public WindowManagerObserver {
public: public:
// Internal class name. // Internal class name.
static const char kViewClassName[]; static const char kViewClassName[];
...@@ -26,7 +30,7 @@ class ActivityFrameView : public views::NonClientFrameView { ...@@ -26,7 +30,7 @@ class ActivityFrameView : public views::NonClientFrameView {
ActivityFrameView(views::Widget* frame, ActivityViewModel* view_model); ActivityFrameView(views::Widget* frame, ActivityViewModel* view_model);
virtual ~ActivityFrameView(); virtual ~ActivityFrameView();
// views::NonClientFrameView overrides: // views::NonClientFrameView:
virtual gfx::Rect GetBoundsForClientView() const OVERRIDE; virtual gfx::Rect GetBoundsForClientView() const OVERRIDE;
virtual gfx::Rect GetWindowBoundsForClientBounds( virtual gfx::Rect GetWindowBoundsForClientBounds(
const gfx::Rect& client_bounds) const OVERRIDE; const gfx::Rect& client_bounds) const OVERRIDE;
...@@ -37,18 +41,31 @@ class ActivityFrameView : public views::NonClientFrameView { ...@@ -37,18 +41,31 @@ class ActivityFrameView : public views::NonClientFrameView {
virtual void UpdateWindowIcon() OVERRIDE; virtual void UpdateWindowIcon() OVERRIDE;
virtual void UpdateWindowTitle() OVERRIDE; virtual void UpdateWindowTitle() OVERRIDE;
// views::View overrides: // views::View:
virtual gfx::Size GetPreferredSize() const OVERRIDE; virtual gfx::Size GetPreferredSize() const OVERRIDE;
virtual const char* GetClassName() const OVERRIDE; virtual const char* GetClassName() const OVERRIDE;
virtual void Layout() OVERRIDE; virtual void Layout() OVERRIDE;
virtual void OnPaintBackground(gfx::Canvas* canvas) OVERRIDE;
private: 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; int NonClientTopBorderHeight() const;
// Not owned. // Not owned.
views::Widget* frame_; views::Widget* frame_;
ActivityViewModel* view_model_; ActivityViewModel* view_model_;
views::Label* title_; views::Label* title_;
views::ImageView* icon_;
// Whether overview mode is active.
bool in_overview_;
DISALLOW_COPY_AND_ASSIGN(ActivityFrameView); DISALLOW_COPY_AND_ASSIGN(ActivityFrameView);
}; };
......
...@@ -57,6 +57,12 @@ class ATHENA_EXPORT ActivityViewModel { ...@@ -57,6 +57,12 @@ class ATHENA_EXPORT ActivityViewModel {
// GetRepresentativeColor() should be used to clear the preview area. // GetRepresentativeColor() should be used to clear the preview area.
// Note: We intentionally do not use a layer / view for this. // Note: We intentionally do not use a layer / view for this.
virtual gfx::ImageSkia GetOverviewModeImage() = 0; 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 } // namespace athena
......
...@@ -140,6 +140,17 @@ gfx::ImageSkia AppActivity::GetOverviewModeImage() { ...@@ -140,6 +140,17 @@ gfx::ImageSkia AppActivity::GetOverviewModeImage() {
return overview_mode_image_; 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() { AppActivity::~AppActivity() {
// If this activity is registered, we unregister it now. // If this activity is registered, we unregister it now.
if (app_activity_registry_) if (app_activity_registry_)
......
...@@ -45,6 +45,8 @@ class AppActivity : public Activity, ...@@ -45,6 +45,8 @@ class AppActivity : public Activity,
virtual views::View* GetContentsView() OVERRIDE; virtual views::View* GetContentsView() OVERRIDE;
virtual void CreateOverviewModeImage() OVERRIDE; virtual void CreateOverviewModeImage() OVERRIDE;
virtual gfx::ImageSkia GetOverviewModeImage() OVERRIDE; virtual gfx::ImageSkia GetOverviewModeImage() OVERRIDE;
virtual void PrepareContentsForOverview() OVERRIDE;
virtual void ResetContentsView() OVERRIDE;
protected: protected:
virtual ~AppActivity(); virtual ~AppActivity();
......
...@@ -90,4 +90,10 @@ gfx::ImageSkia AppActivityProxy::GetOverviewModeImage() { ...@@ -90,4 +90,10 @@ gfx::ImageSkia AppActivityProxy::GetOverviewModeImage() {
return image_; return image_;
} }
void AppActivityProxy::PrepareContentsForOverview() {
}
void AppActivityProxy::ResetContentsView() {
}
} // namespace athena } // namespace athena
...@@ -45,6 +45,8 @@ class AppActivityProxy : public Activity, ...@@ -45,6 +45,8 @@ class AppActivityProxy : public Activity,
virtual views::View* GetContentsView() OVERRIDE; virtual views::View* GetContentsView() OVERRIDE;
virtual void CreateOverviewModeImage() OVERRIDE; virtual void CreateOverviewModeImage() OVERRIDE;
virtual gfx::ImageSkia GetOverviewModeImage() OVERRIDE; virtual gfx::ImageSkia GetOverviewModeImage() OVERRIDE;
virtual void PrepareContentsForOverview() OVERRIDE;
virtual void ResetContentsView() OVERRIDE;
private: private:
// The creator of this object which needs to be informed if the object gets // The creator of this object which needs to be informed if the object gets
......
...@@ -465,6 +465,17 @@ gfx::ImageSkia WebActivity::GetOverviewModeImage() { ...@@ -465,6 +465,17 @@ gfx::ImageSkia WebActivity::GetOverviewModeImage() {
return overview_mode_image_; 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, void WebActivity::TitleWasSet(content::NavigationEntry* entry,
bool explicit_set) { bool explicit_set) {
ActivityManager::Get()->UpdateActivity(this); ActivityManager::Get()->UpdateActivity(this);
......
...@@ -53,6 +53,8 @@ class WebActivity : public Activity, ...@@ -53,6 +53,8 @@ class WebActivity : public Activity,
virtual views::View* GetContentsView() OVERRIDE; virtual views::View* GetContentsView() OVERRIDE;
virtual void CreateOverviewModeImage() OVERRIDE; virtual void CreateOverviewModeImage() OVERRIDE;
virtual gfx::ImageSkia GetOverviewModeImage() OVERRIDE; virtual gfx::ImageSkia GetOverviewModeImage() OVERRIDE;
virtual void PrepareContentsForOverview() OVERRIDE;
virtual void ResetContentsView() OVERRIDE;
// content::WebContentsObserver: // content::WebContentsObserver:
virtual void TitleWasSet(content::NavigationEntry* entry, virtual void TitleWasSet(content::NavigationEntry* entry,
......
...@@ -55,6 +55,8 @@ class TestActivity : public Activity, ...@@ -55,6 +55,8 @@ class TestActivity : public Activity,
virtual views::View* GetContentsView() OVERRIDE { return view_; } virtual views::View* GetContentsView() OVERRIDE { return view_; }
virtual void CreateOverviewModeImage() OVERRIDE {} virtual void CreateOverviewModeImage() OVERRIDE {}
virtual gfx::ImageSkia GetOverviewModeImage() OVERRIDE { return image_; } virtual gfx::ImageSkia GetOverviewModeImage() OVERRIDE { return image_; }
virtual void PrepareContentsForOverview() OVERRIDE {}
virtual void ResetContentsView() OVERRIDE {}
private: private:
// The presentation values. // The presentation values.
......
...@@ -80,5 +80,11 @@ gfx::ImageSkia SampleActivity::GetOverviewModeImage() { ...@@ -80,5 +80,11 @@ gfx::ImageSkia SampleActivity::GetOverviewModeImage() {
return gfx::ImageSkia(); return gfx::ImageSkia();
} }
void SampleActivity::PrepareContentsForOverview() {
}
void SampleActivity::ResetContentsView() {
}
} // namespace test } // namespace test
} // namespace athena } // namespace athena
...@@ -38,6 +38,8 @@ class SampleActivity : public Activity, ...@@ -38,6 +38,8 @@ class SampleActivity : public Activity,
virtual views::View* GetContentsView() OVERRIDE; virtual views::View* GetContentsView() OVERRIDE;
virtual void CreateOverviewModeImage() OVERRIDE; virtual void CreateOverviewModeImage() OVERRIDE;
virtual gfx::ImageSkia GetOverviewModeImage() OVERRIDE; virtual gfx::ImageSkia GetOverviewModeImage() OVERRIDE;
virtual void PrepareContentsForOverview() OVERRIDE;
virtual void ResetContentsView() OVERRIDE;
SkColor color_; SkColor color_;
SkColor contents_color_; SkColor contents_color_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment