blob: 0471c98a5d12abd5cd433ed0d39b8c31c2f7deed [file] [log] [blame]
// 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