// 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. // Draws the view for the balloons. #include "chrome/browser/chromeos/notifications/notification_panel.h" #include "app/gfx/canvas.h" #include "app/l10n_util.h" #include "app/resource_bundle.h" #include "base/singleton.h" #include "chrome/browser/chromeos/notifications/balloon_view.h" #include "grit/generated_resources.h" #include "views/background.h" #include "views/widget/widget_gtk.h" namespace chromeos { class BalloonContainer : public views::View { public: explicit BalloonContainer(int margin) : View(), margin_(margin) { } virtual ~BalloonContainer() {} // views::View overrides. virtual gfx::Size GetPreferredSize() { return preferred_size_; } virtual void Layout() { // Layout bottom up int count = GetChildViewCount(); int height = 0; for (int i = count - 1; i >= 0; --i) { views::View* child = GetChildViewAt(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 = GetChildViewCount() - 1; i >= 0; --i) { views::View* c = GetChildViewAt(i); height += c->height() + margin_; max_width = std::max(max_width, c->width()); } if (height > 0) height -= margin_; preferred_size_.set_width(max_width); preferred_size_.set_height(height); PreferredSizeChanged(); SizeToPreferredSize(); } private: gfx::Size preferred_size_; int margin_; }; // static NotificationPanel* NotificationPanel::Get() { return Singleton<NotificationPanel>::get(); } NotificationPanel::NotificationPanel() : panel_widget_(NULL) { Init(); } NotificationPanel::~NotificationPanel() { } gfx::Rect NotificationPanel::GetPanelBounds() { gfx::Size pref_size = balloon_container_->GetPreferredSize(); int new_height = pref_size.height(); return gfx::Rect(0, 0, pref_size.width(), new_height); } void NotificationPanel::Init() { DCHECK(!panel_widget_.get()); balloon_container_ = new BalloonContainer(1); balloon_container_->set_parent_owned(false); balloon_container_->set_background( views::Background::CreateSolidBackground(ResourceBundle::frame_color)); } void NotificationPanel::Add(BalloonViewImpl* view) { balloon_container_->AddChildView(view); balloon_container_->UpdateBounds(); balloon_container_->Layout(); if (panel_widget_.get()) { panel_widget_->SetBounds(GetPanelBounds()); } } void NotificationPanel::Remove(BalloonViewImpl* view) { balloon_container_->RemoveChildView(view); balloon_container_->UpdateBounds(); balloon_container_->Layout(); if (panel_widget_.get()) { if (balloon_container_->GetChildViewCount() == 0) { Hide(); } else { panel_widget_->SetBounds(GetPanelBounds()); } } } void NotificationPanel::Show() { if (!panel_widget_.get()) { // TODO(oshima): Using window because Popup widget behaves weird // when resizing. This needs to be investigated. panel_widget_.reset(new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW)); panel_widget_->Init(NULL, GetPanelBounds()); panel_widget_->SetContentsView(balloon_container_); panel_controller_.reset( new PanelController(this, GTK_WINDOW(panel_widget_->GetNativeView()), gfx::Rect(0, 0, 1000, 1000))); } panel_widget_->Show(); } void NotificationPanel::Hide() { if (panel_widget_.get()) { panel_widget_.release()->Close(); panel_controller_.release()->Close(); } } string16 NotificationPanel::GetPanelTitle() { return string16(l10n_util::GetStringUTF16(IDS_NOTIFICATION_PANEL_TITLE)); } SkBitmap NotificationPanel::GetPanelIcon() { return SkBitmap(); } void NotificationPanel::ClosePanel() { panel_widget_.release()->Close(); } } // namespace chromeos