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 | 8 |
| 9 #include "ui/base/hit_test.h" | 9 #include "ui/base/hit_test.h" |
| 10 #include "ui/base/resource/resource_bundle.h" | 10 #include "ui/base/resource/resource_bundle.h" |
| 11 #include "ui/gfx/path.h" | 11 #include "ui/gfx/path.h" |
| 12 #include "ui/gfx/screen.h" | 12 #include "ui/gfx/screen.h" |
| 13 #include "ui/gfx/skia_util.h" | 13 #include "ui/gfx/skia_util.h" |
| 14 #include "ui/native_theme/native_theme.h" | 14 #include "ui/native_theme/native_theme.h" |
| 15 #include "ui/resources/grit/ui_resources.h" | 15 #include "ui/resources/grit/ui_resources.h" |
| 16 #include "ui/views/bubble/bubble_border.h" | 16 #include "ui/views/bubble/bubble_border.h" |
| 17 #include "ui/views/controls/button/label_button.h" | 17 #include "ui/views/controls/button/label_button.h" |
| 18 #include "ui/views/controls/image_view.h" | |
| 18 #include "ui/views/widget/widget.h" | 19 #include "ui/views/widget/widget.h" |
| 19 #include "ui/views/widget/widget_delegate.h" | 20 #include "ui/views/widget/widget_delegate.h" |
| 20 #include "ui/views/window/client_view.h" | 21 #include "ui/views/window/client_view.h" |
| 21 | 22 |
| 22 namespace { | 23 namespace { |
| 23 | 24 |
| 24 // Insets for the title bar views in pixels. | 25 // Insets for the title bar views in pixels. |
| 25 const int kTitleTopInset = 12; | 26 const int kTitleTopInset = 12; |
| 26 const int kTitleLeftInset = 19; | 27 const int kTitleLeftInset = 19; |
| 27 const int kTitleBottomInset = 12; | 28 const int kTitleBottomInset = 12; |
| 28 const int kTitleRightInset = 7; | 29 const int kTitleRightInset = 7; |
| 29 | 30 |
| 31 // The horizontal padding between the title and the icon. | |
| 32 const int kTitleHorizontalPadding = 5; | |
| 33 | |
| 30 // Get the |vertical| or horizontal amount that |available_bounds| overflows | 34 // Get the |vertical| or horizontal amount that |available_bounds| overflows |
| 31 // |window_bounds|. | 35 // |window_bounds|. |
| 32 int GetOffScreenLength(const gfx::Rect& available_bounds, | 36 int GetOffScreenLength(const gfx::Rect& available_bounds, |
| 33 const gfx::Rect& window_bounds, | 37 const gfx::Rect& window_bounds, |
| 34 bool vertical) { | 38 bool vertical) { |
| 35 if (available_bounds.IsEmpty() || available_bounds.Contains(window_bounds)) | 39 if (available_bounds.IsEmpty() || available_bounds.Contains(window_bounds)) |
| 36 return 0; | 40 return 0; |
| 37 | 41 |
| 38 // window_bounds | 42 // window_bounds |
| 39 // +---------------------------------+ | 43 // +---------------------------------+ |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 51 } | 55 } |
| 52 | 56 |
| 53 } // namespace | 57 } // namespace |
| 54 | 58 |
| 55 namespace views { | 59 namespace views { |
| 56 | 60 |
| 57 // static | 61 // static |
| 58 const char BubbleFrameView::kViewClassName[] = "BubbleFrameView"; | 62 const char BubbleFrameView::kViewClassName[] = "BubbleFrameView"; |
| 59 | 63 |
| 60 BubbleFrameView::BubbleFrameView(const gfx::Insets& content_margins) | 64 BubbleFrameView::BubbleFrameView(const gfx::Insets& content_margins) |
| 61 : bubble_border_(NULL), | 65 : bubble_border_(nullptr), |
| 62 content_margins_(content_margins), | 66 content_margins_(content_margins), |
| 63 title_(NULL), | 67 title_icon_(new views::ImageView()), |
| 64 close_(NULL), | 68 title_(nullptr), |
| 65 titlebar_extra_view_(NULL) { | 69 close_(nullptr), |
| 70 titlebar_extra_view_(nullptr) { | |
| 71 AddChildView(title_icon_); | |
| 72 | |
| 66 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 73 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 67 title_ = new Label(base::string16(), | 74 title_ = new Label(base::string16(), |
| 68 rb.GetFontList(ui::ResourceBundle::MediumFont)); | 75 rb.GetFontList(ui::ResourceBundle::MediumFont)); |
| 69 title_->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 76 title_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 77 title_->set_collapse_when_hidden(true); | |
| 78 title_->SetVisible(false); | |
| 70 AddChildView(title_); | 79 AddChildView(title_); |
| 71 | 80 |
| 72 close_ = CreateCloseButton(this); | 81 close_ = CreateCloseButton(this); |
| 73 close_->SetVisible(false); | 82 close_->SetVisible(false); |
| 74 AddChildView(close_); | 83 AddChildView(close_); |
| 75 } | 84 } |
| 76 | 85 |
| 77 BubbleFrameView::~BubbleFrameView() {} | 86 BubbleFrameView::~BubbleFrameView() {} |
| 78 | 87 |
| 79 // static | 88 // static |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 154 static const int kBottomBorderShadowSize = 2; | 163 static const int kBottomBorderShadowSize = 2; |
| 155 rect.fBottom += SkIntToScalar(kBottomBorderShadowSize); | 164 rect.fBottom += SkIntToScalar(kBottomBorderShadowSize); |
| 156 window_mask->addRect(rect); | 165 window_mask->addRect(rect); |
| 157 } | 166 } |
| 158 } | 167 } |
| 159 | 168 |
| 160 void BubbleFrameView::ResetWindowControls() { | 169 void BubbleFrameView::ResetWindowControls() { |
| 161 close_->SetVisible(GetWidget()->widget_delegate()->ShouldShowCloseButton()); | 170 close_->SetVisible(GetWidget()->widget_delegate()->ShouldShowCloseButton()); |
| 162 } | 171 } |
| 163 | 172 |
| 164 void BubbleFrameView::UpdateWindowIcon() {} | 173 void BubbleFrameView::UpdateWindowIcon() { |
| 174 gfx::ImageSkia image; | |
| 175 if (GetWidget()->widget_delegate()->ShouldShowWindowIcon()) | |
| 176 image = GetWidget()->widget_delegate()->GetWindowIcon(); | |
| 177 title_icon_->SetImage(&image); | |
| 178 } | |
| 179 | |
| 165 | 180 |
| 166 void BubbleFrameView::UpdateWindowTitle() { | 181 void BubbleFrameView::UpdateWindowTitle() { |
| 167 title_->SetText(GetWidget()->widget_delegate()->ShouldShowWindowTitle() ? | 182 title_->SetText(GetWidget()->widget_delegate()->GetWindowTitle()); |
| 168 GetWidget()->widget_delegate()->GetWindowTitle() : base::string16()); | 183 title_->SetVisible(GetWidget()->widget_delegate()->ShouldShowWindowTitle()); |
| 169 // Update the close button visibility too, otherwise it's not intialized. | 184 // Update close button visibility too, otherwise they are not intialized. |
|
msw
2015/02/20 20:03:44
nit: "they are" is incorrect, leave this as "it's"
xiaoling
2015/02/20 20:23:18
I changed some code and then reverted. But didn't
| |
| 170 ResetWindowControls(); | 185 ResetWindowControls(); |
|
msw
2015/02/20 20:03:44
I added this line as a workaround for a bug that w
xiaoling
2015/02/20 20:23:18
Done.
| |
| 171 } | 186 } |
| 172 | 187 |
| 173 void BubbleFrameView::SizeConstraintsChanged() {} | 188 void BubbleFrameView::SizeConstraintsChanged() {} |
| 174 | 189 |
| 175 void BubbleFrameView::SetTitleFontList(const gfx::FontList& font_list) { | 190 void BubbleFrameView::SetTitleFontList(const gfx::FontList& font_list) { |
| 176 title_->SetFontList(font_list); | 191 title_->SetFontList(font_list); |
| 177 } | 192 } |
| 178 | 193 |
| 179 gfx::Insets BubbleFrameView::GetInsets() const { | 194 gfx::Insets BubbleFrameView::GetInsets() const { |
| 180 gfx::Insets insets = content_margins_; | 195 gfx::Insets insets = content_margins_; |
| 181 const int title_height = title_->text().empty() ? 0 : | 196 |
| 182 title_->GetPreferredSize().height() + kTitleTopInset + kTitleBottomInset; | 197 const int icon_height = title_icon_->GetPreferredSize().height(); |
| 198 const int label_height = title_->GetPreferredSize().height(); | |
| 199 const bool has_title = icon_height > 0 || label_height > 0; | |
| 200 const int title_padding = has_title ? kTitleTopInset + kTitleBottomInset : 0; | |
| 201 const int title_height = std::max(icon_height, label_height) + title_padding; | |
| 183 const int close_height = close_->visible() ? close_->height() : 0; | 202 const int close_height = close_->visible() ? close_->height() : 0; |
| 184 insets += gfx::Insets(std::max(title_height, close_height), 0, 0, 0); | 203 insets += gfx::Insets(std::max(title_height, close_height), 0, 0, 0); |
| 185 return insets; | 204 return insets; |
| 186 } | 205 } |
| 187 | 206 |
| 188 gfx::Size BubbleFrameView::GetPreferredSize() const { | 207 gfx::Size BubbleFrameView::GetPreferredSize() const { |
| 189 return GetSizeForClientSize(GetWidget()->client_view()->GetPreferredSize()); | 208 return GetSizeForClientSize(GetWidget()->client_view()->GetPreferredSize()); |
| 190 } | 209 } |
| 191 | 210 |
| 192 gfx::Size BubbleFrameView::GetMinimumSize() const { | 211 gfx::Size BubbleFrameView::GetMinimumSize() const { |
| 193 return GetSizeForClientSize(GetWidget()->client_view()->GetMinimumSize()); | 212 return GetSizeForClientSize(GetWidget()->client_view()->GetMinimumSize()); |
| 194 } | 213 } |
| 195 | 214 |
| 196 void BubbleFrameView::Layout() { | 215 void BubbleFrameView::Layout() { |
| 197 gfx::Rect bounds(GetContentsBounds()); | 216 gfx::Rect bounds(GetContentsBounds()); |
| 198 bounds.Inset(GetTitleInsets()); | 217 bounds.Inset(GetTitleInsets()); |
| 199 if (bounds.IsEmpty()) | 218 if (bounds.IsEmpty()) |
| 200 return; | 219 return; |
| 201 | 220 |
| 202 // The close button top inset is actually smaller than the title top inset. | 221 // The close button top inset is actually smaller than the title top inset. |
| 203 close_->SetPosition(gfx::Point(bounds.right() - close_->width(), | 222 close_->SetPosition(gfx::Point(bounds.right() - close_->width(), |
| 204 bounds.y() - 5)); | 223 bounds.y() - 5)); |
| 205 | 224 |
| 206 gfx::Size title_size(title_->GetPreferredSize()); | 225 gfx::Size title_icon_size(title_icon_->GetPreferredSize()); |
| 207 const int title_width = std::max(0, close_->x() - bounds.x()); | 226 gfx::Size title_label_size(title_->GetPreferredSize()); |
| 208 title_size.SetToMin(gfx::Size(title_width, title_size.height())); | 227 int padding = 0; |
| 209 bounds.set_size(title_size); | 228 if (title_icon_size.width() > 0 && title_label_size.width() > 0) |
| 210 title_->SetBoundsRect(bounds); | 229 padding = kTitleHorizontalPadding; |
| 230 const int title_height = std::max(title_icon_size.height(), | |
| 231 title_label_size.height()); | |
| 232 | |
| 233 const int title_icon_width = std::max(0, close_->x() - bounds.x()); | |
| 234 title_icon_size.SetToMin(gfx::Size(title_icon_width, title_height)); | |
| 235 gfx::Rect title_icon_bounds( | |
| 236 bounds.x(), bounds.y(), title_icon_size.width(), title_height); | |
| 237 title_icon_->SetBoundsRect(title_icon_bounds); | |
| 238 | |
| 239 const int title_label_x = title_icon_->bounds().right() + padding; | |
| 240 const int title_label_width = std::max(0, close_->x() - title_label_x); | |
| 241 title_label_size.SetToMin(gfx::Size(title_label_width, | |
| 242 title_label_size.height())); | |
| 243 gfx::Rect title_label_bounds( | |
| 244 title_label_x, bounds.y(), title_label_size.width(), title_height); | |
| 245 title_->SetBoundsRect(title_label_bounds); | |
| 246 | |
| 247 bounds.set_width( | |
| 248 title_icon_size.width() + title_label_size.width() + padding); | |
| 249 bounds.set_height(title_height); | |
| 211 | 250 |
| 212 if (titlebar_extra_view_) { | 251 if (titlebar_extra_view_) { |
| 213 const int extra_width = close_->x() - title_->bounds().right(); | 252 const int extra_width = close_->x() - title_->bounds().right(); |
|
msw
2015/02/20 20:03:44
Change this to handle the case with an icon but no
xiaoling
2015/02/20 20:23:19
Done.
| |
| 214 gfx::Size size = titlebar_extra_view_->GetPreferredSize(); | 253 gfx::Size size = titlebar_extra_view_->GetPreferredSize(); |
| 215 size.SetToMin(gfx::Size(std::max(0, extra_width), size.height())); | 254 size.SetToMin(gfx::Size(std::max(0, extra_width), size.height())); |
| 216 gfx::Rect titlebar_extra_view_bounds( | 255 gfx::Rect titlebar_extra_view_bounds( |
| 217 close_->x() - size.width(), | 256 close_->x() - size.width(), |
| 218 bounds.y(), | 257 bounds.y(), |
| 219 size.width(), | 258 size.width(), |
| 220 bounds.height()); | 259 bounds.height()); |
| 221 titlebar_extra_view_bounds.Subtract(bounds); | 260 titlebar_extra_view_bounds.Subtract(bounds); |
| 222 titlebar_extra_view_->SetBoundsRect(titlebar_extra_view_bounds); | 261 titlebar_extra_view_->SetBoundsRect(titlebar_extra_view_bounds); |
| 223 } | 262 } |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 bubble_border_->set_arrow_offset( | 403 bubble_border_->set_arrow_offset( |
| 365 bubble_border_->GetArrowOffset(window_bounds.size()) - offscreen_adjust); | 404 bubble_border_->GetArrowOffset(window_bounds.size()) - offscreen_adjust); |
| 366 if (offscreen_adjust) | 405 if (offscreen_adjust) |
| 367 SchedulePaint(); | 406 SchedulePaint(); |
| 368 } | 407 } |
| 369 | 408 |
| 370 gfx::Size BubbleFrameView::GetSizeForClientSize( | 409 gfx::Size BubbleFrameView::GetSizeForClientSize( |
| 371 const gfx::Size& client_size) const { | 410 const gfx::Size& client_size) const { |
| 372 // Accommodate the width of the title bar elements. | 411 // Accommodate the width of the title bar elements. |
| 373 int title_bar_width = GetInsets().width() + border()->GetInsets().width(); | 412 int title_bar_width = GetInsets().width() + border()->GetInsets().width(); |
| 374 if (!title_->text().empty()) | 413 gfx::Size title_icon_size = title_icon_->GetPreferredSize(); |
| 375 title_bar_width += kTitleLeftInset + title_->GetPreferredSize().width(); | 414 gfx::Size title_label_size = title_->GetPreferredSize(); |
| 415 if (title_icon_size.width() > 0 || title_label_size.width() > 0) | |
| 416 title_bar_width += kTitleLeftInset; | |
| 417 if (title_icon_size.width() > 0 && title_label_size.width() > 0) | |
| 418 title_bar_width += kTitleHorizontalPadding; | |
| 419 title_bar_width += title_icon_size.width(); | |
| 420 title_bar_width += title_label_size.width(); | |
| 376 if (close_->visible()) | 421 if (close_->visible()) |
| 377 title_bar_width += close_->width() + 1; | 422 title_bar_width += close_->width() + 1; |
| 378 if (titlebar_extra_view_ != NULL) | 423 if (titlebar_extra_view_ != NULL) |
| 379 title_bar_width += titlebar_extra_view_->GetPreferredSize().width(); | 424 title_bar_width += titlebar_extra_view_->GetPreferredSize().width(); |
| 380 gfx::Size size(client_size); | 425 gfx::Size size(client_size); |
| 381 size.SetToMax(gfx::Size(title_bar_width, 0)); | 426 size.SetToMax(gfx::Size(title_bar_width, 0)); |
| 382 const gfx::Insets insets(GetInsets()); | 427 const gfx::Insets insets(GetInsets()); |
| 383 size.Enlarge(insets.width(), insets.height()); | 428 size.Enlarge(insets.width(), insets.height()); |
| 384 return size; | 429 return size; |
| 385 } | 430 } |
| 386 | 431 |
| 387 } // namespace views | 432 } // namespace views |
| OLD | NEW |