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

Side by Side Diff: samplecode/SampleBevel.cpp

Issue 2246243002: Interactive Bevel Sample App (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: Initial position now a constant variable, number of bevel types now a constant variable, MaxWidth n… 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 const SkScalar kWidthCtrlInitialPos = 0.2f;
37 fCtrlRangeRects[0] = SkRect::MakeXYWH(0.0f, currY,
38 kCtrlRange + kSliderWidth,
39 kSliderHeight);
robertphillips 2016/08/17 21:52:13 Well, since Greg sort of brought it up, would it m
dvonbeck 2016/08/17 22:10:22 I am actually working on this for my next CL. I am
robertphillips 2016/08/18 14:40:41 Okay - let's leave it for the follow on.
dvonbeck 2016/08/18 15:12:14 Acknowledged.
40 fWidthCtrlRect = SkRect::MakeXYWH(kWidthCtrlInitialPos * kCtrlRange, cur rY,
41 kSliderWidth, kSliderHeight);
42 fBevelWidth = kBevelWidthMax * kWidthCtrlInitialPos;
43 currY += 2 * kSliderHeight;
44
45 const SkScalar kHeightCtrlInitialPos = 0.75f;
46 fCtrlRangeRects[1] = SkRect::MakeXYWH(0.0f, currY,
47 kCtrlRange + kSliderWidth,
48 kSliderHeight);
49 fHeightCtrlRect = SkRect::MakeXYWH(kHeightCtrlInitialPos * kCtrlRange, c urrY,
50 kSliderWidth, kSliderHeight);
51 // Mapping from (0, 1) to (-1, 1)
52 fBevelHeight = kBevelHeightMax * (kHeightCtrlInitialPos * 2.0f - 1.0f);
53 currY += 2 * kSliderHeight;
54
55 const SkScalar kTypeCtrlInitialPos = 1.0f / (2.0f * kBevelTypeCount);
56 fCtrlRangeRects[2] = SkRect::MakeXYWH(0.0f, currY,
57 kCtrlRange + kSliderWidth,
58 kSliderHeight);
59 fTypeCtrlRect = SkRect::MakeXYWH(kTypeCtrlInitialPos * kCtrlRange, currY ,
60 kSliderWidth, kSliderHeight);
61 fBevelType = (SkNormalSource::BevelType) SkScalarFloorToInt(kTypeCtrlIni tialPos);
62 currY += 2 * kSliderHeight;
63
64 fSelectedCtrlRect = nullptr;
65 }
66
67 protected:
68 bool onQuery(SkEvent *evt) override {
69 if (SampleCode::TitleQ(*evt)) {
70 SampleCode::TitleR(evt, "bevel");
egdaniel 2016/08/18 14:33:28 We genearaly name samples with a capital letter an
dvonbeck 2016/08/18 15:12:14 Done.
71 return true;
72 }
73
74 return this->INHERITED::onQuery(evt);
75 }
76
77 enum Shape {
78 kCircle_Shape,
79 kRect_Shape,
80 };
81 void drawShape(enum Shape shape, SkCanvas* canvas) {
82 canvas->save();
83
84 SkPaint paint;
85
robertphillips 2016/08/18 14:40:41 We should probably be caching this and only recrea
dvonbeck 2016/08/18 15:12:13 Done.
86 sk_sp<SkNormalSource> normalSource = SkNormalSource::MakeBevel(fBevelTyp e, fBevelWidth,
87 fBevelHei ght);
88
89 paint.setShader(SkLightingShader::Make(nullptr, std::move(normalSource), fLights));
90 paint.setAntiAlias(true);
91 paint.setColor(0xFFDDDDDD);
92 switch (shape) {
93 case kCircle_Shape:
94 canvas->drawCircle(fShapeBounds.centerX(), fShapeBounds.centerY( ),
95 fShapeBounds.width()/2.0f, paint);
96 break;
97 case kRect_Shape:
98 canvas->drawRect(fShapeBounds, paint);
99 break;
100 default:
101 SkDEBUGFAIL("Invalid shape enum for drawShape");
102 }
103
104 canvas->restore();
105 }
106
107 void onDrawContent(SkCanvas *canvas) override {
108
109 canvas->save();
110 canvas->resetMatrix(); // Force static controls and labels
111
112 // Draw controls
113
114 SkPaint ctrlRectPaint;
115 ctrlRectPaint.setColor(0xFFF3F3F3);
116 canvas->drawRect(fWidthCtrlRect, ctrlRectPaint);
117 canvas->drawRect(fHeightCtrlRect, ctrlRectPaint);
118 canvas->drawRect(fTypeCtrlRect, ctrlRectPaint);
119
120 SkPaint ctrlRectRangePaint;
121 ctrlRectRangePaint.setColor(0xFFFFFFFF);
122 ctrlRectRangePaint.setStyle(SkPaint::kStroke_Style);
123 ctrlRectRangePaint.setStrokeWidth(2.0f);
124
125 for (size_t i = 0; i < kNumControls; i++) {
126 canvas->drawRect(fCtrlRangeRects[i], ctrlRectRangePaint);
127 }
128
129 // Draw labels
130 constexpr SkScalar kTextSize = 12.0f;
131 SkString widthLabel, heightLabel, typeLabel;
132 SkPaint labelPaint;
robertphillips 2016/08/18 14:40:41 Can we cache off the typeface and reuse it ?
dvonbeck 2016/08/18 15:12:14 Done.
133 labelPaint.setTypeface(sk_tool_utils::create_portable_typeface("sans-ser if",
134 SkFontSty le()));
135 labelPaint.setAntiAlias(true);
136 labelPaint.setColor(0xFFFFFFFF);
137 labelPaint.setTextSize(kTextSize);
138
139 widthLabel.appendf("BevelWidth: %f", fBevelWidth);
140 heightLabel.appendf("BevelHeight: %f", fBevelHeight);
141 typeLabel.append("BevelType: ");
142
143 switch (fBevelType) {
144 case SkNormalSource::BevelType::kLinear:
145 typeLabel.append("Linear");
146 break;
147 case SkNormalSource::BevelType::kRoundedIn:
148 typeLabel.append("RoundedIn");
149 break;
150 case SkNormalSource::BevelType::kRoundedOut:
151 typeLabel.append("RoundedOut");
152 break;
153 }
154
155 canvas->drawText(widthLabel.c_str(), widthLabel.size(), 0,
156 fWidthCtrlRect.fTop - kTextSize/2.0f, labelPaint);
157 canvas->drawText(heightLabel.c_str(), heightLabel.size(), 0,
158 fHeightCtrlRect.fTop - kTextSize/2.0f, labelPaint);
159 canvas->drawText(typeLabel.c_str(), typeLabel.size(), 0,
160 fTypeCtrlRect.fTop - kTextSize/2.0f, labelPaint);
161
162 canvas->restore(); // Return to modified matrix when drawing shapes
163
164 // Draw shapes
165 SkScalar xPos = kCtrlRange + 25.0f;
166 SkScalar yPos = fShapeBounds.height();
167 for (Shape shape : { kCircle_Shape, kRect_Shape }) {
168 canvas->save();
169 canvas->translate(xPos, yPos);
170 this->drawShape(shape, canvas);
171 canvas->restore();
172
173 xPos += 1.2f * fShapeBounds.width();
174 }
175 }
176
177 SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) ove rride {
178 return new SkView::Click(this);
179 }
180
181 bool onClick(Click *click) override {
182 SkScalar x = click->fCurr.fX;
183 SkScalar y = click->fCurr.fY;
184
185 SkScalar dx = x - click->fPrev.fX;
186 SkScalar dy = y - click->fPrev.fY;
187
188 // Control deselection
189 if (Click::State::kUp_State == click->fState) {
190 fSelectedCtrlRect = nullptr;
191 return true;
192 }
193
194 // Control selection
195 if (nullptr == fSelectedCtrlRect && Click::State::kDown_State == click-> fState) {
196 if (fWidthCtrlRect.contains(SkRect::MakeXYWH(x, y, 1, 1))) {
197 fSelectedCtrlRect = &fWidthCtrlRect;
198 } else if (fHeightCtrlRect.contains(SkRect::MakeXYWH(x, y, 1, 1))) {
199 fSelectedCtrlRect = &fHeightCtrlRect;
200 } else if (fTypeCtrlRect.contains(SkRect::MakeXYWH(x, y, 1, 1))) {
201 fSelectedCtrlRect = &fTypeCtrlRect;
202 }
203 }
204
205 // Control modification
206 if (nullptr != fSelectedCtrlRect) {
207 fSelectedCtrlRect->offsetTo(SkScalarPin(x, 0.0f, kCtrlRange), fSelec tedCtrlRect->fTop);
208
209 fBevelHeight = (fHeightCtrlRect.fLeft / kCtrlRange) * kBevelHeightMa x * 2.0f
210 - kBevelHeightMax;
211 fBevelWidth = (fWidthCtrlRect.fLeft / kCtrlRange) * kBevelWidthMax;
212 fBevelType = (SkNormalSource::BevelType)SkTMin(
213 SkScalarFloorToInt(kBevelTypeCount * fTypeCtrlRect.fLeft / k CtrlRange),
214 kBevelTypeCount - 1);
215
216 // Snap type controls to 3 positions
217 fTypeCtrlRect.offsetTo(kCtrlRange * ( ((int)fBevelType)/SkIntToScala r(kBevelTypeCount)
218 + 1.0f/(2.0f * kBevelTypeCount ) ),
219 fTypeCtrlRect.fTop);
220
221 // Ensuring width is non-zero
222 fBevelWidth = SkMaxScalar(1.0f, fBevelWidth);
223
224 this->inval(nullptr);
225 return true;
226 }
robertphillips 2016/08/18 14:40:41 should there be and else here ?
dvonbeck 2016/08/18 15:12:14 Done.
227
228 // Moving light
229 if (nullptr == fSelectedCtrlRect) {
230 if (dx != 0 || dy != 0) {
231 float recipX = 1.0f / kAppWidth;
232 float recipY = 1.0f / kAppHeight;
233
234 if (0 == click->fModifierKeys) { // No modifier
235 fBlueLight = SkLights::Light::MakeDirectional(fBlueLight.col or(),
236 SkVector3::Make((kAppWidth/2.0f - x) * recipX * -3.0 f,
237 (kAppHeight/2.0f - y) * recipY * -3. 0f,
238 1.0f));
239 } else if (1 == click->fModifierKeys) { // Shift key
240 fRedLight = SkLights::Light::MakeDirectional(fRedLight.color (),
241 SkVector3::Make((kAppWidth/2.0f - x) * recipX * -3.0 f,
242 (kAppHeight/2.0f - y) * recipY * -3. 0f,
243 1.0f));
244 }
245
246 SkLights::Builder builder;
247 builder.add(fRedLight);
248 builder.add(fBlueLight);
249 builder.add(SkLights::Light::MakeAmbient(
250 SkColor3f::Make(0.4f, 0.4f, 0.4f)));
251 fLights = builder.finish();
252
253 this->inval(nullptr);
254 }
255 return true;
256 }
257
258 return true;
259 }
260
261 private:
262 static constexpr int kNumTestRects = 3;
263
264 static constexpr SkScalar kAppWidth = 400.0f;
265 static constexpr SkScalar kAppHeight = 400.0f;
266 static constexpr SkScalar kShapeBoundsSize = 120.0f;
267
268 static constexpr SkScalar kCtrlRange = 150.0f;
269 static constexpr SkScalar kBevelWidthMax = kShapeBoundsSize;
270 static constexpr SkScalar kBevelHeightMax = 50.0f;
271 static constexpr int kBevelTypeCount = 3;
272
273 static constexpr SkScalar kSliderHeight = 20.0f;
274 static constexpr SkScalar kSliderWidth = 10.0f;
275
276 const SkRect fShapeBounds;
277
278 static constexpr int kNumControls = 3;
279 SkRect fCtrlRangeRects[kNumControls];
280 SkRect* fSelectedCtrlRect;
281 SkRect fWidthCtrlRect;
282 SkRect fHeightCtrlRect;
283 SkRect fTypeCtrlRect;
284
285 SkScalar fBevelWidth;
286 SkScalar fBevelHeight;
287 SkNormalSource::BevelType fBevelType;
288
289 sk_sp<SkLights> fLights;
290 SkLights::Light fRedLight;
291 SkLights::Light fBlueLight;
292
293 typedef SampleView INHERITED;
294 };
295
296 //////////////////////////////////////////////////////////////////////////////
297
298 static SkView* MyFactory() { return new BevelView; }
299 static SkViewRegister reg(MyFactory);
300
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