| // 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 "peridot/bin/basemgr/presentation_container.h" |
| |
| #include <src/lib/fxl/logging.h> |
| |
| #include <cmath> |
| |
| namespace modular { |
| |
| namespace { |
| // Presentation controller will bind |on_swap_session_shell_| |
| // to lCtrl + |kSwapSessionShellKeyboardBinding| on the active presentation. |
| constexpr char kSwapSessionShellKeyboardBinding = ' '; |
| } // namespace |
| |
| PresentationContainer::PresentationContainer( |
| fuchsia::ui::policy::Presenter* const presenter, |
| fuchsia::ui::views::ViewHolderToken view_holder_token, |
| fuchsia::modular::session::SessionShellConfig shell_config, |
| fit::function<void()> on_swap_session_shell) |
| : presenter_(presenter), |
| on_swap_session_shell_(std::move(on_swap_session_shell)) { |
| presenter_->PresentView(std::move(view_holder_token), |
| presentation_state_.presentation.NewRequest()); |
| AddGlobalKeyboardShortcuts(presentation_state_.presentation); |
| |
| SetShadowTechnique(presentation_state_.shadow_technique); |
| |
| // Set the presentation of the given view to the settings of the active |
| // session shell. |
| if (shell_config.display_usage() != |
| fuchsia::ui::policy::DisplayUsage::kUnknown) { |
| FXL_DLOG(INFO) << "Setting display usage: " |
| << fidl::ToUnderlying(shell_config.display_usage()); |
| presentation_state_.presentation->SetDisplayUsage( |
| shell_config.display_usage()); |
| } |
| |
| if (!std::isnan(shell_config.screen_width()) && |
| !std::isnan(shell_config.screen_height())) { |
| FXL_DLOG(INFO) << "Setting display size: " << shell_config.screen_width() |
| << " x " << shell_config.screen_height(); |
| presentation_state_.presentation->SetDisplaySizeInMm( |
| shell_config.screen_width(), shell_config.screen_height()); |
| } |
| } |
| |
| PresentationContainer::~PresentationContainer() = default; |
| |
| void PresentationContainer::GetPresentation( |
| fidl::InterfaceRequest<fuchsia::ui::policy::Presentation> request) { |
| presentation_state_.bindings.AddBinding( |
| presentation_state_.presentation.get(), std::move(request)); |
| } |
| |
| void PresentationContainer::AddGlobalKeyboardShortcuts( |
| fuchsia::ui::policy::PresentationPtr& presentation) { |
| presentation->CaptureKeyboardEventHACK( |
| { |
| .code_point = kSwapSessionShellKeyboardBinding, |
| .modifiers = fuchsia::ui::input::kModifierLeftControl, |
| }, |
| keyboard_capture_listener_bindings_.AddBinding(this)); |
| presentation->CaptureKeyboardEventHACK( |
| { |
| .code_point = 's', |
| .modifiers = fuchsia::ui::input::kModifierLeftControl, |
| }, |
| keyboard_capture_listener_bindings_.AddBinding(this)); |
| presentation->CaptureKeyboardEventHACK( |
| { |
| .code_point = 'l', |
| .modifiers = fuchsia::ui::input::kModifierRightAlt, |
| }, |
| keyboard_capture_listener_bindings_.AddBinding(this)); |
| } |
| |
| void PresentationContainer::OnEvent(fuchsia::ui::input::KeyboardEvent event) { |
| switch (event.code_point) { |
| case kSwapSessionShellKeyboardBinding: { |
| if (on_swap_session_shell_) { |
| on_swap_session_shell_(); |
| } |
| break; |
| } |
| case 's': { |
| SetNextShadowTechnique(); |
| break; |
| } |
| case 'l': |
| ToggleClipping(); |
| break; |
| default: |
| FXL_DLOG(INFO) << "Unknown keyboard event: codepoint=" << event.code_point |
| << ", modifiers=" << event.modifiers; |
| break; |
| } |
| } |
| |
| void PresentationContainer::SetNextShadowTechnique() { |
| using ShadowTechnique = fuchsia::ui::gfx::ShadowTechnique; |
| |
| // These are the only two types currently supported by the Scenic renderer. |
| // TODO(MF-266) Make this more robust. |
| auto next_shadow_technique = |
| [](ShadowTechnique shadow_technique) -> ShadowTechnique { |
| switch (shadow_technique) { |
| case ShadowTechnique::UNSHADOWED: |
| return ShadowTechnique::STENCIL_SHADOW_VOLUME; |
| case ShadowTechnique::STENCIL_SHADOW_VOLUME: |
| return ShadowTechnique::UNSHADOWED; |
| default: |
| FXL_LOG(ERROR) << "Unknown shadow technique: " |
| << fidl::ToUnderlying(shadow_technique); |
| return ShadowTechnique::UNSHADOWED; |
| } |
| }; |
| |
| SetShadowTechnique( |
| next_shadow_technique(presentation_state_.shadow_technique)); |
| } |
| |
| void PresentationContainer::SetShadowTechnique( |
| fuchsia::ui::gfx::ShadowTechnique shadow_technique) { |
| if (!presentation_state_.presentation) |
| return; |
| |
| presentation_state_.shadow_technique = shadow_technique; |
| |
| FXL_LOG(INFO) << "Setting shadow technique to " |
| << fidl::ToUnderlying(presentation_state_.shadow_technique); |
| |
| fuchsia::ui::gfx::RendererParam param; |
| param.set_shadow_technique(presentation_state_.shadow_technique); |
| |
| std::vector<fuchsia::ui::gfx::RendererParam> renderer_params; |
| renderer_params.push_back(std::move(param)); |
| |
| presentation_state_.presentation->SetRendererParams( |
| std::move(renderer_params)); |
| } |
| |
| void PresentationContainer::ToggleClipping() { |
| if (!presentation_state_.presentation) |
| return; |
| |
| FXL_DLOG(INFO) << "Toggling clipping"; |
| |
| presentation_state_.clipping_enabled = !presentation_state_.clipping_enabled; |
| presentation_state_.presentation->EnableClipping( |
| presentation_state_.clipping_enabled); |
| } |
| |
| } // namespace modular |