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

Unified Diff: chrome/browser/chromeos/notifications/notification_panel.cc

Issue 9664072: Removing WmIpc and related files from ChromeOS (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Copyright Created 8 years, 9 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/chromeos/notifications/notification_panel.cc
diff --git a/chrome/browser/chromeos/notifications/notification_panel.cc b/chrome/browser/chromeos/notifications/notification_panel.cc
deleted file mode 100644
index 49d6a01722dd196fbf1f6847cca543e371f688cb..0000000000000000000000000000000000000000
--- a/chrome/browser/chromeos/notifications/notification_panel.cc
+++ /dev/null
@@ -1,897 +0,0 @@
-// Copyright (c) 2011 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.
-
-// Draws the view for the balloons.
-
-#include "chrome/browser/chromeos/notifications/notification_panel.h"
-
-#include <algorithm>
-
-#include "base/bind.h"
-#include "chrome/browser/chromeos/notifications/balloon_collection_impl.h"
-#include "chrome/browser/chromeos/notifications/balloon_view.h"
-#include "chrome/common/chrome_notification_types.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_source.h"
-#include "grit/generated_resources.h"
-#include "third_party/cros_system_api/window_manager/chromeos_wm_ipc_enums.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/canvas.h"
-#include "ui/views/background.h"
-#include "ui/views/controls/native/native_view_host.h"
-#include "ui/views/controls/scroll_view.h"
-#include "ui/views/widget/native_widget_gtk.h"
-
-#define SET_STATE(state) SetState(state, __PRETTY_FUNCTION__)
-
-using views::Widget;
-
-namespace {
-// Minimum and maximum size of balloon content.
-const int kBalloonMinWidth = 300;
-const int kBalloonMaxWidth = 300;
-const int kBalloonMinHeight = 24;
-const int kBalloonMaxHeight = 120;
-
-// Maximum height of the notification panel.
-// TODO(oshima): Get this from system's metrics.
-const int kMaxPanelHeight = 400;
-
-// The duration for a new notification to become stale.
-const int kStaleTimeoutInSeconds = 10;
-
-// Panel Background color
-const SkColor kPanelBackground = 0xFFEEEEEE;
-
-using chromeos::BalloonViewImpl;
-using chromeos::NotificationPanel;
-
-#if !defined(NDEBUG)
-// A utility function to convert State enum to string.
-const char* ToStr(const NotificationPanel::State state) {
- switch (state) {
- case NotificationPanel::FULL:
- return "full";
- case NotificationPanel::KEEP_SIZE:
- return "keep_size";
- case NotificationPanel::STICKY_AND_NEW:
- return "sticky_new";
- case NotificationPanel::MINIMIZED:
- return "minimized";
- case NotificationPanel::CLOSED:
- return "closed";
- default:
- return "unknown";
- }
-}
-#endif
-
-chromeos::BalloonViewImpl* GetBalloonViewOf(const Balloon* balloon) {
- return static_cast<chromeos::BalloonViewImpl*>(balloon->view());
-}
-
-// A Widget that covers entire ScrollView's viewport. Without this, all
-// renderer's native gtk widgets are moved one by one via
-// View::VisibleBoundsInRootChanged() notification, which makes scrolling not
-// smooth.
-class ViewportWidget : public views::Widget {
- public:
- explicit ViewportWidget(chromeos::NotificationPanel* panel)
- : panel_(panel),
- pointer_inside_panel_(false) {
- }
-
- void UpdateControl() {
- if (pointer_inside_panel_)
- panel_->OnMouseMotion(last_point_);
- }
-
- // views::Widget overrides:
- virtual bool OnMouseEvent(const views::MouseEvent& event) OVERRIDE {
- bool result = Widget::OnMouseEvent(event);
- switch (event.type()) {
- case ui::ET_MOUSE_MOVED:
- OnMouseMoved(event);
- break;
- case ui::ET_MOUSE_EXITED:
- OnMouseExited(event);
- break;
- default:
- break;
- }
- return result;
- }
-
- private:
- void OnMouseMoved(const views::MouseEvent& event) {
- // Convert the point to the panel's coordinate system.
- Widget* top_level_widget = GetTopLevelWidget();
- // TODO: remove cast when this extends Widget.
- DCHECK(top_level_widget != static_cast<Widget*>(this));
- gfx::Rect panel_rect(event.location(), gfx::Size());
- Widget::ConvertRect(this, top_level_widget, &panel_rect);
- last_point_ = panel_rect.origin();
- pointer_inside_panel_ = true;
- panel_->OnMouseMotion(last_point_);
- }
-
- void OnMouseExited(const views::MouseEvent& event) {
- // Filter gtk's fake mouse leave events that are issued when
- // window activation changes.
- if (event.location().x() == 0 && event.location().y() == 0)
- return;
-
- // Leave notify can happen if the mouse moves into the child gdk window.
- // Make sure the mouse is outside of the panel.
- gfx::Rect bounds = GetWindowScreenBounds();
- if (!bounds.Contains(event.location().x() + bounds.x(),
- event.location().y() + bounds.y())) {
- panel_->OnMouseLeave();
- pointer_inside_panel_ = false;
- }
- }
-
- private:
- chromeos::NotificationPanel* panel_;
- gfx::Point last_point_;
- bool pointer_inside_panel_;
-
- DISALLOW_COPY_AND_ASSIGN(ViewportWidget);
-};
-
-class BalloonSubContainer : public views::View {
- public:
- explicit BalloonSubContainer(int margin)
- : margin_(margin) {
- }
-
- virtual ~BalloonSubContainer() {}
-
- // views::View overrides.
- virtual gfx::Size GetPreferredSize() {
- return preferred_size_;
- }
-
- virtual void Layout() {
- // Layout bottom up
- int height = 0;
- for (int i = child_count() - 1; i >= 0; --i) {
- views::View* child = child_at(i);
- child->SetBounds(0, height, child->width(), child->height());
- height += child->height() + margin_;
- }
- SchedulePaint();
- }
-
- // Updates the bound so that it can show all balloons.
- void UpdateBounds() {
- int height = 0;
- int max_width = 0;
- for (int i = child_count() - 1; i >= 0; --i) {
- views::View* child = child_at(i);
- height += child->height() + margin_;
- max_width = std::max(max_width, child->width());
- }
- if (height > 0)
- height -= margin_;
- preferred_size_.set_width(max_width);
- preferred_size_.set_height(height);
- SizeToPreferredSize();
- }
-
- // Returns the bounds that covers new notifications.
- gfx::Rect GetNewBounds() {
- gfx::Rect rect;
- for (int i = child_count() - 1; i >= 0; --i) {
- BalloonViewImpl* view = static_cast<BalloonViewImpl*>(child_at(i));
- if (!view->stale()) {
- if (rect.IsEmpty()) {
- rect = view->bounds();
- } else {
- rect = rect.Union(view->bounds());
- }
- }
- }
- return gfx::Rect(x(), y(), rect.width(), rect.height());
- }
-
- // Returns # of new notifications.
- int GetNewCount() {
- int count = 0;
- for (int i = child_count() - 1; i >= 0; --i) {
- BalloonViewImpl* view = static_cast<BalloonViewImpl*>(child_at(i));
- if (!view->stale())
- count++;
- }
- return count;
- }
-
- // Make all notifications stale.
- void MakeAllStale() {
- for (int i = child_count() - 1; i >= 0; --i) {
- BalloonViewImpl* view = static_cast<BalloonViewImpl*>(child_at(i));
- view->set_stale();
- }
- }
-
- void DismissAll() {
- for (int i = child_count() - 1; i >= 0; --i) {
- BalloonViewImpl* view = static_cast<BalloonViewImpl*>(child_at(i));
- view->Close(true);
- }
- }
-
- BalloonViewImpl* FindBalloonView(const Notification& notification) {
- for (int i = child_count() - 1; i >= 0; --i) {
- BalloonViewImpl* view = static_cast<BalloonViewImpl*>(child_at(i));
- if (view->IsFor(notification)) {
- return view;
- }
- }
- return NULL;
- }
-
- BalloonViewImpl* FindBalloonView(const gfx::Point point) {
- gfx::Point copy(point);
- ConvertPointFromWidget(this, &copy);
- for (int i = child_count() - 1; i >= 0; --i) {
- views::View* view = child_at(i);
- if (view->bounds().Contains(copy))
- return static_cast<BalloonViewImpl*>(view);
- }
- return NULL;
- }
-
- // Returns true if the |view| is in the container.
- // |view| can be a deleted pointer - we do not dereference it.
- bool HasChildView(View* view) const {
- for (int i = 0; i < child_count(); ++i) {
- if (child_at(i) == view)
- return true;
- }
- return false;
- }
-
- private:
- gfx::Size preferred_size_;
- int margin_;
-
- DISALLOW_COPY_AND_ASSIGN(BalloonSubContainer);
-};
-
-} // namespace
-
-namespace chromeos {
-
-class BalloonContainer : public views::View {
- public:
- explicit BalloonContainer(int margin)
- : margin_(margin),
- sticky_container_(new BalloonSubContainer(margin)),
- non_sticky_container_(new BalloonSubContainer(margin)) {
- AddChildView(sticky_container_);
- AddChildView(non_sticky_container_);
- }
- virtual ~BalloonContainer() {}
-
- // views::View overrides.
- virtual void Layout() {
- int margin =
- (sticky_container_->child_count() != 0 &&
- non_sticky_container_->child_count() != 0) ?
- margin_ : 0;
- sticky_container_->SetBounds(
- 0, 0, width(), sticky_container_->height());
- non_sticky_container_->SetBounds(
- 0, sticky_container_->bounds().bottom() + margin,
- width(), non_sticky_container_->height());
- }
-
- virtual gfx::Size GetPreferredSize() {
- return preferred_size_;
- }
-
- // Returns the size that covers sticky and new notifications.
- gfx::Size GetStickyNewSize() {
- gfx::Rect sticky = sticky_container_->bounds();
- gfx::Rect new_non_sticky = non_sticky_container_->GetNewBounds();
- if (sticky.IsEmpty())
- return new_non_sticky.size();
- if (new_non_sticky.IsEmpty())
- return sticky.size();
- return sticky.Union(new_non_sticky).size();
- }
-
- // Adds a ballon to the panel.
- void Add(Balloon* balloon) {
- BalloonViewImpl* view = GetBalloonViewOf(balloon);
- GetContainerFor(balloon)->AddChildView(view);
- }
-
- // Updates the position of the |balloon|.
- bool Update(Balloon* balloon) {
- BalloonViewImpl* view = GetBalloonViewOf(balloon);
- View* container = NULL;
- if (view->parent() == sticky_container_) {
- container = sticky_container_;
- } else if (view->parent() == non_sticky_container_) {
- container = non_sticky_container_;
- }
- if (container) {
- container->RemoveChildView(view);
- container->AddChildView(view);
- return true;
- } else {
- return false;
- }
- }
-
- // Removes a ballon from the panel.
- BalloonViewImpl* Remove(Balloon* balloon) {
- BalloonViewImpl* view = GetBalloonViewOf(balloon);
- GetContainerFor(balloon)->RemoveChildView(view);
- return view;
- }
-
- // Returns the number of notifications added to the panel.
- int GetNotificationCount() {
- return sticky_container_->child_count() +
- non_sticky_container_->child_count();
- }
-
- // Returns the # of new notifications.
- int GetNewNotificationCount() {
- return sticky_container_->GetNewCount() +
- non_sticky_container_->GetNewCount();
- }
-
- // Returns the # of sticky and new notifications.
- int GetStickyNewNotificationCount() {
- return sticky_container_->child_count() +
- non_sticky_container_->GetNewCount();
- }
-
- // Returns the # of sticky notifications.
- int GetStickyNotificationCount() {
- return sticky_container_->child_count();
- }
-
- // Returns true if the |view| is contained in the panel.
- // |view| can be a deleted pointer - we do not dereference it.
- bool HasBalloonView(View* view) {
- return sticky_container_->HasChildView(view) ||
- non_sticky_container_->HasChildView(view);
- }
-
- // Updates the bounds so that all notifications are visible.
- void UpdateBounds() {
- sticky_container_->UpdateBounds();
- non_sticky_container_->UpdateBounds();
- preferred_size_ = sticky_container_->GetPreferredSize();
-
- gfx::Size non_sticky_size = non_sticky_container_->GetPreferredSize();
- int margin =
- (!preferred_size_.IsEmpty() && !non_sticky_size.IsEmpty()) ?
- margin_ : 0;
- preferred_size_.Enlarge(0, non_sticky_size.height() + margin);
- preferred_size_.set_width(std::max(
- preferred_size_.width(), non_sticky_size.width()));
- SizeToPreferredSize();
- }
-
- void MakeAllStale() {
- sticky_container_->MakeAllStale();
- non_sticky_container_->MakeAllStale();
- }
-
- void DismissAllNonSticky() {
- non_sticky_container_->DismissAll();
- }
-
- BalloonViewImpl* FindBalloonView(const Notification& notification) {
- BalloonViewImpl* view = sticky_container_->FindBalloonView(notification);
- return view ? view : non_sticky_container_->FindBalloonView(notification);
- }
-
- BalloonViewImpl* FindBalloonView(const gfx::Point& point) {
- BalloonViewImpl* view = sticky_container_->FindBalloonView(point);
- return view ? view : non_sticky_container_->FindBalloonView(point);
- }
-
- private:
- BalloonSubContainer* GetContainerFor(Balloon* balloon) const {
- BalloonViewImpl* view = GetBalloonViewOf(balloon);
- return view->sticky() ?
- sticky_container_ : non_sticky_container_;
- }
-
- int margin_;
- // Sticky/non-sticky ballon containers. They're child views and
- // deleted when this container is deleted.
- BalloonSubContainer* sticky_container_;
- BalloonSubContainer* non_sticky_container_;
- gfx::Size preferred_size_;
-
- DISALLOW_COPY_AND_ASSIGN(BalloonContainer);
-};
-
-NotificationPanel::NotificationPanel()
- : balloon_container_(NULL),
- panel_widget_(NULL),
- container_host_(NULL),
- state_(CLOSED),
- min_bounds_(0, 0, kBalloonMinWidth, kBalloonMinHeight),
- stale_timeout_(1000 * kStaleTimeoutInSeconds),
- active_(NULL),
- scroll_to_(NULL) {
- Init();
-}
-
-NotificationPanel::~NotificationPanel() {
- Hide();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NotificationPanel public.
-
-void NotificationPanel::Show() {
- if (!panel_widget_) {
- panel_widget_ = new views::Widget;
- // TODO(oshima): Using window because Popup widget behaves weird
- // when resizing. This needs to be investigated.
- Widget::InitParams params(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
- // Enable double buffering because the panel has both pure views
- // control and native controls (scroll bar).
- params.double_buffer = true;
-
- gfx::Rect bounds = GetPreferredBounds();
- bounds = bounds.Union(min_bounds_);
- params.bounds = bounds;
- panel_widget_->Init(params);
- // Set minimum bounds so that it can grow freely.
- gtk_widget_set_size_request(GTK_WIDGET(panel_widget_->GetNativeView()),
- min_bounds_.width(), min_bounds_.height());
-
- views::NativeViewHost* native = new views::NativeViewHost();
- scroll_view_->SetContents(native);
-
- panel_widget_->SetContentsView(scroll_view_.get());
-
-#if defined(USE_AURA)
- native->AttachToView(balloon_container_.get());
-#else
- // Add the view port after scroll_view is attached to the panel widget.
- ViewportWidget* viewport_widget = new ViewportWidget(this);
- container_host_ = viewport_widget;
- container_host_->Init(
- views::Widget::InitParams(views::Widget::InitParams::TYPE_CONTROL));
- container_host_->SetContentsView(balloon_container_.get());
- // The window_contents_ is onwed by the Widget. Increase ref count
- // so that window_contents does not get deleted when detached.
- g_object_ref(viewport_widget->GetNativeView());
- native->Attach(viewport_widget->GetNativeView());
-#endif
- UnregisterNotification();
- panel_controller_.reset(
- new PanelController(this, GTK_WINDOW(panel_widget_->GetNativeView())));
- panel_controller_->Init(false /* don't focus when opened */,
- gfx::Rect(0, 0, kBalloonMinWidth, 1), 0,
- WM_IPC_PANEL_USER_RESIZE_VERTICALLY);
- registrar_.Add(this, chrome::NOTIFICATION_PANEL_STATE_CHANGED,
- content::Source<PanelController>(panel_controller_.get()));
- }
- panel_widget_->Show();
-}
-
-void NotificationPanel::Hide() {
- balloon_container_->DismissAllNonSticky();
- if (panel_widget_) {
- if (container_host_)
- container_host_->GetRootView()->RemoveChildView(balloon_container_.get());
-
- views::NativeViewHost* native =
- static_cast<views::NativeViewHost*>(scroll_view_->GetContents());
- native->Detach();
- scroll_view_->SetContents(NULL);
- if (container_host_) {
- container_host_->Hide();
- container_host_->CloseNow();
- container_host_ = NULL;
- }
-
- UnregisterNotification();
- panel_controller_->Close();
- MessageLoop::current()->DeleteSoon(FROM_HERE, panel_controller_.release());
- // We need to remove & detach the scroll view from hierarchy to
- // avoid GTK deleting child.
- // TODO(oshima): handle this details in NativeWidgetGtk.
- panel_widget_->GetRootView()->RemoveChildView(scroll_view_.get());
- panel_widget_->Close();
- panel_widget_ = NULL;
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// BalloonCollectionImpl::NotificationUI overrides.
-
-void NotificationPanel::Add(Balloon* balloon) {
- balloon_container_->Add(balloon);
- if (state_ == CLOSED || state_ == MINIMIZED)
- SET_STATE(STICKY_AND_NEW);
- Show();
- // Don't resize the panel yet. The panel will be resized when WebKit tells
- // the size in ResizeNotification.
- UpdatePanel(false);
- UpdateControl();
- StartStaleTimer(balloon);
- scroll_to_ = balloon;
-}
-
-bool NotificationPanel::Update(Balloon* balloon) {
- return balloon_container_->Update(balloon);
-}
-
-void NotificationPanel::Remove(Balloon* balloon) {
- BalloonViewImpl* view = balloon_container_->Remove(balloon);
- if (view == active_)
- active_ = NULL;
- if (scroll_to_ == balloon)
- scroll_to_ = NULL;
-
- // TODO(oshima): May be we shouldn't close
- // if the mouse pointer is still on the panel.
- if (balloon_container_->GetNotificationCount() == 0)
- SET_STATE(CLOSED);
- // no change to the state
- if (state_ == KEEP_SIZE) {
- // Just update the content.
- UpdateContainerBounds();
- } else {
- if (state_ != CLOSED &&
- balloon_container_->GetStickyNewNotificationCount() == 0)
- SET_STATE(MINIMIZED);
- UpdatePanel(true);
- }
- UpdateControl();
-}
-
-void NotificationPanel::Show(Balloon* balloon) {
- if (state_ == CLOSED || state_ == MINIMIZED)
- SET_STATE(STICKY_AND_NEW);
- Show();
- UpdatePanel(true);
- StartStaleTimer(balloon);
- ScrollBalloonToVisible(balloon);
-}
-
-void NotificationPanel::ResizeNotification(
- Balloon* balloon, const gfx::Size& size) {
- // restrict to the min & max sizes
- gfx::Size real_size(
- std::max(kBalloonMinWidth,
- std::min(kBalloonMaxWidth, size.width())),
- std::max(kBalloonMinHeight,
- std::min(kBalloonMaxHeight, size.height())));
-
- // Don't allow balloons to shrink. This avoids flickering
- // which sometimes rapidly reports alternating sizes. Special
- // case for setting the minimum value.
- gfx::Size old_size = balloon->content_size();
- if (real_size.width() > old_size.width() ||
- real_size.height() > old_size.height() ||
- real_size == min_bounds_.size()) {
- balloon->set_content_size(real_size);
- GetBalloonViewOf(balloon)->Layout();
- UpdatePanel(true);
- if (scroll_to_ == balloon) {
- ScrollBalloonToVisible(scroll_to_);
- scroll_to_ = NULL;
- }
- }
-}
-
-void NotificationPanel::SetActiveView(BalloonViewImpl* view) {
- // Don't change the active view if it's same notification,
- // or the notification is being closed.
- if (active_ == view || (view && view->closed()))
- return;
- if (active_)
- active_->Deactivated();
- active_ = view;
- if (active_)
- active_->Activated();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// PanelController overrides.
-
-string16 NotificationPanel::GetPanelTitle() {
- return string16(l10n_util::GetStringUTF16(IDS_NOTIFICATION_PANEL_TITLE));
-}
-
-SkBitmap NotificationPanel::GetPanelIcon() {
- return SkBitmap();
-}
-
-bool NotificationPanel::CanClosePanel() {
- return true;
-}
-
-void NotificationPanel::ClosePanel() {
- SET_STATE(CLOSED);
- UpdatePanel(false);
-}
-
-void NotificationPanel::ActivatePanel() {
- if (active_)
- active_->Activated();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// content::NotificationObserver overrides.
-
-void NotificationPanel::Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- DCHECK(type == chrome::NOTIFICATION_PANEL_STATE_CHANGED);
- PanelController::State* state =
- reinterpret_cast<PanelController::State*>(details.map_key());
- switch (*state) {
- case PanelController::EXPANDED:
- // Geting expanded in STICKY_AND_NEW or in KEEP_SIZE state means
- // that a new notification is added, so just leave the
- // state. Otherwise, expand to full.
- if (state_ != STICKY_AND_NEW && state_ != KEEP_SIZE)
- SET_STATE(FULL);
- // When the panel is to be expanded, we either show all, or
- // show only sticky/new, depending on the state.
- UpdatePanel(false);
- break;
- case PanelController::MINIMIZED:
- SET_STATE(MINIMIZED);
- // Make all notifications stale when a user minimize the panel.
- balloon_container_->MakeAllStale();
- break;
- case PanelController::INITIAL:
- NOTREACHED() << "Transition to Initial state should not happen";
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// PanelController public.
-
-void NotificationPanel::OnMouseLeave() {
- SetActiveView(NULL);
- if (balloon_container_->GetNotificationCount() == 0)
- SET_STATE(CLOSED);
- UpdatePanel(true);
-}
-
-void NotificationPanel::OnMouseMotion(const gfx::Point& point) {
- SetActiveView(balloon_container_->FindBalloonView(point));
- // We need to set the focus to scroll view to get mouse wheel
- // working. Setting focus when mouse moves on the panel
- // because focus may be taken by other view.
- scroll_view_->RequestFocus();
- // This method used to set KEEP_SIZE state. However,
- // some html notifications may want to change their size,
- // and setting KEEP_SIZE caused them to behave differently
- // depending on whether user moved mouse over notification
- // or not.
-}
-
-NotificationPanelTester* NotificationPanel::GetTester() {
- if (!tester_.get())
- tester_.reset(new NotificationPanelTester(this));
- return tester_.get();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NotificationPanel private.
-
-void NotificationPanel::Init() {
- DCHECK(!panel_widget_);
- balloon_container_.reset(new BalloonContainer(1));
- balloon_container_->set_parent_owned(false);
- balloon_container_->set_background(
- views::Background::CreateSolidBackground(kPanelBackground));
-
- scroll_view_.reset(new views::ScrollView());
- scroll_view_->set_focusable(true);
- scroll_view_->set_parent_owned(false);
- scroll_view_->set_background(
- views::Background::CreateSolidBackground(SK_ColorWHITE));
-}
-
-void NotificationPanel::UnregisterNotification() {
- if (panel_controller_.get()) {
- registrar_.Remove(
- this, chrome::NOTIFICATION_PANEL_STATE_CHANGED,
- content::Source<PanelController>(panel_controller_.get()));
- }
-}
-
-void NotificationPanel::ScrollBalloonToVisible(Balloon* balloon) {
- BalloonViewImpl* view = GetBalloonViewOf(balloon);
- if (!view->closed()) {
- // We can't use View::ScrollRectToVisible because the viewport is not
- // ancestor of the BalloonViewImpl.
- // Use Widget's coordinate which is same as viewport's coordinates.
- gfx::Point p(0, 0);
- views::View::ConvertPointToWidget(view, &p);
- gfx::Rect visible_rect(p.x(), p.y(), view->width(), view->height());
- scroll_view_->ScrollContentsRegionToBeVisible(visible_rect);
- }
-}
-
-void NotificationPanel::UpdatePanel(bool update_container_size) {
- if (update_container_size)
- UpdateContainerBounds();
- switch (state_) {
- case KEEP_SIZE: {
- gfx::Rect min_bounds = GetPreferredBounds();
- gfx::Rect panel_bounds = panel_widget_->GetWindowScreenBounds();
- if (min_bounds.height() < panel_bounds.height())
- panel_widget_->SetBounds(min_bounds);
- else if (min_bounds.height() > panel_bounds.height()) {
- // need scroll bar
- int width = balloon_container_->width() +
- scroll_view_->GetScrollBarWidth();
- panel_bounds.set_width(width);
- panel_widget_->SetBounds(panel_bounds);
- }
-
- // no change.
- break;
- }
- case CLOSED:
- Hide();
- break;
- case MINIMIZED:
- balloon_container_->MakeAllStale();
- if (panel_controller_.get())
- panel_controller_->SetState(PanelController::MINIMIZED);
- break;
- case FULL:
- if (panel_widget_) {
- panel_widget_->SetBounds(GetPreferredBounds());
- panel_controller_->SetState(PanelController::EXPANDED);
- }
- break;
- case STICKY_AND_NEW:
- if (panel_widget_) {
- panel_widget_->SetBounds(GetStickyNewBounds());
- panel_controller_->SetState(PanelController::EXPANDED);
- }
- break;
- }
-}
-
-void NotificationPanel::UpdateContainerBounds() {
- balloon_container_->UpdateBounds();
- views::NativeViewHost* native =
- static_cast<views::NativeViewHost*>(scroll_view_->GetContents());
- // Update from WebKit may arrive after the panel is closed/hidden
- // and viewport widget is detached.
- if (native) {
- native->SetBoundsRect(balloon_container_->bounds());
- scroll_view_->Layout();
- }
-}
-
-void NotificationPanel::UpdateControl() {
- if (container_host_)
- static_cast<ViewportWidget*>(container_host_)->UpdateControl();
-}
-
-gfx::Rect NotificationPanel::GetPreferredBounds() {
- gfx::Size pref_size = balloon_container_->GetPreferredSize();
- int new_height = std::min(pref_size.height(), kMaxPanelHeight);
- int new_width = pref_size.width();
- // Adjust the width to avoid showing a horizontal scroll bar.
- if (new_height != pref_size.height()) {
- new_width += scroll_view_->GetScrollBarWidth();
- }
- return gfx::Rect(0, 0, new_width, new_height).Union(min_bounds_);
-}
-
-gfx::Rect NotificationPanel::GetStickyNewBounds() {
- gfx::Size pref_size = balloon_container_->GetPreferredSize();
- gfx::Size sticky_size = balloon_container_->GetStickyNewSize();
- int new_height = std::min(sticky_size.height(), kMaxPanelHeight);
- int new_width = pref_size.width();
- // Adjust the width to avoid showing a horizontal scroll bar.
- if (new_height != pref_size.height())
- new_width += scroll_view_->GetScrollBarWidth();
- return gfx::Rect(0, 0, new_width, new_height).Union(min_bounds_);
-}
-
-void NotificationPanel::StartStaleTimer(Balloon* balloon) {
- BalloonViewImpl* view = GetBalloonViewOf(balloon);
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&NotificationPanel::OnStale, AsWeakPtr(), view),
- stale_timeout_);
-}
-
-void NotificationPanel::OnStale(BalloonViewImpl* view) {
- // Note: |view| may point to deleted memory.
- if (balloon_container_->HasBalloonView(view) && !view->stale()) {
- view->set_stale();
- // don't update panel on stale
- if (state_ == KEEP_SIZE)
- return;
- if (balloon_container_->GetStickyNewNotificationCount() > 0) {
- SET_STATE(STICKY_AND_NEW);
- } else {
- SET_STATE(MINIMIZED);
- }
- UpdatePanel(false);
- }
-}
-
-void NotificationPanel::SetState(State new_state, const char* name) {
-#if !defined(NDEBUG)
- DVLOG(1) << "state transition " << ToStr(state_) << " >> " << ToStr(new_state)
- << " in " << name;
-#endif
- state_ = new_state;
-}
-
-void NotificationPanel::MarkStale(const Notification& notification) {
- BalloonViewImpl* view = balloon_container_->FindBalloonView(notification);
- DCHECK(view);
- OnStale(view);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NotificationPanelTester public.
-
-int NotificationPanelTester::GetNotificationCount() const {
- return panel_->balloon_container_->GetNotificationCount();
-}
-
-int NotificationPanelTester::GetStickyNotificationCount() const {
- return panel_->balloon_container_->GetStickyNotificationCount();
-}
-
-int NotificationPanelTester::GetNewNotificationCount() const {
- return panel_->balloon_container_->GetNewNotificationCount();
-}
-
-void NotificationPanelTester::SetStaleTimeout(int timeout) {
- panel_->stale_timeout_ = timeout;
-}
-
-void NotificationPanelTester::MarkStale(const Notification& notification) {
- panel_->MarkStale(notification);
-}
-
-PanelController* NotificationPanelTester::GetPanelController() const {
- return panel_->panel_controller_.get();
-}
-
-BalloonViewImpl* NotificationPanelTester::GetBalloonView(
- BalloonCollectionImpl* collection,
- const Notification& notification) {
- Balloon* balloon = collection->FindBalloon(notification);
- DCHECK(balloon);
- return GetBalloonViewOf(balloon);
-}
-
-bool NotificationPanelTester::IsVisible(const BalloonViewImpl* view) const {
- gfx::Rect rect = panel_->scroll_view_->GetVisibleRect();
- gfx::Point origin(0, 0);
- views::View::ConvertPointToView(view, panel_->balloon_container_.get(),
- &origin);
- return rect.Contains(gfx::Rect(origin, view->size()));
-}
-
-
-bool NotificationPanelTester::IsActive(const BalloonViewImpl* view) const {
- return panel_->active_ == view;
-}
-
-} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698