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

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: constant and braces 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 const int kNumberOfFocusedStates = 2;
27
28 GtkStateType GetGtkState(ui::NativeTheme::State state) {
19 switch (state) { 29 switch (state) {
20 case views::Button::STATE_HOVERED: 30 case ui::NativeTheme::kDisabled: return GTK_STATE_INSENSITIVE;
21 return GTK_STATE_PRELIGHT; 31 case ui::NativeTheme::kHovered: return GTK_STATE_PRELIGHT;
22 case views::Button::STATE_PRESSED: 32 case ui::NativeTheme::kNormal: return GTK_STATE_NORMAL;
23 return GTK_STATE_ACTIVE; 33 case ui::NativeTheme::kPressed: return GTK_STATE_ACTIVE;
24 case views::Button::STATE_DISABLED: 34 case ui::NativeTheme::kMaxState: NOTREACHED() << "Unknown state: " << state;
25 return GTK_STATE_INSENSITIVE;
26 default:
27 return GTK_STATE_NORMAL;
28 } 35 }
36 return GTK_STATE_NORMAL;
29 } 37 }
30 38
31 class ButtonImageSkiaSource : public gfx::ImageSkiaSource { 39 class ButtonImageSkiaSource : public gfx::ImageSkiaSource {
32 public: 40 public:
33 ButtonImageSkiaSource(const Gtk2UI* gtk2_ui, 41 ButtonImageSkiaSource(const Gtk2UI* gtk2_ui,
34 GtkStateType state, 42 const GtkStateType state,
43 const bool focused,
35 const gfx::Size& size) 44 const gfx::Size& size)
36 : gtk2_ui_(gtk2_ui), 45 : gtk2_ui_(gtk2_ui),
37 state_(state), 46 state_(state),
47 focused_(focused),
38 size_(size) { 48 size_(size) {
39 } 49 }
40 50
41 virtual ~ButtonImageSkiaSource() { 51 virtual ~ButtonImageSkiaSource() {
42 } 52 }
43 53
44 virtual gfx::ImageSkiaRep GetImageForScale(float scale) OVERRIDE { 54 virtual gfx::ImageSkiaRep GetImageForScale(float scale) OVERRIDE {
45 int w = size_.width() * scale; 55 int w = size_.width() * scale;
46 int h = size_.height() * scale; 56 int h = size_.height() * scale;
47 return gfx::ImageSkiaRep( 57 return gfx::ImageSkiaRep(
48 gtk2_ui_->DrawGtkButtonBorder(state_, w, h), scale); 58 gtk2_ui_->DrawGtkButtonBorder(state_, focused_, w, h), scale);
49 } 59 }
50 60
51 private: 61 private:
52 const Gtk2UI* gtk2_ui_; 62 const Gtk2UI* gtk2_ui_;
53 const GtkStateType state_; 63 const GtkStateType state_;
64 const bool focused_;
54 const gfx::Size size_; 65 const gfx::Size size_;
55 66
56 DISALLOW_COPY_AND_ASSIGN(ButtonImageSkiaSource); 67 DISALLOW_COPY_AND_ASSIGN(ButtonImageSkiaSource);
57 }; 68 };
58 69
59 } // namespace 70 } // namespace
60 71
61 Gtk2Border::Gtk2Border(Gtk2UI* gtk2_ui, 72 Gtk2Border::Gtk2Border(Gtk2UI* gtk2_ui,
62 views::CustomButton* owning_button, 73 views::LabelButton* owning_button,
63 scoped_ptr<views::Border> border) 74 scoped_ptr<views::Border> border)
64 : gtk2_ui_(gtk2_ui), 75 : gtk2_ui_(gtk2_ui),
65 use_gtk_(gtk2_ui_->GetUseSystemTheme()), 76 use_gtk_(gtk2_ui_->GetUseSystemTheme()),
66 owning_button_(owning_button), 77 owning_button_(owning_button),
67 border_(border.Pass()) { 78 border_(border.Pass()) {
68 gtk2_ui_->AddGtkBorder(this); 79 gtk2_ui_->AddGtkBorder(this);
69 } 80 }
70 81
71 Gtk2Border::~Gtk2Border() { 82 Gtk2Border::~Gtk2Border() {
72 gtk2_ui_->RemoveGtkBorder(this); 83 gtk2_ui_->RemoveGtkBorder(this);
73 } 84 }
74 85
75 void Gtk2Border::InvalidateAndSetUsesGtk(bool use_gtk) { 86 void Gtk2Border::InvalidateAndSetUsesGtk(bool use_gtk) {
76 hovered_ = gfx::ImageSkia(); 87 for (int i = 0; i < kNumberOfFocusedStates; ++i) {
77 pressed_ = gfx::ImageSkia(); 88 for (int j = 0; j < views::Button::STATE_COUNT; ++j) {
89 button_images_[i][j] = gfx::ImageSkia();
90 }
91 }
78 92
79 // Our owning view must have its layout invalidated because the insets could 93 // Our owning view must have its layout invalidated because the insets could
80 // have changed. 94 // have changed.
81 owning_button_->InvalidateLayout(); 95 owning_button_->InvalidateLayout();
82 96
83 use_gtk_ = use_gtk; 97 use_gtk_ = use_gtk;
84 } 98 }
85 99
86 void Gtk2Border::Paint(const views::View& view, gfx::Canvas* canvas) { 100 void Gtk2Border::Paint(const views::View& view, gfx::Canvas* canvas) {
87 if (!use_gtk_) { 101 if (!use_gtk_) {
88 border_->Paint(view, canvas); 102 border_->Paint(view, canvas);
89 return; 103 return;
90 } 104 }
91 105
92 DCHECK_EQ(&view, owning_button_); 106 DCHECK_EQ(&view, owning_button_);
93 GtkStateType state = ViewsToGtkState(owning_button_->state()); 107 const NativeThemeDelegate* native_theme_delegate = owning_button_;
108 gfx::Rect rect(native_theme_delegate->GetThemePaintRect());
109 ui::NativeTheme::ExtraParams extra;
110 ui::NativeTheme::State state = native_theme_delegate->GetThemeState(&extra);
94 111
95 if (state == GTK_STATE_PRELIGHT) { 112 const gfx::Animation* animation = native_theme_delegate->GetThemeAnimation();
96 if (hovered_.isNull() || hovered_.size() != view.size()) { 113 if (animation && animation->is_animating()) {
97 hovered_ = gfx::ImageSkia( 114 // Linearly interpolate background and foreground painters during animation.
98 new ButtonImageSkiaSource(gtk2_ui_, state, view.size()), view.size()); 115 const SkRect sk_rect = gfx::RectToSkRect(rect);
99 } 116 canvas->sk_canvas()->saveLayer(&sk_rect, NULL);
117 state = native_theme_delegate->GetBackgroundThemeState(&extra);
118 PaintState(state, extra, rect, canvas);
100 119
101 canvas->DrawImageInt(hovered_, 0, 0); 120 SkPaint paint;
102 } else if (state == GTK_STATE_ACTIVE) { 121 skia::RefPtr<SkXfermode> sk_lerp_xfer =
103 if (pressed_.isNull() || pressed_.size() != view.size()) { 122 skia::AdoptRef(SkLerpXfermode::Create(animation->GetCurrentValue()));
104 pressed_ = gfx::ImageSkia( 123 paint.setXfermode(sk_lerp_xfer.get());
105 new ButtonImageSkiaSource(gtk2_ui_, state, view.size()), view.size()); 124 canvas->sk_canvas()->saveLayer(&sk_rect, &paint);
106 } 125 state = native_theme_delegate->GetForegroundThemeState(&extra);
126 PaintState(state, extra, rect, canvas);
127 canvas->sk_canvas()->restore();
107 128
108 canvas->DrawImageInt(pressed_, 0, 0); 129 canvas->sk_canvas()->restore();
130 } else {
131 PaintState(state, extra, rect, canvas);
109 } 132 }
110 } 133 }
111 134
112 gfx::Insets Gtk2Border::GetInsets() const { 135 gfx::Insets Gtk2Border::GetInsets() const {
113 if (!use_gtk_) 136 if (!use_gtk_)
114 return border_->GetInsets(); 137 return border_->GetInsets();
115 138
116 return gtk2_ui_->GetButtonInsets(); 139 return gtk2_ui_->GetButtonInsets();
117 } 140 }
118 141
119 gfx::Size Gtk2Border::GetMinimumSize() const { 142 gfx::Size Gtk2Border::GetMinimumSize() const {
120 if (!use_gtk_) 143 if (!use_gtk_)
121 return border_->GetMinimumSize(); 144 return border_->GetMinimumSize();
122 145
123 gfx::Insets insets = GetInsets(); 146 gfx::Insets insets = GetInsets();
124 return gfx::Size(insets.width(), insets.height()); 147 return gfx::Size(insets.width(), insets.height());
125 } 148 }
126 149
150 void Gtk2Border::PaintState(const ui::NativeTheme::State state,
151 const ui::NativeTheme::ExtraParams& extra,
152 const gfx::Rect& rect,
153 gfx::Canvas* canvas) {
154 bool focused = extra.button.is_focused;
155 Button::ButtonState views_state = Button::GetButtonStateFrom(state);
156
157 if (ShouldDrawBorder(focused, views_state)) {
158 gfx::ImageSkia* image = &button_images_[focused][views_state];
159
160 if (image->isNull() || image->size() != rect.size()) {
161 GtkStateType gtk_state = GetGtkState(state);
162 *image = gfx::ImageSkia(
163 new ButtonImageSkiaSource(gtk2_ui_, gtk_state, focused, rect.size()),
164 rect.size());
165 }
166 canvas->DrawImageInt(*image, rect.x(), rect.y());
167 }
168 }
169
170 bool Gtk2Border::ShouldDrawBorder(bool focused,
171 views::Button::ButtonState state) {
172 // This logic should be kept in sync with the LabelButtonBorder constructor.
173 if (owning_button_->style() == Button::STYLE_BUTTON) {
174 return true;
175 } else if (owning_button_->style() == Button::STYLE_TEXTBUTTON) {
176 return focused == false && (state == Button::STATE_HOVERED ||
177 state == Button::STATE_PRESSED);
178 }
179
180 return false;
181 }
182
127 } // namespace libgtk2ui 183 } // 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