Chromium Code Reviews| 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/bubble/bubble_frame_view.h" | 5 #include "ui/views/bubble/bubble_frame_view.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 #include "ui/gfx/skia_util.h" | 22 #include "ui/gfx/skia_util.h" |
| 23 #include "ui/native_theme/native_theme.h" | 23 #include "ui/native_theme/native_theme.h" |
| 24 #include "ui/resources/grit/ui_resources.h" | 24 #include "ui/resources/grit/ui_resources.h" |
| 25 #include "ui/strings/grit/ui_strings.h" | 25 #include "ui/strings/grit/ui_strings.h" |
| 26 #include "ui/vector_icons/vector_icons.h" | 26 #include "ui/vector_icons/vector_icons.h" |
| 27 #include "ui/views/bubble/bubble_border.h" | 27 #include "ui/views/bubble/bubble_border.h" |
| 28 #include "ui/views/controls/button/image_button.h" | 28 #include "ui/views/controls/button/image_button.h" |
| 29 #include "ui/views/controls/button/image_button_factory.h" | 29 #include "ui/views/controls/button/image_button_factory.h" |
| 30 #include "ui/views/controls/image_view.h" | 30 #include "ui/views/controls/image_view.h" |
| 31 #include "ui/views/controls/label.h" | 31 #include "ui/views/controls/label.h" |
| 32 #include "ui/views/controls/styled_label.h" | |
| 32 #include "ui/views/layout/box_layout.h" | 33 #include "ui/views/layout/box_layout.h" |
| 33 #include "ui/views/layout/layout_provider.h" | 34 #include "ui/views/layout/layout_provider.h" |
| 34 #include "ui/views/resources/grit/views_resources.h" | 35 #include "ui/views/resources/grit/views_resources.h" |
| 35 #include "ui/views/widget/widget.h" | 36 #include "ui/views/widget/widget.h" |
| 36 #include "ui/views/widget/widget_delegate.h" | 37 #include "ui/views/widget/widget_delegate.h" |
| 37 #include "ui/views/window/client_view.h" | 38 #include "ui/views/window/client_view.h" |
| 38 #include "ui/views/window/dialog_delegate.h" | 39 #include "ui/views/window/dialog_delegate.h" |
| 39 | 40 |
| 40 namespace views { | 41 namespace views { |
| 41 | 42 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 73 } // namespace | 74 } // namespace |
| 74 | 75 |
| 75 // static | 76 // static |
| 76 const char BubbleFrameView::kViewClassName[] = "BubbleFrameView"; | 77 const char BubbleFrameView::kViewClassName[] = "BubbleFrameView"; |
| 77 | 78 |
| 78 BubbleFrameView::BubbleFrameView(const gfx::Insets& title_margins, | 79 BubbleFrameView::BubbleFrameView(const gfx::Insets& title_margins, |
| 79 const gfx::Insets& content_margins) | 80 const gfx::Insets& content_margins) |
| 80 : bubble_border_(nullptr), | 81 : bubble_border_(nullptr), |
| 81 title_margins_(title_margins), | 82 title_margins_(title_margins), |
| 82 content_margins_(content_margins), | 83 content_margins_(content_margins), |
| 84 title_font_list_(views::style::GetFont(style::CONTEXT_DIALOG_TITLE, | |
| 85 views::style::STYLE_PRIMARY)), | |
| 83 title_icon_(new views::ImageView()), | 86 title_icon_(new views::ImageView()), |
| 84 title_(nullptr), | 87 title_(nullptr), |
| 85 close_(nullptr), | 88 close_(nullptr), |
| 86 footnote_container_(nullptr), | 89 footnote_container_(nullptr), |
| 87 close_button_clicked_(false) { | 90 close_button_clicked_(false) { |
| 88 AddChildView(title_icon_); | 91 AddChildView(title_icon_); |
| 89 | 92 |
| 90 title_ = new Label(base::string16(), style::CONTEXT_DIALOG_TITLE); | |
| 91 title_->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
| 92 title_->set_collapse_when_hidden(true); | |
| 93 title_->SetVisible(false); | |
| 94 title_->SetMultiLine(true); | |
| 95 AddChildView(title_); | |
| 96 | |
| 97 close_ = CreateCloseButton(this); | 93 close_ = CreateCloseButton(this); |
| 98 close_->SetVisible(false); | 94 close_->SetVisible(false); |
| 99 #if defined(OS_WIN) | 95 #if defined(OS_WIN) |
| 100 // Windows will automatically create a tooltip for the close button based on | 96 // Windows will automatically create a tooltip for the close button based on |
| 101 // the HTCLOSE result from NonClientHitTest(). | 97 // the HTCLOSE result from NonClientHitTest(). |
| 102 close_->SetTooltipText(base::string16()); | 98 close_->SetTooltipText(base::string16()); |
| 103 #endif | 99 #endif |
| 104 AddChildView(close_); | 100 AddChildView(close_); |
| 105 } | 101 } |
| 106 | 102 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 167 | 163 |
| 168 // Allow dialogs to show the system menu and be dragged. | 164 // Allow dialogs to show the system menu and be dragged. |
| 169 if (GetWidget()->widget_delegate()->AsDialogDelegate() && | 165 if (GetWidget()->widget_delegate()->AsDialogDelegate() && |
| 170 !GetWidget()->widget_delegate()->AsBubbleDialogDelegate()) { | 166 !GetWidget()->widget_delegate()->AsBubbleDialogDelegate()) { |
| 171 gfx::Rect bounds(GetContentsBounds()); | 167 gfx::Rect bounds(GetContentsBounds()); |
| 172 bounds.Inset(title_margins_); | 168 bounds.Inset(title_margins_); |
| 173 gfx::Rect sys_rect(0, 0, bounds.x(), bounds.y()); | 169 gfx::Rect sys_rect(0, 0, bounds.x(), bounds.y()); |
| 174 sys_rect.set_origin(gfx::Point(GetMirroredXForRect(sys_rect), 0)); | 170 sys_rect.set_origin(gfx::Point(GetMirroredXForRect(sys_rect), 0)); |
| 175 if (sys_rect.Contains(point)) | 171 if (sys_rect.Contains(point)) |
| 176 return HTSYSMENU; | 172 return HTSYSMENU; |
| 177 if (point.y() < title_->bounds().bottom()) | 173 if (title_ && point.y() < title_->bounds().bottom()) |
| 178 return HTCAPTION; | 174 return HTCAPTION; |
| 179 } | 175 } |
| 180 | 176 |
| 181 return GetWidget()->client_view()->NonClientHitTest(point); | 177 return GetWidget()->client_view()->NonClientHitTest(point); |
| 182 } | 178 } |
| 183 | 179 |
| 184 void BubbleFrameView::GetWindowMask(const gfx::Size& size, | 180 void BubbleFrameView::GetWindowMask(const gfx::Size& size, |
| 185 gfx::Path* window_mask) { | 181 gfx::Path* window_mask) { |
| 186 if (bubble_border_->shadow() != BubbleBorder::SMALL_SHADOW && | 182 if (bubble_border_->shadow() != BubbleBorder::SMALL_SHADOW && |
| 187 bubble_border_->shadow() != BubbleBorder::NO_SHADOW_OPAQUE_BORDER && | 183 bubble_border_->shadow() != BubbleBorder::NO_SHADOW_OPAQUE_BORDER && |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 226 } | 222 } |
| 227 | 223 |
| 228 void BubbleFrameView::UpdateWindowIcon() { | 224 void BubbleFrameView::UpdateWindowIcon() { |
| 229 gfx::ImageSkia image; | 225 gfx::ImageSkia image; |
| 230 if (GetWidget()->widget_delegate()->ShouldShowWindowIcon()) | 226 if (GetWidget()->widget_delegate()->ShouldShowWindowIcon()) |
| 231 image = GetWidget()->widget_delegate()->GetWindowIcon(); | 227 image = GetWidget()->widget_delegate()->GetWindowIcon(); |
| 232 title_icon_->SetImage(&image); | 228 title_icon_->SetImage(&image); |
| 233 } | 229 } |
| 234 | 230 |
| 235 void BubbleFrameView::UpdateWindowTitle() { | 231 void BubbleFrameView::UpdateWindowTitle() { |
| 236 title_->SetText(GetWidget()->widget_delegate()->GetWindowTitle()); | 232 if (title_) { |
| 237 title_->SetVisible(GetWidget()->widget_delegate()->ShouldShowWindowTitle()); | 233 RemoveChildView(title_); |
| 234 delete title_; | |
| 235 title_ = nullptr; | |
| 236 } | |
| 237 if (!GetWidget()->widget_delegate()->ShouldShowWindowTitle()) | |
| 238 return; | |
|
Peter Kasting
2017/06/07 02:40:43
Why decide not to add the title at all, rather tha
Bret
2017/06/07 20:15:41
The decision as to whether to use CreateTitleView
| |
| 239 | |
| 240 DialogDelegate* delegate = GetWidget()->widget_delegate()->AsDialogDelegate(); | |
| 241 if (delegate) | |
| 242 title_ = delegate->CreateTitleView(); | |
| 243 if (!title_) { | |
| 244 // No title from delegate, so use default. | |
| 245 title_ = new StyledLabel(GetWidget()->widget_delegate()->GetWindowTitle(), | |
| 246 nullptr); | |
| 247 } | |
| 248 title_->SetBaseFontList(title_font_list_); | |
| 249 title_->SetVisible(true); | |
| 250 AddChildView(title_); | |
| 238 } | 251 } |
| 239 | 252 |
| 240 void BubbleFrameView::SizeConstraintsChanged() {} | 253 void BubbleFrameView::SizeConstraintsChanged() {} |
| 241 | 254 |
| 242 void BubbleFrameView::SetTitleFontList(const gfx::FontList& font_list) { | 255 void BubbleFrameView::SetTitleFontList(const gfx::FontList& font_list) { |
| 243 title_->SetFontList(font_list); | 256 title_font_list_ = font_list; |
| 257 if (title_) | |
| 258 title_->SetBaseFontList(title_font_list_); | |
| 244 } | 259 } |
| 245 | 260 |
| 246 const char* BubbleFrameView::GetClassName() const { | 261 const char* BubbleFrameView::GetClassName() const { |
| 247 return kViewClassName; | 262 return kViewClassName; |
| 248 } | 263 } |
| 249 | 264 |
| 250 gfx::Insets BubbleFrameView::GetInsets() const { | 265 gfx::Insets BubbleFrameView::GetInsets() const { |
| 251 gfx::Insets insets = content_margins_; | 266 gfx::Insets insets = content_margins_; |
| 252 | 267 |
| 253 const int icon_height = title_icon_->GetPreferredSize().height(); | 268 const int icon_height = title_icon_->GetPreferredSize().height(); |
| 254 const int label_height = title_->GetPreferredSize().height(); | 269 const int label_height = title_ ? title_->GetPreferredSize().height() : 0; |
| 255 const bool has_title = icon_height > 0 || label_height > 0; | 270 const bool has_title = icon_height > 0 || label_height > 0; |
| 256 const int title_padding = has_title ? title_margins_.height() : 0; | 271 const int title_padding = has_title ? title_margins_.height() : 0; |
| 257 const int title_height = std::max(icon_height, label_height) + title_padding; | 272 const int title_height = std::max(icon_height, label_height) + title_padding; |
| 258 const int close_height = | 273 const int close_height = |
| 259 GetWidget()->widget_delegate()->ShouldShowCloseButton() | 274 GetWidget()->widget_delegate()->ShouldShowCloseButton() |
| 260 ? close_->height() + LayoutProvider::Get()->GetDistanceMetric( | 275 ? close_->height() + LayoutProvider::Get()->GetDistanceMetric( |
| 261 DISTANCE_CLOSE_BUTTON_MARGIN) | 276 DISTANCE_CLOSE_BUTTON_MARGIN) |
| 262 : 0; | 277 : 0; |
| 263 insets += gfx::Insets(std::max(title_height, close_height), 0, 0, 0); | 278 insets += gfx::Insets(std::max(title_height, close_height), 0, 0, 0); |
| 264 return insets; | 279 return insets; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 297 #endif // OS_MACOSX | 312 #endif // OS_MACOSX |
| 298 // Non-dialog bubbles should be non-resizable, so its max size is its | 313 // Non-dialog bubbles should be non-resizable, so its max size is its |
| 299 // preferred size. | 314 // preferred size. |
| 300 return GetPreferredSize(); | 315 return GetPreferredSize(); |
| 301 #endif | 316 #endif |
| 302 } | 317 } |
| 303 | 318 |
| 304 void BubbleFrameView::Layout() { | 319 void BubbleFrameView::Layout() { |
| 305 // The title margins may not be set, but make sure that's only the case when | 320 // The title margins may not be set, but make sure that's only the case when |
| 306 // there's no title. | 321 // there's no title. |
| 307 DCHECK(!title_margins_.IsEmpty() || !title_->visible()); | 322 DCHECK(!title_margins_.IsEmpty() || !title_); |
| 308 | 323 |
| 309 const gfx::Rect contents_bounds = GetContentsBounds(); | 324 const gfx::Rect contents_bounds = GetContentsBounds(); |
| 310 gfx::Rect bounds = contents_bounds; | 325 gfx::Rect bounds = contents_bounds; |
| 311 bounds.Inset(title_margins_); | 326 bounds.Inset(title_margins_); |
| 312 if (bounds.IsEmpty()) | 327 if (bounds.IsEmpty()) |
| 313 return; | 328 return; |
| 314 | 329 |
| 315 // The close button is positioned somewhat closer to the edge of the bubble. | 330 // The close button is positioned somewhat closer to the edge of the bubble. |
| 316 const int close_margin = | 331 const int close_margin = |
| 317 LayoutProvider::Get()->GetDistanceMetric(DISTANCE_CLOSE_BUTTON_MARGIN); | 332 LayoutProvider::Get()->GetDistanceMetric(DISTANCE_CLOSE_BUTTON_MARGIN); |
| 318 close_->SetPosition( | 333 close_->SetPosition( |
| 319 gfx::Point(contents_bounds.right() - close_margin - close_->width(), | 334 gfx::Point(contents_bounds.right() - close_margin - close_->width(), |
| 320 contents_bounds.y() + close_margin)); | 335 contents_bounds.y() + close_margin)); |
| 321 | 336 |
| 322 gfx::Size title_icon_pref_size(title_icon_->GetPreferredSize()); | 337 gfx::Size title_icon_pref_size(title_icon_->GetPreferredSize()); |
| 323 int padding = 0; | 338 int padding = 0; |
| 324 int title_height = title_icon_pref_size.height(); | 339 int title_height = title_icon_pref_size.height(); |
| 325 | 340 |
| 326 if (title_->visible() && !title_->text().empty()) { | 341 if (title_ && !title_->text().empty()) { |
| 327 if (title_icon_pref_size.width() > 0) | 342 if (title_icon_pref_size.width() > 0) |
| 328 padding = title_margins_.left(); | 343 padding = title_margins_.left(); |
| 329 | 344 |
| 330 const int title_label_x = | 345 const int title_label_x = |
| 331 bounds.x() + title_icon_pref_size.width() + padding; | 346 bounds.x() + title_icon_pref_size.width() + padding; |
| 332 title_->SizeToFit(std::max(1, close_->x() - title_label_x)); | 347 title_->SizeToFit(std::max(1, close_->x() - title_label_x)); |
| 333 title_height = std::max(title_height, title_->height()); | 348 title_height = std::max(title_height, title_->height()); |
| 334 title_->SetPosition(gfx::Point( | 349 title_->SetPosition(gfx::Point( |
| 335 title_label_x, bounds.y() + (title_height - title_->height()) / 2)); | 350 title_label_x, bounds.y() + (title_height - title_->height()) / 2)); |
| 336 } | 351 } |
| 337 | 352 |
| 338 title_icon_->SetBounds(bounds.x(), bounds.y(), title_icon_pref_size.width(), | 353 title_icon_->SetBounds(bounds.x(), bounds.y(), title_icon_pref_size.width(), |
| 339 title_height); | 354 title_height); |
| 340 bounds.set_width(title_->bounds().right() - bounds.x()); | 355 const int title_right = title_ ? title_->bounds().right() : 0; |
| 356 bounds.set_width(title_right - bounds.x()); | |
| 341 bounds.set_height(title_height); | 357 bounds.set_height(title_height); |
| 342 | 358 |
| 343 if (footnote_container_) { | 359 if (footnote_container_) { |
| 344 const int width = contents_bounds.width(); | 360 const int width = contents_bounds.width(); |
| 345 const int height = footnote_container_->GetHeightForWidth(width); | 361 const int height = footnote_container_->GetHeightForWidth(width); |
| 346 footnote_container_->SetBounds( | 362 footnote_container_->SetBounds( |
| 347 contents_bounds.x(), contents_bounds.bottom() - height, width, height); | 363 contents_bounds.x(), contents_bounds.bottom() - height, width, height); |
| 348 } | 364 } |
| 349 } | 365 } |
| 350 | 366 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 522 bubble_border_->GetArrowOffset(window_bounds.size()) - offscreen_adjust); | 538 bubble_border_->GetArrowOffset(window_bounds.size()) - offscreen_adjust); |
| 523 if (offscreen_adjust) | 539 if (offscreen_adjust) |
| 524 SchedulePaint(); | 540 SchedulePaint(); |
| 525 } | 541 } |
| 526 | 542 |
| 527 gfx::Size BubbleFrameView::GetSizeForClientSize( | 543 gfx::Size BubbleFrameView::GetSizeForClientSize( |
| 528 const gfx::Size& client_size) const { | 544 const gfx::Size& client_size) const { |
| 529 // Accommodate the width of the title bar elements. | 545 // Accommodate the width of the title bar elements. |
| 530 int title_bar_width = title_margins_.width() + border()->GetInsets().width(); | 546 int title_bar_width = title_margins_.width() + border()->GetInsets().width(); |
| 531 gfx::Size title_icon_size = title_icon_->GetPreferredSize(); | 547 gfx::Size title_icon_size = title_icon_->GetPreferredSize(); |
| 532 gfx::Size title_label_size = title_->GetPreferredSize(); | 548 gfx::Size title_label_size = |
| 549 title_ ? title_->GetPreferredSize() : gfx::Size(); | |
| 533 if (title_icon_size.width() > 0 && title_label_size.width() > 0) | 550 if (title_icon_size.width() > 0 && title_label_size.width() > 0) |
| 534 title_bar_width += title_margins_.left(); | 551 title_bar_width += title_margins_.left(); |
| 535 title_bar_width += title_icon_size.width(); | 552 title_bar_width += title_icon_size.width(); |
| 536 if (close_->visible()) | 553 if (close_->visible()) |
| 537 title_bar_width += close_->width() + 1; | 554 title_bar_width += close_->width() + 1; |
| 538 | 555 |
| 539 gfx::Size size(client_size); | 556 gfx::Size size(client_size); |
| 540 gfx::Insets client_insets = GetInsets(); | 557 gfx::Insets client_insets = GetInsets(); |
| 541 size.Enlarge(client_insets.width(), client_insets.height()); | 558 size.Enlarge(client_insets.width(), client_insets.height()); |
| 542 size.SetToMax(gfx::Size(title_bar_width, 0)); | 559 size.SetToMax(gfx::Size(title_bar_width, 0)); |
| 543 | 560 |
| 544 if (footnote_container_) | 561 if (footnote_container_) |
| 545 size.Enlarge(0, footnote_container_->GetHeightForWidth(size.width())); | 562 size.Enlarge(0, footnote_container_->GetHeightForWidth(size.width())); |
| 546 | 563 |
| 547 DialogDelegate* dialog_delegate = | 564 DialogDelegate* dialog_delegate = |
| 548 GetWidget()->widget_delegate()->AsDialogDelegate(); | 565 GetWidget()->widget_delegate()->AsDialogDelegate(); |
| 549 if (dialog_delegate && dialog_delegate->ShouldSnapFrameWidth()) | 566 if (dialog_delegate && dialog_delegate->ShouldSnapFrameWidth()) |
| 550 size.set_width(LayoutProvider::Get()->GetSnappedDialogWidth(size.width())); | 567 size.set_width(LayoutProvider::Get()->GetSnappedDialogWidth(size.width())); |
| 551 | 568 |
| 552 return size; | 569 return size; |
| 553 } | 570 } |
| 554 | 571 |
| 555 } // namespace views | 572 } // namespace views |
| OLD | NEW |