1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file. 4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/ui/screen_capture_notification_ui.h" 6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ash/shell.h" 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/app/chrome_dll_resource.h" 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/ui/views/chrome_views_export.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/generated_resources.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "grit/theme_resources.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h" 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/base/hit_test.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/base/l10n/l10n_util.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/base/resource/resource_bundle.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/views/bubble/bubble_border.h" 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/views/bubble/bubble_frame_view.h" 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/views/controls/button/blue_button.h" 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/views/controls/image_view.h" 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/views/controls/link.h" 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/views/controls/link_listener.h" 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/views/view.h" 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/views/widget/widget.h" 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/views/widget/widget_delegate.h" 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/shadow_types.h" 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(OS_WIN) 28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/views/win/hwnd_util.h" 29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif 30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace { 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst int kMinimumWidth = 460; 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst int kMaximumWidth = 1000; 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst int kHorizontalMargin = 10; 36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst float kWindowAlphaValue = 0.85f; 37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst int kPaddingVertical = 5; 38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst int kPaddingHorizontal = 10; 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace { 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// A ClientView that overrides NonClientHitTest() so that the whole window area 43e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// acts as a window caption, except a rect specified using set_client_rect(). 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// ScreenCaptureNotificationUIViews uses this class to make the notification bar 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// draggable. 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass NotificationBarClientView : public views::ClientView { 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NotificationBarClientView(views::Widget* widget, views::View* view) 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : views::ClientView(widget, view) { 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual ~NotificationBarClientView() {} 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 53e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch void set_client_rect(const gfx::Rect& rect) { rect_ = rect; } 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // views::ClientView overrides. 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual int NonClientHitTest(const gfx::Point& point) OVERRIDE { 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!bounds().Contains(point)) 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return HTNOWHERE; 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // The whole window is HTCAPTION, except the |rect_|. 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (rect_.Contains(gfx::PointAtOffsetFromOrigin(point - bounds().origin()))) 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return HTCLIENT; 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return HTCAPTION; 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect rect_; 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DISALLOW_COPY_AND_ASSIGN(NotificationBarClientView); 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace 73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// ScreenCaptureNotificationUI implementation using Views. 75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass ScreenCaptureNotificationUIViews 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : public ScreenCaptureNotificationUI, 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public views::WidgetDelegateView, 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public views::ButtonListener, 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public views::LinkListener { 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) explicit ScreenCaptureNotificationUIViews(const base::string16& text); 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual ~ScreenCaptureNotificationUIViews(); 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // ScreenCaptureNotificationUI interface. 85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual gfx::NativeViewId OnStarted(const base::Closure& stop_callback) 86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch OVERRIDE; 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // views::View overrides. 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual gfx::Size GetPreferredSize() const OVERRIDE; 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void Layout() OVERRIDE; 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // views::WidgetDelegateView overrides. 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void DeleteDelegate() OVERRIDE; 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual views::View* GetContentsView() OVERRIDE; 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual views::ClientView* CreateClientView(views::Widget* widget) OVERRIDE; 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual views::NonClientFrameView* CreateNonClientFrameView( 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::Widget* widget) OVERRIDE; 98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual base::string16 GetWindowTitle() const OVERRIDE; 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual bool ShouldShowWindowTitle() const OVERRIDE; 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual bool ShouldShowCloseButton() const OVERRIDE; 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool CanActivate() const OVERRIDE; 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // views::ButtonListener interface. 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void ButtonPressed(views::Button* sender, 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const ui::Event& event) OVERRIDE; 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // views::LinkListener interface. 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE; 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Helper to call |stop_callback_|. 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void NotifyStopped(); 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16 text_; 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Closure stop_callback_; 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NotificationBarClientView* client_view_; 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::ImageView* gripper_; 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::Label* label_; 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::BlueButton* stop_button_; 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) views::Link* hide_link_; 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DISALLOW_COPY_AND_ASSIGN(ScreenCaptureNotificationUIViews); 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben MurdochScreenCaptureNotificationUIViews::ScreenCaptureNotificationUIViews( 126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& text) 1273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch : text_(text), 1283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch client_view_(NULL), 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gripper_(NULL), 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch label_(NULL), 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stop_button_(NULL), 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) hide_link_(NULL) { 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch set_owned_by_client(); 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gripper_ = new views::ImageView(); 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gripper_->SetImage( 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IDR_SCREEN_CAPTURE_NOTIFICATION_GRIP)); 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddChildView(gripper_); 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch label_ = new views::Label(); 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddChildView(label_); 143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 stop_text = 145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch l10n_util::GetStringUTF16(IDS_MEDIA_SCREEN_CAPTURE_NOTIFICATION_STOP); 146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stop_button_ = new views::BlueButton(this, stop_text); 147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddChildView(stop_button_); 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(jiayl): IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON is used for the need to 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // merge to M34. Change it to a new IDS_ after the merge. 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) hide_link_ = new views::Link( 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON)); 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) hide_link_->set_listener(this); 154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch hide_link_->SetUnderline(false); 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AddChildView(hide_link_); 156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochScreenCaptureNotificationUIViews::~ScreenCaptureNotificationUIViews() { 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stop_callback_.Reset(); 160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delete GetWidget(); 161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 163effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochgfx::NativeViewId ScreenCaptureNotificationUIViews::OnStarted( 1643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch const base::Closure& stop_callback) { 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stop_callback_ = stop_callback; 166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) label_->SetElideBehavior(gfx::ELIDE_MIDDLE); 168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); 1693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch label_->SetText(text_); 170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::Widget* widget = new views::Widget; 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); 174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch params.delegate = this; 175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch params.remove_standard_frame = true; 178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch params.keep_on_top = true; 179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(sergeyu): The notification bar must be shown on the monitor that's 181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // being captured. Make sure it's always the case. Currently we always capture 182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // the primary monitor. 183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ash::Shell::HasInstance()) 184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch params.context = ash::Shell::GetPrimaryRootWindow(); 185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch widget->set_frame_type(views::Widget::FRAME_TYPE_FORCE_CUSTOM); 187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch widget->Init(params); 188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch widget->SetAlwaysOnTop(true); 189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 190e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch set_background(views::Background::CreateSolidBackground(GetNativeTheme()-> 191e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch GetSystemColor(ui::NativeTheme::kColorId_DialogBackground))); 192e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Screen* screen = gfx::Screen::GetNativeScreen(); 194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(sergeyu): Move the notification to the display being captured when 195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // per-display screen capture is supported. 196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect work_area = screen->GetPrimaryDisplay().work_area(); 197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Place the bar in the center of the bottom of the display. 199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Size size = widget->non_client_view()->GetPreferredSize(); 200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect bounds( 201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch work_area.x() + work_area.width() / 2 - size.width() / 2, 202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch work_area.y() + work_area.height() - size.height(), 203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch size.width(), size.height()); 204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch widget->SetBounds(bounds); 205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch widget->Show(); 2060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // This has to be called after Show() to have effect. 2070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch widget->SetOpacity(0xFF * kWindowAlphaValue); 208effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 209effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(OS_WIN) 210effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return gfx::NativeViewId(views::HWNDForWidget(widget)); 211effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#else 212effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return 0; 213effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif 214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size ScreenCaptureNotificationUIViews::GetPreferredSize() const { 217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Size grip_size = gripper_->GetPreferredSize(); 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Size label_size = label_->GetPreferredSize(); 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Size stop_button_size = stop_button_->GetPreferredSize(); 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Size hide_link_size = hide_link_->GetPreferredSize(); 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int width = kHorizontalMargin * 3 + grip_size.width() + label_size.width() + 222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stop_button_size.width() + hide_link_size.width(); 223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch width = std::max(width, kMinimumWidth); 224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch width = std::min(width, kMaximumWidth); 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return gfx::Size(width, std::max(label_size.height(), 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::max(hide_link_size.height(), 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stop_button_size.height()))); 228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ScreenCaptureNotificationUIViews::Layout() { 231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect grip_rect(gripper_->GetPreferredSize()); 232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) grip_rect.set_y((bounds().height() - grip_rect.height()) / 2); 233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gripper_->SetBoundsRect(grip_rect); 234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect stop_button_rect(stop_button_->GetPreferredSize()); 236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect hide_link_rect(hide_link_->GetPreferredSize()); 237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) hide_link_rect.set_x(bounds().width() - hide_link_rect.width()); 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) hide_link_rect.set_y((bounds().height() - hide_link_rect.height()) / 2); 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) hide_link_->SetBoundsRect(hide_link_rect); 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stop_button_rect.set_x( 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) hide_link_rect.x() - kHorizontalMargin - stop_button_rect.width()); 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stop_button_->SetBoundsRect(stop_button_rect); 245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::Rect label_rect; 247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch label_rect.set_x(grip_rect.right() + kHorizontalMargin); 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) label_rect.set_width( 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stop_button_rect.x() - kHorizontalMargin - label_rect.x()); 250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch label_rect.set_height(bounds().height()); 251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch label_->SetBoundsRect(label_rect); 252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 253e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch client_view_->set_client_rect(gfx::Rect( 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stop_button_rect.x(), stop_button_rect.y(), 255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) stop_button_rect.width() + kHorizontalMargin + hide_link_rect.width(), 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::max(stop_button_rect.height(), hide_link_rect.height()))); 257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ScreenCaptureNotificationUIViews::DeleteDelegate() { 260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NotifyStopped(); 261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochviews::View* ScreenCaptureNotificationUIViews::GetContentsView() { 264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return this; 265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochviews::ClientView* ScreenCaptureNotificationUIViews::CreateClientView( 268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::Widget* widget) { 269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!client_view_); 270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch client_view_ = new NotificationBarClientView(widget, this); 271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return client_view_; 272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochviews::NonClientFrameView* 275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochScreenCaptureNotificationUIViews::CreateNonClientFrameView( 276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::Widget* widget) { 277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch views::BubbleFrameView* frame = new views::BubbleFrameView( 278effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch gfx::Insets(kPaddingVertical, 279effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kPaddingHorizontal, 280effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kPaddingVertical, 281effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kPaddingHorizontal)); 282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SkColor color = widget->GetNativeTheme()->GetSystemColor( 283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ui::NativeTheme::kColorId_DialogBackground); 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) frame->SetBubbleBorder(scoped_ptr<views::BubbleBorder>( 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new views::BubbleBorder(views::BubbleBorder::NONE, 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) views::BubbleBorder::SMALL_SHADOW, 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) color))); 288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return frame; 289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 ScreenCaptureNotificationUIViews::GetWindowTitle() const { 2923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return text_; 293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool ScreenCaptureNotificationUIViews::ShouldShowWindowTitle() const { 296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool ScreenCaptureNotificationUIViews::ShouldShowCloseButton() const { 300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ScreenCaptureNotificationUIViews::CanActivate() const { 304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // When the window is visible, it can be activated so the mouse clicks 305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // can be sent to the window; when the window is minimized, we don't want it 306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // to activate, otherwise it sometimes does not show properly on Windows. 307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return GetWidget() && GetWidget()->IsVisible(); 308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ScreenCaptureNotificationUIViews::ButtonPressed(views::Button* sender, 311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const ui::Event& event) { 312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NotifyStopped(); 313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ScreenCaptureNotificationUIViews::LinkClicked(views::Link* source, 316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int event_flags) { 317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetWidget()->Minimize(); 318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ScreenCaptureNotificationUIViews::NotifyStopped() { 321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!stop_callback_.is_null()) { 322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Closure callback = stop_callback_; 323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stop_callback_.Reset(); 324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback.Run(); 325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace 329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochscoped_ptr<ScreenCaptureNotificationUI> ScreenCaptureNotificationUI::Create( 331a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& text) { 332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return scoped_ptr<ScreenCaptureNotificationUI>( 3333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch new ScreenCaptureNotificationUIViews(text)); 334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 335