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

Unified Diff: ash/system/user/tray_user.cc

Issue 11377133: Customize user details in ash system bubble for public account mode (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments addressed. Created 8 years, 1 month 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
« no previous file with comments | « ash/system/user/tray_user.h ('k') | chrome/browser/chromeos/system/ash_system_tray_delegate.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ash/system/user/tray_user.cc
diff --git a/ash/system/user/tray_user.cc b/ash/system/user/tray_user.cc
index 1a4a0ee6b826fc497a51d59797398c06080bdec3..b782954e5e9dda29a9f57d0922c468b9c683dcce 100644
--- a/ash/system/user/tray_user.cc
+++ b/ash/system/user/tray_user.cc
@@ -4,37 +4,75 @@
#include "ash/system/user/tray_user.h"
+#include <algorithm>
+#include <climits>
+#include <vector>
+
#include "ash/shell.h"
#include "ash/system/tray/system_tray.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/tray/tray_constants.h"
#include "ash/system/tray/tray_item_view.h"
#include "ash/system/tray/tray_views.h"
+#include "base/i18n/rtl.h"
+#include "base/logging.h"
+#include "base/memory/scoped_vector.h"
+#include "base/string16.h"
+#include "base/string_util.h"
#include "base/utf_string_conversions.h"
+#include "grit/ash_resources.h"
#include "grit/ash_strings.h"
#include "skia/ext/image_operations.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/range/range.h"
#include "ui/base/resource/resource_bundle.h"
+#include "ui/base/text/text_elider.h"
#include "ui/gfx/canvas.h"
+#include "ui/gfx/font.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia_operations.h"
+#include "ui/gfx/insets.h"
+#include "ui/gfx/rect.h"
+#include "ui/gfx/render_text.h"
#include "ui/gfx/size.h"
#include "ui/gfx/skia_util.h"
+#include "ui/views/border.h"
+#include "ui/views/controls/button/border_images.h"
#include "ui/views/controls/button/button.h"
-#include "ui/views/controls/button/text_button.h"
+#include "ui/views/controls/button/custom_button.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
+#include "ui/views/controls/link.h"
+#include "ui/views/controls/link_listener.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
namespace {
-const int kUserInfoVerticalPadding = 10;
-const int kUserIconSize = 27;
+const int kUserDetailsVerticalPadding = 5;
+const int kUserCardVerticalPadding = 10;
const int kProfileRoundedCornerRadius = 2;
+const int kUserIconSize = 27;
+
+// The invisible word joiner character, used as a marker to indicate the start
+// and end of the user's display name in the public account user card's text.
+const char16 kDisplayNameMark[] = { 0x2060 };
+
+const int kPublicAccountLogoutButtonBorderImagesNormal[] = {
+ IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER,
+ IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
+ IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
+ IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER,
+ IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
+ IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
+ IDR_AURA_TRAY_POPUP_PUBLIC_ACCOUNT_LOGOUT_BUTTON_BORDER,
+ IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
+ IDR_AURA_TRAY_POPUP_LABEL_BUTTON_NORMAL_BACKGROUND,
+};
} // namespace
@@ -48,49 +86,18 @@ class RoundedImageView : public views::View {
public:
// Constructs a new rounded image view with rounded corners of radius
// |corner_radius|.
- explicit RoundedImageView(int corner_radius) : corner_radius_(corner_radius) {
- }
-
- virtual ~RoundedImageView() {
- }
+ explicit RoundedImageView(int corner_radius);
+ virtual ~RoundedImageView();
// Set the image that should be displayed from a pointer. The pointer
// contents is copied in the receiver's image.
- void SetImage(const gfx::ImageSkia& img, const gfx::Size& size) {
- image_ = img;
- image_size_ = size;
-
- // Try to get the best image quality for the avatar.
- resized_ = gfx::ImageSkiaOperations::CreateResizedImage(image_,
- skia::ImageOperations::RESIZE_BEST, size);
- if (GetWidget() && visible()) {
- PreferredSizeChanged();
- SchedulePaint();
- }
- }
+ void SetImage(const gfx::ImageSkia& img, const gfx::Size& size);
+ private:
// Overridden from views::View.
- virtual gfx::Size GetPreferredSize() OVERRIDE {
- return gfx::Size(image_size_.width() + GetInsets().width(),
- image_size_.height() + GetInsets().height());
- }
-
- virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
- View::OnPaint(canvas);
- gfx::Rect image_bounds(size());
- image_bounds.ClampToCenteredSize(GetPreferredSize());
- image_bounds.Inset(GetInsets());
- const SkScalar kRadius = SkIntToScalar(corner_radius_);
- SkPath path;
- path.addRoundRect(gfx::RectToSkRect(image_bounds), kRadius, kRadius);
- SkPaint paint;
- paint.setAntiAlias(true);
- paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
- canvas->DrawImageInPath(resized_, image_bounds.x(), image_bounds.y(),
- path, paint);
- }
+ virtual gfx::Size GetPreferredSize() OVERRIDE;
+ virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
- private:
gfx::ImageSkia image_;
gfx::ImageSkia resized_;
gfx::Size image_size_;
@@ -99,144 +106,405 @@ class RoundedImageView : public views::View {
DISALLOW_COPY_AND_ASSIGN(RoundedImageView);
};
+// The user details shown in public account mode. This is essentially a label
+// but with custom painting code as the text is styled with multiple colors and
+// contains a link.
+class PublicAccountUserDetails : public views::View,
+ public views::LinkListener {
+ public:
+ PublicAccountUserDetails(SystemTrayItem* owner, int used_width);
+ virtual ~PublicAccountUserDetails();
+
+ private:
+ // Overridden from views::LinkListener.
+ virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
+
+ // Overridden from views::View.
+ virtual void Layout() OVERRIDE;
+ virtual gfx::Size GetPreferredSize() OVERRIDE { return preferred_size_; };
+ virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
+
+ // Calculate a preferred size that ensures the label text and the following
+ // link do not wrap over more than three lines in total for aesthetic reasons
+ // if possible.
+ void CalculatePreferredSize(SystemTrayItem* owner, int used_width);
+
+ string16 text_;
+ views::Link* learn_more_;
+ gfx::Font font_;
+ gfx::Size preferred_size_;
+ ScopedVector<gfx::RenderText> lines_;
+
+ DISALLOW_COPY_AND_ASSIGN(PublicAccountUserDetails);
+};
+
class UserView : public views::View,
public views::ButtonListener {
public:
- explicit UserView(ash::user::LoginStatus login)
- : login_(login),
- user_info_(NULL),
- username_(NULL),
- email_(NULL),
- signout_(NULL) {
- CHECK(login_ != ash::user::LOGGED_IN_NONE);
-
- bool public_account = login_ == ash::user::LOGGED_IN_PUBLIC;
- bool guest = login_ == ash::user::LOGGED_IN_GUEST;
- bool locked = login_ == ash::user::LOGGED_IN_LOCKED;
-
- set_background(views::Background::CreateSolidBackground(
- public_account ? kPublicAccountBackgroundColor : kBackgroundColor));
-
- if (!guest)
- AddUserInfo();
-
- // A user should not be able to modify logged in state when screen is
- // locked.
- if (!locked)
- AddButtonContainer();
- }
+ explicit UserView(SystemTrayItem* owner, ash::user::LoginStatus login);
+ virtual ~UserView();
+
+ private:
+ // Overridden from views::View.
+ virtual gfx::Size GetPreferredSize() OVERRIDE;
+ virtual void Layout() OVERRIDE;
+
+ // Overridden from views::ButtonListener.
+ virtual void ButtonPressed(views::Button* sender,
+ const ui::Event& event) OVERRIDE;
+
+ void AddLogoutButton(ash::user::LoginStatus login);
+ void AddUserCard(SystemTrayItem* owner, ash::user::LoginStatus login);
+
+ views::View* user_card_;
+ views::View* logout_button_;
- virtual ~UserView() {}
+ DISALLOW_COPY_AND_ASSIGN(UserView);
+};
+
+RoundedImageView::RoundedImageView(int corner_radius)
+ : corner_radius_(corner_radius) {}
+
+RoundedImageView::~RoundedImageView() {}
+
+void RoundedImageView::SetImage(const gfx::ImageSkia& img,
+ const gfx::Size& size) {
+ image_ = img;
+ image_size_ = size;
- // Create container for buttons.
- void AddButtonContainer() {
- TrayPopupLabelButton* button = new TrayPopupLabelButton(this,
- ash::user::GetLocalizedSignOutStringForStatus(login_, true));
- AddChildView(button);
- signout_ = button;
+ // Try to get the best image quality for the avatar.
+ resized_ = gfx::ImageSkiaOperations::CreateResizedImage(image_,
+ skia::ImageOperations::RESIZE_BEST, size);
+ if (GetWidget() && visible()) {
+ PreferredSizeChanged();
+ SchedulePaint();
}
+}
- private:
- void AddUserInfo() {
- user_info_ = new views::View;
- user_info_->SetLayoutManager(new views::BoxLayout(
- views::BoxLayout::kHorizontal, kTrayPopupPaddingHorizontal,
- kUserInfoVerticalPadding, kTrayPopupPaddingBetweenItems));
- AddChildView(user_info_);
-
- if (login_ == ash::user::LOGGED_IN_KIOSK) {
- views::Label* label = new views::Label;
- ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
- label->SetText(
- bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_KIOSK_LABEL));
- label->set_border(views::Border::CreateEmptyBorder(
- 0, 4, 0, 1));
- label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
- user_info_->AddChildView(label);
- return;
+gfx::Size RoundedImageView::GetPreferredSize() {
+ return gfx::Size(image_size_.width() + GetInsets().width(),
+ image_size_.height() + GetInsets().height());
+}
+
+void RoundedImageView::OnPaint(gfx::Canvas* canvas) {
+ View::OnPaint(canvas);
+ gfx::Rect image_bounds(size());
+ image_bounds.ClampToCenteredSize(GetPreferredSize());
+ image_bounds.Inset(GetInsets());
+ const SkScalar kRadius = SkIntToScalar(corner_radius_);
+ SkPath path;
+ path.addRoundRect(gfx::RectToSkRect(image_bounds), kRadius, kRadius);
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
+ canvas->DrawImageInPath(resized_, image_bounds.x(), image_bounds.y(),
+ path, paint);
+}
+
+PublicAccountUserDetails::PublicAccountUserDetails(SystemTrayItem* owner,
+ int used_width)
+ : learn_more_(NULL),
+ font_(ResourceBundle::GetSharedInstance().GetFont(
+ ResourceBundle::BaseFont)) {
+ const int inner_padding =
+ kTrayPopupPaddingHorizontal - kTrayPopupPaddingBetweenItems;
+ const bool rtl = base::i18n::IsRTL();
+ set_border(views::Border::CreateEmptyBorder(
+ kUserDetailsVerticalPadding, rtl ? 0 : inner_padding,
+ kUserDetailsVerticalPadding, rtl ? inner_padding : 0));
+
+ ash::SystemTrayDelegate* delegate =
+ ash::Shell::GetInstance()->tray_delegate();
+ // Retrieve the user's display name and wrap it with markers.
+ string16 display_name = delegate->GetUserDisplayName();
+ ReplaceChars(display_name, kDisplayNameMark, string16(), &display_name);
+ display_name.insert(0U, 1U, kDisplayNameMark[0]);
+ display_name.push_back(kDisplayNameMark[0]);
+ // Retrieve the domain managing the device and wrap it with markers.
+ string16 domain = UTF8ToUTF16(delegate->GetEnterpriseDomain());
+ ReplaceChars(domain, kDisplayNameMark, string16(), &domain);
+ base::i18n::WrapStringWithLTRFormatting(&domain);
+ // Retrieve the label text, inserting the display name and domain.
+ text_ = l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_PUBLIC_LABEL,
+ display_name, domain);
+
+ learn_more_ = new views::Link(l10n_util::GetStringUTF16(IDS_ASH_LEARN_MORE));
+ learn_more_->SetUnderline(false);
+ learn_more_->set_listener(this);
+ AddChildView(learn_more_);
+
+ CalculatePreferredSize(owner, used_width);
+}
+
+PublicAccountUserDetails::~PublicAccountUserDetails() {}
+
+void PublicAccountUserDetails::LinkClicked(views::Link* source,
+ int event_flags) {
+ DCHECK_EQ(source, learn_more_);
+ ash::Shell::GetInstance()->tray_delegate()->ShowPublicAccountInfo();
+}
+
+void PublicAccountUserDetails::Layout() {
+ lines_.clear();
+ const gfx::Rect contents_area = GetContentsBounds();
+ if (contents_area.IsEmpty())
+ return;
+
+ // Word-wrap the label text.
+ std::vector<string16> lines;
+ ui::ElideRectangleText(text_, font_, contents_area.width(),
+ contents_area.height(), ui::ELIDE_LONG_WORDS, &lines);
+ // Loop through the lines, creating a renderer for each.
+ gfx::Point position = contents_area.origin();
+ ui::Range display_name(ui::Range::InvalidRange());
+ for (std::vector<string16>::const_iterator it = lines.begin();
+ it != lines.end(); ++it) {
+ gfx::RenderText* line = gfx::RenderText::CreateInstance();
+ line->SetDirectionalityMode(gfx::DIRECTIONALITY_FROM_UI);
+ line->SetText(*it);
+ const gfx::Size size(contents_area.width(), line->GetStringSize().height());
+ line->SetDisplayRect(gfx::Rect(position, size));
+ position.set_y(position.y() + size.height());
+
+ // Set the default text color for the line.
+ gfx::StyleRange default_style(line->default_style());
+ default_style.foreground = kPublicAccountUserCardTextColor;
+ line->set_default_style(default_style);
+ line->ApplyDefaultStyle();
+
+ // If a range of the line contains the user's display name, apply a custom
+ // text color to it.
+ if (display_name.is_empty())
+ display_name.set_start(it->find(kDisplayNameMark));
+ if (!display_name.is_empty()) {
+ display_name.set_end(
+ it->find(kDisplayNameMark, display_name.start() + 1));
+ gfx::StyleRange display_name_style(line->default_style());
+ display_name_style.foreground = kPublicAccountUserCardNameColor;
+ ui::Range line_range(0, it->size());
+ display_name_style.range = display_name.Intersect(line_range);
+ line->ApplyStyleRange(display_name_style);
+ // Update the range for the next line.
+ if (display_name.end() >= line_range.end())
+ display_name.set_start(0);
+ else
+ display_name = ui::Range::InvalidRange();
}
- RoundedImageView* image = new RoundedImageView(kProfileRoundedCornerRadius);
- image->SetImage(ash::Shell::GetInstance()->tray_delegate()->GetUserImage(),
- gfx::Size(kUserIconSize, kUserIconSize));
- user_info_->AddChildView(image);
-
- views::View* user = new views::View;
- user->SetLayoutManager(new views::BoxLayout(
- views::BoxLayout::kVertical, 0, 5, 0));
- ash::SystemTrayDelegate* tray =
- ash::Shell::GetInstance()->tray_delegate();
- username_ = new views::Label(tray->GetUserDisplayName());
- username_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
- user->AddChildView(username_);
-
- email_ = new views::Label(UTF8ToUTF16(tray->GetUserEmail()));
- email_->SetFont(username_->font().DeriveFont(-1));
- email_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
- email_->SetEnabled(false);
- user->AddChildView(email_);
-
- user_info_->AddChildView(user);
+ lines_.push_back(line);
}
- // Overridden from views::ButtonListener.
- virtual void ButtonPressed(views::Button* sender,
- const ui::Event& event) OVERRIDE {
- CHECK(sender == signout_);
- ash::SystemTrayDelegate* tray = ash::Shell::GetInstance()->tray_delegate();
- tray->SignOut();
+ // Position link after the label text, separated by a space. If it does not
+ // fit onto the last line of the text, wrap the link onto its own line.
+ const gfx::Size last_line_size = lines_.back()->GetStringSize();
+ const int space_width = font_.GetStringWidth(ASCIIToUTF16(" "));
+ const gfx::Size link_size = learn_more_->GetPreferredSize();
+ if (contents_area.width() - last_line_size.width() >=
+ space_width + link_size.width()) {
+ position.set_x(position.x() + last_line_size.width() + space_width);
+ position.set_y(position.y() - last_line_size.height());
+ }
+ position.set_y(position.y() - learn_more_->GetInsets().top());
+ gfx::Rect learn_more_bounds(position, link_size);
+ learn_more_bounds.Intersect(contents_area);
+ if (base::i18n::IsRTL()) {
+ const gfx::Insets insets = GetInsets();
+ learn_more_bounds.Offset(insets.right() - insets.left(), 0);
}
+ learn_more_->SetBoundsRect(learn_more_bounds);
+}
- // Overridden from views::View.
- virtual gfx::Size GetPreferredSize() OVERRIDE {
- gfx::Size size;
- if (user_info_)
- size = user_info_->GetPreferredSize();
- if (signout_) {
- gfx::Size signout_size = signout_->GetPreferredSize();
- // Make sure the user default view item at least as tall as the other
- // tray popup items.
- if (size.height() == 0)
- size.set_height(kTrayPopupItemHeight);
- size.set_height(std::max(size.height(), signout_size.height()));
- size.set_width(size.width() + signout_size.width() +
- kTrayPopupPaddingHorizontal * 2 + kTrayPopupPaddingBetweenItems);
- }
- return size;
+void PublicAccountUserDetails::OnPaint(gfx::Canvas* canvas) {
+ for (ScopedVector<gfx::RenderText>::const_iterator it = lines_.begin();
+ it != lines_.end(); ++it) {
+ (*it)->Draw(canvas);
}
+ views::View::OnPaint(canvas);
+}
- virtual void Layout() OVERRIDE {
- views::View::Layout();
- if (bounds().IsEmpty())
- return;
-
- if (signout_ && user_info_) {
- gfx::Rect signout_bounds(bounds());
- signout_bounds.ClampToCenteredSize(signout_->GetPreferredSize());
- signout_bounds.set_x(width() - signout_bounds.width() -
- kTrayPopupPaddingHorizontal);
- signout_->SetBoundsRect(signout_bounds);
-
- gfx::Rect usercard_bounds(user_info_->GetPreferredSize());
- usercard_bounds.set_width(signout_bounds.x());
- user_info_->SetBoundsRect(usercard_bounds);
- } else if (signout_) {
- signout_->SetBoundsRect(gfx::Rect(size()));
- } else if (user_info_) {
- user_info_->SetBoundsRect(gfx::Rect(size()));
+void PublicAccountUserDetails::CalculatePreferredSize(SystemTrayItem* owner,
+ int used_width) {
+
+ const gfx::Size link_size = learn_more_->GetPreferredSize();
+ const int space_width = font_.GetStringWidth(ASCIIToUTF16(" "));
+ const gfx::Insets insets = GetInsets();
+ views::TrayBubbleView* bubble_view =
+ owner->system_tray()->GetSystemBubble()->bubble_view();
+ int min_width = std::max(
+ link_size.width(),
+ bubble_view->GetPreferredSize().width() - (used_width + insets.width()));
+ int max_width = std::min(
+ font_.GetStringWidth(text_) + space_width + link_size.width(),
+ bubble_view->GetMaximumSize().width() - (used_width + insets.width()));
+ // Do a binary search for the minimum width that ensures no more than three
+ // lines are needed. The lower bound is the minimum of the current bubble
+ // width and the width of the link (as no wrapping is permitted inside the
+ // link). The upper bound is the maximum of the largest allowed bubble width
+ // and the sum of the label text and link widths when put on a single line.
+ std::vector<string16> lines;
+ while (min_width < max_width) {
+ lines.clear();
+ const int width = (min_width + max_width) / 2;
+ const bool too_narrow = ui::ElideRectangleText(
+ text_, font_, width, INT_MAX, ui::TRUNCATE_LONG_WORDS, &lines);
+ int line_count = lines.size();
+ if (!too_narrow && line_count == 3 &&
+ width - font_.GetStringWidth(lines.back()) <=
+ space_width + link_size.width()) {
+ ++line_count;
}
+ if (too_narrow || line_count > 3)
+ min_width = width + 1;
+ else
+ max_width = width;
}
- user::LoginStatus login_;
+ // Calculate the corresponding height and set the preferred size.
+ lines.clear();
+ ui::ElideRectangleText(
+ text_, font_, min_width, INT_MAX, ui::TRUNCATE_LONG_WORDS, &lines);
+ int line_count = lines.size();
+ if (min_width - font_.GetStringWidth(lines.back()) <=
+ space_width + link_size.width()) {
+ ++line_count;
+ }
+ const int line_height = font_.GetHeight();
+ const int link_extra_height = std::max(
+ link_size.height() - learn_more_->GetInsets().top() - line_height, 0);
+ preferred_size_ = gfx::Size(
+ min_width + insets.width(),
+ line_count * line_height + link_extra_height + insets.height());
+
+ bubble_view->SetWidth(preferred_size_.width() + used_width);
+}
- views::View* user_info_;
- views::Label* username_;
- views::Label* email_;
+UserView::UserView(SystemTrayItem* owner, ash::user::LoginStatus login)
+ : user_card_(NULL),
+ logout_button_(NULL) {
+ CHECK(login != ash::user::LOGGED_IN_NONE);
+ set_background(views::Background::CreateSolidBackground(
+ login == ash::user::LOGGED_IN_PUBLIC ? kPublicAccountBackgroundColor :
+ kBackgroundColor));
+ SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0,
+ kTrayPopupPaddingBetweenItems));
+ AddLogoutButton(login);
+ AddUserCard(owner, login);
+}
- views::Button* signout_;
+UserView::~UserView() {}
- DISALLOW_COPY_AND_ASSIGN(UserView);
-};
+gfx::Size UserView::GetPreferredSize() {
+ gfx::Size size = views::View::GetPreferredSize();
+ if (!user_card_) {
+ // Make sure the default user default view item is at least as tall as the
+ // other items.
+ size.set_height(std::max(size.height(),
+ kTrayPopupItemHeight + GetInsets().height()));
+ }
+ return size;
+}
+
+void UserView::Layout() {
+ gfx::Rect contents_area(GetContentsBounds());
+ if (user_card_ && logout_button_) {
+ // Give the logout button the space it requests.
+ gfx::Rect logout_area = contents_area;
+ logout_area.ClampToCenteredSize(logout_button_->GetPreferredSize());
+ logout_area.set_x(contents_area.right() - logout_area.width());
+ logout_button_->SetBoundsRect(logout_area);
+
+ // Give the remaining space to the user card.
+ gfx::Rect user_card_area = contents_area;
+ user_card_area.set_width(contents_area.width() -
+ (logout_area.width() + kTrayPopupPaddingBetweenItems));
+ user_card_->SetBoundsRect(user_card_area);
+ } else if (user_card_) {
+ user_card_->SetBoundsRect(contents_area);
+ } else if (logout_button_) {
+ logout_button_->SetBoundsRect(contents_area);
+ }
+}
+
+void UserView::ButtonPressed(views::Button* sender, const ui::Event& event) {
+ DCHECK(sender == logout_button_);
+ ash::Shell::GetInstance()->tray_delegate()->SignOut();
+}
+
+void UserView::AddLogoutButton(ash::user::LoginStatus login) {
+ // The logout button must be added before the user card.
+ DCHECK(!user_card_);
+
+ // A user should not be able to modify logged-in state when screen is
+ // locked.
+ if (login == ash::user::LOGGED_IN_LOCKED)
+ return;
+
+ TrayPopupLabelButton* logout_button = new TrayPopupLabelButton(
+ this, ash::user::GetLocalizedSignOutStringForStatus(login, true));
+ // In public account mode, the vertical separator painted by the logout
+ // button's border has a custom color.
+ if (login == ash::user::LOGGED_IN_PUBLIC) {
+ static_cast<TrayPopupLabelButtonBorder*>(logout_button->border())->
+ SetImages(views::CustomButton::STATE_NORMAL,
+ views::BorderImages(kPublicAccountLogoutButtonBorderImagesNormal));
+ }
+ logout_button_ = logout_button;
+ AddChildView(logout_button);
+}
+
+void UserView::AddUserCard(SystemTrayItem* owner,
+ ash::user::LoginStatus login) {
+ if (login == ash::user::LOGGED_IN_GUEST)
+ return;
+
+ set_border(views::Border::CreateEmptyBorder(0, kTrayPopupPaddingHorizontal,
+ 0, kTrayPopupPaddingHorizontal));
+
+ user_card_ = new views::View();
+ user_card_->SetLayoutManager(new views::BoxLayout(
+ views::BoxLayout::kHorizontal, 0, kUserCardVerticalPadding,
+ kTrayPopupPaddingBetweenItems));
+ AddChildViewAt(user_card_, 0);
+
+ if (login == ash::user::LOGGED_IN_KIOSK) {
+ views::Label* details = new views::Label;
+ ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
+ details->SetText(
+ bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_KIOSK_LABEL));
+ details->set_border(views::Border::CreateEmptyBorder(0, 4, 0, 1));
+ details->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+ user_card_->AddChildView(details);
+ return;
+ }
+
+ RoundedImageView* avatar = new RoundedImageView(kProfileRoundedCornerRadius);
+ avatar->SetImage(ash::Shell::GetInstance()->tray_delegate()->GetUserImage(),
+ gfx::Size(kUserIconSize, kUserIconSize));
+ user_card_->AddChildView(avatar);
+
+ if (login == ash::user::LOGGED_IN_PUBLIC) {
+ user_card_->AddChildView(new PublicAccountUserDetails(
+ owner, GetPreferredSize().width() + kTrayPopupPaddingBetweenItems));
+ return;
+ }
+
+ ash::SystemTrayDelegate* delegate =
+ ash::Shell::GetInstance()->tray_delegate();
+ views::View* details = new views::View;
+ details->SetLayoutManager(new views::BoxLayout(
+ views::BoxLayout::kVertical, 0, kUserDetailsVerticalPadding, 0));
+ views::Label* username = new views::Label(delegate->GetUserDisplayName());
+ username->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+ details->AddChildView(username);
+
+ views::Label* email = new views::Label(UTF8ToUTF16(delegate->GetUserEmail()));
+ email->SetFont(username->font().DeriveFont(-1));
+ email->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+ email->SetElideBehavior(views::Label::ELIDE_AS_EMAIL);
bartfab (slow) 2012/11/19 18:18:05 I changed this back because it introduced a rather
+ email->SetEnabled(false);
+ details->AddChildView(email);
+ user_card_->AddChildView(details);
+}
} // namespace tray
@@ -271,7 +539,7 @@ views::View* TrayUser::CreateDefaultView(user::LoginStatus status) {
return NULL;
CHECK(user_ == NULL);
- user_ = new tray::UserView(status);
+ user_ = new tray::UserView(this, status);
return user_;
}
« no previous file with comments | « ash/system/user/tray_user.h ('k') | chrome/browser/chromeos/system/ash_system_tray_delegate.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698