Home | History | Annotate | Download | only in infobars
      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/ui/gtk/infobars/infobar_arrow_model.h"
      6 
      7 #include "chrome/browser/ui/gtk/infobars/infobar_gtk.h"
      8 #include "third_party/skia/include/effects/SkGradientShader.h"
      9 #include "ui/gfx/canvas_skia_paint.h"
     10 #include "ui/gfx/color_utils.h"
     11 #include "ui/gfx/rect.h"
     12 #include "ui/gfx/skia_utils_gtk.h"
     13 
     14 const size_t InfoBarArrowModel::kDefaultArrowSize = 12;
     15 
     16 InfoBarArrowModel::InfoBarArrowModel(Observer* observer)
     17     : observer_(observer),
     18       animation_(this) {
     19   animation_.SetTweenType(ui::Tween::LINEAR);
     20   animation_.Reset(1.0);
     21   target_colors_.top = target_colors_.bottom = SkColorSetARGB(0, 0, 0, 0);
     22   previous_colors_ = target_colors_;
     23 }
     24 
     25 InfoBarArrowModel::~InfoBarArrowModel() {
     26 }
     27 
     28 InfoBarArrowModel::InfoBarColors InfoBarArrowModel::CurrentInfoBarColors() {
     29   double alpha = animation_.GetCurrentValue();
     30   InfoBarColors colors = {
     31       color_utils::AlphaBlend(target_colors_.top,
     32                               previous_colors_.top,
     33                               alpha * 0xff),
     34       color_utils::AlphaBlend(target_colors_.bottom,
     35                               previous_colors_.bottom,
     36                               alpha * 0xff)};
     37   return colors;
     38 }
     39 
     40 bool InfoBarArrowModel::NeedToDrawInfoBarArrow() {
     41   return SkColorGetA(CurrentInfoBarColors().top) != 0;
     42 }
     43 
     44 void InfoBarArrowModel::ShowArrowFor(InfoBar* bar, bool animate) {
     45   scoped_ptr<std::pair<SkColor, SkColor> > colors;
     46 
     47   previous_colors_ = CurrentInfoBarColors();
     48 
     49   if (bar) {
     50     double r, g, b;
     51     bar->GetTopColor(bar->delegate()->GetInfoBarType(), &r, &g, &b);
     52     target_colors_.top = SkColorSetRGB(r * 0xff, g * 0xff, b * 0xff);
     53     bar->GetBottomColor(bar->delegate()->GetInfoBarType(), &r, &g, &b);
     54     target_colors_.bottom = SkColorSetRGB(r * 0xff, g * 0xff, b * 0xff);
     55   } else {
     56     target_colors_.bottom = target_colors_.top = SkColorSetARGB(0, 0, 0, 0);
     57   }
     58 
     59   if (animate) {
     60     // Fade from the current color to the target color.
     61     animation_.Reset();
     62     animation_.Show();
     63   } else {
     64     // Skip straight to showing the target color.
     65     animation_.Reset(1.0);
     66   }
     67 
     68   observer_->PaintStateChanged();
     69 }
     70 
     71 void InfoBarArrowModel::Paint(GtkWidget* widget,
     72                               GdkEventExpose* expose,
     73                               const gfx::Rect& bounds,
     74                               const GdkColor& border_color) {
     75   if (!NeedToDrawInfoBarArrow())
     76     return;
     77 
     78   SkPath path;
     79   path.moveTo(bounds.x() + 0.5, bounds.bottom() + 0.5);
     80   path.rLineTo(bounds.width() / 2.0, -bounds.height());
     81   path.lineTo(bounds.right() + 0.5, bounds.bottom() + 0.5);
     82   path.close();
     83 
     84   SkPaint paint;
     85   paint.setStrokeWidth(1);
     86   paint.setStyle(SkPaint::kFill_Style);
     87   paint.setAntiAlias(true);
     88 
     89   SkPoint grad_points[2];
     90   grad_points[0].set(SkIntToScalar(0), SkIntToScalar(bounds.bottom()));
     91   grad_points[1].set(SkIntToScalar(0),
     92                      SkIntToScalar(bounds.bottom() + InfoBar::kInfoBarHeight));
     93 
     94   InfoBarColors colors = CurrentInfoBarColors();
     95   SkColor grad_colors[2];
     96   grad_colors[0] = colors.top;
     97   grad_colors[1] = colors.bottom;
     98 
     99   SkShader* gradient_shader = SkGradientShader::CreateLinear(
    100       grad_points, grad_colors, NULL, 2, SkShader::kMirror_TileMode);
    101   paint.setShader(gradient_shader);
    102   gradient_shader->unref();
    103 
    104   gfx::CanvasSkiaPaint canvas(expose, false);
    105   canvas.drawPath(path, paint);
    106 
    107   paint.setShader(NULL);
    108   paint.setColor(SkColorSetA(gfx::GdkColorToSkColor(border_color),
    109                              SkColorGetA(colors.top)));
    110   paint.setStyle(SkPaint::kStroke_Style);
    111   canvas.drawPath(path, paint);
    112 }
    113 
    114 void InfoBarArrowModel::AnimationEnded(const ui::Animation* animation) {
    115   observer_->PaintStateChanged();
    116 }
    117 
    118 void InfoBarArrowModel::AnimationProgressed(const ui::Animation* animation) {
    119   observer_->PaintStateChanged();
    120 }
    121 
    122 void InfoBarArrowModel::AnimationCanceled(const ui::Animation* animation) {
    123   observer_->PaintStateChanged();
    124 }
    125