• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
InfoBarArrowModel(Observer * observer)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 
~InfoBarArrowModel()25 InfoBarArrowModel::~InfoBarArrowModel() {
26 }
27 
CurrentInfoBarColors()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 
NeedToDrawInfoBarArrow()40 bool InfoBarArrowModel::NeedToDrawInfoBarArrow() {
41   return SkColorGetA(CurrentInfoBarColors().top) != 0;
42 }
43 
ShowArrowFor(InfoBar * bar,bool animate)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 
Paint(GtkWidget * widget,GdkEventExpose * expose,const gfx::Rect & bounds,const GdkColor & border_color)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 
AnimationEnded(const ui::Animation * animation)114 void InfoBarArrowModel::AnimationEnded(const ui::Animation* animation) {
115   observer_->PaintStateChanged();
116 }
117 
AnimationProgressed(const ui::Animation * animation)118 void InfoBarArrowModel::AnimationProgressed(const ui::Animation* animation) {
119   observer_->PaintStateChanged();
120 }
121 
AnimationCanceled(const ui::Animation * animation)122 void InfoBarArrowModel::AnimationCanceled(const ui::Animation* animation) {
123   observer_->PaintStateChanged();
124 }
125