| // Copyright 2019 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 "garnet/examples/ui/simplest_app/view.h" |
| |
| #include <lib/trace/event.h> |
| |
| #include <src/lib/fxl/logging.h> |
| |
| namespace simplest_app { |
| |
| using ::fuchsia::ui::input::InputEvent; |
| using ::fuchsia::ui::input::KeyboardEventPhase; |
| using ::fuchsia::ui::input::PointerEventPhase; |
| |
| namespace { |
| |
| // TODO(SCN-1278): Remove this. |
| // Turns two floats (high bits, low bits) into a 64-bit uint. |
| trace_flow_id_t PointerTraceHACK(float fa, float fb) { |
| uint32_t ia, ib; |
| memcpy(&ia, &fa, sizeof(uint32_t)); |
| memcpy(&ib, &fb, sizeof(uint32_t)); |
| return (((uint64_t)ia) << 32) | ib; |
| } |
| |
| // Helper for OnInputEvent: respond to pointer events. |
| scenic::Material NextColor(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; |
| } |
| |
| } // namespace |
| |
| SimplestAppView::SimplestAppView(scenic::ViewContextTransitional context, async::Loop* message_loop) |
| : scenic::BaseViewTransitional(std::move(context), "simplest_app SimplestAppView"), |
| message_loop_(message_loop), |
| background_(session()), |
| focused_(false) { |
| FXL_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 SimplestAppView::OnPropertiesChanged(fuchsia::ui::gfx::ViewProperties old_properties) { |
| if (view_holder_) { |
| view_holder_->SetViewProperties(view_properties()); |
| } |
| |
| UpdateBackground(); |
| } |
| |
| void SimplestAppView::OnInputEvent(fuchsia::ui::input::InputEvent event) { |
| TRACE_DURATION("gfx", "SimplestAppView::OnInputEvent"); |
| |
| switch (event.Which()) { |
| case InputEvent::Tag::kFocus: { |
| focused_ = event.focus().focused; |
| break; |
| } |
| case InputEvent::Tag::kPointer: { |
| const auto& pointer = event.pointer(); |
| trace_flow_id_t trace_id = PointerTraceHACK(pointer.radius_major, pointer.radius_minor); |
| TRACE_FLOW_END("input", "dispatch_event_to_client", trace_id); |
| switch (pointer.phase) { |
| case PointerEventPhase::DOWN: { |
| if (focused_) { |
| UpdateBackground(); |
| } |
| 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: { |
| FXL_NOTREACHED(); |
| break; |
| } |
| } |
| } |
| |
| void SimplestAppView::UpdateBackground() { |
| 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_.SetMaterial(NextColor(session())); |
| background_.SetShape(background_shape); |
| background_.SetTranslation(width / 2.f, height / 2.f, -10.f); |
| PresentScene(); |
| } |
| |
| } // namespace simplest_app |