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

Unified Diff: chrome/browser/ui/gtk/notifications/balloon_view_gtk.cc

Issue 231733005: Delete the GTK+ port of Chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remerge to ToT Created 6 years, 8 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
Index: chrome/browser/ui/gtk/notifications/balloon_view_gtk.cc
diff --git a/chrome/browser/ui/gtk/notifications/balloon_view_gtk.cc b/chrome/browser/ui/gtk/notifications/balloon_view_gtk.cc
deleted file mode 100644
index 97180d9ff8433aa21daa4d21ff9ac8770607bbcb..0000000000000000000000000000000000000000
--- a/chrome/browser/ui/gtk/notifications/balloon_view_gtk.cc
+++ /dev/null
@@ -1,474 +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 "chrome/browser/ui/gtk/notifications/balloon_view_gtk.h"
-
-#include <gtk/gtk.h>
-
-#include <string>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/debug/trace_event.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/string_util.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/notifications/balloon.h"
-#include "chrome/browser/notifications/desktop_notification_service.h"
-#include "chrome/browser/notifications/notification.h"
-#include "chrome/browser/notifications/notification_options_menu_model.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/themes/theme_service.h"
-#include "chrome/browser/ui/browser_list.h"
-#include "chrome/browser/ui/browser_window.h"
-#include "chrome/browser/ui/gtk/custom_button.h"
-#include "chrome/browser/ui/gtk/gtk_theme_service.h"
-#include "chrome/browser/ui/gtk/gtk_util.h"
-#include "chrome/browser/ui/gtk/menu_gtk.h"
-#include "chrome/browser/ui/gtk/notifications/balloon_view_host_gtk.h"
-#include "chrome/browser/ui/gtk/rounded_window.h"
-#include "content/public/browser/notification_source.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/render_widget_host_view.h"
-#include "content/public/browser/web_contents.h"
-#include "extensions/browser/extension_host.h"
-#include "extensions/browser/process_manager.h"
-#include "extensions/common/extension.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "ui/base/gtk/gtk_hig_constants.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/animation/slide_animation.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/insets.h"
-#include "ui/gfx/native_widget_types.h"
-
-namespace {
-
-// Margin, in pixels, between the notification frame and the contents
-// of the notification.
-const int kTopMargin = 0;
-const int kBottomMargin = 1;
-const int kLeftMargin = 1;
-const int kRightMargin = 1;
-
-// Properties of the origin label.
-const int kLeftLabelMargin = 8;
-
-// TODO(johnnyg): Add a shadow for the frame.
-const int kLeftShadowWidth = 0;
-const int kRightShadowWidth = 0;
-const int kTopShadowWidth = 0;
-const int kBottomShadowWidth = 0;
-
-// Space in pixels between text and icon on the buttons.
-const int kButtonSpacing = 3;
-
-// Number of characters to show in the origin label before ellipsis.
-const int kOriginLabelCharacters = 18;
-
-// The shelf height for the system default font size. It is scaled
-// with changes in the default font size.
-const int kDefaultShelfHeight = 25;
-
-// The amount that the bubble collections class offsets from the side of the
-// screen.
-const int kScreenBorder = 5;
-
-// Colors specified in various ways for different parts of the UI.
-// These match the windows colors in balloon_view.cc
-const char* kLabelColor = "#7D7D7D";
-const double kShelfBackgroundColorR = 245.0 / 255.0;
-const double kShelfBackgroundColorG = 245.0 / 255.0;
-const double kShelfBackgroundColorB = 245.0 / 255.0;
-const double kDividerLineColorR = 180.0 / 255.0;
-const double kDividerLineColorG = 180.0 / 255.0;
-const double kDividerLineColorB = 180.0 / 255.0;
-
-// Makes the website label relatively smaller to the base text size.
-const char* kLabelMarkup = "<span size=\"small\" color=\"%s\">%s</span>";
-
-} // namespace
-
-BalloonViewImpl::BalloonViewImpl(BalloonCollection* collection)
- : balloon_(NULL),
- theme_service_(NULL),
- frame_container_(NULL),
- shelf_(NULL),
- hbox_(NULL),
- html_container_(NULL),
- menu_showing_(false),
- pending_close_(false),
- weak_factory_(this) {}
-
-BalloonViewImpl::~BalloonViewImpl() {
- if (frame_container_) {
- GtkWidget* widget = frame_container_;
- frame_container_ = NULL;
- gtk_widget_hide(widget);
- }
-}
-
-void BalloonViewImpl::Close(bool by_user) {
- // Delay a system-initiated close if the menu is showing.
- if (!by_user && menu_showing_) {
- pending_close_ = true;
- } else {
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&BalloonViewImpl::DelayedClose,
- weak_factory_.GetWeakPtr(),
- 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();
-
- // Although this may not be the instantaneous size of the balloon if
- // called in the middle of an animation, it is the effective size that
- // will result from the animation.
- return gfx::Size(GetDesiredTotalWidth(), GetDesiredTotalHeight());
-}
-
-BalloonHost* BalloonViewImpl::GetHost() const {
- return html_contents_.get();
-}
-
-void BalloonViewImpl::DelayedClose(bool by_user) {
- html_contents_->Shutdown();
- if (frame_container_) {
- // It's possible that |frame_container_| was destroyed before the
- // BalloonViewImpl if our related browser window was closed first.
- gtk_widget_hide(frame_container_);
- }
- balloon_->OnClose(by_user);
-}
-
-void BalloonViewImpl::RepositionToBalloon() {
- if (!frame_container_) {
- // No need to create a slide animation when this balloon is fading out.
- return;
- }
-
- DCHECK(balloon_);
-
- // Create an amination from the current position to the desired one.
- int start_x;
- int start_y;
- int start_w;
- int start_h;
- gtk_window_get_position(GTK_WINDOW(frame_container_), &start_x, &start_y);
- gtk_window_get_size(GTK_WINDOW(frame_container_), &start_w, &start_h);
-
- int end_x = balloon_->GetPosition().x();
- int end_y = balloon_->GetPosition().y();
- int end_w = GetDesiredTotalWidth();
- int end_h = GetDesiredTotalHeight();
-
- anim_frame_start_ = gfx::Rect(start_x, start_y, start_w, start_h);
- anim_frame_end_ = gfx::Rect(end_x, end_y, end_w, end_h);
- animation_.reset(new gfx::SlideAnimation(this));
- animation_->Show();
-}
-
-void BalloonViewImpl::AnimationProgressed(const gfx::Animation* animation) {
- DCHECK_EQ(animation, animation_.get());
-
- // Linear interpolation from start to end position.
- double end = animation->GetCurrentValue();
- double start = 1.0 - end;
-
- gfx::Rect frame_position(
- static_cast<int>(start * anim_frame_start_.x() +
- end * anim_frame_end_.x()),
- static_cast<int>(start * anim_frame_start_.y() +
- end * anim_frame_end_.y()),
- static_cast<int>(start * anim_frame_start_.width() +
- end * anim_frame_end_.width()),
- static_cast<int>(start * anim_frame_start_.height() +
- end * anim_frame_end_.height()));
- gtk_window_resize(GTK_WINDOW(frame_container_),
- frame_position.width(), frame_position.height());
- gtk_window_move(GTK_WINDOW(frame_container_),
- frame_position.x(), frame_position.y());
-
- gfx::Rect contents_rect = GetContentsRectangle();
- html_contents_->UpdateActualSize(contents_rect.size());
-}
-
-void BalloonViewImpl::Show(Balloon* balloon) {
- theme_service_ = GtkThemeService::GetFrom(balloon->profile());
-
- const std::string source_label_text = l10n_util::GetStringFUTF8(
- IDS_NOTIFICATION_BALLOON_SOURCE_LABEL,
- balloon->notification().display_source());
- const std::string options_text =
- l10n_util::GetStringUTF8(IDS_NOTIFICATION_OPTIONS_MENU_LABEL);
- const std::string dismiss_text =
- l10n_util::GetStringUTF8(IDS_NOTIFICATION_BALLOON_DISMISS_LABEL);
-
- balloon_ = balloon;
- frame_container_ = gtk_window_new(GTK_WINDOW_POPUP);
-
- g_signal_connect(frame_container_, "expose-event",
- G_CALLBACK(OnExposeThunk), this);
- g_signal_connect(frame_container_, "destroy",
- G_CALLBACK(OnDestroyThunk), this);
-
- // Construct the options menu.
- options_menu_model_.reset(new NotificationOptionsMenuModel(balloon_));
- options_menu_.reset(new MenuGtk(this, options_menu_model_.get()));
-
- // Create a BalloonViewHost to host the HTML contents of this balloon.
- html_contents_.reset(new BalloonViewHost(balloon));
- html_contents_->Init();
- gfx::NativeView contents = html_contents_->native_view();
- g_signal_connect_after(contents, "expose-event",
- G_CALLBACK(OnContentsExposeThunk), this);
-
- // Divide the frame vertically into the shelf and the content area.
- GtkWidget* vbox = gtk_vbox_new(0, 0);
- gtk_container_add(GTK_CONTAINER(frame_container_), vbox);
-
- // Create the toolbar.
- shelf_ = gtk_hbox_new(FALSE, 0);
- gtk_widget_set_size_request(GTK_WIDGET(shelf_), -1, GetShelfHeight());
- gtk_container_add(GTK_CONTAINER(vbox), shelf_);
-
- // Create a label for the source of the notification and add it to the
- // toolbar.
- GtkWidget* source_label_ = gtk_label_new(NULL);
- char* markup = g_markup_printf_escaped(kLabelMarkup,
- kLabelColor,
- source_label_text.c_str());
- gtk_label_set_markup(GTK_LABEL(source_label_), markup);
- g_free(markup);
- gtk_label_set_max_width_chars(GTK_LABEL(source_label_),
- kOriginLabelCharacters);
- gtk_label_set_ellipsize(GTK_LABEL(source_label_), PANGO_ELLIPSIZE_END);
- GtkWidget* label_alignment = gtk_alignment_new(0, 0.5, 0, 0);
- gtk_alignment_set_padding(GTK_ALIGNMENT(label_alignment),
- 0, 0, kLeftLabelMargin, 0);
- gtk_container_add(GTK_CONTAINER(label_alignment), source_label_);
- gtk_box_pack_start(GTK_BOX(shelf_), label_alignment, FALSE, FALSE, 0);
-
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-
- // Create a button to dismiss the balloon and add it to the toolbar.
- close_button_.reset(CustomDrawButton::CloseButtonBar(theme_service_));
- close_button_->SetBackground(
- SK_ColorBLACK,
- rb.GetImageNamed(IDR_CLOSE_1).AsBitmap(),
- rb.GetImageNamed(IDR_CLOSE_1_MASK).AsBitmap());
- gtk_widget_set_tooltip_text(close_button_->widget(), dismiss_text.c_str());
- g_signal_connect(close_button_->widget(), "clicked",
- G_CALLBACK(OnCloseButtonThunk), this);
- gtk_widget_set_can_focus(close_button_->widget(), FALSE);
- GtkWidget* close_alignment = gtk_alignment_new(0.0, 0.5, 0, 0);
- gtk_container_add(GTK_CONTAINER(close_alignment), close_button_->widget());
- gtk_box_pack_end(GTK_BOX(shelf_), close_alignment, FALSE, FALSE,
- kButtonSpacing);
-
- // Create a button for showing the options menu, and add it to the toolbar.
- options_menu_button_.reset(new CustomDrawButton(IDR_BALLOON_WRENCH,
- IDR_BALLOON_WRENCH_P,
- IDR_BALLOON_WRENCH_H,
- 0));
- gtk_widget_set_tooltip_text(options_menu_button_->widget(),
- options_text.c_str());
- g_signal_connect(options_menu_button_->widget(), "button-press-event",
- G_CALLBACK(OnOptionsMenuButtonThunk), this);
- gtk_widget_set_can_focus(options_menu_button_->widget(), FALSE);
- GtkWidget* options_alignment = gtk_alignment_new(0.0, 0.5, 0, 0);
- gtk_container_add(GTK_CONTAINER(options_alignment),
- options_menu_button_->widget());
- gtk_box_pack_end(GTK_BOX(shelf_), options_alignment, FALSE, FALSE, 0);
-
- // Add main contents to bubble.
- GtkWidget* alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
- gtk_alignment_set_padding(
- GTK_ALIGNMENT(alignment),
- kTopMargin, kBottomMargin, kLeftMargin, kRightMargin);
- gtk_widget_show_all(alignment);
- gtk_container_add(GTK_CONTAINER(alignment), contents);
- gtk_container_add(GTK_CONTAINER(vbox), alignment);
- gtk_widget_show_all(vbox);
-
- notification_registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
- content::Source<ThemeService>(theme_service_));
-
- // We don't do InitThemesFor() because it just forces a redraw.
- gtk_util::ActAsRoundedWindow(frame_container_, ui::kGdkBlack, 3,
- gtk_util::ROUNDED_ALL,
- gtk_util::BORDER_ALL);
-
- // Realize the frame container so we can do size calculations.
- gtk_widget_realize(frame_container_);
-
- // Update to make sure we have everything sized properly and then move our
- // window offscreen for its initial animation.
- html_contents_->UpdateActualSize(balloon_->content_size());
- int window_width;
- gtk_window_get_size(GTK_WINDOW(frame_container_), &window_width, NULL);
-
- int pos_x = gdk_screen_width() - window_width - kScreenBorder;
- int pos_y = gdk_screen_height();
- gtk_window_move(GTK_WINDOW(frame_container_), pos_x, pos_y);
- balloon_->SetPosition(gfx::Point(pos_x, pos_y), false);
- gtk_widget_show_all(frame_container_);
-
- notification_registrar_.Add(this,
- chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED,
- content::Source<Balloon>(balloon));
-}
-
-void BalloonViewImpl::Update() {
- DCHECK(html_contents_.get()) << "BalloonView::Update called before Show";
- if (!html_contents_->web_contents())
- return;
- html_contents_->web_contents()->GetController().LoadURL(
- balloon_->notification().content_url(), content::Referrer(),
- content::PAGE_TRANSITION_LINK, std::string());
-}
-
-gfx::Point BalloonViewImpl::GetContentsOffset() const {
- return gfx::Point(kLeftShadowWidth + kLeftMargin,
- GetShelfHeight() + kTopShadowWidth + kTopMargin);
-}
-
-int BalloonViewImpl::GetShelfHeight() const {
- // TODO(johnnyg): add scaling here.
- return kDefaultShelfHeight;
-}
-
-int BalloonViewImpl::GetDesiredTotalWidth() const {
- return balloon_->content_size().width() +
- kLeftMargin + kRightMargin + kLeftShadowWidth + kRightShadowWidth;
-}
-
-int BalloonViewImpl::GetDesiredTotalHeight() 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();
- int x = 0, y = 0;
- gtk_window_get_position(GTK_WINDOW(frame_container_), &x, &y);
- return gfx::Rect(x + offset.x(), y + offset.y(),
- content_size.width(), content_size.height());
-}
-
-void BalloonViewImpl::Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- if (type == chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED) {
- // 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,
- chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED,
- content::Source<Balloon>(balloon_));
- Close(false);
- } else if (type == chrome::NOTIFICATION_BROWSER_THEME_CHANGED) {
- // Since all the buttons change their own properties, and our expose does
- // all the real differences, we'll need a redraw.
- gtk_widget_queue_draw(frame_container_);
- } else {
- NOTREACHED();
- }
-}
-
-void BalloonViewImpl::OnCloseButton(GtkWidget* widget) {
- Close(true);
-}
-
-// We draw black dots on the bottom left and right corners to fill in the
-// border. Otherwise, the border has a gap because the sharp corners of the
-// HTML view cut off the roundedness of the notification window.
-gboolean BalloonViewImpl::OnContentsExpose(GtkWidget* sender,
- GdkEventExpose* event) {
- TRACE_EVENT0("ui::gtk", "BalloonViewImpl::OnContentsExpose");
- cairo_t* cr = gdk_cairo_create(gtk_widget_get_window(sender));
- gdk_cairo_rectangle(cr, &event->area);
- cairo_clip(cr);
-
- GtkAllocation allocation;
- gtk_widget_get_allocation(sender, &allocation);
-
- // According to a discussion on a mailing list I found, these degenerate
- // paths are the officially supported way to draw points in Cairo.
- cairo_set_source_rgb(cr, 0, 0, 0);
- cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
- cairo_set_line_width(cr, 1.0);
- cairo_move_to(cr, 0.5, allocation.height - 0.5);
- cairo_close_path(cr);
- cairo_move_to(cr, allocation.width - 0.5, allocation.height - 0.5);
- cairo_close_path(cr);
- cairo_stroke(cr);
- cairo_destroy(cr);
-
- return FALSE;
-}
-
-gboolean BalloonViewImpl::OnExpose(GtkWidget* sender, GdkEventExpose* event) {
- TRACE_EVENT0("ui::gtk", "BalloonViewImpl::OnExpose");
- cairo_t* cr = gdk_cairo_create(gtk_widget_get_window(sender));
- gdk_cairo_rectangle(cr, &event->area);
- cairo_clip(cr);
-
- gfx::Size content_size = balloon_->content_size();
- gfx::Point offset = GetContentsOffset();
-
- // Draw a background color behind the shelf.
- cairo_set_source_rgb(cr, kShelfBackgroundColorR,
- kShelfBackgroundColorG, kShelfBackgroundColorB);
- cairo_rectangle(cr, kLeftMargin, kTopMargin + 0.5,
- content_size.width() - 0.5, GetShelfHeight());
- cairo_fill(cr);
-
- // Now draw a one pixel line between content and shelf.
- cairo_move_to(cr, offset.x(), offset.y() - 1);
- cairo_line_to(cr, offset.x() + content_size.width(), offset.y() - 1);
- cairo_set_line_width(cr, 0.5);
- cairo_set_source_rgb(cr, kDividerLineColorR,
- kDividerLineColorG, kDividerLineColorB);
- cairo_stroke(cr);
-
- cairo_destroy(cr);
-
- return FALSE;
-}
-
-void BalloonViewImpl::OnOptionsMenuButton(GtkWidget* widget,
- GdkEventButton* event) {
- menu_showing_ = true;
- options_menu_->PopupForWidget(widget, event->button, event->time);
-}
-
-// Called when the menu stops showing.
-void BalloonViewImpl::StoppedShowing() {
- menu_showing_ = false;
- if (pending_close_) {
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(
- &BalloonViewImpl::DelayedClose, weak_factory_.GetWeakPtr(), false));
- }
-}
-
-gboolean BalloonViewImpl::OnDestroy(GtkWidget* widget) {
- frame_container_ = NULL;
- Close(false);
- return FALSE; // Propagate.
-}

Powered by Google App Engine
This is Rietveld 408576698