constrained_window_views.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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/constrained_window_views.h" 6 7#include <algorithm> 8 9#include "chrome/browser/themes/theme_properties.h" 10#include "chrome/browser/ui/browser_finder.h" 11#include "chrome/browser/ui/views/theme_image_mapper.h" 12#include "components/web_modal/web_contents_modal_dialog_host.h" 13#include "grit/theme_resources.h" 14#include "grit/ui_resources.h" 15#include "ui/base/hit_test.h" 16#include "ui/base/resource/resource_bundle.h" 17#include "ui/gfx/canvas.h" 18#include "ui/gfx/font.h" 19#include "ui/views/border.h" 20#include "ui/views/color_constants.h" 21#include "ui/views/controls/button/image_button.h" 22#include "ui/views/widget/widget.h" 23#include "ui/views/widget/widget_observer.h" 24#include "ui/views/window/dialog_delegate.h" 25#include "ui/views/window/frame_background.h" 26#include "ui/views/window/window_resources.h" 27#include "ui/views/window/window_shape.h" 28 29#if defined(OS_WIN) && !defined(USE_AURA) 30#include "ui/base/win/shell.h" 31#include "ui/views/widget/native_widget_win.h" 32#endif 33 34#if defined(USE_AURA) 35#include "ui/aura/window.h" 36#endif 37 38#if defined(USE_ASH) 39#include "ash/wm/custom_frame_view_ash.h" 40#endif 41 42using web_modal::ModalDialogHost; 43using web_modal::ModalDialogHostObserver; 44 45namespace { 46// The name of a key to store on the window handle to associate 47// BrowserModalDialogHostObserverViews with the Widget. 48const char* const kBrowserModalDialogHostObserverViewsKey = 49 "__BROWSER_MODAL_DIALOG_HOST_OBSERVER_VIEWS__"; 50 51// Applies positioning changes from the ModalDialogHost to the Widget. 52class BrowserModalDialogHostObserverViews 53 : public views::WidgetObserver, 54 public ModalDialogHostObserver { 55 public: 56 BrowserModalDialogHostObserverViews( 57 ModalDialogHost* host, 58 views::Widget* target_widget, 59 const char *const native_window_property) 60 : host_(host), 61 target_widget_(target_widget), 62 native_window_property_(native_window_property) { 63 DCHECK(host_); 64 DCHECK(target_widget_); 65 host_->AddObserver(this); 66 target_widget_->AddObserver(this); 67 } 68 69 virtual ~BrowserModalDialogHostObserverViews() { 70 if (host_) 71 host_->RemoveObserver(this); 72 target_widget_->RemoveObserver(this); 73 target_widget_->SetNativeWindowProperty(native_window_property_, 74 NULL); 75 } 76 77 // WidgetObserver overrides 78 virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE { 79 delete this; 80 } 81 82 // WebContentsModalDialogHostObserver overrides 83 virtual void OnPositionRequiresUpdate() OVERRIDE { 84 UpdateBrowserModalDialogPosition(target_widget_, host_); 85 } 86 87 virtual void OnHostDestroying() OVERRIDE { 88 host_->RemoveObserver(this); 89 host_ = NULL; 90 } 91 92 private: 93 ModalDialogHost* host_; 94 views::Widget* target_widget_; 95 const char* const native_window_property_; 96 97 DISALLOW_COPY_AND_ASSIGN(BrowserModalDialogHostObserverViews); 98}; 99 100void UpdateModalDialogPosition( 101 views::Widget* widget, 102 web_modal::ModalDialogHost* dialog_host, 103 const gfx::Size& size) { 104 gfx::Point position = dialog_host->GetDialogPosition(size); 105 views::Border* border = 106 widget->non_client_view()->frame_view()->border(); 107 // Border may be null during widget initialization. 108 if (border) { 109 // Align the first row of pixels inside the border. This is the apparent 110 // top of the dialog. 111 position.set_y(position.y() - border->GetInsets().top()); 112 } 113 114 if (widget->is_top_level()) { 115 position += 116 views::Widget::GetWidgetForNativeView(dialog_host->GetHostView())-> 117 GetClientAreaBoundsInScreen().OffsetFromOrigin(); 118 } 119 120 widget->SetBounds(gfx::Rect(position, size)); 121} 122 123} // namespace 124 125// An enumeration of image resources used by this window. 126enum { 127 FRAME_PART_IMAGE_FIRST = 0, // Must be first. 128 129 // Window Frame Border. 130 FRAME_BOTTOM_EDGE, 131 FRAME_BOTTOM_LEFT_CORNER, 132 FRAME_BOTTOM_RIGHT_CORNER, 133 FRAME_LEFT_EDGE, 134 FRAME_RIGHT_EDGE, 135 FRAME_TOP_EDGE, 136 FRAME_TOP_LEFT_CORNER, 137 FRAME_TOP_RIGHT_CORNER, 138 139 FRAME_PART_IMAGE_COUNT // Must be last. 140}; 141 142static const int kXPFramePartIDs[] = { 143 0, 144 IDR_WINDOW_BOTTOM_CENTER, IDR_WINDOW_BOTTOM_LEFT_CORNER, 145 IDR_WINDOW_BOTTOM_RIGHT_CORNER, IDR_WINDOW_LEFT_SIDE, 146 IDR_WINDOW_RIGHT_SIDE, IDR_WINDOW_TOP_CENTER, 147 IDR_WINDOW_TOP_LEFT_CORNER, IDR_WINDOW_TOP_RIGHT_CORNER, 148 0 }; 149static const int kVistaFramePartIDs[] = { 150 0, 151 IDR_CONSTRAINED_BOTTOM_CENTER_V, IDR_CONSTRAINED_BOTTOM_LEFT_CORNER_V, 152 IDR_CONSTRAINED_BOTTOM_RIGHT_CORNER_V, IDR_CONSTRAINED_LEFT_SIDE_V, 153 IDR_CONSTRAINED_RIGHT_SIDE_V, IDR_CONSTRAINED_TOP_CENTER_V, 154 IDR_CONSTRAINED_TOP_LEFT_CORNER_V, IDR_CONSTRAINED_TOP_RIGHT_CORNER_V, 155 0 }; 156 157class XPWindowResources : public views::WindowResources { 158 public: 159 XPWindowResources() { 160 InitClass(); 161 } 162 virtual ~XPWindowResources() {} 163 164 virtual gfx::ImageSkia* GetPartImage( 165 views::FramePartImage part_id) const OVERRIDE { 166 return images_[part_id]; 167 } 168 169 private: 170 static void InitClass() { 171 static bool initialized = false; 172 if (!initialized) { 173 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 174 for (int i = 0; i < FRAME_PART_IMAGE_COUNT; ++i) { 175 int id = kXPFramePartIDs[i]; 176 if (id != 0) 177 images_[i] = rb.GetImageSkiaNamed(id); 178 } 179 initialized = true; 180 } 181 } 182 183 static gfx::ImageSkia* images_[FRAME_PART_IMAGE_COUNT]; 184 185 DISALLOW_COPY_AND_ASSIGN(XPWindowResources); 186}; 187 188class VistaWindowResources : public views::WindowResources { 189 public: 190 VistaWindowResources() { 191 InitClass(); 192 } 193 virtual ~VistaWindowResources() {} 194 195 virtual gfx::ImageSkia* GetPartImage( 196 views::FramePartImage part_id) const OVERRIDE { 197 return images_[part_id]; 198 } 199 200 private: 201 static void InitClass() { 202 static bool initialized = false; 203 if (!initialized) { 204 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 205 for (int i = 0; i < FRAME_PART_IMAGE_COUNT; ++i) { 206 int id = kVistaFramePartIDs[i]; 207 if (id != 0) 208 images_[i] = rb.GetImageSkiaNamed(id); 209 } 210 initialized = true; 211 } 212 } 213 214 static gfx::ImageSkia* images_[FRAME_PART_IMAGE_COUNT]; 215 216 DISALLOW_COPY_AND_ASSIGN(VistaWindowResources); 217}; 218 219gfx::ImageSkia* XPWindowResources::images_[]; 220gfx::ImageSkia* VistaWindowResources::images_[]; 221 222class ConstrainedWindowFrameView : public views::NonClientFrameView, 223 public views::ButtonListener { 224 public: 225 ConstrainedWindowFrameView(views::Widget* container, 226 bool browser_is_off_the_record); 227 virtual ~ConstrainedWindowFrameView(); 228 229 virtual void UpdateWindowTitle() OVERRIDE; 230 231 // Overridden from views::NonClientFrameView: 232 virtual gfx::Rect GetBoundsForClientView() const OVERRIDE; 233 virtual gfx::Rect GetWindowBoundsForClientBounds( 234 const gfx::Rect& client_bounds) const OVERRIDE; 235 virtual int NonClientHitTest(const gfx::Point& point) OVERRIDE; 236 virtual void GetWindowMask(const gfx::Size& size, 237 gfx::Path* window_mask) OVERRIDE; 238 virtual void ResetWindowControls() OVERRIDE {} 239 virtual void UpdateWindowIcon() OVERRIDE {} 240 241 // Overridden from views::View: 242 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; 243 virtual void Layout() OVERRIDE; 244 virtual void OnThemeChanged() OVERRIDE; 245 246 // Overridden from views::ButtonListener: 247 virtual void ButtonPressed(views::Button* sender, 248 const ui::Event& event) OVERRIDE; 249 250 private: 251 // Returns the thickness of the entire nonclient left, right, and bottom 252 // borders, including both the window frame and any client edge. 253 int NonClientBorderThickness() const; 254 255 // Returns the height of the entire nonclient top border, including the window 256 // frame, any title area, and any connected client edge. 257 int NonClientTopBorderHeight() const; 258 259 // Returns the thickness of the nonclient portion of the 3D edge along the 260 // bottom of the titlebar. 261 int TitlebarBottomThickness() const; 262 263 // Returns what the size of the titlebar icon would be if there was one. 264 int IconSize() const; 265 266 // Returns what the titlebar icon's bounds would be if there was one. 267 gfx::Rect IconBounds() const; 268 269 // Paints different parts of the window to the incoming canvas. 270 void PaintFrameBorder(gfx::Canvas* canvas); 271 void PaintTitleBar(gfx::Canvas* canvas); 272 void PaintClientEdge(gfx::Canvas* canvas); 273 274 // Layout various sub-components of this view. 275 void LayoutWindowControls(); 276 void LayoutTitleBar(); 277 278 // Returns the bounds of the client area for the specified view size. 279 gfx::Rect CalculateClientAreaBounds(int width, int height) const; 280 281 SkColor GetTitleColor() const { 282 return browser_is_off_the_record_ 283#if defined(OS_WIN) && !defined(USE_AURA) 284 || !ui::win::IsAeroGlassEnabled() 285#endif 286 ? SK_ColorWHITE : SK_ColorBLACK; 287 } 288 289 // Loads the appropriate set of WindowResources for the frame view. 290 void InitWindowResources(); 291 292 views::Widget* container_; 293 294 bool browser_is_off_the_record_; 295 296 scoped_ptr<views::WindowResources> resources_; 297 298 gfx::Rect title_bounds_; 299 300 views::ImageButton* close_button_; 301 302 // The bounds of the ClientView. 303 gfx::Rect client_view_bounds_; 304 305 // Background painter for the frame. 306 scoped_ptr<views::FrameBackground> frame_background_; 307 308 static void InitClass(); 309 310 // The font to be used to render the titlebar text. 311 static const gfx::Font* title_font_; 312 313 DISALLOW_COPY_AND_ASSIGN(ConstrainedWindowFrameView); 314}; 315 316const gfx::Font* ConstrainedWindowFrameView::title_font_ = NULL; 317 318namespace { 319// The frame border is only visible in restored mode and is hardcoded to 4 px on 320// each side regardless of the system window border size. 321const int kFrameBorderThickness = 4; 322// Various edges of the frame border have a 1 px shadow along their edges; in a 323// few cases we shift elements based on this amount for visual appeal. 324const int kFrameShadowThickness = 1; 325// In the window corners, the resize areas don't actually expand bigger, but the 326// 16 px at the end of each edge triggers diagonal resizing. 327const int kResizeAreaCornerSize = 16; 328// The titlebar never shrinks too short to show the caption button plus some 329// padding below it. 330const int kCaptionButtonHeightWithPadding = 19; 331// The titlebar has a 2 px 3D edge along the top and bottom. 332const int kTitlebarTopAndBottomEdgeThickness = 2; 333// The icon would never shrink below 16 px on a side, if there was one. 334const int kIconMinimumSize = 16; 335// The title text starts 2 px from the right edge of the left frame border. 336const int kTitleLeftSpacing = 2; 337// There is a 5 px gap between the title text and the caption buttons. 338const int kTitleCaptionSpacing = 5; 339 340const SkColor kContentsBorderShadow = SkColorSetARGB(51, 0, 0, 0); 341 342} // namespace 343 344ConstrainedWindowFrameView::ConstrainedWindowFrameView( 345 views::Widget* container, bool browser_is_off_the_record) 346 : NonClientFrameView(), 347 container_(container), 348 browser_is_off_the_record_(browser_is_off_the_record), 349 close_button_(new views::ImageButton(this)), 350 frame_background_(new views::FrameBackground()) { 351 InitClass(); 352 InitWindowResources(); 353 354 // Constrained windows always use the custom frame - they just have a 355 // different set of images. 356 container->set_frame_type(views::Widget::FRAME_TYPE_FORCE_CUSTOM); 357 358 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 359 close_button_->SetImage(views::CustomButton::STATE_NORMAL, 360 rb.GetImageSkiaNamed(IDR_CLOSE_SA)); 361 close_button_->SetImage(views::CustomButton::STATE_HOVERED, 362 rb.GetImageSkiaNamed(IDR_CLOSE_SA_H)); 363 close_button_->SetImage(views::CustomButton::STATE_PRESSED, 364 rb.GetImageSkiaNamed(IDR_CLOSE_SA_P)); 365 close_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER, 366 views::ImageButton::ALIGN_MIDDLE); 367 AddChildView(close_button_); 368} 369 370ConstrainedWindowFrameView::~ConstrainedWindowFrameView() { 371} 372 373void ConstrainedWindowFrameView::UpdateWindowTitle() { 374 SchedulePaintInRect(title_bounds_); 375} 376 377gfx::Rect ConstrainedWindowFrameView::GetBoundsForClientView() const { 378 return client_view_bounds_; 379} 380 381gfx::Rect ConstrainedWindowFrameView::GetWindowBoundsForClientBounds( 382 const gfx::Rect& client_bounds) const { 383 int top_height = NonClientTopBorderHeight(); 384 int border_thickness = NonClientBorderThickness(); 385 return gfx::Rect(std::max(0, client_bounds.x() - border_thickness), 386 std::max(0, client_bounds.y() - top_height), 387 client_bounds.width() + (2 * border_thickness), 388 client_bounds.height() + top_height + border_thickness); 389} 390 391int ConstrainedWindowFrameView::NonClientHitTest(const gfx::Point& point) { 392 if (!bounds().Contains(point)) 393 return HTNOWHERE; 394 395 int frame_component = 396 container_->client_view()->NonClientHitTest(point); 397 398 // See if we're in the sysmenu region. (We check the ClientView first to be 399 // consistent with OpaqueBrowserFrameView; it's not really necessary here.) 400 gfx::Rect sysmenu_rect(IconBounds()); 401 sysmenu_rect.set_x(GetMirroredXForRect(sysmenu_rect)); 402 if (sysmenu_rect.Contains(point)) 403 return (frame_component == HTCLIENT) ? HTCLIENT : HTSYSMENU; 404 405 if (frame_component != HTNOWHERE) 406 return frame_component; 407 408 // Then see if the point is within any of the window controls. 409 if (close_button_->GetMirroredBounds().Contains(point)) 410 return HTCLOSE; 411 412 int window_component = GetHTComponentForFrame(point, kFrameBorderThickness, 413 NonClientBorderThickness(), kResizeAreaCornerSize, kResizeAreaCornerSize, 414 container_->widget_delegate()->CanResize()); 415 // Fall back to the caption if no other component matches. 416 return (window_component == HTNOWHERE) ? HTCAPTION : window_component; 417} 418 419void ConstrainedWindowFrameView::GetWindowMask(const gfx::Size& size, 420 gfx::Path* window_mask) { 421 DCHECK(window_mask); 422 views::GetDefaultWindowMask(size, window_mask); 423} 424 425void ConstrainedWindowFrameView::OnPaint(gfx::Canvas* canvas) { 426 PaintFrameBorder(canvas); 427 PaintTitleBar(canvas); 428 PaintClientEdge(canvas); 429} 430 431void ConstrainedWindowFrameView::Layout() { 432 LayoutWindowControls(); 433 LayoutTitleBar(); 434 client_view_bounds_ = CalculateClientAreaBounds(width(), height()); 435} 436 437void ConstrainedWindowFrameView::OnThemeChanged() { 438 InitWindowResources(); 439} 440 441void ConstrainedWindowFrameView::ButtonPressed( 442 views::Button* sender, const ui::Event& event) { 443 if (sender == close_button_) 444 container_->Close(); 445} 446 447int ConstrainedWindowFrameView::NonClientBorderThickness() const { 448 return kFrameBorderThickness + kClientEdgeThickness; 449} 450 451int ConstrainedWindowFrameView::NonClientTopBorderHeight() const { 452 return std::max(kFrameBorderThickness + IconSize(), 453 kFrameShadowThickness + kCaptionButtonHeightWithPadding) + 454 TitlebarBottomThickness(); 455} 456 457int ConstrainedWindowFrameView::TitlebarBottomThickness() const { 458 return kTitlebarTopAndBottomEdgeThickness + kClientEdgeThickness; 459} 460 461int ConstrainedWindowFrameView::IconSize() const { 462#if defined(OS_WIN) 463 // This metric scales up if either the titlebar height or the titlebar font 464 // size are increased. 465 return GetSystemMetrics(SM_CYSMICON); 466#else 467 return std::max(title_font_->GetHeight(), kIconMinimumSize); 468#endif 469} 470 471gfx::Rect ConstrainedWindowFrameView::IconBounds() const { 472 int size = IconSize(); 473 // Our frame border has a different "3D look" than Windows'. Theirs has a 474 // more complex gradient on the top that they push their icon/title below; 475 // then the maximized window cuts this off and the icon/title are centered 476 // in the remaining space. Because the apparent shape of our border is 477 // simpler, using the same positioning makes things look slightly uncentered 478 // with restored windows, so instead of calculating the remaining space from 479 // below the frame border, we calculate from below the 3D edge. 480 int unavailable_px_at_top = kTitlebarTopAndBottomEdgeThickness; 481 // When the icon is shorter than the minimum space we reserve for the caption 482 // button, we vertically center it. We want to bias rounding to put extra 483 // space above the icon, since the 3D edge + client edge below looks (to the 484 // eye) more like additional space than does the 3D edge above; hence the +1. 485 int y = unavailable_px_at_top + (NonClientTopBorderHeight() - 486 unavailable_px_at_top - size - TitlebarBottomThickness() + 1) / 2; 487 return gfx::Rect(kFrameBorderThickness + kTitleLeftSpacing, y, size, size); 488} 489 490void ConstrainedWindowFrameView::PaintFrameBorder(gfx::Canvas* canvas) { 491 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 492 frame_background_->set_frame_color(ThemeProperties::GetDefaultColor( 493 ThemeProperties::COLOR_FRAME)); 494 chrome::HostDesktopType desktop_type = 495 chrome::GetHostDesktopTypeForNativeView(GetWidget()->GetNativeView()); 496 gfx::ImageSkia* theme_frame = rb.GetImageSkiaNamed( 497 chrome::MapThemeImage(desktop_type, IDR_THEME_FRAME)); 498 frame_background_->set_theme_image(theme_frame); 499 frame_background_->set_theme_overlay_image(NULL); 500 frame_background_->set_top_area_height(theme_frame->height()); 501 502 frame_background_->SetCornerImages( 503 resources_->GetPartImage(FRAME_TOP_LEFT_CORNER), 504 resources_->GetPartImage(FRAME_TOP_RIGHT_CORNER), 505 resources_->GetPartImage(FRAME_BOTTOM_LEFT_CORNER), 506 resources_->GetPartImage(FRAME_BOTTOM_RIGHT_CORNER)); 507 frame_background_->SetSideImages( 508 resources_->GetPartImage(FRAME_LEFT_EDGE), 509 resources_->GetPartImage(FRAME_TOP_EDGE), 510 resources_->GetPartImage(FRAME_RIGHT_EDGE), 511 resources_->GetPartImage(FRAME_BOTTOM_EDGE)); 512 frame_background_->PaintRestored(canvas, this); 513} 514 515void ConstrainedWindowFrameView::PaintTitleBar(gfx::Canvas* canvas) { 516 canvas->DrawStringInt( 517 container_->widget_delegate()->GetWindowTitle(), 518 *title_font_, GetTitleColor(), GetMirroredXForRect(title_bounds_), 519 title_bounds_.y(), title_bounds_.width(), title_bounds_.height()); 520} 521 522void ConstrainedWindowFrameView::PaintClientEdge(gfx::Canvas* canvas) { 523 gfx::Rect client_edge_bounds(CalculateClientAreaBounds(width(), height())); 524 client_edge_bounds.Inset(-kClientEdgeThickness, -kClientEdgeThickness); 525 gfx::Rect frame_shadow_bounds(client_edge_bounds); 526 frame_shadow_bounds.Inset(-kFrameShadowThickness, -kFrameShadowThickness); 527 528 canvas->FillRect(frame_shadow_bounds, kContentsBorderShadow); 529 canvas->FillRect(client_edge_bounds, views::kClientEdgeColor); 530} 531 532void ConstrainedWindowFrameView::LayoutWindowControls() { 533 gfx::Size close_button_size = close_button_->GetPreferredSize(); 534 close_button_->SetBounds( 535 width() - kFrameBorderThickness - close_button_size.width(), 536 kFrameShadowThickness, close_button_size.width(), 537 close_button_size.height()); 538} 539 540void ConstrainedWindowFrameView::LayoutTitleBar() { 541 // The window title is based on the calculated icon position, even though' 542 // there is no icon in constrained windows. 543 gfx::Rect icon_bounds(IconBounds()); 544 int title_x = icon_bounds.x(); 545 int title_height = title_font_->GetHeight(); 546 // We bias the title position so that when the difference between the icon and 547 // title heights is odd, the extra pixel of the title is above the vertical 548 // midline rather than below. This compensates for how the icon is already 549 // biased downwards (see IconBounds()) and helps prevent descenders on the 550 // title from overlapping the 3D edge at the bottom of the titlebar. 551 title_bounds_.SetRect(title_x, 552 icon_bounds.y() + ((icon_bounds.height() - title_height - 1) / 2), 553 std::max(0, close_button_->x() - kTitleCaptionSpacing - title_x), 554 title_height); 555} 556 557gfx::Rect ConstrainedWindowFrameView::CalculateClientAreaBounds( 558 int width, 559 int height) const { 560 int top_height = NonClientTopBorderHeight(); 561 int border_thickness = NonClientBorderThickness(); 562 return gfx::Rect(border_thickness, top_height, 563 std::max(0, width - (2 * border_thickness)), 564 std::max(0, height - top_height - border_thickness)); 565} 566 567void ConstrainedWindowFrameView::InitWindowResources() { 568#if defined(OS_WIN) && !defined(USE_AURA) 569 resources_.reset(ui::win::IsAeroGlassEnabled() ? 570 static_cast<views::WindowResources*>(new VistaWindowResources) : 571 new XPWindowResources); 572#else 573 // TODO(oshima): Use aura frame decoration. 574 resources_.reset(new XPWindowResources); 575#endif 576} 577 578// static 579void ConstrainedWindowFrameView::InitClass() { 580 static bool initialized = false; 581 if (!initialized) { 582#if defined(OS_WIN) && !defined(USE_AURA) 583 title_font_ = new gfx::Font(views::NativeWidgetWin::GetWindowTitleFont()); 584#else 585 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 586 title_font_ = &rb.GetFont(ui::ResourceBundle::MediumFont); 587#endif 588 initialized = true; 589 } 590} 591 592void UpdateWebContentsModalDialogPosition( 593 views::Widget* widget, 594 web_modal::WebContentsModalDialogHost* dialog_host) { 595 gfx::Size size = widget->GetRootView()->GetPreferredSize(); 596 gfx::Size max_size = dialog_host->GetMaximumDialogSize(); 597 // Enlarge the max size by the top border, as the dialog will be shifted 598 // outside the area specified by the dialog host by this amount later. 599 views::Border* border = 600 widget->non_client_view()->frame_view()->border(); 601 // Border may be null during widget initialization. 602 if (border) 603 max_size.Enlarge(0, border->GetInsets().top()); 604 size.SetToMin(max_size); 605 UpdateModalDialogPosition(widget, dialog_host, size); 606} 607 608void UpdateBrowserModalDialogPosition( 609 views::Widget* widget, 610 web_modal::ModalDialogHost* dialog_host) { 611 UpdateModalDialogPosition(widget, 612 dialog_host, 613 widget->GetRootView()->GetPreferredSize()); 614} 615 616views::Widget* CreateBrowserModalDialogViews(views::DialogDelegate* dialog, 617 gfx::NativeWindow parent) { 618 views::Widget* widget = 619 views::DialogDelegate::CreateDialogWidget(dialog, NULL, parent); 620 if (!dialog->UseNewStyleForThisDialog()) 621 return widget; 622 623 // Get the browser dialog management and hosting components from |parent|. 624 Browser* browser = chrome::FindBrowserWithWindow(parent); 625 if (browser) { 626 ChromeWebModalDialogManagerDelegate* manager = browser; 627 ModalDialogHost* host = manager->GetWebContentsModalDialogHost(); 628 DCHECK_EQ(parent, host->GetHostView()); 629 ModalDialogHostObserver* dialog_host_observer = 630 new BrowserModalDialogHostObserverViews( 631 host, widget, kBrowserModalDialogHostObserverViewsKey); 632 dialog_host_observer->OnPositionRequiresUpdate(); 633 } 634 return widget; 635} 636 637views::NonClientFrameView* CreateConstrainedStyleNonClientFrameView( 638 views::Widget* widget, 639 content::BrowserContext* browser_context) { 640 if (views::DialogDelegate::UseNewStyle()) { 641#if defined(USE_AURA) 642 const bool force_opaque_border = false; 643#else 644 const bool force_opaque_border = true; 645#endif 646 return views::DialogDelegate::CreateNewStyleFrameView(widget, 647 force_opaque_border); 648 } 649#if defined(USE_ASH) 650 ash::CustomFrameViewAsh* frame = new ash::CustomFrameViewAsh; 651 frame->Init(widget); 652 // Always use "active" look. 653 frame->SetInactiveRenderingDisabled(true); 654 return frame; 655#endif 656 return new ConstrainedWindowFrameView(widget, 657 browser_context->IsOffTheRecord()); 658} 659