From dcb3070302b8ee07a3d1dbfc290a84d325c7a6e3 Mon Sep 17 00:00:00 2001 From: "estade@chromium.org" Date: Tue, 26 Oct 2010 22:00:37 +0000 Subject: [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 --- chrome/browser/gtk/infobar_arrow_model.cc | 124 ++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 chrome/browser/gtk/infobar_arrow_model.cc (limited to 'chrome/browser/gtk/infobar_arrow_model.cc') 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 > 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(); +} -- cgit v1.1