blob: 3ecda9c8abfe3f4f43c65a30ac1e3981ed0f9219 [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,
drawing::path_for_rectangle,
make_app_assistant,
render::{BlendMode, Context as RenderContext, Fill, FillRule, Layer, Path, Style},
scene::{
facets::Facet,
scene::{Scene, SceneBuilder, SceneOrder},
LayerGroup,
},
App, AppAssistant, Point, Rect, Size, ViewAssistant, ViewAssistantContext,
ViewAssistantPtr, ViewKey,
},
euclid::{size2, vec2, Transform2D},
fuchsia_zircon::Event,
};
const BLACK_COLOR: Color = Color { r: 0, g: 0, b: 0, a: 255 };
const TRANSLUCENT_COLOR: Color = Color { r: 0, g: 0, b: 0, a: 127 };
const GRAY_COLOR: Color = Color { r: 187, g: 187, b: 187, a: 255 };
const WHITE_COLOR: Color = Color { r: 255, g: 255, b: 255, a: 255 };
#[derive(Default)]
struct GammaAppAssistant;
impl AppAssistant for GammaAppAssistant {
fn setup(&mut self) -> Result<(), Error> {
Ok(())
}
fn create_view_assistant(&mut self, _: ViewKey) -> Result<ViewAssistantPtr, Error> {
Ok(Box::new(GammaViewAssistant::new()))
}
}
struct GammaFacet {
path: Path,
size: Size,
}
impl GammaFacet {
fn new(context: &mut RenderContext) -> Self {
let path = path_for_rectangle(&Rect::new(Point::zero(), size2(1.0, 1.0)), context);
Self { path, size: Size::zero() }
}
}
impl Facet for GammaFacet {
fn update_layers(
&mut self,
size: Size,
layer_group: &mut dyn LayerGroup,
render_context: &mut RenderContext,
_view_context: &ViewAssistantContext,
) -> std::result::Result<(), anyhow::Error> {
self.size = size;
let transform = Transform2D::scale(size.width * 0.5, size.height * 0.5);
let mut raster_builder = render_context.raster_builder().expect("raster_builder");
raster_builder.add(&self.path, Some(&transform));
let raster = raster_builder.build();
let transform = Transform2D::scale(size.width * 0.5, 1.0);
let mut raster_builder = render_context.raster_builder().expect("raster_builder");
raster_builder.add(&self.path, Some(&transform));
let line_raster = raster_builder.build();
let layers = std::iter::once(Layer {
raster: raster.clone(),
clip: None,
style: Style {
fill_rule: FillRule::NonZero,
fill: Fill::Solid(GRAY_COLOR),
blend_mode: BlendMode::Over,
},
})
.chain(std::iter::once(Layer {
raster: raster.clone().translate(vec2(0, (size.height * 0.5) as i32)),
clip: None,
style: Style {
fill_rule: FillRule::NonZero,
fill: Fill::Solid(TRANSLUCENT_COLOR),
blend_mode: BlendMode::Over,
},
}))
.chain((0..size.height as i32).step_by(2).map(|y| Layer {
raster: line_raster.clone().translate(vec2((size.width * 0.5) as i32, y)),
clip: None,
style: Style {
fill_rule: FillRule::NonZero,
fill: Fill::Solid(BLACK_COLOR),
blend_mode: BlendMode::Over,
},
}));
layer_group.clear();
for (i, layer) in layers.enumerate() {
layer_group.insert(SceneOrder::try_from(i).unwrap_or_else(|e| panic!("{}", e)), layer);
}
Ok(())
}
fn calculate_size(&self, _available: Size) -> Size {
self.size
}
}
struct SceneDetails {
scene: Scene,
}
struct GammaViewAssistant {
scene_details: Option<SceneDetails>,
}
impl GammaViewAssistant {
pub fn new() -> Self {
Self { scene_details: None }
}
}
impl ViewAssistant for GammaViewAssistant {
fn resize(&mut self, _new_size: &Size) -> Result<(), Error> {
self.scene_details = None;
Ok(())
}
fn render(
&mut self,
render_context: &mut RenderContext,
ready_event: Event,
context: &ViewAssistantContext,
) -> Result<(), Error> {
let mut scene_details = self.scene_details.take().unwrap_or_else(|| {
let mut builder = SceneBuilder::new().background_color(WHITE_COLOR);
let gamma_facet = GammaFacet::new(render_context);
let _ = builder.facet(Box::new(gamma_facet));
SceneDetails { scene: builder.build() }
});
scene_details.scene.render(render_context, ready_event, context)?;
self.scene_details = Some(scene_details);
context.request_render();
Ok(())
}
}
fn main() -> Result<(), Error> {
fuchsia_trace_provider::trace_provider_create_with_fdio();
println!("Gamma Example");
App::run(make_app_assistant::<GammaAppAssistant>())
}