Commit 1bf7bc00 authored by stevenjb@chromium.org's avatar stevenjb@chromium.org

Change web notifications to show at the top of the list, clean up layout.

This partially addresses http://code.google.com/p/chromium/issues/detail?id=137155 by placing new notifications at the front of the list and rendering newer notifications first.
This also greatly simplifes the layout code for web notifications.
It also fixes a bug where notifications were not getting redrawn correctly when the shelf alignment was changed.

BUG=137155
TEST=New web notifications should show up at the top of the list. The list should size correctly as new notifications arrive, scrolling when the max size is reached, showing up to 99 notifications in the list.
R=sadrul@chromium.org


Review URL: https://chromiumcodereview.appspot.com/10833041

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148991 0039d316-1c4b-4281-b951-d872f2087c98
parent 0229effa
......@@ -502,7 +502,7 @@ void SystemTray::UpdateNotificationBubble() {
void SystemTray::UpdateNotificationAnchor() {
if (!notification_bubble_.get())
return;
notification_bubble_->bubble_view()->UpdateAnchor();
notification_bubble_->bubble_view()->UpdateBubble();
// Ensure that the notification buble is above the launcher/status area.
notification_bubble_->bubble_view()->GetWidget()->StackAtTop();
}
......@@ -533,6 +533,13 @@ void SystemTray::SetShelfAlignment(ShelfAlignment alignment) {
UpdateAfterShelfAlignmentChange(alignment);
SetBorder();
tray_container_->UpdateLayout(alignment);
// Destroy an existing bubble so that it is rebuilt correctly.
bubble_.reset();
// Rebuild any notification bubble.
if (notification_bubble_.get()) {
notification_bubble_.reset();
UpdateNotificationBubble();
}
}
bool SystemTray::PerformAction(const views::Event& event) {
......
......@@ -245,7 +245,7 @@ void TrayBubbleView::SetBubbleBorder(int arrow_offset) {
SizeToContents();
}
void TrayBubbleView::UpdateAnchor() {
void TrayBubbleView::UpdateBubble() {
SizeToContents();
GetWidget()->GetRootView()->SchedulePaint();
}
......
......@@ -68,8 +68,8 @@ class TrayBubbleView : public views::BubbleDelegateView {
// Creates a bubble border with the specified arrow offset.
void SetBubbleBorder(int arrow_offset);
// Called whenever the bubble anchor location may have moved.
void UpdateAnchor();
// Called whenever the bubble size or location may have moved.
void UpdateBubble();
// Sets the maximum bubble height and resizes the bubble.
void SetMaxHeight(int height);
......
......@@ -43,7 +43,7 @@ const int kNotificationImageIconInset = 4;
// Web Notification Bubble constants
const int kWebNotificationBubbleMinHeight = 80;
const int kWebNotificationBubbleMaxHeight = 400;
const int kWebNotificationBubbleMaxHeight = 480;
// Delay laying out the Bubble until all notifications have been added and icons
// have had a chance to load.
const int kUpdateDelayMs = 50;
......@@ -51,7 +51,7 @@ const int kUpdateDelayMs = 50;
const int kMaxVisibleNotifications = 100;
// Individual notifications constants
const int kWebNotificationWidth = 400;
const int kWebNotificationWidth = 320;
const int kWebNotificationButtonWidth = 32;
const int kWebNotificationIconSize = 40;
......@@ -124,7 +124,7 @@ class WebNotificationList {
iter->display_source = display_source;
iter->extension_id = extension_id;
} else {
notifications_.push_back(
notifications_.push_front(
WebNotification(id, title, message, display_source, extension_id));
}
}
......@@ -342,7 +342,8 @@ class WebNotificationView : public views::View,
views::ColumnSet* columns = layout->AddColumnSet(0);
columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal/2);
int padding_width = kTrayPopupPaddingHorizontal/2;
columns->AddPaddingColumn(0, padding_width);
// Notification Icon.
columns->AddColumn(views::GridLayout::CENTER, views::GridLayout::LEADING,
......@@ -350,14 +351,16 @@ class WebNotificationView : public views::View,
views::GridLayout::FIXED,
kWebNotificationIconSize, kWebNotificationIconSize);
columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal/2);
columns->AddPaddingColumn(0, padding_width);
// Notification message text.
int message_width = kWebNotificationWidth - kWebNotificationIconSize -
kWebNotificationButtonWidth - (padding_width * 3);
columns->AddColumn(views::GridLayout::FILL, views::GridLayout::LEADING,
100, /* resize percent */
views::GridLayout::USE_PREF, 0, 0);
views::GridLayout::FIXED, message_width, message_width);
columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal/2);
columns->AddPaddingColumn(0, padding_width);
// Close and menu buttons.
columns->AddColumn(views::GridLayout::CENTER, views::GridLayout::LEADING,
......@@ -499,6 +502,7 @@ class WebNotificationTray::BubbleContentsView : public views::View {
scroll_content_ = new views::View;
scroll_content_->SetLayoutManager(
new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1));
scroller_ = new internal::FixedSizedScrollView;
scroller_->SetContentsView(scroll_content_);
AddChildView(scroller_);
......@@ -509,36 +513,16 @@ class WebNotificationTray::BubbleContentsView : public views::View {
void Update(const WebNotificationList::Notifications& notifications) {
scroll_content_->RemoveAllChildViews(true);
int num_children = notifications.size();
WebNotificationList::Notifications::const_iterator iter =
notifications.begin();
if (num_children > kMaxVisibleNotifications) {
std::advance(iter, num_children - kMaxVisibleNotifications);
num_children = kMaxVisibleNotifications;
}
for (; iter != notifications.end(); ++iter) {
int num_children = 0;
for (WebNotificationList::Notifications::const_iterator iter =
notifications.begin(); iter != notifications.end(); ++iter) {
WebNotificationView* view = new WebNotificationView(tray_, *iter);
scroll_content_->AddChildView(view);
if (++num_children >= kMaxVisibleNotifications)
break;
}
// Layout this first to set the preferred size of the scroller.
PreferredSizeChanged();
Layout();
// Now layout the widget with this correctly sized.
PreferredSizeChanged();
GetWidget()->GetRootView()->Layout();
GetWidget()->GetRootView()->SchedulePaint();
// Scroll to show the most recent notification.
if (num_children > 0) {
scroll_content_->ScrollRectToVisible(
scroll_content_->child_at(num_children - 1)->bounds());
}
}
// Overridden from views::View:
virtual void Layout() OVERRIDE {
SizeScrollContent();
views::View::Layout();
GetWidget()->GetRootView()->SchedulePaint();
}
private:
......@@ -549,13 +533,9 @@ class WebNotificationTray::BubbleContentsView : public views::View {
std::max(scroll_size.height(),
kWebNotificationBubbleMinHeight - button_height),
kWebNotificationBubbleMaxHeight - button_height);
if (scroll_height < scroll_size.height()) {
scroll_size.set_height(scroll_height);
scroller_->SetFixedSize(scroll_size);
} else {
scroller_->SetFixedSize(gfx::Size());
}
scroller_->InvalidateLayout();
scroll_size.set_height(scroll_height);
scroller_->SetFixedSize(scroll_size);
scroller_->SizeToPreferredSize();
}
WebNotificationTray* tray_;
......@@ -659,6 +639,7 @@ class WebNotificationTray::Bubble : public internal::TrayBubbleView::Host,
void UpdateBubbleView() {
contents_view_->Update(tray_->notification_list()->notifications());
bubble_view_->Show();
bubble_view_->UpdateBubble();
}
WebNotificationTray* tray_;
......@@ -817,6 +798,8 @@ void WebNotificationTray::SetShelfAlignment(ShelfAlignment alignment) {
alignment == SHELF_ALIGNMENT_BOTTOM ?
views::BoxLayout::kHorizontal : views::BoxLayout::kVertical,
0, 0, 0));
// Destroy any existing bubble so that it will be rebuilt correctly.
bubble_.reset();
}
bool WebNotificationTray::PerformAction(const views::Event& event) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment