OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "views/widget/widget.h" | 5 #include "views/widget/widget.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
10 #include "ui/base/l10n/l10n_font_util.h" | 10 #include "ui/base/l10n/l10n_font_util.h" |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 delegate(NULL), | 89 delegate(NULL), |
90 child(false), | 90 child(false), |
91 transient(false), | 91 transient(false), |
92 transparent(false), | 92 transparent(false), |
93 accept_events(true), | 93 accept_events(true), |
94 can_activate(true), | 94 can_activate(true), |
95 keep_on_top(false), | 95 keep_on_top(false), |
96 ownership(NATIVE_WIDGET_OWNS_WIDGET), | 96 ownership(NATIVE_WIDGET_OWNS_WIDGET), |
97 mirror_origin_in_rtl(false), | 97 mirror_origin_in_rtl(false), |
98 has_dropshadow(false), | 98 has_dropshadow(false), |
| 99 maximize(false), |
99 double_buffer(false), | 100 double_buffer(false), |
100 parent(NULL), | 101 parent(NULL), |
101 parent_widget(NULL), | 102 parent_widget(NULL), |
102 native_widget(NULL) { | 103 native_widget(NULL) { |
103 } | 104 } |
104 | 105 |
105 Widget::InitParams::InitParams(Type type) | 106 Widget::InitParams::InitParams(Type type) |
106 : type(type), | 107 : type(type), |
107 delegate(NULL), | 108 delegate(NULL), |
108 child(type == TYPE_CONTROL), | 109 child(type == TYPE_CONTROL), |
109 transient(type == TYPE_POPUP || type == TYPE_MENU), | 110 transient(type == TYPE_POPUP || type == TYPE_MENU), |
110 transparent(false), | 111 transparent(false), |
111 accept_events(true), | 112 accept_events(true), |
112 can_activate(type != TYPE_POPUP && type != TYPE_MENU), | 113 can_activate(type != TYPE_POPUP && type != TYPE_MENU), |
113 keep_on_top(type == TYPE_MENU), | 114 keep_on_top(type == TYPE_MENU), |
114 ownership(NATIVE_WIDGET_OWNS_WIDGET), | 115 ownership(NATIVE_WIDGET_OWNS_WIDGET), |
115 mirror_origin_in_rtl(false), | 116 mirror_origin_in_rtl(false), |
116 has_dropshadow(false), | 117 has_dropshadow(false), |
| 118 maximize(false), |
117 double_buffer(false), | 119 double_buffer(false), |
118 parent(NULL), | 120 parent(NULL), |
119 parent_widget(NULL), | 121 parent_widget(NULL), |
120 native_widget(NULL) { | 122 native_widget(NULL) { |
121 } | 123 } |
122 | 124 |
123 //////////////////////////////////////////////////////////////////////////////// | 125 //////////////////////////////////////////////////////////////////////////////// |
124 // Widget, public: | 126 // Widget, public: |
125 | 127 |
126 // static | 128 // static |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 ownership_ = params.ownership; | 265 ownership_ = params.ownership; |
264 native_widget_ = params.native_widget ? | 266 native_widget_ = params.native_widget ? |
265 params.native_widget->AsNativeWidgetPrivate() : | 267 params.native_widget->AsNativeWidgetPrivate() : |
266 internal::NativeWidgetPrivate::CreateNativeWidget(this); | 268 internal::NativeWidgetPrivate::CreateNativeWidget(this); |
267 GetRootView(); | 269 GetRootView(); |
268 default_theme_provider_.reset(new DefaultThemeProvider); | 270 default_theme_provider_.reset(new DefaultThemeProvider); |
269 if (params.type == InitParams::TYPE_MENU) { | 271 if (params.type == InitParams::TYPE_MENU) { |
270 is_mouse_button_pressed_ = | 272 is_mouse_button_pressed_ = |
271 internal::NativeWidgetPrivate::IsMouseButtonDown(); | 273 internal::NativeWidgetPrivate::IsMouseButtonDown(); |
272 } | 274 } |
273 native_widget_->InitNativeWidget(params); | 275 InitParams params_copy(params); |
274 if (params.type == InitParams::TYPE_WINDOW) { | 276 if (params.type == InitParams::TYPE_WINDOW) { |
| 277 // If we're creating a window see if the delegate wants us to use a size |
| 278 // different than that supplied to the constructor. |
| 279 gfx::Rect saved_bounds; |
| 280 bool saved_maximized_state; |
| 281 if (GetSavedBounds(&saved_bounds, &saved_maximized_state)) { |
| 282 params_copy.maximize = saved_maximized_state; |
| 283 params_copy.bounds = saved_bounds; |
| 284 } |
| 285 } |
| 286 native_widget_->InitNativeWidget(params_copy); |
| 287 if (params.type == InitParams::TYPE_WINDOW) { |
| 288 // Create the ClientView, add it to the NonClientView and add the |
| 289 // NonClientView to the RootView. This will cause everything to be parented. |
275 non_client_view_ = new NonClientView; | 290 non_client_view_ = new NonClientView; |
276 non_client_view_->SetFrameView(CreateNonClientFrameView()); | 291 non_client_view_->SetFrameView(CreateNonClientFrameView()); |
277 // Create the ClientView, add it to the NonClientView and add the | |
278 // NonClientView to the RootView. This will cause everything to be parented. | |
279 non_client_view_->set_client_view(widget_delegate_->CreateClientView(this)); | 292 non_client_view_->set_client_view(widget_delegate_->CreateClientView(this)); |
280 SetContentsView(non_client_view_); | 293 SetContentsView(non_client_view_); |
281 SetInitialBounds(params.bounds); | 294 SetInitialBounds(params.bounds); |
282 UpdateWindowTitle(); | 295 UpdateWindowTitle(); |
283 } | 296 } |
284 } | 297 } |
285 | 298 |
286 // Unconverted methods (see header) -------------------------------------------- | 299 // Unconverted methods (see header) -------------------------------------------- |
287 | 300 |
288 gfx::NativeView Widget::GetNativeView() const { | 301 gfx::NativeView Widget::GetNativeView() const { |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 } | 418 } |
406 | 419 |
407 void Widget::EnableClose(bool enable) { | 420 void Widget::EnableClose(bool enable) { |
408 if (non_client_view_) | 421 if (non_client_view_) |
409 non_client_view_->EnableClose(enable); | 422 non_client_view_->EnableClose(enable); |
410 native_widget_->EnableClose(enable); | 423 native_widget_->EnableClose(enable); |
411 } | 424 } |
412 | 425 |
413 void Widget::Show() { | 426 void Widget::Show() { |
414 if (non_client_view_) { | 427 if (non_client_view_) { |
415 native_widget_->ShowNativeWidget( | 428 if (saved_maximized_state_ && !initial_restored_bounds_.IsEmpty()) { |
416 saved_maximized_state_ ? internal::NativeWidgetPrivate::SHOW_MAXIMIZED | 429 native_widget_->ShowMaximized(initial_restored_bounds_); |
417 : internal::NativeWidgetPrivate::SHOW_RESTORED); | 430 } else { |
| 431 native_widget_->ShowNativeWidget(saved_maximized_state_ ? |
| 432 internal::NativeWidgetPrivate::SHOW_MAXIMIZED : |
| 433 internal::NativeWidgetPrivate::SHOW_RESTORED); |
| 434 } |
418 // |saved_maximized_state_| only applies the first time the window is shown. | 435 // |saved_maximized_state_| only applies the first time the window is shown. |
419 // If we don't reset the value the window will be shown maximized every time | 436 // If we don't reset the value the window will be shown maximized every time |
420 // it is subsequently shown after being hidden. | 437 // it is subsequently shown after being hidden. |
421 saved_maximized_state_ = false; | 438 saved_maximized_state_ = false; |
422 } else { | 439 } else { |
423 native_widget_->Show(); | 440 native_widget_->Show(); |
424 } | 441 } |
425 } | 442 } |
426 | 443 |
427 void Widget::Hide() { | 444 void Widget::Hide() { |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
965 bool maximized; | 982 bool maximized; |
966 gfx::Rect bounds; | 983 gfx::Rect bounds; |
967 native_widget_->GetWindowBoundsAndMaximizedState(&bounds, &maximized); | 984 native_widget_->GetWindowBoundsAndMaximizedState(&bounds, &maximized); |
968 widget_delegate_->SaveWindowPlacement(bounds, maximized); | 985 widget_delegate_->SaveWindowPlacement(bounds, maximized); |
969 } | 986 } |
970 | 987 |
971 void Widget::SetInitialBounds(const gfx::Rect& bounds) { | 988 void Widget::SetInitialBounds(const gfx::Rect& bounds) { |
972 if (!non_client_view_) | 989 if (!non_client_view_) |
973 return; | 990 return; |
974 | 991 |
975 // First we obtain the window's saved show-style and store it. We need to do | 992 gfx::Rect saved_bounds; |
976 // this here, rather than in Show() because by the time Show() is called, | 993 if (GetSavedBounds(&saved_bounds, &saved_maximized_state_)) { |
977 // the window's size will have been reset (below) and the saved maximized | 994 if (saved_maximized_state_) { |
978 // state will have been lost. Sadly there's no way to tell on Windows when | 995 // If we're going to maximize, wait until Show is invoked to set the |
979 // a window is restored from maximized state, so we can't more accurately | 996 // bounds. That way we avoid a noticable resize. |
980 // track maximized state independently of sizing information. | 997 initial_restored_bounds_ = saved_bounds; |
981 widget_delegate_->GetSavedMaximizedState( | |
982 &saved_maximized_state_); | |
983 | |
984 // Restore the window's placement from the controller. | |
985 gfx::Rect saved_bounds = bounds; | |
986 if (widget_delegate_->GetSavedWindowBounds(&saved_bounds)) { | |
987 if (!widget_delegate_->ShouldRestoreWindowSize()) { | |
988 saved_bounds.set_size(non_client_view_->GetPreferredSize()); | |
989 } else { | 998 } else { |
990 // Make sure the bounds are at least the minimum size. | 999 SetBounds(saved_bounds); |
991 if (saved_bounds.width() < minimum_size_.width()) { | |
992 saved_bounds.SetRect(saved_bounds.x(), saved_bounds.y(), | |
993 saved_bounds.right() + minimum_size_.width() - | |
994 saved_bounds.width(), | |
995 saved_bounds.bottom()); | |
996 } | |
997 | |
998 if (saved_bounds.height() < minimum_size_.height()) { | |
999 saved_bounds.SetRect(saved_bounds.x(), saved_bounds.y(), | |
1000 saved_bounds.right(), | |
1001 saved_bounds.bottom() + minimum_size_.height() - | |
1002 saved_bounds.height()); | |
1003 } | |
1004 } | 1000 } |
1005 | |
1006 // Widget's SetBounds method does not further modify the bounds that are | |
1007 // passed to it. | |
1008 SetBounds(saved_bounds); | |
1009 } else { | 1001 } else { |
1010 if (bounds.IsEmpty()) { | 1002 if (bounds.IsEmpty()) { |
1011 // No initial bounds supplied, so size the window to its content and | 1003 // No initial bounds supplied, so size the window to its content and |
1012 // center over its parent. | 1004 // center over its parent. |
1013 native_widget_->CenterWindow(non_client_view_->GetPreferredSize()); | 1005 native_widget_->CenterWindow(non_client_view_->GetPreferredSize()); |
1014 } else { | 1006 } else { |
1015 // Use the supplied initial bounds. | 1007 // Use the supplied initial bounds. |
1016 SetBoundsConstrained(bounds, NULL); | 1008 SetBoundsConstrained(bounds, NULL); |
1017 } | 1009 } |
1018 } | 1010 } |
1019 } | 1011 } |
1020 | 1012 |
| 1013 bool Widget::GetSavedBounds(gfx::Rect* bounds, bool* maximize) { |
| 1014 // First we obtain the window's saved show-style and store it. We need to do |
| 1015 // this here, rather than in Show() because by the time Show() is called, |
| 1016 // the window's size will have been reset (below) and the saved maximized |
| 1017 // state will have been lost. Sadly there's no way to tell on Windows when |
| 1018 // a window is restored from maximized state, so we can't more accurately |
| 1019 // track maximized state independently of sizing information. |
| 1020 widget_delegate_->GetSavedMaximizedState(maximize); |
| 1021 |
| 1022 // Restore the window's placement from the controller. |
| 1023 if (widget_delegate_->GetSavedWindowBounds(bounds)) { |
| 1024 if (!widget_delegate_->ShouldRestoreWindowSize()) { |
| 1025 if (!non_client_view_) { |
| 1026 // This may be invoked before the non_client_view_ is created. |
| 1027 return false; |
| 1028 } |
| 1029 bounds->set_size(non_client_view_->GetPreferredSize()); |
| 1030 } else { |
| 1031 // Make sure the bounds are at least the minimum size. |
| 1032 if (bounds->width() < minimum_size_.width()) |
| 1033 bounds->set_width(minimum_size_.width()); |
| 1034 |
| 1035 if (bounds->height() < minimum_size_.height()) |
| 1036 bounds->set_height(minimum_size_.height()); |
| 1037 } |
| 1038 return true; |
| 1039 } |
| 1040 return false; |
| 1041 } |
| 1042 |
1021 namespace internal { | 1043 namespace internal { |
1022 | 1044 |
1023 //////////////////////////////////////////////////////////////////////////////// | 1045 //////////////////////////////////////////////////////////////////////////////// |
1024 // internal::NativeWidgetPrivate, NativeWidget implementation: | 1046 // internal::NativeWidgetPrivate, NativeWidget implementation: |
1025 | 1047 |
1026 internal::NativeWidgetPrivate* NativeWidgetPrivate::AsNativeWidgetPrivate() { | 1048 internal::NativeWidgetPrivate* NativeWidgetPrivate::AsNativeWidgetPrivate() { |
1027 return this; | 1049 return this; |
1028 } | 1050 } |
1029 | 1051 |
1030 } // namespace internal | 1052 } // namespace internal |
1031 } // namespace views | 1053 } // namespace views |
OLD | NEW |