summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/views/new_avatar_button.cc
blob: 2804e15b664ffb828719b63a44bfc390f1d7ad1c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright 2013 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.

#include "chrome/browser/ui/views/new_avatar_button.h"

#include "base/win/windows_version.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profiles_state.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/text_elider.h"
#include "ui/views/border.h"
#include "ui/views/painter.h"

namespace {

// Text padding within the button border.
const int kInset = 10;

views::TextButtonDefaultBorder* CreateBorder(const int normal_image_set[],
                                             const int hot_image_set[],
                                             const int pushed_image_set[]) {
  views::TextButtonDefaultBorder* border = new views::TextButtonDefaultBorder();

  border->SetInsets(gfx::Insets(kInset, kInset, kInset, kInset));
  border->set_normal_painter(
      views::Painter::CreateImageGridPainter(normal_image_set));
  border->set_hot_painter(
      views::Painter::CreateImageGridPainter(hot_image_set));
  border->set_pushed_painter(
      views::Painter::CreateImageGridPainter(pushed_image_set));

  return border;
}

base::string16 GetElidedText(const base::string16& original_text) {
  // Maximum characters the button can be before the text will get elided.
  const int kMaxCharactersToDisplay = 15;

  gfx::FontList font_list = ui::ResourceBundle::GetSharedInstance().GetFontList(
      ui::ResourceBundle::BaseFont);
  return gfx::ElideText(
      original_text,
      font_list,
      font_list.GetExpectedTextWidth(kMaxCharactersToDisplay),
      gfx::ELIDE_AT_END);
}

}  // namespace

NewAvatarButton::NewAvatarButton(
    views::ButtonListener* listener,
    const base::string16& profile_name,
    AvatarButtonStyle button_style,
    Browser* browser)
    : MenuButton(listener, GetElidedText(profile_name), NULL, true),
      browser_(browser) {
  set_animate_on_state_change(false);

  ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
  SetFont(rb->GetFont(ui::ResourceBundle::BaseFont));

  bool is_win8 = false;
#if defined(OS_WIN)
  is_win8 = base::win::GetVersion() >= base::win::VERSION_WIN8;
#endif

  if (button_style == THEMED_BUTTON) {
    const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_THEMED_BUTTON_NORMAL);
    const int kHotImageSet[] = IMAGE_GRID(IDR_AVATAR_THEMED_BUTTON_HOVER);
    const int kPushedImageSet[] = IMAGE_GRID(IDR_AVATAR_THEMED_BUTTON_PRESSED);

    set_border(CreateBorder(kNormalImageSet, kHotImageSet, kPushedImageSet));
    set_menu_marker(
        rb->GetImageNamed(IDR_AVATAR_THEMED_BUTTON_DROPARROW).ToImageSkia());
  } else if (is_win8) {
    const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_METRO_BUTTON_NORMAL);
    const int kHotImageSet[] = IMAGE_GRID(IDR_AVATAR_METRO_BUTTON_HOVER);
    const int kPushedImageSet[] = IMAGE_GRID(IDR_AVATAR_METRO_BUTTON_PRESSED);

    set_border(CreateBorder(kNormalImageSet, kHotImageSet, kPushedImageSet));
    set_menu_marker(
        rb->GetImageNamed(IDR_AVATAR_METRO_BUTTON_DROPARROW).ToImageSkia());
  } else {
    const int kNormalImageSet[] = IMAGE_GRID(IDR_AVATAR_GLASS_BUTTON_NORMAL);
    const int kHotImageSet[] = IMAGE_GRID(IDR_AVATAR_GLASS_BUTTON_HOVER);
    const int kPushedImageSet[] = IMAGE_GRID(IDR_AVATAR_GLASS_BUTTON_PRESSED);

    set_border(CreateBorder(kNormalImageSet, kHotImageSet, kPushedImageSet));
    set_menu_marker(
        rb->GetImageNamed(IDR_AVATAR_GLASS_BUTTON_DROPARROW).ToImageSkia());
  }

  avatar_menu_.reset(new AvatarMenu(
      &g_browser_process->profile_manager()->GetProfileInfoCache(),
      this,
      browser_));
  avatar_menu_->RebuildMenu();

  SchedulePaint();
}

NewAvatarButton::~NewAvatarButton() {
}

void NewAvatarButton::OnPaint(gfx::Canvas* canvas) {
  // From TextButton::PaintButton, draw everything but the text.
  OnPaintBackground(canvas);
  OnPaintBorder(canvas);
  views::Painter::PaintFocusPainter(this, canvas, focus_painter());

  gfx::Rect rect;
  // In RTL languages the marker gets drawn leftmost, so account for its offset.
  if (base::i18n::IsRTL())
    rect = gfx::Rect(-kInset, 0, size().width(), size().height());
  else
    rect = gfx::Rect(kInset, 0, size().width(), size().height());

  canvas->DrawStringRectWithHalo(
      text(),
      ui::ResourceBundle::GetSharedInstance().GetFontList(
          ui::ResourceBundle::BaseFont),
      SK_ColorWHITE,
      SK_ColorDKGRAY,
      rect,
      gfx::Canvas::NO_SUBPIXEL_RENDERING);

  // From MenuButton::PaintButton, paint the marker
  PaintMenuMarker(canvas);
}

void NewAvatarButton::OnAvatarMenuChanged(AvatarMenu* avatar_menu) {
  // We want the button to resize if the new text is shorter.
  ClearMaxTextSize();
  SetText(GetElidedText(profiles::GetActiveProfileDisplayName(browser_)));

  // Because the width of the button might have changed, the parent browser
  // frame needs to recalculate the button bounds and redraw it.
  parent()->Layout();
}