| // 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>()) |
| } |