Add a minor text member to ui::MenuModel.
[chromium-blink-merge.git] / chrome / browser / ui / views / screen_capture_notification_ui_views.cc
blob04433336d5418a8dea23ba86ae1a23d3589f129f
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
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/screen_capture_notification_ui.h"
7 #include "ash/shell.h"
8 #include "chrome/app/chrome_dll_resource.h"
9 #include "chrome/browser/ui/views/chrome_views_export.h"
10 #include "grit/generated_resources.h"
11 #include "grit/theme_resources.h"
12 #include "ui/aura/root_window.h"
13 #include "ui/base/hit_test.h"
14 #include "ui/base/l10n/l10n_util.h"
15 #include "ui/base/resource/resource_bundle.h"
16 #include "ui/views/bubble/bubble_border.h"
17 #include "ui/views/bubble/bubble_frame_view.h"
18 #include "ui/views/controls/button/blue_button.h"
19 #include "ui/views/controls/image_view.h"
20 #include "ui/views/corewm/shadow_types.h"
21 #include "ui/views/layout/box_layout.h"
22 #include "ui/views/view.h"
23 #include "ui/views/widget/widget.h"
24 #include "ui/views/widget/widget_delegate.h"
26 namespace {
28 const int kMinimumWidth = 460;
29 const int kMaximumWidth = 1000;
30 const int kHorizontalMargin = 10;
31 const int kPadding = 5;
32 const int kPaddingLeft = 10;
34 namespace {
36 // A ClientView that overrides NonClientHitTest() so that the whole window area
37 // acts as a window caption, except a rect specified using SetClientRect().
38 // ScreenCaptureNotificationUIViews uses this class to make the notification bar
39 // draggable.
40 class NotificationBarClientView : public views::ClientView {
41 public:
42 NotificationBarClientView(views::Widget* widget, views::View* view)
43 : views::ClientView(widget, view) {
45 virtual ~NotificationBarClientView() {}
47 void SetClientRect(const gfx::Rect& rect) {
48 rect_ = rect;
51 // views::ClientView overrides.
52 virtual int NonClientHitTest(const gfx::Point& point) OVERRIDE {
53 if (!bounds().Contains(point))
54 return HTNOWHERE;
55 // The whole window is HTCAPTION, except the |rect_|.
56 if (rect_.Contains(gfx::PointAtOffsetFromOrigin(point - bounds().origin())))
57 return HTCLIENT;
59 return HTCAPTION;
62 private:
63 gfx::Rect rect_;
65 DISALLOW_COPY_AND_ASSIGN(NotificationBarClientView);
68 } // namespace
70 // ScreenCaptureNotificationUI implementation using Views.
71 class ScreenCaptureNotificationUIViews
72 : public ScreenCaptureNotificationUI,
73 public views::WidgetDelegateView,
74 public views::ButtonListener {
75 public:
76 explicit ScreenCaptureNotificationUIViews(const string16& text);
77 virtual ~ScreenCaptureNotificationUIViews();
79 // ScreenCaptureNotificationUI interface.
80 virtual void OnStarted(const base::Closure& stop_callback) OVERRIDE;
82 // views::View overrides.
83 virtual gfx::Size GetPreferredSize() OVERRIDE;
84 virtual void Layout() OVERRIDE;
86 // views::WidgetDelegateView overrides.
87 virtual void DeleteDelegate() OVERRIDE;
88 virtual views::View* GetContentsView() OVERRIDE;
89 virtual views::ClientView* CreateClientView(views::Widget* widget) OVERRIDE;
90 virtual views::NonClientFrameView* CreateNonClientFrameView(
91 views::Widget* widget) OVERRIDE;
92 virtual string16 GetWindowTitle() const OVERRIDE;
93 virtual bool ShouldShowWindowTitle() const OVERRIDE;
94 virtual bool ShouldShowCloseButton() const OVERRIDE;
96 // views::ButtonListener interface.
97 virtual void ButtonPressed(views::Button* sender,
98 const ui::Event& event) OVERRIDE;
100 private:
101 // Helper to call |stop_callback_|.
102 void NotifyStopped();
104 const string16 text_;
105 base::Closure stop_callback_;
106 NotificationBarClientView* client_view_;
107 views::ImageView* gripper_;
108 views::Label* label_;
109 views::BlueButton* stop_button_;
111 DISALLOW_COPY_AND_ASSIGN(ScreenCaptureNotificationUIViews);
114 ScreenCaptureNotificationUIViews::ScreenCaptureNotificationUIViews(
115 const string16& text)
116 : text_(text),
117 client_view_(NULL),
118 gripper_(NULL),
119 label_(NULL),
120 stop_button_(NULL) {
121 set_owned_by_client();
123 set_background(views::Background::CreateSolidBackground(GetNativeTheme()->
124 GetSystemColor(ui::NativeTheme::kColorId_DialogBackground)));
126 gripper_ = new views::ImageView();
127 gripper_->SetImage(
128 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
129 IDR_SCREEN_CAPTURE_NOTIFICATION_GRIP));
130 AddChildView(gripper_);
132 label_ = new views::Label();
133 AddChildView(label_);
135 string16 stop_text =
136 l10n_util::GetStringUTF16(IDS_MEDIA_SCREEN_CAPTURE_NOTIFICATION_STOP);
137 stop_button_ = new views::BlueButton(this, stop_text);
138 AddChildView(stop_button_);
141 ScreenCaptureNotificationUIViews::~ScreenCaptureNotificationUIViews() {
142 stop_callback_.Reset();
143 delete GetWidget();
146 void ScreenCaptureNotificationUIViews::OnStarted(
147 const base::Closure& stop_callback) {
148 stop_callback_ = stop_callback;
150 label_->SetElideBehavior(views::Label::ELIDE_IN_MIDDLE);
151 label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
152 label_->SetText(text_);
154 views::Widget* widget = new views::Widget;
156 views::Widget::InitParams params;
157 params.delegate = this;
158 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
159 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
160 params.remove_standard_frame = true;
161 params.keep_on_top = true;
162 params.top_level = true;
163 params.can_activate = false;
165 #if defined(USE_ASH)
166 // 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
168 // the primary monitor.
169 if (ash::Shell::HasInstance())
170 params.context = ash::Shell::GetPrimaryRootWindow();
171 #endif
173 widget->set_frame_type(views::Widget::FRAME_TYPE_FORCE_CUSTOM);
174 widget->Init(params);
175 widget->SetAlwaysOnTop(true);
177 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
178 // TODO(sergeyu): Move the notification to the display being captured when
179 // per-display screen capture is supported.
180 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
182 // Place the bar in the center of the bottom of the display.
183 gfx::Size size = widget->non_client_view()->GetPreferredSize();
184 gfx::Rect bounds(
185 work_area.x() + work_area.width() / 2 - size.width() / 2,
186 work_area.y() + work_area.height() - size.height(),
187 size.width(), size.height());
188 widget->SetBounds(bounds);
190 widget->Show();
193 gfx::Size ScreenCaptureNotificationUIViews::GetPreferredSize() {
194 gfx::Size grip_size = gripper_->GetPreferredSize();
195 gfx::Size label_size = child_at(1)->GetPreferredSize();
196 gfx::Size button_size = child_at(2)->GetPreferredSize();
197 int width = kHorizontalMargin * 2 + grip_size.width() + label_size.width() +
198 button_size.width();
199 width = std::max(width, kMinimumWidth);
200 width = std::min(width, kMaximumWidth);
201 return gfx::Size(width, std::max(label_size.height(), button_size.height()));
204 void ScreenCaptureNotificationUIViews::Layout() {
205 gfx::Rect grip_rect(gripper_->GetPreferredSize());
206 grip_rect.set_y(bounds().height() / 2 - grip_rect.height() / 2);
207 gripper_->SetBoundsRect(grip_rect);
209 gfx::Rect button_rect(stop_button_->GetPreferredSize());
210 button_rect.set_x(bounds().width() - button_rect.width());
211 stop_button_->SetBoundsRect(button_rect);
213 gfx::Rect label_rect;
214 label_rect.set_x(grip_rect.right() + kHorizontalMargin);
215 label_rect.set_width(button_rect.x() - kHorizontalMargin - label_rect.x());
216 label_rect.set_height(bounds().height());
217 label_->SetBoundsRect(label_rect);
219 client_view_->SetClientRect(button_rect);
222 void ScreenCaptureNotificationUIViews::DeleteDelegate() {
223 NotifyStopped();
226 views::View* ScreenCaptureNotificationUIViews::GetContentsView() {
227 return this;
230 views::ClientView* ScreenCaptureNotificationUIViews::CreateClientView(
231 views::Widget* widget) {
232 DCHECK(!client_view_);
233 client_view_ = new NotificationBarClientView(widget, this);
234 return client_view_;
237 views::NonClientFrameView*
238 ScreenCaptureNotificationUIViews::CreateNonClientFrameView(
239 views::Widget* widget) {
240 views::BubbleFrameView* frame = new views::BubbleFrameView(
241 gfx::Insets(kPadding, kPaddingLeft, kPadding, kPadding));
242 SkColor color = widget->GetNativeTheme()->GetSystemColor(
243 ui::NativeTheme::kColorId_DialogBackground);
244 views::BubbleBorder* border = new views::BubbleBorder(
245 views::BubbleBorder::NONE, views::BubbleBorder::SMALL_SHADOW, color);
246 frame->SetBubbleBorder(border);
247 return frame;
250 string16 ScreenCaptureNotificationUIViews::GetWindowTitle() const {
251 return text_;
254 bool ScreenCaptureNotificationUIViews::ShouldShowWindowTitle() const {
255 return false;
258 bool ScreenCaptureNotificationUIViews::ShouldShowCloseButton() const {
259 return false;
262 void ScreenCaptureNotificationUIViews::ButtonPressed(views::Button* sender,
263 const ui::Event& event) {
264 NotifyStopped();
267 void ScreenCaptureNotificationUIViews::NotifyStopped() {
268 if (!stop_callback_.is_null()) {
269 base::Closure callback = stop_callback_;
270 stop_callback_.Reset();
271 callback.Run();
275 } // namespace
277 scoped_ptr<ScreenCaptureNotificationUI> ScreenCaptureNotificationUI::Create(
278 const string16& text) {
279 return scoped_ptr<ScreenCaptureNotificationUI>(
280 new ScreenCaptureNotificationUIViews(text));