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

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

Powered by Google App Engine
This is Rietveld 408576698