Factor the demo UI into model and presenter

This commit is contained in:
Patrick Walton 2019-05-06 15:25:58 -07:00
parent 3857a28e6a
commit 78908c5e3c
3 changed files with 124 additions and 128 deletions

View File

@ -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 || {

View File

@ -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();

View File

@ -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;
} }
} }