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_(NULL), |
|
msw
2015/02/19 23:56:14
nit: please update these to nullptr.
xiaoling
2015/02/20 19:43:21
Done.
| |
| 62 content_margins_(content_margins), | 66 content_margins_(content_margins), |
| 67 title_icon_(NULL), | |
| 63 title_(NULL), | 68 title_(NULL), |
| 64 close_(NULL), | 69 close_(NULL), |
| 65 titlebar_extra_view_(NULL) { | 70 titlebar_extra_view_(NULL) { |
| 66 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 71 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 72 title_icon_ = new views::ImageView(); | |
|
msw
2015/02/19 23:56:14
nit: inline this in the initializer list.
xiaoling
2015/02/20 19:43:21
Done.
| |
| 73 AddChildView(title_icon_); | |
| 74 | |
| 67 title_ = new Label(base::string16(), | 75 title_ = new Label(base::string16(), |
| 68 rb.GetFontList(ui::ResourceBundle::MediumFont)); | 76 rb.GetFontList(ui::ResourceBundle::MediumFont)); |
| 69 title_->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 77 title_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 70 AddChildView(title_); | 78 AddChildView(title_); |
| 71 | 79 |
| 72 close_ = CreateCloseButton(this); | 80 close_ = CreateCloseButton(this); |
| 73 close_->SetVisible(false); | 81 close_->SetVisible(false); |
| 74 AddChildView(close_); | 82 AddChildView(close_); |
| 75 } | 83 } |
| 76 | 84 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 157 } | 165 } |
| 158 } | 166 } |
| 159 | 167 |
| 160 void BubbleFrameView::ResetWindowControls() { | 168 void BubbleFrameView::ResetWindowControls() { |
| 161 close_->SetVisible(GetWidget()->widget_delegate()->ShouldShowCloseButton()); | 169 close_->SetVisible(GetWidget()->widget_delegate()->ShouldShowCloseButton()); |
| 162 } | 170 } |
| 163 | 171 |
| 164 void BubbleFrameView::UpdateWindowIcon() {} | 172 void BubbleFrameView::UpdateWindowIcon() {} |
| 165 | 173 |
| 166 void BubbleFrameView::UpdateWindowTitle() { | 174 void BubbleFrameView::UpdateWindowTitle() { |
| 175 gfx::ImageSkia image; | |
|
msw
2015/02/19 23:56:14
Move this into UpdateWindowIcon(), but you may nee
xiaoling
2015/02/20 19:43:21
Done. I made views::Widget::Init() calls UpdateWin
msw
2015/02/20 20:03:44
It should be correct, thanks.
| |
| 176 if (GetWidget()->widget_delegate()->ShouldShowWindowIcon()) | |
| 177 image = GetWidget()->widget_delegate()->GetWindowIcon(); | |
| 178 title_icon_->SetImage(&image); | |
| 179 | |
| 167 title_->SetText(GetWidget()->widget_delegate()->ShouldShowWindowTitle() ? | 180 title_->SetText(GetWidget()->widget_delegate()->ShouldShowWindowTitle() ? |
| 168 GetWidget()->widget_delegate()->GetWindowTitle() : base::string16()); | 181 GetWidget()->widget_delegate()->GetWindowTitle() : base::string16()); |
| 169 // Update the close button visibility too, otherwise it's not intialized. | 182 // Update the close button visibility too, otherwise it's not intialized. |
| 170 ResetWindowControls(); | 183 ResetWindowControls(); |
| 171 } | 184 } |
| 172 | 185 |
| 173 void BubbleFrameView::SizeConstraintsChanged() {} | 186 void BubbleFrameView::SizeConstraintsChanged() {} |
| 174 | 187 |
| 175 void BubbleFrameView::SetTitleFontList(const gfx::FontList& font_list) { | 188 void BubbleFrameView::SetTitleFontList(const gfx::FontList& font_list) { |
| 176 title_->SetFontList(font_list); | 189 title_->SetFontList(font_list); |
| 177 } | 190 } |
| 178 | 191 |
| 179 gfx::Insets BubbleFrameView::GetInsets() const { | 192 gfx::Insets BubbleFrameView::GetInsets() const { |
| 180 gfx::Insets insets = content_margins_; | 193 gfx::Insets insets = content_margins_; |
| 181 const int title_height = title_->text().empty() ? 0 : | 194 |
| 182 title_->GetPreferredSize().height() + kTitleTopInset + kTitleBottomInset; | 195 const int icon_height = title_icon_->GetPreferredSize().height(); |
| 196 const int label_height = | |
| 197 title_->text().empty() ? 0 : title_->GetPreferredSize().height(); | |
|
msw
2015/02/19 23:56:14
Maybe you can title_->set_collapse_when_hidden(tru
xiaoling
2015/02/20 19:43:21
Done.
| |
| 198 const bool has_title = icon_height > 0 || label_height > 0; | |
| 199 const int title_padding = has_title ? kTitleTopInset + kTitleBottomInset : 0; | |
| 200 const int title_height = std::max(icon_height, label_height) + title_padding; | |
| 183 const int close_height = close_->visible() ? close_->height() : 0; | 201 const int close_height = close_->visible() ? close_->height() : 0; |
| 184 insets += gfx::Insets(std::max(title_height, close_height), 0, 0, 0); | 202 insets += gfx::Insets(std::max(title_height, close_height), 0, 0, 0); |
| 185 return insets; | 203 return insets; |
| 186 } | 204 } |
| 187 | 205 |
| 188 gfx::Size BubbleFrameView::GetPreferredSize() const { | 206 gfx::Size BubbleFrameView::GetPreferredSize() const { |
| 189 return GetSizeForClientSize(GetWidget()->client_view()->GetPreferredSize()); | 207 return GetSizeForClientSize(GetWidget()->client_view()->GetPreferredSize()); |
| 190 } | 208 } |
| 191 | 209 |
| 192 gfx::Size BubbleFrameView::GetMinimumSize() const { | 210 gfx::Size BubbleFrameView::GetMinimumSize() const { |
| 193 return GetSizeForClientSize(GetWidget()->client_view()->GetMinimumSize()); | 211 return GetSizeForClientSize(GetWidget()->client_view()->GetMinimumSize()); |
| 194 } | 212 } |
| 195 | 213 |
| 196 void BubbleFrameView::Layout() { | 214 void BubbleFrameView::Layout() { |
| 197 gfx::Rect bounds(GetContentsBounds()); | 215 gfx::Rect bounds(GetContentsBounds()); |
| 198 bounds.Inset(GetTitleInsets()); | 216 bounds.Inset(GetTitleInsets()); |
| 199 if (bounds.IsEmpty()) | 217 if (bounds.IsEmpty()) |
| 200 return; | 218 return; |
| 201 | 219 |
| 202 // The close button top inset is actually smaller than the title top inset. | 220 // The close button top inset is actually smaller than the title top inset. |
| 203 close_->SetPosition(gfx::Point(bounds.right() - close_->width(), | 221 close_->SetPosition(gfx::Point(bounds.right() - close_->width(), |
| 204 bounds.y() - 5)); | 222 bounds.y() - 5)); |
| 205 | 223 |
| 206 gfx::Size title_size(title_->GetPreferredSize()); | 224 gfx::Size title_icon_size(title_icon_->GetPreferredSize()); |
| 207 const int title_width = std::max(0, close_->x() - bounds.x()); | 225 gfx::Size title_label_size(title_->GetPreferredSize()); |
|
msw
2015/02/19 23:56:14
Wouldn't this have the same defect: non-zero heigh
xiaoling
2015/02/20 19:43:21
Right, I inherited the defect:(
| |
| 208 title_size.SetToMin(gfx::Size(title_width, title_size.height())); | 226 const int title_height = std::max(title_icon_size.height(), |
| 209 bounds.set_size(title_size); | 227 title_label_size.height()); |
|
msw
2015/02/19 23:56:14
nit: the old code updated |bounds| to have the siz
xiaoling
2015/02/20 19:43:21
Ahh, I missed that. Done.
| |
| 210 title_->SetBoundsRect(bounds); | 228 |
| 229 const int title_icon_width = std::max(0, close_->x() - bounds.x()); | |
| 230 title_icon_size.SetToMin(gfx::Size(title_icon_width, title_height)); | |
| 231 gfx::Rect title_icon_bounds( | |
| 232 bounds.x(), | |
| 233 bounds.y() + (title_height - title_icon_size.height()) / 2, | |
|
msw
2015/02/19 23:56:14
Did you fix vertical centering? Please post screen
xiaoling
2015/02/20 19:43:21
I think yes. My naive way seems to have the same r
| |
| 234 title_icon_size.width(), | |
| 235 title_icon_size.height()); | |
| 236 title_icon_->SetBoundsRect(title_icon_bounds); | |
| 237 | |
| 238 const int title_label_x = | |
| 239 title_icon_->bounds().right() + kTitleHorizontalPadding; | |
| 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, | |
| 245 bounds.y() + (title_height - title_label_size.height()) / 2, | |
| 246 title_label_size.width(), | |
| 247 title_label_size.height()); | |
| 248 title_->SetBoundsRect(title_label_bounds); | |
| 211 | 249 |
| 212 if (titlebar_extra_view_) { | 250 if (titlebar_extra_view_) { |
| 213 const int extra_width = close_->x() - title_->bounds().right(); | 251 const int extra_width = close_->x() - title_->bounds().right(); |
| 214 gfx::Size size = titlebar_extra_view_->GetPreferredSize(); | 252 gfx::Size size = titlebar_extra_view_->GetPreferredSize(); |
| 215 size.SetToMin(gfx::Size(std::max(0, extra_width), size.height())); | 253 size.SetToMin(gfx::Size(std::max(0, extra_width), size.height())); |
| 216 gfx::Rect titlebar_extra_view_bounds( | 254 gfx::Rect titlebar_extra_view_bounds( |
| 217 close_->x() - size.width(), | 255 close_->x() - size.width(), |
| 218 bounds.y(), | 256 bounds.y(), |
| 219 size.width(), | 257 size.width(), |
| 220 bounds.height()); | 258 bounds.height()); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 bubble_border_->set_arrow_offset( | 402 bubble_border_->set_arrow_offset( |
| 365 bubble_border_->GetArrowOffset(window_bounds.size()) - offscreen_adjust); | 403 bubble_border_->GetArrowOffset(window_bounds.size()) - offscreen_adjust); |
| 366 if (offscreen_adjust) | 404 if (offscreen_adjust) |
| 367 SchedulePaint(); | 405 SchedulePaint(); |
| 368 } | 406 } |
| 369 | 407 |
| 370 gfx::Size BubbleFrameView::GetSizeForClientSize( | 408 gfx::Size BubbleFrameView::GetSizeForClientSize( |
| 371 const gfx::Size& client_size) const { | 409 const gfx::Size& client_size) const { |
| 372 // Accommodate the width of the title bar elements. | 410 // Accommodate the width of the title bar elements. |
| 373 int title_bar_width = GetInsets().width() + border()->GetInsets().width(); | 411 int title_bar_width = GetInsets().width() + border()->GetInsets().width(); |
| 412 gfx::Size title_icon_size = title_icon_->GetPreferredSize(); | |
| 413 if (title_icon_size.width() > 0 || !title_->text().empty()) | |
| 414 title_bar_width += kTitleLeftInset; | |
| 415 if (title_icon_size.width() > 0 && !title_->text().empty()) | |
| 416 title_bar_width += kTitleHorizontalPadding; | |
| 417 if (title_icon_size.width() > 0) | |
| 418 title_bar_width += title_icon_size.width(); | |
| 374 if (!title_->text().empty()) | 419 if (!title_->text().empty()) |
| 375 title_bar_width += kTitleLeftInset + title_->GetPreferredSize().width(); | 420 title_bar_width += title_->GetPreferredSize().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 |