Rename `DebugUI` to `DebugUIPresenter` and `UI` to `UIPresenter`

This commit is contained in:
Patrick Walton 2019-05-06 15:36:39 -07:00
parent 78908c5e3c
commit 15f63df844
5 changed files with 118 additions and 91 deletions

View File

@ -444,10 +444,10 @@ impl<W> DemoApp<W> where W: Window {
let frame = self.current_frame.take().unwrap();
for ui_event in &frame.ui_events {
self.dirty = true;
self.renderer.debug_ui.ui.event_queue.push(*ui_event);
self.renderer.debug_ui_presenter.ui_presenter.event_queue.push(*ui_event);
}
self.renderer.debug_ui.ui.mouse_position = self
self.renderer.debug_ui_presenter.ui_presenter.mouse_position = self
.last_mouse_position
.to_f32()
.scale(self.window_size.backing_scale_factor);
@ -459,7 +459,7 @@ impl<W> DemoApp<W> where W: Window {
self.ui_presenter.update(
&self.renderer.device,
&mut self.window,
&mut self.renderer.debug_ui,
&mut self.renderer.debug_ui_presenter,
&mut ui_action,
&mut self.ui_model,
);
@ -497,11 +497,13 @@ impl<W> DemoApp<W> where W: Window {
)
};
self.renderer.debug_ui.add_sample(aggregate_stats, build_time, total_rendering_time);
self.renderer.debug_ui_presenter.add_sample(aggregate_stats,
build_time,
total_rendering_time);
}
fn handle_ui_events(&mut self, mut frame: Frame, ui_action: &mut UIAction) {
frame.ui_events = self.renderer.debug_ui.ui.event_queue.drain();
frame.ui_events = self.renderer.debug_ui_presenter.ui_presenter.event_queue.drain();
self.handle_ui_action(ui_action);

View File

@ -15,7 +15,7 @@ use pathfinder_geometry::basic::point::Point2DI32;
use pathfinder_geometry::basic::rect::RectI32;
use pathfinder_gpu::resources::ResourceLoader;
use pathfinder_gpu::Device;
use pathfinder_renderer::gpu::debug::DebugUI;
use pathfinder_renderer::gpu::debug::DebugUIPresenter;
use pathfinder_ui::{BUTTON_HEIGHT, BUTTON_TEXT_OFFSET, BUTTON_WIDTH, FONT_ASCENT, PADDING};
use pathfinder_ui::{TEXT_COLOR, TOOLTIP_HEIGHT, WINDOW_COLOR};
use std::f32::consts::PI;
@ -129,7 +129,7 @@ where
&mut self,
device: &D,
window: &mut W,
debug_ui: &mut DebugUI<D>,
debug_ui_presenter: &mut DebugUIPresenter<D>,
action: &mut UIAction,
model: &mut DemoUIModel
) where
@ -137,22 +137,24 @@ where
{
// Draw message text.
self.draw_message_text(device, debug_ui, model);
self.draw_message_text(device, debug_ui_presenter, model);
// Draw button strip.
let bottom = debug_ui.ui.framebuffer_size().y() - PADDING;
let bottom = debug_ui_presenter.ui_presenter.framebuffer_size().y() - PADDING;
let mut position = Point2DI32::new(PADDING, bottom - BUTTON_HEIGHT);
let button_size = Point2DI32::new(BUTTON_WIDTH, BUTTON_HEIGHT);
// Draw text effects button.
if self.show_text_effects {
if debug_ui.ui.draw_button(device, position, &self.effects_texture) {
if debug_ui_presenter.ui_presenter.draw_button(device,
position,
&self.effects_texture) {
self.effects_panel_visible = !self.effects_panel_visible;
}
if !self.effects_panel_visible {
debug_ui.ui.draw_tooltip(
debug_ui_presenter.ui_presenter.draw_tooltip(
device,
"Text Effects",
RectI32::new(position, button_size),
@ -162,23 +164,27 @@ where
}
// Draw open button.
if debug_ui.ui.draw_button(device, position, &self.open_texture) {
if debug_ui_presenter.ui_presenter.draw_button(device, position, &self.open_texture) {
// FIXME(pcwalton): This is not sufficient for Android, where we will need to take in
// the contents of the file.
window.present_open_svg_dialog();
}
debug_ui.ui.draw_tooltip(device, "Open SVG", RectI32::new(position, button_size));
debug_ui_presenter.ui_presenter.draw_tooltip(device,
"Open SVG",
RectI32::new(position, button_size));
position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0);
// Draw screenshot button.
if debug_ui.ui.draw_button(device, position, &self.screenshot_texture) {
if debug_ui_presenter.ui_presenter.draw_button(device,
position,
&self.screenshot_texture) {
// FIXME(pcwalton): This is not sufficient for Android, where we will need to take in
// the contents of the file.
if let Ok(file) = window.run_save_dialog("png") {
*action = UIAction::TakeScreenshot(file);
}
}
debug_ui.ui.draw_tooltip(
debug_ui_presenter.ui_presenter.draw_tooltip(
device,
"Take Screenshot",
RectI32::new(position, button_size),
@ -186,8 +192,11 @@ where
position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0);
// Draw mode switch.
let new_mode =
debug_ui.ui.draw_text_switch(device, position, &["2D", "3D", "VR"], model.mode as u8);
let new_mode = debug_ui_presenter.ui_presenter.draw_text_switch(
device,
position,
&["2D", "3D", "VR"],
model.mode as u8);
if new_mode != model.mode as u8 {
model.mode = match new_mode {
0 => Mode::TwoD,
@ -197,9 +206,9 @@ where
*action = UIAction::ModelChanged;
}
let mode_switch_width = debug_ui.ui.measure_switch(3);
let mode_switch_width = debug_ui_presenter.ui_presenter.measure_switch(3);
let mode_switch_size = Point2DI32::new(mode_switch_width, BUTTON_HEIGHT);
debug_ui.ui.draw_tooltip(
debug_ui_presenter.ui_presenter.draw_tooltip(
device,
"2D/3D/VR Mode",
RectI32::new(position, mode_switch_size),
@ -207,11 +216,13 @@ where
position += Point2DI32::new(mode_switch_width + PADDING, 0);
// Draw background switch.
if debug_ui.ui.draw_button(device, position, &self.background_texture) {
if debug_ui_presenter.ui_presenter.draw_button(device,
position,
&self.background_texture) {
self.background_panel_visible = !self.background_panel_visible;
}
if !self.background_panel_visible {
debug_ui.ui.draw_tooltip(
debug_ui_presenter.ui_presenter.draw_tooltip(
device,
"Background Color",
RectI32::new(position, button_size),
@ -219,56 +230,62 @@ where
}
// Draw background panel, if necessary.
self.draw_background_panel(device, debug_ui, position.x(), action, model);
self.draw_background_panel(device, debug_ui_presenter, position.x(), action, model);
position += Point2DI32::new(button_size.x() + PADDING, 0);
// Draw effects panel, if necessary.
self.draw_effects_panel(device, debug_ui, model);
self.draw_effects_panel(device, debug_ui_presenter, model);
// Draw rotate and zoom buttons, if applicable.
if model.mode != Mode::TwoD {
return;
}
if debug_ui.ui.draw_button(device, position, &self.rotate_texture) {
if debug_ui_presenter.ui_presenter.draw_button(device, position, &self.rotate_texture) {
self.rotate_panel_visible = !self.rotate_panel_visible;
}
if !self.rotate_panel_visible {
debug_ui.ui.draw_tooltip(device, "Rotate", RectI32::new(position, button_size));
debug_ui_presenter.ui_presenter.draw_tooltip(device,
"Rotate",
RectI32::new(position, button_size));
}
self.draw_rotate_panel(device, debug_ui, position.x(), action, model);
self.draw_rotate_panel(device, debug_ui_presenter, position.x(), action, model);
position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0);
if debug_ui.ui.draw_button(device, position, &self.zoom_in_texture) {
if debug_ui_presenter.ui_presenter.draw_button(device, position, &self.zoom_in_texture) {
*action = UIAction::ZoomIn;
}
debug_ui.ui.draw_tooltip(device, "Zoom In", RectI32::new(position, button_size));
debug_ui_presenter.ui_presenter.draw_tooltip(device,
"Zoom In",
RectI32::new(position, button_size));
position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0);
if debug_ui.ui.draw_button(device, position, &self.zoom_out_texture) {
if debug_ui_presenter.ui_presenter.draw_button(device, position, &self.zoom_out_texture) {
*action = UIAction::ZoomOut;
}
debug_ui.ui.draw_tooltip(device, "Zoom Out", RectI32::new(position, button_size));
debug_ui_presenter.ui_presenter.draw_tooltip(device,
"Zoom Out",
RectI32::new(position, button_size));
position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0);
}
fn draw_message_text(&mut self,
device: &D,
debug_ui: &mut DebugUI<D>,
debug_ui_presenter: &mut DebugUIPresenter<D>,
model: &mut DemoUIModel) {
if model.message.is_empty() {
return;
}
let message_size = debug_ui.ui.measure_text(&model.message);
let message_size = debug_ui_presenter.ui_presenter.measure_text(&model.message);
let window_origin = Point2DI32::new(PADDING, PADDING);
let window_size = Point2DI32::new(PADDING * 2 + message_size, TOOLTIP_HEIGHT);
debug_ui.ui.draw_solid_rounded_rect(
debug_ui_presenter.ui_presenter.draw_solid_rounded_rect(
device,
RectI32::new(window_origin, window_size),
WINDOW_COLOR,
);
debug_ui.ui.draw_text(
debug_ui_presenter.ui_presenter.draw_text(
device,
&model.message,
window_origin + Point2DI32::new(PADDING, PADDING + FONT_ASCENT),
@ -278,15 +295,15 @@ where
fn draw_effects_panel(&mut self,
device: &D,
debug_ui: &mut DebugUI<D>,
debug_ui_presenter: &mut DebugUIPresenter<D>,
model: &mut DemoUIModel) {
if !self.effects_panel_visible {
return;
}
let bottom = debug_ui.ui.framebuffer_size().y() - PADDING;
let bottom = debug_ui_presenter.ui_presenter.framebuffer_size().y() - PADDING;
let effects_panel_y = bottom - (BUTTON_HEIGHT + PADDING + EFFECTS_PANEL_HEIGHT);
debug_ui.ui.draw_solid_rounded_rect(
debug_ui_presenter.ui_presenter.draw_solid_rounded_rect(
device,
RectI32::new(
Point2DI32::new(PADDING, effects_panel_y),
@ -297,7 +314,7 @@ where
model.gamma_correction_effect_enabled = self.draw_effects_switch(
device,
debug_ui,
debug_ui_presenter,
"Gamma Correction",
0,
effects_panel_y,
@ -305,7 +322,7 @@ where
);
model.stem_darkening_effect_enabled = self.draw_effects_switch(
device,
debug_ui,
debug_ui_presenter,
"Stem Darkening",
1,
effects_panel_y,
@ -313,7 +330,7 @@ where
);
model.subpixel_aa_effect_enabled = self.draw_effects_switch(
device,
debug_ui,
debug_ui_presenter,
"Subpixel AA",
2,
effects_panel_y,
@ -324,7 +341,7 @@ where
fn draw_background_panel(
&mut self,
device: &D,
debug_ui: &mut DebugUI<D>,
debug_ui_presenter: &mut DebugUIPresenter<D>,
panel_x: i32,
action: &mut UIAction,
model: &mut DemoUIModel,
@ -333,10 +350,10 @@ where
return;
}
let bottom = debug_ui.ui.framebuffer_size().y() - PADDING;
let bottom = debug_ui_presenter.ui_presenter.framebuffer_size().y() - PADDING;
let panel_y = bottom - (BUTTON_HEIGHT + PADDING + BACKGROUND_PANEL_HEIGHT);
let panel_position = Point2DI32::new(panel_x, panel_y);
debug_ui.ui.draw_solid_rounded_rect(
debug_ui_presenter.ui_presenter.draw_solid_rounded_rect(
device,
RectI32::new(
panel_position,
@ -347,7 +364,7 @@ where
self.draw_background_menu_item(
device,
debug_ui,
debug_ui_presenter,
BackgroundColor::Light,
panel_position,
action,
@ -355,7 +372,7 @@ where
);
self.draw_background_menu_item(
device,
debug_ui,
debug_ui_presenter,
BackgroundColor::Dark,
panel_position,
action,
@ -363,7 +380,7 @@ where
);
self.draw_background_menu_item(
device,
debug_ui,
debug_ui_presenter,
BackgroundColor::Transparent,
panel_position,
action,
@ -374,7 +391,7 @@ where
fn draw_rotate_panel(
&mut self,
device: &D,
debug_ui: &mut DebugUI<D>,
debug_ui_presenter: &mut DebugUIPresenter<D>,
rotate_panel_x: i32,
action: &mut UIAction,
model: &mut DemoUIModel
@ -383,11 +400,11 @@ where
return;
}
let bottom = debug_ui.ui.framebuffer_size().y() - PADDING;
let bottom = debug_ui_presenter.ui_presenter.framebuffer_size().y() - PADDING;
let rotate_panel_y = bottom - (BUTTON_HEIGHT + PADDING + ROTATE_PANEL_HEIGHT);
let rotate_panel_origin = Point2DI32::new(rotate_panel_x, rotate_panel_y);
let rotate_panel_size = Point2DI32::new(ROTATE_PANEL_WIDTH, ROTATE_PANEL_HEIGHT);
debug_ui.ui.draw_solid_rounded_rect(
debug_ui_presenter.ui_presenter.draw_solid_rounded_rect(
device,
RectI32::new(rotate_panel_origin, rotate_panel_size),
WINDOW_COLOR,
@ -398,8 +415,8 @@ where
Point2DI32::new(widget_x, widget_y),
Point2DI32::new(SLIDER_WIDTH, SLIDER_KNOB_HEIGHT),
);
if let Some(position) = debug_ui
.ui
if let Some(position) = debug_ui_presenter
.ui_presenter
.event_queue
.handle_mouse_down_or_dragged_in_rect(widget_rect)
{
@ -413,8 +430,8 @@ where
Point2DI32::new(widget_x, slider_track_y),
Point2DI32::new(SLIDER_WIDTH, SLIDER_TRACK_HEIGHT),
);
debug_ui
.ui
debug_ui_presenter
.ui_presenter
.draw_rect_outline(device, slider_track_rect, TEXT_COLOR);
let slider_knob_x = widget_x + model.rotation - SLIDER_KNOB_WIDTH / 2;
@ -422,13 +439,13 @@ where
Point2DI32::new(slider_knob_x, widget_y),
Point2DI32::new(SLIDER_KNOB_WIDTH, SLIDER_KNOB_HEIGHT),
);
debug_ui.ui.draw_solid_rect(device, slider_knob_rect, TEXT_COLOR);
debug_ui_presenter.ui_presenter.draw_solid_rect(device, slider_knob_rect, TEXT_COLOR);
}
fn draw_background_menu_item(
&mut self,
device: &D,
debug_ui: &mut DebugUI<D>,
debug_ui_presenter: &mut DebugUIPresenter<D>,
color: BackgroundColor,
panel_position: Point2DI32,
action: &mut UIAction,
@ -441,14 +458,21 @@ where
let widget_rect = RectI32::new(widget_origin, widget_size);
if color == model.background_color {
debug_ui.ui.draw_solid_rounded_rect(device, widget_rect, TEXT_COLOR);
debug_ui_presenter.ui_presenter.draw_solid_rounded_rect(device,
widget_rect,
TEXT_COLOR);
}
let (text_x, text_y) = (PADDING * 2, BUTTON_TEXT_OFFSET);
let text_position = widget_origin + Point2DI32::new(text_x, text_y);
debug_ui.ui.draw_text(device, text, text_position, color == model.background_color);
debug_ui_presenter.ui_presenter.draw_text(device,
text,
text_position, color == model.background_color);
if debug_ui.ui.event_queue.handle_mouse_down_in_rect(widget_rect).is_some() {
if debug_ui_presenter.ui_presenter
.event_queue
.handle_mouse_down_in_rect(widget_rect)
.is_some() {
model.background_color = color;
*action = UIAction::ModelChanged;
}
@ -457,7 +481,7 @@ where
fn draw_effects_switch(
&self,
device: &D,
debug_ui: &mut DebugUI<D>,
debug_ui_presenter: &mut DebugUIPresenter<D>,
text: &str,
index: i32,
window_y: i32,
@ -465,16 +489,16 @@ where
) -> bool {
let text_x = PADDING * 2;
let text_y = window_y + PADDING + BUTTON_TEXT_OFFSET + (BUTTON_HEIGHT + PADDING) * index;
debug_ui
.ui
debug_ui_presenter
.ui_presenter
.draw_text(device, text, Point2DI32::new(text_x, text_y), false);
let switch_width = debug_ui.ui.measure_switch(2);
let switch_width = debug_ui_presenter.ui_presenter.measure_switch(2);
let switch_x = PADDING + EFFECTS_PANEL_WIDTH - (switch_width + PADDING);
let switch_y = window_y + PADDING + (BUTTON_HEIGHT + PADDING) * index;
let switch_position = Point2DI32::new(switch_x, switch_y);
debug_ui
.ui
debug_ui_presenter
.ui_presenter
.draw_text_switch(device, switch_position, &["Off", "On"], value as u8)
!= 0
}

View File

@ -20,7 +20,7 @@ use pathfinder_geometry::basic::point::Point2DI32;
use pathfinder_geometry::basic::rect::RectI32;
use pathfinder_gpu::resources::ResourceLoader;
use pathfinder_gpu::Device;
use pathfinder_ui::{FONT_ASCENT, LINE_HEIGHT, PADDING, UI, WINDOW_COLOR};
use pathfinder_ui::{FONT_ASCENT, LINE_HEIGHT, PADDING, UIPresenter, WINDOW_COLOR};
use std::collections::VecDeque;
use std::ops::{Add, Div};
use std::time::Duration;
@ -30,17 +30,17 @@ const SAMPLE_BUFFER_SIZE: usize = 60;
const PERF_WINDOW_WIDTH: i32 = 375;
const PERF_WINDOW_HEIGHT: i32 = LINE_HEIGHT * 6 + PADDING + 2;
pub struct DebugUI<D>
pub struct DebugUIPresenter<D>
where
D: Device,
{
pub ui: UI<D>,
pub ui_presenter: UIPresenter<D>,
cpu_samples: SampleBuffer<CPUSample>,
gpu_samples: SampleBuffer<GPUSample>,
}
impl<D> DebugUI<D>
impl<D> DebugUIPresenter<D>
where
D: Device,
{
@ -48,10 +48,10 @@ where
device: &D,
resources: &dyn ResourceLoader,
framebuffer_size: Point2DI32,
) -> DebugUI<D> {
let ui = UI::new(device, resources, framebuffer_size);
DebugUI {
ui,
) -> DebugUIPresenter<D> {
let ui_presenter = UIPresenter::new(device, resources, framebuffer_size);
DebugUIPresenter {
ui_presenter,
cpu_samples: SampleBuffer::new(),
gpu_samples: SampleBuffer::new(),
}
@ -76,7 +76,7 @@ where
pub fn draw(&self, device: &D) {
// Draw performance window.
let framebuffer_size = self.ui.framebuffer_size();
let framebuffer_size = self.ui_presenter.framebuffer_size();
let bottom = framebuffer_size.y() - PADDING;
let window_rect = RectI32::new(
Point2DI32::new(
@ -85,37 +85,36 @@ where
),
Point2DI32::new(PERF_WINDOW_WIDTH, PERF_WINDOW_HEIGHT),
);
self.ui
.draw_solid_rounded_rect(device, window_rect, WINDOW_COLOR);
self.ui_presenter.draw_solid_rounded_rect(device, window_rect, WINDOW_COLOR);
let origin = window_rect.origin() + Point2DI32::new(PADDING, PADDING + FONT_ASCENT);
let mean_cpu_sample = self.cpu_samples.mean();
self.ui.draw_text(
self.ui_presenter.draw_text(
device,
&format!("Objects: {}", mean_cpu_sample.stats.object_count),
origin,
false,
);
self.ui.draw_text(
self.ui_presenter.draw_text(
device,
&format!("Solid Tiles: {}", mean_cpu_sample.stats.solid_tile_count),
origin + Point2DI32::new(0, LINE_HEIGHT * 1),
false,
);
self.ui.draw_text(
self.ui_presenter.draw_text(
device,
&format!("Alpha Tiles: {}", mean_cpu_sample.stats.alpha_tile_count),
origin + Point2DI32::new(0, LINE_HEIGHT * 2),
false,
);
self.ui.draw_text(
self.ui_presenter.draw_text(
device,
&format!("Fills: {}", mean_cpu_sample.stats.fill_count),
origin + Point2DI32::new(0, LINE_HEIGHT * 3),
false,
);
self.ui.draw_text(
self.ui_presenter.draw_text(
device,
&format!(
"CPU Time: {:.3} ms",
@ -126,7 +125,7 @@ where
);
let mean_gpu_sample = self.gpu_samples.mean();
self.ui.draw_text(
self.ui_presenter.draw_text(
device,
&format!(
"GPU Time: {:.3} ms",

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use crate::gpu::debug::DebugUI;
use crate::gpu::debug::DebugUIPresenter;
use crate::gpu_data::{AlphaTileBatchPrimitive, FillBatchPrimitive};
use crate::gpu_data::{RenderCommand, SolidTileBatchPrimitive};
use crate::post::DefringingKernel;
@ -93,7 +93,7 @@ where
current_timer_query: Option<D::TimerQuery>,
pending_timer_queries: VecDeque<D::TimerQuery>,
free_timer_queries: Vec<D::TimerQuery>,
pub debug_ui: DebugUI<D>,
pub debug_ui_presenter: DebugUIPresenter<D>,
// Extra info
render_mode: RenderMode,
@ -175,7 +175,8 @@ where
Point2DI32::new(FILL_COLORS_TEXTURE_WIDTH, FILL_COLORS_TEXTURE_HEIGHT);
let fill_colors_texture = device.create_texture(TextureFormat::RGBA8, fill_colors_size);
let debug_ui = DebugUI::new(&device, resources, dest_framebuffer.window_size(&device));
let window_size = dest_framebuffer.window_size(&device);
let debug_ui_presenter = DebugUIPresenter::new(&device, resources, window_size);
let renderer = Renderer {
device,
@ -211,7 +212,7 @@ where
current_timer_query: None,
pending_timer_queries: VecDeque::new(),
free_timer_queries: vec![],
debug_ui,
debug_ui_presenter,
mask_framebuffer_cleared: false,
buffered_fills: vec![],
@ -279,7 +280,7 @@ where
pub fn draw_debug_ui(&self) {
self.bind_dest_framebuffer();
self.debug_ui.draw(&self.device);
self.debug_ui_presenter.draw(&self.device);
}
pub fn shift_timer_query(&mut self) -> Option<Duration> {
@ -308,7 +309,7 @@ where
#[inline]
pub fn set_main_framebuffer_size(&mut self, new_framebuffer_size: Point2DI32) {
self.debug_ui.ui.set_framebuffer_size(new_framebuffer_size);
self.debug_ui_presenter.ui_presenter.set_framebuffer_size(new_framebuffer_size);
}
#[inline]

View File

@ -63,7 +63,7 @@ static QUAD_INDICES: [u32; 6] = [0, 1, 3, 1, 2, 3];
static RECT_LINE_INDICES: [u32; 8] = [0, 1, 1, 2, 2, 3, 3, 0];
static OUTLINE_RECT_LINE_INDICES: [u32; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
pub struct UI<D> where D: Device {
pub struct UIPresenter<D> where D: Device {
pub event_queue: UIEventQueue,
pub mouse_position: Point2DF32,
@ -80,8 +80,9 @@ pub struct UI<D> where D: Device {
corner_outline_texture: D::Texture,
}
impl<D> UI<D> where D: Device {
pub fn new(device: &D, resources: &dyn ResourceLoader, framebuffer_size: Point2DI32) -> UI<D> {
impl<D> UIPresenter<D> where D: Device {
pub fn new(device: &D, resources: &dyn ResourceLoader, framebuffer_size: Point2DI32)
-> UIPresenter<D> {
let texture_program = DebugTextureProgram::new(device, resources);
let texture_vertex_array = DebugTextureVertexArray::new(device, &texture_program);
let font = DebugFont::load(resources);
@ -94,7 +95,7 @@ impl<D> UI<D> where D: Device {
let corner_outline_texture = device.create_texture_from_png(resources,
CORNER_OUTLINE_PNG_NAME);
UI {
UIPresenter {
event_queue: UIEventQueue::new(),
mouse_position: Point2DF32::default(),