1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/chromeos/login/oobe_progress_bar.h"
6
7#include "base/logging.h"
8#include "base/utf_string_conversions.h"
9#include "grit/theme_resources.h"
10#include "third_party/skia/include/core/SkBitmap.h"
11#include "ui/base/l10n/l10n_util.h"
12#include "ui/base/resource/resource_bundle.h"
13#include "ui/gfx/canvas_skia.h"
14
15namespace chromeos {
16
17// static
18SkBitmap* OobeProgressBar::dot_current_ = NULL;
19SkBitmap* OobeProgressBar::dot_empty_ = NULL;
20SkBitmap* OobeProgressBar::dot_filled_ = NULL;
21SkBitmap* OobeProgressBar::line_ = NULL;
22SkBitmap* OobeProgressBar::line_left_ = NULL;
23SkBitmap* OobeProgressBar::line_right_ = NULL;
24
25static const SkColor kCurrentTextColor = SkColorSetRGB(255, 255, 255);
26static const SkColor kEmptyTextColor = SkColorSetRGB(112, 115, 118);
27static const SkColor kFilledTextColor = SkColorSetRGB(112, 115, 118);
28static const int kTextPadding = 5;
29
30OobeProgressBar::OobeProgressBar(const std::vector<int>& steps)
31    : steps_(steps), progress_(0) {
32  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
33  font_ = rb.GetFont(ResourceBundle::BaseFont);
34  InitClass();
35}
36
37// static
38void OobeProgressBar::InitClass() {
39  static bool initialized = false;
40  if (!initialized) {
41    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
42
43    // Load images.
44    dot_current_ = rb.GetBitmapNamed(IDR_OOBE_PROGRESS_DOT_CURRENT);
45    dot_empty_ = rb.GetBitmapNamed(IDR_OOBE_PROGRESS_DOT_EMPTY);
46    dot_filled_ = rb.GetBitmapNamed(IDR_OOBE_PROGRESS_DOT_FILLED);
47    line_ = rb.GetBitmapNamed(IDR_OOBE_PROGRESS_LINE);
48    line_left_ = rb.GetBitmapNamed(IDR_OOBE_PROGRESS_LINE_LEFT);
49    line_right_ = rb.GetBitmapNamed(IDR_OOBE_PROGRESS_LINE_RIGHT);
50
51    initialized = true;
52  }
53}
54
55void OobeProgressBar::OnPaint(gfx::Canvas* canvas) {
56  gfx::Rect bounds = GetContentsBounds();
57
58  int x = bounds.x();
59  int y = bounds.y();
60
61  double step_width = static_cast<double>(bounds.width()) / steps_.size();
62
63  for (size_t i = 0; i < steps_.size(); ++i) {
64    SkBitmap* dot;
65    SkColor color;
66    SkBitmap* line_before = line_;
67    SkBitmap* line_after = line_;
68    if (i < progress_) {
69      dot = dot_filled_;
70      color = kFilledTextColor;
71    } else if (i == progress_) {
72      dot = dot_current_;
73      color = kCurrentTextColor;
74      line_before = line_left_;
75      line_after = line_right_;
76    } else {
77      dot = dot_empty_;
78      color = kEmptyTextColor;
79    }
80
81    // x coordinate for next step.
82    int next_x = static_cast<int>((i + 1) * step_width);
83
84    // Offset of line origin from dot origin.
85    int line_offset_y = (dot->height() - line_->height()) / 2;
86
87    // Current x for painting.
88    int ix = x;
89
90    int line_width = ((next_x - x) -
91        (line_before->width() + dot->width() + line_after->width())) / 2;
92    if (i > 0) {
93      canvas->TileImageInt(*line_, ix, y + line_offset_y,
94                           line_width, line_->height());
95    }
96    ix += line_width;
97    if (i > 0) {
98      canvas->DrawBitmapInt(*line_before, ix, y + line_offset_y);
99    }
100    ix += line_before->width();
101
102    canvas->DrawBitmapInt(*dot, ix, y);
103    ix += dot->width();
104
105    if (i != steps_.size() - 1)
106      canvas->DrawBitmapInt(*line_after, ix, y + line_offset_y);
107    ix += line_after->width();
108
109    if (i != steps_.size() - 1) {
110      canvas->TileImageInt(*line_, ix, y + line_offset_y,
111                           next_x - ix, line_->height());
112    }
113
114    string16 str = l10n_util::GetStringUTF16(steps_[i]);
115    canvas->DrawStringInt(str, font_, color,
116        x + kTextPadding, y + dot->height() + kTextPadding,
117        (next_x - x - 2 * kTextPadding),
118        (bounds.height() - dot->height() - 2 * kTextPadding),
119        gfx::Canvas::MULTI_LINE | gfx::Canvas::TEXT_ALIGN_CENTER |
120            gfx::Canvas::TEXT_VALIGN_TOP);
121
122    x = next_x;
123  }
124}
125
126void OobeProgressBar::OnLocaleChanged() {
127  font_ = ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont);
128  SchedulePaint();
129}
130
131void OobeProgressBar::SetStep(int step) {
132  for (size_t i = 0; i < steps_.size(); ++i) {
133    if (steps_[i] == step) {
134      progress_ = i;
135      SchedulePaint();
136      return;
137    }
138  }
139  NOTREACHED();
140}
141
142}  // namespace chromeos
143