blob: 36170cf0292738ac8298f6bbede6dd66be770bd4 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "topaz/examples/ui/jank/jank_view.h"
#include <unistd.h>
#include <string>
#include "lib/component/cpp/connect.h"
#include "src/lib/fxl/logging.h"
#include "src/lib/fxl/macros.h"
#include "src/lib/fxl/time/time_delta.h"
namespace examples {
namespace {
constexpr SkScalar kButtonWidth = 300;
constexpr SkScalar kButtonHeight = 24;
constexpr SkScalar kTextSize = 10;
constexpr SkScalar kMargin = 10;
} // namespace
const JankView::Button JankView::kButtons[] = {
{"Hang for 10 seconds", Action::kHang10},
{"Stutter for 30 seconds", Action::kStutter30},
{"Crash!", Action::kCrash},
};
JankView::JankView(scenic::ViewContext view_context,
fuchsia::fonts::ProviderPtr font_provider)
: SkiaView(std::move(view_context), "Jank"),
font_loader_(std::move(font_provider)) {
font_loader_.LoadDefaultFont([this](sk_sp<SkTypeface> typeface) {
FXL_CHECK(typeface); // TODO(jeffbrown): Fail gracefully.
typeface_ = std::move(typeface);
InvalidateScene();
});
}
void JankView::OnSceneInvalidated(
fuchsia::images::PresentationInfo presentation_info) {
if (!typeface_)
return;
SkCanvas* canvas = AcquireCanvas();
if (!canvas)
return;
DrawContent(canvas);
ReleaseAndSwapCanvas();
// Stutter if needed.
if (stutter_end_time_ > fxl::TimePoint::Now())
sleep(2);
// Animate.
InvalidateScene();
}
void JankView::DrawContent(SkCanvas* canvas) {
SkScalar hsv[3] = {
static_cast<SkScalar>(
fmod(fxl::TimePoint::Now().ToEpochDelta().ToSecondsF() * 60, 360.)),
1, 1};
canvas->clear(SkHSVToColor(hsv));
SkScalar x = kMargin;
SkScalar y = kMargin;
for (const auto& button : kButtons) {
DrawButton(canvas, button.label,
SkRect::MakeXYWH(x, y, kButtonWidth, kButtonHeight));
y += kButtonHeight + kMargin;
}
}
void JankView::DrawButton(SkCanvas* canvas, const char* label,
const SkRect& bounds) {
SkPaint boxPaint;
boxPaint.setColor(SkColorSetRGB(200, 200, 200));
canvas->drawRect(bounds, boxPaint);
boxPaint.setColor(SkColorSetRGB(40, 40, 40));
boxPaint.setStyle(SkPaint::kStroke_Style);
canvas->drawRect(bounds, boxPaint);
SkRect textBounds;
SkFont textFont;
textFont.setTypeface(typeface_);
textFont.setSize(kTextSize);
textFont.measureText(label, strlen(label), SkTextEncoding::kUTF8,
&textBounds);
SkPaint textPaint;
textPaint.setColor(SK_ColorBLACK);
textPaint.setAntiAlias(true);
canvas->drawSimpleText(label, strlen(label), SkTextEncoding::kUTF8,
bounds.centerX() - textBounds.centerX(),
bounds.centerY() - textBounds.centerY(), textFont,
textPaint);
}
void JankView::OnInputEvent(fuchsia::ui::input::InputEvent event) {
if (event.is_pointer()) {
const fuchsia::ui::input::PointerEvent& pointer = event.pointer();
if (pointer.phase == fuchsia::ui::input::PointerEventPhase::DOWN) {
SkScalar x = pointer.x;
SkScalar y = pointer.y;
if (x >= kMargin && x <= kButtonWidth + kMargin) {
int index = (y - kMargin) / (kButtonHeight + kMargin);
if (index >= 0 &&
size_t(index) < sizeof(kButtons) / sizeof(kButtons[0]) &&
y < (kButtonHeight + kMargin) * (index + 1))
OnClick(kButtons[index]);
return;
}
}
}
}
void JankView::OnClick(const Button& button) {
switch (button.action) {
case Action::kHang10: {
sleep(10);
break;
}
case Action::kStutter30: {
stutter_end_time_ =
fxl::TimePoint::Now() + fxl::TimeDelta::FromSeconds(30);
break;
}
case Action::kCrash: {
abort();
break;
}
}
}
} // namespace examples