Chromium Code Reviews| 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 |