screen_capture_notification_ui_views.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/screen_capture_notification_ui.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/app/chrome_dll_resource.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/chrome_views_export.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/hit_test.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/bubble/bubble_border.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/bubble/bubble_frame_view.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/blue_button.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/image_view.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/link.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/link_listener.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget_delegate.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/wm/core/shadow_types.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/win/hwnd_util.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMinimumWidth = 460;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaximumWidth = 1000;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kHorizontalMargin = 10;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const float kWindowAlphaValue = 0.85f;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kPaddingVertical = 5;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kPaddingHorizontal = 10;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A ClientView that overrides NonClientHitTest() so that the whole window area
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// acts as a window caption, except a rect specified using SetClientRect().
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ScreenCaptureNotificationUIViews uses this class to make the notification bar
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// draggable.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NotificationBarClientView : public views::ClientView {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotificationBarClientView(views::Widget* widget, views::View* view)
49ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      : views::ClientView(widget, view) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~NotificationBarClientView() {}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void SetClientRect(const gfx::Rect& rect) {
54ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    rect_ = rect;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::ClientView overrides.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int NonClientHitTest(const gfx::Point& point) OVERRIDE  {
59ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (!bounds().Contains(point))
603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return HTNOWHERE;
613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // The whole window is HTCAPTION, except the |rect_|.
623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (rect_.Contains(gfx::PointAtOffsetFromOrigin(point - bounds().origin())))
63ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      return HTCLIENT;
64ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return HTCAPTION;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect rect_;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(NotificationBarClientView);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
73ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
74ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}  // namespace
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ScreenCaptureNotificationUI implementation using Views.
77ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochclass ScreenCaptureNotificationUIViews
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public ScreenCaptureNotificationUI,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public views::WidgetDelegateView,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public views::ButtonListener,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public views::LinkListener {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ScreenCaptureNotificationUIViews(const base::string16& text);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ScreenCaptureNotificationUIViews();
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ScreenCaptureNotificationUI interface.
87ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual gfx::NativeViewId OnStarted(const base::Closure& stop_callback)
88ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      OVERRIDE;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::View overrides.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual gfx::Size GetPreferredSize() OVERRIDE;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Layout() OVERRIDE;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::WidgetDelegateView overrides.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DeleteDelegate() OVERRIDE;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual views::View* GetContentsView() OVERRIDE;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual views::ClientView* CreateClientView(views::Widget* widget) OVERRIDE;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual views::NonClientFrameView* CreateNonClientFrameView(
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      views::Widget* widget) OVERRIDE;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual base::string16 GetWindowTitle() const OVERRIDE;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool ShouldShowWindowTitle() const OVERRIDE;
102ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual bool ShouldShowCloseButton() const OVERRIDE;
103ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual bool CanActivate() const OVERRIDE;
104ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // views::ButtonListener interface.
106ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual void ButtonPressed(views::Button* sender,
107ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                             const ui::Event& event) OVERRIDE;
108ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // views::LinkListener interface.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper to call |stop_callback_|.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NotifyStopped();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::string16 text_;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure stop_callback_;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotificationBarClientView* client_view_;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::ImageView* gripper_;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Label* label_;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::BlueButton* stop_button_;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Link* hide_link_;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScreenCaptureNotificationUIViews);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScreenCaptureNotificationUIViews::ScreenCaptureNotificationUIViews(
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::string16& text)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : text_(text),
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      client_view_(NULL),
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gripper_(NULL),
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      label_(NULL),
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      stop_button_(NULL),
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hide_link_(NULL) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set_owned_by_client();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set_background(views::Background::CreateSolidBackground(GetNativeTheme()->
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetSystemColor(ui::NativeTheme::kColorId_DialogBackground)));
139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
140ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  gripper_ = new views::ImageView();
141ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  gripper_->SetImage(
142ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
143ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          IDR_SCREEN_CAPTURE_NOTIFICATION_GRIP));
144ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  AddChildView(gripper_);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  label_ = new views::Label();
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddChildView(label_);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::string16 stop_text =
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_MEDIA_SCREEN_CAPTURE_NOTIFICATION_STOP);
151ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  stop_button_ = new views::BlueButton(this, stop_text);
152ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  AddChildView(stop_button_);
153ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
154ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // TODO(jiayl): IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON is used for the need to
155ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // merge to M34. Change it to a new IDS_ after the merge.
156ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  hide_link_ = new views::Link(
157ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      l10n_util::GetStringUTF16(IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON));
158ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  hide_link_->set_listener(this);
159ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  hide_link_->SetUnderline(false);
160ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  AddChildView(hide_link_);
161ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
162ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
163ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochScreenCaptureNotificationUIViews::~ScreenCaptureNotificationUIViews() {
164ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  stop_callback_.Reset();
165ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  delete GetWidget();
166ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::NativeViewId ScreenCaptureNotificationUIViews::OnStarted(
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Closure& stop_callback) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  stop_callback_ = stop_callback;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
172ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  label_->SetElideBehavior(views::Label::ELIDE_IN_MIDDLE);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  label_->SetText(text_);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Widget* widget = new views::Widget;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Widget::InitParams params;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.delegate = this;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.remove_standard_frame = true;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.keep_on_top = true;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.top_level = true;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure can_activate is true so the window icon will show in the taskbar.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.can_activate = true;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_ASH)
189ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // TODO(sergeyu): The notification bar must be shown on the monitor that's
190ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // being captured. Make sure it's always the case. Currently we always capture
191ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // the primary monitor.
192ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (ash::Shell::HasInstance())
193ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    params.context = ash::Shell::GetPrimaryRootWindow();
194ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#endif
195ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
196ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  widget->set_frame_type(views::Widget::FRAME_TYPE_FORCE_CUSTOM);
197ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  widget->Init(params);
198ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  widget->SetAlwaysOnTop(true);
199ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
200ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  gfx::Screen* screen = gfx::Screen::GetNativeScreen();
201ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // TODO(sergeyu): Move the notification to the display being captured when
202ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // per-display screen capture is supported.
203ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Place the bar in the center of the bottom of the display.
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size size = widget->non_client_view()->GetPreferredSize();
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect bounds(
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      work_area.x() + work_area.width() / 2 - size.width() / 2,
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      work_area.y() + work_area.height() - size.height(),
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size.width(), size.height());
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->SetBounds(bounds);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->SetOpacity(0xFF * kWindowAlphaValue);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget->Show();
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::NativeViewId(views::HWNDForWidget(widget));
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size ScreenCaptureNotificationUIViews::GetPreferredSize() {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size grip_size = gripper_->GetPreferredSize();
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size label_size = label_->GetPreferredSize();
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size stop_button_size = stop_button_->GetPreferredSize();
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size hide_link_size = hide_link_->GetPreferredSize();
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int width = kHorizontalMargin * 3 + grip_size.width() + label_size.width() +
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      stop_button_size.width() + hide_link_size.width();
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  width = std::max(width, kMinimumWidth);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  width = std::min(width, kMaximumWidth);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size(width, std::max(label_size.height(),
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   std::max(hide_link_size.height(),
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            stop_button_size.height())));
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScreenCaptureNotificationUIViews::Layout() {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect grip_rect(gripper_->GetPreferredSize());
2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  grip_rect.set_y((bounds().height() - grip_rect.height()) / 2);
239ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  gripper_->SetBoundsRect(grip_rect);
2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
241ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  gfx::Rect stop_button_rect(stop_button_->GetPreferredSize());
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect hide_link_rect(hide_link_->GetPreferredSize());
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hide_link_rect.set_x(bounds().width() - hide_link_rect.width());
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hide_link_rect.set_y((bounds().height() - hide_link_rect.height()) / 2);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hide_link_->SetBoundsRect(hide_link_rect);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  stop_button_rect.set_x(
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hide_link_rect.x() - kHorizontalMargin - stop_button_rect.width());
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  stop_button_->SetBoundsRect(stop_button_rect);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect label_rect;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  label_rect.set_x(grip_rect.right() + kHorizontalMargin);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  label_rect.set_width(
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      stop_button_rect.x() - kHorizontalMargin - label_rect.x());
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  label_rect.set_height(bounds().height());
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  label_->SetBoundsRect(label_rect);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_view_->SetClientRect(gfx::Rect(
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      stop_button_rect.x(), stop_button_rect.y(),
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      stop_button_rect.width() + kHorizontalMargin + hide_link_rect.width(),
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::max(stop_button_rect.height(), hide_link_rect.height())));
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ScreenCaptureNotificationUIViews::DeleteDelegate() {
266ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  NotifyStopped();
267ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
268ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
269ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochviews::View* ScreenCaptureNotificationUIViews::GetContentsView() {
270ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  return this;
271ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
272ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::ClientView* ScreenCaptureNotificationUIViews::CreateClientView(
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    views::Widget* widget) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!client_view_);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_view_ = new NotificationBarClientView(widget, this);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return client_view_;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::NonClientFrameView*
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScreenCaptureNotificationUIViews::CreateNonClientFrameView(
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    views::Widget* widget) {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::BubbleFrameView* frame = new views::BubbleFrameView(
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Insets(kPaddingVertical,
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  kPaddingHorizontal,
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  kPaddingVertical,
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  kPaddingHorizontal));
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor color = widget->GetNativeTheme()->GetSystemColor(
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::NativeTheme::kColorId_DialogBackground);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frame->SetBubbleBorder(scoped_ptr<views::BubbleBorder>(
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new views::BubbleBorder(views::BubbleBorder::NONE,
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              views::BubbleBorder::SMALL_SHADOW,
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              color)));
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return frame;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::string16 ScreenCaptureNotificationUIViews::GetWindowTitle() const {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return text_;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ScreenCaptureNotificationUIViews::ShouldShowWindowTitle() const {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ScreenCaptureNotificationUIViews::ShouldShowCloseButton() const {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ScreenCaptureNotificationUIViews::CanActivate() const {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When the window is visible, it can be activated so the mouse clicks
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // can be sent to the window; when the window is minimized, we don't want it
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to activate, otherwise it sometimes does not show properly on Windows.
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetWidget() && GetWidget()->IsVisible();
314ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScreenCaptureNotificationUIViews::ButtonPressed(views::Button* sender,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     const ui::Event& event) {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotifyStopped();
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScreenCaptureNotificationUIViews::LinkClicked(views::Link* source,
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   int event_flags) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetWidget()->Minimize();
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScreenCaptureNotificationUIViews::NotifyStopped() {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!stop_callback_.is_null()) {
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Closure callback = stop_callback_;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stop_callback_.Reset();
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run();
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<ScreenCaptureNotificationUI> ScreenCaptureNotificationUI::Create(
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::string16& text) {
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return scoped_ptr<ScreenCaptureNotificationUI>(
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new ScreenCaptureNotificationUIViews(text));
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)