Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Unified Diff: ui/views/bubble/bubble_frame_view.cc

Issue 851853002: It is time. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Trying to reup because the last upload failed. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/views/bubble/bubble_frame_view.h ('k') | ui/views/bubble/bubble_frame_view_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/bubble/bubble_frame_view.cc
diff --git a/ui/views/bubble/bubble_frame_view.cc b/ui/views/bubble/bubble_frame_view.cc
deleted file mode 100644
index e3eb3c8999ec62ed16e1b8d663095aa3e72e15a2..0000000000000000000000000000000000000000
--- a/ui/views/bubble/bubble_frame_view.cc
+++ /dev/null
@@ -1,387 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/views/bubble/bubble_frame_view.h"
-
-#include <algorithm>
-
-#include "ui/base/hit_test.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/path.h"
-#include "ui/gfx/screen.h"
-#include "ui/gfx/skia_util.h"
-#include "ui/native_theme/native_theme.h"
-#include "ui/resources/grit/ui_resources.h"
-#include "ui/views/bubble/bubble_border.h"
-#include "ui/views/controls/button/label_button.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/widget/widget_delegate.h"
-#include "ui/views/window/client_view.h"
-
-namespace {
-
-// Insets for the title bar views in pixels.
-const int kTitleTopInset = 12;
-const int kTitleLeftInset = 19;
-const int kTitleBottomInset = 12;
-const int kTitleRightInset = 7;
-
-// Get the |vertical| or horizontal amount that |available_bounds| overflows
-// |window_bounds|.
-int GetOffScreenLength(const gfx::Rect& available_bounds,
- const gfx::Rect& window_bounds,
- bool vertical) {
- if (available_bounds.IsEmpty() || available_bounds.Contains(window_bounds))
- return 0;
-
- // window_bounds
- // +---------------------------------+
- // | top |
- // | +------------------+ |
- // | left | available_bounds | right |
- // | +------------------+ |
- // | bottom |
- // +---------------------------------+
- if (vertical)
- return std::max(0, available_bounds.y() - window_bounds.y()) +
- std::max(0, window_bounds.bottom() - available_bounds.bottom());
- return std::max(0, available_bounds.x() - window_bounds.x()) +
- std::max(0, window_bounds.right() - available_bounds.right());
-}
-
-} // namespace
-
-namespace views {
-
-// static
-const char BubbleFrameView::kViewClassName[] = "BubbleFrameView";
-
-BubbleFrameView::BubbleFrameView(const gfx::Insets& content_margins)
- : bubble_border_(NULL),
- content_margins_(content_margins),
- title_(NULL),
- close_(NULL),
- titlebar_extra_view_(NULL) {
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- title_ = new Label(base::string16(),
- rb.GetFontList(ui::ResourceBundle::MediumFont));
- title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
- AddChildView(title_);
-
- close_ = CreateCloseButton(this);
- close_->SetVisible(false);
- AddChildView(close_);
-}
-
-BubbleFrameView::~BubbleFrameView() {}
-
-// static
-gfx::Insets BubbleFrameView::GetTitleInsets() {
- return gfx::Insets(
- kTitleTopInset, kTitleLeftInset, kTitleBottomInset, kTitleRightInset);
-}
-
-// static
-LabelButton* BubbleFrameView::CreateCloseButton(ButtonListener* listener) {
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- LabelButton* close = new LabelButton(listener, base::string16());
- close->SetImage(CustomButton::STATE_NORMAL,
- *rb.GetImageNamed(IDR_CLOSE_DIALOG).ToImageSkia());
- close->SetImage(CustomButton::STATE_HOVERED,
- *rb.GetImageNamed(IDR_CLOSE_DIALOG_H).ToImageSkia());
- close->SetImage(CustomButton::STATE_PRESSED,
- *rb.GetImageNamed(IDR_CLOSE_DIALOG_P).ToImageSkia());
- close->SetBorder(scoped_ptr<Border>());
- close->SetSize(close->GetPreferredSize());
- return close;
-}
-
-gfx::Rect BubbleFrameView::GetBoundsForClientView() const {
- gfx::Rect client_bounds = GetLocalBounds();
- client_bounds.Inset(GetInsets());
- client_bounds.Inset(bubble_border_->GetInsets());
- return client_bounds;
-}
-
-gfx::Rect BubbleFrameView::GetWindowBoundsForClientBounds(
- const gfx::Rect& client_bounds) const {
- return const_cast<BubbleFrameView*>(this)->GetUpdatedWindowBounds(
- gfx::Rect(), client_bounds.size(), false);
-}
-
-int BubbleFrameView::NonClientHitTest(const gfx::Point& point) {
- if (!bounds().Contains(point))
- return HTNOWHERE;
- if (close_->visible() && close_->GetMirroredBounds().Contains(point))
- return HTCLOSE;
-
- // Allow dialogs to show the system menu and be dragged.
- if (GetWidget()->widget_delegate()->AsDialogDelegate()) {
- gfx::Rect sys_rect(0, 0, title_->x(), title_->y());
- sys_rect.set_origin(gfx::Point(GetMirroredXForRect(sys_rect), 0));
- if (sys_rect.Contains(point))
- return HTSYSMENU;
- if (point.y() < title_->bounds().bottom())
- return HTCAPTION;
- }
-
- return GetWidget()->client_view()->NonClientHitTest(point);
-}
-
-void BubbleFrameView::GetWindowMask(const gfx::Size& size,
- gfx::Path* window_mask) {
- // NOTE: this only provides implementations for the types used by dialogs.
- if ((bubble_border_->arrow() != BubbleBorder::NONE &&
- bubble_border_->arrow() != BubbleBorder::FLOAT) ||
- (bubble_border_->shadow() != BubbleBorder::SMALL_SHADOW &&
- bubble_border_->shadow() != BubbleBorder::NO_SHADOW_OPAQUE_BORDER))
- return;
-
- // Use a window mask roughly matching the border in the image assets.
- static const int kBorderStrokeSize = 1;
- static const SkScalar kCornerRadius = SkIntToScalar(6);
- const gfx::Insets border_insets = bubble_border_->GetInsets();
- SkRect rect = { SkIntToScalar(border_insets.left() - kBorderStrokeSize),
- SkIntToScalar(border_insets.top() - kBorderStrokeSize),
- SkIntToScalar(size.width() - border_insets.right() +
- kBorderStrokeSize),
- SkIntToScalar(size.height() - border_insets.bottom() +
- kBorderStrokeSize) };
- if (bubble_border_->shadow() == BubbleBorder::NO_SHADOW_OPAQUE_BORDER) {
- window_mask->addRoundRect(rect, kCornerRadius, kCornerRadius);
- } else {
- static const int kBottomBorderShadowSize = 2;
- rect.fBottom += SkIntToScalar(kBottomBorderShadowSize);
- window_mask->addRect(rect);
- }
-}
-
-void BubbleFrameView::ResetWindowControls() {
- close_->SetVisible(GetWidget()->widget_delegate()->ShouldShowCloseButton());
-}
-
-void BubbleFrameView::UpdateWindowIcon() {}
-
-void BubbleFrameView::UpdateWindowTitle() {
- title_->SetText(GetWidget()->widget_delegate()->ShouldShowWindowTitle() ?
- GetWidget()->widget_delegate()->GetWindowTitle() : base::string16());
- // Update the close button visibility too, otherwise it's not intialized.
- ResetWindowControls();
-}
-
-void BubbleFrameView::SizeConstraintsChanged() {}
-
-void BubbleFrameView::SetTitleFontList(const gfx::FontList& font_list) {
- title_->SetFontList(font_list);
-}
-
-gfx::Insets BubbleFrameView::GetInsets() const {
- gfx::Insets insets = content_margins_;
- const int title_height = title_->text().empty() ? 0 :
- title_->GetPreferredSize().height() + kTitleTopInset + kTitleBottomInset;
- const int close_height = close_->visible() ? close_->height() : 0;
- insets += gfx::Insets(std::max(title_height, close_height), 0, 0, 0);
- return insets;
-}
-
-gfx::Size BubbleFrameView::GetPreferredSize() const {
- return GetSizeForClientSize(GetWidget()->client_view()->GetPreferredSize());
-}
-
-gfx::Size BubbleFrameView::GetMinimumSize() const {
- return GetSizeForClientSize(GetWidget()->client_view()->GetMinimumSize());
-}
-
-void BubbleFrameView::Layout() {
- gfx::Rect bounds(GetContentsBounds());
- bounds.Inset(GetTitleInsets());
- if (bounds.IsEmpty())
- return;
-
- // The close button top inset is actually smaller than the title top inset.
- close_->SetPosition(gfx::Point(bounds.right() - close_->width(),
- bounds.y() - 5));
-
- gfx::Size title_size(title_->GetPreferredSize());
- const int title_width = std::max(0, close_->x() - bounds.x());
- title_size.SetToMin(gfx::Size(title_width, title_size.height()));
- bounds.set_size(title_size);
- title_->SetBoundsRect(bounds);
-
- if (titlebar_extra_view_) {
- const int extra_width = close_->x() - title_->bounds().right();
- gfx::Size size = titlebar_extra_view_->GetPreferredSize();
- size.SetToMin(gfx::Size(std::max(0, extra_width), size.height()));
- gfx::Rect titlebar_extra_view_bounds(
- close_->x() - size.width(),
- bounds.y(),
- size.width(),
- bounds.height());
- titlebar_extra_view_bounds.Subtract(bounds);
- titlebar_extra_view_->SetBoundsRect(titlebar_extra_view_bounds);
- }
-}
-
-const char* BubbleFrameView::GetClassName() const {
- return kViewClassName;
-}
-
-void BubbleFrameView::ChildPreferredSizeChanged(View* child) {
- if (child == titlebar_extra_view_ || child == title_)
- Layout();
-}
-
-void BubbleFrameView::OnThemeChanged() {
- UpdateWindowTitle();
- ResetWindowControls();
- UpdateWindowIcon();
-}
-
-void BubbleFrameView::OnNativeThemeChanged(const ui::NativeTheme* theme) {
- if (bubble_border_ && bubble_border_->use_theme_background_color()) {
- bubble_border_->set_background_color(GetNativeTheme()->
- GetSystemColor(ui::NativeTheme::kColorId_DialogBackground));
- SchedulePaint();
- }
-}
-
-void BubbleFrameView::ButtonPressed(Button* sender, const ui::Event& event) {
- if (sender == close_)
- GetWidget()->Close();
-}
-
-void BubbleFrameView::SetBubbleBorder(scoped_ptr<BubbleBorder> border) {
- bubble_border_ = border.get();
- SetBorder(border.Pass());
-
- // Update the background, which relies on the border.
- set_background(new views::BubbleBackground(bubble_border_));
-}
-
-void BubbleFrameView::SetTitlebarExtraView(View* view) {
- DCHECK(view);
- DCHECK(!titlebar_extra_view_);
- AddChildView(view);
- titlebar_extra_view_ = view;
-}
-
-gfx::Rect BubbleFrameView::GetUpdatedWindowBounds(const gfx::Rect& anchor_rect,
- gfx::Size client_size,
- bool adjust_if_offscreen) {
- gfx::Size size(GetSizeForClientSize(client_size));
-
- const BubbleBorder::Arrow arrow = bubble_border_->arrow();
- if (adjust_if_offscreen && BubbleBorder::has_arrow(arrow)) {
- // Try to mirror the anchoring if the bubble does not fit on the screen.
- if (!bubble_border_->is_arrow_at_center(arrow)) {
- MirrorArrowIfOffScreen(true, anchor_rect, size);
- MirrorArrowIfOffScreen(false, anchor_rect, size);
- } else {
- const bool mirror_vertical = BubbleBorder::is_arrow_on_horizontal(arrow);
- MirrorArrowIfOffScreen(mirror_vertical, anchor_rect, size);
- OffsetArrowIfOffScreen(anchor_rect, size);
- }
- }
-
- // Calculate the bounds with the arrow in its updated location and offset.
- return bubble_border_->GetBounds(anchor_rect, size);
-}
-
-gfx::Rect BubbleFrameView::GetAvailableScreenBounds(const gfx::Rect& rect) {
- // The bubble attempts to fit within the current screen bounds.
- // TODO(scottmg): Native is wrong. http://crbug.com/133312
- return gfx::Screen::GetNativeScreen()->GetDisplayNearestPoint(
- rect.CenterPoint()).work_area();
-}
-
-bool BubbleFrameView::IsCloseButtonVisible() const {
- return close_->visible();
-}
-
-gfx::Rect BubbleFrameView::GetCloseButtonBounds() const {
- return close_->bounds();
-}
-
-void BubbleFrameView::MirrorArrowIfOffScreen(
- bool vertical,
- const gfx::Rect& anchor_rect,
- const gfx::Size& client_size) {
- // Check if the bounds don't fit on screen.
- gfx::Rect available_bounds(GetAvailableScreenBounds(anchor_rect));
- gfx::Rect window_bounds(bubble_border_->GetBounds(anchor_rect, client_size));
- if (GetOffScreenLength(available_bounds, window_bounds, vertical) > 0) {
- BubbleBorder::Arrow arrow = bubble_border()->arrow();
- // Mirror the arrow and get the new bounds.
- bubble_border_->set_arrow(
- vertical ? BubbleBorder::vertical_mirror(arrow) :
- BubbleBorder::horizontal_mirror(arrow));
- gfx::Rect mirror_bounds =
- bubble_border_->GetBounds(anchor_rect, client_size);
- // Restore the original arrow if mirroring doesn't show more of the bubble.
- // Otherwise it should invoke parent's Layout() to layout the content based
- // on the new bubble border.
- if (GetOffScreenLength(available_bounds, mirror_bounds, vertical) >=
- GetOffScreenLength(available_bounds, window_bounds, vertical))
- bubble_border_->set_arrow(arrow);
- else if (parent())
- parent()->Layout();
- }
-}
-
-void BubbleFrameView::OffsetArrowIfOffScreen(const gfx::Rect& anchor_rect,
- const gfx::Size& client_size) {
- BubbleBorder::Arrow arrow = bubble_border()->arrow();
- DCHECK(BubbleBorder::is_arrow_at_center(arrow));
-
- // Get the desired bubble bounds without adjustment.
- bubble_border_->set_arrow_offset(0);
- gfx::Rect window_bounds(bubble_border_->GetBounds(anchor_rect, client_size));
-
- gfx::Rect available_bounds(GetAvailableScreenBounds(anchor_rect));
- if (available_bounds.IsEmpty() || available_bounds.Contains(window_bounds))
- return;
-
- // Calculate off-screen adjustment.
- const bool is_horizontal = BubbleBorder::is_arrow_on_horizontal(arrow);
- int offscreen_adjust = 0;
- if (is_horizontal) {
- if (window_bounds.x() < available_bounds.x())
- offscreen_adjust = available_bounds.x() - window_bounds.x();
- else if (window_bounds.right() > available_bounds.right())
- offscreen_adjust = available_bounds.right() - window_bounds.right();
- } else {
- if (window_bounds.y() < available_bounds.y())
- offscreen_adjust = available_bounds.y() - window_bounds.y();
- else if (window_bounds.bottom() > available_bounds.bottom())
- offscreen_adjust = available_bounds.bottom() - window_bounds.bottom();
- }
-
- // For center arrows, arrows are moved in the opposite direction of
- // |offscreen_adjust|, e.g. positive |offscreen_adjust| means bubble
- // window needs to be moved to the right and that means we need to move arrow
- // to the left, and that means negative offset.
- bubble_border_->set_arrow_offset(
- bubble_border_->GetArrowOffset(window_bounds.size()) - offscreen_adjust);
- if (offscreen_adjust)
- SchedulePaint();
-}
-
-gfx::Size BubbleFrameView::GetSizeForClientSize(
- const gfx::Size& client_size) const {
- // Accommodate the width of the title bar elements.
- int title_bar_width = GetInsets().width() + border()->GetInsets().width();
- if (!title_->text().empty())
- title_bar_width += kTitleLeftInset + title_->GetPreferredSize().width();
- if (close_->visible())
- title_bar_width += close_->width() + 1;
- if (titlebar_extra_view_ != NULL)
- title_bar_width += titlebar_extra_view_->GetPreferredSize().width();
- gfx::Size size(client_size);
- size.SetToMax(gfx::Size(title_bar_width, 0));
- const gfx::Insets insets(GetInsets());
- size.Enlarge(insets.width(), insets.height());
- return size;
-}
-
-} // namespace views
« no previous file with comments | « ui/views/bubble/bubble_frame_view.h ('k') | ui/views/bubble/bubble_frame_view_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698