Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Side by Side Diff: chrome/browser/ui/libgtk2ui/gtk2_border.cc

Issue 132023010: linux_aura: Fixes a couple of issues with the button border integration. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: msw's return statement comment Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/libgtk2ui/gtk2_border.h ('k') | chrome/browser/ui/libgtk2ui/gtk2_ui.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/libgtk2ui/gtk2_border.h" 5 #include "chrome/browser/ui/libgtk2ui/gtk2_border.h"
6 6
7 #include <gtk/gtk.h> 7 #include <gtk/gtk.h>
8 8
9 #include "chrome/browser/ui/libgtk2ui/gtk2_ui.h" 9 #include "chrome/browser/ui/libgtk2ui/gtk2_ui.h"
10 #include "third_party/skia/include/effects/SkLerpXfermode.h"
11 #include "ui/gfx/animation/animation.h"
10 #include "ui/gfx/canvas.h" 12 #include "ui/gfx/canvas.h"
11 #include "ui/gfx/image/image_skia_source.h" 13 #include "ui/gfx/image/image_skia_source.h"
12 #include "ui/views/controls/button/custom_button.h" 14 #include "ui/gfx/rect.h"
15 #include "ui/gfx/skia_util.h"
16 #include "ui/views/controls/button/label_button.h"
17 #include "ui/views/native_theme_delegate.h"
18
19 using views::Button;
20 using views::NativeThemeDelegate;
13 21
14 namespace libgtk2ui { 22 namespace libgtk2ui {
15 23
16 namespace { 24 namespace {
17 25
18 GtkStateType ViewsToGtkState(views::Button::ButtonState state) { 26 GtkStateType GetGtkState(ui::NativeTheme::State state) {
19 switch (state) { 27 switch (state) {
20 case views::Button::STATE_HOVERED: 28 case ui::NativeTheme::kDisabled: return GTK_STATE_INSENSITIVE;
21 return GTK_STATE_PRELIGHT; 29 case ui::NativeTheme::kHovered: return GTK_STATE_PRELIGHT;
22 case views::Button::STATE_PRESSED: 30 case ui::NativeTheme::kNormal: return GTK_STATE_NORMAL;
23 return GTK_STATE_ACTIVE; 31 case ui::NativeTheme::kPressed: return GTK_STATE_ACTIVE;
24 case views::Button::STATE_DISABLED: 32 case ui::NativeTheme::kMaxState: NOTREACHED() << "Unknown state: " << state;
25 return GTK_STATE_INSENSITIVE;
26 default:
27 return GTK_STATE_NORMAL;
28 } 33 }
34 return GTK_STATE_NORMAL;
29 } 35 }
30 36
31 class ButtonImageSkiaSource : public gfx::ImageSkiaSource { 37 class ButtonImageSkiaSource : public gfx::ImageSkiaSource {
32 public: 38 public:
33 ButtonImageSkiaSource(const Gtk2UI* gtk2_ui, 39 ButtonImageSkiaSource(const Gtk2UI* gtk2_ui,
34 GtkStateType state, 40 const GtkStateType state,
41 const bool focused,
35 const gfx::Size& size) 42 const gfx::Size& size)
36 : gtk2_ui_(gtk2_ui), 43 : gtk2_ui_(gtk2_ui),
37 state_(state), 44 state_(state),
45 focused_(focused),
38 size_(size) { 46 size_(size) {
39 } 47 }
40 48
41 virtual ~ButtonImageSkiaSource() { 49 virtual ~ButtonImageSkiaSource() {
42 } 50 }
43 51
44 virtual gfx::ImageSkiaRep GetImageForScale(float scale) OVERRIDE { 52 virtual gfx::ImageSkiaRep GetImageForScale(float scale) OVERRIDE {
45 int w = size_.width() * scale; 53 int w = size_.width() * scale;
46 int h = size_.height() * scale; 54 int h = size_.height() * scale;
47 return gfx::ImageSkiaRep( 55 return gfx::ImageSkiaRep(
48 gtk2_ui_->DrawGtkButtonBorder(state_, w, h), scale); 56 gtk2_ui_->DrawGtkButtonBorder(state_, focused_, w, h), scale);
49 } 57 }
50 58
51 private: 59 private:
52 const Gtk2UI* gtk2_ui_; 60 const Gtk2UI* gtk2_ui_;
53 const GtkStateType state_; 61 const GtkStateType state_;
62 const bool focused_;
54 const gfx::Size size_; 63 const gfx::Size size_;
55 64
56 DISALLOW_COPY_AND_ASSIGN(ButtonImageSkiaSource); 65 DISALLOW_COPY_AND_ASSIGN(ButtonImageSkiaSource);
57 }; 66 };
58 67
59 } // namespace 68 } // namespace
60 69
61 Gtk2Border::Gtk2Border(Gtk2UI* gtk2_ui, 70 Gtk2Border::Gtk2Border(Gtk2UI* gtk2_ui,
62 views::CustomButton* owning_button, 71 views::LabelButton* owning_button,
63 scoped_ptr<views::Border> border) 72 scoped_ptr<views::Border> border)
64 : gtk2_ui_(gtk2_ui), 73 : gtk2_ui_(gtk2_ui),
65 use_gtk_(gtk2_ui_->GetUseSystemTheme()), 74 use_gtk_(gtk2_ui_->GetUseSystemTheme()),
66 owning_button_(owning_button), 75 owning_button_(owning_button),
67 border_(border.Pass()) { 76 border_(border.Pass()) {
68 gtk2_ui_->AddGtkBorder(this); 77 gtk2_ui_->AddGtkBorder(this);
69 } 78 }
70 79
71 Gtk2Border::~Gtk2Border() { 80 Gtk2Border::~Gtk2Border() {
72 gtk2_ui_->RemoveGtkBorder(this); 81 gtk2_ui_->RemoveGtkBorder(this);
73 } 82 }
74 83
75 void Gtk2Border::InvalidateAndSetUsesGtk(bool use_gtk) { 84 void Gtk2Border::InvalidateAndSetUsesGtk(bool use_gtk) {
76 hovered_ = gfx::ImageSkia(); 85 for (int i = 0; i < 2; ++i)
sky 2014/01/25 00:41:32 arraysize or a constant? I would also add parens a
77 pressed_ = gfx::ImageSkia(); 86 for (int j = 0; j < views::Button::STATE_COUNT; ++j)
87 button_images_[i][j] = gfx::ImageSkia();
78 88
79 // Our owning view must have its layout invalidated because the insets could 89 // Our owning view must have its layout invalidated because the insets could
80 // have changed. 90 // have changed.
81 owning_button_->InvalidateLayout(); 91 owning_button_->InvalidateLayout();
82 92
83 use_gtk_ = use_gtk; 93 use_gtk_ = use_gtk;
84 } 94 }
85 95
86 void Gtk2Border::Paint(const views::View& view, gfx::Canvas* canvas) { 96 void Gtk2Border::Paint(const views::View& view, gfx::Canvas* canvas) {
87 if (!use_gtk_) { 97 if (!use_gtk_) {
88 border_->Paint(view, canvas); 98 border_->Paint(view, canvas);
89 return; 99 return;
90 } 100 }
91 101
92 DCHECK_EQ(&view, owning_button_); 102 DCHECK_EQ(&view, owning_button_);
93 GtkStateType state = ViewsToGtkState(owning_button_->state()); 103 const NativeThemeDelegate* native_theme_delegate = owning_button_;
104 gfx::Rect rect(native_theme_delegate->GetThemePaintRect());
105 ui::NativeTheme::ExtraParams extra;
106 ui::NativeTheme::State state = native_theme_delegate->GetThemeState(&extra);
94 107
95 if (state == GTK_STATE_PRELIGHT) { 108 const gfx::Animation* animation = native_theme_delegate->GetThemeAnimation();
96 if (hovered_.isNull() || hovered_.size() != view.size()) { 109 if (animation && animation->is_animating()) {
97 hovered_ = gfx::ImageSkia( 110 // Linearly interpolate background and foreground painters during animation.
98 new ButtonImageSkiaSource(gtk2_ui_, state, view.size()), view.size()); 111 const SkRect sk_rect = gfx::RectToSkRect(rect);
99 } 112 canvas->sk_canvas()->saveLayer(&sk_rect, NULL);
113 state = native_theme_delegate->GetBackgroundThemeState(&extra);
114 PaintState(state, extra, rect, canvas);
100 115
101 canvas->DrawImageInt(hovered_, 0, 0); 116 SkPaint paint;
102 } else if (state == GTK_STATE_ACTIVE) { 117 skia::RefPtr<SkXfermode> sk_lerp_xfer =
103 if (pressed_.isNull() || pressed_.size() != view.size()) { 118 skia::AdoptRef(SkLerpXfermode::Create(animation->GetCurrentValue()));
104 pressed_ = gfx::ImageSkia( 119 paint.setXfermode(sk_lerp_xfer.get());
105 new ButtonImageSkiaSource(gtk2_ui_, state, view.size()), view.size()); 120 canvas->sk_canvas()->saveLayer(&sk_rect, &paint);
106 } 121 state = native_theme_delegate->GetForegroundThemeState(&extra);
122 PaintState(state, extra, rect, canvas);
123 canvas->sk_canvas()->restore();
107 124
108 canvas->DrawImageInt(pressed_, 0, 0); 125 canvas->sk_canvas()->restore();
126 } else {
127 PaintState(state, extra, rect, canvas);
109 } 128 }
110 } 129 }
111 130
112 gfx::Insets Gtk2Border::GetInsets() const { 131 gfx::Insets Gtk2Border::GetInsets() const {
113 if (!use_gtk_) 132 if (!use_gtk_)
114 return border_->GetInsets(); 133 return border_->GetInsets();
115 134
116 return gtk2_ui_->GetButtonInsets(); 135 return gtk2_ui_->GetButtonInsets();
117 } 136 }
118 137
119 gfx::Size Gtk2Border::GetMinimumSize() const { 138 gfx::Size Gtk2Border::GetMinimumSize() const {
120 if (!use_gtk_) 139 if (!use_gtk_)
121 return border_->GetMinimumSize(); 140 return border_->GetMinimumSize();
122 141
123 gfx::Insets insets = GetInsets(); 142 gfx::Insets insets = GetInsets();
124 return gfx::Size(insets.width(), insets.height()); 143 return gfx::Size(insets.width(), insets.height());
125 } 144 }
126 145
146 void Gtk2Border::PaintState(const ui::NativeTheme::State state,
147 const ui::NativeTheme::ExtraParams& extra,
148 const gfx::Rect& rect,
149 gfx::Canvas* canvas) {
150 bool focused = extra.button.is_focused;
151 Button::ButtonState views_state = Button::GetButtonStateFrom(state);
152
153 if (ShouldDrawBorder(focused, views_state)) {
154 gfx::ImageSkia* image = &button_images_[focused][views_state];
155
156 if (image->isNull() || image->size() != rect.size()) {
157 GtkStateType gtk_state = GetGtkState(state);
158 *image = gfx::ImageSkia(
159 new ButtonImageSkiaSource(gtk2_ui_, gtk_state, focused, rect.size()),
160 rect.size());
161 }
162 canvas->DrawImageInt(*image, rect.x(), rect.y());
163 }
164 }
165
166 bool Gtk2Border::ShouldDrawBorder(bool focused,
167 views::Button::ButtonState state) {
168 // This logic should be kept in sync with the LabelButtonBorder constructor.
169 if (owning_button_->style() == Button::STYLE_BUTTON) {
170 return true;
171 } else if (owning_button_->style() == Button::STYLE_TEXTBUTTON) {
172 return focused == false && (state == Button::STATE_HOVERED ||
173 state == Button::STATE_PRESSED);
174 }
175
176 return false;
177 }
178
127 } // namespace libgtk2ui 179 } // namespace libgtk2ui
OLDNEW
« no previous file with comments | « chrome/browser/ui/libgtk2ui/gtk2_border.h ('k') | chrome/browser/ui/libgtk2ui/gtk2_ui.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698