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

Side by Side Diff: samplecode/SampleBevel.cpp

Issue 2246243002: Interactive Bevel Sample App (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: Controls now use Rect::MakeXYWH, constants are now SkScalar Created 4 years, 4 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
« no previous file with comments | « gyp/samples.gypi ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SampleCode.h"
9 #include "SkCanvas.h"
10 #include "SkLightingShader.h"
11 #include "SkNormalSource.h"
12 #include "sk_tool_utils.h"
13
14
15 class BevelView : public SampleView {
16 public:
17 BevelView()
18 : fShapeBounds(SkRect::MakeWH(kShapeBoundsSize, kShapeBoundsSize))
19 , fRedLight(SkLights::Light::MakeDirectional(SkColor3f::Make(0.6f, 0.45f , 0.3f),
20 SkVector3::Make(0.0f, -5.0f , 1.0f)))
21 , fBlueLight(SkLights::Light::MakeDirectional(SkColor3f::Make(0.3f, 0.45 f, 0.6f),
22 SkVector3::Make(0.0f, 5.0f , 1.0f))) {
23 this->setBGColor(0xFF666868); // Slightly colorized gray for contrast
24
25 // Lights
26 SkLights::Builder builder;
27 builder.add(fRedLight);
28 builder.add(fBlueLight);
29 builder.add(SkLights::Light::MakeAmbient(SkColor3f::Make(0.4f, 0.4f, 0.4 f)));
30 fLights = builder.finish();
31
32 // Controls
33
34 SkScalar currY = kSliderHeight;
35
36 fCtrlRangeRects[0] = SkRect::MakeXYWH(0.0f, currY,
37 kCtrlRange + kSliderWidth,
38 kSliderHeight);
39 fWidthCtrlRect = SkRect::MakeXYWH(0.3f * kCtrlRange, currY,
40 kSliderWidth, kSliderHeight);
41 fBevelWidth = kBevelWidthMax * 0.3f;
42 currY += 2 * kSliderHeight;
43
44 fCtrlRangeRects[1] = SkRect::MakeXYWH(0.0f, currY,
45 kCtrlRange + kSliderWidth,
46 kSliderHeight);
47 fHeightCtrlRect = SkRect::MakeXYWH(0.75f * kCtrlRange, currY,
egdaniel 2016/08/17 19:12:54 lets make a constant kStartHeightSomeThing for 0.7
dvonbeck 2016/08/17 19:33:37 Done.
48 kSliderWidth, kSliderHeight);
49 fBevelHeight = kBevelHeightMax * (0.75f * 2.0f - 1.0f); // Mapping from (0, 1) to (-1, 1)
50 currY += 2 * kSliderHeight;
51
52 fCtrlRangeRects[2] = SkRect::MakeXYWH(0.0f, currY,
53 kCtrlRange + kSliderWidth,
54 kSliderHeight);
55 fTypeCtrlRect = SkRect::MakeXYWH((1.0f/6.0f) * kCtrlRange, currY,
56 kSliderWidth, kSliderHeight);
57 fBevelType = (SkNormalSource::BevelType) 0;
58 currY += 2 * kSliderHeight;
59
60 fSelectedCtrlRect = nullptr;
61 }
62
63 protected:
64 bool onQuery(SkEvent *evt) override {
65 if (SampleCode::TitleQ(*evt)) {
66 SampleCode::TitleR(evt, "bevel");
67 return true;
68 }
69
70 return this->INHERITED::onQuery(evt);
71 }
72
73 enum Shape {
74 kCircle_Shape,
75 kRect_Shape,
76 };
77 void drawShape(enum Shape shape, SkCanvas* canvas) {
78 canvas->save();
79
80 SkPaint paint;
81
82 sk_sp<SkNormalSource> normalSource = SkNormalSource::MakeBevel(fBevelTyp e, fBevelWidth,
83 fBevelHei ght);
84
85 paint.setShader(SkLightingShader::Make(nullptr, std::move(normalSource), fLights));
86 paint.setAntiAlias(true);
87 paint.setColor(0xFFDDDDDD);
88 switch (shape) {
89 case kCircle_Shape:
90 canvas->drawCircle(fShapeBounds.centerX(), fShapeBounds.centerY( ),
91 fShapeBounds.width()/2.0f, paint);
92 break;
93 case kRect_Shape:
94 canvas->drawRect(fShapeBounds, paint);
95 break;
96 default:
97 SkDEBUGFAIL("Invalid shape enum for drawShape");
98 }
99
100 canvas->restore();
101 }
102
103 void onDrawContent(SkCanvas *canvas) override {
104
105 canvas->save();
106 canvas->resetMatrix(); // Force static controls and labels
107
108 // Draw controls
109
110 SkPaint ctrlRectPaint;
111 ctrlRectPaint.setColor(0xFFF3F3F3);
112 canvas->drawRect(fWidthCtrlRect, ctrlRectPaint);
113 canvas->drawRect(fHeightCtrlRect, ctrlRectPaint);
114 canvas->drawRect(fTypeCtrlRect, ctrlRectPaint);
115
116 SkPaint ctrlRectRangePaint;
117 ctrlRectRangePaint.setColor(0xFFFFFFFF);
118 ctrlRectRangePaint.setStyle(SkPaint::kStroke_Style);
119 ctrlRectRangePaint.setStrokeWidth(2.0f);
120
121 for (size_t i = 0; i < kNumControls; i++) {
122 canvas->drawRect(fCtrlRangeRects[i], ctrlRectRangePaint);
123 }
124
125 // Draw labels
126 constexpr SkScalar kTextSize = 12.0f;
127 SkString widthLabel, heightLabel, typeLabel;
128 SkPaint labelPaint;
129 labelPaint.setTypeface(sk_tool_utils::create_portable_typeface("sans-ser if",
130 SkFontSty le()));
131 labelPaint.setAntiAlias(true);
132 labelPaint.setColor(0xFFFFFFFF);
133 labelPaint.setTextSize(kTextSize);
134
135 widthLabel.appendf("BevelWidth: %f", fBevelWidth);
136 heightLabel.appendf("BevelHeight: %f", fBevelHeight);
137 typeLabel.append("BevelType: ");
138
139 switch (fBevelType) {
140 case SkNormalSource::BevelType::kLinear:
141 typeLabel.append("Linear");
142 break;
143 case SkNormalSource::BevelType::kRoundedIn:
144 typeLabel.append("RoundedIn");
145 break;
146 case SkNormalSource::BevelType::kRoundedOut:
147 typeLabel.append("RoundedOut");
148 break;
149 }
150
151 canvas->drawText(widthLabel.c_str(), widthLabel.size(), 0,
152 fWidthCtrlRect.fTop - kTextSize/2.0f, labelPaint);
153 canvas->drawText(heightLabel.c_str(), heightLabel.size(), 0,
154 fHeightCtrlRect.fTop - kTextSize/2.0f, labelPaint);
155 canvas->drawText(typeLabel.c_str(), typeLabel.size(), 0,
156 fTypeCtrlRect.fTop - kTextSize/2.0f, labelPaint);
157
158 canvas->restore(); // Return to modified matrix when drawing shapes
159
160 // Draw shapes
161 SkScalar xPos = kCtrlRange + 25.0f;
162 SkScalar yPos = fShapeBounds.height();
163 for (Shape shape : { kCircle_Shape, kRect_Shape }) {
164 canvas->save();
165 canvas->translate(xPos, yPos);
166 this->drawShape(shape, canvas);
167 canvas->restore();
168
169 xPos += 1.2f * fShapeBounds.width();
170 }
171 }
172
173 SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) ove rride {
174 return new SkView::Click(this);
175 }
176
177 bool onClick(Click *click) override {
178 SkScalar x = click->fCurr.fX;
179 SkScalar y = click->fCurr.fY;
180
181 SkScalar dx = x - click->fPrev.fX;
182 SkScalar dy = y - click->fPrev.fY;
183
184 // Control deselection
185 if (Click::State::kUp_State == click->fState) {
186 fSelectedCtrlRect = nullptr;
187 return true;
188 }
189
190 // Control selection
191 if (nullptr == fSelectedCtrlRect && Click::State::kDown_State == click-> fState) {
192 if (fWidthCtrlRect.contains(SkRect::MakeXYWH(x, y, 1, 1))) {
193 fSelectedCtrlRect = &fWidthCtrlRect;
194 } else if (fHeightCtrlRect.contains(SkRect::MakeXYWH(x, y, 1, 1))) {
195 fSelectedCtrlRect = &fHeightCtrlRect;
196 } else if (fTypeCtrlRect.contains(SkRect::MakeXYWH(x, y, 1, 1))) {
197 fSelectedCtrlRect = &fTypeCtrlRect;
198 }
199 }
200
201 // Control modification
202 if (nullptr != fSelectedCtrlRect) {
203 fSelectedCtrlRect->offsetTo(SkScalarPin(x, 0.0f, kCtrlRange), fSelec tedCtrlRect->fTop);
204
205 fBevelHeight = (fHeightCtrlRect.fLeft / kCtrlRange) * kBevelHeightMa x * 2.0f
206 - kBevelHeightMax;
207 fBevelWidth = (fWidthCtrlRect.fLeft / kCtrlRange) * kBevelWidthMax;
208 fBevelType = (SkNormalSource::BevelType)SkTMin(
209 SkScalarFloorToInt(3.0f * fTypeCtrlRect.fLeft / kCtrlRange),
210 2);
211
212 // Snap type controls to 3 positions
213 fTypeCtrlRect.offsetTo(kCtrlRange * ( ((int)fBevelType)/3.0f + 1.0f/ 6.0f ),
214 fTypeCtrlRect.fTop);
215
216 // Ensuring width is non-zero
217 fBevelWidth = SkMaxScalar(1.0f, fBevelWidth);
218
219 this->inval(nullptr);
220 return true;
221 }
222
223 // Moving light
224 if (nullptr == fSelectedCtrlRect) {
225 if (dx != 0 || dy != 0) {
226 float recipX = 1.0f / kAppWidth;
227 float recipY = 1.0f / kAppHeight;
228
229 if (0 == click->fModifierKeys) { // No modifier
230 fBlueLight = SkLights::Light::MakeDirectional(fBlueLight.col or(),
231 SkVector3::Make((kAppWidth/2.0f - x) * recipX * -3.0 f,
232 (kAppHeight/2.0f - y) * recipY * -3. 0f,
233 1.0f));
234 } else if (1 == click->fModifierKeys) { // Shift key
235 fRedLight = SkLights::Light::MakeDirectional(fRedLight.color (),
236 SkVector3::Make((kAppWidth/2.0f - x) * recipX * -3.0 f,
237 (kAppHeight/2.0f - y) * recipY * -3. 0f,
238 1.0f));
239 }
240
241 SkLights::Builder builder;
242 builder.add(fRedLight);
243 builder.add(fBlueLight);
244 builder.add(SkLights::Light::MakeAmbient(
245 SkColor3f::Make(0.4f, 0.4f, 0.4f)));
246 fLights = builder.finish();
247
248 this->inval(nullptr);
249 }
250 return true;
251 }
252
253 return true;
254 }
255
256 private:
257 static constexpr int kNumTestRects = 3;
258
259 static constexpr SkScalar kAppWidth = 400.0f;
260 static constexpr SkScalar kAppHeight = 400.0f;
261 static constexpr SkScalar kShapeBoundsSize = 120.0f;
262
263 static constexpr SkScalar kCtrlRange = 150.0f;
264 static constexpr SkScalar kBevelWidthMax = 100.0f;
egdaniel 2016/08/17 19:12:54 Can we make this equal to kShapeBoundsSize? Thus i
dvonbeck 2016/08/17 19:33:37 Done.
265 static constexpr SkScalar kBevelHeightMax = 50.0f;
266
267 static constexpr SkScalar kSliderHeight = 20.0f;
268 static constexpr SkScalar kSliderWidth = 10.0f;
269
270 const SkRect fShapeBounds;
271
272 static constexpr int kNumControls = 3;
273 SkRect fCtrlRangeRects[kNumControls];
274 SkRect* fSelectedCtrlRect;
275 SkRect fWidthCtrlRect;
276 SkRect fHeightCtrlRect;
277 SkRect fTypeCtrlRect;
278
279 SkScalar fBevelWidth;
280 SkScalar fBevelHeight;
281 SkNormalSource::BevelType fBevelType;
282
283 sk_sp<SkLights> fLights;
284 SkLights::Light fRedLight;
285 SkLights::Light fBlueLight;
286
287 typedef SampleView INHERITED;
288 };
289
290 //////////////////////////////////////////////////////////////////////////////
291
292 static SkView* MyFactory() { return new BevelView; }
293 static SkViewRegister reg(MyFactory);
294
OLDNEW
« no previous file with comments | « gyp/samples.gypi ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698