Factor the demo UI into model and presenter
This commit is contained in:
parent
3857a28e6a
commit
78908c5e3c
|
@ -16,7 +16,7 @@ extern crate log;
|
||||||
use crate::camera::{Camera, Mode};
|
use crate::camera::{Camera, Mode};
|
||||||
use crate::concurrent::DemoExecutor;
|
use crate::concurrent::DemoExecutor;
|
||||||
use crate::device::{GroundProgram, GroundVertexArray};
|
use crate::device::{GroundProgram, GroundVertexArray};
|
||||||
use crate::ui::{DemoUI, UIAction};
|
use crate::ui::{DemoUIModel, DemoUIPresenter, UIAction};
|
||||||
use crate::window::{Event, Keycode, SVGPath, Window, WindowSize};
|
use crate::window::{Event, Keycode, SVGPath, Window, WindowSize};
|
||||||
use clap::{App, Arg};
|
use clap::{App, Arg};
|
||||||
use pathfinder_geometry::basic::point::{Point2DF32, Point2DI32};
|
use pathfinder_geometry::basic::point::{Point2DF32, Point2DI32};
|
||||||
|
@ -103,7 +103,9 @@ pub struct DemoApp<W> where W: Window {
|
||||||
current_frame: Option<Frame>,
|
current_frame: Option<Frame>,
|
||||||
build_time: Option<Duration>,
|
build_time: Option<Duration>,
|
||||||
|
|
||||||
ui: DemoUI<GLDevice>,
|
ui_model: DemoUIModel,
|
||||||
|
ui_presenter: DemoUIPresenter<GLDevice>,
|
||||||
|
|
||||||
scene_proxy: SceneProxy,
|
scene_proxy: SceneProxy,
|
||||||
renderer: Renderer<GLDevice>,
|
renderer: Renderer<GLDevice>,
|
||||||
|
|
||||||
|
@ -147,15 +149,18 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
&ground_program,
|
&ground_program,
|
||||||
&renderer.quad_vertex_positions_buffer());
|
&renderer.quad_vertex_positions_buffer());
|
||||||
|
|
||||||
let mut ui = DemoUI::new(&renderer.device, resources, options.clone());
|
let mut ui_model = DemoUIModel::new(&options);
|
||||||
|
|
||||||
let mut message_epoch = 0;
|
let mut message_epoch = 0;
|
||||||
emit_message::<W>(
|
emit_message::<W>(
|
||||||
&mut ui,
|
&mut ui_model,
|
||||||
&mut message_epoch,
|
&mut message_epoch,
|
||||||
expire_message_event_id,
|
expire_message_event_id,
|
||||||
message,
|
message,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let ui_presenter = DemoUIPresenter::new(&renderer.device, resources);
|
||||||
|
|
||||||
DemoApp {
|
DemoApp {
|
||||||
window,
|
window,
|
||||||
should_exit: false,
|
should_exit: false,
|
||||||
|
@ -179,7 +184,9 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
current_frame: None,
|
current_frame: None,
|
||||||
build_time: None,
|
build_time: None,
|
||||||
|
|
||||||
ui,
|
ui_presenter,
|
||||||
|
ui_model,
|
||||||
|
|
||||||
scene_proxy,
|
scene_proxy,
|
||||||
renderer,
|
renderer,
|
||||||
|
|
||||||
|
@ -232,14 +239,14 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
|
|
||||||
let render_options = RenderOptions {
|
let render_options = RenderOptions {
|
||||||
transform: self.render_transform.clone().unwrap(),
|
transform: self.render_transform.clone().unwrap(),
|
||||||
dilation: if self.ui.stem_darkening_effect_enabled {
|
dilation: if self.ui_model.stem_darkening_effect_enabled {
|
||||||
let font_size = APPROX_FONT_SIZE * self.window_size.backing_scale_factor;
|
let font_size = APPROX_FONT_SIZE * self.window_size.backing_scale_factor;
|
||||||
let (x, y) = (STEM_DARKENING_FACTORS[0], STEM_DARKENING_FACTORS[1]);
|
let (x, y) = (STEM_DARKENING_FACTORS[0], STEM_DARKENING_FACTORS[1]);
|
||||||
Point2DF32::new(x, y).scale(font_size)
|
Point2DF32::new(x, y).scale(font_size)
|
||||||
} else {
|
} else {
|
||||||
Point2DF32::default()
|
Point2DF32::default()
|
||||||
},
|
},
|
||||||
subpixel_aa_enabled: self.ui.subpixel_aa_effect_enabled,
|
subpixel_aa_enabled: self.ui_model.subpixel_aa_effect_enabled,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.render_command_stream = Some(self.scene_proxy.build_with_stream(render_options));
|
self.render_command_stream = Some(self.scene_proxy.build_with_stream(render_options));
|
||||||
|
@ -257,7 +264,7 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
}
|
}
|
||||||
Event::WindowResized(new_size) => {
|
Event::WindowResized(new_size) => {
|
||||||
self.window_size = new_size;
|
self.window_size = new_size;
|
||||||
let viewport = self.window.viewport(self.ui.mode.view(0));
|
let viewport = self.window.viewport(self.ui_model.mode.view(0));
|
||||||
self.scene_proxy.set_view_box(RectF32::new(Point2DF32::default(),
|
self.scene_proxy.set_view_box(RectF32::new(Point2DF32::default(),
|
||||||
viewport.size().to_f32()));
|
viewport.size().to_f32()));
|
||||||
self.renderer
|
self.renderer
|
||||||
|
@ -392,12 +399,12 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
|
|
||||||
Event::OpenSVG(ref svg_path) => {
|
Event::OpenSVG(ref svg_path) => {
|
||||||
let mut built_svg = load_scene(self.window.resource_loader(), svg_path);
|
let mut built_svg = load_scene(self.window.resource_loader(), svg_path);
|
||||||
self.ui.message = get_svg_building_message(&built_svg);
|
self.ui_model.message = get_svg_building_message(&built_svg);
|
||||||
|
|
||||||
let viewport_size = self.window.viewport(self.ui.mode.view(0)).size();
|
let viewport_size = self.window.viewport(self.ui_model.mode.view(0)).size();
|
||||||
self.scene_metadata =
|
self.scene_metadata =
|
||||||
SceneMetadata::new_clipping_view_box(&mut built_svg.scene, viewport_size);
|
SceneMetadata::new_clipping_view_box(&mut built_svg.scene, viewport_size);
|
||||||
self.camera = Camera::new(self.ui.mode,
|
self.camera = Camera::new(self.ui_model.mode,
|
||||||
self.scene_metadata.view_box,
|
self.scene_metadata.view_box,
|
||||||
viewport_size);
|
viewport_size);
|
||||||
|
|
||||||
|
@ -412,7 +419,7 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
} if event_id == self.expire_message_event_id
|
} if event_id == self.expire_message_event_id
|
||||||
&& expected_epoch as u32 == self.message_epoch =>
|
&& expected_epoch as u32 == self.message_epoch =>
|
||||||
{
|
{
|
||||||
self.ui.message = String::new();
|
self.ui_model.message = String::new();
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
_ => continue,
|
_ => continue,
|
||||||
|
@ -444,15 +451,17 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
.last_mouse_position
|
.last_mouse_position
|
||||||
.to_f32()
|
.to_f32()
|
||||||
.scale(self.window_size.backing_scale_factor);
|
.scale(self.window_size.backing_scale_factor);
|
||||||
self.ui.show_text_effects = self.scene_metadata.monochrome_color.is_some();
|
|
||||||
|
self.ui_presenter.set_show_text_effects(self.scene_metadata.monochrome_color.is_some());
|
||||||
|
|
||||||
let mut ui_action = UIAction::None;
|
let mut ui_action = UIAction::None;
|
||||||
if self.options.ui == UIVisibility::All {
|
if self.options.ui == UIVisibility::All {
|
||||||
self.ui.update(
|
self.ui_presenter.update(
|
||||||
&self.renderer.device,
|
&self.renderer.device,
|
||||||
&mut self.window,
|
&mut self.window,
|
||||||
&mut self.renderer.debug_ui,
|
&mut self.renderer.debug_ui,
|
||||||
&mut ui_action,
|
&mut ui_action,
|
||||||
|
&mut self.ui_model,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,9 +508,11 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
// Switch camera mode (2D/3D) if requested.
|
// Switch camera mode (2D/3D) if requested.
|
||||||
//
|
//
|
||||||
// FIXME(pcwalton): This should really be an MVC setup.
|
// FIXME(pcwalton): This should really be an MVC setup.
|
||||||
if self.camera.mode() != self.ui.mode {
|
if self.camera.mode() != self.ui_model.mode {
|
||||||
let viewport_size = self.window.viewport(self.ui.mode.view(0)).size();
|
let viewport_size = self.window.viewport(self.ui_model.mode.view(0)).size();
|
||||||
self.camera = Camera::new(self.ui.mode, self.scene_metadata.view_box, viewport_size);
|
self.camera = Camera::new(self.ui_model.mode,
|
||||||
|
self.scene_metadata.view_box,
|
||||||
|
viewport_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
for ui_event in frame.ui_events {
|
for ui_event in frame.ui_events {
|
||||||
|
@ -564,7 +575,7 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn background_color(&self) -> ColorU {
|
fn background_color(&self) -> ColorU {
|
||||||
match self.ui.background_color {
|
match self.ui_model.background_color {
|
||||||
BackgroundColor::Light => LIGHT_BG_COLOR,
|
BackgroundColor::Light => LIGHT_BG_COLOR,
|
||||||
BackgroundColor::Dark => DARK_BG_COLOR,
|
BackgroundColor::Dark => DARK_BG_COLOR,
|
||||||
BackgroundColor::Transparent => TRANSPARENT_BG_COLOR,
|
BackgroundColor::Transparent => TRANSPARENT_BG_COLOR,
|
||||||
|
@ -711,7 +722,7 @@ fn get_svg_building_message(built_svg: &BuiltSVG) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_message<W>(
|
fn emit_message<W>(
|
||||||
ui: &mut DemoUI<GLDevice>,
|
ui_model: &mut DemoUIModel,
|
||||||
message_epoch: &mut u32,
|
message_epoch: &mut u32,
|
||||||
expire_message_event_id: u32,
|
expire_message_event_id: u32,
|
||||||
message: String,
|
message: String,
|
||||||
|
@ -722,7 +733,7 @@ fn emit_message<W>(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.message = message;
|
ui_model.message = message;
|
||||||
let expected_epoch = *message_epoch + 1;
|
let expected_epoch = *message_epoch + 1;
|
||||||
*message_epoch = expected_epoch;
|
*message_epoch = expected_epoch;
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
|
|
|
@ -42,7 +42,7 @@ const GRIDLINE_COUNT: i32 = 10;
|
||||||
impl<W> DemoApp<W> where W: Window {
|
impl<W> DemoApp<W> where W: Window {
|
||||||
pub fn prepare_frame_rendering(&mut self) -> u32 {
|
pub fn prepare_frame_rendering(&mut self) -> u32 {
|
||||||
// Make the GL context current.
|
// Make the GL context current.
|
||||||
let view = self.ui.mode.view(0);
|
let view = self.ui_model.mode.view(0);
|
||||||
self.window.make_current(view);
|
self.window.make_current(view);
|
||||||
|
|
||||||
// Set up framebuffers.
|
// Set up framebuffers.
|
||||||
|
@ -101,7 +101,7 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_scene(&mut self) {
|
pub fn draw_scene(&mut self) {
|
||||||
let view = self.ui.mode.view(0);
|
let view = self.ui_model.mode.view(0);
|
||||||
self.window.make_current(view);
|
self.window.make_current(view);
|
||||||
|
|
||||||
if self.camera.mode() != Mode::VR {
|
if self.camera.mode() != Mode::VR {
|
||||||
|
@ -212,7 +212,7 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
RenderTransform::Perspective(perspective) => perspective,
|
RenderTransform::Perspective(perspective) => perspective,
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.ui.background_color == BackgroundColor::Transparent {
|
if self.ui_model.background_color == BackgroundColor::Transparent {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,8 +264,8 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
self.renderer.set_render_mode(RenderMode::Monochrome {
|
self.renderer.set_render_mode(RenderMode::Monochrome {
|
||||||
fg_color: fg_color.to_f32(),
|
fg_color: fg_color.to_f32(),
|
||||||
bg_color: self.background_color().to_f32(),
|
bg_color: self.background_color().to_f32(),
|
||||||
gamma_correction: self.ui.gamma_correction_effect_enabled,
|
gamma_correction: self.ui_model.gamma_correction_effect_enabled,
|
||||||
defringing_kernel: if self.ui.subpixel_aa_effect_enabled {
|
defringing_kernel: if self.ui_model.subpixel_aa_effect_enabled {
|
||||||
// TODO(pcwalton): Select FreeType defringing kernel as necessary.
|
// TODO(pcwalton): Select FreeType defringing kernel as necessary.
|
||||||
Some(DEFRINGING_KERNEL_CORE_GRAPHICS)
|
Some(DEFRINGING_KERNEL_CORE_GRAPHICS)
|
||||||
} else {
|
} else {
|
||||||
|
@ -275,7 +275,7 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.ui.mode == Mode::TwoD {
|
if self.ui_model.mode == Mode::TwoD {
|
||||||
self.renderer.disable_depth();
|
self.renderer.disable_depth();
|
||||||
} else {
|
} else {
|
||||||
self.renderer.enable_depth();
|
self.renderer.enable_depth();
|
||||||
|
|
|
@ -44,7 +44,35 @@ static ZOOM_OUT_PNG_NAME: &'static str = "demo-zoom-out";
|
||||||
static BACKGROUND_PNG_NAME: &'static str = "demo-background";
|
static BACKGROUND_PNG_NAME: &'static str = "demo-background";
|
||||||
static SCREENSHOT_PNG_NAME: &'static str = "demo-screenshot";
|
static SCREENSHOT_PNG_NAME: &'static str = "demo-screenshot";
|
||||||
|
|
||||||
pub struct DemoUI<D>
|
pub struct DemoUIModel {
|
||||||
|
pub mode: Mode,
|
||||||
|
pub background_color: BackgroundColor,
|
||||||
|
pub gamma_correction_effect_enabled: bool,
|
||||||
|
pub stem_darkening_effect_enabled: bool,
|
||||||
|
pub subpixel_aa_effect_enabled: bool,
|
||||||
|
pub rotation: i32,
|
||||||
|
pub message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DemoUIModel {
|
||||||
|
pub fn new(options: &Options) -> DemoUIModel {
|
||||||
|
DemoUIModel {
|
||||||
|
mode: options.mode,
|
||||||
|
background_color: options.background_color,
|
||||||
|
gamma_correction_effect_enabled: false,
|
||||||
|
stem_darkening_effect_enabled: false,
|
||||||
|
subpixel_aa_effect_enabled: false,
|
||||||
|
rotation: SLIDER_WIDTH / 2,
|
||||||
|
message: String::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rotation(&self) -> f32 {
|
||||||
|
(self.rotation as f32 / SLIDER_WIDTH as f32 * 2.0 - 1.0) * PI
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DemoUIPresenter<D>
|
||||||
where
|
where
|
||||||
D: Device,
|
D: Device,
|
||||||
{
|
{
|
||||||
|
@ -60,22 +88,14 @@ where
|
||||||
background_panel_visible: bool,
|
background_panel_visible: bool,
|
||||||
rotate_panel_visible: bool,
|
rotate_panel_visible: bool,
|
||||||
|
|
||||||
// FIXME(pcwalton): Factor the below out into a model class.
|
show_text_effects: bool,
|
||||||
pub mode: Mode,
|
|
||||||
pub background_color: BackgroundColor,
|
|
||||||
pub gamma_correction_effect_enabled: bool,
|
|
||||||
pub stem_darkening_effect_enabled: bool,
|
|
||||||
pub subpixel_aa_effect_enabled: bool,
|
|
||||||
pub rotation: i32,
|
|
||||||
pub message: String,
|
|
||||||
pub show_text_effects: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D> DemoUI<D>
|
impl<D> DemoUIPresenter<D>
|
||||||
where
|
where
|
||||||
D: Device,
|
D: Device,
|
||||||
{
|
{
|
||||||
pub fn new(device: &D, resources: &dyn ResourceLoader, options: Options) -> DemoUI<D> {
|
pub fn new(device: &D, resources: &dyn ResourceLoader) -> DemoUIPresenter<D> {
|
||||||
let effects_texture = device.create_texture_from_png(resources, EFFECTS_PNG_NAME);
|
let effects_texture = device.create_texture_from_png(resources, EFFECTS_PNG_NAME);
|
||||||
let open_texture = device.create_texture_from_png(resources, OPEN_PNG_NAME);
|
let open_texture = device.create_texture_from_png(resources, OPEN_PNG_NAME);
|
||||||
let rotate_texture = device.create_texture_from_png(resources, ROTATE_PNG_NAME);
|
let rotate_texture = device.create_texture_from_png(resources, ROTATE_PNG_NAME);
|
||||||
|
@ -84,7 +104,7 @@ where
|
||||||
let background_texture = device.create_texture_from_png(resources, BACKGROUND_PNG_NAME);
|
let background_texture = device.create_texture_from_png(resources, BACKGROUND_PNG_NAME);
|
||||||
let screenshot_texture = device.create_texture_from_png(resources, SCREENSHOT_PNG_NAME);
|
let screenshot_texture = device.create_texture_from_png(resources, SCREENSHOT_PNG_NAME);
|
||||||
|
|
||||||
DemoUI {
|
DemoUIPresenter {
|
||||||
effects_texture,
|
effects_texture,
|
||||||
open_texture,
|
open_texture,
|
||||||
rotate_texture,
|
rotate_texture,
|
||||||
|
@ -97,19 +117,12 @@ where
|
||||||
background_panel_visible: false,
|
background_panel_visible: false,
|
||||||
rotate_panel_visible: false,
|
rotate_panel_visible: false,
|
||||||
|
|
||||||
mode: options.mode,
|
|
||||||
background_color: options.background_color,
|
|
||||||
gamma_correction_effect_enabled: false,
|
|
||||||
stem_darkening_effect_enabled: false,
|
|
||||||
subpixel_aa_effect_enabled: false,
|
|
||||||
rotation: SLIDER_WIDTH / 2,
|
|
||||||
message: String::new(),
|
|
||||||
show_text_effects: true,
|
show_text_effects: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rotation(&self) -> f32 {
|
pub fn set_show_text_effects(&mut self, show_text_effects: bool) {
|
||||||
(self.rotation as f32 / SLIDER_WIDTH as f32 * 2.0 - 1.0) * PI
|
self.show_text_effects = show_text_effects;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update<W>(
|
pub fn update<W>(
|
||||||
|
@ -118,12 +131,13 @@ where
|
||||||
window: &mut W,
|
window: &mut W,
|
||||||
debug_ui: &mut DebugUI<D>,
|
debug_ui: &mut DebugUI<D>,
|
||||||
action: &mut UIAction,
|
action: &mut UIAction,
|
||||||
|
model: &mut DemoUIModel
|
||||||
) where
|
) where
|
||||||
W: Window,
|
W: Window,
|
||||||
{
|
{
|
||||||
// Draw message text.
|
// Draw message text.
|
||||||
|
|
||||||
self.draw_message_text(device, debug_ui);
|
self.draw_message_text(device, debug_ui, model);
|
||||||
|
|
||||||
// Draw button strip.
|
// Draw button strip.
|
||||||
|
|
||||||
|
@ -134,10 +148,7 @@ where
|
||||||
|
|
||||||
// Draw text effects button.
|
// Draw text effects button.
|
||||||
if self.show_text_effects {
|
if self.show_text_effects {
|
||||||
if debug_ui
|
if debug_ui.ui.draw_button(device, position, &self.effects_texture) {
|
||||||
.ui
|
|
||||||
.draw_button(device, position, &self.effects_texture)
|
|
||||||
{
|
|
||||||
self.effects_panel_visible = !self.effects_panel_visible;
|
self.effects_panel_visible = !self.effects_panel_visible;
|
||||||
}
|
}
|
||||||
if !self.effects_panel_visible {
|
if !self.effects_panel_visible {
|
||||||
|
@ -151,24 +162,16 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw open button.
|
// Draw open button.
|
||||||
if debug_ui
|
if debug_ui.ui.draw_button(device, position, &self.open_texture) {
|
||||||
.ui
|
|
||||||
.draw_button(device, position, &self.open_texture)
|
|
||||||
{
|
|
||||||
// FIXME(pcwalton): This is not sufficient for Android, where we will need to take in
|
// FIXME(pcwalton): This is not sufficient for Android, where we will need to take in
|
||||||
// the contents of the file.
|
// the contents of the file.
|
||||||
window.present_open_svg_dialog();
|
window.present_open_svg_dialog();
|
||||||
}
|
}
|
||||||
debug_ui
|
debug_ui.ui.draw_tooltip(device, "Open SVG", RectI32::new(position, button_size));
|
||||||
.ui
|
|
||||||
.draw_tooltip(device, "Open SVG", RectI32::new(position, button_size));
|
|
||||||
position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0);
|
position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0);
|
||||||
|
|
||||||
// Draw screenshot button.
|
// Draw screenshot button.
|
||||||
if debug_ui
|
if debug_ui.ui.draw_button(device, position, &self.screenshot_texture) {
|
||||||
.ui
|
|
||||||
.draw_button(device, position, &self.screenshot_texture)
|
|
||||||
{
|
|
||||||
// FIXME(pcwalton): This is not sufficient for Android, where we will need to take in
|
// FIXME(pcwalton): This is not sufficient for Android, where we will need to take in
|
||||||
// the contents of the file.
|
// the contents of the file.
|
||||||
if let Ok(file) = window.run_save_dialog("png") {
|
if let Ok(file) = window.run_save_dialog("png") {
|
||||||
|
@ -184,11 +187,9 @@ where
|
||||||
|
|
||||||
// Draw mode switch.
|
// Draw mode switch.
|
||||||
let new_mode =
|
let new_mode =
|
||||||
debug_ui
|
debug_ui.ui.draw_text_switch(device, position, &["2D", "3D", "VR"], model.mode as u8);
|
||||||
.ui
|
if new_mode != model.mode as u8 {
|
||||||
.draw_text_switch(device, position, &["2D", "3D", "VR"], self.mode as u8);
|
model.mode = match new_mode {
|
||||||
if new_mode != self.mode as u8 {
|
|
||||||
self.mode = match new_mode {
|
|
||||||
0 => Mode::TwoD,
|
0 => Mode::TwoD,
|
||||||
1 => Mode::ThreeD,
|
1 => Mode::ThreeD,
|
||||||
_ => Mode::VR,
|
_ => Mode::VR,
|
||||||
|
@ -206,10 +207,7 @@ where
|
||||||
position += Point2DI32::new(mode_switch_width + PADDING, 0);
|
position += Point2DI32::new(mode_switch_width + PADDING, 0);
|
||||||
|
|
||||||
// Draw background switch.
|
// Draw background switch.
|
||||||
if debug_ui
|
if debug_ui.ui.draw_button(device, position, &self.background_texture) {
|
||||||
.ui
|
|
||||||
.draw_button(device, position, &self.background_texture)
|
|
||||||
{
|
|
||||||
self.background_panel_visible = !self.background_panel_visible;
|
self.background_panel_visible = !self.background_panel_visible;
|
||||||
}
|
}
|
||||||
if !self.background_panel_visible {
|
if !self.background_panel_visible {
|
||||||
|
@ -221,60 +219,48 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw background panel, if necessary.
|
// Draw background panel, if necessary.
|
||||||
self.draw_background_panel(device, debug_ui, position.x(), action);
|
self.draw_background_panel(device, debug_ui, position.x(), action, model);
|
||||||
position += Point2DI32::new(button_size.x() + PADDING, 0);
|
position += Point2DI32::new(button_size.x() + PADDING, 0);
|
||||||
|
|
||||||
// Draw effects panel, if necessary.
|
// Draw effects panel, if necessary.
|
||||||
self.draw_effects_panel(device, debug_ui);
|
self.draw_effects_panel(device, debug_ui, model);
|
||||||
|
|
||||||
// Draw rotate and zoom buttons, if applicable.
|
// Draw rotate and zoom buttons, if applicable.
|
||||||
if self.mode != Mode::TwoD {
|
if model.mode != Mode::TwoD {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if debug_ui
|
if debug_ui.ui.draw_button(device, position, &self.rotate_texture) {
|
||||||
.ui
|
|
||||||
.draw_button(device, position, &self.rotate_texture)
|
|
||||||
{
|
|
||||||
self.rotate_panel_visible = !self.rotate_panel_visible;
|
self.rotate_panel_visible = !self.rotate_panel_visible;
|
||||||
}
|
}
|
||||||
if !self.rotate_panel_visible {
|
if !self.rotate_panel_visible {
|
||||||
debug_ui
|
debug_ui.ui.draw_tooltip(device, "Rotate", RectI32::new(position, button_size));
|
||||||
.ui
|
|
||||||
.draw_tooltip(device, "Rotate", RectI32::new(position, button_size));
|
|
||||||
}
|
}
|
||||||
self.draw_rotate_panel(device, debug_ui, position.x(), action);
|
self.draw_rotate_panel(device, debug_ui, position.x(), action, model);
|
||||||
position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0);
|
position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0);
|
||||||
|
|
||||||
if debug_ui
|
if debug_ui.ui.draw_button(device, position, &self.zoom_in_texture) {
|
||||||
.ui
|
|
||||||
.draw_button(device, position, &self.zoom_in_texture)
|
|
||||||
{
|
|
||||||
*action = UIAction::ZoomIn;
|
*action = UIAction::ZoomIn;
|
||||||
}
|
}
|
||||||
debug_ui
|
debug_ui.ui.draw_tooltip(device, "Zoom In", RectI32::new(position, button_size));
|
||||||
.ui
|
|
||||||
.draw_tooltip(device, "Zoom In", RectI32::new(position, button_size));
|
|
||||||
position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0);
|
position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0);
|
||||||
|
|
||||||
if debug_ui
|
if debug_ui.ui.draw_button(device, position, &self.zoom_out_texture) {
|
||||||
.ui
|
|
||||||
.draw_button(device, position, &self.zoom_out_texture)
|
|
||||||
{
|
|
||||||
*action = UIAction::ZoomOut;
|
*action = UIAction::ZoomOut;
|
||||||
}
|
}
|
||||||
debug_ui
|
debug_ui.ui.draw_tooltip(device, "Zoom Out", RectI32::new(position, button_size));
|
||||||
.ui
|
|
||||||
.draw_tooltip(device, "Zoom Out", RectI32::new(position, button_size));
|
|
||||||
position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0);
|
position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_message_text(&mut self, device: &D, debug_ui: &mut DebugUI<D>) {
|
fn draw_message_text(&mut self,
|
||||||
if self.message.is_empty() {
|
device: &D,
|
||||||
|
debug_ui: &mut DebugUI<D>,
|
||||||
|
model: &mut DemoUIModel) {
|
||||||
|
if model.message.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let message_size = debug_ui.ui.measure_text(&self.message);
|
let message_size = debug_ui.ui.measure_text(&model.message);
|
||||||
let window_origin = Point2DI32::new(PADDING, PADDING);
|
let window_origin = Point2DI32::new(PADDING, PADDING);
|
||||||
let window_size = Point2DI32::new(PADDING * 2 + message_size, TOOLTIP_HEIGHT);
|
let window_size = Point2DI32::new(PADDING * 2 + message_size, TOOLTIP_HEIGHT);
|
||||||
debug_ui.ui.draw_solid_rounded_rect(
|
debug_ui.ui.draw_solid_rounded_rect(
|
||||||
|
@ -284,13 +270,16 @@ where
|
||||||
);
|
);
|
||||||
debug_ui.ui.draw_text(
|
debug_ui.ui.draw_text(
|
||||||
device,
|
device,
|
||||||
&self.message,
|
&model.message,
|
||||||
window_origin + Point2DI32::new(PADDING, PADDING + FONT_ASCENT),
|
window_origin + Point2DI32::new(PADDING, PADDING + FONT_ASCENT),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_effects_panel(&mut self, device: &D, debug_ui: &mut DebugUI<D>) {
|
fn draw_effects_panel(&mut self,
|
||||||
|
device: &D,
|
||||||
|
debug_ui: &mut DebugUI<D>,
|
||||||
|
model: &mut DemoUIModel) {
|
||||||
if !self.effects_panel_visible {
|
if !self.effects_panel_visible {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -306,29 +295,29 @@ where
|
||||||
WINDOW_COLOR,
|
WINDOW_COLOR,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.gamma_correction_effect_enabled = self.draw_effects_switch(
|
model.gamma_correction_effect_enabled = self.draw_effects_switch(
|
||||||
device,
|
device,
|
||||||
debug_ui,
|
debug_ui,
|
||||||
"Gamma Correction",
|
"Gamma Correction",
|
||||||
0,
|
0,
|
||||||
effects_panel_y,
|
effects_panel_y,
|
||||||
self.gamma_correction_effect_enabled,
|
model.gamma_correction_effect_enabled,
|
||||||
);
|
);
|
||||||
self.stem_darkening_effect_enabled = self.draw_effects_switch(
|
model.stem_darkening_effect_enabled = self.draw_effects_switch(
|
||||||
device,
|
device,
|
||||||
debug_ui,
|
debug_ui,
|
||||||
"Stem Darkening",
|
"Stem Darkening",
|
||||||
1,
|
1,
|
||||||
effects_panel_y,
|
effects_panel_y,
|
||||||
self.stem_darkening_effect_enabled,
|
model.stem_darkening_effect_enabled,
|
||||||
);
|
);
|
||||||
self.subpixel_aa_effect_enabled = self.draw_effects_switch(
|
model.subpixel_aa_effect_enabled = self.draw_effects_switch(
|
||||||
device,
|
device,
|
||||||
debug_ui,
|
debug_ui,
|
||||||
"Subpixel AA",
|
"Subpixel AA",
|
||||||
2,
|
2,
|
||||||
effects_panel_y,
|
effects_panel_y,
|
||||||
self.subpixel_aa_effect_enabled,
|
model.subpixel_aa_effect_enabled,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,6 +327,7 @@ where
|
||||||
debug_ui: &mut DebugUI<D>,
|
debug_ui: &mut DebugUI<D>,
|
||||||
panel_x: i32,
|
panel_x: i32,
|
||||||
action: &mut UIAction,
|
action: &mut UIAction,
|
||||||
|
model: &mut DemoUIModel,
|
||||||
) {
|
) {
|
||||||
if !self.background_panel_visible {
|
if !self.background_panel_visible {
|
||||||
return;
|
return;
|
||||||
|
@ -361,6 +351,7 @@ where
|
||||||
BackgroundColor::Light,
|
BackgroundColor::Light,
|
||||||
panel_position,
|
panel_position,
|
||||||
action,
|
action,
|
||||||
|
model,
|
||||||
);
|
);
|
||||||
self.draw_background_menu_item(
|
self.draw_background_menu_item(
|
||||||
device,
|
device,
|
||||||
|
@ -368,6 +359,7 @@ where
|
||||||
BackgroundColor::Dark,
|
BackgroundColor::Dark,
|
||||||
panel_position,
|
panel_position,
|
||||||
action,
|
action,
|
||||||
|
model,
|
||||||
);
|
);
|
||||||
self.draw_background_menu_item(
|
self.draw_background_menu_item(
|
||||||
device,
|
device,
|
||||||
|
@ -375,6 +367,7 @@ where
|
||||||
BackgroundColor::Transparent,
|
BackgroundColor::Transparent,
|
||||||
panel_position,
|
panel_position,
|
||||||
action,
|
action,
|
||||||
|
model,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,6 +377,7 @@ where
|
||||||
debug_ui: &mut DebugUI<D>,
|
debug_ui: &mut DebugUI<D>,
|
||||||
rotate_panel_x: i32,
|
rotate_panel_x: i32,
|
||||||
action: &mut UIAction,
|
action: &mut UIAction,
|
||||||
|
model: &mut DemoUIModel
|
||||||
) {
|
) {
|
||||||
if !self.rotate_panel_visible {
|
if !self.rotate_panel_visible {
|
||||||
return;
|
return;
|
||||||
|
@ -409,8 +403,8 @@ where
|
||||||
.event_queue
|
.event_queue
|
||||||
.handle_mouse_down_or_dragged_in_rect(widget_rect)
|
.handle_mouse_down_or_dragged_in_rect(widget_rect)
|
||||||
{
|
{
|
||||||
self.rotation = position.x();
|
model.rotation = position.x();
|
||||||
*action = UIAction::Rotate(self.rotation());
|
*action = UIAction::Rotate(model.rotation());
|
||||||
}
|
}
|
||||||
|
|
||||||
let slider_track_y =
|
let slider_track_y =
|
||||||
|
@ -423,14 +417,12 @@ where
|
||||||
.ui
|
.ui
|
||||||
.draw_rect_outline(device, slider_track_rect, TEXT_COLOR);
|
.draw_rect_outline(device, slider_track_rect, TEXT_COLOR);
|
||||||
|
|
||||||
let slider_knob_x = widget_x + self.rotation - SLIDER_KNOB_WIDTH / 2;
|
let slider_knob_x = widget_x + model.rotation - SLIDER_KNOB_WIDTH / 2;
|
||||||
let slider_knob_rect = RectI32::new(
|
let slider_knob_rect = RectI32::new(
|
||||||
Point2DI32::new(slider_knob_x, widget_y),
|
Point2DI32::new(slider_knob_x, widget_y),
|
||||||
Point2DI32::new(SLIDER_KNOB_WIDTH, SLIDER_KNOB_HEIGHT),
|
Point2DI32::new(SLIDER_KNOB_WIDTH, SLIDER_KNOB_HEIGHT),
|
||||||
);
|
);
|
||||||
debug_ui
|
debug_ui.ui.draw_solid_rect(device, slider_knob_rect, TEXT_COLOR);
|
||||||
.ui
|
|
||||||
.draw_solid_rect(device, slider_knob_rect, TEXT_COLOR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_background_menu_item(
|
fn draw_background_menu_item(
|
||||||
|
@ -440,6 +432,7 @@ where
|
||||||
color: BackgroundColor,
|
color: BackgroundColor,
|
||||||
panel_position: Point2DI32,
|
panel_position: Point2DI32,
|
||||||
action: &mut UIAction,
|
action: &mut UIAction,
|
||||||
|
model: &mut DemoUIModel,
|
||||||
) {
|
) {
|
||||||
let (text, index) = (color.as_str(), color as i32);
|
let (text, index) = (color.as_str(), color as i32);
|
||||||
|
|
||||||
|
@ -447,24 +440,16 @@ where
|
||||||
let widget_origin = panel_position + Point2DI32::new(0, widget_size.y() * index);
|
let widget_origin = panel_position + Point2DI32::new(0, widget_size.y() * index);
|
||||||
let widget_rect = RectI32::new(widget_origin, widget_size);
|
let widget_rect = RectI32::new(widget_origin, widget_size);
|
||||||
|
|
||||||
if color == self.background_color {
|
if color == model.background_color {
|
||||||
debug_ui
|
debug_ui.ui.draw_solid_rounded_rect(device, widget_rect, TEXT_COLOR);
|
||||||
.ui
|
|
||||||
.draw_solid_rounded_rect(device, widget_rect, TEXT_COLOR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let (text_x, text_y) = (PADDING * 2, BUTTON_TEXT_OFFSET);
|
let (text_x, text_y) = (PADDING * 2, BUTTON_TEXT_OFFSET);
|
||||||
let text_position = widget_origin + Point2DI32::new(text_x, text_y);
|
let text_position = widget_origin + Point2DI32::new(text_x, text_y);
|
||||||
debug_ui
|
debug_ui.ui.draw_text(device, text, text_position, color == model.background_color);
|
||||||
.ui
|
|
||||||
.draw_text(device, text, text_position, color == self.background_color);
|
|
||||||
|
|
||||||
if let Some(_) = debug_ui
|
if debug_ui.ui.event_queue.handle_mouse_down_in_rect(widget_rect).is_some() {
|
||||||
.ui
|
model.background_color = color;
|
||||||
.event_queue
|
|
||||||
.handle_mouse_down_in_rect(widget_rect)
|
|
||||||
{
|
|
||||||
self.background_color = color;
|
|
||||||
*action = UIAction::ModelChanged;
|
*action = UIAction::ModelChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue