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

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

Issue 11363250: Allow Chrome apps to create Ash Panels (apps v2) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase off issue 11280173 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/extensions/native_app_window_views.h" 5 #include "chrome/browser/ui/views/extensions/native_app_window_views.h"
6 6
7 #include "base/utf_string_conversions.h"
8 #include "chrome/browser/extensions/extension_host.h" 7 #include "chrome/browser/extensions/extension_host.h"
9 #include "chrome/browser/favicon/favicon_tab_helper.h" 8 #include "chrome/browser/favicon/favicon_tab_helper.h"
10 #include "chrome/browser/ui/views/extensions/extension_keybinding_registry_views .h" 9 #include "chrome/browser/ui/views/extensions/extension_keybinding_registry_views .h"
10 #include "chrome/browser/ui/views/extensions/shell_window_frame_view.h"
11 #include "chrome/common/extensions/draggable_region.h" 11 #include "chrome/common/extensions/draggable_region.h"
12 #include "chrome/common/extensions/extension.h" 12 #include "chrome/common/extensions/extension.h"
13 #include "content/public/browser/render_view_host.h" 13 #include "content/public/browser/render_view_host.h"
14 #include "content/public/browser/render_widget_host_view.h" 14 #include "content/public/browser/render_widget_host_view.h"
15 #include "content/public/browser/web_contents.h" 15 #include "content/public/browser/web_contents.h"
16 #include "content/public/browser/web_contents_view.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" 17 #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" 18 #include "ui/views/widget/widget.h"
32 #include "ui/views/window/non_client_view.h" 19 #include "ui/views/window/non_client_view.h"
33 20
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) 21 #if defined(USE_ASH)
41 #include "ash/ash_constants.h"
42 #include "ash/wm/custom_frame_view_ash.h" 22 #include "ash/wm/custom_frame_view_ash.h"
23 #include "ash/wm/panel_frame_view.h"
43 #include "chrome/browser/ui/ash/ash_util.h" 24 #include "chrome/browser/ui/ash/ash_util.h"
44 #include "ui/aura/env.h"
45 #include "ui/aura/window.h"
46 #endif 25 #endif
47 26
48 namespace { 27 namespace {
49 const int kResizeInsideBoundsSize = 5; 28 const int kMinPanelWidth = 100;
50 const int kResizeAreaCornerSize = 16; 29 const int kMinPanelHeight = 100;
51 30 const int kDefaultPanelWidth = 200;
52 // Height of the chrome-style caption, in pixels. 31 const int kDefaultPanelHeight = 300;
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(NativeAppWindowViews* 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 NativeAppWindowViews* 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(NativeAppWindowViews* 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 } 32 }
397 33
398 NativeAppWindowViews::NativeAppWindowViews( 34 NativeAppWindowViews::NativeAppWindowViews(
399 ShellWindow* shell_window, 35 ShellWindow* shell_window,
400 const ShellWindow::CreateParams& win_params) 36 const ShellWindow::CreateParams& create_params)
401 : shell_window_(shell_window), 37 : shell_window_(shell_window),
402 web_view_(NULL), 38 web_view_(NULL),
39 window_(NULL),
403 is_fullscreen_(false), 40 is_fullscreen_(false),
404 frameless_(win_params.frame == ShellWindow::CreateParams::FRAME_NONE) { 41 frameless_(create_params.frame == ShellWindow::FRAME_NONE) {
42 minimum_size_ = create_params.minimum_size;
43 maximum_size_ = create_params.maximum_size;
44
405 window_ = new views::Widget; 45 window_ = new views::Widget;
406 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); 46 if (create_params.window_type == ShellWindow::WINDOW_TYPE_PANEL)
407 params.delegate = this; 47 InitializePanelWindow(create_params);
408 params.remove_standard_frame = true; 48 else
409 params.use_system_default_icon = true; 49 InitializeDefaultWindow(create_params);
410 minimum_size_ = win_params.minimum_size; 50
411 maximum_size_ = win_params.maximum_size; 51 extension_keybinding_registry_.reset(
412 window_->Init(params); 52 new ExtensionKeybindingRegistryViews(
53 profile(),
54 window_->GetFocusManager(),
55 extensions::ExtensionKeybindingRegistry::PLATFORM_APPS_ONLY,
56 shell_window_));
57
58 OnViewWasResized();
59 window_->AddObserver(this);
60 }
61
62 NativeAppWindowViews::~NativeAppWindowViews() {
63 web_view_->SetWebContents(NULL);
64 }
65
66 void NativeAppWindowViews::InitializeDefaultWindow(
67 const ShellWindow::CreateParams& create_params) {
68 views::Widget::InitParams init_params(views::Widget::InitParams::TYPE_WINDOW);
69 init_params.delegate = this;
70 init_params.remove_standard_frame = true;
71 init_params.use_system_default_icon = true;
72 window_->Init(init_params);
413 gfx::Rect window_bounds = 73 gfx::Rect window_bounds =
414 window_->non_client_view()->GetWindowBoundsForClientBounds( 74 window_->non_client_view()->GetWindowBoundsForClientBounds(
415 win_params.bounds); 75 create_params.bounds);
416 // Center window if no position was specified. 76 // Center window if no position was specified.
417 if (win_params.bounds.x() == INT_MIN || win_params.bounds.y() == INT_MIN) { 77 if (create_params.bounds.x() == INT_MIN ||
78 create_params.bounds.y() == INT_MIN) {
418 window_->CenterWindow(window_bounds.size()); 79 window_->CenterWindow(window_bounds.size());
419 } else { 80 } else {
420 window_->SetBounds(window_bounds); 81 window_->SetBounds(window_bounds);
421 } 82 }
83
422 #if defined(OS_WIN) && !defined(USE_AURA) 84 #if defined(OS_WIN) && !defined(USE_AURA)
423 std::string app_name = web_app::GenerateApplicationNameFromExtensionId( 85 std::string app_name = web_app::GenerateApplicationNameFromExtensionId(
424 extension()->id()); 86 extension()->id());
425 ui::win::SetAppIdForWindow( 87 ui::win::SetAppIdForWindow(
426 ShellIntegration::GetAppModelIdForProfile( 88 ShellIntegration::GetAppModelIdForProfile(
427 UTF8ToWide(app_name), shell_window_->profile()->GetPath()), 89 UTF8ToWide(app_name), shell_window_->profile()->GetPath()),
428 GetWidget()->GetTopLevelWidget()->GetNativeWindow()); 90 GetWidget()->GetTopLevelWidget()->GetNativeWindow());
429 #endif 91 #endif
430
431 extension_keybinding_registry_.reset(
432 new ExtensionKeybindingRegistryViews(shell_window_->profile(),
433 window_->GetFocusManager(),
434 extensions::ExtensionKeybindingRegistry::PLATFORM_APPS_ONLY,
435 shell_window_));
436
437 OnViewWasResized();
438 window_->AddObserver(this);
439 } 92 }
440 93
441 views::View* NativeAppWindowViews::GetInitiallyFocusedView() { 94 void NativeAppWindowViews::InitializePanelWindow(
442 return web_view_; 95 const ShellWindow::CreateParams& create_params) {
96 views::Widget::InitParams params(views::Widget::InitParams::TYPE_PANEL);
97 params.delegate = this;
98
99 preferred_size_ = gfx::Size(create_params.bounds.width(),
100 create_params.bounds.height());
101 if (preferred_size_.width() == 0)
102 preferred_size_.set_width(kDefaultPanelWidth);
103 else if (preferred_size_.width() < kMinPanelWidth)
104 preferred_size_.set_width(kMinPanelWidth);
105
106 if (preferred_size_.height() == 0)
107 preferred_size_.set_height(kDefaultPanelHeight);
108 else if (preferred_size_.height() < kMinPanelHeight)
109 preferred_size_.set_height(kMinPanelHeight);
110
111 params.bounds = gfx::Rect(preferred_size_.width(), preferred_size_.height());
112 window_->Init(params);
113
114 gfx::Rect window_bounds =
115 window_->non_client_view()->GetWindowBoundsForClientBounds(
116 create_params.bounds);
117 window_->SetBounds(window_bounds);
443 } 118 }
444 119
445 bool NativeAppWindowViews::ShouldDescendIntoChildForEventHandling( 120 // BaseWindow implementation.
446 gfx::NativeView child,
447 const gfx::Point& location) {
448 #if defined(USE_AURA)
449 DCHECK_EQ(child, web_view_->web_contents()->GetView()->GetNativeView());
450 // Shell window should claim mouse events that fall within the draggable
451 // region.
452 return !draggable_region_.get() ||
453 !draggable_region_->contains(location.x(), location.y());
454 #else
455 return true;
456 #endif
457 }
458
459 void NativeAppWindowViews::OnFocus() {
460 web_view_->RequestFocus();
461 }
462
463 void NativeAppWindowViews::ViewHierarchyChanged(
464 bool is_add, views::View *parent, views::View *child) {
465 if (is_add && child == this) {
466 web_view_ = new views::WebView(NULL);
467 AddChildView(web_view_);
468 web_view_->SetWebContents(web_contents());
469 }
470 }
471
472 gfx::Size NativeAppWindowViews::GetMinimumSize() {
473 return minimum_size_;
474 }
475
476 gfx::Size NativeAppWindowViews::GetMaximumSize() {
477 return maximum_size_;
478 }
479
480 void NativeAppWindowViews::SetFullscreen(bool fullscreen) {
481 is_fullscreen_ = fullscreen;
482 window_->SetFullscreen(fullscreen);
483 // TODO(jeremya) we need to call RenderViewHost::ExitFullscreen() if we
484 // ever drop the window out of fullscreen in response to something that
485 // wasn't the app calling webkitCancelFullScreen().
486 }
487
488 bool NativeAppWindowViews::IsFullscreenOrPending() const {
489 return is_fullscreen_;
490 }
491
492 NativeAppWindowViews::~NativeAppWindowViews() {
493 web_view_->SetWebContents(NULL);
494 }
495 121
496 bool NativeAppWindowViews::IsActive() const { 122 bool NativeAppWindowViews::IsActive() const {
497 return window_->IsActive(); 123 return window_->IsActive();
498 } 124 }
499 125
500 bool NativeAppWindowViews::IsMaximized() const { 126 bool NativeAppWindowViews::IsMaximized() const {
501 return window_->IsMaximized(); 127 return window_->IsMaximized();
502 } 128 }
503 129
504 bool NativeAppWindowViews::IsMinimized() const { 130 bool NativeAppWindowViews::IsMinimized() const {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 192
567 void NativeAppWindowViews::SetBounds(const gfx::Rect& bounds) { 193 void NativeAppWindowViews::SetBounds(const gfx::Rect& bounds) {
568 GetWidget()->SetBounds(bounds); 194 GetWidget()->SetBounds(bounds);
569 } 195 }
570 196
571 void NativeAppWindowViews::FlashFrame(bool flash) { 197 void NativeAppWindowViews::FlashFrame(bool flash) {
572 window_->FlashFrame(flash); 198 window_->FlashFrame(flash);
573 } 199 }
574 200
575 bool NativeAppWindowViews::IsAlwaysOnTop() const { 201 bool NativeAppWindowViews::IsAlwaysOnTop() const {
576 return false; 202 return shell_window_->window_type() == ShellWindow::WINDOW_TYPE_PANEL;
577 } 203 }
578 204
579 void NativeAppWindowViews::DeleteDelegate() { 205 // Private method. TODO(stevenjb): Move this.
jeremya 2012/11/29 02:49:05 Move it where? Why?
stevenjb 2012/11/29 03:11:26 Clarified the comment. Moving this to match the de
580 window_->RemoveObserver(this);
581 shell_window_->OnNativeClose();
582 }
583
584 bool NativeAppWindowViews::CanResize() const {
585 return maximum_size_.IsEmpty() || minimum_size_ != maximum_size_;
586 }
587
588 bool NativeAppWindowViews::CanMaximize() const {
589 return maximum_size_.IsEmpty();
590 }
591
592 views::View* NativeAppWindowViews::GetContentsView() {
593 return this;
594 }
595
596 views::NonClientFrameView* NativeAppWindowViews::CreateNonClientFrameView(
597 views::Widget* widget) {
598 #if defined(USE_ASH)
599 if (chrome::IsNativeViewInAsh(widget->GetNativeView()) && !frameless_) {
600 ash::CustomFrameViewAsh* frame = new ash::CustomFrameViewAsh();
601 frame->Init(widget);
602 return frame;
603 }
604 #endif
605 ShellWindowFrameView* frame_view = new ShellWindowFrameView(this);
606 frame_view->Init(window_);
607 return frame_view;
608 }
609
610 string16 NativeAppWindowViews::GetWindowTitle() const {
611 return shell_window_->GetTitle();
612 }
613
614 views::Widget* NativeAppWindowViews::GetWidget() {
615 return window_;
616 }
617
618 const views::Widget* NativeAppWindowViews::GetWidget() const {
619 return window_;
620 }
621 206
622 void NativeAppWindowViews::OnViewWasResized() { 207 void NativeAppWindowViews::OnViewWasResized() {
623 // TODO(jeremya): this doesn't seem like a terribly elegant way to keep the 208 // TODO(jeremya): this doesn't seem like a terribly elegant way to keep the
624 // window shape in sync. 209 // window shape in sync.
625 #if defined(OS_WIN) && !defined(USE_AURA) 210 #if defined(OS_WIN) && !defined(USE_AURA)
626 // Set the window shape of the RWHV. 211 // Set the window shape of the RWHV.
627 DCHECK(window_); 212 DCHECK(window_);
628 DCHECK(web_view_); 213 DCHECK(web_view_);
629 gfx::Size sz = web_view_->size(); 214 gfx::Size sz = web_view_->size();
630 int height = sz.height(), width = sz.width(); 215 int height = sz.height(), width = sz.width();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 SkRegion::kUnion_Op); 249 SkRegion::kUnion_Op);
665 rgn->op(0, height - kResizeInsideBoundsSize, width, height, 250 rgn->op(0, height - kResizeInsideBoundsSize, width, height,
666 SkRegion::kUnion_Op); 251 SkRegion::kUnion_Op);
667 } 252 }
668 } 253 }
669 if (web_contents()->GetRenderViewHost()->GetView()) 254 if (web_contents()->GetRenderViewHost()->GetView())
670 web_contents()->GetRenderViewHost()->GetView()->SetClickthroughRegion(rgn); 255 web_contents()->GetRenderViewHost()->GetView()->SetClickthroughRegion(rgn);
671 #endif 256 #endif
672 } 257 }
673 258
259 // WidgetDelegate implementation.
260
261 void NativeAppWindowViews::OnWidgetMove() {
262 shell_window_->OnNativeWindowChanged();
263 }
264
265 views::View* NativeAppWindowViews::GetInitiallyFocusedView() {
266 return web_view_;
267 }
268
269 bool NativeAppWindowViews::CanResize() const {
270 return maximum_size_.IsEmpty() || minimum_size_ != maximum_size_;
271 }
272
273 bool NativeAppWindowViews::CanMaximize() const {
274 return maximum_size_.IsEmpty();
275 }
276
277 string16 NativeAppWindowViews::GetWindowTitle() const {
278 return shell_window_->GetTitle();
279 }
280
281 bool NativeAppWindowViews::ShouldShowWindowTitle() const {
282 return false;
283 }
284
674 gfx::ImageSkia NativeAppWindowViews::GetWindowAppIcon() { 285 gfx::ImageSkia NativeAppWindowViews::GetWindowAppIcon() {
675 gfx::Image app_icon = shell_window_->app_icon(); 286 gfx::Image app_icon = shell_window_->app_icon();
676 if (app_icon.IsEmpty()) 287 if (app_icon.IsEmpty())
677 return GetWindowIcon(); 288 return GetWindowIcon();
678 else 289 else
679 return *app_icon.ToImageSkia(); 290 return *app_icon.ToImageSkia();
680 } 291 }
681 292
682 gfx::ImageSkia NativeAppWindowViews::GetWindowIcon() { 293 gfx::ImageSkia NativeAppWindowViews::GetWindowIcon() {
683 content::WebContents* web_contents = shell_window_->web_contents(); 294 content::WebContents* web_contents = shell_window_->web_contents();
684 if (web_contents) { 295 if (web_contents) {
685 FaviconTabHelper* favicon_tab_helper = 296 FaviconTabHelper* favicon_tab_helper =
686 FaviconTabHelper::FromWebContents(web_contents); 297 FaviconTabHelper::FromWebContents(web_contents);
687 gfx::Image app_icon = favicon_tab_helper->GetFavicon(); 298 gfx::Image app_icon = favicon_tab_helper->GetFavicon();
688 if (!app_icon.IsEmpty()) 299 if (!app_icon.IsEmpty())
689 return *app_icon.ToImageSkia(); 300 return *app_icon.ToImageSkia();
690 } 301 }
691 return gfx::ImageSkia(); 302 return gfx::ImageSkia();
692 } 303 }
693 304
694 bool NativeAppWindowViews::ShouldShowWindowTitle() const { 305 void NativeAppWindowViews::SaveWindowPlacement(const gfx::Rect& bounds,
695 return false; 306 ui::WindowShowState show_state) {
307 views::WidgetDelegate::SaveWindowPlacement(bounds, show_state);
308 shell_window_->OnNativeWindowChanged();
696 } 309 }
697 310
698 void NativeAppWindowViews::OnWidgetMove() { 311 void NativeAppWindowViews::DeleteDelegate() {
699 shell_window_->OnNativeWindowChanged(); 312 window_->RemoveObserver(this);
313 shell_window_->OnNativeClose();
700 } 314 }
701 315
316 views::Widget* NativeAppWindowViews::GetWidget() {
317 return window_;
318 }
319
320 const views::Widget* NativeAppWindowViews::GetWidget() const {
321 return window_;
322 }
323
324 views::NonClientFrameView* NativeAppWindowViews::CreateNonClientFrameView(
325 views::Widget* widget) {
326 #if defined(USE_ASH)
327 if (shell_window_->window_type() == ShellWindow::WINDOW_TYPE_PANEL) {
328 ash::PanelFrameView::FrameType frame_type = frameless_ ?
329 ash::PanelFrameView::FRAME_NONE : ash::PanelFrameView::FRAME_ASH;
330 return new ash::PanelFrameView(widget, frame_type);
331 }
332 if (chrome::IsNativeViewInAsh(widget->GetNativeView()) && !frameless_) {
333 ash::CustomFrameViewAsh* frame = new ash::CustomFrameViewAsh();
334 frame->Init(widget);
335 return frame;
336 }
337 #endif
338 ShellWindowFrameView* frame_view = new ShellWindowFrameView(this);
339 frame_view->Init(window_);
340 return frame_view;
341 }
342
343 bool NativeAppWindowViews::ShouldDescendIntoChildForEventHandling(
344 gfx::NativeView child,
345 const gfx::Point& location) {
346 #if defined(USE_AURA)
347 DCHECK_EQ(child, web_view_->web_contents()->GetView()->GetNativeView());
348 // Shell window should claim mouse events that fall within the draggable
349 // region.
350 return !draggable_region_.get() ||
351 !draggable_region_->contains(location.x(), location.y());
352 #else
353 return true;
354 #endif
355 }
356
357 // WidgetObserver implementation.
358
702 void NativeAppWindowViews::OnWidgetVisibilityChanged(views::Widget* widget, 359 void NativeAppWindowViews::OnWidgetVisibilityChanged(views::Widget* widget,
703 bool visible) { 360 bool visible) {
704 shell_window_->OnNativeWindowChanged(); 361 shell_window_->OnNativeWindowChanged();
705 } 362 }
706 363
707 void NativeAppWindowViews::OnWidgetActivationChanged(views::Widget* widget, 364 void NativeAppWindowViews::OnWidgetActivationChanged(views::Widget* widget,
708 bool active) { 365 bool active) {
709 shell_window_->OnNativeWindowChanged(); 366 shell_window_->OnNativeWindowChanged();
710 } 367 }
711 368
369 // views::View implementation.
370
712 void NativeAppWindowViews::Layout() { 371 void NativeAppWindowViews::Layout() {
713 DCHECK(web_view_); 372 DCHECK(web_view_);
714 web_view_->SetBounds(0, 0, width(), height()); 373 web_view_->SetBounds(0, 0, width(), height());
715 OnViewWasResized(); 374 OnViewWasResized();
716 } 375 }
717 376
377 void NativeAppWindowViews::ViewHierarchyChanged(
378 bool is_add, views::View *parent, views::View *child) {
379 if (is_add && child == this) {
380 web_view_ = new views::WebView(NULL);
381 AddChildView(web_view_);
382 web_view_->SetWebContents(web_contents());
383 }
384 }
385
386 gfx::Size NativeAppWindowViews::GetPreferredSize() {
387 if (!preferred_size_.IsEmpty())
388 return preferred_size_;
389 return views::View::GetPreferredSize();
390 }
391
392 gfx::Size NativeAppWindowViews::GetMinimumSize() {
393 return minimum_size_;
394 }
395
396 gfx::Size NativeAppWindowViews::GetMaximumSize() {
397 return maximum_size_;
398 }
399
400 void NativeAppWindowViews::OnFocus() {
401 web_view_->RequestFocus();
402 }
403
404 // NativeAppWindow implementation.
405
406 void NativeAppWindowViews::SetFullscreen(bool fullscreen) {
407 // Fullscreen not supported by panels.
408 if (shell_window_->window_type() == ShellWindow::WINDOW_TYPE_PANEL)
409 return;
410 is_fullscreen_ = fullscreen;
411 window_->SetFullscreen(fullscreen);
412 // TODO(jeremya) we need to call RenderViewHost::ExitFullscreen() if we
413 // ever drop the window out of fullscreen in response to something that
414 // wasn't the app calling webkitCancelFullScreen().
415 }
416
417 bool NativeAppWindowViews::IsFullscreenOrPending() const {
418 return is_fullscreen_;
419 }
420
421 views::View* NativeAppWindowViews::GetContentsView() {
422 return this;
423 }
424
718 void NativeAppWindowViews::UpdateWindowIcon() { 425 void NativeAppWindowViews::UpdateWindowIcon() {
719 window_->UpdateWindowIcon(); 426 window_->UpdateWindowIcon();
720 } 427 }
721 428
722 void NativeAppWindowViews::UpdateWindowTitle() { 429 void NativeAppWindowViews::UpdateWindowTitle() {
723 window_->UpdateWindowTitle(); 430 window_->UpdateWindowTitle();
724 } 431 }
725 432
726 void NativeAppWindowViews::UpdateDraggableRegions( 433 void NativeAppWindowViews::UpdateDraggableRegions(
727 const std::vector<extensions::DraggableRegion>& regions) { 434 const std::vector<extensions::DraggableRegion>& regions) {
728 // Draggable region is not supported for non-frameless window. 435 // Draggable region is not supported for non-frameless window.
729 if (!frameless_) 436 if (!frameless_)
730 return; 437 return;
731 438
732 draggable_region_.reset(ShellWindow::RawDraggableRegionsToSkRegion(regions)); 439 draggable_region_.reset(ShellWindow::RawDraggableRegionsToSkRegion(regions));
733 OnViewWasResized(); 440 OnViewWasResized();
734 } 441 }
735 442
736 void NativeAppWindowViews::HandleKeyboardEvent( 443 void NativeAppWindowViews::HandleKeyboardEvent(
737 const content::NativeWebKeyboardEvent& event) { 444 const content::NativeWebKeyboardEvent& event) {
738 unhandled_keyboard_event_handler_.HandleKeyboardEvent(event, 445 unhandled_keyboard_event_handler_.HandleKeyboardEvent(event,
739 GetFocusManager()); 446 GetFocusManager());
740 } 447 }
741 448
742 void NativeAppWindowViews::RenderViewHostChanged() { 449 void NativeAppWindowViews::RenderViewHostChanged() {
743 OnViewWasResized(); 450 OnViewWasResized();
744 } 451 }
745 452
746 void NativeAppWindowViews::SaveWindowPlacement(const gfx::Rect& bounds, 453 //------------------------------------------------------------------------------
747 ui::WindowShowState show_state) { 454 // NativeAppWindow::Create
748 views::WidgetDelegate::SaveWindowPlacement(bounds, show_state);
749 shell_window_->OnNativeWindowChanged();
750 }
751 455
752 // static 456 // static
753 NativeAppWindow* NativeAppWindow::Create( 457 NativeAppWindow* NativeAppWindow::Create(
754 ShellWindow* shell_window, const ShellWindow::CreateParams& params) { 458 ShellWindow* shell_window, const ShellWindow::CreateParams& params) {
755 return new NativeAppWindowViews(shell_window, params); 459 return new NativeAppWindowViews(shell_window, params);
756 } 460 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698