Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Side by Side Diff: chrome/browser/ui/views/extensions/shell_window_views.cc

Issue 11280173: Rename ShellWindow* classes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix mac build Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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.
4
5 #include "chrome/browser/ui/views/extensions/shell_window_views.h"
6
7 #include "base/utf_string_conversions.h"
8 #include "chrome/browser/extensions/extension_host.h"
9 #include "chrome/browser/favicon/favicon_tab_helper.h"
10 #include "chrome/browser/ui/views/extensions/extension_keybinding_registry_views .h"
11 #include "chrome/common/extensions/draggable_region.h"
12 #include "chrome/common/extensions/extension.h"
13 #include "content/public/browser/render_view_host.h"
14 #include "content/public/browser/render_widget_host_view.h"
15 #include "content/public/browser/web_contents.h"
16 #include "content/public/browser/web_contents_view.h"
17 #include "grit/theme_resources.h"
18 #include "grit/ui_strings.h" // Accessibility names
19 #include "third_party/skia/include/core/SkPaint.h"
20 #include "ui/base/hit_test.h"
21 #include "ui/base/l10n/l10n_util.h"
22 #include "ui/base/resource/resource_bundle.h"
23 #include "ui/gfx/canvas.h"
24 #include "ui/gfx/image/image.h"
25 #include "ui/gfx/path.h"
26 #include "ui/views/controls/button/button.h"
27 #include "ui/views/controls/button/image_button.h"
28 #include "ui/views/controls/webview/webview.h"
29 #include "ui/views/layout/grid_layout.h"
30 #include "ui/views/views_delegate.h"
31 #include "ui/views/widget/widget.h"
32 #include "ui/views/window/non_client_view.h"
33
34 #if defined(OS_WIN) && !defined(USE_AURA)
35 #include "chrome/browser/shell_integration.h"
36 #include "chrome/browser/web_applications/web_app.h"
37 #include "ui/base/win/shell.h"
38 #endif
39
40 #if defined(USE_ASH)
41 #include "ash/ash_constants.h"
42 #include "ash/wm/custom_frame_view_ash.h"
43 #include "chrome/browser/ui/ash/ash_util.h"
44 #include "ui/aura/env.h"
45 #include "ui/aura/window.h"
46 #endif
47
48 namespace {
49 const int kResizeInsideBoundsSize = 5;
50 const int kResizeAreaCornerSize = 16;
51
52 // Height of the chrome-style caption, in pixels.
53 const int kCaptionHeight = 25;
54 } // namespace
55
56 class ShellWindowFrameView : public views::NonClientFrameView,
57 public views::ButtonListener {
58 public:
59 static const char kViewClassName[];
60
61 explicit ShellWindowFrameView(ShellWindowViews* window);
62 virtual ~ShellWindowFrameView();
63
64 void Init(views::Widget* frame);
65
66 // views::NonClientFrameView implementation.
67 virtual gfx::Rect GetBoundsForClientView() const OVERRIDE;
68 virtual gfx::Rect GetWindowBoundsForClientBounds(
69 const gfx::Rect& client_bounds) const OVERRIDE;
70 virtual int NonClientHitTest(const gfx::Point& point) OVERRIDE;
71 virtual void GetWindowMask(const gfx::Size& size,
72 gfx::Path* window_mask) OVERRIDE;
73 virtual void ResetWindowControls() OVERRIDE {}
74 virtual void UpdateWindowIcon() OVERRIDE {}
75 virtual void UpdateWindowTitle() OVERRIDE {}
76
77 // views::View implementation.
78 virtual gfx::Size GetPreferredSize() OVERRIDE;
79 virtual void Layout() OVERRIDE;
80 virtual std::string GetClassName() const OVERRIDE;
81 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
82 virtual gfx::Size GetMinimumSize() OVERRIDE;
83 virtual gfx::Size GetMaximumSize() OVERRIDE;
84
85 private:
86 // views::ButtonListener implementation.
87 virtual void ButtonPressed(views::Button* sender, const ui::Event& event)
88 OVERRIDE;
89
90 ShellWindowViews* window_;
91 views::Widget* frame_;
92 views::ImageButton* close_button_;
93 views::ImageButton* maximize_button_;
94 views::ImageButton* restore_button_;
95 views::ImageButton* minimize_button_;
96
97 DISALLOW_COPY_AND_ASSIGN(ShellWindowFrameView);
98 };
99
100 const char ShellWindowFrameView::kViewClassName[] =
101 "browser/ui/views/extensions/ShellWindowFrameView";
102
103 ShellWindowFrameView::ShellWindowFrameView(ShellWindowViews* window)
104 : window_(window),
105 frame_(NULL),
106 close_button_(NULL) {
107 }
108
109 ShellWindowFrameView::~ShellWindowFrameView() {
110 }
111
112 void ShellWindowFrameView::Init(views::Widget* frame) {
113 frame_ = frame;
114
115 if (!window_->frameless()) {
116 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
117 close_button_ = new views::ImageButton(this);
118 close_button_->SetImage(views::CustomButton::STATE_NORMAL,
119 rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE).ToImageSkia());
120 close_button_->SetImage(views::CustomButton::STATE_HOVERED,
121 rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE_H).ToImageSkia());
122 close_button_->SetImage(views::CustomButton::STATE_PRESSED,
123 rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE_P).ToImageSkia());
124 close_button_->SetAccessibleName(
125 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE));
126 AddChildView(close_button_);
127 maximize_button_ = new views::ImageButton(this);
128 maximize_button_->SetImage(views::CustomButton::STATE_NORMAL,
129 rb.GetNativeImageNamed(IDR_APP_WINDOW_MAXIMIZE).ToImageSkia());
130 maximize_button_->SetImage(views::CustomButton::STATE_HOVERED,
131 rb.GetNativeImageNamed(IDR_APP_WINDOW_MAXIMIZE_H).ToImageSkia());
132 maximize_button_->SetImage(views::CustomButton::STATE_PRESSED,
133 rb.GetNativeImageNamed(IDR_APP_WINDOW_MAXIMIZE_P).ToImageSkia());
134 maximize_button_->SetImage(views::CustomButton::STATE_DISABLED,
135 rb.GetNativeImageNamed(IDR_APP_WINDOW_MAXIMIZE_D).ToImageSkia());
136 maximize_button_->SetAccessibleName(
137 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MAXIMIZE));
138 AddChildView(maximize_button_);
139 restore_button_ = new views::ImageButton(this);
140 restore_button_->SetImage(views::CustomButton::STATE_NORMAL,
141 rb.GetNativeImageNamed(IDR_APP_WINDOW_RESTORE).ToImageSkia());
142 restore_button_->SetImage(views::CustomButton::STATE_HOVERED,
143 rb.GetNativeImageNamed(IDR_APP_WINDOW_RESTORE_H).ToImageSkia());
144 restore_button_->SetImage(views::CustomButton::STATE_PRESSED,
145 rb.GetNativeImageNamed(IDR_APP_WINDOW_RESTORE_P).ToImageSkia());
146 restore_button_->SetAccessibleName(
147 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_RESTORE));
148 AddChildView(restore_button_);
149 minimize_button_ = new views::ImageButton(this);
150 minimize_button_->SetImage(views::CustomButton::STATE_NORMAL,
151 rb.GetNativeImageNamed(IDR_APP_WINDOW_MINIMIZE).ToImageSkia());
152 minimize_button_->SetImage(views::CustomButton::STATE_HOVERED,
153 rb.GetNativeImageNamed(IDR_APP_WINDOW_MINIMIZE_H).ToImageSkia());
154 minimize_button_->SetImage(views::CustomButton::STATE_PRESSED,
155 rb.GetNativeImageNamed(IDR_APP_WINDOW_MINIMIZE_P).ToImageSkia());
156 minimize_button_->SetAccessibleName(
157 l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MINIMIZE));
158 AddChildView(minimize_button_);
159 }
160
161 #if defined(USE_ASH)
162 aura::Window* window = frame->GetNativeWindow();
163 if (chrome::IsNativeWindowInAsh(window)) {
164 // Ensure we get resize cursors for a few pixels outside our bounds.
165 window->SetHitTestBoundsOverrideOuter(
166 gfx::Insets(-ash::kResizeOutsideBoundsSize,
167 -ash::kResizeOutsideBoundsSize,
168 -ash::kResizeOutsideBoundsSize,
169 -ash::kResizeOutsideBoundsSize),
170 ash::kResizeOutsideBoundsScaleForTouch);
171 // Ensure we get resize cursors just inside our bounds as well.
172 // TODO(jeremya): do we need to update these when in fullscreen/maximized?
173 window->set_hit_test_bounds_override_inner(
174 gfx::Insets(ash::kResizeInsideBoundsSize, ash::kResizeInsideBoundsSize,
175 ash::kResizeInsideBoundsSize,
176 ash::kResizeInsideBoundsSize));
177 }
178 #endif
179 }
180
181 gfx::Rect ShellWindowFrameView::GetBoundsForClientView() const {
182 if (window_->frameless() || frame_->IsFullscreen())
183 return bounds();
184 return gfx::Rect(0, kCaptionHeight, width(),
185 std::max(0, height() - kCaptionHeight));
186 }
187
188 gfx::Rect ShellWindowFrameView::GetWindowBoundsForClientBounds(
189 const gfx::Rect& client_bounds) const {
190 if (window_->frameless()) {
191 gfx::Rect window_bounds = client_bounds;
192 // Enforce minimum size (1, 1) in case that client_bounds is passed with
193 // empty size. This could occur when the frameless window is being
194 // initialized.
195 if (window_bounds.IsEmpty()) {
196 window_bounds.set_width(1);
197 window_bounds.set_height(1);
198 }
199 return window_bounds;
200 }
201
202 int closeButtonOffsetX =
203 (kCaptionHeight - close_button_->height()) / 2;
204 int header_width = close_button_->width() + closeButtonOffsetX * 2;
205 return gfx::Rect(client_bounds.x(),
206 std::max(0, client_bounds.y() - kCaptionHeight),
207 std::max(header_width, client_bounds.width()),
208 client_bounds.height() + kCaptionHeight);
209 }
210
211 int ShellWindowFrameView::NonClientHitTest(const gfx::Point& point) {
212 if (frame_->IsFullscreen())
213 return HTCLIENT;
214
215 int resize_inside_bounds_size = kResizeInsideBoundsSize;
216 int resize_area_corner_size = kResizeAreaCornerSize;
217
218 #if defined(USE_ASH)
219 gfx::Rect expanded_bounds = bounds();
220 int outside_bounds = ash::kResizeOutsideBoundsSize;
221 if (aura::Env::GetInstance()->is_touch_down())
222 outside_bounds *= ash::kResizeOutsideBoundsScaleForTouch;
223 expanded_bounds.Inset(-outside_bounds, -outside_bounds);
224 if (!expanded_bounds.Contains(point))
225 return HTNOWHERE;
226
227 resize_inside_bounds_size = ash::kResizeInsideBoundsSize;
228 resize_area_corner_size = ash::kResizeAreaCornerSize;
229 #endif
230
231 // Check the frame first, as we allow a small area overlapping the contents
232 // to be used for resize handles.
233 bool can_ever_resize = frame_->widget_delegate() ?
234 frame_->widget_delegate()->CanResize() :
235 false;
236 if (can_ever_resize) {
237 // Don't allow overlapping resize handles when the window is maximized or
238 // fullscreen, as it can't be resized in those states.
239 int resize_border =
240 frame_->IsMaximized() || frame_->IsFullscreen() ? 0 :
241 resize_inside_bounds_size;
242 int frame_component = GetHTComponentForFrame(point,
243 resize_border,
244 resize_border,
245 resize_area_corner_size,
246 resize_area_corner_size,
247 can_ever_resize);
248 if (frame_component != HTNOWHERE)
249 return frame_component;
250 }
251
252 // Check for possible draggable region in the client area for the frameless
253 // window.
254 if (window_->frameless() &&
255 window_->draggable_region() &&
256 window_->draggable_region()->contains(point.x(), point.y()))
257 return HTCAPTION;
258
259 int client_component = frame_->client_view()->NonClientHitTest(point);
260 if (client_component != HTNOWHERE)
261 return client_component;
262
263 // Then see if the point is within any of the window controls.
264 if (close_button_ && close_button_->visible() &&
265 close_button_->GetMirroredBounds().Contains(point))
266 return HTCLOSE;
267
268 // Caption is a safe default.
269 return HTCAPTION;
270 }
271
272 void ShellWindowFrameView::GetWindowMask(const gfx::Size& size,
273 gfx::Path* window_mask) {
274 // We got nothing to say about no window mask.
275 }
276
277 gfx::Size ShellWindowFrameView::GetPreferredSize() {
278 gfx::Size pref = frame_->client_view()->GetPreferredSize();
279 gfx::Rect bounds(0, 0, pref.width(), pref.height());
280 return frame_->non_client_view()->GetWindowBoundsForClientBounds(
281 bounds).size();
282 }
283
284 void ShellWindowFrameView::Layout() {
285 if (window_->frameless())
286 return;
287 gfx::Size close_size = close_button_->GetPreferredSize();
288 int closeButtonOffsetY =
289 (kCaptionHeight - close_size.height()) / 2;
290 const int kButtonSpacing = 9;
291
292 close_button_->SetBounds(
293 width() - kButtonSpacing - close_size.width(),
294 closeButtonOffsetY,
295 close_size.width(),
296 close_size.height());
297
298 bool can_ever_resize = frame_->widget_delegate() ?
299 frame_->widget_delegate()->CanResize() :
300 false;
301 maximize_button_->SetEnabled(can_ever_resize);
302 gfx::Size maximize_size = maximize_button_->GetPreferredSize();
303 maximize_button_->SetBounds(
304 close_button_->x() - kButtonSpacing - maximize_size.width(),
305 closeButtonOffsetY,
306 maximize_size.width(),
307 maximize_size.height());
308 gfx::Size restore_size = restore_button_->GetPreferredSize();
309 restore_button_->SetBounds(
310 close_button_->x() - kButtonSpacing - restore_size.width(),
311 closeButtonOffsetY,
312 restore_size.width(),
313 restore_size.height());
314
315 bool maximized = frame_->IsMaximized();
316 maximize_button_->SetVisible(!maximized);
317 restore_button_->SetVisible(maximized);
318 if (maximized)
319 maximize_button_->SetState(views::CustomButton::STATE_NORMAL);
320 else
321 restore_button_->SetState(views::CustomButton::STATE_NORMAL);
322
323 gfx::Size minimize_size = minimize_button_->GetPreferredSize();
324 minimize_button_->SetBounds(
325 maximize_button_->x() - kButtonSpacing - minimize_size.width(),
326 closeButtonOffsetY,
327 minimize_size.width(),
328 minimize_size.height());
329 }
330
331 void ShellWindowFrameView::OnPaint(gfx::Canvas* canvas) {
332 if (window_->frameless())
333 return;
334 // TODO(jeremya): different look for inactive?
335 SkPaint paint;
336 paint.setAntiAlias(false);
337 paint.setStyle(SkPaint::kFill_Style);
338 paint.setColor(SK_ColorWHITE);
339 gfx::Path path;
340 const int radius = frame_->IsMaximized() ? 0 : 1;
341 path.moveTo(0, radius);
342 path.lineTo(radius, 0);
343 path.lineTo(width() - radius - 1, 0);
344 path.lineTo(width(), radius + 1);
345 path.lineTo(width(), kCaptionHeight);
346 path.lineTo(0, kCaptionHeight);
347 path.close();
348 canvas->DrawPath(path, paint);
349 }
350
351 std::string ShellWindowFrameView::GetClassName() const {
352 return kViewClassName;
353 }
354
355 gfx::Size ShellWindowFrameView::GetMinimumSize() {
356 gfx::Size min_size = frame_->client_view()->GetMinimumSize();
357 if (window_->frameless())
358 return min_size;
359
360 // Ensure we can display the top of the caption area.
361 gfx::Rect client_bounds = GetBoundsForClientView();
362 min_size.Enlarge(0, client_bounds.y());
363 // Ensure we have enough space for the window icon and buttons. We allow
364 // the title string to collapse to zero width.
365 int closeButtonOffsetX =
366 (kCaptionHeight - close_button_->height()) / 2;
367 int header_width = close_button_->width() + closeButtonOffsetX * 2;
368 if (header_width > min_size.width())
369 min_size.set_width(header_width);
370 return min_size;
371 }
372
373 gfx::Size ShellWindowFrameView::GetMaximumSize() {
374 gfx::Size max_size = frame_->client_view()->GetMaximumSize();
375 if (window_->frameless())
376 return max_size;
377
378 if (!max_size.IsEmpty()) {
379 gfx::Rect client_bounds = GetBoundsForClientView();
380 max_size.Enlarge(0, client_bounds.y());
381 }
382 return max_size;
383 }
384
385 void ShellWindowFrameView::ButtonPressed(views::Button* sender,
386 const ui::Event& event) {
387 DCHECK(!window_->frameless());
388 if (sender == close_button_)
389 frame_->Close();
390 else if (sender == maximize_button_)
391 frame_->Maximize();
392 else if (sender == restore_button_)
393 frame_->Restore();
394 else if (sender == minimize_button_)
395 frame_->Minimize();
396 }
397
398 ShellWindowViews::ShellWindowViews(ShellWindow* shell_window,
399 const ShellWindow::CreateParams& win_params)
400 : shell_window_(shell_window),
401 web_view_(NULL),
402 is_fullscreen_(false),
403 frameless_(win_params.frame == ShellWindow::CreateParams::FRAME_NONE) {
404 window_ = new views::Widget;
405 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
406 params.delegate = this;
407 params.remove_standard_frame = true;
408 params.use_system_default_icon = true;
409 minimum_size_ = win_params.minimum_size;
410 maximum_size_ = win_params.maximum_size;
411 window_->Init(params);
412 gfx::Rect window_bounds =
413 window_->non_client_view()->GetWindowBoundsForClientBounds(
414 win_params.bounds);
415 // Center window if no position was specified.
416 if (win_params.bounds.x() == INT_MIN || win_params.bounds.y() == INT_MIN) {
417 window_->CenterWindow(window_bounds.size());
418 } else {
419 window_->SetBounds(window_bounds);
420 }
421 #if defined(OS_WIN) && !defined(USE_AURA)
422 std::string app_name = web_app::GenerateApplicationNameFromExtensionId(
423 extension()->id());
424 ui::win::SetAppIdForWindow(
425 ShellIntegration::GetAppModelIdForProfile(
426 UTF8ToWide(app_name), shell_window_->profile()->GetPath()),
427 GetWidget()->GetTopLevelWidget()->GetNativeWindow());
428 #endif
429
430 extension_keybinding_registry_.reset(
431 new ExtensionKeybindingRegistryViews(shell_window_->profile(),
432 window_->GetFocusManager(),
433 extensions::ExtensionKeybindingRegistry::PLATFORM_APPS_ONLY,
434 shell_window_));
435
436 OnViewWasResized();
437 }
438
439 views::View* ShellWindowViews::GetInitiallyFocusedView() {
440 return web_view_;
441 }
442
443 bool ShellWindowViews::ShouldDescendIntoChildForEventHandling(
444 gfx::NativeView child,
445 const gfx::Point& location) {
446 #if defined(USE_AURA)
447 DCHECK_EQ(child, web_view_->web_contents()->GetView()->GetNativeView());
448 // Shell window should claim mouse events that fall within the draggable
449 // region.
450 return !draggable_region_.get() ||
451 !draggable_region_->contains(location.x(), location.y());
452 #else
453 return true;
454 #endif
455 }
456
457 void ShellWindowViews::OnFocus() {
458 web_view_->RequestFocus();
459 }
460
461 void ShellWindowViews::ViewHierarchyChanged(
462 bool is_add, views::View *parent, views::View *child) {
463 if (is_add && child == this) {
464 web_view_ = new views::WebView(NULL);
465 AddChildView(web_view_);
466 web_view_->SetWebContents(web_contents());
467 }
468 }
469
470 gfx::Size ShellWindowViews::GetMinimumSize() {
471 return minimum_size_;
472 }
473
474 gfx::Size ShellWindowViews::GetMaximumSize() {
475 return maximum_size_;
476 }
477
478 void ShellWindowViews::SetFullscreen(bool fullscreen) {
479 is_fullscreen_ = fullscreen;
480 window_->SetFullscreen(fullscreen);
481 // TODO(jeremya) we need to call RenderViewHost::ExitFullscreen() if we
482 // ever drop the window out of fullscreen in response to something that
483 // wasn't the app calling webkitCancelFullScreen().
484 }
485
486 bool ShellWindowViews::IsFullscreenOrPending() const {
487 return is_fullscreen_;
488 }
489
490 ShellWindowViews::~ShellWindowViews() {
491 web_view_->SetWebContents(NULL);
492 }
493
494 bool ShellWindowViews::IsActive() const {
495 return window_->IsActive();
496 }
497
498 bool ShellWindowViews::IsMaximized() const {
499 return window_->IsMaximized();
500 }
501
502 bool ShellWindowViews::IsMinimized() const {
503 return window_->IsMinimized();
504 }
505
506 bool ShellWindowViews::IsFullscreen() const {
507 return window_->IsFullscreen();
508 }
509
510 gfx::NativeWindow ShellWindowViews::GetNativeWindow() {
511 return window_->GetNativeWindow();
512 }
513
514 gfx::Rect ShellWindowViews::GetRestoredBounds() const {
515 return window_->GetRestoredBounds();
516 }
517
518 gfx::Rect ShellWindowViews::GetBounds() const {
519 return window_->GetWindowBoundsInScreen();
520 }
521
522 void ShellWindowViews::Show() {
523 if (window_->IsVisible()) {
524 window_->Activate();
525 return;
526 }
527
528 window_->Show();
529 }
530
531 void ShellWindowViews::ShowInactive() {
532 if (window_->IsVisible())
533 return;
534 window_->ShowInactive();
535 }
536
537 void ShellWindowViews::Hide() {
538 window_->Hide();
539 }
540
541 void ShellWindowViews::Close() {
542 window_->Close();
543 }
544
545 void ShellWindowViews::Activate() {
546 window_->Activate();
547 }
548
549 void ShellWindowViews::Deactivate() {
550 window_->Deactivate();
551 }
552
553 void ShellWindowViews::Maximize() {
554 window_->Maximize();
555 }
556
557 void ShellWindowViews::Minimize() {
558 window_->Minimize();
559 }
560
561 void ShellWindowViews::Restore() {
562 window_->Restore();
563 }
564
565 void ShellWindowViews::SetBounds(const gfx::Rect& bounds) {
566 GetWidget()->SetBounds(bounds);
567 }
568
569 void ShellWindowViews::FlashFrame(bool flash) {
570 window_->FlashFrame(flash);
571 }
572
573 bool ShellWindowViews::IsAlwaysOnTop() const {
574 return false;
575 }
576
577 void ShellWindowViews::DeleteDelegate() {
578 shell_window_->OnNativeClose();
579 }
580
581 bool ShellWindowViews::CanResize() const {
582 return maximum_size_.IsEmpty() || minimum_size_ != maximum_size_;
583 }
584
585 bool ShellWindowViews::CanMaximize() const {
586 return maximum_size_.IsEmpty();
587 }
588
589 views::View* ShellWindowViews::GetContentsView() {
590 return this;
591 }
592
593 views::NonClientFrameView* ShellWindowViews::CreateNonClientFrameView(
594 views::Widget* widget) {
595 #if defined(USE_ASH)
596 if (chrome::IsNativeViewInAsh(widget->GetNativeView()) && !frameless_) {
597 ash::CustomFrameViewAsh* frame = new ash::CustomFrameViewAsh();
598 frame->Init(widget);
599 return frame;
600 }
601 #endif
602 ShellWindowFrameView* frame_view = new ShellWindowFrameView(this);
603 frame_view->Init(window_);
604 return frame_view;
605 }
606
607 string16 ShellWindowViews::GetWindowTitle() const {
608 return shell_window_->GetTitle();
609 }
610
611 views::Widget* ShellWindowViews::GetWidget() {
612 return window_;
613 }
614
615 const views::Widget* ShellWindowViews::GetWidget() const {
616 return window_;
617 }
618
619 void ShellWindowViews::OnViewWasResized() {
620 // TODO(jeremya): this doesn't seem like a terribly elegant way to keep the
621 // window shape in sync.
622 #if defined(OS_WIN) && !defined(USE_AURA)
623 // Set the window shape of the RWHV.
624 DCHECK(window_);
625 DCHECK(web_view_);
626 gfx::Size sz = web_view_->size();
627 int height = sz.height(), width = sz.width();
628 int radius = 1;
629 gfx::Path path;
630 if (window_->IsMaximized() || window_->IsFullscreen()) {
631 // Don't round the corners when the window is maximized or fullscreen.
632 path.addRect(0, 0, width, height);
633 } else {
634 if (frameless_) {
635 path.moveTo(0, radius);
636 path.lineTo(radius, 0);
637 path.lineTo(width - radius, 0);
638 path.lineTo(width, radius);
639 } else {
640 // Don't round the top corners in chrome-style frame mode.
641 path.moveTo(0, 0);
642 path.lineTo(width, 0);
643 }
644 path.lineTo(width, height - radius - 1);
645 path.lineTo(width - radius - 1, height);
646 path.lineTo(radius + 1, height);
647 path.lineTo(0, height - radius - 1);
648 path.close();
649 }
650 SetWindowRgn(web_contents()->GetNativeView(), path.CreateNativeRegion(), 1);
651
652 SkRegion* rgn = new SkRegion;
653 if (!window_->IsFullscreen()) {
654 if (draggable_region())
655 rgn->op(*draggable_region(), SkRegion::kUnion_Op);
656 if (!window_->IsMaximized()) {
657 if (frameless_)
658 rgn->op(0, 0, width, kResizeInsideBoundsSize, SkRegion::kUnion_Op);
659 rgn->op(0, 0, kResizeInsideBoundsSize, height, SkRegion::kUnion_Op);
660 rgn->op(width - kResizeInsideBoundsSize, 0, width, height,
661 SkRegion::kUnion_Op);
662 rgn->op(0, height - kResizeInsideBoundsSize, width, height,
663 SkRegion::kUnion_Op);
664 }
665 }
666 if (web_contents()->GetRenderViewHost()->GetView())
667 web_contents()->GetRenderViewHost()->GetView()->SetClickthroughRegion(rgn);
668 #endif
669 }
670
671 gfx::ImageSkia ShellWindowViews::GetWindowAppIcon() {
672 gfx::Image app_icon = shell_window_->app_icon();
673 if (app_icon.IsEmpty())
674 return GetWindowIcon();
675 else
676 return *app_icon.ToImageSkia();
677 }
678
679 gfx::ImageSkia ShellWindowViews::GetWindowIcon() {
680 content::WebContents* web_contents = shell_window_->web_contents();
681 if (web_contents) {
682 FaviconTabHelper* favicon_tab_helper =
683 FaviconTabHelper::FromWebContents(web_contents);
684 gfx::Image app_icon = favicon_tab_helper->GetFavicon();
685 if (!app_icon.IsEmpty())
686 return *app_icon.ToImageSkia();
687 }
688 return gfx::ImageSkia();
689 }
690
691 bool ShellWindowViews::ShouldShowWindowTitle() const {
692 return false;
693 }
694
695 void ShellWindowViews::OnWidgetMove() {
696 shell_window_->SaveWindowPosition();
697 }
698
699 void ShellWindowViews::Layout() {
700 DCHECK(web_view_);
701 web_view_->SetBounds(0, 0, width(), height());
702 OnViewWasResized();
703 }
704
705 void ShellWindowViews::UpdateWindowIcon() {
706 window_->UpdateWindowIcon();
707 }
708
709 void ShellWindowViews::UpdateWindowTitle() {
710 window_->UpdateWindowTitle();
711 }
712
713 void ShellWindowViews::UpdateDraggableRegions(
714 const std::vector<extensions::DraggableRegion>& regions) {
715 // Draggable region is not supported for non-frameless window.
716 if (!frameless_)
717 return;
718
719 draggable_region_.reset(ShellWindow::RawDraggableRegionsToSkRegion(regions));
720 OnViewWasResized();
721 }
722
723 void ShellWindowViews::HandleKeyboardEvent(
724 const content::NativeWebKeyboardEvent& event) {
725 unhandled_keyboard_event_handler_.HandleKeyboardEvent(event,
726 GetFocusManager());
727 }
728
729 void ShellWindowViews::RenderViewHostChanged() {
730 OnViewWasResized();
731 }
732
733 void ShellWindowViews::SaveWindowPlacement(const gfx::Rect& bounds,
734 ui::WindowShowState show_state) {
735 views::WidgetDelegate::SaveWindowPlacement(bounds, show_state);
736 shell_window_->SaveWindowPosition();
737 }
738
739 // static
740 NativeShellWindow* NativeShellWindow::Create(
741 ShellWindow* shell_window, const ShellWindow::CreateParams& params) {
742 return new ShellWindowViews(shell_window, params);
743 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698