Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / constrained_window_views.cc
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/ui/browser_finder.h"
10 #include "components/web_modal/web_contents_modal_dialog_host.h"
11 #include "ui/views/border.h"
12 #include "ui/views/widget/widget.h"
13 #include "ui/views/widget/widget_observer.h"
14 #include "ui/views/window/dialog_delegate.h"
15
16 using web_modal::ModalDialogHost;
17 using web_modal::ModalDialogHostObserver;
18
19 namespace {
20 // The name of a key to store on the window handle to associate
21 // BrowserModalDialogHostObserverViews with the Widget.
22 const char* const kBrowserModalDialogHostObserverViewsKey =
23     "__BROWSER_MODAL_DIALOG_HOST_OBSERVER_VIEWS__";
24
25 // Applies positioning changes from the ModalDialogHost to the Widget.
26 class BrowserModalDialogHostObserverViews
27     : public views::WidgetObserver,
28       public ModalDialogHostObserver {
29  public:
30   BrowserModalDialogHostObserverViews(ModalDialogHost* host,
31                                       views::Widget* target_widget,
32                                       const char *const native_window_property)
33       : host_(host),
34         target_widget_(target_widget),
35         native_window_property_(native_window_property) {
36     DCHECK(host_);
37     DCHECK(target_widget_);
38     host_->AddObserver(this);
39     target_widget_->AddObserver(this);
40   }
41
42   virtual ~BrowserModalDialogHostObserverViews() {
43     if (host_)
44       host_->RemoveObserver(this);
45     target_widget_->RemoveObserver(this);
46     target_widget_->SetNativeWindowProperty(native_window_property_, NULL);
47   }
48
49   // WidgetObserver overrides
50   virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE {
51     delete this;
52   }
53
54   // WebContentsModalDialogHostObserver overrides
55   virtual void OnPositionRequiresUpdate() OVERRIDE {
56     UpdateBrowserModalDialogPosition(target_widget_, host_);
57   }
58
59   virtual void OnHostDestroying() OVERRIDE {
60     host_->RemoveObserver(this);
61     host_ = NULL;
62   }
63
64  private:
65   ModalDialogHost* host_;
66   views::Widget* target_widget_;
67   const char* const native_window_property_;
68
69   DISALLOW_COPY_AND_ASSIGN(BrowserModalDialogHostObserverViews);
70 };
71
72 void UpdateModalDialogPosition(views::Widget* widget,
73                                web_modal::ModalDialogHost* dialog_host,
74                                const gfx::Size& size) {
75   // Do not forcibly update the dialog widget position if it is being dragged.
76   if (widget->HasCapture())
77     return;
78
79   gfx::Point position = dialog_host->GetDialogPosition(size);
80   views::Border* border = widget->non_client_view()->frame_view()->border();
81   // Border may be null during widget initialization.
82   if (border) {
83     // Align the first row of pixels inside the border. This is the apparent
84     // top of the dialog.
85     position.set_y(position.y() - border->GetInsets().top());
86   }
87
88   if (widget->is_top_level()) {
89     position +=
90         views::Widget::GetWidgetForNativeView(dialog_host->GetHostView())->
91             GetClientAreaBoundsInScreen().OffsetFromOrigin();
92   }
93
94   widget->SetBounds(gfx::Rect(position, size));
95 }
96
97 }  // namespace
98
99 void UpdateWebContentsModalDialogPosition(
100     views::Widget* widget,
101     web_modal::WebContentsModalDialogHost* dialog_host) {
102   gfx::Size size = widget->GetRootView()->GetPreferredSize();
103   gfx::Size max_size = dialog_host->GetMaximumDialogSize();
104   // Enlarge the max size by the top border, as the dialog will be shifted
105   // outside the area specified by the dialog host by this amount later.
106   views::Border* border =
107       widget->non_client_view()->frame_view()->border();
108   // Border may be null during widget initialization.
109   if (border)
110     max_size.Enlarge(0, border->GetInsets().top());
111   size.SetToMin(max_size);
112   UpdateModalDialogPosition(widget, dialog_host, size);
113 }
114
115 void UpdateBrowserModalDialogPosition(views::Widget* widget,
116                                       web_modal::ModalDialogHost* dialog_host) {
117   UpdateModalDialogPosition(widget, dialog_host,
118                             widget->GetRootView()->GetPreferredSize());
119 }
120
121 views::Widget* CreateBrowserModalDialogViews(views::DialogDelegate* dialog,
122                                              gfx::NativeWindow parent) {
123   views::Widget* widget =
124       views::DialogDelegate::CreateDialogWidget(dialog, NULL, parent);
125   if (!dialog->UseNewStyleForThisDialog())
126     return widget;
127
128   // Get the browser dialog management and hosting components from |parent|.
129   Browser* browser = chrome::FindBrowserWithWindow(parent);
130   if (browser) {
131     ChromeWebModalDialogManagerDelegate* manager = browser;
132     ModalDialogHost* host = manager->GetWebContentsModalDialogHost();
133     DCHECK_EQ(parent, host->GetHostView());
134     ModalDialogHostObserver* dialog_host_observer =
135         new BrowserModalDialogHostObserverViews(
136             host, widget, kBrowserModalDialogHostObserverViewsKey);
137     dialog_host_observer->OnPositionRequiresUpdate();
138   }
139   return widget;
140 }