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

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: Merge fix 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
« no previous file with comments | « chrome/browser/ui/views/extensions/shell_window_views.h ('k') | chrome/chrome_browser_ui.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 window_->AddObserver(this);
438 }
439
440 views::View* ShellWindowViews::GetInitiallyFocusedView() {
441 return web_view_;
442 }
443
444 bool ShellWindowViews::ShouldDescendIntoChildForEventHandling(
445 gfx::NativeView child,
446 const gfx::Point& location) {
447 #if defined(USE_AURA)
448 DCHECK_EQ(child, web_view_->web_contents()->GetView()->GetNativeView());
449 // Shell window should claim mouse events that fall within the draggable
450 // region.
451 return !draggable_region_.get() ||
452 !draggable_region_->contains(location.x(), location.y());
453 #else
454 return true;
455 #endif
456 }
457
458 void ShellWindowViews::OnFocus() {
459 web_view_->RequestFocus();
460 }
461
462 void ShellWindowViews::ViewHierarchyChanged(
463 bool is_add, views::View *parent, views::View *child) {
464 if (is_add && child == this) {
465 web_view_ = new views::WebView(NULL);
466 AddChildView(web_view_);
467 web_view_->SetWebContents(web_contents());
468 }
469 }
470
471 gfx::Size ShellWindowViews::GetMinimumSize() {
472 return minimum_size_;
473 }
474
475 gfx::Size ShellWindowViews::GetMaximumSize() {
476 return maximum_size_;
477 }
478
479 void ShellWindowViews::SetFullscreen(bool fullscreen) {
480 is_fullscreen_ = fullscreen;
481 window_->SetFullscreen(fullscreen);
482 // TODO(jeremya) we need to call RenderViewHost::ExitFullscreen() if we
483 // ever drop the window out of fullscreen in response to something that
484 // wasn't the app calling webkitCancelFullScreen().
485 }
486
487 bool ShellWindowViews::IsFullscreenOrPending() const {
488 return is_fullscreen_;
489 }
490
491 ShellWindowViews::~ShellWindowViews() {
492 web_view_->SetWebContents(NULL);
493 }
494
495 bool ShellWindowViews::IsActive() const {
496 return window_->IsActive();
497 }
498
499 bool ShellWindowViews::IsMaximized() const {
500 return window_->IsMaximized();
501 }
502
503 bool ShellWindowViews::IsMinimized() const {
504 return window_->IsMinimized();
505 }
506
507 bool ShellWindowViews::IsFullscreen() const {
508 return window_->IsFullscreen();
509 }
510
511 gfx::NativeWindow ShellWindowViews::GetNativeWindow() {
512 return window_->GetNativeWindow();
513 }
514
515 gfx::Rect ShellWindowViews::GetRestoredBounds() const {
516 return window_->GetRestoredBounds();
517 }
518
519 gfx::Rect ShellWindowViews::GetBounds() const {
520 return window_->GetWindowBoundsInScreen();
521 }
522
523 void ShellWindowViews::Show() {
524 if (window_->IsVisible()) {
525 window_->Activate();
526 return;
527 }
528
529 window_->Show();
530 }
531
532 void ShellWindowViews::ShowInactive() {
533 if (window_->IsVisible())
534 return;
535 window_->ShowInactive();
536 }
537
538 void ShellWindowViews::Hide() {
539 window_->Hide();
540 }
541
542 void ShellWindowViews::Close() {
543 window_->Close();
544 }
545
546 void ShellWindowViews::Activate() {
547 window_->Activate();
548 }
549
550 void ShellWindowViews::Deactivate() {
551 window_->Deactivate();
552 }
553
554 void ShellWindowViews::Maximize() {
555 window_->Maximize();
556 }
557
558 void ShellWindowViews::Minimize() {
559 window_->Minimize();
560 }
561
562 void ShellWindowViews::Restore() {
563 window_->Restore();
564 }
565
566 void ShellWindowViews::SetBounds(const gfx::Rect& bounds) {
567 GetWidget()->SetBounds(bounds);
568 }
569
570 void ShellWindowViews::FlashFrame(bool flash) {
571 window_->FlashFrame(flash);
572 }
573
574 bool ShellWindowViews::IsAlwaysOnTop() const {
575 return false;
576 }
577
578 void ShellWindowViews::DeleteDelegate() {
579 window_->RemoveObserver(this);
580 shell_window_->OnNativeClose();
581 }
582
583 bool ShellWindowViews::CanResize() const {
584 return maximum_size_.IsEmpty() || minimum_size_ != maximum_size_;
585 }
586
587 bool ShellWindowViews::CanMaximize() const {
588 return maximum_size_.IsEmpty();
589 }
590
591 views::View* ShellWindowViews::GetContentsView() {
592 return this;
593 }
594
595 views::NonClientFrameView* ShellWindowViews::CreateNonClientFrameView(
596 views::Widget* widget) {
597 #if defined(USE_ASH)
598 if (chrome::IsNativeViewInAsh(widget->GetNativeView()) && !frameless_) {
599 ash::CustomFrameViewAsh* frame = new ash::CustomFrameViewAsh();
600 frame->Init(widget);
601 return frame;
602 }
603 #endif
604 ShellWindowFrameView* frame_view = new ShellWindowFrameView(this);
605 frame_view->Init(window_);
606 return frame_view;
607 }
608
609 string16 ShellWindowViews::GetWindowTitle() const {
610 return shell_window_->GetTitle();
611 }
612
613 views::Widget* ShellWindowViews::GetWidget() {
614 return window_;
615 }
616
617 const views::Widget* ShellWindowViews::GetWidget() const {
618 return window_;
619 }
620
621 void ShellWindowViews::OnViewWasResized() {
622 // TODO(jeremya): this doesn't seem like a terribly elegant way to keep the
623 // window shape in sync.
624 #if defined(OS_WIN) && !defined(USE_AURA)
625 // Set the window shape of the RWHV.
626 DCHECK(window_);
627 DCHECK(web_view_);
628 gfx::Size sz = web_view_->size();
629 int height = sz.height(), width = sz.width();
630 int radius = 1;
631 gfx::Path path;
632 if (window_->IsMaximized() || window_->IsFullscreen()) {
633 // Don't round the corners when the window is maximized or fullscreen.
634 path.addRect(0, 0, width, height);
635 } else {
636 if (frameless_) {
637 path.moveTo(0, radius);
638 path.lineTo(radius, 0);
639 path.lineTo(width - radius, 0);
640 path.lineTo(width, radius);
641 } else {
642 // Don't round the top corners in chrome-style frame mode.
643 path.moveTo(0, 0);
644 path.lineTo(width, 0);
645 }
646 path.lineTo(width, height - radius - 1);
647 path.lineTo(width - radius - 1, height);
648 path.lineTo(radius + 1, height);
649 path.lineTo(0, height - radius - 1);
650 path.close();
651 }
652 SetWindowRgn(web_contents()->GetNativeView(), path.CreateNativeRegion(), 1);
653
654 SkRegion* rgn = new SkRegion;
655 if (!window_->IsFullscreen()) {
656 if (draggable_region())
657 rgn->op(*draggable_region(), SkRegion::kUnion_Op);
658 if (!window_->IsMaximized()) {
659 if (frameless_)
660 rgn->op(0, 0, width, kResizeInsideBoundsSize, SkRegion::kUnion_Op);
661 rgn->op(0, 0, kResizeInsideBoundsSize, height, SkRegion::kUnion_Op);
662 rgn->op(width - kResizeInsideBoundsSize, 0, width, height,
663 SkRegion::kUnion_Op);
664 rgn->op(0, height - kResizeInsideBoundsSize, width, height,
665 SkRegion::kUnion_Op);
666 }
667 }
668 if (web_contents()->GetRenderViewHost()->GetView())
669 web_contents()->GetRenderViewHost()->GetView()->SetClickthroughRegion(rgn);
670 #endif
671 }
672
673 gfx::ImageSkia ShellWindowViews::GetWindowAppIcon() {
674 gfx::Image app_icon = shell_window_->app_icon();
675 if (app_icon.IsEmpty())
676 return GetWindowIcon();
677 else
678 return *app_icon.ToImageSkia();
679 }
680
681 gfx::ImageSkia ShellWindowViews::GetWindowIcon() {
682 content::WebContents* web_contents = shell_window_->web_contents();
683 if (web_contents) {
684 FaviconTabHelper* favicon_tab_helper =
685 FaviconTabHelper::FromWebContents(web_contents);
686 gfx::Image app_icon = favicon_tab_helper->GetFavicon();
687 if (!app_icon.IsEmpty())
688 return *app_icon.ToImageSkia();
689 }
690 return gfx::ImageSkia();
691 }
692
693 bool ShellWindowViews::ShouldShowWindowTitle() const {
694 return false;
695 }
696
697 void ShellWindowViews::OnWidgetMove() {
698 shell_window_->OnNativeWindowChanged();
699 }
700
701 void ShellWindowViews::OnWidgetVisibilityChanged(views::Widget* widget,
702 bool visible) {
703 shell_window_->OnNativeWindowChanged();
704 }
705
706 void ShellWindowViews::OnWidgetActivationChanged(views::Widget* widget,
707 bool active) {
708 shell_window_->OnNativeWindowChanged();
709 }
710
711 void ShellWindowViews::Layout() {
712 DCHECK(web_view_);
713 web_view_->SetBounds(0, 0, width(), height());
714 OnViewWasResized();
715 }
716
717 void ShellWindowViews::UpdateWindowIcon() {
718 window_->UpdateWindowIcon();
719 }
720
721 void ShellWindowViews::UpdateWindowTitle() {
722 window_->UpdateWindowTitle();
723 }
724
725 void ShellWindowViews::UpdateDraggableRegions(
726 const std::vector<extensions::DraggableRegion>& regions) {
727 // Draggable region is not supported for non-frameless window.
728 if (!frameless_)
729 return;
730
731 draggable_region_.reset(ShellWindow::RawDraggableRegionsToSkRegion(regions));
732 OnViewWasResized();
733 }
734
735 void ShellWindowViews::HandleKeyboardEvent(
736 const content::NativeWebKeyboardEvent& event) {
737 unhandled_keyboard_event_handler_.HandleKeyboardEvent(event,
738 GetFocusManager());
739 }
740
741 void ShellWindowViews::RenderViewHostChanged() {
742 OnViewWasResized();
743 }
744
745 void ShellWindowViews::SaveWindowPlacement(const gfx::Rect& bounds,
746 ui::WindowShowState show_state) {
747 views::WidgetDelegate::SaveWindowPlacement(bounds, show_state);
748 shell_window_->OnNativeWindowChanged();
749 }
750
751 // static
752 NativeShellWindow* NativeShellWindow::Create(
753 ShellWindow* shell_window, const ShellWindow::CreateParams& params) {
754 return new ShellWindowViews(shell_window, params);
755 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/extensions/shell_window_views.h ('k') | chrome/chrome_browser_ui.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698