OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "athena/activity/activity_frame_view.h" | 5 #include "athena/activity/activity_frame_view.h" |
6 | 6 |
7 #include <algorithm> | |
8 #include <vector> | |
9 | |
10 #include "athena/activity/public/activity_view_model.h" | 7 #include "athena/activity/public/activity_view_model.h" |
8 #include "athena/wm/public/window_manager.h" | |
9 #include "third_party/skia/include/core/SkBitmap.h" | |
11 #include "ui/base/hit_test.h" | 10 #include "ui/base/hit_test.h" |
11 #include "ui/gfx/canvas.h" | |
12 #include "ui/gfx/image/image_skia.h" | |
12 #include "ui/views/background.h" | 13 #include "ui/views/background.h" |
13 #include "ui/views/border.h" | 14 #include "ui/views/controls/image_view.h" |
14 #include "ui/views/controls/label.h" | 15 #include "ui/views/controls/label.h" |
15 #include "ui/views/view.h" | 16 #include "ui/views/view.h" |
16 #include "ui/views/widget/widget.h" | 17 #include "ui/views/widget/widget.h" |
17 #include "ui/views/widget/widget_delegate.h" | 18 #include "ui/views/widget/widget_delegate.h" |
19 #include "ui/views/window/client_view.h" | |
18 | 20 |
19 namespace athena { | 21 namespace athena { |
22 namespace { | |
20 | 23 |
21 //////////////////////////////////////////////////////////////////////////////// | 24 // The icon size. |
22 // FrameViewAthena, public: | 25 const int kIconSize = 32; |
26 | |
27 // The distance between the icon and the title when the icon is visible. | |
28 const int kIconTitleSpacing = 5; | |
29 | |
30 // The height of the top border necessary to display the title without the icon. | |
31 const int kDefaultTitleHeight = 25; | |
32 | |
33 // The height of the top border in overview mode. | |
34 const int kOverviewTitleHeight = 55; | |
35 | |
36 // The height of the top border for fullscreen and frameless activities in | |
37 // overview mode. | |
38 const int kOverviewShortTitleHeight = 30; | |
39 | |
40 // The thickness of the left, right and bottom borders in overview mode. | |
41 const int kOverviewBorderThickness = 5; | |
42 | |
43 } // namespace | |
23 | 44 |
24 // static | 45 // static |
25 const char ActivityFrameView::kViewClassName[] = "ActivityFrameView"; | 46 const char ActivityFrameView::kViewClassName[] = "ActivityFrameView"; |
26 | 47 |
27 ActivityFrameView::ActivityFrameView(views::Widget* frame, | 48 ActivityFrameView::ActivityFrameView(views::Widget* frame, |
28 ActivityViewModel* view_model) | 49 ActivityViewModel* view_model) |
29 : frame_(frame), view_model_(view_model), title_(new views::Label) { | 50 : frame_(frame), |
30 title_->SetHorizontalAlignment(gfx::ALIGN_CENTER); | 51 view_model_(view_model), |
52 title_(new views::Label), | |
53 icon_(new views::ImageView), | |
54 in_overview_(false) { | |
31 title_->SetEnabledColor(SkColorSetA(SK_ColorBLACK, 0xe5)); | 55 title_->SetEnabledColor(SkColorSetA(SK_ColorBLACK, 0xe5)); |
32 title_->SetBorder(views::Border::CreateSolidSidedBorder(0, 0, 1, 0, | 56 |
33 SkColorSetA(SK_ColorGRAY, 0x7f))); | 57 SkBitmap bitmap; |
58 bitmap.allocN32Pixels(kIconSize, kIconSize); | |
59 bitmap.eraseARGB(255, 0, 255, 0); | |
60 icon_->SetImage(gfx::ImageSkia::CreateFrom1xBitmap(bitmap)); | |
61 | |
34 AddChildView(title_); | 62 AddChildView(title_); |
63 AddChildView(icon_); | |
sadrul
2014/09/03 16:10:18
Add |icon_| only when entering the overview mode,
sadrul
2014/09/03 20:05:07
ping?
pkotwicz
2014/09/03 20:15:45
Sorry for missing your comment
I believe that you
sadrul
2014/09/03 20:28:43
Sounds good.
| |
64 | |
65 SkColor bgcolor = view_model_->GetRepresentativeColor(); | |
66 set_background(views::Background::CreateSolidBackground(bgcolor)); | |
35 UpdateWindowTitle(); | 67 UpdateWindowTitle(); |
68 | |
69 WindowManager::GetInstance()->AddObserver(this); | |
36 } | 70 } |
37 | 71 |
38 ActivityFrameView::~ActivityFrameView() { | 72 ActivityFrameView::~ActivityFrameView() { |
73 WindowManager::GetInstance()->RemoveObserver(this); | |
39 } | 74 } |
40 | 75 |
41 //////////////////////////////////////////////////////////////////////////////// | |
42 // ActivityFrameView, views::NonClientFrameView overrides: | |
43 | |
44 gfx::Rect ActivityFrameView::GetBoundsForClientView() const { | 76 gfx::Rect ActivityFrameView::GetBoundsForClientView() const { |
45 gfx::Rect client_bounds = bounds(); | 77 gfx::Rect client_bounds = bounds(); |
46 if (view_model_->UsesFrame()) | 78 client_bounds.Inset(NonClientBorderInsets()); |
47 client_bounds.Inset(0, NonClientTopBorderHeight(), 0, 0); | |
48 return client_bounds; | 79 return client_bounds; |
49 } | 80 } |
50 | 81 |
51 gfx::Rect ActivityFrameView::GetWindowBoundsForClientBounds( | 82 gfx::Rect ActivityFrameView::GetWindowBoundsForClientBounds( |
52 const gfx::Rect& client_bounds) const { | 83 const gfx::Rect& client_bounds) const { |
53 gfx::Rect window_bounds = client_bounds; | 84 gfx::Rect window_bounds = client_bounds; |
54 if (view_model_->UsesFrame()) | 85 window_bounds.Inset(-NonClientBorderInsets()); |
55 window_bounds.Inset(0, -NonClientTopBorderHeight(), 0, 0); | |
56 return window_bounds; | 86 return window_bounds; |
57 } | 87 } |
58 | 88 |
59 int ActivityFrameView::NonClientHitTest(const gfx::Point& point) { | 89 int ActivityFrameView::NonClientHitTest(const gfx::Point& point) { |
60 if (frame_->IsFullscreen()) | 90 if (!bounds().Contains(point)) |
61 return 0; | 91 return HTNOWHERE; |
62 if (title_->bounds().Contains(point)) | 92 int client_hit_test = frame_->client_view()->NonClientHitTest(point); |
63 return HTCAPTION; | 93 return (client_hit_test == HTNOWHERE) ? |
64 return 0; | 94 HTCAPTION : client_hit_test; |
sadrul
2014/09/03 16:10:18
This still doesn't look right. We should return HT
pkotwicz
2014/09/03 19:40:59
You're right, I did not take into account the left
| |
65 } | 95 } |
66 | 96 |
67 void ActivityFrameView::GetWindowMask(const gfx::Size& size, | 97 void ActivityFrameView::GetWindowMask(const gfx::Size& size, |
68 gfx::Path* window_mask) { | 98 gfx::Path* window_mask) { |
69 } | 99 } |
70 | 100 |
71 void ActivityFrameView::ResetWindowControls() { | 101 void ActivityFrameView::ResetWindowControls() { |
72 } | 102 } |
73 | 103 |
74 void ActivityFrameView::UpdateWindowIcon() { | 104 void ActivityFrameView::UpdateWindowIcon() { |
sadrul
2014/09/03 16:10:18
Update icon_ here? (https://codereview.chromium.or
pkotwicz
2014/09/03 19:40:59
Yes, when we have a real icon. Currently, |icon_|
sadrul
2014/09/03 20:05:07
Ah, I see. It would be a good idea to plumb the ic
| |
75 } | 105 } |
76 | 106 |
77 void ActivityFrameView::UpdateWindowTitle() { | 107 void ActivityFrameView::UpdateWindowTitle() { |
78 if (!view_model_->UsesFrame()) | 108 if (!view_model_->UsesFrame()) |
79 return; | 109 return; |
80 | 110 |
81 SkColor bgcolor = view_model_->GetRepresentativeColor(); | 111 SkColor bgcolor = view_model_->GetRepresentativeColor(); |
82 title_->set_background(views::Background::CreateSolidBackground(bgcolor)); | 112 set_background(views::Background::CreateSolidBackground(bgcolor)); |
83 title_->SetBackgroundColor(bgcolor); | 113 title_->SetBackgroundColor(bgcolor); |
84 title_->SetText(frame_->widget_delegate()->GetWindowTitle()); | 114 title_->SetText(frame_->widget_delegate()->GetWindowTitle()); |
115 Layout(); | |
85 } | 116 } |
86 | 117 |
87 //////////////////////////////////////////////////////////////////////////////// | |
88 // ActivityFrameView, views::View overrides: | |
89 | |
90 gfx::Size ActivityFrameView::GetPreferredSize() const { | 118 gfx::Size ActivityFrameView::GetPreferredSize() const { |
91 gfx::Size pref = frame_->client_view()->GetPreferredSize(); | 119 gfx::Size pref = frame_->client_view()->GetPreferredSize(); |
92 gfx::Rect bounds(0, 0, pref.width(), pref.height()); | 120 gfx::Rect bounds(0, 0, pref.width(), pref.height()); |
93 return frame_->non_client_view() | 121 return frame_->non_client_view() |
94 ->GetWindowBoundsForClientBounds(bounds) | 122 ->GetWindowBoundsForClientBounds(bounds) |
95 .size(); | 123 .size(); |
96 } | 124 } |
97 | 125 |
98 const char* ActivityFrameView::GetClassName() const { | 126 const char* ActivityFrameView::GetClassName() const { |
99 return kViewClassName; | 127 return kViewClassName; |
100 } | 128 } |
101 | 129 |
102 void ActivityFrameView::Layout() { | 130 void ActivityFrameView::Layout() { |
103 title_->SetBounds(0, 0, width(), NonClientTopBorderHeight()); | 131 if (frame_->IsFullscreen() || !view_model_->UsesFrame()) { |
132 title_->SetVisible(false); | |
133 icon_->SetVisible(false); | |
134 return; | |
135 } | |
136 | |
137 title_->SetVisible(true); | |
138 icon_->SetVisible(in_overview_); | |
139 | |
140 gfx::Size preferred_title_size = title_->GetPreferredSize(); | |
141 int top_height = NonClientTopBorderHeight(); | |
142 int title_x = 0; | |
143 if (in_overview_) { | |
144 int edge = (top_height - kIconSize) / 2; | |
145 icon_->SetBounds(edge, edge, kIconSize, kIconSize); | |
146 | |
147 title_x = icon_->bounds().right() + kIconTitleSpacing; | |
148 } else { | |
149 title_x = (width() - preferred_title_size.width()) / 2; | |
150 } | |
151 | |
152 title_->SetBounds(title_x, | |
153 (top_height - preferred_title_size.height()) / 2, | |
154 preferred_title_size.width(), | |
155 preferred_title_size.height()); | |
sadrul
2014/09/03 16:10:17
Consider using a BoxLayout instead. (in the box la
pkotwicz
2014/09/03 19:40:59
I think that |icon_| and |title_| would need to be
| |
104 } | 156 } |
105 | 157 |
106 //////////////////////////////////////////////////////////////////////////////// | 158 void ActivityFrameView::OnPaintBackground(gfx::Canvas* canvas) { |
107 // ActivityFrameView, private: | 159 View::OnPaintBackground(canvas); |
160 | |
161 gfx::Rect border_bounds = GetLocalBounds(); | |
162 border_bounds.Inset(NonClientBorderInsets()); | |
163 border_bounds.Inset(-1, -1, 0, 0); | |
164 canvas->DrawRect(border_bounds, SkColorSetA(SK_ColorGRAY, 0x7f)); | |
165 } | |
166 | |
167 void ActivityFrameView::OnOverviewModeEnter() { | |
168 view_model_->PrepareContentsForOverview(); | |
169 in_overview_ = true; | |
170 InvalidateLayout(); | |
171 frame_->client_view()->InvalidateLayout(); | |
172 frame_->GetRootView()->Layout(); | |
173 SchedulePaint(); | |
174 } | |
175 | |
176 void ActivityFrameView::OnOverviewModeExit() { | |
177 in_overview_ = false; | |
178 InvalidateLayout(); | |
179 frame_->client_view()->InvalidateLayout(); | |
180 frame_->GetRootView()->Layout(); | |
181 SchedulePaint(); | |
182 view_model_->ResetContentsView(); | |
183 } | |
184 | |
185 void ActivityFrameView::OnActivityOrderHasChanged() { | |
186 } | |
187 | |
188 gfx::Insets ActivityFrameView::NonClientBorderInsets() const { | |
189 int edge_width = in_overview_ ? kOverviewBorderThickness : 0; | |
190 return gfx::Insets(NonClientTopBorderHeight(), | |
191 edge_width, | |
192 edge_width, | |
193 edge_width); | |
194 } | |
108 | 195 |
109 int ActivityFrameView::NonClientTopBorderHeight() const { | 196 int ActivityFrameView::NonClientTopBorderHeight() const { |
110 const int kDefaultTitleHeight = 25; | 197 if (frame_->IsFullscreen() || !view_model_->UsesFrame()) |
111 return frame_->IsFullscreen() ? 0 : kDefaultTitleHeight; | 198 return in_overview_ ? kOverviewShortTitleHeight : 0; |
199 return in_overview_ ? kOverviewTitleHeight : kDefaultTitleHeight; | |
112 } | 200 } |
113 | 201 |
114 } // namespace ash | 202 } // namespace athena |
OLD | NEW |