summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk/infobar_arrow_model.cc
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-26 22:00:37 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-26 22:00:37 +0000
commitdcb3070302b8ee07a3d1dbfc290a84d325c7a6e3 (patch)
treec4f5942b02cb09f2a37dc96298bbb32d1858d421 /chrome/browser/gtk/infobar_arrow_model.cc
parenta314ee5ab5322b95a861e38fdc377ec156b0add9 (diff)
downloadchromium_src-dcb3070302b8ee07a3d1dbfc290a84d325c7a6e3.zip
chromium_src-dcb3070302b8ee07a3d1dbfc290a84d325c7a6e3.tar.gz
chromium_src-dcb3070302b8ee07a3d1dbfc290a84d325c7a6e3.tar.bz2
[gtk] spoof proof infobars, take 2
This looks like a big review, but a lot of it is just shuffling code around: - rip out dropshadow code - move arrow state and drawing to a model class, to allow sharing between BrowserWindow and Infobar - get rid of InfoBar's border_bin_ and slightly simplify baseclasses by no longer requiring them to call show() on the toplevel widget Added stuff: - transition between arrow colors (previous_color_ vs. target_color_ business) - arrows protruding on neighboring infobars BUG=48996 TEST=manual, with animations slowed down 100x Review URL: http://codereview.chromium.org/3919004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@63956 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk/infobar_arrow_model.cc')
-rw-r--r--chrome/browser/gtk/infobar_arrow_model.cc124
1 files changed, 124 insertions, 0 deletions
diff --git a/chrome/browser/gtk/infobar_arrow_model.cc b/chrome/browser/gtk/infobar_arrow_model.cc
new file mode 100644
index 0000000..e66bb02
--- /dev/null
+++ b/chrome/browser/gtk/infobar_arrow_model.cc
@@ -0,0 +1,124 @@
+// 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 "chrome/browser/gtk/infobar_arrow_model.h"
+
+#include "chrome/browser/gtk/infobar_gtk.h"
+#include "gfx/canvas_skia_paint.h"
+#include "gfx/color_utils.h"
+#include "gfx/point.h"
+#include "gfx/skia_utils_gtk.h"
+#include "third_party/skia/include/effects/SkGradientShader.h"
+
+InfoBarArrowModel::InfoBarArrowModel(Observer* observer)
+ : observer_(observer),
+ animation_(this) {
+ animation_.SetTweenType(Tween::LINEAR);
+ animation_.Reset(1.0);
+ target_colors_.top = target_colors_.bottom = SkColorSetARGB(0, 0, 0, 0);
+ previous_colors_ = target_colors_;
+}
+
+InfoBarArrowModel::~InfoBarArrowModel() {
+}
+
+InfoBarArrowModel::InfoBarColors InfoBarArrowModel::CurrentInfoBarColors() {
+ double alpha = animation_.GetCurrentValue();
+ InfoBarColors colors = {
+ color_utils::AlphaBlend(target_colors_.top,
+ previous_colors_.top,
+ alpha * 0xff),
+ color_utils::AlphaBlend(target_colors_.bottom,
+ previous_colors_.bottom,
+ alpha * 0xff)};
+ return colors;
+}
+
+bool InfoBarArrowModel::NeedToDrawInfoBarArrow() {
+ return SkColorGetA(CurrentInfoBarColors().top) != 0;
+}
+
+void InfoBarArrowModel::ShowArrowFor(InfoBar* bar, bool animate) {
+ scoped_ptr<std::pair<SkColor, SkColor> > colors;
+
+ previous_colors_ = CurrentInfoBarColors();
+
+ if (bar) {
+ double r, g, b;
+ bar->GetTopColor(bar->delegate()->GetInfoBarType(), &r, &g, &b);
+ target_colors_.top = SkColorSetRGB(r * 0xff, g * 0xff, b * 0xff);
+ bar->GetBottomColor(bar->delegate()->GetInfoBarType(), &r, &g, &b);
+ target_colors_.bottom = SkColorSetRGB(r * 0xff, g * 0xff, b * 0xff);
+ } else {
+ target_colors_.bottom = target_colors_.top = SkColorSetARGB(0, 0, 0, 0);
+ }
+
+ if (animate) {
+ // Fade from the current color to the target color.
+ animation_.Reset();
+ animation_.Show();
+ } else {
+ // Skip straight to showing the target color.
+ animation_.Reset(1.0);
+ }
+
+ observer_->PaintStateChanged();
+}
+
+void InfoBarArrowModel::Paint(GtkWidget* widget,
+ GdkEventExpose* expose,
+ const gfx::Point& origin,
+ const GdkColor& border_color) {
+ if (!NeedToDrawInfoBarArrow())
+ return;
+
+ // The size of the arrow (its height; also half its width).
+ const int kArrowSize = 10;
+
+ SkPath path;
+ path.moveTo(SkPoint::Make(origin.x() - kArrowSize, origin.y()));
+ path.rLineTo(kArrowSize, -kArrowSize);
+ path.rLineTo(kArrowSize, kArrowSize);
+ path.close();
+
+ SkPaint paint;
+ paint.setStrokeWidth(1);
+ paint.setStyle(SkPaint::kFill_Style);
+
+ SkPoint grad_points[2];
+ grad_points[0].set(SkIntToScalar(0), SkIntToScalar(origin.y()));
+ grad_points[1].set(SkIntToScalar(0),
+ SkIntToScalar(origin.y() + InfoBar::kInfoBarHeight));
+
+ InfoBarColors colors = CurrentInfoBarColors();
+ SkColor grad_colors[2];
+ grad_colors[0] = colors.top;
+ grad_colors[1] = colors.bottom;
+
+ SkShader* gradient_shader = SkGradientShader::CreateLinear(
+ grad_points, grad_colors, NULL, 2, SkShader::kMirror_TileMode);
+ paint.setShader(gradient_shader);
+ gradient_shader->unref();
+
+ gfx::CanvasSkiaPaint canvas(expose, false);
+ canvas.drawPath(path, paint);
+
+ paint.setShader(NULL);
+ paint.setColor(SkColorSetA(gfx::GdkColorToSkColor(border_color),
+ SkColorGetA(colors.top)));
+ paint.setStyle(SkPaint::kStroke_Style);
+ canvas.drawPath(path, paint);
+}
+
+void InfoBarArrowModel::AnimationEnded(const Animation* animation) {
+ observer_->PaintStateChanged();
+}
+
+void InfoBarArrowModel::AnimationProgressed(const Animation* animation) {
+ observer_->PaintStateChanged();
+}
+
+void InfoBarArrowModel::AnimationCanceled(const Animation* animation) {
+ observer_->PaintStateChanged();
+}