summaryrefslogtreecommitdiffstats
path: root/ash/launcher/overflow_button.cc
blob: 4ff843243f99ddc657175c5797d9627a26653d43 (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
// Copyright (c) 2012 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 "ash/launcher/overflow_button.h"

#include "grit/ash_strings.h"
#include "grit/ui_resources.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
#include "ui/base/animation/throb_animation.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/transform.h"

namespace ash {
namespace internal {

namespace {

const int kButtonHoverAlpha = 150;

const int kButtonCornerRadius = 2;

const int kButtonHoverSize = 28;

void RotateCounterclockwise(ui::Transform* transform) {
  transform->matrix().set3x3(0, -1, 0,
                             1,  0, 0,
                             0,  0, 1);
}

void RotateClockwise(ui::Transform* transform) {
  transform->matrix().set3x3( 0, 1, 0,
                             -1, 0, 0,
                              0, 0, 1);
}

}  // namesapce

OverflowButton::OverflowButton(views::ButtonListener* listener)
    : CustomButton(listener),
      alignment_(SHELF_ALIGNMENT_BOTTOM),
      image_(NULL) {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  image_ = rb.GetImageNamed(IDR_AURA_LAUNCHER_OVERFLOW).ToImageSkia();

  set_accessibility_focusable(true);
  SetAccessibleName(
      l10n_util::GetStringUTF16(IDS_AURA_LAUNCHER_OVERFLOW_NAME));
}


OverflowButton::~OverflowButton() {
}

void OverflowButton::SetShelfAlignment(ShelfAlignment alignment) {
  if (alignment_ == alignment)
    return;

  alignment_ = alignment;
  SchedulePaint();
}

void OverflowButton::PaintBackground(gfx::Canvas* canvas, int alpha) {
  gfx::Rect rect(GetContentsBounds());
  rect = rect.Center(gfx::Size(kButtonHoverSize, kButtonHoverSize));

  SkPaint paint;
  paint.setAntiAlias(true);
  paint.setStyle(SkPaint::kFill_Style);
  paint.setColor(SkColorSetARGB(
      kButtonHoverAlpha * hover_animation_->GetCurrentValue(),
      0, 0, 0));

  const SkScalar radius = SkIntToScalar(kButtonCornerRadius);
  SkPath path;
  path.addRoundRect(gfx::RectToSkRect(rect), radius, radius);
  canvas->DrawPath(path, paint);
}

void OverflowButton::OnPaint(gfx::Canvas* canvas) {
  if (hover_animation_->is_animating()) {
    PaintBackground(
        canvas,
        kButtonHoverAlpha * hover_animation_->GetCurrentValue());
  } else if (state() == BS_HOT || state() == BS_PUSHED) {
    PaintBackground(canvas, kButtonHoverAlpha);
  }

  ui::Transform transform;

  switch (alignment_) {
    case SHELF_ALIGNMENT_BOTTOM:
      // Shift 1 pixel left to align with overflow bubble tip.
      transform.ConcatTranslate(-1, 0);
      break;
    case SHELF_ALIGNMENT_LEFT:
      RotateClockwise(&transform);
      transform.ConcatTranslate(width(), -1);
      break;
    case SHELF_ALIGNMENT_RIGHT:
      RotateCounterclockwise(&transform);
      transform.ConcatTranslate(0, height());
      break;
  }

  canvas->Save();
  canvas->Transform(transform);

  gfx::Rect rect(GetContentsBounds());
  canvas->DrawImageInt(*image_,
                       rect.x() + (rect.width() - image_->width()) / 2,
                       rect.y() + (rect.height() - image_->height()) / 2);

  canvas->Restore();
}

}  // namespace internal
}  // namespace ash