Implement 2D rotation
This commit is contained in:
parent
a9ac960862
commit
22fe63503f
|
@ -164,7 +164,7 @@ impl DemoApp {
|
||||||
let (drawable_width, drawable_height) = self.window.drawable_size();
|
let (drawable_width, drawable_height) = self.window.drawable_size();
|
||||||
let drawable_size = Size2D::new(drawable_width, drawable_height);
|
let drawable_size = Size2D::new(drawable_width, drawable_height);
|
||||||
|
|
||||||
let perspective = if self.ui.threed_enabled {
|
let render_transform = if self.ui.threed_enabled {
|
||||||
let rotation = Transform3DF32::from_rotation(-self.camera_yaw,
|
let rotation = Transform3DF32::from_rotation(-self.camera_yaw,
|
||||||
-self.camera_pitch,
|
-self.camera_pitch,
|
||||||
0.0);
|
0.0);
|
||||||
|
@ -189,15 +189,16 @@ impl DemoApp {
|
||||||
translation.y(),
|
translation.y(),
|
||||||
translation.z()));
|
translation.z()));
|
||||||
|
|
||||||
Some(Perspective::new(&transform, &drawable_size))
|
RenderTransform::Perspective(Perspective::new(&transform, &drawable_size))
|
||||||
} else {
|
} else {
|
||||||
None
|
let transform = Transform2DF32::from_rotation(self.ui.rotation());
|
||||||
|
RenderTransform::Transform2D(transform)
|
||||||
};
|
};
|
||||||
|
|
||||||
let count = if self.frame_counter == 0 { 2 } else { 1 };
|
let count = if self.frame_counter == 0 { 2 } else { 1 };
|
||||||
for _ in 0..count {
|
for _ in 0..count {
|
||||||
self.scene_thread_proxy.sender.send(MainToSceneMsg::Build(BuildOptions {
|
self.scene_thread_proxy.sender.send(MainToSceneMsg::Build(BuildOptions {
|
||||||
perspective,
|
render_transform: render_transform.clone(),
|
||||||
stem_darkening_font_size: if self.ui.stem_darkening_effect_enabled {
|
stem_darkening_font_size: if self.ui.stem_darkening_effect_enabled {
|
||||||
Some(APPROX_FONT_SIZE * self.scale_factor)
|
Some(APPROX_FONT_SIZE * self.scale_factor)
|
||||||
} else {
|
} else {
|
||||||
|
@ -397,7 +398,7 @@ enum MainToSceneMsg {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BuildOptions {
|
struct BuildOptions {
|
||||||
perspective: Option<Perspective>,
|
render_transform: RenderTransform,
|
||||||
stem_darkening_font_size: Option<f32>,
|
stem_darkening_font_size: Option<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,10 +466,7 @@ fn build_scene(scene: &Scene, build_options: BuildOptions, jobs: Option<usize>)
|
||||||
let z_buffer = ZBuffer::new(scene.view_box);
|
let z_buffer = ZBuffer::new(scene.view_box);
|
||||||
|
|
||||||
let render_options = RenderOptions {
|
let render_options = RenderOptions {
|
||||||
transform: match build_options.perspective {
|
transform: build_options.render_transform,
|
||||||
None => RenderTransform::Transform2D(Transform2DF32::default()),
|
|
||||||
Some(perspective) => RenderTransform::Perspective(perspective),
|
|
||||||
},
|
|
||||||
dilation: match build_options.stem_darkening_font_size {
|
dilation: match build_options.stem_darkening_font_size {
|
||||||
None => Point2DF32::default(),
|
None => Point2DF32::default(),
|
||||||
Some(font_size) => {
|
Some(font_size) => {
|
||||||
|
|
113
demo/src/ui.rs
113
demo/src/ui.rs
|
@ -15,53 +15,77 @@ use pathfinder_geometry::basic::rect::RectI32;
|
||||||
use pathfinder_gl::debug::{BUTTON_HEIGHT, BUTTON_TEXT_OFFSET, BUTTON_WIDTH, DebugUI, PADDING};
|
use pathfinder_gl::debug::{BUTTON_HEIGHT, BUTTON_TEXT_OFFSET, BUTTON_WIDTH, DebugUI, PADDING};
|
||||||
use pathfinder_gl::debug::{TEXT_COLOR, WINDOW_COLOR};
|
use pathfinder_gl::debug::{TEXT_COLOR, WINDOW_COLOR};
|
||||||
use pathfinder_gl::device::Texture;
|
use pathfinder_gl::device::Texture;
|
||||||
|
use std::f32::consts::PI;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
const SWITCH_SIZE: i32 = SWITCH_HALF_SIZE * 2 + 1;
|
const SWITCH_SIZE: i32 = SWITCH_HALF_SIZE * 2 + 1;
|
||||||
const SWITCH_HALF_SIZE: i32 = 96;
|
const SWITCH_HALF_SIZE: i32 = 96;
|
||||||
|
|
||||||
const EFFECTS_WINDOW_WIDTH: i32 = 550;
|
const SLIDER_WIDTH: i32 = 360;
|
||||||
const EFFECTS_WINDOW_HEIGHT: i32 = BUTTON_HEIGHT * 3 + PADDING * 4;
|
const SLIDER_HEIGHT: i32 = 48;
|
||||||
|
const SLIDER_TRACK_HEIGHT: i32 = 24;
|
||||||
|
const SLIDER_KNOB_WIDTH: i32 = 12;
|
||||||
|
const SLIDER_KNOB_HEIGHT: i32 = 48;
|
||||||
|
|
||||||
|
const EFFECTS_PANEL_WIDTH: i32 = 550;
|
||||||
|
const EFFECTS_PANEL_HEIGHT: i32 = BUTTON_HEIGHT * 3 + PADDING * 4;
|
||||||
|
|
||||||
|
const ROTATE_PANEL_X: i32 = PADDING + (BUTTON_WIDTH + PADDING) * 2 + PADDING + SWITCH_SIZE;
|
||||||
|
const ROTATE_PANEL_WIDTH: i32 = SLIDER_WIDTH + PADDING * 2;
|
||||||
|
const ROTATE_PANEL_HEIGHT: i32 = PADDING * 2 + SLIDER_HEIGHT;
|
||||||
|
|
||||||
static EFFECTS_PNG_NAME: &'static str = "demo-effects";
|
static EFFECTS_PNG_NAME: &'static str = "demo-effects";
|
||||||
static OPEN_PNG_NAME: &'static str = "demo-open";
|
static OPEN_PNG_NAME: &'static str = "demo-open";
|
||||||
|
static ROTATE_PNG_NAME: &'static str = "demo-rotate";
|
||||||
|
|
||||||
pub struct DemoUI {
|
pub struct DemoUI {
|
||||||
effects_texture: Texture,
|
effects_texture: Texture,
|
||||||
open_texture: Texture,
|
open_texture: Texture,
|
||||||
|
rotate_texture: Texture,
|
||||||
|
|
||||||
|
effects_panel_visible: bool,
|
||||||
|
rotate_panel_visible: bool,
|
||||||
|
|
||||||
effects_window_visible: bool,
|
|
||||||
pub threed_enabled: bool,
|
pub threed_enabled: bool,
|
||||||
pub gamma_correction_effect_enabled: bool,
|
pub gamma_correction_effect_enabled: bool,
|
||||||
pub stem_darkening_effect_enabled: bool,
|
pub stem_darkening_effect_enabled: bool,
|
||||||
pub subpixel_aa_effect_enabled: bool,
|
pub subpixel_aa_effect_enabled: bool,
|
||||||
pub file_to_open: Option<PathBuf>,
|
pub file_to_open: Option<PathBuf>,
|
||||||
|
pub rotation: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DemoUI {
|
impl DemoUI {
|
||||||
pub fn new(options: Options) -> DemoUI {
|
pub fn new(options: Options) -> DemoUI {
|
||||||
let effects_texture = Texture::from_png(EFFECTS_PNG_NAME);
|
let effects_texture = Texture::from_png(EFFECTS_PNG_NAME);
|
||||||
let open_texture = Texture::from_png(OPEN_PNG_NAME);
|
let open_texture = Texture::from_png(OPEN_PNG_NAME);
|
||||||
|
let rotate_texture = Texture::from_png(ROTATE_PNG_NAME);
|
||||||
|
|
||||||
DemoUI {
|
DemoUI {
|
||||||
effects_texture,
|
effects_texture,
|
||||||
open_texture,
|
open_texture,
|
||||||
|
rotate_texture,
|
||||||
threed_enabled: options.threed,
|
threed_enabled: options.threed,
|
||||||
effects_window_visible: false,
|
effects_panel_visible: false,
|
||||||
|
rotate_panel_visible: true,
|
||||||
gamma_correction_effect_enabled: false,
|
gamma_correction_effect_enabled: false,
|
||||||
stem_darkening_effect_enabled: false,
|
stem_darkening_effect_enabled: false,
|
||||||
subpixel_aa_effect_enabled: false,
|
subpixel_aa_effect_enabled: false,
|
||||||
file_to_open: None,
|
file_to_open: None,
|
||||||
|
rotation: SLIDER_WIDTH / 2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn rotation(&self) -> f32 {
|
||||||
|
(self.rotation as f32 / SLIDER_WIDTH as f32 * 2.0 - 1.0) * PI
|
||||||
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, debug_ui: &mut DebugUI, event: &mut UIEvent) {
|
pub fn update(&mut self, debug_ui: &mut DebugUI, event: &mut UIEvent) {
|
||||||
let bottom = debug_ui.framebuffer_size().height as i32 - PADDING;
|
let bottom = debug_ui.framebuffer_size().height as i32 - PADDING;
|
||||||
|
|
||||||
// Draw effects button.
|
// Draw effects button.
|
||||||
let effects_button_position = Point2DI32::new(PADDING, bottom - BUTTON_HEIGHT);
|
let effects_button_position = Point2DI32::new(PADDING, bottom - BUTTON_HEIGHT);
|
||||||
if self.draw_button(debug_ui, event, effects_button_position, &self.effects_texture) {
|
if self.draw_button(debug_ui, event, effects_button_position, &self.effects_texture) {
|
||||||
self.effects_window_visible = !self.effects_window_visible;
|
self.effects_panel_visible = !self.effects_panel_visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw open button.
|
// Draw open button.
|
||||||
|
@ -87,20 +111,32 @@ impl DemoUI {
|
||||||
"3D",
|
"3D",
|
||||||
self.threed_enabled);
|
self.threed_enabled);
|
||||||
|
|
||||||
// Draw effects window, if necessary.
|
// Draw rotate button, if applicable.
|
||||||
self.draw_effects_window(debug_ui, event);
|
if !self.threed_enabled {
|
||||||
|
let rotate_button_y = bottom - BUTTON_HEIGHT;
|
||||||
|
let rotate_button_position = Point2DI32::new(ROTATE_PANEL_X, rotate_button_y);
|
||||||
|
if self.draw_button(debug_ui, event, rotate_button_position, &self.rotate_texture) {
|
||||||
|
self.rotate_panel_visible = !self.rotate_panel_visible;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_effects_window(&mut self, debug_ui: &mut DebugUI, event: &mut UIEvent) {
|
// Draw effects panel, if necessary.
|
||||||
if !self.effects_window_visible {
|
self.draw_effects_panel(debug_ui, event);
|
||||||
|
|
||||||
|
// Draw rotate panel, if necessary.
|
||||||
|
self.draw_rotate_panel(debug_ui, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_effects_panel(&mut self, debug_ui: &mut DebugUI, event: &mut UIEvent) {
|
||||||
|
if !self.effects_panel_visible {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let bottom = debug_ui.framebuffer_size().height as i32 - PADDING;
|
let bottom = debug_ui.framebuffer_size().height as i32 - PADDING;
|
||||||
let effects_window_y = bottom - (BUTTON_HEIGHT + PADDING + EFFECTS_WINDOW_HEIGHT);
|
let effects_panel_y = bottom - (BUTTON_HEIGHT + PADDING + EFFECTS_PANEL_HEIGHT);
|
||||||
debug_ui.draw_solid_rect(RectI32::new(Point2DI32::new(PADDING, effects_window_y),
|
debug_ui.draw_solid_rect(RectI32::new(Point2DI32::new(PADDING, effects_panel_y),
|
||||||
Point2DI32::new(EFFECTS_WINDOW_WIDTH,
|
Point2DI32::new(EFFECTS_PANEL_WIDTH,
|
||||||
EFFECTS_WINDOW_HEIGHT)),
|
EFFECTS_PANEL_HEIGHT)),
|
||||||
WINDOW_COLOR);
|
WINDOW_COLOR);
|
||||||
|
|
||||||
self.gamma_correction_effect_enabled =
|
self.gamma_correction_effect_enabled =
|
||||||
|
@ -108,25 +144,58 @@ impl DemoUI {
|
||||||
event,
|
event,
|
||||||
"Gamma Correction",
|
"Gamma Correction",
|
||||||
0,
|
0,
|
||||||
effects_window_y,
|
effects_panel_y,
|
||||||
self.gamma_correction_effect_enabled);
|
self.gamma_correction_effect_enabled);
|
||||||
self.stem_darkening_effect_enabled =
|
self.stem_darkening_effect_enabled =
|
||||||
self.draw_effects_switch(debug_ui,
|
self.draw_effects_switch(debug_ui,
|
||||||
event,
|
event,
|
||||||
"Stem Darkening",
|
"Stem Darkening",
|
||||||
1,
|
1,
|
||||||
effects_window_y,
|
effects_panel_y,
|
||||||
self.stem_darkening_effect_enabled);
|
self.stem_darkening_effect_enabled);
|
||||||
self.subpixel_aa_effect_enabled =
|
self.subpixel_aa_effect_enabled =
|
||||||
self.draw_effects_switch(debug_ui,
|
self.draw_effects_switch(debug_ui,
|
||||||
event,
|
event,
|
||||||
"Subpixel AA",
|
"Subpixel AA",
|
||||||
2,
|
2,
|
||||||
effects_window_y,
|
effects_panel_y,
|
||||||
self.subpixel_aa_effect_enabled);
|
self.subpixel_aa_effect_enabled);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn draw_rotate_panel(&mut self, debug_ui: &mut DebugUI, event: &mut UIEvent) {
|
||||||
|
if !self.rotate_panel_visible {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let bottom = debug_ui.framebuffer_size().height as i32 - PADDING;
|
||||||
|
let rotate_panel_y = bottom - (BUTTON_HEIGHT + PADDING + ROTATE_PANEL_HEIGHT);
|
||||||
|
debug_ui.draw_solid_rect(RectI32::new(Point2DI32::new(ROTATE_PANEL_X, rotate_panel_y),
|
||||||
|
Point2DI32::new(ROTATE_PANEL_WIDTH,
|
||||||
|
ROTATE_PANEL_HEIGHT)),
|
||||||
|
WINDOW_COLOR);
|
||||||
|
|
||||||
|
let (widget_x, widget_y) = (ROTATE_PANEL_X + PADDING, rotate_panel_y + PADDING);
|
||||||
|
let widget_rect = RectI32::new(Point2DI32::new(widget_x, widget_y),
|
||||||
|
Point2DI32::new(SLIDER_WIDTH, SLIDER_KNOB_HEIGHT));
|
||||||
|
if let Some(position) = event.handle_mouse_down_in_rect(widget_rect) {
|
||||||
|
self.rotation = position.x();
|
||||||
|
}
|
||||||
|
|
||||||
|
let slider_track_y = rotate_panel_y + PADDING + SLIDER_KNOB_HEIGHT / 2 -
|
||||||
|
SLIDER_TRACK_HEIGHT / 2;
|
||||||
|
let slider_track_rect =
|
||||||
|
RectI32::new(Point2DI32::new(widget_x, slider_track_y),
|
||||||
|
Point2DI32::new(SLIDER_WIDTH, SLIDER_TRACK_HEIGHT));
|
||||||
|
debug_ui.draw_rect_outline(slider_track_rect, TEXT_COLOR);
|
||||||
|
|
||||||
|
let slider_knob_x = widget_x + self.rotation - SLIDER_KNOB_WIDTH / 2;
|
||||||
|
let slider_knob_rect =
|
||||||
|
RectI32::new(Point2DI32::new(slider_knob_x, widget_y),
|
||||||
|
Point2DI32::new(SLIDER_KNOB_WIDTH, SLIDER_KNOB_HEIGHT));
|
||||||
|
debug_ui.draw_solid_rect(slider_knob_rect, TEXT_COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
fn draw_button(&self,
|
fn draw_button(&self,
|
||||||
debug_ui: &mut DebugUI,
|
debug_ui: &mut DebugUI,
|
||||||
event: &mut UIEvent,
|
event: &mut UIEvent,
|
||||||
|
@ -137,7 +206,7 @@ impl DemoUI {
|
||||||
debug_ui.draw_solid_rect(button_rect, WINDOW_COLOR);
|
debug_ui.draw_solid_rect(button_rect, WINDOW_COLOR);
|
||||||
debug_ui.draw_rect_outline(button_rect, TEXT_COLOR);
|
debug_ui.draw_rect_outline(button_rect, TEXT_COLOR);
|
||||||
debug_ui.draw_texture(origin + Point2DI32::new(PADDING, PADDING), texture, TEXT_COLOR);
|
debug_ui.draw_texture(origin + Point2DI32::new(PADDING, PADDING), texture, TEXT_COLOR);
|
||||||
event.handle_mouse_down_in_rect(button_rect)
|
event.handle_mouse_down_in_rect(button_rect).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_effects_switch(&self,
|
fn draw_effects_switch(&self,
|
||||||
|
@ -152,7 +221,7 @@ impl DemoUI {
|
||||||
let text_y = window_y + PADDING + BUTTON_TEXT_OFFSET + (BUTTON_HEIGHT + PADDING) * index;
|
let text_y = window_y + PADDING + BUTTON_TEXT_OFFSET + (BUTTON_HEIGHT + PADDING) * index;
|
||||||
debug_ui.draw_text(text, Point2DI32::new(text_x, text_y), false);
|
debug_ui.draw_text(text, Point2DI32::new(text_x, text_y), false);
|
||||||
|
|
||||||
let switch_x = PADDING + EFFECTS_WINDOW_WIDTH - (SWITCH_SIZE + PADDING);
|
let switch_x = PADDING + EFFECTS_PANEL_WIDTH - (SWITCH_SIZE + PADDING);
|
||||||
let switch_y = window_y + PADDING + (BUTTON_HEIGHT + PADDING) * index;
|
let switch_y = window_y + PADDING + (BUTTON_HEIGHT + PADDING) * index;
|
||||||
self.draw_switch(debug_ui, event, Point2DI32::new(switch_x, switch_y), "Off", "On", value)
|
self.draw_switch(debug_ui, event, Point2DI32::new(switch_x, switch_y), "Off", "On", value)
|
||||||
}
|
}
|
||||||
|
@ -166,7 +235,7 @@ impl DemoUI {
|
||||||
mut value: bool)
|
mut value: bool)
|
||||||
-> bool {
|
-> bool {
|
||||||
let widget_rect = RectI32::new(origin, Point2DI32::new(SWITCH_SIZE, BUTTON_HEIGHT));
|
let widget_rect = RectI32::new(origin, Point2DI32::new(SWITCH_SIZE, BUTTON_HEIGHT));
|
||||||
if event.handle_mouse_down_in_rect(widget_rect) {
|
if event.handle_mouse_down_in_rect(widget_rect).is_some() {
|
||||||
value = !value;
|
value = !value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,13 +274,13 @@ impl UIEvent {
|
||||||
match *self { UIEvent::None => true, _ => false }
|
match *self { UIEvent::None => true, _ => false }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_mouse_down_in_rect(&mut self, rect: RectI32) -> bool {
|
fn handle_mouse_down_in_rect(&mut self, rect: RectI32) -> Option<Point2DI32> {
|
||||||
if let UIEvent::MouseDown(point) = *self {
|
if let UIEvent::MouseDown(point) = *self {
|
||||||
if rect.contains_point(point) {
|
if rect.contains_point(point) {
|
||||||
*self = UIEvent::None;
|
*self = UIEvent::None;
|
||||||
return true;
|
return Some(point - rect.origin());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ pub const BUTTON_HEIGHT: i32 = PADDING * 2 + ICON_SIZE;
|
||||||
pub const BUTTON_TEXT_OFFSET: i32 = PADDING + 36;
|
pub const BUTTON_TEXT_OFFSET: i32 = PADDING + 36;
|
||||||
|
|
||||||
pub static TEXT_COLOR: ColorU = ColorU { r: 255, g: 255, b: 255, a: 255 };
|
pub static TEXT_COLOR: ColorU = ColorU { r: 255, g: 255, b: 255, a: 255 };
|
||||||
pub static WINDOW_COLOR: ColorU = ColorU { r: 30, g: 30, b: 30, a: 255 - 30 };
|
pub static WINDOW_COLOR: ColorU = ColorU { r: 0, g: 0, b: 0, a: 255 - 90 };
|
||||||
|
|
||||||
const PERF_WINDOW_WIDTH: i32 = 300;
|
const PERF_WINDOW_WIDTH: i32 = 300;
|
||||||
const PERF_WINDOW_HEIGHT: i32 = LINE_HEIGHT * 2 + PADDING + 2;
|
const PERF_WINDOW_HEIGHT: i32 = LINE_HEIGHT * 2 + PADDING + 2;
|
||||||
|
|
Loading…
Reference in New Issue