| OLD | NEW |
| 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 "ui/views/window/dialog_client_view.h" | 5 #include "ui/views/window/dialog_client_view.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "build/build_config.h" | 9 #include "build/build_config.h" |
| 10 #include "ui/base/material_design/material_design_controller.h" | 10 #include "ui/base/material_design/material_design_controller.h" |
| 11 #include "ui/events/keycodes/keyboard_codes.h" | 11 #include "ui/events/keycodes/keyboard_codes.h" |
| 12 #include "ui/views/background.h" | 12 #include "ui/views/background.h" |
| 13 #include "ui/views/border.h" | 13 #include "ui/views/border.h" |
| 14 #include "ui/views/controls/button/blue_button.h" | 14 #include "ui/views/controls/button/blue_button.h" |
| 15 #include "ui/views/controls/button/custom_button.h" | 15 #include "ui/views/controls/button/custom_button.h" |
| 16 #include "ui/views/controls/button/label_button.h" | 16 #include "ui/views/controls/button/label_button.h" |
| 17 #include "ui/views/controls/button/md_text_button.h" | 17 #include "ui/views/controls/button/md_text_button.h" |
| 18 #include "ui/views/layout/layout_constants.h" | |
| 19 #include "ui/views/style/platform_style.h" | 18 #include "ui/views/style/platform_style.h" |
| 20 #include "ui/views/views_delegate.h" | 19 #include "ui/views/views_delegate.h" |
| 21 #include "ui/views/widget/widget.h" | 20 #include "ui/views/widget/widget.h" |
| 22 #include "ui/views/window/dialog_delegate.h" | 21 #include "ui/views/window/dialog_delegate.h" |
| 23 | 22 |
| 24 namespace views { | 23 namespace views { |
| 25 | 24 |
| 26 namespace { | 25 namespace { |
| 27 | 26 |
| 28 // The group used by the buttons. This name is chosen voluntarily big not to | 27 // The group used by the buttons. This name is chosen voluntarily big not to |
| (...skipping 19 matching lines...) Expand all Loading... |
| 48 if (!button) | 47 if (!button) |
| 49 return; | 48 return; |
| 50 | 49 |
| 51 const gfx::Size size = button->GetPreferredSize(); | 50 const gfx::Size size = button->GetPreferredSize(); |
| 52 row_bounds->set_width(row_bounds->width() - size.width()); | 51 row_bounds->set_width(row_bounds->width() - size.width()); |
| 53 DCHECK_LE(button_height, row_bounds->height()); | 52 DCHECK_LE(button_height, row_bounds->height()); |
| 54 button->SetBounds( | 53 button->SetBounds( |
| 55 row_bounds->right(), | 54 row_bounds->right(), |
| 56 row_bounds->y() + (row_bounds->height() - button_height) / 2, | 55 row_bounds->y() + (row_bounds->height() - button_height) / 2, |
| 57 size.width(), button_height); | 56 size.width(), button_height); |
| 58 int spacing = ViewsDelegate::GetInstance() | 57 const int spacing = |
| 59 ? ViewsDelegate::GetInstance() | 58 ViewsDelegate::GetInstance()->GetDialogRelatedButtonHorizontalSpacing(); |
| 60 ->GetDialogRelatedButtonHorizontalSpacing() | |
| 61 : kRelatedButtonHSpacing; | |
| 62 row_bounds->set_width(row_bounds->width() - spacing); | 59 row_bounds->set_width(row_bounds->width() - spacing); |
| 63 } | 60 } |
| 64 | 61 |
| 65 } // namespace | 62 } // namespace |
| 66 | 63 |
| 67 /////////////////////////////////////////////////////////////////////////////// | 64 /////////////////////////////////////////////////////////////////////////////// |
| 68 // DialogClientView, public: | 65 // DialogClientView, public: |
| 69 | 66 |
| 70 DialogClientView::DialogClientView(Widget* owner, View* contents_view) | 67 DialogClientView::DialogClientView(Widget* owner, View* contents_view) |
| 71 : ClientView(owner, contents_view) { | 68 : ClientView(owner, contents_view), |
| 72 button_row_insets_ = | 69 button_row_insets_( |
| 73 ViewsDelegate::GetInstance() | 70 ViewsDelegate::GetInstance()->GetDialogButtonInsets()) { |
| 74 ? ViewsDelegate::GetInstance()->GetDialogButtonInsets() | |
| 75 : gfx::Insets(0, kButtonHEdgeMarginNew, kButtonVEdgeMarginNew, | |
| 76 kButtonHEdgeMarginNew); | |
| 77 // Doing this now ensures this accelerator will have lower priority than | 71 // Doing this now ensures this accelerator will have lower priority than |
| 78 // one set by the contents view. | 72 // one set by the contents view. |
| 79 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); | 73 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); |
| 80 | |
| 81 if (ViewsDelegate::GetInstance()) | |
| 82 button_row_insets_ = ViewsDelegate::GetInstance()->GetDialogButtonInsets(); | |
| 83 } | 74 } |
| 84 | 75 |
| 85 DialogClientView::~DialogClientView() { | 76 DialogClientView::~DialogClientView() { |
| 86 } | 77 } |
| 87 | 78 |
| 88 void DialogClientView::AcceptWindow() { | 79 void DialogClientView::AcceptWindow() { |
| 89 // Only notify the delegate once. See |delegate_allowed_close_|'s comment. | 80 // Only notify the delegate once. See |delegate_allowed_close_|'s comment. |
| 90 if (!delegate_allowed_close_ && GetDialogDelegate()->Accept()) { | 81 if (!delegate_allowed_close_ && GetDialogDelegate()->Accept()) { |
| 91 delegate_allowed_close_ = true; | 82 delegate_allowed_close_ = true; |
| 92 GetWidget()->Close(); | 83 GetWidget()->Close(); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 return this; | 141 return this; |
| 151 } | 142 } |
| 152 | 143 |
| 153 //////////////////////////////////////////////////////////////////////////////// | 144 //////////////////////////////////////////////////////////////////////////////// |
| 154 // DialogClientView, View overrides: | 145 // DialogClientView, View overrides: |
| 155 | 146 |
| 156 gfx::Size DialogClientView::GetPreferredSize() const { | 147 gfx::Size DialogClientView::GetPreferredSize() const { |
| 157 // Initialize the size to fit the buttons and extra view row. | 148 // Initialize the size to fit the buttons and extra view row. |
| 158 int extra_view_padding = 0; | 149 int extra_view_padding = 0; |
| 159 if (!GetDialogDelegate()->GetExtraViewPadding(&extra_view_padding)) | 150 if (!GetDialogDelegate()->GetExtraViewPadding(&extra_view_padding)) |
| 160 extra_view_padding = ViewsDelegate::GetInstance() | 151 extra_view_padding = |
| 161 ? ViewsDelegate::GetInstance() | 152 ViewsDelegate::GetInstance()->GetDialogRelatedButtonHorizontalSpacing(); |
| 162 ->GetDialogRelatedButtonHorizontalSpacing() | |
| 163 : kRelatedButtonHSpacing; | |
| 164 gfx::Size size( | 153 gfx::Size size( |
| 165 (ok_button_ ? ok_button_->GetPreferredSize().width() : 0) + | 154 (ok_button_ ? ok_button_->GetPreferredSize().width() : 0) + |
| 166 (cancel_button_ ? cancel_button_->GetPreferredSize().width() : 0) + | 155 (cancel_button_ ? cancel_button_->GetPreferredSize().width() : 0) + |
| 167 (cancel_button_ && ok_button_ | 156 (cancel_button_ && ok_button_ |
| 168 ? (ViewsDelegate::GetInstance() | 157 ? ViewsDelegate::GetInstance() |
| 169 ? ViewsDelegate::GetInstance() | 158 ->GetDialogRelatedButtonHorizontalSpacing() |
| 170 ->GetDialogRelatedButtonHorizontalSpacing() | 159 : 0) + |
| 171 : kRelatedButtonHSpacing) : 0) + | 160 (ShouldShow(extra_view_) ? extra_view_->GetPreferredSize().width() |
| 172 (ShouldShow(extra_view_) ? extra_view_->GetPreferredSize().width() : 0) + | 161 : 0) + |
| 173 (ShouldShow(extra_view_) && has_dialog_buttons() ? extra_view_padding | 162 (ShouldShow(extra_view_) && has_dialog_buttons() ? extra_view_padding |
| 174 : 0), | 163 : 0), |
| 175 0); | 164 0); |
| 176 | 165 |
| 177 int buttons_height = GetButtonsAndExtraViewRowHeight(); | 166 int buttons_height = GetButtonsAndExtraViewRowHeight(); |
| 178 if (buttons_height != 0) { | 167 if (buttons_height != 0) { |
| 179 size.Enlarge(0, buttons_height + GetButtonsAndExtraViewRowTopPadding()); | 168 size.Enlarge(0, buttons_height); |
| 180 // Inset the buttons and extra view. | 169 // Inset the buttons and extra view. |
| 181 const gfx::Insets insets = GetButtonRowInsets(); | 170 const gfx::Insets insets = GetButtonRowInsets(); |
| 182 size.Enlarge(insets.width(), insets.height()); | 171 size.Enlarge(insets.width(), insets.height()); |
| 183 } | 172 } |
| 184 | 173 |
| 185 // Increase the size as needed to fit the contents view. | 174 // Increase the size as needed to fit the contents view. |
| 186 // NOTE: The contents view is not inset on the top or side client view edges. | 175 // NOTE: The contents view is not inset on the top or side client view edges. |
| 187 gfx::Size contents_size = contents_view()->GetPreferredSize(); | 176 gfx::Size contents_size = contents_view()->GetPreferredSize(); |
| 188 size.Enlarge(0, contents_size.height()); | 177 size.Enlarge(0, contents_size.height()); |
| 189 size.set_width(std::max(size.width(), contents_size.width())); | 178 size.set_width(std::max(size.width(), contents_size.width())); |
| 190 | 179 |
| 191 size.SetToMax(minimum_size_); | 180 size.SetToMax(minimum_size_); |
| 192 | 181 |
| 193 return size; | 182 return size; |
| 194 } | 183 } |
| 195 | 184 |
| 196 void DialogClientView::Layout() { | 185 void DialogClientView::Layout() { |
| 197 gfx::Rect bounds = GetContentsBounds(); | 186 gfx::Rect bounds = GetContentsBounds(); |
| 198 | 187 |
| 199 // Layout the row containing the buttons and the extra view. | 188 // Layout the row containing the buttons and the extra view. |
| 200 if (has_dialog_buttons() || ShouldShow(extra_view_)) { | 189 if (has_dialog_buttons() || ShouldShow(extra_view_)) { |
| 201 bounds.Inset(GetButtonRowInsets()); | 190 gfx::Insets button_row_insets = GetButtonRowInsets(); |
| 191 // Don't apply the top inset here because it's supposed to go above the |
| 192 // buttons, not at the top of the dialog. |
| 193 bounds.Inset(button_row_insets.left(), 0, button_row_insets.right(), |
| 194 button_row_insets.bottom()); |
| 202 const int height = GetButtonsAndExtraViewRowHeight(); | 195 const int height = GetButtonsAndExtraViewRowHeight(); |
| 203 gfx::Rect row_bounds(bounds.x(), bounds.bottom() - height, | 196 gfx::Rect row_bounds(bounds.x(), bounds.bottom() - height, |
| 204 bounds.width(), height); | 197 bounds.width(), height); |
| 205 // If the |extra_view_| is a also button, then the |button_height| is the | 198 // If the |extra_view_| is a also button, then the |button_height| is the |
| 206 // maximum height of the three buttons, otherwise it is the maximum height | 199 // maximum height of the three buttons, otherwise it is the maximum height |
| 207 // of the ok and cancel buttons. | 200 // of the ok and cancel buttons. |
| 208 const int button_height = | 201 const int button_height = |
| 209 CustomButton::AsCustomButton(extra_view_) ? height : GetButtonHeight(); | 202 CustomButton::AsCustomButton(extra_view_) ? height : GetButtonHeight(); |
| 210 if (kIsOkButtonOnLeftSide) { | 203 if (kIsOkButtonOnLeftSide) { |
| 211 LayoutButton(cancel_button_, &row_bounds, button_height); | 204 LayoutButton(cancel_button_, &row_bounds, button_height); |
| 212 LayoutButton(ok_button_, &row_bounds, button_height); | 205 LayoutButton(ok_button_, &row_bounds, button_height); |
| 213 } else { | 206 } else { |
| 214 LayoutButton(ok_button_, &row_bounds, button_height); | 207 LayoutButton(ok_button_, &row_bounds, button_height); |
| 215 LayoutButton(cancel_button_, &row_bounds, button_height); | 208 LayoutButton(cancel_button_, &row_bounds, button_height); |
| 216 } | 209 } |
| 217 if (extra_view_) { | 210 if (extra_view_) { |
| 218 int custom_padding = 0; | 211 int custom_padding = 0; |
| 219 if (has_dialog_buttons() && | 212 if (has_dialog_buttons() && |
| 220 GetDialogDelegate()->GetExtraViewPadding(&custom_padding)) { | 213 GetDialogDelegate()->GetExtraViewPadding(&custom_padding)) { |
| 221 // The call to LayoutButton() will already have accounted for some of | 214 // The padding between buttons applied in LayoutButton() will already |
| 222 // the padding. | 215 // have accounted for some of the distance here. |
| 223 custom_padding -= GetButtonsAndExtraViewRowTopPadding(); | 216 custom_padding -= ViewsDelegate::GetInstance() |
| 217 ->GetDialogRelatedButtonHorizontalSpacing(); |
| 224 row_bounds.set_width(row_bounds.width() - custom_padding); | 218 row_bounds.set_width(row_bounds.width() - custom_padding); |
| 225 } | 219 } |
| 226 row_bounds.set_width(std::min(row_bounds.width(), | 220 row_bounds.set_width(std::min(row_bounds.width(), |
| 227 extra_view_->GetPreferredSize().width())); | 221 extra_view_->GetPreferredSize().width())); |
| 228 extra_view_->SetBoundsRect(row_bounds); | 222 extra_view_->SetBoundsRect(row_bounds); |
| 229 } | 223 } |
| 230 | 224 |
| 231 if (height > 0) | 225 if (height > 0) { |
| 232 bounds.Inset(0, 0, 0, height + GetButtonsAndExtraViewRowTopPadding()); | 226 // Inset to the top of the buttons, plus their top padding, in order to |
| 227 // exclude that area from the content view's bounds. |
| 228 bounds.Inset(0, 0, 0, height + button_row_insets.top()); |
| 229 } |
| 233 } | 230 } |
| 234 | 231 |
| 235 // Layout the contents view to the top and side edges of the contents bounds. | 232 // Layout the contents view to the top and side edges of the contents bounds. |
| 236 // NOTE: The local insets do not apply to the contents view sides or top. | 233 // NOTE: The local insets do not apply to the contents view sides or top. |
| 237 const gfx::Rect contents_bounds = GetContentsBounds(); | 234 const gfx::Rect contents_bounds = GetContentsBounds(); |
| 238 contents_view()->SetBounds(contents_bounds.x(), contents_bounds.y(), | 235 contents_view()->SetBounds(contents_bounds.x(), contents_bounds.y(), |
| 239 contents_bounds.width(), bounds.bottom() - contents_bounds.y()); | 236 contents_bounds.width(), bounds.bottom() - contents_bounds.y()); |
| 240 } | 237 } |
| 241 | 238 |
| 242 bool DialogClientView::AcceleratorPressed(const ui::Accelerator& accelerator) { | 239 bool DialogClientView::AcceleratorPressed(const ui::Accelerator& accelerator) { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 PlatformStyle::kDialogDefaultButtonCanBeCancel); | 334 PlatformStyle::kDialogDefaultButtonCanBeCancel); |
| 338 | 335 |
| 339 // The default button is always blue in Harmony. | 336 // The default button is always blue in Harmony. |
| 340 if (is_default && (ui::MaterialDesignController::IsSecondaryUiMaterial() || | 337 if (is_default && (ui::MaterialDesignController::IsSecondaryUiMaterial() || |
| 341 GetDialogDelegate()->ShouldDefaultButtonBeBlue())) { | 338 GetDialogDelegate()->ShouldDefaultButtonBeBlue())) { |
| 342 button = MdTextButton::CreateSecondaryUiBlueButton(this, title); | 339 button = MdTextButton::CreateSecondaryUiBlueButton(this, title); |
| 343 } else { | 340 } else { |
| 344 button = MdTextButton::CreateSecondaryUiButton(this, title); | 341 button = MdTextButton::CreateSecondaryUiButton(this, title); |
| 345 } | 342 } |
| 346 | 343 |
| 347 const int kDialogMinButtonWidth = 75; | 344 // TODO(bsep): Setting the minimum size is redundant with MdTextButton, so |
| 348 button->SetMinSize(gfx::Size(kDialogMinButtonWidth, 0)); | 345 // this can be deleted when harmony is always on. |
| 346 const int minimum_width = |
| 347 ViewsDelegate::GetInstance()->GetDialogButtonMinimumWidth(); |
| 348 button->SetMinSize(gfx::Size(minimum_width, 0)); |
| 349 |
| 349 button->SetGroup(kButtonGroup); | 350 button->SetGroup(kButtonGroup); |
| 350 return button; | 351 return button; |
| 351 } | 352 } |
| 352 | 353 |
| 353 int DialogClientView::GetButtonHeight() const { | 354 int DialogClientView::GetButtonHeight() const { |
| 354 return std::max( | 355 return std::max( |
| 355 ok_button_ ? ok_button_->GetPreferredSize().height() : 0, | 356 ok_button_ ? ok_button_->GetPreferredSize().height() : 0, |
| 356 cancel_button_ ? cancel_button_->GetPreferredSize().height() : 0); | 357 cancel_button_ ? cancel_button_->GetPreferredSize().height() : 0); |
| 357 } | 358 } |
| 358 | 359 |
| 359 int DialogClientView::GetExtraViewHeight() const { | 360 int DialogClientView::GetExtraViewHeight() const { |
| 360 return ShouldShow(extra_view_) ? extra_view_->GetPreferredSize().height() : 0; | 361 return ShouldShow(extra_view_) ? extra_view_->GetPreferredSize().height() : 0; |
| 361 } | 362 } |
| 362 | 363 |
| 363 int DialogClientView::GetButtonsAndExtraViewRowHeight() const { | 364 int DialogClientView::GetButtonsAndExtraViewRowHeight() const { |
| 364 return std::max(GetExtraViewHeight(), GetButtonHeight()); | 365 return std::max(GetExtraViewHeight(), GetButtonHeight()); |
| 365 } | 366 } |
| 366 | 367 |
| 367 gfx::Insets DialogClientView::GetButtonRowInsets() const { | 368 gfx::Insets DialogClientView::GetButtonRowInsets() const { |
| 368 return GetButtonsAndExtraViewRowHeight() == 0 ? gfx::Insets() | 369 if (GetButtonsAndExtraViewRowHeight() == 0) |
| 369 : button_row_insets_; | 370 return gfx::Insets(); |
| 370 } | |
| 371 | 371 |
| 372 int DialogClientView::GetButtonsAndExtraViewRowTopPadding() const { | |
| 373 int spacing = button_row_insets_.top(); | |
| 374 // Some subclasses of DialogClientView, in order to do their own layout, set | 372 // Some subclasses of DialogClientView, in order to do their own layout, set |
| 375 // button_row_insets_ to gfx::Insets(). To avoid breaking behavior of those | 373 // button_row_insets_ to gfx::Insets(). To avoid breaking behavior of those |
| 376 // dialogs, supplying 0 for the top inset of the row falls back to | 374 // dialogs, supplying 0 for the top inset of the row falls back to |
| 377 // ViewsDelegate::GetRelatedControlVerticalSpacing or | 375 // ViewsDelegate::GetRelatedControlVerticalSpacing. |
| 378 // kRelatedControlVerticalSpacing. | 376 // TODO(bsep): The top inset should never be 0 when harmony is enabled. |
| 379 if (!spacing) | 377 const int top = button_row_insets_.top() == 0 |
| 380 spacing = ViewsDelegate::GetInstance() | 378 ? ViewsDelegate::GetInstance() |
| 381 ? ViewsDelegate::GetInstance() | 379 ->GetDialogRelatedControlVerticalSpacing() |
| 382 ->GetDialogRelatedControlVerticalSpacing() | 380 : button_row_insets_.top(); |
| 383 : kRelatedControlVerticalSpacing; | 381 return gfx::Insets(top, button_row_insets_.left(), |
| 384 return spacing; | 382 button_row_insets_.bottom(), button_row_insets_.right()); |
| 385 } | 383 } |
| 386 | 384 |
| 387 void DialogClientView::SetupFocusChain() { | 385 void DialogClientView::SetupFocusChain() { |
| 388 // Create a vector of child views in the order of intended focus. | 386 // Create a vector of child views in the order of intended focus. |
| 389 std::vector<View*> child_views; | 387 std::vector<View*> child_views; |
| 390 child_views.push_back(contents_view()); | 388 child_views.push_back(contents_view()); |
| 391 child_views.push_back(extra_view_); | 389 child_views.push_back(extra_view_); |
| 392 if (kIsOkButtonOnLeftSide) { | 390 if (kIsOkButtonOnLeftSide) { |
| 393 child_views.push_back(ok_button_); | 391 child_views.push_back(ok_button_); |
| 394 child_views.push_back(cancel_button_); | 392 child_views.push_back(cancel_button_); |
| 395 } else { | 393 } else { |
| 396 child_views.push_back(cancel_button_); | 394 child_views.push_back(cancel_button_); |
| 397 child_views.push_back(ok_button_); | 395 child_views.push_back(ok_button_); |
| 398 } | 396 } |
| 399 | 397 |
| 400 // Remove all null views from the vector. | 398 // Remove all null views from the vector. |
| 401 child_views.erase( | 399 child_views.erase( |
| 402 std::remove(child_views.begin(), child_views.end(), nullptr), | 400 std::remove(child_views.begin(), child_views.end(), nullptr), |
| 403 child_views.end()); | 401 child_views.end()); |
| 404 | 402 |
| 405 // Setup focus by reordering views. It is not safe to use SetNextFocusableView | 403 // Setup focus by reordering views. It is not safe to use SetNextFocusableView |
| 406 // since child views may be added externally to this view. | 404 // since child views may be added externally to this view. |
| 407 for (size_t i = 0; i < child_views.size(); i++) | 405 for (size_t i = 0; i < child_views.size(); i++) |
| 408 ReorderChildView(child_views[i], i); | 406 ReorderChildView(child_views[i], i); |
| 409 } | 407 } |
| 410 | 408 |
| 411 } // namespace views | 409 } // namespace views |
| OLD | NEW |