| // Copyright 2018 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 "src/ui/examples/simplest_embedder/view.h" | |
| #include <lib/async/cpp/task.h> | |
| #include <lib/syslog/cpp/macros.h> | |
| namespace simplest_embedder { | |
| using ::fuchsia::ui::input::InputEvent; | |
| using ::fuchsia::ui::input::KeyboardEventPhase; | |
| using ::fuchsia::ui::input::PointerEventPhase; | |
| ShadertoyEmbedderView::ShadertoyEmbedderView(scenic::ViewContext context, async::Loop* message_loop) | |
| : scenic::BaseView(std::move(context), "simplest_embedder ShadertoyEmbedderView"), | |
| message_loop_(message_loop), | |
| background_(session()), | |
| focused_(false) { | |
| FX_CHECK(message_loop_); | |
| root_node().AddChild(background_); | |
| scenic::Material background_material(session()); | |
| background_material.SetColor(30, 30, 120, 255); | |
| background_.SetMaterial(background_material); | |
| fuchsia::ui::input::SetHardKeyboardDeliveryCmd cmd; | |
| cmd.delivery_request = true; | |
| fuchsia::ui::input::Command input_cmd; | |
| input_cmd.set_set_hard_keyboard_delivery(std::move(cmd)); | |
| session()->Enqueue(std::move(input_cmd)); | |
| // Consider breaking out into a discrete initializer if more work is added. | |
| } | |
| void ShadertoyEmbedderView::LaunchShadertoyClient() { | |
| FX_DCHECK(!view_holder_); | |
| fuchsia::sys::LauncherPtr launcher; | |
| component_context()->svc()->Connect(launcher.NewRequest()); | |
| embedded_view_info_ = scenic::LaunchComponentAndCreateView( | |
| launcher, "fuchsia-pkg://fuchsia.com/shadertoy_client#meta/shadertoy_client.cmx"); | |
| view_holder_ = std::make_unique<scenic::ViewHolder>( | |
| session(), std::move(embedded_view_info_.view_holder_token), | |
| "shadertoy_client for simplest_embedder"); | |
| root_node().Attach(*(view_holder_.get())); | |
| } | |
| void ShadertoyEmbedderView::OnPropertiesChanged(fuchsia::ui::gfx::ViewProperties old_properties) { | |
| if (view_holder_) { | |
| view_holder_->SetViewProperties(view_properties()); | |
| } | |
| InvalidateScene(); | |
| } | |
| void ShadertoyEmbedderView::OnSceneInvalidated( | |
| fuchsia::images::PresentationInfo presentation_info) { | |
| if (!has_logical_size()) { | |
| return; | |
| } | |
| const auto size = logical_size(); | |
| const float width = size.x; | |
| const float height = size.y; | |
| scenic::RoundedRectangle background_shape(session(), width, height, 20, 20, 80, 10); | |
| background_.SetShape(background_shape); | |
| background_.SetTranslation(width / 2.f, height / 2.f, -10.f); | |
| } | |
| // Helper for OnInputEvent: respond to pointer events. | |
| static scenic::Material next_color(scenic::Session* session) { | |
| static uint8_t red = 128, green = 128, blue = 128; | |
| scenic::Material material(session); | |
| material.SetColor(red, green, blue, 255); | |
| red += 16; | |
| green += 32; | |
| blue += 64; | |
| return material; | |
| } | |
| void ShadertoyEmbedderView::OnInputEvent(fuchsia::ui::input::InputEvent event) { | |
| switch (event.Which()) { | |
| case InputEvent::Tag::kFocus: { | |
| focused_ = event.focus().focused; | |
| break; | |
| } | |
| case InputEvent::Tag::kPointer: { | |
| const auto& pointer = event.pointer(); | |
| switch (pointer.phase) { | |
| case PointerEventPhase::DOWN: { | |
| if (focused_) { | |
| background_.SetMaterial(next_color(session())); | |
| InvalidateScene(); | |
| } | |
| break; | |
| } | |
| default: | |
| break; // Ignore all other pointer phases. | |
| } | |
| break; | |
| } | |
| case InputEvent::Tag::kKeyboard: { | |
| const auto& key = event.keyboard(); | |
| if (key.hid_usage == /* Esc key*/ 0x29 && key.phase == KeyboardEventPhase::RELEASED) { | |
| async::PostTask(message_loop_->dispatcher(), [this] { message_loop_->Quit(); }); | |
| } | |
| break; | |
| } | |
| case InputEvent::Tag::Invalid: { | |
| FX_NOTREACHED(); | |
| break; | |
| } | |
| } | |
| } | |
| } // namespace simplest_embedder |