summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views/notifications/balloon_view.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/views/notifications/balloon_view.cc')
-rw-r--r--chrome/browser/views/notifications/balloon_view.cc502
1 files changed, 0 insertions, 502 deletions
diff --git a/chrome/browser/views/notifications/balloon_view.cc b/chrome/browser/views/notifications/balloon_view.cc
deleted file mode 100644
index cf0442b..0000000
--- a/chrome/browser/views/notifications/balloon_view.cc
+++ /dev/null
@@ -1,502 +0,0 @@
-// Copyright (c) 2010 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 "chrome/browser/views/notifications/balloon_view.h"
-
-#include <vector>
-
-#include "app/l10n_util.h"
-#include "app/resource_bundle.h"
-#include "base/message_loop.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/notifications/balloon.h"
-#include "chrome/browser/notifications/balloon_collection.h"
-#include "chrome/browser/notifications/desktop_notification_service.h"
-#include "chrome/browser/notifications/notification_options_menu_model.h"
-#include "chrome/browser/profile.h"
-#include "chrome/browser/renderer_host/render_view_host.h"
-#include "chrome/browser/renderer_host/render_widget_host_view.h"
-#include "chrome/browser/themes/browser_theme_provider.h"
-#include "chrome/browser/views/bubble_border.h"
-#include "chrome/browser/views/notifications/balloon_view_host.h"
-#include "chrome/common/notification_details.h"
-#include "chrome/common/notification_source.h"
-#include "chrome/common/notification_type.h"
-#include "gfx/canvas_skia.h"
-#include "gfx/insets.h"
-#include "gfx/native_widget_types.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "views/controls/button/button.h"
-#include "views/controls/button/image_button.h"
-#include "views/controls/button/text_button.h"
-#include "views/controls/menu/menu_2.h"
-#include "views/controls/native/native_view_host.h"
-#include "views/painter.h"
-#include "views/widget/root_view.h"
-#if defined(OS_WIN)
-#include "views/widget/widget_win.h"
-#endif
-#if defined(OS_LINUX)
-#include "views/widget/widget_gtk.h"
-#endif
-
-using views::Widget;
-
-namespace {
-
-const int kTopMargin = 2;
-const int kBottomMargin = 0;
-const int kLeftMargin = 4;
-const int kRightMargin = 4;
-const int kShelfBorderTopOverlap = 0;
-
-// Properties of the dismiss button.
-const int kDismissButtonWidth = 14;
-const int kDismissButtonHeight = 14;
-const int kDismissButtonTopMargin = 6;
-const int kDismissButtonRightMargin = 6;
-
-// Properties of the options menu.
-const int kOptionsButtonWidth = 21;
-const int kOptionsButtonHeight = 14;
-const int kOptionsButtonTopMargin = 5;
-const int kOptionsButtonRightMargin = 4;
-
-// Properties of the origin label.
-const int kLabelLeftMargin = 10;
-const int kLabelTopMargin = 6;
-
-// Size of the drop shadow. The shadow is provided by BubbleBorder,
-// not this class.
-const int kLeftShadowWidth = 0;
-const int kRightShadowWidth = 0;
-const int kTopShadowWidth = 0;
-const int kBottomShadowWidth = 6;
-
-// Optional animation.
-const bool kAnimateEnabled = true;
-
-// The shelf height for the system default font size. It is scaled
-// with changes in the default font size.
-const int kDefaultShelfHeight = 22;
-
-// Menu commands
-const int kRevokePermissionCommand = 0;
-
-// Colors
-const SkColor kControlBarBackgroundColor = SkColorSetRGB(245, 245, 245);
-const SkColor kControlBarTextColor = SkColorSetRGB(125, 125, 125);
-const SkColor kControlBarSeparatorLineColor = SkColorSetRGB(180, 180, 180);
-
-} // namespace
-
-BalloonViewImpl::BalloonViewImpl(BalloonCollection* collection)
- : balloon_(NULL),
- collection_(collection),
- frame_container_(NULL),
- html_container_(NULL),
- html_contents_(NULL),
- method_factory_(this),
- close_button_(NULL),
- animation_(NULL),
- options_menu_model_(NULL),
- options_menu_menu_(NULL),
- options_menu_button_(NULL) {
- // This object is not to be deleted by the views hierarchy,
- // as it is owned by the balloon.
- set_parent_owned(false);
-
- BubbleBorder* bubble_border = new BubbleBorder(BubbleBorder::FLOAT);
- set_border(bubble_border);
-}
-
-BalloonViewImpl::~BalloonViewImpl() {
-}
-
-void BalloonViewImpl::Close(bool by_user) {
- MessageLoop::current()->PostTask(FROM_HERE,
- method_factory_.NewRunnableMethod(
- &BalloonViewImpl::DelayedClose, by_user));
-}
-
-gfx::Size BalloonViewImpl::GetSize() const {
- // BalloonView has no size if it hasn't been shown yet (which is when
- // balloon_ is set).
- if (!balloon_)
- return gfx::Size(0, 0);
-
- return gfx::Size(GetTotalWidth(), GetTotalHeight());
-}
-
-void BalloonViewImpl::RunMenu(views::View* source, const gfx::Point& pt) {
- RunOptionsMenu(pt);
-}
-
-void BalloonViewImpl::DisplayChanged() {
- collection_->DisplayChanged();
-}
-
-void BalloonViewImpl::WorkAreaChanged() {
- collection_->DisplayChanged();
-}
-
-void BalloonViewImpl::ButtonPressed(views::Button* sender,
- const views::Event&) {
- // The only button currently is the close button.
- DCHECK(sender == close_button_);
- Close(true);
-}
-
-void BalloonViewImpl::DelayedClose(bool by_user) {
- html_contents_->Shutdown();
- html_container_->CloseNow();
- // The BalloonViewImpl has to be detached from frame_container_ now
- // because CloseNow on linux/views destroys the view hierachy
- // asynchronously.
- frame_container_->GetRootView()->RemoveAllChildViews(true);
- frame_container_->CloseNow();
- balloon_->OnClose(by_user);
-}
-
-void BalloonViewImpl::DidChangeBounds(const gfx::Rect& previous,
- const gfx::Rect& current) {
- SizeContentsWindow();
-}
-
-void BalloonViewImpl::SizeContentsWindow() {
- if (!html_container_ || !frame_container_)
- return;
-
- gfx::Rect contents_rect = GetContentsRectangle();
- html_container_->SetBounds(contents_rect);
- html_container_->MoveAbove(frame_container_);
-
- gfx::Path path;
- GetContentsMask(contents_rect, &path);
- html_container_->SetShape(path.CreateNativeRegion());
-
- close_button_->SetBounds(GetCloseButtonBounds());
- options_menu_button_->SetBounds(GetOptionsButtonBounds());
- source_label_->SetBounds(GetLabelBounds());
-}
-
-void BalloonViewImpl::RepositionToBalloon() {
- DCHECK(frame_container_);
- DCHECK(html_container_);
- DCHECK(balloon_);
-
- if (!kAnimateEnabled) {
- frame_container_->SetBounds(
- gfx::Rect(balloon_->GetPosition().x(), balloon_->GetPosition().y(),
- GetTotalWidth(), GetTotalHeight()));
- gfx::Rect contents_rect = GetContentsRectangle();
- html_container_->SetBounds(contents_rect);
- html_contents_->SetPreferredSize(contents_rect.size());
- RenderWidgetHostView* view = html_contents_->render_view_host()->view();
- if (view)
- view->SetSize(contents_rect.size());
- return;
- }
-
- anim_frame_end_ = gfx::Rect(
- balloon_->GetPosition().x(), balloon_->GetPosition().y(),
- GetTotalWidth(), GetTotalHeight());
- frame_container_->GetBounds(&anim_frame_start_, false);
- animation_.reset(new SlideAnimation(this));
- animation_->Show();
-}
-
-void BalloonViewImpl::Update() {
- DCHECK(html_contents_.get()) << "BalloonView::Update called before Show";
- if (html_contents_->render_view_host())
- html_contents_->render_view_host()->NavigateToURL(
- balloon_->notification().content_url());
-}
-
-void BalloonViewImpl::AnimationProgressed(const Animation* animation) {
- DCHECK(animation == animation_.get());
-
- // Linear interpolation from start to end position.
- double e = animation->GetCurrentValue();
- double s = (1.0 - e);
-
- gfx::Rect frame_position(
- static_cast<int>(s * anim_frame_start_.x() +
- e * anim_frame_end_.x()),
- static_cast<int>(s * anim_frame_start_.y() +
- e * anim_frame_end_.y()),
- static_cast<int>(s * anim_frame_start_.width() +
- e * anim_frame_end_.width()),
- static_cast<int>(s * anim_frame_start_.height() +
- e * anim_frame_end_.height()));
- frame_container_->SetBounds(frame_position);
-
- gfx::Path path;
- gfx::Rect contents_rect = GetContentsRectangle();
- html_container_->SetBounds(contents_rect);
- GetContentsMask(contents_rect, &path);
- html_container_->SetShape(path.CreateNativeRegion());
-
- html_contents_->SetPreferredSize(contents_rect.size());
- RenderWidgetHostView* view = html_contents_->render_view_host()->view();
- if (view)
- view->SetSize(contents_rect.size());
-}
-
-gfx::Rect BalloonViewImpl::GetCloseButtonBounds() const {
- return gfx::Rect(
- width() - kDismissButtonWidth -
- kDismissButtonRightMargin - kRightShadowWidth,
- kDismissButtonTopMargin,
- kDismissButtonWidth,
- kDismissButtonHeight);
-}
-
-gfx::Rect BalloonViewImpl::GetOptionsButtonBounds() const {
- gfx::Rect close_rect = GetCloseButtonBounds();
-
- return gfx::Rect(
- close_rect.x() - kOptionsButtonWidth - kOptionsButtonRightMargin,
- kOptionsButtonTopMargin,
- kOptionsButtonWidth,
- kOptionsButtonHeight);
-}
-
-gfx::Rect BalloonViewImpl::GetLabelBounds() const {
- return gfx::Rect(
- kLeftShadowWidth + kLabelLeftMargin,
- kLabelTopMargin,
- std::max(0, width() - kOptionsButtonWidth -
- kRightMargin),
- kOptionsButtonHeight);
-}
-
-void BalloonViewImpl::Show(Balloon* balloon) {
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
-
- balloon_ = balloon;
-
- SetBounds(balloon_->GetPosition().x(), balloon_->GetPosition().y(),
- GetTotalWidth(), GetTotalHeight());
-
- const string16 source_label_text = l10n_util::GetStringFUTF16(
- IDS_NOTIFICATION_BALLOON_SOURCE_LABEL,
- balloon->notification().display_source());
-
- source_label_ = new views::Label(UTF16ToWide(source_label_text));
- AddChildView(source_label_);
- options_menu_button_ = new views::MenuButton(NULL, L"", this, false);
- AddChildView(options_menu_button_);
- close_button_ = new views::ImageButton(this);
- close_button_->SetTooltipText(l10n_util::GetString(
- IDS_NOTIFICATION_BALLOON_DISMISS_LABEL));
- AddChildView(close_button_);
-
- // We have to create two windows: one for the contents and one for the
- // frame. Why?
- // * The contents is an html window which cannot be a
- // layered window (because it may have child windows for instance).
- // * The frame is a layered window so that we can have nicely rounded
- // corners using alpha blending (and we may do other alpha blending
- // effects).
- // Unfortunately, layered windows cannot have child windows. (Well, they can
- // but the child windows don't render).
- //
- // We carefully keep these two windows in sync to present the illusion of
- // one window to the user.
- //
- // We don't let the OS manage the RTL layout of these widgets, because
- // this code is already taking care of correctly reversing the layout.
- gfx::Rect contents_rect = GetContentsRectangle();
- html_contents_.reset(new BalloonViewHost(balloon));
- html_contents_->SetPreferredSize(gfx::Size(10000, 10000));
- html_container_ = Widget::CreatePopupWidget(Widget::NotTransparent,
- Widget::AcceptEvents,
- Widget::DeleteOnDestroy,
- Widget::DontMirrorOriginInRTL);
- html_container_->SetAlwaysOnTop(true);
- html_container_->Init(NULL, contents_rect);
- html_container_->SetContentsView(html_contents_->view());
-
- gfx::Rect balloon_rect(x(), y(), GetTotalWidth(), GetTotalHeight());
- frame_container_ = Widget::CreatePopupWidget(Widget::Transparent,
- Widget::AcceptEvents,
- Widget::DeleteOnDestroy,
- Widget::DontMirrorOriginInRTL);
- frame_container_->SetWidgetDelegate(this);
- frame_container_->SetAlwaysOnTop(true);
- frame_container_->Init(NULL, balloon_rect);
- frame_container_->SetContentsView(this);
- frame_container_->MoveAbove(html_container_);
-
- close_button_->SetImage(views::CustomButton::BS_NORMAL,
- rb.GetBitmapNamed(IDR_TAB_CLOSE));
- close_button_->SetImage(views::CustomButton::BS_HOT,
- rb.GetBitmapNamed(IDR_TAB_CLOSE_H));
- close_button_->SetImage(views::CustomButton::BS_PUSHED,
- rb.GetBitmapNamed(IDR_TAB_CLOSE_P));
- close_button_->SetBounds(GetCloseButtonBounds());
- close_button_->SetBackground(SK_ColorBLACK,
- rb.GetBitmapNamed(IDR_TAB_CLOSE),
- rb.GetBitmapNamed(IDR_TAB_CLOSE_MASK));
-
- options_menu_button_->SetIcon(*rb.GetBitmapNamed(IDR_BALLOON_WRENCH));
- options_menu_button_->SetHoverIcon(*rb.GetBitmapNamed(IDR_BALLOON_WRENCH_H));
- options_menu_button_->SetPushedIcon(*rb.GetBitmapNamed(IDR_BALLOON_WRENCH_P));
- options_menu_button_->set_alignment(views::TextButton::ALIGN_CENTER);
- options_menu_button_->set_border(NULL);
- options_menu_button_->SetBounds(GetOptionsButtonBounds());
-
- source_label_->SetFont(rb.GetFont(ResourceBundle::SmallFont));
- source_label_->SetColor(kControlBarTextColor);
- source_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
- source_label_->SetBounds(GetLabelBounds());
-
- SizeContentsWindow();
- html_container_->Show();
- frame_container_->Show();
-
- notification_registrar_.Add(this,
- NotificationType::NOTIFY_BALLOON_DISCONNECTED, Source<Balloon>(balloon));
-}
-
-void BalloonViewImpl::RunOptionsMenu(const gfx::Point& pt) {
- CreateOptionsMenu();
- options_menu_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT);
-}
-
-void BalloonViewImpl::CreateOptionsMenu() {
- if (options_menu_model_.get())
- return;
-
- options_menu_model_.reset(new NotificationOptionsMenuModel(balloon_));
- options_menu_menu_.reset(new views::Menu2(options_menu_model_.get()));
-}
-
-void BalloonViewImpl::GetContentsMask(const gfx::Rect& rect,
- gfx::Path* path) const {
- // This rounds the corners, and we also cut out a circle for the close
- // button, since we can't guarantee the ordering of two top-most windows.
- SkScalar radius = SkIntToScalar(BubbleBorder::GetCornerRadius());
- SkScalar spline_radius = radius -
- SkScalarMul(radius, (SK_ScalarSqrt2 - SK_Scalar1) * 4 / 3);
- SkScalar left = SkIntToScalar(0);
- SkScalar top = SkIntToScalar(0);
- SkScalar right = SkIntToScalar(rect.width());
- SkScalar bottom = SkIntToScalar(rect.height());
-
- path->moveTo(left, top);
- path->lineTo(right, top);
- path->lineTo(right, bottom - radius);
- path->cubicTo(right, bottom - spline_radius,
- right - spline_radius, bottom,
- right - radius, bottom);
- path->lineTo(left + radius, bottom);
- path->cubicTo(left + spline_radius, bottom,
- left, bottom - spline_radius,
- left, bottom - radius);
- path->lineTo(left, top);
- path->close();
-}
-
-void BalloonViewImpl::GetFrameMask(const gfx::Rect& rect,
- gfx::Path* path) const {
- SkScalar radius = SkIntToScalar(BubbleBorder::GetCornerRadius());
- SkScalar spline_radius = radius -
- SkScalarMul(radius, (SK_ScalarSqrt2 - SK_Scalar1) * 4 / 3);
- SkScalar left = SkIntToScalar(rect.x());
- SkScalar top = SkIntToScalar(rect.y());
- SkScalar right = SkIntToScalar(rect.right());
- SkScalar bottom = SkIntToScalar(rect.bottom());
-
- path->moveTo(left, bottom);
- path->lineTo(left, top + radius);
- path->cubicTo(left, top + spline_radius,
- left + spline_radius, top,
- left + radius, top);
- path->lineTo(right - radius, top);
- path->cubicTo(right - spline_radius, top,
- right, top + spline_radius,
- right, top + radius);
- path->lineTo(right, bottom);
- path->lineTo(left, bottom);
- path->close();
-}
-
-gfx::Point BalloonViewImpl::GetContentsOffset() const {
- return gfx::Point(kLeftShadowWidth + kLeftMargin,
- kTopShadowWidth + kTopMargin);
-}
-
-int BalloonViewImpl::GetShelfHeight() const {
- // TODO(johnnyg): add scaling here.
- return kDefaultShelfHeight;
-}
-
-int BalloonViewImpl::GetBalloonFrameHeight() const {
- return GetTotalHeight() - GetShelfHeight();
-}
-
-int BalloonViewImpl::GetTotalWidth() const {
- return balloon_->content_size().width()
- + kLeftMargin + kRightMargin + kLeftShadowWidth + kRightShadowWidth;
-}
-
-int BalloonViewImpl::GetTotalHeight() const {
- return balloon_->content_size().height()
- + kTopMargin + kBottomMargin + kTopShadowWidth + kBottomShadowWidth
- + GetShelfHeight();
-}
-
-gfx::Rect BalloonViewImpl::GetContentsRectangle() const {
- if (!frame_container_)
- return gfx::Rect();
-
- gfx::Size content_size = balloon_->content_size();
- gfx::Point offset = GetContentsOffset();
- gfx::Rect frame_rect;
- frame_container_->GetBounds(&frame_rect, true);
- return gfx::Rect(frame_rect.x() + offset.x(),
- frame_rect.y() + GetShelfHeight() + offset.y(),
- content_size.width(),
- content_size.height());
-}
-
-void BalloonViewImpl::Paint(gfx::Canvas* canvas) {
- DCHECK(canvas);
- // Paint the menu bar area white, with proper rounded corners.
- gfx::Path path;
- gfx::Rect rect = GetLocalBounds(false);
- rect.set_height(GetShelfHeight());
- GetFrameMask(rect, &path);
-
- SkPaint paint;
- paint.setAntiAlias(true);
- paint.setColor(kControlBarBackgroundColor);
- canvas->AsCanvasSkia()->drawPath(path, paint);
-
- // Draw a 1-pixel gray line between the content and the menu bar.
- int line_width = GetTotalWidth() - kLeftMargin - kRightMargin;
- canvas->FillRectInt(kControlBarSeparatorLineColor,
- kLeftMargin, 1 + GetShelfHeight(), line_width, 1);
-
- View::Paint(canvas);
- PaintBorder(canvas);
-}
-
-void BalloonViewImpl::Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- if (type != NotificationType::NOTIFY_BALLOON_DISCONNECTED) {
- NOTREACHED();
- return;
- }
-
- // If the renderer process attached to this balloon is disconnected
- // (e.g., because of a crash), we want to close the balloon.
- notification_registrar_.Remove(this,
- NotificationType::NOTIFY_BALLOON_DISCONNECTED, Source<Balloon>(balloon_));
- Close(false);
-}