| 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 |