Commit 0db5e968 authored by dewittj@chromium.org's avatar dewittj@chromium.org

Reland 220500: Adds the contextMessage field to notifications.

This is a field displayed in an alternate font that adds an extra line
of information about the notification.

BUG=276004

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@220688 0039d316-1c4b-4281-b951-d872f2087c98
parent 5f4c1ed7
......@@ -284,6 +284,9 @@ bool NotificationsApiFunction::CreateNotification(
UTF8ToUTF16(*options->expanded_message);
}
if (options->context_message)
optional_fields.context_message = UTF8ToUTF16(*options->context_message);
bool has_image = NotificationBitmapToGfxImage(options->image_bitmap.get(),
&optional_fields.image);
// We should have an image if and only if the type is an image type.
......@@ -384,6 +387,9 @@ bool NotificationsApiFunction::UpdateNotification(
}
}
if (options->context_message)
notification->set_context_message(UTF8ToUTF16(*options->context_message));
if (options->expanded_message) {
notification->set_expanded_message(
UTF8ToUTF16(*options->expanded_message));
......
......@@ -53,6 +53,9 @@ namespace notifications {
// Main notification content.
DOMString? message;
// Alternate notification content with a lower-weight font.
DOMString? contextMessage;
// Priority ranges from -2 to 2. -2 is lowest priority. 2 is highest. Zero
// is default.
long? priority;
......
......@@ -46,6 +46,9 @@ MESSAGE_CENTER_EXPORT
// Body text of the message. Hidden for list notifications.
base::scoped_nsobject<NSTextField> message_;
// Context-giving text of the message. Alternate font used to distinguish it.
base::scoped_nsobject<NSTextField> contextMessage_;
// Container for optional list item views.
base::scoped_nsobject<NSView> listItemView_;
......
......@@ -203,6 +203,9 @@
// Initializes message_ in the given frame.
- (void)configureBodyInFrame:(NSRect)rootFrame;
// Initializes contextMessage_ in the given frame.
- (void)configureContextMessageInFrame:(NSRect)rootFrame;
// Creates a NSTextField that the caller owns configured as a label in a
// notification.
- (NSTextField*)newLabelWithFrame:(NSRect)frame;
......@@ -260,6 +263,10 @@
[self configureBodyInFrame:rootFrame];
[rootView addSubview:message_];
// Create the context message body.
[self configureContextMessageInFrame:rootFrame];
[rootView addSubview:contextMessage_];
// Populate the data.
[self updateNotification:notification_];
}
......@@ -285,9 +292,15 @@
CGFloat messageTopGap =
roundf([[message_ font] ascender] - [[message_ font] capHeight]);
CGFloat messageBottomGap = roundf(fabs([[message_ font] descender]));
CGFloat messagePadding =
message_center::kTextTopPadding - titleBottomGap - messageTopGap;
CGFloat contextMessageTopGap = roundf(
[[contextMessage_ font] ascender] - [[contextMessage_ font] capHeight]);
CGFloat contextMessagePadding =
message_center::kTextTopPadding - messageBottomGap - contextMessageTopGap;
// Set the title and recalculate the frame.
[title_ setStringValue:base::SysUTF16ToNSString(
[self wrapText:notification_->title()
......@@ -300,26 +313,50 @@
// Set the message and recalculate the frame.
[message_ setStringValue:base::SysUTF16ToNSString(
[self wrapText:notification_->message()
forField:title_
forField:message_
maxNumberOfLines:message_center::kMessageExpandedLineLimit])];
[message_ setHidden:NO];
[message_ sizeToFit];
NSRect messageFrame = [message_ frame];
messageFrame.origin.y =
NSMinY(titleFrame) - messagePadding - NSHeight(messageFrame);
messageFrame.size.height = NSHeight([message_ frame]);
// Create the list item views (up to a maximum).
[listItemView_ removeFromSuperview];
// If there are list items, then the message_ view should not be displayed.
const std::vector<message_center::NotificationItem>& items =
notification->items();
NSRect listFrame = NSZeroRect;
if (items.size() > 0) {
// If there are list items, then the message_ view should not be displayed.
[message_ setHidden:YES];
messageFrame.origin.y = titleFrame.origin.y;
messageFrame.size.height = 0;
} else {
[message_ setHidden:NO];
messageFrame.origin.y =
NSMinY(titleFrame) - messagePadding - NSHeight(messageFrame);
messageFrame.size.height = NSHeight([message_ frame]);
}
// Set the context message and recalculate the frame.
[contextMessage_ setStringValue:base::SysUTF16ToNSString(
[self wrapText:notification_->context_message()
forField:contextMessage_
maxNumberOfLines:message_center::kContextMessageLineLimit])];
[contextMessage_ sizeToFit];
NSRect contextMessageFrame = [contextMessage_ frame];
if (notification_->context_message().empty()) {
[contextMessage_ setHidden:YES];
contextMessageFrame.origin.y = messageFrame.origin.y;
contextMessageFrame.size.height = 0;
} else {
[contextMessage_ setHidden:NO];
contextMessageFrame.origin.y =
NSMinY(messageFrame) -
contextMessagePadding -
NSHeight(contextMessageFrame);
contextMessageFrame.size.height = NSHeight([contextMessage_ frame]);
}
// Create the list item views (up to a maximum).
[listItemView_ removeFromSuperview];
NSRect listFrame = NSZeroRect;
if (items.size() > 0) {
listFrame = [self currentContentRect];
listFrame.origin.y = 0;
listFrame.size.height = 0;
......@@ -348,10 +385,10 @@
}
// TODO(thakis): The spacing is not completely right.
CGFloat listTopPadding =
message_center::kTextTopPadding - messageTopGap;
message_center::kTextTopPadding - contextMessageTopGap;
listFrame.size.height = y;
listFrame.origin.y =
NSMinY(titleFrame) - listTopPadding - NSHeight(listFrame);
NSMinY(contextMessageFrame) - listTopPadding - NSHeight(listFrame);
[listItemView_ setFrame:listFrame];
[[self view] addSubview:listItemView_];
}
......@@ -361,7 +398,7 @@
NSRect progressBarFrame = NSZeroRect;
if (notification->type() == message_center::NOTIFICATION_TYPE_PROGRESS) {
progressBarFrame = [self currentContentRect];
progressBarFrame.origin.y = NSMinY(messageFrame) -
progressBarFrame.origin.y = NSMinY(contextMessageFrame) -
message_center::kProgressBarTopPadding -
message_center::kProgressBarThickness;
progressBarFrame.size.height = message_center::kProgressBarThickness;
......@@ -376,7 +413,7 @@
// If the bottom-most element so far is out of the rootView's bounds, resize
// the view.
CGFloat minY = NSMinY(messageFrame);
CGFloat minY = NSMinY(contextMessageFrame);
if (listItemView_ && NSMinY(listFrame) < minY)
minY = NSMinY(listFrame);
if (progressBarView_ && NSMinY(progressBarFrame) < minY)
......@@ -386,6 +423,7 @@
rootFrame.size.height += delta;
titleFrame.origin.y += delta;
messageFrame.origin.y += delta;
contextMessageFrame.origin.y += delta;
listFrame.origin.y += delta;
progressBarFrame.origin.y += delta;
}
......@@ -456,6 +494,7 @@
rootFrame.size.height += NSHeight(frame);
titleFrame.origin.y += NSHeight(frame);
messageFrame.origin.y += NSHeight(frame);
contextMessageFrame.origin.y += NSHeight(frame);
listFrame.origin.y += NSHeight(frame);
progressBarFrame.origin.y += NSHeight(frame);
......@@ -467,6 +506,7 @@
rootFrame.size.height += bottomAdjust;
titleFrame.origin.y += bottomAdjust;
messageFrame.origin.y += bottomAdjust;
contextMessageFrame.origin.y += bottomAdjust;
listFrame.origin.y += bottomAdjust;
progressBarFrame.origin.y += bottomAdjust;
}
......@@ -474,6 +514,7 @@
[[self view] setFrame:rootFrame];
[title_ setFrame:titleFrame];
[message_ setFrame:messageFrame];
[contextMessage_ setFrame:contextMessageFrame];
[listItemView_ setFrame:listFrame];
[progressBarView_ setFrame:progressBarFrame];
......@@ -611,11 +652,22 @@
message_.reset([self newLabelWithFrame:frame]);
[message_ setAutoresizingMask:NSViewMinYMargin];
[message_ setTextColor:gfx::SkColorToCalibratedNSColor(
message_center::kDimTextColor)];
message_center::kRegularTextColor)];
[message_ setFont:
[NSFont messageFontOfSize:message_center::kMessageFontSize]];
}
- (void)configureContextMessageInFrame:(NSRect)rootFrame {
NSRect frame = [self currentContentRect];
frame.size.height = 0;
contextMessage_.reset([self newLabelWithFrame:frame]);
[contextMessage_ setAutoresizingMask:NSViewMinYMargin];
[contextMessage_ setTextColor:gfx::SkColorToCalibratedNSColor(
message_center::kDimTextColor)];
[contextMessage_ setFont:
[NSFont messageFontOfSize:message_center::kMessageFontSize]];
}
- (NSTextField*)newLabelWithFrame:(NSRect)frame {
NSTextField* label = [[NSTextField alloc] initWithFrame:frame];
[label setDrawsBackground:NO];
......
......@@ -84,6 +84,10 @@ class MockMessageCenter : public message_center::FakeMessageCenter {
return message_.get();
}
- (NSTextField*)contextMessageView {
return contextMessage_.get();
}
- (NSView*)listItemView {
return listItemView_.get();
}
......@@ -272,6 +276,7 @@ TEST_F(NotificationControllerTest, List) {
UTF8ToUTF16("Second title"),
UTF8ToUTF16("second slightly longer message"));
optional.items.push_back(item2);
optional.context_message = UTF8ToUTF16("Context Message");
scoped_ptr<message_center::Notification> notification(
new message_center::Notification(
......@@ -293,6 +298,7 @@ TEST_F(NotificationControllerTest, List) {
EXPECT_FALSE([[controller titleView] isHidden]);
EXPECT_TRUE([[controller messageView] isHidden]);
EXPECT_FALSE([[controller contextMessageView] isHidden]);
EXPECT_EQ(2u, [[[controller listItemView] subviews] count]);
EXPECT_LT(NSMaxY([[controller listItemView] frame]),
......
......@@ -76,7 +76,8 @@ class PopupCollectionTest : public ui::CocoaTest {
"that has a much longer body "
"than the other notifications. It "
"may not fit on the screen if we "
"set the screen size too small."),
"set the screen size too small or "
"if the notification is way too big"),
gfx::Image(),
string16(),
message_center::NotifierId(),
......
......@@ -42,8 +42,8 @@ const int kMessageLineHeight = 18;
// Colors.
const SkColor kNotificationBackgroundColor = SkColorSetRGB(255, 255, 255);
const SkColor kLegacyIconBackgroundColor = SkColorSetRGB(0xf5, 0xf5, 0xf5);
const SkColor kRegularTextColor = SkColorSetRGB(34, 34, 34);
const SkColor kDimTextColor = SkColorSetRGB(102, 102, 102);
const SkColor kRegularTextColor = SkColorSetRGB(0x22, 0x22, 0x22);
const SkColor kDimTextColor = SkColorSetRGB(0x66, 0x66, 0x66);
const SkColor kFocusBorderColor = SkColorSetRGB(64, 128, 250);
// Limits.
......
......@@ -43,10 +43,10 @@ extern const int kIconBottomPadding; // Minimum non-zero V space between icon
// and frame.
// Text sizes.
extern const int kTitleFontSize; // For title only.
extern const int kTitleLineHeight; // In DIPs.
extern const int kMessageFontSize; // For everything but title.
extern const int kMessageLineHeight; // In DIPs.
extern const int kTitleFontSize; // For title only.
extern const int kTitleLineHeight; // In DIPs.
extern const int kMessageFontSize; // For everything but title.
extern const int kMessageLineHeight; // In DIPs.
// Colors.
extern const SkColor kNotificationBackgroundColor; // Background of the card.
......@@ -54,7 +54,7 @@ extern const SkColor kLegacyIconBackgroundColor; // Used behind icons smaller.
// than the icon view.
extern const SkColor kRegularTextColor; // Title, message, ...
extern const SkColor kDimTextColor;
extern const SkColor kFocusBorderColor; // The focus border.
extern const SkColor kFocusBorderColor; // The focus border.
// Limits.
......@@ -91,6 +91,7 @@ const SkColor kProgressBarSliceColor = SkColorSetRGB(120, 120, 120);
const int kTitleLineLimit = 3;
const int kMessageCollapsedLineLimit = 3;
const int kMessageExpandedLineLimit = 7;
const int kContextMessageLineLimit = 1;
// Around notifications ////////////////////////////////////////////////////////
......
......@@ -36,6 +36,7 @@ RichNotificationData::RichNotificationData(const RichNotificationData& other)
never_timeout(other.never_timeout),
timestamp(other.timestamp),
expanded_message(other.expanded_message),
context_message(other.context_message),
image(other.image),
items(other.items),
progress(other.progress),
......
......@@ -43,6 +43,7 @@ class MESSAGE_CENTER_EXPORT RichNotificationData {
bool never_timeout;
base::Time timestamp;
string16 expanded_message;
string16 context_message;
gfx::Image image;
std::vector<NotificationItem> items;
int progress;
......@@ -102,6 +103,13 @@ class MESSAGE_CENTER_EXPORT Notification {
optional_fields_.expanded_message = expanded_message;
}
const string16& context_message() const {
return optional_fields_.context_message;
}
void set_context_message(const string16& context_message) {
optional_fields_.context_message = context_message;
}
const std::vector<NotificationItem>& items() const {
return optional_fields_.items;
}
......
......@@ -53,12 +53,16 @@ const size_t kTitleCharacterLimit =
const size_t kMessageCharacterLimit =
message_center::kNotificationWidth *
message_center::kMessageExpandedLineLimit / 3;
const size_t kContextMessageCharacterLimit =
message_center::kNotificationWidth *
message_center::kContextMessageLineLimit / 3;
// Notification colors. The text background colors below are used only to keep
// view::Label from modifying the text color and will not actually be drawn.
// See view::Label's RecalculateColors() for details.
const SkColor kRegularTextBackgroundColor = SK_ColorWHITE;
const SkColor kDimTextBackgroundColor = SK_ColorWHITE;
const SkColor kContextTextBackgroundColor = SK_ColorWHITE;
// static
views::Background* MakeBackground(
......@@ -486,13 +490,32 @@ NotificationView::NotificationView(const Notification& notification,
ui::TruncateString(notification.message(), kMessageCharacterLimit));
message_view_->SetLineHeight(kMessageLineHeight);
message_view_->SetVisible(!is_expanded() || !notification.items().size());
message_view_->SetColors(message_center::kDimTextColor,
message_view_->SetColors(message_center::kRegularTextColor,
kDimTextBackgroundColor);
message_view_->set_border(MakeTextBorder(padding, 4, 0));
top_view_->AddChildView(message_view_);
accessible_lines.push_back(notification.message());
}
// Create the context message view if appropriate.
context_message_view_ = NULL;
if (!notification.context_message().empty()) {
gfx::Font font = views::Label().font();
int padding = kMessageLineHeight - font.GetHeight();
context_message_view_ =
new BoundedLabel(ui::TruncateString(notification.context_message(),
kContextMessageCharacterLimit),
font);
context_message_view_->SetLineLimit(
message_center::kContextMessageLineLimit);
context_message_view_->SetLineHeight(kMessageLineHeight);
context_message_view_->SetColors(message_center::kDimTextColor,
kContextTextBackgroundColor);
context_message_view_->set_border(MakeTextBorder(padding, 4, 0));
top_view_->AddChildView(context_message_view_);
accessible_lines.push_back(notification.context_message());
}
// Create the progress bar view.
progress_bar_view_ = NULL;
if (notification.type() == NOTIFICATION_TYPE_PROGRESS) {
......
......@@ -71,6 +71,7 @@ class MESSAGE_CENTER_EXPORT NotificationView : public MessageView {
views::View* top_view_;
BoundedLabel* title_view_;
BoundedLabel* message_view_;
BoundedLabel* context_message_view_;
std::vector<views::View*> item_views_;
views::View* icon_view_;
views::View* bottom_view_;
......
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