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

Side by Side Diff: ui/views/controls/button/button_border.cc

Issue 11068012: Add new views::LabelButton and LabelButtonBorder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix unit test build error; remove stray line. Created 8 years, 2 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
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "ui/views/controls/button/button_border.h"
6
7 #include "base/basictypes.h"
8 #include "base/logging.h"
9 #include "grit/ui_resources.h"
10 #include "ui/base/animation/animation.h"
11 #include "ui/base/resource/resource_bundle.h"
12 #include "ui/gfx/canvas.h"
13 #include "ui/views/controls/button/label_button.h"
14
15 namespace {
16
17 // Preferred padding between content and edge.
18 static const int kPreferredPaddingHorizontal = 6;
19 static const int kPreferredPaddingVertical = 5;
20
21 // Preferred padding between content and edge for NativeTheme border.
22 static const int kPreferredNativeThemePaddingHorizontal = 12;
23 static const int kPreferredNativeThemePaddingVertical = 5;
24
25 const int kHoverImageSet[] = {
26 IDR_TEXTBUTTON_HOVER_TOP_LEFT,
27 IDR_TEXTBUTTON_HOVER_TOP,
28 IDR_TEXTBUTTON_HOVER_TOP_RIGHT,
29 IDR_TEXTBUTTON_HOVER_LEFT,
30 IDR_TEXTBUTTON_HOVER_CENTER,
31 IDR_TEXTBUTTON_HOVER_RIGHT,
32 IDR_TEXTBUTTON_HOVER_BOTTOM_LEFT,
33 IDR_TEXTBUTTON_HOVER_BOTTOM,
34 IDR_TEXTBUTTON_HOVER_BOTTOM_RIGHT,
35 };
36
37 const int kPressedImageSet[] = {
38 IDR_TEXTBUTTON_PRESSED_TOP_LEFT,
39 IDR_TEXTBUTTON_PRESSED_TOP,
40 IDR_TEXTBUTTON_PRESSED_TOP_RIGHT,
41 IDR_TEXTBUTTON_PRESSED_LEFT,
42 IDR_TEXTBUTTON_PRESSED_CENTER,
43 IDR_TEXTBUTTON_PRESSED_RIGHT,
44 IDR_TEXTBUTTON_PRESSED_BOTTOM_LEFT,
45 IDR_TEXTBUTTON_PRESSED_BOTTOM,
46 IDR_TEXTBUTTON_PRESSED_BOTTOM_RIGHT,
47 };
48
49 } // namespace
50
51 namespace views {
52
53 ButtonBorder::ButtonBorder(NativeThemeDelegate* delegate)
54 : native_theme_delegate_(delegate),
55 native_theme_(false) {
56 SetImages(CustomButton::BS_HOT, BorderImages(kHoverImageSet));
57 SetImages(CustomButton::BS_PUSHED, BorderImages(kPressedImageSet));
58 }
59
60 ButtonBorder::~ButtonBorder() {}
61
62 ButtonBorder::BorderImages::BorderImages() {}
63
64 ButtonBorder::BorderImages::~BorderImages() {}
65
66 ButtonBorder::BorderImages::BorderImages(const int image_ids[]) {
67 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
68 top_left = *rb.GetImageSkiaNamed(image_ids[0]);
69 top = *rb.GetImageSkiaNamed(image_ids[1]);
70 top_right = *rb.GetImageSkiaNamed(image_ids[2]);
71 left = *rb.GetImageSkiaNamed(image_ids[3]);
72 center = *rb.GetImageSkiaNamed(image_ids[4]);
73 right = *rb.GetImageSkiaNamed(image_ids[5]);
74 bottom_left = *rb.GetImageSkiaNamed(image_ids[6]);
75 bottom = *rb.GetImageSkiaNamed(image_ids[7]);
76 bottom_right = *rb.GetImageSkiaNamed(image_ids[8]);
77 }
78
79 void ButtonBorder::SetImages(CustomButton::ButtonState state,
80 const BorderImages& set) {
81 images_[state] = set;
82 }
83
84 void ButtonBorder::Paint(const View& view, gfx::Canvas* canvas) const {
85 const CustomButton* button = static_cast<const CustomButton*>(&view);
86 if (native_theme()) {
87 PaintNativeTheme(view, canvas);
88 } else if (native_theme_delegate_->GetThemeAnimation() &&
89 native_theme_delegate_->GetThemeAnimation()->is_animating()) {
90 // TODO(pkasting|msw): Crossfade between button state image sets.
91 canvas->SaveLayerAlpha(static_cast<uint8>(native_theme_delegate_->
92 GetThemeAnimation()->CurrentValueBetween(0, 255)));
93 canvas->DrawColor(SkColorSetARGB(0x00, 0xFF, 0xFF, 0xFF),
94 SkXfermode::kClear_Mode);
95 PaintImages(view, canvas, button->state());
96 canvas->Restore();
97 } else {
98 PaintImages(view, canvas, button->state());
99 }
100 }
101
102 void ButtonBorder::GetInsets(gfx::Insets* insets) const {
103 if (native_theme()) {
104 insets->Set(kPreferredNativeThemePaddingVertical,
105 kPreferredNativeThemePaddingHorizontal,
106 kPreferredNativeThemePaddingVertical,
107 kPreferredNativeThemePaddingHorizontal);
108 } else {
109 insets->Set(kPreferredPaddingVertical, kPreferredPaddingHorizontal,
110 kPreferredPaddingVertical, kPreferredPaddingHorizontal);
111 }
112 }
113
114 void ButtonBorder::PaintImages(
115 const View& view,
116 gfx::Canvas* canvas,
117 CustomButton::ButtonState state) const {
118 const BorderImages& set = images_[state];
119 if (set.top_left.isNull())
120 return;
121
122 const int width = view.bounds().width();
123 const int height = view.bounds().height();
124 const int tl_width = set.top_left.width();
125 const int tl_height = set.top_left.height();
126 const int t_height = set.top.height();
127 const int tr_height = set.top_right.height();
128 const int l_width = set.left.width();
129 const int r_width = set.right.width();
130 const int bl_width = set.bottom_left.width();
131 const int bl_height = set.bottom_left.height();
132 const int b_height = set.bottom.height();
133 const int br_width = set.bottom_right.width();
134 const int br_height = set.bottom_right.height();
135
136 canvas->DrawImageInt(set.top_left, 0, 0);
137 canvas->DrawImageInt(set.top, 0, 0, set.top.width(), t_height, tl_width, 0,
138 width - tl_width - set.top_right.width(), t_height, false);
139 canvas->DrawImageInt(set.top_right, width - set.top_right.width(), 0);
140 canvas->DrawImageInt(set.left, 0, 0, l_width, set.left.height(), 0,
141 tl_height, tl_width, height - tl_height - bl_height, false);
142 canvas->DrawImageInt(set.center, 0, 0, set.center.width(),
143 set.center.height(), l_width, t_height, width - l_width - r_width,
144 height - t_height - b_height, false);
145 canvas->DrawImageInt(set.right, 0, 0, r_width, set.right.height(),
146 width - r_width, tr_height, r_width,
147 height - tr_height - br_height, false);
148 canvas->DrawImageInt(set.bottom_left, 0, height - bl_height);
149 canvas->DrawImageInt(set.bottom, 0, 0, set.bottom.width(), b_height,
150 bl_width, height - b_height,
151 width - bl_width - br_width, b_height, false);
152 canvas->DrawImageInt(set.bottom_right, width - br_width,
153 height - br_height);
154 }
155
156 void ButtonBorder::PaintNativeTheme(const View& view,
157 gfx::Canvas* canvas) const {
158 const ui::NativeTheme* theme = ui::NativeTheme::instance();
159 ui::NativeTheme::Part part = native_theme_delegate_->GetThemePart();
160 gfx::Rect rect(native_theme_delegate_->GetThemePaintRect());
161
162 ui::NativeTheme::State state;
163 ui::NativeTheme::ExtraParams extra;
164 const ui::Animation* animation = native_theme_delegate_->GetThemeAnimation();
165 if (animation && animation->is_animating()) {
166 // Paint the background state.
167 state = native_theme_delegate_->GetBackgroundThemeState(&extra);
168 theme->Paint(canvas->sk_canvas(), part, state, rect, extra);
169
170 // Composite the foreground state above the background state.
171 state = native_theme_delegate_->GetForegroundThemeState(&extra);
172 const int alpha = animation->CurrentValueBetween(0, 255);
173 canvas->SaveLayerAlpha(static_cast<uint8>(alpha));
174 theme->Paint(canvas->sk_canvas(), part, state, rect, extra);
175 canvas->Restore();
176 } else {
177 state = native_theme_delegate_->GetThemeState(&extra);
178 theme->Paint(canvas->sk_canvas(), part, state, rect, extra);
179 }
180
181 #if defined(OS_WIN)
182 // Draw the Views focus border for the Windows native theme style.
183 if (view.focus_border() && extra.button.is_focused)
184 view.focus_border()->Paint(view, canvas);
185 #endif
186 }
187
188 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698