blob: c0a913d47492b268348bb4d143687b8e30dda58d [file] [log] [blame]
// Copyright 2020 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 {
anyhow::Error,
carnelian::{
color::Color,
input, make_app_assistant,
render::Context,
scene::{
facets::{FacetId, ShedFacet},
scene::{Scene, SceneBuilder},
},
App, AppAssistant, Point, Rect, Size, ViewAssistant, ViewAssistantContext,
ViewAssistantPtr, ViewKey,
},
euclid::{default::Point2D, size2},
fuchsia_zircon::Event,
std::{collections::BTreeMap, path::PathBuf},
};
const BACKGROUND_COLOR: Color = Color { r: 255, g: 255, b: 255, a: 255 };
const SPACING_FRACTION: f32 = 0.8;
#[derive(Default)]
struct SvgAppAssistant;
impl AppAssistant for SvgAppAssistant {
fn setup(&mut self) -> Result<(), Error> {
Ok(())
}
fn create_view_assistant(&mut self, _: ViewKey) -> Result<ViewAssistantPtr, Error> {
Ok(Box::new(SvgViewAssistant::new()))
}
}
struct SceneDetails {
scene: Scene,
facet_id: FacetId,
}
struct SvgViewAssistant {
scene_details: Option<SceneDetails>,
touch_locations: BTreeMap<input::pointer::PointerId, Point2D<f32>>,
position: Point,
}
impl SvgViewAssistant {
pub fn new() -> Self {
Self { scene_details: None, touch_locations: BTreeMap::new(), position: Point::zero() }
}
}
impl ViewAssistant for SvgViewAssistant {
fn setup(&mut self, _context: &ViewAssistantContext) -> Result<(), Error> {
Ok(())
}
fn resize(&mut self, _new_size: &Size) -> Result<(), Error> {
self.scene_details = None;
Ok(())
}
fn render(
&mut self,
render_context: &mut Context,
ready_event: Event,
context: &ViewAssistantContext,
) -> Result<(), Error> {
let mut scene_details = self.scene_details.take().unwrap_or_else(|| {
let location = Rect::from_size(context.size).center();
self.position = location;
let mut builder = SceneBuilder::new().background_color(BACKGROUND_COLOR);
let edge_size = context.size.width.min(context.size.height) * SPACING_FRACTION;
let shed_facet = ShedFacet::new(
PathBuf::from("/pkg/data/static/fuchsia.shed"),
size2(edge_size, edge_size),
);
let shed_facet_id = builder.facet(Box::new(shed_facet));
let mut scene = builder.build();
scene.set_facet_location(&shed_facet_id, location);
SceneDetails { scene, facet_id: shed_facet_id }
});
scene_details.scene.render(render_context, ready_event, context)?;
self.scene_details = Some(scene_details);
Ok(())
}
fn handle_pointer_event(
&mut self,
context: &mut ViewAssistantContext,
_event: &input::Event,
pointer_event: &input::pointer::Event,
) -> Result<(), Error> {
match &pointer_event.phase {
input::pointer::Phase::Down(touch_location) => {
self.touch_locations
.insert(pointer_event.pointer_id.clone(), touch_location.to_f32());
}
input::pointer::Phase::Moved(touch_location) => {
if let Some(location) = self.touch_locations.get_mut(&pointer_event.pointer_id) {
// Pan image using the change to touch location.
self.position += touch_location.to_f32() - *location;
*location = touch_location.to_f32();
}
if let Some(scene_details) = self.scene_details.as_mut() {
scene_details.scene.set_facet_location(&scene_details.facet_id, self.position);
}
}
input::pointer::Phase::Up => {
self.touch_locations.remove(&pointer_event.pointer_id.clone());
}
_ => (),
}
context.request_render();
Ok(())
}
}
fn main() -> Result<(), Error> {
fuchsia_trace_provider::trace_provider_create_with_fdio();
println!("Svg Example");
App::run(make_app_assistant::<SvgAppAssistant>())
}