summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-12 16:52:04 +0000
committerfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-12 16:52:04 +0000
commitf5a51b22795117b60b3d4045eed9039a511d697a (patch)
tree739a4bdaf9e223fecf61ac407b2cb491098f2dd5
parent44ce0b1adb867c77d02c45c2eb2a6c7ee3471167 (diff)
downloadchromium_src-f5a51b22795117b60b3d4045eed9039a511d697a.zip
chromium_src-f5a51b22795117b60b3d4045eed9039a511d697a.tar.gz
chromium_src-f5a51b22795117b60b3d4045eed9039a511d697a.tar.bz2
Implementation of a progress bar control.
BUG=37960 TEST=Unit tests provided, run chrome_tests. Checking in patch from Denis Romanov, reviewed as: http://codereview.chromium.org/889001/show Review URL: http://codereview.chromium.org/842007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41436 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--views/controls/progress_bar.cc212
-rw-r--r--views/controls/progress_bar.h82
-rw-r--r--views/controls/progress_bar_unittest.cc52
-rw-r--r--views/views.gyp2
5 files changed, 349 insertions, 0 deletions
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index ef4d494..4118beb 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -23,6 +23,7 @@
'../views/view_unittest.cc',
'../views/focus/focus_manager_unittest.cc',
'../views/controls/label_unittest.cc',
+ '../views/controls/progress_bar_unittest.cc',
'../views/controls/table/table_view_unittest.cc',
'../views/grid_layout_unittest.cc',
],
diff --git a/views/controls/progress_bar.cc b/views/controls/progress_bar.cc
new file mode 100644
index 0000000..96ceb44
--- /dev/null
+++ b/views/controls/progress_bar.cc
@@ -0,0 +1,212 @@
+// Copyright (c) 2010 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 "views/controls/progress_bar.h"
+
+#include "app/gfx/canvas.h"
+#include "app/gfx/color_utils.h"
+#include "app/gfx/font.h"
+#include "app/gfx/insets.h"
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "base/logging.h"
+#include "base/string_util.h"
+#include "third_party/skia/include/effects/SkGradientShader.h"
+#include "third_party/skia/include/effects/SkBlurMaskFilter.h"
+#include "views/background.h"
+#include "views/border.h"
+#include "views/painter.h"
+
+namespace {
+
+// Corner radius for the progress bar's border.
+const int kCornerRadius = 3;
+
+// Progress bar's border width
+const int kBorderWidth = 1;
+
+static void AddRoundRectPath(int x, int y,
+ int w, int h,
+ int corner_radius,
+ SkPath* path) {
+ DCHECK(path);
+ if (path == NULL)
+ return;
+ SkScalar half = SkIntToScalar(1) / 2;
+ SkRect rect;
+ rect.set(
+ SkIntToScalar(x) + half, SkIntToScalar(y) + half,
+ SkIntToScalar(x + w) - half, SkIntToScalar(y + h) - half);
+ path->addRoundRect(
+ rect,
+ SkIntToScalar(corner_radius - half),
+ SkIntToScalar(corner_radius - half));
+}
+
+static void FillRoundRect(gfx::Canvas* canvas,
+ int x, int y,
+ int w, int h,
+ int corner_radius,
+ SkColor gradient_start_color,
+ SkColor gradient_end_color,
+ bool gradient_horizontal) {
+ SkPath path;
+ AddRoundRectPath(x, y, w, h, corner_radius, &path);
+ SkPaint paint;
+ paint.setStyle(SkPaint::kFill_Style);
+ paint.setFlags(SkPaint::kAntiAlias_Flag);
+ if (gradient_start_color != gradient_end_color) {
+ SkPoint p[2];
+ p[0].set(SkIntToScalar(x), SkIntToScalar(y));
+ if (gradient_horizontal) {
+ p[1].set(SkIntToScalar(x + w), SkIntToScalar(y));
+ } else {
+ p[1].set(SkIntToScalar(x), SkIntToScalar(y + h));
+ }
+ SkColor colors[2] = { gradient_start_color, gradient_end_color };
+ SkShader* s = SkGradientShader::CreateLinear(
+ p, colors, NULL, 2, SkShader::kClamp_TileMode, NULL);
+ paint.setShader(s);
+ // Need to unref shader, otherwise never deleted.
+ s->unref();
+ } else {
+ paint.setColor(gradient_start_color);
+ }
+ canvas->drawPath(path, paint);
+}
+
+static void StrokeRoundRect(gfx::Canvas* canvas,
+ int x, int y,
+ int w, int h,
+ int corner_radius,
+ SkColor stroke_color,
+ int stroke_width) {
+ SkPath path;
+ AddRoundRectPath(x, y, w, h, corner_radius, &path);
+ SkPaint paint;
+ paint.setShader(NULL);
+ paint.setColor(stroke_color);
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setFlags(SkPaint::kAntiAlias_Flag);
+ paint.setStrokeWidth(SkIntToScalar(stroke_width));
+ canvas->drawPath(path, paint);
+}
+
+} // anonymous namespace
+
+namespace views {
+
+// static
+const char ProgressBar::kViewClassName[] = "views/ProgressBar";
+
+ProgressBar::ProgressBar() {
+ Init(0);
+}
+
+ProgressBar::ProgressBar(double progress) {
+ Init(progress);
+}
+
+ProgressBar::~ProgressBar() {
+}
+
+gfx::Size ProgressBar::GetPreferredSize() {
+ return gfx::Size(100, 16);
+}
+
+void ProgressBar::Paint(gfx::Canvas* canvas) {
+ SkColor bar_color_start = SkColorSetRGB(81, 138, 223);
+ SkColor bar_color_end = SkColorSetRGB(51, 103, 205);
+ SkColor background_color_start = SkColorSetRGB(212, 212, 212);
+ SkColor background_color_end = SkColorSetRGB(252, 252, 252);
+ SkColor border_color = SkColorSetRGB(144, 144, 144);
+
+ FillRoundRect(canvas,
+ 0, 0, width(), height(),
+ kCornerRadius,
+ background_color_start,
+ background_color_end,
+ false);
+ if (progress_ * width() > 1) {
+ FillRoundRect(canvas,
+ 0, 0,
+ int(progress_ * width()), height(),
+ kCornerRadius,
+ bar_color_start,
+ bar_color_end,
+ false);
+ }
+ StrokeRoundRect(canvas,
+ 0, 0,
+ width(), height(),
+ kCornerRadius,
+ border_color,
+ kBorderWidth);
+}
+
+std::string ProgressBar::GetClassName() const {
+ return kViewClassName;
+}
+
+void ProgressBar::SetProgress(double progress) {
+ progress_ = progress;
+ if (progress_ < 0)
+ progress_ = 0;
+ else if (progress_ > 1)
+ progress_ = 1;
+ SchedulePaint();
+}
+
+double ProgressBar::GetProgress() const {
+ return progress_;
+}
+
+void ProgressBar::SetTooltipText(const std::wstring& tooltip_text) {
+ tooltip_text_ = tooltip_text;
+}
+
+bool ProgressBar::GetTooltipText(const gfx::Point& p, std::wstring* tooltip) {
+ DCHECK(tooltip);
+ if (tooltip == NULL)
+ return false;
+ tooltip->assign(tooltip_text_);
+ return !tooltip_text_.empty();
+}
+
+void ProgressBar::SetEnabled(bool enabled) {
+ if (enabled == enabled_)
+ return;
+ View::SetEnabled(enabled);
+ // TODO(denisromanov): Need to switch progress bar color here?
+}
+
+bool ProgressBar::GetAccessibleRole(AccessibilityTypes::Role* role) {
+ DCHECK(role);
+ if (role == NULL)
+ return false;
+ *role = AccessibilityTypes::ROLE_TEXT;
+ return true;
+}
+
+bool ProgressBar::GetAccessibleName(std::wstring* name) {
+ DCHECK(name);
+ if (name == NULL)
+ return false;
+ // TODO(denisromanov): Return valid text here.
+ return false;
+}
+
+bool ProgressBar::GetAccessibleState(AccessibilityTypes::State* state) {
+ DCHECK(state);
+ if (state == NULL)
+ return false;
+ *state = AccessibilityTypes::STATE_READONLY;
+ return true;
+}
+
+void ProgressBar::Init(double progress) {
+ progress_ = progress;
+}
+
+} // namespace views
diff --git a/views/controls/progress_bar.h b/views/controls/progress_bar.h
new file mode 100644
index 0000000..e5587d5
--- /dev/null
+++ b/views/controls/progress_bar.h
@@ -0,0 +1,82 @@
+// Copyright (c) 2010 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.
+
+#ifndef VIEWS_CONTROLS_PROGRESS_BAR_H_
+#define VIEWS_CONTROLS_PROGRESS_BAR_H_
+
+#include "views/view.h"
+
+namespace gfx {
+class Canvas;
+class Point;
+class Size;
+}
+
+namespace views {
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// ProgressBar class
+//
+// A progress bar is a control that indicates progress visually.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+class ProgressBar : public View {
+ public:
+ // Creates a new progress bar with progress zero.
+ ProgressBar();
+
+ // Creates a new progress bar with specified progress.
+ explicit ProgressBar(double progress);
+
+ virtual ~ProgressBar();
+
+ // Overridden to return preferred size of the progress bar.
+ virtual gfx::Size GetPreferredSize();
+
+ // Returns views/ProgressBar.
+ virtual std::string GetClassName() const;
+
+ // Overridden to paint
+ virtual void Paint(gfx::Canvas* canvas);
+
+ // Set and get the progress bar progress in range [0, 1].
+ virtual void SetProgress(double progress);
+ virtual double GetProgress() const;
+
+ // Sets the tooltip text. Default behavior for a progress bar is to show
+ // no tooltip on mouse hover. Calling this lets you set a custom tooltip.
+ // To revert to default behavior, call this with an empty string.
+ virtual void SetTooltipText(const std::wstring& tooltip_text);
+
+ // Gets the tooltip text if has been specified with SetTooltipText().
+ virtual bool GetTooltipText(const gfx::Point& p, std::wstring* tooltip);
+
+ // Sets the enabled state.
+ virtual void SetEnabled(bool enabled);
+
+ // Accessibility accessors, overridden from View.
+ virtual bool GetAccessibleRole(AccessibilityTypes::Role* role);
+ virtual bool GetAccessibleName(std::wstring* name);
+ virtual bool GetAccessibleState(AccessibilityTypes::State* state);
+
+ private:
+ void Init(double progress);
+
+ // Progress in range [0, 1].
+ double progress_;
+
+ // Tooltip text.
+ std::wstring tooltip_text_;
+
+ // The view class name.
+ static const char kViewClassName[];
+
+ DISALLOW_COPY_AND_ASSIGN(ProgressBar);
+};
+
+} // namespace views
+
+#endif // VIEWS_CONTROLS_PROGRESS_BAR_H_
diff --git a/views/controls/progress_bar_unittest.cc b/views/controls/progress_bar_unittest.cc
new file mode 100644
index 0000000..1f653b7
--- /dev/null
+++ b/views/controls/progress_bar_unittest.cc
@@ -0,0 +1,52 @@
+// Copyright (c) 2010 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 "app/l10n_util.h"
+#include "base/string_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "views/controls/progress_bar.h"
+
+namespace views {
+
+TEST(ProgressBarTest, ProgressProperty) {
+ ProgressBar bar;
+ double progress = 0;
+ bar.SetProgress(-1);
+ progress = bar.GetProgress();
+ EXPECT_EQ(0, progress);
+ bar.SetProgress(3);
+ progress = bar.GetProgress();
+ EXPECT_EQ(1, progress);
+ bar.SetProgress(0.618);
+ progress = bar.GetProgress();
+ EXPECT_EQ(0.618, progress);
+}
+
+TEST(ProgressBarTest, TooltipTextProperty) {
+ ProgressBar bar;
+ std::wstring tooltip = L"Some text";
+ EXPECT_FALSE(bar.GetTooltipText(gfx::Point(), &tooltip));
+ EXPECT_EQ(L"", tooltip);
+ std::wstring tooltip_text = L"My progress";
+ bar.SetTooltipText(tooltip_text);
+ EXPECT_TRUE(bar.GetTooltipText(gfx::Point(), &tooltip));
+ EXPECT_EQ(tooltip_text, tooltip);
+}
+
+TEST(ProgressBarTest, Accessibility) {
+ ProgressBar bar;
+ bar.SetProgress(0.618);
+
+ AccessibilityTypes::Role role;
+ EXPECT_TRUE(bar.GetAccessibleRole(&role));
+ EXPECT_EQ(AccessibilityTypes::ROLE_TEXT, role);
+
+ // TODO(denisromanov): Test accessibility text here when it's implemented.
+
+ AccessibilityTypes::State state;
+ EXPECT_TRUE(bar.GetAccessibleState(&state));
+ EXPECT_EQ(AccessibilityTypes::STATE_READONLY, state);
+}
+
+} // namespace views
diff --git a/views/views.gyp b/views/views.gyp
index 91b6b60..5981083 100644
--- a/views/views.gyp
+++ b/views/views.gyp
@@ -153,6 +153,8 @@
'controls/native/native_view_host_win.cc',
'controls/native/native_view_host_win.h',
'controls/native/native_view_host_wrapper.h',
+ 'controls/progress_bar.h',
+ 'controls/progress_bar.cc',
'controls/resize_gripper.cc',
'controls/resize_gripper.h',
'controls/scroll_view.cc',