blob: 302e819f13df001228d34e4404ee6b078ebe9c32 [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.
use carnelian::{App, AppAssistant, ViewAssistant, ViewAssistantContext, ViewAssistantPtr};
use failure::Error;
use fidl::endpoints::create_endpoints;
use fidl_fuchsia_ui_gfx::{self as gfx, ColorRgba};
use fidl_fuchsia_ui_viewsv1::ViewProviderMarker;
use fidl_fuchsia_ui_viewsv1token::ViewOwnerMarker;
use fuchsia_app::client::{App as LaunchedApp, Launcher};
use fuchsia_scenic::{Circle, EntityNode, ImportNode, Material, Rectangle, SessionPtr, ShapeNode};
use parking_lot::Mutex;
use std::collections::BTreeMap;
use std::{any::Any, cell::RefCell};
mod layout;
use crate::layout::{layout, ChildViewData};
struct VoilaAppAssistant {}
impl AppAssistant for VoilaAppAssistant {
fn setup(&mut self) -> Result<(), Error> {
Ok(())
}
fn create_view_assistant(&mut self, session: &SessionPtr) -> Result<ViewAssistantPtr, Error> {
Ok(Mutex::new(RefCell::new(Box::new(VoilaViewAssistant {
background_node: ShapeNode::new(session.clone()),
circle_node: ShapeNode::new(session.clone()),
width: 0.0,
height: 0.0,
child_sessions: BTreeMap::new(),
}))))
}
}
struct VoilaViewAssistant {
background_node: ShapeNode,
circle_node: ShapeNode,
width: f32,
height: f32,
child_sessions: BTreeMap<u32, ChildSessionData>,
}
/// Represents an emulated session and holds its internal state.
struct ChildSessionData {
#[allow(unused)]
app: LaunchedApp,
view: ChildViewData,
}
impl VoilaViewAssistant {
fn create_and_setup_view(
&mut self, key: u32, url: &str, session: &SessionPtr,
view_container: &fidl_fuchsia_ui_viewsv1::ViewContainerProxy, import_node: &ImportNode,
) -> Result<(), Error> {
let app = Launcher::new()?.launch(url.to_string(), None)?;
let view_provider = app.connect_to_service(ViewProviderMarker)?;
let (view_owner_client, view_owner_server) = create_endpoints::<ViewOwnerMarker>()?;
view_provider.create_view(view_owner_server, None)?;
let host_node = EntityNode::new(session.clone());
let host_import_token = host_node.export_as_request();
import_node.add_child(&host_node);
let view_data = ChildViewData::new(key, host_node);
let session_data = ChildSessionData {
app: app,
view: view_data,
};
self.child_sessions.insert(key, session_data);
view_container.add_child(key, view_owner_client, host_import_token)?;
Ok(())
}
}
impl ViewAssistant for VoilaViewAssistant {
fn setup(&mut self, context: &ViewAssistantContext) -> Result<(), Error> {
context
.import_node
.resource()
.set_event_mask(gfx::METRICS_EVENT_MASK);
context.import_node.add_child(&self.background_node);
let material = Material::new(context.session.clone());
material.set_color(ColorRgba {
red: 0x00,
green: 0x00,
blue: 0xff,
alpha: 0xff,
});
self.background_node.set_material(&material);
context.import_node.add_child(&self.circle_node);
let material = Material::new(context.session.clone());
material.set_color(ColorRgba {
red: 0xff,
green: 0x00,
blue: 0xff,
alpha: 0xff,
});
self.circle_node.set_material(&material);
self.create_and_setup_view(
1,
"fuchsia-pkg://fuchsia.com/spinning_square_rs#meta/spinning_square_rs.cmx",
context.session,
context.view_container,
context.import_node,
)?;
self.create_and_setup_view(
2,
"fuchsia-pkg://fuchsia.com/noodles#meta/noodles.cmx",
context.session,
context.view_container,
context.import_node,
)?;
Ok(())
}
fn update(&mut self, context: &ViewAssistantContext) -> Result<(), Error> {
self.width = context.width;
self.height = context.height;
let center_x = self.width * 0.5;
let center_y = self.height * 0.5;
self.background_node.set_shape(&Rectangle::new(
context.session.clone(),
self.width,
self.height,
));
self.background_node
.set_translation(center_x, center_y, 0.0);
let circle_radius = self.width.min(self.height) * 0.25;
self.circle_node
.set_shape(&Circle::new(context.session.clone(), circle_radius));
self.circle_node.set_translation(center_x, center_y, 8.0);
let mut views: Vec<&mut ChildViewData> = self
.child_sessions
.iter_mut()
.map(|(_key, child_session)| &mut child_session.view)
.collect();
layout(&mut views, context.view_container, self.width, self.height);
Ok(())
}
fn handle_message(&mut self, _message: &Any) {}
}
fn main() -> Result<(), Error> {
let assistant = VoilaAppAssistant {};
App::run(Box::new(assistant))
}