Add partial support for transparent background colors.
This commit is contained in:
parent
12b3b1cd9a
commit
c5ccd0f6e0
|
@ -11,7 +11,7 @@
|
|||
//! A demo app for Pathfinder.
|
||||
|
||||
use crate::device::{GroundLineVertexArray, GroundProgram, GroundSolidVertexArray};
|
||||
use crate::ui::{DemoUI, UIAction};
|
||||
use crate::ui::{BackgroundColor, DemoUI, UIAction};
|
||||
use crate::window::{Event, Keycode, SVGPath, Window, WindowSize};
|
||||
use clap::{App, Arg};
|
||||
use image::ColorType;
|
||||
|
@ -62,6 +62,8 @@ const FAR_CLIP_PLANE: f32 = 10.0;
|
|||
|
||||
const LIGHT_BG_COLOR: ColorU = ColorU { r: 248, g: 248, b: 248, a: 255 };
|
||||
const DARK_BG_COLOR: ColorU = ColorU { r: 32, g: 32, b: 32, a: 255 };
|
||||
const TRANSPARENT_BG_COLOR: ColorU = ColorU { r: 0, g: 0, b: 0, a: 0 };
|
||||
|
||||
const GROUND_SOLID_COLOR: ColorU = ColorU { r: 80, g: 80, b: 80, a: 255 };
|
||||
const GROUND_LINE_COLOR: ColorU = ColorU { r: 127, g: 127, b: 127, a: 255 };
|
||||
|
||||
|
@ -90,7 +92,7 @@ pub struct DemoApp<W> where W: Window {
|
|||
frame_counter: u32,
|
||||
pending_screenshot_path: Option<PathBuf>,
|
||||
mouselook_enabled: bool,
|
||||
dirty: bool,
|
||||
pub dirty: bool,
|
||||
expire_message_event_id: u32,
|
||||
message_epoch: u32,
|
||||
last_mouse_position: Point2DI32,
|
||||
|
@ -185,6 +187,9 @@ impl<W> DemoApp<W> where W: Window {
|
|||
}
|
||||
|
||||
pub fn prepare_frame(&mut self, events: Vec<Event>) -> u32 {
|
||||
// Clear dirty flag.
|
||||
self.dirty = false;
|
||||
|
||||
// Handle events.
|
||||
let ui_events = self.handle_events(events);
|
||||
|
||||
|
@ -595,6 +600,7 @@ impl<W> DemoApp<W> where W: Window {
|
|||
fn handle_ui_action(&mut self, ui_action: &mut UIAction) {
|
||||
match ui_action {
|
||||
UIAction::None => {}
|
||||
UIAction::ModelChanged => self.dirty = true,
|
||||
UIAction::TakeScreenshot(ref path) => {
|
||||
self.pending_screenshot_path = Some((*path).clone());
|
||||
self.dirty = true;
|
||||
|
@ -643,7 +649,11 @@ impl<W> DemoApp<W> where W: Window {
|
|||
}
|
||||
|
||||
fn background_color(&self) -> ColorU {
|
||||
if self.ui.dark_background_enabled { DARK_BG_COLOR } else { LIGHT_BG_COLOR }
|
||||
match self.ui.background_color {
|
||||
BackgroundColor::Light => LIGHT_BG_COLOR,
|
||||
BackgroundColor::Dark => DARK_BG_COLOR,
|
||||
BackgroundColor::Transparent => TRANSPARENT_BG_COLOR,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -813,6 +823,7 @@ pub struct Options {
|
|||
pub mode: Mode,
|
||||
pub input_path: SVGPath,
|
||||
pub ui: UIVisibility,
|
||||
pub background_color: BackgroundColor,
|
||||
hidden_field_for_future_proofing: (),
|
||||
}
|
||||
|
||||
|
@ -823,6 +834,7 @@ impl Default for Options {
|
|||
mode: Mode::TwoD,
|
||||
input_path: SVGPath::Default,
|
||||
ui: UIVisibility::All,
|
||||
background_color: BackgroundColor::Light,
|
||||
hidden_field_for_future_proofing: (),
|
||||
}
|
||||
}
|
||||
|
@ -849,6 +861,14 @@ impl Options {
|
|||
.possible_values(&["none", "stats", "all"])
|
||||
.help("How much UI to show"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("background")
|
||||
.short("b")
|
||||
.long("background")
|
||||
.takes_value(true)
|
||||
.possible_values(&["light", "dark", "transparent"])
|
||||
.help("The background color to use"),
|
||||
)
|
||||
.arg(Arg::with_name("INPUT").help("Path to the SVG file to render").index(1))
|
||||
.get_matches();
|
||||
|
||||
|
@ -870,12 +890,21 @@ impl Options {
|
|||
};
|
||||
}
|
||||
|
||||
if let Some(background_color) = matches.value_of("background") {
|
||||
self.background_color = match background_color {
|
||||
"light" => BackgroundColor::Light,
|
||||
"dark" => BackgroundColor::Dark,
|
||||
_ => BackgroundColor::Transparent,
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(path) = matches.value_of("INPUT") {
|
||||
self.input_path = SVGPath::Path(PathBuf::from(path));
|
||||
};
|
||||
}
|
||||
|
||||
fn adjust_thread_pool_settings(&self, mut thread_pool_builder: ThreadPoolBuilder) -> ThreadPoolBuilder {
|
||||
fn adjust_thread_pool_settings(&self, mut thread_pool_builder: ThreadPoolBuilder)
|
||||
-> ThreadPoolBuilder {
|
||||
if let Some(jobs) = self.jobs {
|
||||
thread_pool_builder = thread_pool_builder.num_threads(jobs);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,9 @@ const SLIDER_KNOB_HEIGHT: i32 = 48;
|
|||
const EFFECTS_PANEL_WIDTH: i32 = 550;
|
||||
const EFFECTS_PANEL_HEIGHT: i32 = BUTTON_HEIGHT * 3 + PADDING * 4;
|
||||
|
||||
const BACKGROUND_PANEL_WIDTH: i32 = 250;
|
||||
const BACKGROUND_PANEL_HEIGHT: i32 = BUTTON_HEIGHT * 3;
|
||||
|
||||
const ROTATE_PANEL_WIDTH: i32 = SLIDER_WIDTH + PADDING * 2;
|
||||
const ROTATE_PANEL_HEIGHT: i32 = PADDING * 2 + SLIDER_HEIGHT;
|
||||
|
||||
|
@ -37,8 +40,7 @@ static OPEN_PNG_NAME: &'static str = "demo-open";
|
|||
static ROTATE_PNG_NAME: &'static str = "demo-rotate";
|
||||
static ZOOM_IN_PNG_NAME: &'static str = "demo-zoom-in";
|
||||
static ZOOM_OUT_PNG_NAME: &'static str = "demo-zoom-out";
|
||||
static BG_LIGHT_PNG_NAME: &'static str = "demo-bg-light";
|
||||
static BG_DARK_PNG_NAME: &'static str = "demo-bg-dark";
|
||||
static BACKGROUND_PNG_NAME: &'static str = "demo-background";
|
||||
static SCREENSHOT_PNG_NAME: &'static str = "demo-screenshot";
|
||||
|
||||
pub struct DemoUI<D> where D: Device {
|
||||
|
@ -47,17 +49,17 @@ pub struct DemoUI<D> where D: Device {
|
|||
rotate_texture: D::Texture,
|
||||
zoom_in_texture: D::Texture,
|
||||
zoom_out_texture: D::Texture,
|
||||
bg_light_texture: D::Texture,
|
||||
bg_dark_texture: D::Texture,
|
||||
background_texture: D::Texture,
|
||||
screenshot_texture: D::Texture,
|
||||
|
||||
effects_panel_visible: bool,
|
||||
background_panel_visible: bool,
|
||||
rotate_panel_visible: bool,
|
||||
|
||||
// FIXME(pcwalton): Factor the below out into a model class.
|
||||
|
||||
pub mode: Mode,
|
||||
pub dark_background_enabled: bool,
|
||||
pub background_color: BackgroundColor,
|
||||
pub gamma_correction_effect_enabled: bool,
|
||||
pub stem_darkening_effect_enabled: bool,
|
||||
pub subpixel_aa_effect_enabled: bool,
|
||||
|
@ -73,8 +75,7 @@ impl<D> DemoUI<D> where D: Device {
|
|||
let rotate_texture = device.create_texture_from_png(resources, ROTATE_PNG_NAME);
|
||||
let zoom_in_texture = device.create_texture_from_png(resources, ZOOM_IN_PNG_NAME);
|
||||
let zoom_out_texture = device.create_texture_from_png(resources, ZOOM_OUT_PNG_NAME);
|
||||
let bg_light_texture = device.create_texture_from_png(resources, BG_LIGHT_PNG_NAME);
|
||||
let bg_dark_texture = device.create_texture_from_png(resources, BG_DARK_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);
|
||||
|
||||
DemoUI {
|
||||
|
@ -83,15 +84,15 @@ impl<D> DemoUI<D> where D: Device {
|
|||
rotate_texture,
|
||||
zoom_in_texture,
|
||||
zoom_out_texture,
|
||||
bg_light_texture,
|
||||
bg_dark_texture,
|
||||
background_texture,
|
||||
screenshot_texture,
|
||||
|
||||
effects_panel_visible: false,
|
||||
background_panel_visible: false,
|
||||
rotate_panel_visible: false,
|
||||
|
||||
mode: options.mode,
|
||||
dark_background_enabled: false,
|
||||
background_color: options.background_color,
|
||||
gamma_correction_effect_enabled: false,
|
||||
stem_darkening_effect_enabled: false,
|
||||
subpixel_aa_effect_enabled: false,
|
||||
|
@ -166,7 +167,9 @@ impl<D> DemoUI<D> where D: Device {
|
|||
1 => Mode::ThreeD,
|
||||
_ => Mode::VR,
|
||||
};
|
||||
*action = UIAction::ModelChanged;
|
||||
}
|
||||
|
||||
let mode_switch_width = debug_ui.ui.measure_switch(3);
|
||||
let mode_switch_size = Point2DI32::new(mode_switch_width, BUTTON_HEIGHT);
|
||||
debug_ui.ui.draw_tooltip(device,
|
||||
|
@ -175,17 +178,18 @@ impl<D> DemoUI<D> where D: Device {
|
|||
position += Point2DI32::new(mode_switch_width + PADDING, 0);
|
||||
|
||||
// Draw background switch.
|
||||
self.dark_background_enabled = debug_ui.ui.draw_image_switch(device,
|
||||
position,
|
||||
&self.bg_light_texture,
|
||||
&self.bg_dark_texture,
|
||||
self.dark_background_enabled);
|
||||
let background_color_switch_width = debug_ui.ui.measure_switch(2);
|
||||
let background_color_switch_size = Point2DI32::new(background_color_switch_width,
|
||||
BUTTON_HEIGHT);
|
||||
let background_color_switch_rect = RectI32::new(position, background_color_switch_size);
|
||||
debug_ui.ui.draw_tooltip(device, "Background Color", background_color_switch_rect);
|
||||
position += Point2DI32::new(background_color_switch_width + PADDING, 0);
|
||||
if debug_ui.ui.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(device,
|
||||
"Background Color",
|
||||
RectI32::new(position, button_size));
|
||||
}
|
||||
|
||||
// Draw background panel, if necessary.
|
||||
self.draw_background_panel(device, debug_ui, position.x(), action);
|
||||
position += Point2DI32::new(button_size.x() + PADDING, 0);
|
||||
|
||||
// Draw effects panel, if necessary.
|
||||
self.draw_effects_panel(device, debug_ui);
|
||||
|
@ -268,7 +272,41 @@ impl<D> DemoUI<D> where D: Device {
|
|||
2,
|
||||
effects_panel_y,
|
||||
self.subpixel_aa_effect_enabled);
|
||||
}
|
||||
|
||||
fn draw_background_panel(&mut self,
|
||||
device: &D,
|
||||
debug_ui: &mut DebugUI<D>,
|
||||
panel_x: i32,
|
||||
action: &mut UIAction) {
|
||||
if !self.background_panel_visible {
|
||||
return;
|
||||
}
|
||||
|
||||
let bottom = debug_ui.ui.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(device,
|
||||
RectI32::new(panel_position,
|
||||
Point2DI32::new(BACKGROUND_PANEL_WIDTH,
|
||||
BACKGROUND_PANEL_HEIGHT)),
|
||||
WINDOW_COLOR);
|
||||
|
||||
self.draw_background_menu_item(device,
|
||||
debug_ui,
|
||||
BackgroundColor::Light,
|
||||
panel_position,
|
||||
action);
|
||||
self.draw_background_menu_item(device,
|
||||
debug_ui,
|
||||
BackgroundColor::Dark,
|
||||
panel_position,
|
||||
action);
|
||||
self.draw_background_menu_item(device,
|
||||
debug_ui,
|
||||
BackgroundColor::Transparent,
|
||||
panel_position,
|
||||
action);
|
||||
}
|
||||
|
||||
fn draw_rotate_panel(&mut self,
|
||||
|
@ -312,6 +350,32 @@ impl<D> DemoUI<D> where D: Device {
|
|||
debug_ui.ui.draw_solid_rect(device, slider_knob_rect, TEXT_COLOR);
|
||||
}
|
||||
|
||||
fn draw_background_menu_item(&mut self,
|
||||
device: &D,
|
||||
debug_ui: &mut DebugUI<D>,
|
||||
color: BackgroundColor,
|
||||
panel_position: Point2DI32,
|
||||
action: &mut UIAction) {
|
||||
let (text, index) = (color.as_str(), color as i32);
|
||||
|
||||
let widget_size = Point2DI32::new(BACKGROUND_PANEL_WIDTH, BUTTON_HEIGHT);
|
||||
let widget_origin = panel_position + Point2DI32::new(0, widget_size.y() * index);
|
||||
let widget_rect = RectI32::new(widget_origin, widget_size);
|
||||
|
||||
if color == self.background_color {
|
||||
debug_ui.ui.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 == self.background_color);
|
||||
|
||||
if let Some(_) = debug_ui.ui.event_queue.handle_mouse_down_in_rect(widget_rect) {
|
||||
self.background_color = color;
|
||||
*action = UIAction::ModelChanged;
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_effects_switch(&self,
|
||||
device: &D,
|
||||
debug_ui: &mut DebugUI<D>,
|
||||
|
@ -335,8 +399,26 @@ impl<D> DemoUI<D> where D: Device {
|
|||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum UIAction {
|
||||
None,
|
||||
ModelChanged,
|
||||
TakeScreenshot(PathBuf),
|
||||
ZoomIn,
|
||||
ZoomOut,
|
||||
Rotate(f32),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum BackgroundColor {
|
||||
Light = 0,
|
||||
Dark = 1,
|
||||
Transparent = 2,
|
||||
}
|
||||
|
||||
impl BackgroundColor {
|
||||
fn as_str(&self) -> &'static str {
|
||||
match *self {
|
||||
BackgroundColor::Light => "Light",
|
||||
BackgroundColor::Dark => "Dark",
|
||||
BackgroundColor::Transparent => "Transparent",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,10 @@ fn main() {
|
|||
let mut app = DemoApp::new(window, window_size, options);
|
||||
|
||||
while !app.should_exit {
|
||||
let mut events = vec![app.window.get_event()];
|
||||
let mut events = vec![];
|
||||
if !app.dirty {
|
||||
events.push(app.window.get_event());
|
||||
}
|
||||
while let Some(event) = app.window.try_get_event() {
|
||||
events.push(event);
|
||||
}
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 954 B |
Binary file not shown.
Before Width: | Height: | Size: 780 B |
Binary file not shown.
Before Width: | Height: | Size: 448 B |
|
@ -711,7 +711,7 @@ impl UIEventQueue {
|
|||
mem::replace(&mut self.events, vec![])
|
||||
}
|
||||
|
||||
fn handle_mouse_down_in_rect(&mut self, rect: RectI32) -> Option<Point2DI32> {
|
||||
pub fn handle_mouse_down_in_rect(&mut self, rect: RectI32) -> Option<Point2DI32> {
|
||||
let (mut remaining_events, mut result) = (vec![], None);
|
||||
for event in self.events.drain(..) {
|
||||
match event {
|
||||
|
|
Loading…
Reference in New Issue