Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "chrome/browser/ui/screen_capture_notification_ui.h" | 5 #include "chrome/browser/ui/screen_capture_notification_ui.h" |
| 6 | 6 |
| 7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
| 8 #include "chrome/app/chrome_dll_resource.h" | 8 #include "chrome/app/chrome_dll_resource.h" |
| 9 #include "chrome/browser/ui/views/chrome_views_export.h" | 9 #include "chrome/browser/ui/views/chrome_views_export.h" |
| 10 #include "grit/generated_resources.h" | 10 #include "grit/generated_resources.h" |
| 11 #include "grit/theme_resources.h" | 11 #include "grit/theme_resources.h" |
| 12 #include "ui/aura/window_event_dispatcher.h" | 12 #include "ui/aura/window_event_dispatcher.h" |
| 13 #include "ui/base/hit_test.h" | 13 #include "ui/base/hit_test.h" |
| 14 #include "ui/base/l10n/l10n_util.h" | 14 #include "ui/base/l10n/l10n_util.h" |
| 15 #include "ui/base/resource/resource_bundle.h" | 15 #include "ui/base/resource/resource_bundle.h" |
| 16 #include "ui/views/bubble/bubble_border.h" | 16 #include "ui/views/bubble/bubble_border.h" |
| 17 #include "ui/views/bubble/bubble_frame_view.h" | 17 #include "ui/views/bubble/bubble_frame_view.h" |
| 18 #include "ui/views/controls/button/blue_button.h" | 18 #include "ui/views/controls/button/blue_button.h" |
| 19 #include "ui/views/controls/image_view.h" | 19 #include "ui/views/controls/image_view.h" |
| 20 #include "ui/views/controls/link.h" | |
| 21 #include "ui/views/controls/link_listener.h" | |
| 20 #include "ui/views/corewm/shadow_types.h" | 22 #include "ui/views/corewm/shadow_types.h" |
| 21 #include "ui/views/layout/box_layout.h" | 23 #include "ui/views/layout/box_layout.h" |
| 22 #include "ui/views/view.h" | 24 #include "ui/views/view.h" |
| 23 #include "ui/views/widget/widget.h" | 25 #include "ui/views/widget/widget.h" |
| 24 #include "ui/views/widget/widget_delegate.h" | 26 #include "ui/views/widget/widget_delegate.h" |
| 25 | 27 |
| 26 namespace { | 28 namespace { |
| 27 | 29 |
| 28 const int kMinimumWidth = 460; | 30 const int kMinimumWidth = 460; |
| 29 const int kMaximumWidth = 1000; | 31 const int kMaximumWidth = 1000; |
| 30 const int kHorizontalMargin = 10; | 32 const int kHorizontalMargin = 10; |
| 31 const int kPadding = 5; | 33 const int kPadding = 5; |
| 32 const int kPaddingLeft = 10; | 34 const int kPaddingLeft = 10; |
| 33 | 35 |
| 34 namespace { | 36 namespace { |
| 35 | 37 |
| 36 // A ClientView that overrides NonClientHitTest() so that the whole window area | 38 // A ClientView that overrides NonClientHitTest() so that the whole window area |
| 37 // acts as a window caption, except a rect specified using SetClientRect(). | 39 // acts as a window caption, except a rect specified using SetClientRect(). |
| 38 // ScreenCaptureNotificationUIViews uses this class to make the notification bar | 40 // ScreenCaptureNotificationUIViews uses this class to make the notification bar |
| 39 // draggable. | 41 // draggable. |
| 40 class NotificationBarClientView : public views::ClientView { | 42 class NotificationBarClientView : public views::ClientView { |
| 41 public: | 43 public: |
| 42 NotificationBarClientView(views::Widget* widget, views::View* view) | 44 NotificationBarClientView(views::Widget* widget, views::View* view) |
| 43 : views::ClientView(widget, view) { | 45 : views::ClientView(widget, view) { |
|
msw
2014/03/12 18:32:25
I know this isn't directly related to the issue, b
jiayl
2014/03/12 19:08:34
I'm not comfortable adding unrelated change to thi
msw
2014/03/12 19:37:25
I filed http://crbug.com/351839
| |
| 44 } | 46 } |
| 45 virtual ~NotificationBarClientView() {} | 47 virtual ~NotificationBarClientView() {} |
| 46 | 48 |
| 47 void SetClientRect(const gfx::Rect& rect) { | 49 void SetClientRect(const gfx::Rect& rect) { |
| 48 rect_ = rect; | 50 rect_ = rect; |
| 49 } | 51 } |
| 50 | 52 |
| 51 // views::ClientView overrides. | 53 // views::ClientView overrides. |
| 52 virtual int NonClientHitTest(const gfx::Point& point) OVERRIDE { | 54 virtual int NonClientHitTest(const gfx::Point& point) OVERRIDE { |
| 53 if (!bounds().Contains(point)) | 55 if (!bounds().Contains(point)) |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 64 | 66 |
| 65 DISALLOW_COPY_AND_ASSIGN(NotificationBarClientView); | 67 DISALLOW_COPY_AND_ASSIGN(NotificationBarClientView); |
| 66 }; | 68 }; |
| 67 | 69 |
| 68 } // namespace | 70 } // namespace |
| 69 | 71 |
| 70 // ScreenCaptureNotificationUI implementation using Views. | 72 // ScreenCaptureNotificationUI implementation using Views. |
| 71 class ScreenCaptureNotificationUIViews | 73 class ScreenCaptureNotificationUIViews |
| 72 : public ScreenCaptureNotificationUI, | 74 : public ScreenCaptureNotificationUI, |
| 73 public views::WidgetDelegateView, | 75 public views::WidgetDelegateView, |
| 74 public views::ButtonListener { | 76 public views::ButtonListener, |
| 77 public views::LinkListener { | |
| 75 public: | 78 public: |
| 76 explicit ScreenCaptureNotificationUIViews(const base::string16& text); | 79 explicit ScreenCaptureNotificationUIViews(const base::string16& text); |
| 77 virtual ~ScreenCaptureNotificationUIViews(); | 80 virtual ~ScreenCaptureNotificationUIViews(); |
| 78 | 81 |
| 79 // ScreenCaptureNotificationUI interface. | 82 // ScreenCaptureNotificationUI interface. |
| 80 virtual void OnStarted(const base::Closure& stop_callback) OVERRIDE; | 83 virtual void OnStarted(const base::Closure& stop_callback) OVERRIDE; |
| 81 | 84 |
| 82 // views::View overrides. | 85 // views::View overrides. |
| 83 virtual gfx::Size GetPreferredSize() OVERRIDE; | 86 virtual gfx::Size GetPreferredSize() OVERRIDE; |
| 84 virtual void Layout() OVERRIDE; | 87 virtual void Layout() OVERRIDE; |
| 85 | 88 |
| 86 // views::WidgetDelegateView overrides. | 89 // views::WidgetDelegateView overrides. |
| 87 virtual void DeleteDelegate() OVERRIDE; | 90 virtual void DeleteDelegate() OVERRIDE; |
| 88 virtual views::View* GetContentsView() OVERRIDE; | 91 virtual views::View* GetContentsView() OVERRIDE; |
| 89 virtual views::ClientView* CreateClientView(views::Widget* widget) OVERRIDE; | 92 virtual views::ClientView* CreateClientView(views::Widget* widget) OVERRIDE; |
| 90 virtual views::NonClientFrameView* CreateNonClientFrameView( | 93 virtual views::NonClientFrameView* CreateNonClientFrameView( |
| 91 views::Widget* widget) OVERRIDE; | 94 views::Widget* widget) OVERRIDE; |
| 92 virtual base::string16 GetWindowTitle() const OVERRIDE; | 95 virtual base::string16 GetWindowTitle() const OVERRIDE; |
| 93 virtual bool ShouldShowWindowTitle() const OVERRIDE; | 96 virtual bool ShouldShowWindowTitle() const OVERRIDE; |
| 94 virtual bool ShouldShowCloseButton() const OVERRIDE; | 97 virtual bool ShouldShowCloseButton() const OVERRIDE; |
| 98 virtual bool CanActivate() const OVERRIDE; | |
| 95 | 99 |
| 96 // views::ButtonListener interface. | 100 // views::ButtonListener interface. |
| 97 virtual void ButtonPressed(views::Button* sender, | 101 virtual void ButtonPressed(views::Button* sender, |
| 98 const ui::Event& event) OVERRIDE; | 102 const ui::Event& event) OVERRIDE; |
| 99 | 103 |
| 104 // views::LinkListener interface. | |
| 105 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE; | |
| 106 | |
| 100 private: | 107 private: |
| 101 // Helper to call |stop_callback_|. | 108 // Helper to call |stop_callback_|. |
| 102 void NotifyStopped(); | 109 void NotifyStopped(); |
| 103 | 110 |
| 104 const base::string16 text_; | 111 const base::string16 text_; |
| 105 base::Closure stop_callback_; | 112 base::Closure stop_callback_; |
| 106 NotificationBarClientView* client_view_; | 113 NotificationBarClientView* client_view_; |
| 107 views::ImageView* gripper_; | 114 views::ImageView* gripper_; |
| 108 views::Label* label_; | 115 views::Label* label_; |
| 109 views::BlueButton* stop_button_; | 116 views::BlueButton* stop_button_; |
| 117 views::Link* hide_link_; | |
| 110 | 118 |
| 111 DISALLOW_COPY_AND_ASSIGN(ScreenCaptureNotificationUIViews); | 119 DISALLOW_COPY_AND_ASSIGN(ScreenCaptureNotificationUIViews); |
| 112 }; | 120 }; |
| 113 | 121 |
| 114 ScreenCaptureNotificationUIViews::ScreenCaptureNotificationUIViews( | 122 ScreenCaptureNotificationUIViews::ScreenCaptureNotificationUIViews( |
| 115 const base::string16& text) | 123 const base::string16& text) |
| 116 : text_(text), | 124 : text_(text), |
| 117 client_view_(NULL), | 125 client_view_(NULL), |
| 118 gripper_(NULL), | 126 gripper_(NULL), |
| 119 label_(NULL), | 127 label_(NULL), |
| 120 stop_button_(NULL) { | 128 stop_button_(NULL), |
| 129 hide_link_(NULL) { | |
| 121 set_owned_by_client(); | 130 set_owned_by_client(); |
| 122 | 131 |
| 123 set_background(views::Background::CreateSolidBackground(GetNativeTheme()-> | 132 set_background(views::Background::CreateSolidBackground(GetNativeTheme()-> |
| 124 GetSystemColor(ui::NativeTheme::kColorId_DialogBackground))); | 133 GetSystemColor(ui::NativeTheme::kColorId_DialogBackground))); |
| 125 | 134 |
| 126 gripper_ = new views::ImageView(); | 135 gripper_ = new views::ImageView(); |
| 127 gripper_->SetImage( | 136 gripper_->SetImage( |
| 128 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | 137 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
| 129 IDR_SCREEN_CAPTURE_NOTIFICATION_GRIP)); | 138 IDR_SCREEN_CAPTURE_NOTIFICATION_GRIP)); |
| 130 AddChildView(gripper_); | 139 AddChildView(gripper_); |
| 131 | 140 |
| 132 label_ = new views::Label(); | 141 label_ = new views::Label(); |
| 133 AddChildView(label_); | 142 AddChildView(label_); |
| 134 | 143 |
| 135 base::string16 stop_text = | 144 base::string16 stop_text = |
| 136 l10n_util::GetStringUTF16(IDS_MEDIA_SCREEN_CAPTURE_NOTIFICATION_STOP); | 145 l10n_util::GetStringUTF16(IDS_MEDIA_SCREEN_CAPTURE_NOTIFICATION_STOP); |
| 137 stop_button_ = new views::BlueButton(this, stop_text); | 146 stop_button_ = new views::BlueButton(this, stop_text); |
| 138 AddChildView(stop_button_); | 147 AddChildView(stop_button_); |
| 148 | |
| 149 hide_link_ = new views::Link( | |
| 150 l10n_util::GetStringUTF16(IDS_MEDIA_SCREEN_CAPTURE_NOTIFICATION_HIDE)); | |
| 151 hide_link_->set_listener(this); | |
| 152 AddChildView(hide_link_); | |
| 139 } | 153 } |
| 140 | 154 |
| 141 ScreenCaptureNotificationUIViews::~ScreenCaptureNotificationUIViews() { | 155 ScreenCaptureNotificationUIViews::~ScreenCaptureNotificationUIViews() { |
| 142 stop_callback_.Reset(); | 156 stop_callback_.Reset(); |
| 143 delete GetWidget(); | 157 delete GetWidget(); |
| 144 } | 158 } |
| 145 | 159 |
| 146 void ScreenCaptureNotificationUIViews::OnStarted( | 160 void ScreenCaptureNotificationUIViews::OnStarted( |
| 147 const base::Closure& stop_callback) { | 161 const base::Closure& stop_callback) { |
| 148 stop_callback_ = stop_callback; | 162 stop_callback_ = stop_callback; |
| 149 | 163 |
| 150 label_->SetElideBehavior(views::Label::ELIDE_IN_MIDDLE); | 164 label_->SetElideBehavior(views::Label::ELIDE_IN_MIDDLE); |
| 151 label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 165 label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 152 label_->SetText(text_); | 166 label_->SetText(text_); |
| 153 | 167 |
| 154 views::Widget* widget = new views::Widget; | 168 views::Widget* widget = new views::Widget; |
| 155 | 169 |
| 156 views::Widget::InitParams params; | 170 views::Widget::InitParams params; |
| 157 params.delegate = this; | 171 params.delegate = this; |
| 158 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 172 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 159 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 173 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
| 160 params.remove_standard_frame = true; | 174 params.remove_standard_frame = true; |
| 161 params.keep_on_top = true; | 175 params.keep_on_top = true; |
| 162 params.top_level = true; | 176 params.top_level = true; |
| 163 params.can_activate = false; | 177 // Make sure can_activate is true so the window icon will show in the taskbar. |
| 178 params.can_activate = true; | |
| 164 | 179 |
| 165 #if defined(USE_ASH) | 180 #if defined(USE_ASH) |
| 166 // TODO(sergeyu): The notification bar must be shown on the monitor that's | 181 // TODO(sergeyu): The notification bar must be shown on the monitor that's |
| 167 // being captured. Make sure it's always the case. Currently we always capture | 182 // being captured. Make sure it's always the case. Currently we always capture |
| 168 // the primary monitor. | 183 // the primary monitor. |
| 169 if (ash::Shell::HasInstance()) | 184 if (ash::Shell::HasInstance()) |
| 170 params.context = ash::Shell::GetPrimaryRootWindow(); | 185 params.context = ash::Shell::GetPrimaryRootWindow(); |
| 171 #endif | 186 #endif |
| 172 | 187 |
| 173 widget->set_frame_type(views::Widget::FRAME_TYPE_FORCE_CUSTOM); | 188 widget->set_frame_type(views::Widget::FRAME_TYPE_FORCE_CUSTOM); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 185 work_area.x() + work_area.width() / 2 - size.width() / 2, | 200 work_area.x() + work_area.width() / 2 - size.width() / 2, |
| 186 work_area.y() + work_area.height() - size.height(), | 201 work_area.y() + work_area.height() - size.height(), |
| 187 size.width(), size.height()); | 202 size.width(), size.height()); |
| 188 widget->SetBounds(bounds); | 203 widget->SetBounds(bounds); |
| 189 | 204 |
| 190 widget->Show(); | 205 widget->Show(); |
| 191 } | 206 } |
| 192 | 207 |
| 193 gfx::Size ScreenCaptureNotificationUIViews::GetPreferredSize() { | 208 gfx::Size ScreenCaptureNotificationUIViews::GetPreferredSize() { |
| 194 gfx::Size grip_size = gripper_->GetPreferredSize(); | 209 gfx::Size grip_size = gripper_->GetPreferredSize(); |
| 195 gfx::Size label_size = child_at(1)->GetPreferredSize(); | 210 gfx::Size label_size = label_->GetPreferredSize(); |
| 196 gfx::Size button_size = child_at(2)->GetPreferredSize(); | 211 gfx::Size stop_button_size = stop_button_->GetPreferredSize(); |
| 197 int width = kHorizontalMargin * 2 + grip_size.width() + label_size.width() + | 212 gfx::Size hide_link_size = hide_link_->GetPreferredSize(); |
| 198 button_size.width(); | 213 int width = kHorizontalMargin * 3 + grip_size.width() + label_size.width() + |
| 214 stop_button_size.width() + hide_link_size.width(); | |
| 199 width = std::max(width, kMinimumWidth); | 215 width = std::max(width, kMinimumWidth); |
| 200 width = std::min(width, kMaximumWidth); | 216 width = std::min(width, kMaximumWidth); |
| 201 return gfx::Size(width, std::max(label_size.height(), button_size.height())); | 217 return gfx::Size(width, std::max(label_size.height(), |
| 218 std::max(hide_link_size.height(), | |
| 219 stop_button_size.height()))); | |
| 202 } | 220 } |
| 203 | 221 |
| 204 void ScreenCaptureNotificationUIViews::Layout() { | 222 void ScreenCaptureNotificationUIViews::Layout() { |
| 205 gfx::Rect grip_rect(gripper_->GetPreferredSize()); | 223 gfx::Rect grip_rect(gripper_->GetPreferredSize()); |
| 206 grip_rect.set_y(bounds().height() / 2 - grip_rect.height() / 2); | 224 grip_rect.set_y((bounds().height() - grip_rect.height()) / 2); |
| 207 gripper_->SetBoundsRect(grip_rect); | 225 gripper_->SetBoundsRect(grip_rect); |
| 208 | 226 |
| 209 gfx::Rect button_rect(stop_button_->GetPreferredSize()); | 227 gfx::Rect stop_button_rect(stop_button_->GetPreferredSize()); |
| 210 button_rect.set_x(bounds().width() - button_rect.width()); | 228 gfx::Rect hide_link_rect(hide_link_->GetPreferredSize()); |
| 211 stop_button_->SetBoundsRect(button_rect); | 229 |
| 230 hide_link_rect.set_x(bounds().width() - hide_link_rect.width()); | |
|
msw
2014/03/12 18:32:25
I think this link looks weird with no padding on t
jiayl
2014/03/12 19:08:34
The window padding is set through
views::BubbleFra
| |
| 231 hide_link_rect.set_y((bounds().height() - hide_link_rect.height()) / 2); | |
| 232 hide_link_->SetBoundsRect(hide_link_rect); | |
| 233 | |
| 234 stop_button_rect.set_x( | |
| 235 hide_link_rect.x() - kHorizontalMargin - stop_button_rect.width()); | |
| 236 stop_button_->SetBoundsRect(stop_button_rect); | |
| 212 | 237 |
| 213 gfx::Rect label_rect; | 238 gfx::Rect label_rect; |
| 214 label_rect.set_x(grip_rect.right() + kHorizontalMargin); | 239 label_rect.set_x(grip_rect.right() + kHorizontalMargin); |
| 215 label_rect.set_width(button_rect.x() - kHorizontalMargin - label_rect.x()); | 240 label_rect.set_width( |
| 241 stop_button_rect.x() - kHorizontalMargin - label_rect.x()); | |
| 216 label_rect.set_height(bounds().height()); | 242 label_rect.set_height(bounds().height()); |
| 217 label_->SetBoundsRect(label_rect); | 243 label_->SetBoundsRect(label_rect); |
| 218 | 244 |
| 219 client_view_->SetClientRect(button_rect); | 245 client_view_->SetClientRect(gfx::Rect( |
| 246 stop_button_rect.x(), stop_button_rect.y(), | |
| 247 stop_button_rect.width() + kHorizontalMargin + hide_link_rect.width(), | |
| 248 std::max(stop_button_rect.height(), hide_link_rect.height()))); | |
| 220 } | 249 } |
| 221 | 250 |
| 222 void ScreenCaptureNotificationUIViews::DeleteDelegate() { | 251 void ScreenCaptureNotificationUIViews::DeleteDelegate() { |
| 223 NotifyStopped(); | 252 NotifyStopped(); |
| 224 } | 253 } |
| 225 | 254 |
| 226 views::View* ScreenCaptureNotificationUIViews::GetContentsView() { | 255 views::View* ScreenCaptureNotificationUIViews::GetContentsView() { |
| 227 return this; | 256 return this; |
| 228 } | 257 } |
| 229 | 258 |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 253 } | 282 } |
| 254 | 283 |
| 255 bool ScreenCaptureNotificationUIViews::ShouldShowWindowTitle() const { | 284 bool ScreenCaptureNotificationUIViews::ShouldShowWindowTitle() const { |
| 256 return false; | 285 return false; |
| 257 } | 286 } |
| 258 | 287 |
| 259 bool ScreenCaptureNotificationUIViews::ShouldShowCloseButton() const { | 288 bool ScreenCaptureNotificationUIViews::ShouldShowCloseButton() const { |
| 260 return false; | 289 return false; |
| 261 } | 290 } |
| 262 | 291 |
| 292 bool ScreenCaptureNotificationUIViews::CanActivate() const { | |
| 293 // If we do not override this method, the window sometimes does not properly | |
| 294 // restore to its normal size on Windows. | |
| 295 return false; | |
| 296 } | |
| 297 | |
| 263 void ScreenCaptureNotificationUIViews::ButtonPressed(views::Button* sender, | 298 void ScreenCaptureNotificationUIViews::ButtonPressed(views::Button* sender, |
| 264 const ui::Event& event) { | 299 const ui::Event& event) { |
| 265 NotifyStopped(); | 300 NotifyStopped(); |
| 266 } | 301 } |
| 267 | 302 |
| 303 void ScreenCaptureNotificationUIViews::LinkClicked(views::Link* source, | |
| 304 int event_flags) { | |
| 305 GetWidget()->Minimize(); | |
| 306 } | |
| 307 | |
| 268 void ScreenCaptureNotificationUIViews::NotifyStopped() { | 308 void ScreenCaptureNotificationUIViews::NotifyStopped() { |
| 269 if (!stop_callback_.is_null()) { | 309 if (!stop_callback_.is_null()) { |
| 270 base::Closure callback = stop_callback_; | 310 base::Closure callback = stop_callback_; |
| 271 stop_callback_.Reset(); | 311 stop_callback_.Reset(); |
| 272 callback.Run(); | 312 callback.Run(); |
| 273 } | 313 } |
| 274 } | 314 } |
| 275 | 315 |
| 276 } // namespace | 316 } // namespace |
| 277 | 317 |
| 278 scoped_ptr<ScreenCaptureNotificationUI> ScreenCaptureNotificationUI::Create( | 318 scoped_ptr<ScreenCaptureNotificationUI> ScreenCaptureNotificationUI::Create( |
| 279 const base::string16& text) { | 319 const base::string16& text) { |
| 280 return scoped_ptr<ScreenCaptureNotificationUI>( | 320 return scoped_ptr<ScreenCaptureNotificationUI>( |
| 281 new ScreenCaptureNotificationUIViews(text)); | 321 new ScreenCaptureNotificationUIViews(text)); |
| 282 } | 322 } |
| OLD | NEW |