| OLD | NEW |
| (Empty) |
| 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/panels/panel_overflow_indicator_view.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "base/string_number_conversions.h" | |
| 9 #include "chrome/browser/ui/panels/panel_browser_frame_view.h" | |
| 10 #include "ui/base/resource/resource_bundle.h" | |
| 11 #include "ui/gfx/font.h" | |
| 12 #include "ui/gfx/path.h" | |
| 13 #include "ui/views/background.h" | |
| 14 #include "ui/views/painter.h" | |
| 15 #include "ui/views/widget/widget.h" | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 enum OverflowPaintState { | |
| 20 PAINT_AS_NORMAL, | |
| 21 PAINT_FOR_ATTENTION | |
| 22 }; | |
| 23 | |
| 24 // The height in pixels of the widget to show the plus count. | |
| 25 const int kWidgetHeight = 15; | |
| 26 | |
| 27 // The radius of the corner of the border. | |
| 28 const int kCornerRadius = 4; | |
| 29 | |
| 30 // Metrics used to draw the text. | |
| 31 const int kTextFontSize = 10; | |
| 32 const SkColor kTextColor = SK_ColorWHITE; | |
| 33 | |
| 34 // Gradient colors used to draw the background in normal mode. | |
| 35 const SkColor kNormalBackgroundColorStart = 0xff777777; | |
| 36 const SkColor kNormalBackgroundColorEnd = 0xff555555; | |
| 37 | |
| 38 // Gradient colors used to draw the background in attention mode. | |
| 39 const SkColor kAttentionBackgroundColorStart = 0xffffab57; | |
| 40 const SkColor kAttentionBackgroundColorEnd = 0xfff59338; | |
| 41 | |
| 42 views::Painter* GetBackgroundPainter(OverflowPaintState paint_state) { | |
| 43 static views::Painter* normal_painter = NULL; | |
| 44 static views::Painter* attention_painter = NULL; | |
| 45 | |
| 46 if (paint_state == PAINT_AS_NORMAL) { | |
| 47 if (!normal_painter) { | |
| 48 normal_painter = views::Painter::CreateVerticalGradient( | |
| 49 kNormalBackgroundColorStart, kNormalBackgroundColorEnd); | |
| 50 } | |
| 51 return normal_painter; | |
| 52 } else { | |
| 53 if (!attention_painter) { | |
| 54 attention_painter = views::Painter::CreateVerticalGradient( | |
| 55 kAttentionBackgroundColorStart, kAttentionBackgroundColorEnd); | |
| 56 } | |
| 57 return attention_painter; | |
| 58 } | |
| 59 } | |
| 60 | |
| 61 } // namespace | |
| 62 | |
| 63 PanelOverflowIndicator* PanelOverflowIndicator::Create() { | |
| 64 return new PanelOverflowIndicatorView(); | |
| 65 } | |
| 66 | |
| 67 PanelOverflowIndicatorView::PanelOverflowIndicatorView() | |
| 68 : count_(0), | |
| 69 is_drawing_attention_(false) { | |
| 70 widget_.reset(new views::Widget); | |
| 71 views::Widget::InitParams params; | |
| 72 params.type = views::Widget::InitParams::TYPE_POPUP; | |
| 73 params.keep_on_top = true; | |
| 74 params.can_activate = false; | |
| 75 params.transparent = true; | |
| 76 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 77 widget_->Init(params); | |
| 78 widget_->SetAlwaysOnTop(true); | |
| 79 | |
| 80 const gfx::Font& base_font = | |
| 81 ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont); | |
| 82 title_.SetFont(base_font.DeriveFont( | |
| 83 kTextFontSize - base_font.GetFontSize(), gfx::Font::BOLD)); | |
| 84 title_.SetHorizontalAlignment(views::Label::ALIGN_CENTER); | |
| 85 title_.SetAutoColorReadabilityEnabled(false); | |
| 86 | |
| 87 widget_->SetContentsView(&title_); | |
| 88 widget_->Show(); | |
| 89 | |
| 90 PaintBackground(); | |
| 91 } | |
| 92 | |
| 93 PanelOverflowIndicatorView::~PanelOverflowIndicatorView() { | |
| 94 } | |
| 95 | |
| 96 int PanelOverflowIndicatorView::GetHeight() const { | |
| 97 return kWidgetHeight; | |
| 98 } | |
| 99 | |
| 100 gfx::Rect PanelOverflowIndicatorView::GetBounds() const { | |
| 101 return widget_->GetWindowScreenBounds(); | |
| 102 } | |
| 103 | |
| 104 void PanelOverflowIndicatorView::SetBounds(const gfx::Rect& bounds) { | |
| 105 widget_->SetBounds(bounds); | |
| 106 | |
| 107 gfx::Path path; | |
| 108 GetFrameMask(bounds, &path); | |
| 109 widget_->SetShape(path.CreateNativeRegion()); | |
| 110 } | |
| 111 | |
| 112 int PanelOverflowIndicatorView::GetCount() const { | |
| 113 return count_; | |
| 114 } | |
| 115 | |
| 116 void PanelOverflowIndicatorView::SetCount(int count) { | |
| 117 if (count_ == count) | |
| 118 return; | |
| 119 count_ = count; | |
| 120 | |
| 121 if (count_ > 0) | |
| 122 widget_->Show(); | |
| 123 else | |
| 124 widget_->Hide(); | |
| 125 | |
| 126 UpdateTitle(); | |
| 127 } | |
| 128 | |
| 129 void PanelOverflowIndicatorView::DrawAttention() { | |
| 130 if (is_drawing_attention_) | |
| 131 return; | |
| 132 is_drawing_attention_ = true; | |
| 133 PaintBackground(); | |
| 134 } | |
| 135 | |
| 136 void PanelOverflowIndicatorView::StopDrawingAttention() { | |
| 137 if (!is_drawing_attention_) | |
| 138 return; | |
| 139 is_drawing_attention_ = false; | |
| 140 PaintBackground(); | |
| 141 } | |
| 142 | |
| 143 bool PanelOverflowIndicatorView::IsDrawingAttention() const { | |
| 144 return is_drawing_attention_; | |
| 145 } | |
| 146 | |
| 147 void PanelOverflowIndicatorView::UpdateTitle() { | |
| 148 string16 text(L"+"); | |
| 149 text += base::IntToString16(count_); | |
| 150 title_.SetText(text); | |
| 151 } | |
| 152 | |
| 153 void PanelOverflowIndicatorView::PaintBackground() { | |
| 154 OverflowPaintState paint_state = is_drawing_attention_ ? PAINT_FOR_ATTENTION | |
| 155 : PAINT_AS_NORMAL; | |
| 156 | |
| 157 title_.set_background(views::Background::CreateBackgroundPainter( | |
| 158 false, GetBackgroundPainter(paint_state))); | |
| 159 title_.SetEnabledColor(kTextColor); | |
| 160 title_.SchedulePaint(); // SetEnabledColor does not call SchedulePaint. | |
| 161 } | |
| 162 | |
| 163 void PanelOverflowIndicatorView::GetFrameMask(const gfx::Rect& rect, | |
| 164 gfx::Path* path) const { | |
| 165 SkScalar radius = SkIntToScalar(kCornerRadius); | |
| 166 SkScalar spline_radius = radius - | |
| 167 SkScalarMul(radius, (SK_ScalarSqrt2 - SK_Scalar1) * 4 / 3); | |
| 168 SkScalar left = SkIntToScalar(0); | |
| 169 SkScalar top = SkIntToScalar(0); | |
| 170 SkScalar right = SkIntToScalar(rect.width()); | |
| 171 SkScalar bottom = SkIntToScalar(rect.height()); | |
| 172 | |
| 173 path->moveTo(left + radius, top); | |
| 174 path->lineTo(right - radius, top); | |
| 175 path->cubicTo(right - spline_radius, top, | |
| 176 right, top + spline_radius, | |
| 177 right, top + radius); | |
| 178 path->lineTo(right, bottom); | |
| 179 path->lineTo(left, bottom); | |
| 180 path->lineTo(left, top + radius); | |
| 181 path->cubicTo(left, top + spline_radius, | |
| 182 left + spline_radius, top, | |
| 183 left + radius, top); | |
| 184 path->close(); | |
| 185 } | |
| OLD | NEW |